Skip to content

Commit 976df42

Browse files
authored
[RISCV] Fix bugs about register list of Zcmp push/pop. (#66073)
The pr does two things. One is to fix internal compiler error when we need to spill callee saves but none of them is GPR, another is to fix wrong register number for pushed registers are {ra, s0-s11}.
1 parent 747c40e commit 976df42

File tree

3 files changed

+194
-21
lines changed

3 files changed

+194
-21
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -226,37 +226,38 @@ getRestoreLibCallName(const MachineFunction &MF,
226226
return RestoreLibCalls[LibCallID];
227227
}
228228

229-
// Return encoded value for PUSH/POP instruction, representing
230-
// registers to store/load.
231-
static unsigned getPushPopEncoding(const Register MaxReg) {
229+
// Return encoded value and register count for PUSH/POP instruction,
230+
// representing registers to store/load.
231+
static std::pair<unsigned, unsigned>
232+
getPushPopEncodingAndNum(const Register MaxReg) {
232233
switch (MaxReg) {
233234
default:
234235
llvm_unreachable("Unexpected Reg for Push/Pop Inst");
235236
case RISCV::X27: /*s11*/
236237
case RISCV::X26: /*s10*/
237-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S11;
238+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S11, 13);
238239
case RISCV::X25: /*s9*/
239-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S9;
240+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S9, 11);
240241
case RISCV::X24: /*s8*/
241-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S8;
242+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S8, 10);
242243
case RISCV::X23: /*s7*/
243-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S7;
244+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S7, 9);
244245
case RISCV::X22: /*s6*/
245-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S6;
246+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S6, 8);
246247
case RISCV::X21: /*s5*/
247-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S5;
248+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S5, 7);
248249
case RISCV::X20: /*s4*/
249-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S4;
250+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S4, 6);
250251
case RISCV::X19: /*s3*/
251-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S3;
252+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S3, 5);
252253
case RISCV::X18: /*s2*/
253-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S2;
254+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S2, 4);
254255
case RISCV::X9: /*s1*/
255-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S1;
256+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S1, 3);
256257
case RISCV::X8: /*s0*/
257-
return llvm::RISCVZC::RLISTENCODE::RA_S0;
258+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0, 2);
258259
case RISCV::X1: /*ra*/
259-
return llvm::RISCVZC::RLISTENCODE::RA;
260+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA, 1);
260261
}
261262
}
262263

@@ -1360,14 +1361,12 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
13601361
RISCVMachineFunctionInfo *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
13611362
if (RVFI->isPushable(*MF)) {
13621363
Register MaxReg = getMaxPushPopReg(*MF, CSI);
1363-
unsigned PushedRegNum =
1364-
getPushPopEncoding(MaxReg) - llvm::RISCVZC::RLISTENCODE::RA + 1;
1365-
RVFI->setRVPushRegs(PushedRegNum);
1366-
RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
1367-
13681364
if (MaxReg != RISCV::NoRegister) {
1365+
auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum(MaxReg);
1366+
RVFI->setRVPushRegs(PushedRegNum);
1367+
RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
1368+
13691369
// Use encoded number to represent registers to spill.
1370-
unsigned RegEnc = getPushPopEncoding(MaxReg);
13711370
RVFI->setRVPushRlist(RegEnc);
13721371
MachineInstrBuilder PushBuilder =
13731372
BuildMI(MBB, MI, DL, TII.get(RISCV::CM_PUSH))

llvm/test/CodeGen/RISCV/callee-saved-gprs.ll

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2128,6 +2128,142 @@ entry:
21282128
ret void
21292129
}
21302130

2131+
; Check .cfi_offset of s11 is correct for Zcmp.
2132+
define void @bar() {
2133+
; RV32I-LABEL: bar:
2134+
; RV32I: # %bb.0: # %entry
2135+
; RV32I-NEXT: addi sp, sp, -16
2136+
; RV32I-NEXT: .cfi_def_cfa_offset 16
2137+
; RV32I-NEXT: sw s11, 12(sp) # 4-byte Folded Spill
2138+
; RV32I-NEXT: .cfi_offset s11, -4
2139+
; RV32I-NEXT: #APP
2140+
; RV32I-NEXT: li s11, 0
2141+
; RV32I-NEXT: #NO_APP
2142+
; RV32I-NEXT: lw s11, 12(sp) # 4-byte Folded Reload
2143+
; RV32I-NEXT: addi sp, sp, 16
2144+
; RV32I-NEXT: ret
2145+
;
2146+
; RV32I-WITH-FP-LABEL: bar:
2147+
; RV32I-WITH-FP: # %bb.0: # %entry
2148+
; RV32I-WITH-FP-NEXT: addi sp, sp, -16
2149+
; RV32I-WITH-FP-NEXT: .cfi_def_cfa_offset 16
2150+
; RV32I-WITH-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2151+
; RV32I-WITH-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
2152+
; RV32I-WITH-FP-NEXT: sw s11, 4(sp) # 4-byte Folded Spill
2153+
; RV32I-WITH-FP-NEXT: .cfi_offset ra, -4
2154+
; RV32I-WITH-FP-NEXT: .cfi_offset s0, -8
2155+
; RV32I-WITH-FP-NEXT: .cfi_offset s11, -12
2156+
; RV32I-WITH-FP-NEXT: addi s0, sp, 16
2157+
; RV32I-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2158+
; RV32I-WITH-FP-NEXT: #APP
2159+
; RV32I-WITH-FP-NEXT: li s11, 0
2160+
; RV32I-WITH-FP-NEXT: #NO_APP
2161+
; RV32I-WITH-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2162+
; RV32I-WITH-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
2163+
; RV32I-WITH-FP-NEXT: lw s11, 4(sp) # 4-byte Folded Reload
2164+
; RV32I-WITH-FP-NEXT: addi sp, sp, 16
2165+
; RV32I-WITH-FP-NEXT: ret
2166+
;
2167+
; RV32IZCMP-LABEL: bar:
2168+
; RV32IZCMP: # %bb.0: # %entry
2169+
; RV32IZCMP-NEXT: cm.push {ra, s0-s11}, -64
2170+
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 64
2171+
; RV32IZCMP-NEXT: .cfi_offset s11, -4
2172+
; RV32IZCMP-NEXT: #APP
2173+
; RV32IZCMP-NEXT: li s11, 0
2174+
; RV32IZCMP-NEXT: #NO_APP
2175+
; RV32IZCMP-NEXT: cm.popret {ra, s0-s11}, 64
2176+
;
2177+
; RV32IZCMP-WITH-FP-LABEL: bar:
2178+
; RV32IZCMP-WITH-FP: # %bb.0: # %entry
2179+
; RV32IZCMP-WITH-FP-NEXT: addi sp, sp, -16
2180+
; RV32IZCMP-WITH-FP-NEXT: .cfi_def_cfa_offset 16
2181+
; RV32IZCMP-WITH-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2182+
; RV32IZCMP-WITH-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
2183+
; RV32IZCMP-WITH-FP-NEXT: sw s11, 4(sp) # 4-byte Folded Spill
2184+
; RV32IZCMP-WITH-FP-NEXT: .cfi_offset ra, -4
2185+
; RV32IZCMP-WITH-FP-NEXT: .cfi_offset s0, -8
2186+
; RV32IZCMP-WITH-FP-NEXT: .cfi_offset s11, -12
2187+
; RV32IZCMP-WITH-FP-NEXT: addi s0, sp, 16
2188+
; RV32IZCMP-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2189+
; RV32IZCMP-WITH-FP-NEXT: #APP
2190+
; RV32IZCMP-WITH-FP-NEXT: li s11, 0
2191+
; RV32IZCMP-WITH-FP-NEXT: #NO_APP
2192+
; RV32IZCMP-WITH-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2193+
; RV32IZCMP-WITH-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
2194+
; RV32IZCMP-WITH-FP-NEXT: lw s11, 4(sp) # 4-byte Folded Reload
2195+
; RV32IZCMP-WITH-FP-NEXT: addi sp, sp, 16
2196+
; RV32IZCMP-WITH-FP-NEXT: ret
2197+
;
2198+
; RV64I-LABEL: bar:
2199+
; RV64I: # %bb.0: # %entry
2200+
; RV64I-NEXT: addi sp, sp, -16
2201+
; RV64I-NEXT: .cfi_def_cfa_offset 16
2202+
; RV64I-NEXT: sd s11, 8(sp) # 8-byte Folded Spill
2203+
; RV64I-NEXT: .cfi_offset s11, -8
2204+
; RV64I-NEXT: #APP
2205+
; RV64I-NEXT: li s11, 0
2206+
; RV64I-NEXT: #NO_APP
2207+
; RV64I-NEXT: ld s11, 8(sp) # 8-byte Folded Reload
2208+
; RV64I-NEXT: addi sp, sp, 16
2209+
; RV64I-NEXT: ret
2210+
;
2211+
; RV64I-WITH-FP-LABEL: bar:
2212+
; RV64I-WITH-FP: # %bb.0: # %entry
2213+
; RV64I-WITH-FP-NEXT: addi sp, sp, -32
2214+
; RV64I-WITH-FP-NEXT: .cfi_def_cfa_offset 32
2215+
; RV64I-WITH-FP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
2216+
; RV64I-WITH-FP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
2217+
; RV64I-WITH-FP-NEXT: sd s11, 8(sp) # 8-byte Folded Spill
2218+
; RV64I-WITH-FP-NEXT: .cfi_offset ra, -8
2219+
; RV64I-WITH-FP-NEXT: .cfi_offset s0, -16
2220+
; RV64I-WITH-FP-NEXT: .cfi_offset s11, -24
2221+
; RV64I-WITH-FP-NEXT: addi s0, sp, 32
2222+
; RV64I-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2223+
; RV64I-WITH-FP-NEXT: #APP
2224+
; RV64I-WITH-FP-NEXT: li s11, 0
2225+
; RV64I-WITH-FP-NEXT: #NO_APP
2226+
; RV64I-WITH-FP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
2227+
; RV64I-WITH-FP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
2228+
; RV64I-WITH-FP-NEXT: ld s11, 8(sp) # 8-byte Folded Reload
2229+
; RV64I-WITH-FP-NEXT: addi sp, sp, 32
2230+
; RV64I-WITH-FP-NEXT: ret
2231+
;
2232+
; RV64IZCMP-LABEL: bar:
2233+
; RV64IZCMP: # %bb.0: # %entry
2234+
; RV64IZCMP-NEXT: cm.push {ra, s0-s11}, -112
2235+
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 112
2236+
; RV64IZCMP-NEXT: .cfi_offset s11, -8
2237+
; RV64IZCMP-NEXT: #APP
2238+
; RV64IZCMP-NEXT: li s11, 0
2239+
; RV64IZCMP-NEXT: #NO_APP
2240+
; RV64IZCMP-NEXT: cm.popret {ra, s0-s11}, 112
2241+
;
2242+
; RV64IZCMP-WITH-FP-LABEL: bar:
2243+
; RV64IZCMP-WITH-FP: # %bb.0: # %entry
2244+
; RV64IZCMP-WITH-FP-NEXT: addi sp, sp, -32
2245+
; RV64IZCMP-WITH-FP-NEXT: .cfi_def_cfa_offset 32
2246+
; RV64IZCMP-WITH-FP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
2247+
; RV64IZCMP-WITH-FP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
2248+
; RV64IZCMP-WITH-FP-NEXT: sd s11, 8(sp) # 8-byte Folded Spill
2249+
; RV64IZCMP-WITH-FP-NEXT: .cfi_offset ra, -8
2250+
; RV64IZCMP-WITH-FP-NEXT: .cfi_offset s0, -16
2251+
; RV64IZCMP-WITH-FP-NEXT: .cfi_offset s11, -24
2252+
; RV64IZCMP-WITH-FP-NEXT: addi s0, sp, 32
2253+
; RV64IZCMP-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2254+
; RV64IZCMP-WITH-FP-NEXT: #APP
2255+
; RV64IZCMP-WITH-FP-NEXT: li s11, 0
2256+
; RV64IZCMP-WITH-FP-NEXT: #NO_APP
2257+
; RV64IZCMP-WITH-FP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
2258+
; RV64IZCMP-WITH-FP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
2259+
; RV64IZCMP-WITH-FP-NEXT: ld s11, 8(sp) # 8-byte Folded Reload
2260+
; RV64IZCMP-WITH-FP-NEXT: addi sp, sp, 32
2261+
; RV64IZCMP-WITH-FP-NEXT: ret
2262+
entry:
2263+
tail call void asm sideeffect "li s11, 0", "~{s11}"()
2264+
ret void
2265+
}
2266+
21312267
define void @varargs(...) {
21322268
; RV32I-LABEL: varargs:
21332269
; RV32I: # %bb.0:
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
2+
; RUN: llc -mtriple=riscv32 -mattr=+f,+zcmp -target-abi ilp32f -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV32
3+
; RUN: llc -mtriple=riscv64 -mattr=+f,+zcmp -target-abi lp64f -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64
4+
5+
declare void @callee()
6+
7+
; Test the file could be compiled successfully.
8+
; .cfi_offset of fs0 is wrong here. It should be fixed by #66613.
9+
define float @foo(float %arg) {
10+
; RV32-LABEL: foo:
11+
; RV32: # %bb.0: # %entry
12+
; RV32-NEXT: cm.push {ra}, -32
13+
; RV32-NEXT: .cfi_def_cfa_offset 32
14+
; RV32-NEXT: fsw fs0, 12(sp) # 4-byte Folded Spill
15+
; RV32-NEXT: .cfi_offset ra, -4
16+
; RV32-NEXT: .cfi_offset fs0, -4
17+
; RV32-NEXT: fmv.s fs0, fa0
18+
; RV32-NEXT: call callee@plt
19+
; RV32-NEXT: fmv.s fa0, fs0
20+
; RV32-NEXT: flw fs0, 12(sp) # 4-byte Folded Reload
21+
; RV32-NEXT: cm.popret {ra}, 32
22+
;
23+
; RV64-LABEL: foo:
24+
; RV64: # %bb.0: # %entry
25+
; RV64-NEXT: cm.push {ra}, -32
26+
; RV64-NEXT: .cfi_def_cfa_offset 32
27+
; RV64-NEXT: fsw fs0, 12(sp) # 4-byte Folded Spill
28+
; RV64-NEXT: .cfi_offset ra, -8
29+
; RV64-NEXT: .cfi_offset fs0, -4
30+
; RV64-NEXT: fmv.s fs0, fa0
31+
; RV64-NEXT: call callee@plt
32+
; RV64-NEXT: fmv.s fa0, fs0
33+
; RV64-NEXT: flw fs0, 12(sp) # 4-byte Folded Reload
34+
; RV64-NEXT: cm.popret {ra}, 32
35+
entry:
36+
call void @callee()
37+
ret float %arg
38+
}

0 commit comments

Comments
 (0)