mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-22 20:43:44 +02:00
62e08924a6
It isn't safe to outline sequences of instructions where x16/x17/nzcv live across the sequence. This teaches the outliner to check whether or not a specific canidate has x16/x17/nzcv live across it and discard the candidate in the case that that is true. https://bugs.llvm.org/show_bug.cgi?id=37573 https://reviews.llvm.org/D47655 llvm-svn: 335758
184 lines
4.4 KiB
YAML
184 lines
4.4 KiB
YAML
# 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
|
|
...
|
|
---
|