1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
# 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
...
---
|