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