2019-09-17 14:58:51 +02:00
|
|
|
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
|
|
|
|
# RUN: llc -o - %s -mtriple=thumbv8.1m.main-arm-none-eabi -mattr=+mve.fp -run-pass=stack-protector -run-pass=prologepilog | FileCheck %s
|
|
|
|
---
|
|
|
|
name: func0
|
|
|
|
tracksRegLiveness: true
|
|
|
|
stack:
|
|
|
|
- { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 4,
|
|
|
|
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
|
|
|
local-offset: -16, debug-info-variable: '', debug-info-expression: '',
|
|
|
|
debug-info-location: '' }
|
|
|
|
body: |
|
|
|
|
bb.0:
|
|
|
|
; CHECK-LABEL: name: func0
|
|
|
|
; CHECK: liveins: $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11, $lr
|
2019-12-11 15:24:40 +01:00
|
|
|
; CHECK-NEXT: {{ }}
|
|
|
|
; CHECK-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14, $noreg, killed $r4, killed $r5, killed $r6, killed $r7, killed $r8, killed $r9, killed $r10, killed $r11, killed $lr
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 36
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r11, -8
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r10, -12
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r9, -16
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r8, -20
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -24
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -28
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -32
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -36
|
|
|
|
; CHECK-NEXT: $sp = frame-setup tSUBspi $sp, 5, 14, $noreg
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 56
|
|
|
|
; CHECK-NEXT: $r0 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r1 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r2 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r3 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r4 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r5 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r6 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r7 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r8 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r9 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r10 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r11 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r12 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $lr = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: t2STRi12 killed $r0, $sp, 0, 14, $noreg :: (store 4 into %stack.1)
|
|
|
|
; CHECK-NEXT: $r0 = tMOVr killed $sp, 14, $noreg
|
|
|
|
; CHECK-NEXT: renamable $q2 = MVE_VLDRBU32 killed $r0, 16, 0, $noreg :: (load 4 from %stack.0 + 12)
|
|
|
|
; CHECK-NEXT: $r0 = t2LDRi12 $sp, 0, 14, $noreg :: (load 4 from %stack.1)
|
|
|
|
; CHECK-NEXT: KILL $r0
|
|
|
|
; CHECK-NEXT: KILL $r1
|
|
|
|
; CHECK-NEXT: KILL $r2
|
|
|
|
; CHECK-NEXT: KILL $r3
|
|
|
|
; CHECK-NEXT: KILL $r4
|
|
|
|
; CHECK-NEXT: KILL $r5
|
|
|
|
; CHECK-NEXT: KILL $r6
|
|
|
|
; CHECK-NEXT: KILL $r7
|
|
|
|
; CHECK-NEXT: KILL $r8
|
|
|
|
; CHECK-NEXT: KILL $r9
|
|
|
|
; CHECK-NEXT: KILL $r10
|
|
|
|
; CHECK-NEXT: KILL $r11
|
|
|
|
; CHECK-NEXT: KILL $r12
|
|
|
|
; CHECK-NEXT: KILL $lr
|
2019-09-17 14:58:51 +02:00
|
|
|
$r0 = IMPLICIT_DEF
|
|
|
|
$r1 = IMPLICIT_DEF
|
|
|
|
$r2 = IMPLICIT_DEF
|
|
|
|
$r3 = IMPLICIT_DEF
|
|
|
|
$r4 = IMPLICIT_DEF
|
|
|
|
$r5 = IMPLICIT_DEF
|
|
|
|
$r6 = IMPLICIT_DEF
|
|
|
|
$r7 = IMPLICIT_DEF
|
|
|
|
$r8 = IMPLICIT_DEF
|
|
|
|
$r9 = IMPLICIT_DEF
|
|
|
|
$r10 = IMPLICIT_DEF
|
|
|
|
$r11 = IMPLICIT_DEF
|
|
|
|
$r12 = IMPLICIT_DEF
|
|
|
|
$lr = IMPLICIT_DEF
|
|
|
|
|
|
|
|
renamable $q2 = MVE_VLDRBU32 %stack.0, 12, 0, $noreg :: (load 4 from %stack.0 + 12)
|
|
|
|
|
|
|
|
KILL $r0
|
|
|
|
KILL $r1
|
|
|
|
KILL $r2
|
|
|
|
KILL $r3
|
|
|
|
KILL $r4
|
|
|
|
KILL $r5
|
|
|
|
KILL $r6
|
|
|
|
KILL $r7
|
|
|
|
KILL $r8
|
|
|
|
KILL $r9
|
|
|
|
KILL $r10
|
|
|
|
KILL $r11
|
|
|
|
KILL $r12
|
|
|
|
KILL $lr
|
|
|
|
...
|
|
|
|
---
|
|
|
|
name: func1
|
|
|
|
tracksRegLiveness: true
|
|
|
|
stack:
|
|
|
|
- { id: 0, name: '', type: default, offset: 0, size: 16, alignment: 4,
|
|
|
|
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
|
|
|
local-offset: -1200, debug-info-variable: '', debug-info-expression: '',
|
|
|
|
debug-info-location: '' }
|
|
|
|
- { id: 1, name: '', type: default, offset: 0, size: 1200, alignment: 4,
|
|
|
|
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
|
|
|
|
local-offset: -1200, debug-info-variable: '', debug-info-expression: '',
|
|
|
|
debug-info-location: '' }
|
|
|
|
body: |
|
|
|
|
bb.0:
|
|
|
|
; CHECK-LABEL: name: func1
|
|
|
|
; CHECK: liveins: $r4, $r5, $r6, $r7, $r8, $r9, $r10, $r11, $lr
|
2019-12-11 15:24:40 +01:00
|
|
|
; CHECK-NEXT: {{ }}
|
|
|
|
; CHECK-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14, $noreg, killed $r4, killed $r5, killed $r6, killed $r7, killed $r8, killed $r9, killed $r10, killed $r11, killed $lr
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 36
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r11, -8
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r10, -12
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r9, -16
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r8, -20
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -24
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r6, -28
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r5, -32
|
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r4, -36
|
[ARM][Thumb2] Fix ADD/SUB invalid writes to SP
Summary:
This patch fixes pr23772 [ARM] r226200 can emit illegal thumb2 instruction: "sub sp, r12, #80".
The violation was that SUB and ADD (reg, immediate) instructions can only write to SP if the source register is also SP. So the above instructions was unpredictable.
To enforce that the instruction t2(ADD|SUB)ri does not write to SP we now enforce the destination register to be rGPR (That exclude PC and SP).
Different than the ARM specification, that defines one instruction that can read from SP, and one that can't, here we inserted one that can't write to SP, and other that can only write to SP as to reuse most of the hard-coded size optimizations.
When performing this change, it uncovered that emitting Thumb2 Reg plus Immediate could not emit all variants of ADD SP, SP #imm instructions before so it was refactored to be able to. (see test/CodeGen/Thumb2/mve-stacksplot.mir where we use a subw sp, sp, Imm12 variant )
It also uncovered a disassembly issue of adr.w instructions, that were only written as SUBW instructions (see llvm/test/MC/Disassembler/ARM/thumb2.txt).
Reviewers: eli.friedman, dmgreen, carwil, olista01, efriedma, andreadb
Reviewed By: efriedma
Subscribers: gbedwell, john.brawn, efriedma, ostannard, kristof.beyls, hiraditya, dmgreen, llvm-commits
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D70680
2020-01-13 12:36:02 +01:00
|
|
|
; CHECK-NEXT: $sp = frame-setup t2SUBspImm12 killed $sp, 1220, 14, $noreg
|
2019-12-11 15:24:40 +01:00
|
|
|
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 1256
|
|
|
|
; CHECK-NEXT: $r0 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r1 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r2 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r3 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r4 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r5 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r6 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r7 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r8 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r9 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r10 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r11 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $r12 = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: $lr = IMPLICIT_DEF
|
|
|
|
; CHECK-NEXT: t2STRi12 killed $r0, $sp, 0, 14, $noreg :: (store 4 into %stack.2)
|
|
|
|
; CHECK-NEXT: $r0 = t2ADDri killed $sp, 1152, 14, $noreg, $noreg
|
|
|
|
; CHECK-NEXT: renamable $q2 = MVE_VLDRBU8 killed $r0, 52, 0, $noreg :: (load 4 from %stack.0)
|
|
|
|
; CHECK-NEXT: $r0 = t2LDRi12 $sp, 0, 14, $noreg :: (load 4 from %stack.2)
|
|
|
|
; CHECK-NEXT: KILL $r0
|
|
|
|
; CHECK-NEXT: KILL $r1
|
|
|
|
; CHECK-NEXT: KILL $r2
|
|
|
|
; CHECK-NEXT: KILL $r3
|
|
|
|
; CHECK-NEXT: KILL $r4
|
|
|
|
; CHECK-NEXT: KILL $r5
|
|
|
|
; CHECK-NEXT: KILL $r6
|
|
|
|
; CHECK-NEXT: KILL $r7
|
|
|
|
; CHECK-NEXT: KILL $r8
|
|
|
|
; CHECK-NEXT: KILL $r9
|
|
|
|
; CHECK-NEXT: KILL $r10
|
|
|
|
; CHECK-NEXT: KILL $r11
|
|
|
|
; CHECK-NEXT: KILL $r12
|
|
|
|
; CHECK-NEXT: KILL $lr
|
2019-09-17 14:58:51 +02:00
|
|
|
$r0 = IMPLICIT_DEF
|
|
|
|
$r1 = IMPLICIT_DEF
|
|
|
|
$r2 = IMPLICIT_DEF
|
|
|
|
$r3 = IMPLICIT_DEF
|
|
|
|
$r4 = IMPLICIT_DEF
|
|
|
|
$r5 = IMPLICIT_DEF
|
|
|
|
$r6 = IMPLICIT_DEF
|
|
|
|
$r7 = IMPLICIT_DEF
|
|
|
|
$r8 = IMPLICIT_DEF
|
|
|
|
$r9 = IMPLICIT_DEF
|
|
|
|
$r10 = IMPLICIT_DEF
|
|
|
|
$r11 = IMPLICIT_DEF
|
|
|
|
$r12 = IMPLICIT_DEF
|
|
|
|
$lr = IMPLICIT_DEF
|
|
|
|
|
|
|
|
renamable $q2 = MVE_VLDRBU8 %stack.0, 0, 0, $noreg :: (load 4 from %stack.0)
|
|
|
|
|
|
|
|
KILL $r0
|
|
|
|
KILL $r1
|
|
|
|
KILL $r2
|
|
|
|
KILL $r3
|
|
|
|
KILL $r4
|
|
|
|
KILL $r5
|
|
|
|
KILL $r6
|
|
|
|
KILL $r7
|
|
|
|
KILL $r8
|
|
|
|
KILL $r9
|
|
|
|
KILL $r10
|
|
|
|
KILL $r11
|
|
|
|
KILL $r12
|
|
|
|
KILL $lr
|
|
|
|
...
|