This patch handles cases where we have to save/restore the link register into the stack and and load/store instruction which use the stack are part of the outlined region. It checks that there will be no overflow introduced by the new offset and fixup these instructions accordingly. Differential Revision: https://reviews.llvm.org/D92934
232 lines
9.2 KiB
YAML
232 lines
9.2 KiB
YAML
# RUN: llc -mtriple=thumbv7-- -run-pass=prologepilog \
|
|
# RUN: -run-pass=machine-outliner %s -o - | FileCheck %s
|
|
|
|
--- |
|
|
define void @CheckAddrModeT2_i12() { ret void }
|
|
define void @CheckAddrModeT2_i8() { ret void }
|
|
define void @CheckAddrModeT2_i8s4() { ret void }
|
|
define void @CheckAddrModeT2_ldrex() { ret void }
|
|
define void @CheckAddrModeT1_s() { ret void }
|
|
define void @foo() { ret void }
|
|
|
|
...
|
|
---
|
|
|
|
name: CheckAddrModeT2_i12
|
|
tracksRegLiveness: true
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: $r1
|
|
;CHECK-LABEL: name: CheckAddrModeT2_i12
|
|
;CHECK: $r0 = tMOVr killed $r1, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[I12:[0-9]+]]
|
|
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 4088, 14 /* CC::al */, $noreg
|
|
$r0 = tMOVr killed $r1, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4086, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4088, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4086, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4088, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r0 = t2LDRi12 $sp, 0, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4086, 14, $noreg
|
|
$r0 = t2LDRi12 $sp, 4088, 14, $noreg
|
|
BX_RET 14, $noreg
|
|
...
|
|
---
|
|
|
|
name: CheckAddrModeT2_i8
|
|
tracksRegLiveness: true
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: $r1
|
|
;CHECK-LABEL: name: CheckAddrModeT2_i8
|
|
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[I8:[0-9]+]]
|
|
;CHECK-NEXT: t2STRHi8 $r0, $sp, 248, 14 /* CC::al */, $noreg
|
|
$r0 = tMOVr $r1, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
t2STRHi8 $r0, $sp, 0, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 4, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 247, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 248, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
t2STRHi8 $r0, $sp, 0, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 4, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 247, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 248, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
t2STRHi8 $r0, $sp, 0, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 4, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 247, 14, $noreg
|
|
t2STRHi8 $r0, $sp, 248, 14, $noreg
|
|
BX_RET 14, $noreg
|
|
...
|
|
---
|
|
|
|
name: CheckAddrModeT2_i8s4
|
|
tracksRegLiveness: true
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: $r1
|
|
;CHECK-LABEL: name: CheckAddrModeT2_i8s4
|
|
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[I8S4:[0-9]+]]
|
|
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 254, 14 /* CC::al */, $noreg
|
|
$r0 = tMOVr $r1, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
t2STRDi8 $r0, $r1, $sp, 0, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 8, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 253, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
t2STRDi8 $r0, $r1, $sp, 0, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 8, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 253, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
t2STRDi8 $r0, $r1, $sp, 0, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 8, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 253, 14, $noreg
|
|
t2STRDi8 $r0, $r1, $sp, 254, 14, $noreg
|
|
BX_RET 14, $noreg
|
|
...
|
|
---
|
|
|
|
name: CheckAddrModeT2_ldrex
|
|
tracksRegLiveness: true
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: $r1
|
|
;CHECK-LABEL: name: CheckAddrModeT2_ldrex
|
|
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[LDREX:[0-9]+]]
|
|
;CHECK-NEXT: $r1 = t2LDREX $sp, 254, 14 /* CC::al */, $noreg
|
|
$r0 = tMOVr $r1, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r1 = t2LDREX $sp, 0, 14, $noreg
|
|
$r1 = t2LDREX $sp, 8, 14, $noreg
|
|
$r1 = t2LDREX $sp, 253, 14, $noreg
|
|
$r1 = t2LDREX $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r1 = t2LDREX $sp, 0, 14, $noreg
|
|
$r1 = t2LDREX $sp, 8, 14, $noreg
|
|
$r1 = t2LDREX $sp, 253, 14, $noreg
|
|
$r1 = t2LDREX $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r1 = t2LDREX $sp, 0, 14, $noreg
|
|
$r1 = t2LDREX $sp, 8, 14, $noreg
|
|
$r1 = t2LDREX $sp, 253, 14, $noreg
|
|
$r1 = t2LDREX $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
$r1 = t2LDREX $sp, 0, 14, $noreg
|
|
$r1 = t2LDREX $sp, 8, 14, $noreg
|
|
$r1 = t2LDREX $sp, 253, 14, $noreg
|
|
$r1 = t2LDREX $sp, 254, 14, $noreg
|
|
BX_RET 14, $noreg
|
|
...
|
|
---
|
|
|
|
name: CheckAddrModeT1_s
|
|
tracksRegLiveness: true
|
|
|
|
body: |
|
|
bb.0:
|
|
liveins: $r0, $r1
|
|
;CHECK-LABEL: name: CheckAddrModeT1_s
|
|
;CHECK: $r0 = tMOVr $r1, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @OUTLINED_FUNCTION_[[T1_S:[0-9]+]]
|
|
;CHECK-NEXT: tSTRspi $r0, $sp, 254, 14 /* CC::al */, $noreg
|
|
$r0 = tMOVr $r1, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
tSTRspi $r0, $sp, 0, 14, $noreg
|
|
tSTRspi $r0, $sp, 4, 14, $noreg
|
|
tSTRspi $r0, $sp, 253, 14, $noreg
|
|
tSTRspi $r0, $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
tSTRspi $r0, $sp, 0, 14, $noreg
|
|
tSTRspi $r0, $sp, 4, 14, $noreg
|
|
tSTRspi $r0, $sp, 253, 14, $noreg
|
|
tSTRspi $r0, $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
tSTRspi $r0, $sp, 0, 14, $noreg
|
|
tSTRspi $r0, $sp, 4, 14, $noreg
|
|
tSTRspi $r0, $sp, 253, 14, $noreg
|
|
tSTRspi $r0, $sp, 254, 14, $noreg
|
|
tBL 14, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
tSTRspi $r0, $sp, 0, 14, $noreg
|
|
tSTRspi $r0, $sp, 4, 14, $noreg
|
|
tSTRspi $r0, $sp, 253, 14, $noreg
|
|
tSTRspi $r0, $sp, 254, 14, $noreg
|
|
BX_RET 14, $noreg
|
|
...
|
|
---
|
|
|
|
name: foo
|
|
tracksRegLiveness: true
|
|
body: |
|
|
bb.0:
|
|
liveins: $lr
|
|
|
|
BX_RET 14, $noreg
|
|
|
|
;CHECK: name: OUTLINED_FUNCTION_[[LDREX]]
|
|
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
;CHECK-NEXT: $r1 = t2LDREX $sp, 2, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $r1 = t2LDREX $sp, 10, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $r1 = t2LDREX $sp, 255, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
|
|
|
;CHECK: name: OUTLINED_FUNCTION_[[I8]]
|
|
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
;CHECK-NEXT: t2STRHi8 $r0, $sp, 8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: t2STRHi8 $r0, $sp, 12, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: t2STRHi8 $r0, $sp, 255, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
|
|
|
;CHECK: name: OUTLINED_FUNCTION_[[I8S4]]
|
|
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 2, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 10, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: t2STRDi8 $r0, $r1, $sp, 255, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
|
|
|
;CHECK: name: OUTLINED_FUNCTION_[[I12]]
|
|
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 12, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $r0 = t2LDRi12 $sp, 4094, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|
|
|
|
;CHECK: name: OUTLINED_FUNCTION_[[T1_S]]
|
|
;CHECK: early-clobber $sp = t2STR_PRE killed $lr, $sp, -8, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
|
|
;CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -8
|
|
;CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @foo, implicit-def dead $lr, implicit $sp
|
|
;CHECK-NEXT: tSTRspi $r0, $sp, 2, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tSTRspi $r0, $sp, 6, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: tSTRspi $r0, $sp, 255, 14 /* CC::al */, $noreg
|
|
;CHECK-NEXT: $lr, $sp = t2LDR_POST $sp, 8, 14 /* CC::al */, $noreg
|