Skip to content

Commit 26f6fbe

Browse files
committed
[ARM] Add AddrModeT2_i8neg addressing mode support for frame lowering.
As reported from a failing firefox build, we can sometimes get frame indices with negative offsets from a t2LDRi8. This adds support for them, to prevent the crash.
1 parent 81eece7 commit 26f6fbe

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,8 @@ getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {
530530
unsigned ImmIdx = 0;
531531
switch (AddrMode) {
532532
case ARMII::AddrModeT2_i8:
533+
case ARMII::AddrModeT2_i8neg:
534+
case ARMII::AddrModeT2_i8pos:
533535
case ARMII::AddrModeT2_i12:
534536
case ARMII::AddrMode_i12:
535537
InstrOffs = MI->getOperand(Idx+1).getImm();
@@ -728,6 +730,8 @@ bool ARMBaseRegisterInfo::isFrameOffsetLegal(const MachineInstr *MI,
728730
bool isSigned = true;
729731
switch (AddrMode) {
730732
case ARMII::AddrModeT2_i8:
733+
case ARMII::AddrModeT2_i8pos:
734+
case ARMII::AddrModeT2_i8neg:
731735
case ARMII::AddrModeT2_i12:
732736
// i8 supports only negative, and i12 supports only positive, so
733737
// based on Offset sign, consider the appropriate instruction
Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
2+
# RUN: llc -run-pass=prologepilog %s -o - | FileCheck %s
3+
4+
--- |
5+
target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
6+
target triple = "thumbv7m-none-eabi"
7+
8+
define i32 @testpos() {
9+
entry:
10+
%a = alloca i32, align 4
11+
call void @other(i32* %a)
12+
%b = load i32, i32* %a, align 4
13+
ret i32 %b
14+
}
15+
define i32 @testneg4() {
16+
entry:
17+
%a = alloca i32, align 4
18+
call void @other(i32* %a)
19+
%b = load i32, i32* %a, align 4
20+
ret i32 %b
21+
}
22+
define i32 @testneg8() {
23+
entry:
24+
%a = alloca i32, align 4
25+
call void @other(i32* %a)
26+
%b = load i32, i32* %a, align 4
27+
ret i32 %b
28+
}
29+
30+
declare void @other(i32*)
31+
32+
...
33+
---
34+
name: testpos
35+
tracksRegLiveness: true
36+
frameInfo:
37+
isFrameAddressTaken: false
38+
isReturnAddressTaken: false
39+
hasStackMap: false
40+
hasPatchPoint: false
41+
stackSize: 0
42+
offsetAdjustment: 0
43+
maxAlignment: 4
44+
adjustsStack: true
45+
hasCalls: true
46+
stackProtector: ''
47+
maxCallFrameSize: 0
48+
cvBytesOfCalleeSavedRegisters: 0
49+
hasOpaqueSPAdjustment: false
50+
hasVAStart: false
51+
hasMustTailInVarArgFunc: false
52+
hasTailCall: false
53+
localFrameSize: 4
54+
savePoint: ''
55+
restorePoint: ''
56+
stack:
57+
- { id: 0, name: a, type: default, offset: 0, size: 4, alignment: 4,
58+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
59+
local-offset: -4, debug-info-variable: '', debug-info-expression: '',
60+
debug-info-location: '' }
61+
body: |
62+
bb.0.entry:
63+
; CHECK-LABEL: name: testpos
64+
; CHECK: liveins: $r7, $lr
65+
; CHECK-NEXT: {{ $}}
66+
; CHECK-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r7, killed $lr
67+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
68+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
69+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -8
70+
; CHECK-NEXT: $sp = frame-setup tSUBspi $sp, 2, 14 /* CC::al */, $noreg
71+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
72+
; CHECK-NEXT: renamable $r0 = t2ADDri $sp, 4, 14 /* CC::al */, $noreg, $noreg
73+
; CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @other, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp
74+
; CHECK-NEXT: renamable $r0 = t2LDRi12 $sp, 8, 14 /* CC::al */, $noreg :: (dereferenceable load (s32) from %ir.a)
75+
; CHECK-NEXT: $sp = frame-destroy tADDspi $sp, 2, 14 /* CC::al */, $noreg
76+
; CHECK-NEXT: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc, implicit $r0
77+
ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
78+
renamable $r0 = t2ADDri %stack.0.a, 0, 14 /* CC::al */, $noreg, $noreg
79+
tBL 14 /* CC::al */, $noreg, @other, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp
80+
ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
81+
renamable $r0 = t2LDRi12 %stack.0.a, 4, 14 /* CC::al */, $noreg :: (dereferenceable load (s32) from %ir.a)
82+
tBX_RET 14 /* CC::al */, $noreg, implicit $r0
83+
84+
...
85+
---
86+
name: testneg4
87+
tracksRegLiveness: true
88+
frameInfo:
89+
isFrameAddressTaken: false
90+
isReturnAddressTaken: false
91+
hasStackMap: false
92+
hasPatchPoint: false
93+
stackSize: 0
94+
offsetAdjustment: 0
95+
maxAlignment: 4
96+
adjustsStack: true
97+
hasCalls: true
98+
stackProtector: ''
99+
maxCallFrameSize: 0
100+
cvBytesOfCalleeSavedRegisters: 0
101+
hasOpaqueSPAdjustment: false
102+
hasVAStart: false
103+
hasMustTailInVarArgFunc: false
104+
hasTailCall: false
105+
localFrameSize: 4
106+
savePoint: ''
107+
restorePoint: ''
108+
stack:
109+
- { id: 0, name: a, type: default, offset: 0, size: 4, alignment: 4,
110+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
111+
local-offset: -4, debug-info-variable: '', debug-info-expression: '',
112+
debug-info-location: '' }
113+
body: |
114+
bb.0.entry:
115+
; CHECK-LABEL: name: testneg4
116+
; CHECK: liveins: $r7, $lr
117+
; CHECK-NEXT: {{ $}}
118+
; CHECK-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r7, killed $lr
119+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
120+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
121+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -8
122+
; CHECK-NEXT: $sp = frame-setup tSUBspi $sp, 2, 14 /* CC::al */, $noreg
123+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
124+
; CHECK-NEXT: renamable $r0 = t2ADDri $sp, 4, 14 /* CC::al */, $noreg, $noreg
125+
; CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @other, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp
126+
; CHECK-NEXT: renamable $r0 = t2LDRi12 $sp, 0, 14 /* CC::al */, $noreg :: (dereferenceable load (s32) from %ir.a)
127+
; CHECK-NEXT: $sp = frame-destroy tADDspi $sp, 2, 14 /* CC::al */, $noreg
128+
; CHECK-NEXT: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc, implicit $r0
129+
ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
130+
renamable $r0 = t2ADDri %stack.0.a, 0, 14 /* CC::al */, $noreg, $noreg
131+
tBL 14 /* CC::al */, $noreg, @other, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp
132+
ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
133+
renamable $r0 = t2LDRi8 %stack.0.a, -4, 14 /* CC::al */, $noreg :: (dereferenceable load (s32) from %ir.a)
134+
tBX_RET 14 /* CC::al */, $noreg, implicit $r0
135+
136+
...
137+
---
138+
name: testneg8
139+
tracksRegLiveness: true
140+
frameInfo:
141+
isFrameAddressTaken: false
142+
isReturnAddressTaken: false
143+
hasStackMap: false
144+
hasPatchPoint: false
145+
stackSize: 0
146+
offsetAdjustment: 0
147+
maxAlignment: 4
148+
adjustsStack: true
149+
hasCalls: true
150+
stackProtector: ''
151+
maxCallFrameSize: 0
152+
cvBytesOfCalleeSavedRegisters: 0
153+
hasOpaqueSPAdjustment: false
154+
hasVAStart: false
155+
hasMustTailInVarArgFunc: false
156+
hasTailCall: false
157+
localFrameSize: 4
158+
savePoint: ''
159+
restorePoint: ''
160+
stack:
161+
- { id: 0, name: a, type: default, offset: 0, size: 4, alignment: 4,
162+
stack-id: default, callee-saved-register: '', callee-saved-restored: true,
163+
local-offset: -4, debug-info-variable: '', debug-info-expression: '',
164+
debug-info-location: '' }
165+
body: |
166+
bb.0.entry:
167+
; CHECK-LABEL: name: testneg8
168+
; CHECK: liveins: $r7, $lr
169+
; CHECK-NEXT: {{ $}}
170+
; CHECK-NEXT: $sp = frame-setup t2STMDB_UPD $sp, 14 /* CC::al */, $noreg, killed $r7, killed $lr
171+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 8
172+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $lr, -4
173+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION offset $r7, -8
174+
; CHECK-NEXT: $sp = frame-setup tSUBspi $sp, 2, 14 /* CC::al */, $noreg
175+
; CHECK-NEXT: frame-setup CFI_INSTRUCTION def_cfa_offset 16
176+
; CHECK-NEXT: renamable $r0 = t2ADDri $sp, 4, 14 /* CC::al */, $noreg, $noreg
177+
; CHECK-NEXT: tBL 14 /* CC::al */, $noreg, @other, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp
178+
; CHECK-NEXT: renamable $r0 = t2LDRi8 $sp, -4, 14 /* CC::al */, $noreg :: (dereferenceable load (s32) from %ir.a)
179+
; CHECK-NEXT: $sp = frame-destroy tADDspi $sp, 2, 14 /* CC::al */, $noreg
180+
; CHECK-NEXT: $sp = frame-destroy t2LDMIA_RET $sp, 14 /* CC::al */, $noreg, def $r7, def $pc, implicit $r0
181+
ADJCALLSTACKDOWN 0, 0, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
182+
renamable $r0 = t2ADDri %stack.0.a, 0, 14 /* CC::al */, $noreg, $noreg
183+
tBL 14 /* CC::al */, $noreg, @other, csr_aapcs, implicit-def dead $lr, implicit $sp, implicit $r0, implicit-def $sp
184+
ADJCALLSTACKUP 0, -1, 14 /* CC::al */, $noreg, implicit-def dead $sp, implicit $sp
185+
renamable $r0 = t2LDRi8 %stack.0.a, -8, 14 /* CC::al */, $noreg :: (dereferenceable load (s32) from %ir.a)
186+
tBX_RET 14 /* CC::al */, $noreg, implicit $r0
187+
188+
...
189+

0 commit comments

Comments
 (0)