Skip to content

Commit a5ce8bd

Browse files
committed
[RISCV] Fix wrong CFI directives
Summary: Removes CFI CFA directives that could incorrectly propagate beyond the basic block they were inteded for. Specifically it removes the epilogue CFI directives. See the branch_and_tail_call test for an example of the issue. Should fix the stack unwinding issues caused by the incorrect directives. Reviewers: asb, lenary, shiva0217 Reviewed By: lenary Tags: #llvm Differential Revision: https://reviews.llvm.org/D69723
1 parent a12f588 commit a5ce8bd

File tree

6 files changed

+0
-158
lines changed

6 files changed

+0
-158
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -233,16 +233,13 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
233233
}
234234
}
235235

236-
// FIXME Fix emission of .cfi_restore and .cfi_def_cfa CFI directives that can
237-
// incorrectly affect subsequent basic blocks.
238236
void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
239237
MachineBasicBlock &MBB) const {
240238
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();
241239
const RISCVRegisterInfo *RI = STI.getRegisterInfo();
242240
MachineFrameInfo &MFI = MF.getFrameInfo();
243241
auto *RVFI = MF.getInfo<RISCVMachineFunctionInfo>();
244242
DebugLoc DL = MBBI->getDebugLoc();
245-
const RISCVInstrInfo *TII = STI.getInstrInfo();
246243
Register FPReg = getFPReg(STI);
247244
Register SPReg = getSPReg(STI);
248245

@@ -271,65 +268,13 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
271268

272269
adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount,
273270
MachineInstr::FrameDestroy);
274-
275-
// Emit ".cfi_def_cfa_offset FirstSPAdjustAmount" if using an sp-based CFA
276-
if (!hasFP(MF)) {
277-
unsigned CFIIndex = MF.addFrameInst(
278-
MCCFIInstruction::createDefCfaOffset(nullptr, -FirstSPAdjustAmount));
279-
BuildMI(MBB, LastFrameDestroy, DL,
280-
TII->get(TargetOpcode::CFI_INSTRUCTION))
281-
.addCFIIndex(CFIIndex);
282-
}
283-
}
284-
285-
if (hasFP(MF)) {
286-
// To find the instruction restoring FP from stack.
287-
for (auto &I = LastFrameDestroy; I != MBBI; ++I) {
288-
if (I->mayLoad() && I->getOperand(0).isReg()) {
289-
Register DestReg = I->getOperand(0).getReg();
290-
if (DestReg == FPReg) {
291-
// If there is frame pointer, after restoring $fp registers, we
292-
// need adjust CFA back to the correct sp-based offset.
293-
// Emit ".cfi_def_cfa $sp, CFAOffset"
294-
uint64_t CFAOffset =
295-
FirstSPAdjustAmount
296-
? -FirstSPAdjustAmount + RVFI->getVarArgsSaveSize()
297-
: -FPOffset;
298-
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
299-
nullptr, RI->getDwarfRegNum(SPReg, true), CFAOffset));
300-
BuildMI(MBB, std::next(I), DL,
301-
TII->get(TargetOpcode::CFI_INSTRUCTION))
302-
.addCFIIndex(CFIIndex);
303-
break;
304-
}
305-
}
306-
}
307-
}
308-
309-
// Add CFI directives for callee-saved registers.
310-
const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo();
311-
// Iterate over list of callee-saved registers and emit .cfi_restore
312-
// directives.
313-
for (const auto &Entry : CSI) {
314-
Register Reg = Entry.getReg();
315-
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(
316-
nullptr, RI->getDwarfRegNum(Reg, true)));
317-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
318-
.addCFIIndex(CFIIndex);
319271
}
320272

321273
if (FirstSPAdjustAmount)
322274
StackSize = FirstSPAdjustAmount;
323275

324276
// Deallocate stack
325277
adjustReg(MBB, MBBI, DL, SPReg, SPReg, StackSize, MachineInstr::FrameDestroy);
326-
327-
// After restoring $sp, we need to adjust CFA to $(sp + 0)
328-
// Emit ".cfi_def_cfa_offset 0"
329-
unsigned CFIIndex =
330-
MF.addFrameInst(MCCFIInstruction::createDefCfaOffset(nullptr, 0));
331-
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
332-
.addCFIIndex(CFIIndex);
333278
}
334279

335280
int RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF,

llvm/test/CodeGen/RISCV/exception-pointer-register.ll

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,7 @@ define void @caller(i1* %p) personality i8* bitcast (i32 (...)* @__gxx_personali
4040
; RV32I-NEXT: lw s1, 4(sp)
4141
; RV32I-NEXT: lw s0, 8(sp)
4242
; RV32I-NEXT: lw ra, 12(sp)
43-
; RV32I-NEXT: .cfi_restore ra
44-
; RV32I-NEXT: .cfi_restore s0
45-
; RV32I-NEXT: .cfi_restore s1
4643
; RV32I-NEXT: addi sp, sp, 16
47-
; RV32I-NEXT: .cfi_def_cfa_offset 0
4844
; RV32I-NEXT: ret
4945
; RV32I-NEXT: .LBB0_4: # %lpad
5046
; RV32I-NEXT: .Ltmp4:
@@ -81,11 +77,7 @@ define void @caller(i1* %p) personality i8* bitcast (i32 (...)* @__gxx_personali
8177
; RV64I-NEXT: ld s1, 8(sp)
8278
; RV64I-NEXT: ld s0, 16(sp)
8379
; RV64I-NEXT: ld ra, 24(sp)
84-
; RV64I-NEXT: .cfi_restore ra
85-
; RV64I-NEXT: .cfi_restore s0
86-
; RV64I-NEXT: .cfi_restore s1
8780
; RV64I-NEXT: addi sp, sp, 32
88-
; RV64I-NEXT: .cfi_def_cfa_offset 0
8981
; RV64I-NEXT: ret
9082
; RV64I-NEXT: .LBB0_4: # %lpad
9183
; RV64I-NEXT: .Ltmp4:
@@ -119,12 +111,10 @@ end2:
119111
define internal void @callee(i1* %p) {
120112
; RV32I-LABEL: callee:
121113
; RV32I: # %bb.0:
122-
; RV32I-NEXT: .cfi_def_cfa_offset 0
123114
; RV32I-NEXT: ret
124115
;
125116
; RV64I-LABEL: callee:
126117
; RV64I: # %bb.0:
127-
; RV64I-NEXT: .cfi_def_cfa_offset 0
128118
; RV64I-NEXT: ret
129119
ret void
130120
}

llvm/test/CodeGen/RISCV/frame-info.ll

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@
99
define void @trivial() {
1010
; RV32-LABEL: trivial:
1111
; RV32: # %bb.0:
12-
; RV32-NEXT: .cfi_def_cfa_offset 0
1312
; RV32-NEXT: ret
1413
;
1514
; RV64-LABEL: trivial:
1615
; RV64: # %bb.0:
17-
; RV64-NEXT: .cfi_def_cfa_offset 0
1816
; RV64-NEXT: ret
1917
;
2018
; RV32-WITHFP-LABEL: trivial:
@@ -28,12 +26,8 @@ define void @trivial() {
2826
; RV32-WITHFP-NEXT: addi s0, sp, 16
2927
; RV32-WITHFP-NEXT: .cfi_def_cfa s0, 0
3028
; RV32-WITHFP-NEXT: lw s0, 8(sp)
31-
; RV32-WITHFP-NEXT: .cfi_def_cfa sp, 16
3229
; RV32-WITHFP-NEXT: lw ra, 12(sp)
33-
; RV32-WITHFP-NEXT: .cfi_restore ra
34-
; RV32-WITHFP-NEXT: .cfi_restore s0
3530
; RV32-WITHFP-NEXT: addi sp, sp, 16
36-
; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
3731
; RV32-WITHFP-NEXT: ret
3832
;
3933
; RV64-WITHFP-LABEL: trivial:
@@ -47,12 +41,8 @@ define void @trivial() {
4741
; RV64-WITHFP-NEXT: addi s0, sp, 16
4842
; RV64-WITHFP-NEXT: .cfi_def_cfa s0, 0
4943
; RV64-WITHFP-NEXT: ld s0, 0(sp)
50-
; RV64-WITHFP-NEXT: .cfi_def_cfa sp, 16
5144
; RV64-WITHFP-NEXT: ld ra, 8(sp)
52-
; RV64-WITHFP-NEXT: .cfi_restore ra
53-
; RV64-WITHFP-NEXT: .cfi_restore s0
5445
; RV64-WITHFP-NEXT: addi sp, sp, 16
55-
; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
5646
; RV64-WITHFP-NEXT: ret
5747
ret void
5848
}
@@ -75,12 +65,8 @@ define void @stack_alloc(i32 signext %size) {
7565
; RV32-NEXT: call callee_with_args
7666
; RV32-NEXT: addi sp, s0, -16
7767
; RV32-NEXT: lw s0, 8(sp)
78-
; RV32-NEXT: .cfi_def_cfa sp, 16
7968
; RV32-NEXT: lw ra, 12(sp)
80-
; RV32-NEXT: .cfi_restore ra
81-
; RV32-NEXT: .cfi_restore s0
8269
; RV32-NEXT: addi sp, sp, 16
83-
; RV32-NEXT: .cfi_def_cfa_offset 0
8470
; RV32-NEXT: ret
8571
;
8672
; RV64-LABEL: stack_alloc:
@@ -105,12 +91,8 @@ define void @stack_alloc(i32 signext %size) {
10591
; RV64-NEXT: call callee_with_args
10692
; RV64-NEXT: addi sp, s0, -16
10793
; RV64-NEXT: ld s0, 0(sp)
108-
; RV64-NEXT: .cfi_def_cfa sp, 16
10994
; RV64-NEXT: ld ra, 8(sp)
110-
; RV64-NEXT: .cfi_restore ra
111-
; RV64-NEXT: .cfi_restore s0
11295
; RV64-NEXT: addi sp, sp, 16
113-
; RV64-NEXT: .cfi_def_cfa_offset 0
11496
; RV64-NEXT: ret
11597
;
11698
; RV32-WITHFP-LABEL: stack_alloc:
@@ -130,12 +112,8 @@ define void @stack_alloc(i32 signext %size) {
130112
; RV32-WITHFP-NEXT: call callee_with_args
131113
; RV32-WITHFP-NEXT: addi sp, s0, -16
132114
; RV32-WITHFP-NEXT: lw s0, 8(sp)
133-
; RV32-WITHFP-NEXT: .cfi_def_cfa sp, 16
134115
; RV32-WITHFP-NEXT: lw ra, 12(sp)
135-
; RV32-WITHFP-NEXT: .cfi_restore ra
136-
; RV32-WITHFP-NEXT: .cfi_restore s0
137116
; RV32-WITHFP-NEXT: addi sp, sp, 16
138-
; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
139117
; RV32-WITHFP-NEXT: ret
140118
;
141119
; RV64-WITHFP-LABEL: stack_alloc:
@@ -160,21 +138,15 @@ define void @stack_alloc(i32 signext %size) {
160138
; RV64-WITHFP-NEXT: call callee_with_args
161139
; RV64-WITHFP-NEXT: addi sp, s0, -16
162140
; RV64-WITHFP-NEXT: ld s0, 0(sp)
163-
; RV64-WITHFP-NEXT: .cfi_def_cfa sp, 16
164141
; RV64-WITHFP-NEXT: ld ra, 8(sp)
165-
; RV64-WITHFP-NEXT: .cfi_restore ra
166-
; RV64-WITHFP-NEXT: .cfi_restore s0
167142
; RV64-WITHFP-NEXT: addi sp, sp, 16
168-
; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
169143
; RV64-WITHFP-NEXT: ret
170144
entry:
171145
%0 = alloca i8, i32 %size, align 16
172146
call void @callee_with_args(i8* nonnull %0) #2
173147
ret void
174148
}
175149

176-
; FIXME: fix use of .cfi_restore with wrong CFAs
177-
178150
define void @branch_and_tail_call(i1 %a) {
179151
; RV32-LABEL: branch_and_tail_call:
180152
; RV32: # %bb.0:
@@ -186,16 +158,12 @@ define void @branch_and_tail_call(i1 %a) {
186158
; RV32-NEXT: beqz a0, .LBB2_2
187159
; RV32-NEXT: # %bb.1: # %blue_pill
188160
; RV32-NEXT: lw ra, 12(sp)
189-
; RV32-NEXT: .cfi_restore ra
190161
; RV32-NEXT: addi sp, sp, 16
191-
; RV32-NEXT: .cfi_def_cfa_offset 0
192162
; RV32-NEXT: tail callee1
193163
; RV32-NEXT: .LBB2_2: # %red_pill
194164
; RV32-NEXT: call callee2
195165
; RV32-NEXT: lw ra, 12(sp)
196-
; RV32-NEXT: .cfi_restore ra
197166
; RV32-NEXT: addi sp, sp, 16
198-
; RV32-NEXT: .cfi_def_cfa_offset 0
199167
; RV32-NEXT: ret
200168
;
201169
; RV64-LABEL: branch_and_tail_call:
@@ -208,16 +176,12 @@ define void @branch_and_tail_call(i1 %a) {
208176
; RV64-NEXT: beqz a0, .LBB2_2
209177
; RV64-NEXT: # %bb.1: # %blue_pill
210178
; RV64-NEXT: ld ra, 8(sp)
211-
; RV64-NEXT: .cfi_restore ra
212179
; RV64-NEXT: addi sp, sp, 16
213-
; RV64-NEXT: .cfi_def_cfa_offset 0
214180
; RV64-NEXT: tail callee1
215181
; RV64-NEXT: .LBB2_2: # %red_pill
216182
; RV64-NEXT: call callee2
217183
; RV64-NEXT: ld ra, 8(sp)
218-
; RV64-NEXT: .cfi_restore ra
219184
; RV64-NEXT: addi sp, sp, 16
220-
; RV64-NEXT: .cfi_def_cfa_offset 0
221185
; RV64-NEXT: ret
222186
;
223187
; RV32-WITHFP-LABEL: branch_and_tail_call:
@@ -234,22 +198,14 @@ define void @branch_and_tail_call(i1 %a) {
234198
; RV32-WITHFP-NEXT: beqz a0, .LBB2_2
235199
; RV32-WITHFP-NEXT: # %bb.1: # %blue_pill
236200
; RV32-WITHFP-NEXT: lw s0, 8(sp)
237-
; RV32-WITHFP-NEXT: .cfi_def_cfa sp, 16
238201
; RV32-WITHFP-NEXT: lw ra, 12(sp)
239-
; RV32-WITHFP-NEXT: .cfi_restore ra
240-
; RV32-WITHFP-NEXT: .cfi_restore s0
241202
; RV32-WITHFP-NEXT: addi sp, sp, 16
242-
; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
243203
; RV32-WITHFP-NEXT: tail callee1
244204
; RV32-WITHFP-NEXT: .LBB2_2: # %red_pill
245205
; RV32-WITHFP-NEXT: call callee2
246206
; RV32-WITHFP-NEXT: lw s0, 8(sp)
247-
; RV32-WITHFP-NEXT: .cfi_def_cfa sp, 16
248207
; RV32-WITHFP-NEXT: lw ra, 12(sp)
249-
; RV32-WITHFP-NEXT: .cfi_restore ra
250-
; RV32-WITHFP-NEXT: .cfi_restore s0
251208
; RV32-WITHFP-NEXT: addi sp, sp, 16
252-
; RV32-WITHFP-NEXT: .cfi_def_cfa_offset 0
253209
; RV32-WITHFP-NEXT: ret
254210
;
255211
; RV64-WITHFP-LABEL: branch_and_tail_call:
@@ -266,22 +222,14 @@ define void @branch_and_tail_call(i1 %a) {
266222
; RV64-WITHFP-NEXT: beqz a0, .LBB2_2
267223
; RV64-WITHFP-NEXT: # %bb.1: # %blue_pill
268224
; RV64-WITHFP-NEXT: ld s0, 0(sp)
269-
; RV64-WITHFP-NEXT: .cfi_def_cfa sp, 16
270225
; RV64-WITHFP-NEXT: ld ra, 8(sp)
271-
; RV64-WITHFP-NEXT: .cfi_restore ra
272-
; RV64-WITHFP-NEXT: .cfi_restore s0
273226
; RV64-WITHFP-NEXT: addi sp, sp, 16
274-
; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
275227
; RV64-WITHFP-NEXT: tail callee1
276228
; RV64-WITHFP-NEXT: .LBB2_2: # %red_pill
277229
; RV64-WITHFP-NEXT: call callee2
278230
; RV64-WITHFP-NEXT: ld s0, 0(sp)
279-
; RV64-WITHFP-NEXT: .cfi_def_cfa sp, 16
280231
; RV64-WITHFP-NEXT: ld ra, 8(sp)
281-
; RV64-WITHFP-NEXT: .cfi_restore ra
282-
; RV64-WITHFP-NEXT: .cfi_restore s0
283232
; RV64-WITHFP-NEXT: addi sp, sp, 16
284-
; RV64-WITHFP-NEXT: .cfi_def_cfa_offset 0
285233
; RV64-WITHFP-NEXT: ret
286234
br i1 %a, label %blue_pill, label %red_pill
287235
blue_pill:

llvm/test/CodeGen/RISCV/large-stack.ll

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ define void @test() {
1616
; RV32I-FPELIM-NEXT: lui a0, 74565
1717
; RV32I-FPELIM-NEXT: addi a0, a0, 1664
1818
; RV32I-FPELIM-NEXT: add sp, sp, a0
19-
; RV32I-FPELIM-NEXT: .cfi_def_cfa_offset 0
2019
; RV32I-FPELIM-NEXT: ret
2120
;
2221
; RV32I-WITHFP-LABEL: test:
@@ -36,12 +35,8 @@ define void @test() {
3635
; RV32I-WITHFP-NEXT: addi a0, a0, -352
3736
; RV32I-WITHFP-NEXT: add sp, sp, a0
3837
; RV32I-WITHFP-NEXT: lw s0, 2024(sp)
39-
; RV32I-WITHFP-NEXT: .cfi_def_cfa sp, 2032
4038
; RV32I-WITHFP-NEXT: lw ra, 2028(sp)
41-
; RV32I-WITHFP-NEXT: .cfi_restore ra
42-
; RV32I-WITHFP-NEXT: .cfi_restore s0
4339
; RV32I-WITHFP-NEXT: addi sp, sp, 2032
44-
; RV32I-WITHFP-NEXT: .cfi_def_cfa_offset 0
4540
; RV32I-WITHFP-NEXT: ret
4641
%tmp = alloca [ 305419896 x i8 ] , align 4
4742
ret void
@@ -77,13 +72,9 @@ define void @test_emergency_spill_slot(i32 %a) {
7772
; RV32I-FPELIM-NEXT: lui a0, 97
7873
; RV32I-FPELIM-NEXT: addi a0, a0, 672
7974
; RV32I-FPELIM-NEXT: add sp, sp, a0
80-
; RV32I-FPELIM-NEXT: .cfi_def_cfa_offset 2032
8175
; RV32I-FPELIM-NEXT: lw s1, 2024(sp)
8276
; RV32I-FPELIM-NEXT: lw s0, 2028(sp)
83-
; RV32I-FPELIM-NEXT: .cfi_restore s0
84-
; RV32I-FPELIM-NEXT: .cfi_restore s1
8577
; RV32I-FPELIM-NEXT: addi sp, sp, 2032
86-
; RV32I-FPELIM-NEXT: .cfi_def_cfa_offset 0
8778
; RV32I-FPELIM-NEXT: ret
8879
;
8980
; RV32I-WITHFP-LABEL: test_emergency_spill_slot:
@@ -123,14 +114,8 @@ define void @test_emergency_spill_slot(i32 %a) {
123114
; RV32I-WITHFP-NEXT: lw s2, 2016(sp)
124115
; RV32I-WITHFP-NEXT: lw s1, 2020(sp)
125116
; RV32I-WITHFP-NEXT: lw s0, 2024(sp)
126-
; RV32I-WITHFP-NEXT: .cfi_def_cfa sp, 2032
127117
; RV32I-WITHFP-NEXT: lw ra, 2028(sp)
128-
; RV32I-WITHFP-NEXT: .cfi_restore ra
129-
; RV32I-WITHFP-NEXT: .cfi_restore s0
130-
; RV32I-WITHFP-NEXT: .cfi_restore s1
131-
; RV32I-WITHFP-NEXT: .cfi_restore s2
132118
; RV32I-WITHFP-NEXT: addi sp, sp, 2032
133-
; RV32I-WITHFP-NEXT: .cfi_def_cfa_offset 0
134119
; RV32I-WITHFP-NEXT: ret
135120
%data = alloca [ 100000 x i32 ] , align 4
136121
%ptr = getelementptr inbounds [100000 x i32], [100000 x i32]* %data, i32 0, i32 80000

llvm/test/CodeGen/RISCV/split-offsets.ll

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ define void @test1([65536 x i32]** %sp, [65536 x i32]* %t, i32 %n) {
2222
; RV32I-NEXT: sw a3, 4(a0)
2323
; RV32I-NEXT: sw a3, 0(a1)
2424
; RV32I-NEXT: sw a2, 4(a1)
25-
; RV32I-NEXT: .cfi_def_cfa_offset 0
2625
; RV32I-NEXT: ret
2726
;
2827
; RV64I-LABEL: test1:
@@ -38,7 +37,6 @@ define void @test1([65536 x i32]** %sp, [65536 x i32]* %t, i32 %n) {
3837
; RV64I-NEXT: sw a3, 4(a0)
3938
; RV64I-NEXT: sw a3, 0(a1)
4039
; RV64I-NEXT: sw a2, 4(a1)
41-
; RV64I-NEXT: .cfi_def_cfa_offset 0
4240
; RV64I-NEXT: ret
4341
entry:
4442
%s = load [65536 x i32]*, [65536 x i32]** %sp
@@ -74,7 +72,6 @@ define void @test2([65536 x i32]** %sp, [65536 x i32]* %t, i32 %n) {
7472
; RV32I-NEXT: mv a3, a4
7573
; RV32I-NEXT: blt a3, a2, .LBB1_1
7674
; RV32I-NEXT: .LBB1_2: # %while_end
77-
; RV32I-NEXT: .cfi_def_cfa_offset 0
7875
; RV32I-NEXT: ret
7976
;
8077
; RV64I-LABEL: test2:
@@ -99,7 +96,6 @@ define void @test2([65536 x i32]** %sp, [65536 x i32]* %t, i32 %n) {
9996
; RV64I-NEXT: sext.w a4, a3
10097
; RV64I-NEXT: blt a4, a2, .LBB1_1
10198
; RV64I-NEXT: .LBB1_2: # %while_end
102-
; RV64I-NEXT: .cfi_def_cfa_offset 0
10399
; RV64I-NEXT: ret
104100
entry:
105101
%s = load [65536 x i32]*, [65536 x i32]** %sp

0 commit comments

Comments
 (0)