blob: 500f73a6bd582272c1e1591f429505f737a2f887 [file] [log] [blame]
# RUN: llc -mtriple=aarch64--- -run-pass=machine-outliner \
# RUN: -verify-machineinstrs %s -o - | FileCheck %s
# Ensure that we don't outline from regions where x16, x17, or nzcv are live
# across the outlining candidate. These values are allowed to be clobbered by,
# say, the linker, in the presence of function calls. Thus, we can't outline
# these, since the insertion of the outlined call could change the values of
# these registers.
--- |
; No problematic register appears at all. Safe for outlining.
define void @reg_never_defined() #0 { ret void }
; A problematic register is live, but after the candidate. Safe for outlining.
define void @reg_defined_after_candidate() #0 { ret void }
; A problematic register is live before the candidate, but killed before
; entry to the candidate. Safe for outlining.
define void @reg_killed_before_candidate() #0 { ret void }
; Ensure that we never outline when any of the problematic registers we care
; about are defined across the outlining candidate.
define void @x16_live() #0 { ret void }
define void @x17_live() #0 { ret void }
define void @nzcv_live() #0 { ret void }
; Test a combination of the above behaviours.
; [candidate] (1)
; - define a bad register -
; [candidate] (2)
; - kill the bad register -
; [candidate] (3)
;
; (1) and (3) should be outlined, while (2) should not be outlined.
define void @multiple_ranges() #0 { ret void }
attributes #0 = { noredzone }
...
---
# There should be two calls to outlined functions here, since we haven't tripped
# any of the cases above.
name: reg_never_defined
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: bb.0:
; CHECK: BL
liveins: $w8, $wzr
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
bb.1:
; CHECK-LABEL: bb.1:
; CHECK: BL
liveins: $w8, $wzr
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
bb.2:
RET undef $lr
...
---
name: reg_defined_after_candidate
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: bb.0:
; CHECK: BL
; CHECK-NEXT: $x16 = ORRXri $x8, 5, implicit-def $x16, implicit-def $w16
liveins: $w8, $wzr
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
$x16 = ORRXri $x8, 5, implicit-def $x16, implicit-def $w16
$w8 = ORRWri $w16, 5
RET undef $lr
...
---
name: reg_killed_before_candidate
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: bb.0:
; CHECK: BL
liveins: $w8, $wzr, $x16
dead $x16 = ORRXri $x8, 6
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
RET undef $lr
...
---
name: x16_live
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: bb.0:
; CHECK-NOT: BL
liveins: $w8, $wzr, $x16
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
bb.1:
liveins: $x16
RET undef $lr
...
---
name: x17_live
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: bb.0:
; CHECK-NOT: BL
liveins: $w8, $wzr, $x17
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
$w8 = ORRWri $w17, 5
RET undef $lr
...
---
name: nzcv_live
tracksRegLiveness: true
body: |
bb.0:
liveins: $w8, $wzr, $nzcv
; CHECK-LABEL: bb.0:
; CHECK-NOT: BL
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
bb.1:
liveins: $nzcv
RET undef $lr
...
---
name: multiple_ranges
tracksRegLiveness: true
body: |
bb.0:
; CHECK-LABEL: bb.0:
; CHECK: BL
liveins: $w8, $wzr
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
$x16 = ORRXri $x8, 5, implicit-def $x16
bb.1:
; CHECK-LABEL: bb.1:
; CHECK-NOT: BL
liveins: $w8, $x16
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
bb.2:
; CHECK-LABEL: bb.2:
; CHECK: BL
liveins: $w8, $x16
dead $x16 = ORRXri $x8, 0
$w8 = ORRWri $wzr, 1
$w8 = ORRWri $wzr, 2
$w8 = ORRWri $wzr, 3
$w8 = ORRWri $wzr, 4
bb.3:
liveins: $w8
RET undef $lr
...
---