| # 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 |
| ... |
| --- |