Skip to content

Commit b727e63

Browse files
yetingkKaiYG
authored andcommitted
[RISCV] Fix bugs about register list of Zcmp push/pop. (llvm#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 82d93ad commit b727e63

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
@@ -241,37 +241,38 @@ getRestoreLibCallName(const MachineFunction &MF,
241241
return RestoreLibCalls[LibCallID];
242242
}
243243

244-
// Return encoded value for PUSH/POP instruction, representing
245-
// registers to store/load.
246-
static unsigned getPushPopEncoding(const Register MaxReg) {
244+
// Return encoded value and register count for PUSH/POP instruction,
245+
// representing registers to store/load.
246+
static std::pair<unsigned, unsigned>
247+
getPushPopEncodingAndNum(const Register MaxReg) {
247248
switch (MaxReg) {
248249
default:
249250
llvm_unreachable("Unexpected Reg for Push/Pop Inst");
250251
case RISCV::X27: /*s11*/
251252
case RISCV::X26: /*s10*/
252-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S11;
253+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S11, 13);
253254
case RISCV::X25: /*s9*/
254-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S9;
255+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S9, 11);
255256
case RISCV::X24: /*s8*/
256-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S8;
257+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S8, 10);
257258
case RISCV::X23: /*s7*/
258-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S7;
259+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S7, 9);
259260
case RISCV::X22: /*s6*/
260-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S6;
261+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S6, 8);
261262
case RISCV::X21: /*s5*/
262-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S5;
263+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S5, 7);
263264
case RISCV::X20: /*s4*/
264-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S4;
265+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S4, 6);
265266
case RISCV::X19: /*s3*/
266-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S3;
267+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S3, 5);
267268
case RISCV::X18: /*s2*/
268-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S2;
269+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S2, 4);
269270
case RISCV::X9: /*s1*/
270-
return llvm::RISCVZC::RLISTENCODE::RA_S0_S1;
271+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S1, 3);
271272
case RISCV::X8: /*s0*/
272-
return llvm::RISCVZC::RLISTENCODE::RA_S0;
273+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0, 2);
273274
case RISCV::X1: /*ra*/
274-
return llvm::RISCVZC::RLISTENCODE::RA;
275+
return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA, 1);
275276
}
276277
}
277278

@@ -1348,14 +1349,12 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
13481349
RISCVMachineFunctionInfo *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
13491350
if (RVFI->isPushable(*MF)) {
13501351
Register MaxReg = getMaxPushPopReg(*MF, CSI);
1351-
unsigned PushedRegNum =
1352-
getPushPopEncoding(MaxReg) - llvm::RISCVZC::RLISTENCODE::RA + 1;
1353-
RVFI->setRVPushRegs(PushedRegNum);
1354-
RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
1355-
13561352
if (MaxReg != RISCV::NoRegister) {
1353+
auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum(MaxReg);
1354+
RVFI->setRVPushRegs(PushedRegNum);
1355+
RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
1356+
13571357
// Use encoded number to represent registers to spill.
1358-
unsigned RegEnc = getPushPopEncoding(MaxReg);
13591358
RVFI->setRVPushRlist(RegEnc);
13601359
MachineInstrBuilder PushBuilder =
13611360
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
@@ -2597,6 +2597,142 @@ entry:
25972597
ret void
25982598
}
25992599

2600+
; Check .cfi_offset of s11 is correct for Zcmp.
2601+
define void @bar() {
2602+
; RV32I-LABEL: bar:
2603+
; RV32I: # %bb.0: # %entry
2604+
; RV32I-NEXT: addi sp, sp, -16
2605+
; RV32I-NEXT: .cfi_def_cfa_offset 16
2606+
; RV32I-NEXT: sw s11, 12(sp) # 4-byte Folded Spill
2607+
; RV32I-NEXT: .cfi_offset s11, -4
2608+
; RV32I-NEXT: #APP
2609+
; RV32I-NEXT: li s11, 0
2610+
; RV32I-NEXT: #NO_APP
2611+
; RV32I-NEXT: lw s11, 12(sp) # 4-byte Folded Reload
2612+
; RV32I-NEXT: addi sp, sp, 16
2613+
; RV32I-NEXT: ret
2614+
;
2615+
; RV32I-WITH-FP-LABEL: bar:
2616+
; RV32I-WITH-FP: # %bb.0: # %entry
2617+
; RV32I-WITH-FP-NEXT: addi sp, sp, -16
2618+
; RV32I-WITH-FP-NEXT: .cfi_def_cfa_offset 16
2619+
; RV32I-WITH-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2620+
; RV32I-WITH-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
2621+
; RV32I-WITH-FP-NEXT: sw s11, 4(sp) # 4-byte Folded Spill
2622+
; RV32I-WITH-FP-NEXT: .cfi_offset ra, -4
2623+
; RV32I-WITH-FP-NEXT: .cfi_offset s0, -8
2624+
; RV32I-WITH-FP-NEXT: .cfi_offset s11, -12
2625+
; RV32I-WITH-FP-NEXT: addi s0, sp, 16
2626+
; RV32I-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2627+
; RV32I-WITH-FP-NEXT: #APP
2628+
; RV32I-WITH-FP-NEXT: li s11, 0
2629+
; RV32I-WITH-FP-NEXT: #NO_APP
2630+
; RV32I-WITH-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2631+
; RV32I-WITH-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
2632+
; RV32I-WITH-FP-NEXT: lw s11, 4(sp) # 4-byte Folded Reload
2633+
; RV32I-WITH-FP-NEXT: addi sp, sp, 16
2634+
; RV32I-WITH-FP-NEXT: ret
2635+
;
2636+
; RV32IZCMP-LABEL: bar:
2637+
; RV32IZCMP: # %bb.0: # %entry
2638+
; RV32IZCMP-NEXT: cm.push {ra, s0-s11}, -64
2639+
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 64
2640+
; RV32IZCMP-NEXT: .cfi_offset s11, -4
2641+
; RV32IZCMP-NEXT: #APP
2642+
; RV32IZCMP-NEXT: li s11, 0
2643+
; RV32IZCMP-NEXT: #NO_APP
2644+
; RV32IZCMP-NEXT: cm.popret {ra, s0-s11}, 64
2645+
;
2646+
; RV32IZCMP-WITH-FP-LABEL: bar:
2647+
; RV32IZCMP-WITH-FP: # %bb.0: # %entry
2648+
; RV32IZCMP-WITH-FP-NEXT: addi sp, sp, -16
2649+
; RV32IZCMP-WITH-FP-NEXT: .cfi_def_cfa_offset 16
2650+
; RV32IZCMP-WITH-FP-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
2651+
; RV32IZCMP-WITH-FP-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
2652+
; RV32IZCMP-WITH-FP-NEXT: sw s11, 4(sp) # 4-byte Folded Spill
2653+
; RV32IZCMP-WITH-FP-NEXT: .cfi_offset ra, -4
2654+
; RV32IZCMP-WITH-FP-NEXT: .cfi_offset s0, -8
2655+
; RV32IZCMP-WITH-FP-NEXT: .cfi_offset s11, -12
2656+
; RV32IZCMP-WITH-FP-NEXT: addi s0, sp, 16
2657+
; RV32IZCMP-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2658+
; RV32IZCMP-WITH-FP-NEXT: #APP
2659+
; RV32IZCMP-WITH-FP-NEXT: li s11, 0
2660+
; RV32IZCMP-WITH-FP-NEXT: #NO_APP
2661+
; RV32IZCMP-WITH-FP-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
2662+
; RV32IZCMP-WITH-FP-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
2663+
; RV32IZCMP-WITH-FP-NEXT: lw s11, 4(sp) # 4-byte Folded Reload
2664+
; RV32IZCMP-WITH-FP-NEXT: addi sp, sp, 16
2665+
; RV32IZCMP-WITH-FP-NEXT: ret
2666+
;
2667+
; RV64I-LABEL: bar:
2668+
; RV64I: # %bb.0: # %entry
2669+
; RV64I-NEXT: addi sp, sp, -16
2670+
; RV64I-NEXT: .cfi_def_cfa_offset 16
2671+
; RV64I-NEXT: sd s11, 8(sp) # 8-byte Folded Spill
2672+
; RV64I-NEXT: .cfi_offset s11, -8
2673+
; RV64I-NEXT: #APP
2674+
; RV64I-NEXT: li s11, 0
2675+
; RV64I-NEXT: #NO_APP
2676+
; RV64I-NEXT: ld s11, 8(sp) # 8-byte Folded Reload
2677+
; RV64I-NEXT: addi sp, sp, 16
2678+
; RV64I-NEXT: ret
2679+
;
2680+
; RV64I-WITH-FP-LABEL: bar:
2681+
; RV64I-WITH-FP: # %bb.0: # %entry
2682+
; RV64I-WITH-FP-NEXT: addi sp, sp, -32
2683+
; RV64I-WITH-FP-NEXT: .cfi_def_cfa_offset 32
2684+
; RV64I-WITH-FP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
2685+
; RV64I-WITH-FP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
2686+
; RV64I-WITH-FP-NEXT: sd s11, 8(sp) # 8-byte Folded Spill
2687+
; RV64I-WITH-FP-NEXT: .cfi_offset ra, -8
2688+
; RV64I-WITH-FP-NEXT: .cfi_offset s0, -16
2689+
; RV64I-WITH-FP-NEXT: .cfi_offset s11, -24
2690+
; RV64I-WITH-FP-NEXT: addi s0, sp, 32
2691+
; RV64I-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2692+
; RV64I-WITH-FP-NEXT: #APP
2693+
; RV64I-WITH-FP-NEXT: li s11, 0
2694+
; RV64I-WITH-FP-NEXT: #NO_APP
2695+
; RV64I-WITH-FP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
2696+
; RV64I-WITH-FP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
2697+
; RV64I-WITH-FP-NEXT: ld s11, 8(sp) # 8-byte Folded Reload
2698+
; RV64I-WITH-FP-NEXT: addi sp, sp, 32
2699+
; RV64I-WITH-FP-NEXT: ret
2700+
;
2701+
; RV64IZCMP-LABEL: bar:
2702+
; RV64IZCMP: # %bb.0: # %entry
2703+
; RV64IZCMP-NEXT: cm.push {ra, s0-s11}, -112
2704+
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 112
2705+
; RV64IZCMP-NEXT: .cfi_offset s11, -8
2706+
; RV64IZCMP-NEXT: #APP
2707+
; RV64IZCMP-NEXT: li s11, 0
2708+
; RV64IZCMP-NEXT: #NO_APP
2709+
; RV64IZCMP-NEXT: cm.popret {ra, s0-s11}, 112
2710+
;
2711+
; RV64IZCMP-WITH-FP-LABEL: bar:
2712+
; RV64IZCMP-WITH-FP: # %bb.0: # %entry
2713+
; RV64IZCMP-WITH-FP-NEXT: addi sp, sp, -32
2714+
; RV64IZCMP-WITH-FP-NEXT: .cfi_def_cfa_offset 32
2715+
; RV64IZCMP-WITH-FP-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
2716+
; RV64IZCMP-WITH-FP-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
2717+
; RV64IZCMP-WITH-FP-NEXT: sd s11, 8(sp) # 8-byte Folded Spill
2718+
; RV64IZCMP-WITH-FP-NEXT: .cfi_offset ra, -8
2719+
; RV64IZCMP-WITH-FP-NEXT: .cfi_offset s0, -16
2720+
; RV64IZCMP-WITH-FP-NEXT: .cfi_offset s11, -24
2721+
; RV64IZCMP-WITH-FP-NEXT: addi s0, sp, 32
2722+
; RV64IZCMP-WITH-FP-NEXT: .cfi_def_cfa s0, 0
2723+
; RV64IZCMP-WITH-FP-NEXT: #APP
2724+
; RV64IZCMP-WITH-FP-NEXT: li s11, 0
2725+
; RV64IZCMP-WITH-FP-NEXT: #NO_APP
2726+
; RV64IZCMP-WITH-FP-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
2727+
; RV64IZCMP-WITH-FP-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
2728+
; RV64IZCMP-WITH-FP-NEXT: ld s11, 8(sp) # 8-byte Folded Reload
2729+
; RV64IZCMP-WITH-FP-NEXT: addi sp, sp, 32
2730+
; RV64IZCMP-WITH-FP-NEXT: ret
2731+
entry:
2732+
tail call void asm sideeffect "li s11, 0", "~{s11}"()
2733+
ret void
2734+
}
2735+
26002736
define void @varargs(...) {
26012737
; RV32I-LABEL: varargs:
26022738
; 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)