Skip to content

Commit 7c70e50

Browse files
authored
[RISCV] Fix wrong offset use caused by missing the size of Zcmp push. (#66613)
This fixes two wrong offset uses, 1. .cfi_offset of callee saves are not pushed by cm.push. 2. Reference of frame objests by frame pointer.
1 parent 4c59f80 commit 7c70e50

File tree

4 files changed

+175
-12
lines changed

4 files changed

+175
-12
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -506,8 +506,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
506506
// FIXME (note copied from Lanai): This appears to be overallocating. Needs
507507
// investigation. Get the number of bytes to allocate from the FrameInfo.
508508
uint64_t StackSize = getStackSizeWithRVVPadding(MF);
509-
uint64_t RealStackSize =
510-
StackSize + RVFI->getLibCallStackSize() + RVFI->getRVPushStackSize();
509+
uint64_t RealStackSize = StackSize + RVFI->getReservedSpillsSize();
511510
uint64_t RVVStackSize = RVFI->getRVVStackSize();
512511

513512
// Early exit if there is no need to allocate on the stack
@@ -575,8 +574,7 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
575574
Offset = FrameIdx * (int64_t)STI.getXLen() / 8;
576575
}
577576
} else {
578-
Offset = MFI.getObjectOffset(FrameIdx) -
579-
RVFI->getLibCallStackSize();
577+
Offset = MFI.getObjectOffset(FrameIdx) - RVFI->getReservedSpillsSize();
580578
}
581579
Register Reg = Entry.getReg();
582580
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
@@ -721,8 +719,7 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
721719
LastFrameDestroy = std::prev(MBBI, CSI.size());
722720

723721
uint64_t StackSize = getStackSizeWithRVVPadding(MF);
724-
uint64_t RealStackSize =
725-
StackSize + RVFI->getLibCallStackSize() + RVFI->getRVPushStackSize();
722+
uint64_t RealStackSize = StackSize + RVFI->getReservedSpillsSize();
726723
uint64_t FPOffset = RealStackSize - RVFI->getVarArgsSaveSize();
727724
uint64_t RVVStackSize = RVFI->getRVVStackSize();
728725

@@ -873,7 +870,7 @@ RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
873870
if (FrameReg == getFPReg(STI)) {
874871
Offset += StackOffset::getFixed(RVFI->getVarArgsSaveSize());
875872
if (FI >= 0)
876-
Offset -= StackOffset::getFixed(RVFI->getLibCallStackSize());
873+
Offset -= StackOffset::getFixed(RVFI->getReservedSpillsSize());
877874
// When using FP to access scalable vector objects, we need to minus
878875
// the frame size.
879876
//
@@ -941,8 +938,7 @@ RISCVFrameLowering::getFrameIndexReference(const MachineFunction &MF, int FI,
941938
assert(!RI->hasStackRealignment(MF) &&
942939
"Can't index across variable sized realign");
943940
Offset += StackOffset::get(getStackSizeWithRVVPadding(MF) +
944-
RVFI->getLibCallStackSize() +
945-
RVFI->getRVPushStackSize(),
941+
RVFI->getReservedSpillsSize(),
946942
RVFI->getRVVStackSize());
947943
} else {
948944
Offset += StackOffset::getFixed(MFI.getStackSize());
@@ -1287,7 +1283,7 @@ RISCVFrameLowering::getFirstSPAdjustAmount(const MachineFunction &MF) const {
12871283
// Disable SplitSPAdjust if save-restore libcall is used. The callee-saved
12881284
// registers will be pushed by the save-restore libcalls, so we don't have to
12891285
// split the SP adjustment in this case.
1290-
if (RVFI->getLibCallStackSize() || RVFI->getRVPushStackSize())
1286+
if (RVFI->getReservedSpillsSize())
12911287
return 0;
12921288

12931289
// Return the FirstSPAdjustAmount if the StackSize can not fit in a signed

llvm/lib/Target/RISCV/RISCVMachineFunctionInfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ class RISCVMachineFunctionInfo : public MachineFunctionInfo {
104104
BranchRelaxationScratchFrameIndex = Index;
105105
}
106106

107+
unsigned getReservedSpillsSize() const {
108+
return LibCallStackSize + RVPushStackSize;
109+
}
110+
107111
unsigned getLibCallStackSize() const { return LibCallStackSize; }
108112
void setLibCallStackSize(unsigned Size) { LibCallStackSize = Size; }
109113

llvm/test/CodeGen/RISCV/push-pop-popret.ll

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3122,3 +3122,123 @@ define void @callee_no_irq() nounwind{
31223122
store volatile [32 x i32] %val, [32 x i32]* @var_test_irq
31233123
ret void
31243124
}
3125+
3126+
declare void @bar(ptr, ptr)
3127+
declare ptr @llvm.frameaddress.p0(i32 immarg)
3128+
3129+
define i32 @use_fp(i32 %x) {
3130+
; RV32IZCMP-LABEL: use_fp:
3131+
; RV32IZCMP: # %bb.0: # %entry
3132+
; RV32IZCMP-NEXT: cm.push {ra, s0-s1}, -32
3133+
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 32
3134+
; RV32IZCMP-NEXT: .cfi_offset ra, -12
3135+
; RV32IZCMP-NEXT: .cfi_offset s0, -8
3136+
; RV32IZCMP-NEXT: .cfi_offset s1, -4
3137+
; RV32IZCMP-NEXT: addi s0, sp, 32
3138+
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
3139+
; RV32IZCMP-NEXT: mv s1, a0
3140+
; RV32IZCMP-NEXT: addi a1, s0, -20
3141+
; RV32IZCMP-NEXT: mv a0, s0
3142+
; RV32IZCMP-NEXT: call bar@plt
3143+
; RV32IZCMP-NEXT: mv a0, s1
3144+
; RV32IZCMP-NEXT: cm.popret {ra, s0-s1}, 32
3145+
;
3146+
; RV64IZCMP-LABEL: use_fp:
3147+
; RV64IZCMP: # %bb.0: # %entry
3148+
; RV64IZCMP-NEXT: cm.push {ra, s0-s1}, -48
3149+
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 48
3150+
; RV64IZCMP-NEXT: .cfi_offset ra, -24
3151+
; RV64IZCMP-NEXT: .cfi_offset s0, -16
3152+
; RV64IZCMP-NEXT: .cfi_offset s1, -8
3153+
; RV64IZCMP-NEXT: addi s0, sp, 48
3154+
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
3155+
; RV64IZCMP-NEXT: mv s1, a0
3156+
; RV64IZCMP-NEXT: addi a1, s0, -36
3157+
; RV64IZCMP-NEXT: mv a0, s0
3158+
; RV64IZCMP-NEXT: call bar@plt
3159+
; RV64IZCMP-NEXT: mv a0, s1
3160+
; RV64IZCMP-NEXT: cm.popret {ra, s0-s1}, 48
3161+
;
3162+
; RV32IZCMP-SR-LABEL: use_fp:
3163+
; RV32IZCMP-SR: # %bb.0: # %entry
3164+
; RV32IZCMP-SR-NEXT: cm.push {ra, s0-s1}, -32
3165+
; RV32IZCMP-SR-NEXT: .cfi_def_cfa_offset 32
3166+
; RV32IZCMP-SR-NEXT: .cfi_offset ra, -12
3167+
; RV32IZCMP-SR-NEXT: .cfi_offset s0, -8
3168+
; RV32IZCMP-SR-NEXT: .cfi_offset s1, -4
3169+
; RV32IZCMP-SR-NEXT: addi s0, sp, 32
3170+
; RV32IZCMP-SR-NEXT: .cfi_def_cfa s0, 0
3171+
; RV32IZCMP-SR-NEXT: mv s1, a0
3172+
; RV32IZCMP-SR-NEXT: addi a1, s0, -20
3173+
; RV32IZCMP-SR-NEXT: mv a0, s0
3174+
; RV32IZCMP-SR-NEXT: call bar@plt
3175+
; RV32IZCMP-SR-NEXT: mv a0, s1
3176+
; RV32IZCMP-SR-NEXT: cm.popret {ra, s0-s1}, 32
3177+
;
3178+
; RV64IZCMP-SR-LABEL: use_fp:
3179+
; RV64IZCMP-SR: # %bb.0: # %entry
3180+
; RV64IZCMP-SR-NEXT: cm.push {ra, s0-s1}, -48
3181+
; RV64IZCMP-SR-NEXT: .cfi_def_cfa_offset 48
3182+
; RV64IZCMP-SR-NEXT: .cfi_offset ra, -24
3183+
; RV64IZCMP-SR-NEXT: .cfi_offset s0, -16
3184+
; RV64IZCMP-SR-NEXT: .cfi_offset s1, -8
3185+
; RV64IZCMP-SR-NEXT: addi s0, sp, 48
3186+
; RV64IZCMP-SR-NEXT: .cfi_def_cfa s0, 0
3187+
; RV64IZCMP-SR-NEXT: mv s1, a0
3188+
; RV64IZCMP-SR-NEXT: addi a1, s0, -36
3189+
; RV64IZCMP-SR-NEXT: mv a0, s0
3190+
; RV64IZCMP-SR-NEXT: call bar@plt
3191+
; RV64IZCMP-SR-NEXT: mv a0, s1
3192+
; RV64IZCMP-SR-NEXT: cm.popret {ra, s0-s1}, 48
3193+
;
3194+
; RV32I-LABEL: use_fp:
3195+
; RV32I: # %bb.0: # %entry
3196+
; RV32I-NEXT: addi sp, sp, -16
3197+
; RV32I-NEXT: .cfi_def_cfa_offset 16
3198+
; RV32I-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
3199+
; RV32I-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
3200+
; RV32I-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
3201+
; RV32I-NEXT: .cfi_offset ra, -4
3202+
; RV32I-NEXT: .cfi_offset s0, -8
3203+
; RV32I-NEXT: .cfi_offset s1, -12
3204+
; RV32I-NEXT: addi s0, sp, 16
3205+
; RV32I-NEXT: .cfi_def_cfa s0, 0
3206+
; RV32I-NEXT: mv s1, a0
3207+
; RV32I-NEXT: addi a1, s0, -16
3208+
; RV32I-NEXT: mv a0, s0
3209+
; RV32I-NEXT: call bar@plt
3210+
; RV32I-NEXT: mv a0, s1
3211+
; RV32I-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
3212+
; RV32I-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
3213+
; RV32I-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
3214+
; RV32I-NEXT: addi sp, sp, 16
3215+
; RV32I-NEXT: ret
3216+
;
3217+
; RV64I-LABEL: use_fp:
3218+
; RV64I: # %bb.0: # %entry
3219+
; RV64I-NEXT: addi sp, sp, -32
3220+
; RV64I-NEXT: .cfi_def_cfa_offset 32
3221+
; RV64I-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
3222+
; RV64I-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
3223+
; RV64I-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
3224+
; RV64I-NEXT: .cfi_offset ra, -8
3225+
; RV64I-NEXT: .cfi_offset s0, -16
3226+
; RV64I-NEXT: .cfi_offset s1, -24
3227+
; RV64I-NEXT: addi s0, sp, 32
3228+
; RV64I-NEXT: .cfi_def_cfa s0, 0
3229+
; RV64I-NEXT: mv s1, a0
3230+
; RV64I-NEXT: addi a1, s0, -28
3231+
; RV64I-NEXT: mv a0, s0
3232+
; RV64I-NEXT: call bar@plt
3233+
; RV64I-NEXT: mv a0, s1
3234+
; RV64I-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
3235+
; RV64I-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
3236+
; RV64I-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
3237+
; RV64I-NEXT: addi sp, sp, 32
3238+
; RV64I-NEXT: ret
3239+
entry:
3240+
%var = alloca i32, align 4
3241+
%0 = tail call ptr @llvm.frameaddress.p0(i32 0)
3242+
call void @bar(ptr %0, ptr %var)
3243+
ret i32 %x
3244+
}

llvm/test/CodeGen/RISCV/zcmp-with-float.ll

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ define float @foo(float %arg) {
1313
; RV32-NEXT: .cfi_def_cfa_offset 32
1414
; RV32-NEXT: fsw fs0, 12(sp) # 4-byte Folded Spill
1515
; RV32-NEXT: .cfi_offset ra, -4
16-
; RV32-NEXT: .cfi_offset fs0, -4
16+
; RV32-NEXT: .cfi_offset fs0, -20
1717
; RV32-NEXT: fmv.s fs0, fa0
1818
; RV32-NEXT: call callee@plt
1919
; RV32-NEXT: fmv.s fa0, fs0
@@ -26,7 +26,7 @@ define float @foo(float %arg) {
2626
; RV64-NEXT: .cfi_def_cfa_offset 32
2727
; RV64-NEXT: fsw fs0, 12(sp) # 4-byte Folded Spill
2828
; RV64-NEXT: .cfi_offset ra, -8
29-
; RV64-NEXT: .cfi_offset fs0, -4
29+
; RV64-NEXT: .cfi_offset fs0, -20
3030
; RV64-NEXT: fmv.s fs0, fa0
3131
; RV64-NEXT: call callee@plt
3232
; RV64-NEXT: fmv.s fa0, fs0
@@ -36,3 +36,46 @@ entry:
3636
call void @callee()
3737
ret float %arg
3838
}
39+
40+
define void @foo2(i32 %x, float %y) {
41+
; RV32-LABEL: foo2:
42+
; RV32: # %bb.0: # %entry
43+
; RV32-NEXT: cm.push {ra, s0}, -32
44+
; RV32-NEXT: .cfi_def_cfa_offset 32
45+
; RV32-NEXT: fsw fs0, 12(sp) # 4-byte Folded Spill
46+
; RV32-NEXT: .cfi_offset ra, -8
47+
; RV32-NEXT: .cfi_offset s0, -4
48+
; RV32-NEXT: .cfi_offset fs0, -20
49+
; RV32-NEXT: fmv.s fs0, fa0
50+
; RV32-NEXT: mv s0, a0
51+
; RV32-NEXT: call bar@plt
52+
; RV32-NEXT: mv a0, s0
53+
; RV32-NEXT: fmv.s fa0, fs0
54+
; RV32-NEXT: flw fs0, 12(sp) # 4-byte Folded Reload
55+
; RV32-NEXT: cm.pop {ra, s0}, 32
56+
; RV32-NEXT: tail func@plt
57+
;
58+
; RV64-LABEL: foo2:
59+
; RV64: # %bb.0: # %entry
60+
; RV64-NEXT: cm.push {ra, s0}, -32
61+
; RV64-NEXT: .cfi_def_cfa_offset 32
62+
; RV64-NEXT: fsw fs0, 12(sp) # 4-byte Folded Spill
63+
; RV64-NEXT: .cfi_offset ra, -16
64+
; RV64-NEXT: .cfi_offset s0, -8
65+
; RV64-NEXT: .cfi_offset fs0, -20
66+
; RV64-NEXT: fmv.s fs0, fa0
67+
; RV64-NEXT: mv s0, a0
68+
; RV64-NEXT: call bar@plt
69+
; RV64-NEXT: mv a0, s0
70+
; RV64-NEXT: fmv.s fa0, fs0
71+
; RV64-NEXT: flw fs0, 12(sp) # 4-byte Folded Reload
72+
; RV64-NEXT: cm.pop {ra, s0}, 32
73+
; RV64-NEXT: tail func@plt
74+
entry:
75+
tail call void @bar()
76+
tail call void @func(i32 %x, float %y)
77+
ret void
78+
}
79+
80+
declare void @bar()
81+
declare void @func(i32, float)

0 commit comments

Comments
 (0)