[llvm] [RISCV] Fix internal compiler about Zcmp. (PR #66073)

Yeting Kuo via llvm-commits llvm-commits at lists.llvm.org
Thu Sep 14 02:23:51 PDT 2023


https://github.com/yetingk updated https://github.com/llvm/llvm-project/pull/66073:

>From bf518a62147d7ae94fc6860fb117815c2cc76d09 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Tue, 12 Sep 2023 20:06:06 +0800
Subject: [PATCH 1/2] [RISCV] Fix internal compiler about Zcmp.

The original code encounters ICE when we need to spill callee saves but none of
them is GPR.
---
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 10 +++++-----
 llvm/test/CodeGen/RISCV/zcmp-crash.ll        | 21 ++++++++++++++++++++
 2 files changed, 26 insertions(+), 5 deletions(-)
 create mode 100644 llvm/test/CodeGen/RISCV/zcmp-crash.ll

diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index add933250f8473d..898412ff446b075 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -1371,12 +1371,12 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
   RISCVMachineFunctionInfo *RVFI = MF->getInfo<RISCVMachineFunctionInfo>();
   if (RVFI->isPushable(*MF)) {
     Register MaxReg = getMaxPushPopReg(*MF, CSI);
-    unsigned PushedRegNum =
-        getPushPopEncoding(MaxReg) - llvm::RISCVZC::RLISTENCODE::RA + 1;
-    RVFI->setRVPushRegs(PushedRegNum);
-    RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
-
     if (MaxReg != RISCV::NoRegister) {
+      unsigned PushedRegNum =
+          getPushPopEncoding(MaxReg) - llvm::RISCVZC::RLISTENCODE::RA + 1;
+      RVFI->setRVPushRegs(PushedRegNum);
+      RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
+
       // Use encoded number to represent registers to spill.
       unsigned RegEnc = getPushPopEncoding(MaxReg);
       RVFI->setRVPushRlist(RegEnc);
diff --git a/llvm/test/CodeGen/RISCV/zcmp-crash.ll b/llvm/test/CodeGen/RISCV/zcmp-crash.ll
new file mode 100644
index 000000000000000..b22085f95a3d1b0
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/zcmp-crash.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=riscv32 -target-abi ilp32f -mattr=+f,+zcmp -verify-machineinstrs < %s | FileCheck %s
+
+; Test the file could be compiled successfully.
+define void @bar() {
+; CHECK-LABEL: bar:
+; CHECK:       # %bb.0: # %entry
+; CHECK-NEXT:    addi sp, sp, -16
+; CHECK-NEXT:    .cfi_def_cfa_offset 16
+; CHECK-NEXT:    fsw fs0, 12(sp) # 4-byte Folded Spill
+; CHECK-NEXT:    .cfi_offset fs0, -4
+; CHECK-NEXT:    #APP
+; CHECK-NEXT:    fmv.w.x fs0, zero
+; CHECK-NEXT:    #NO_APP
+; CHECK-NEXT:    flw fs0, 12(sp) # 4-byte Folded Reload
+; CHECK-NEXT:    addi sp, sp, 16
+; CHECK-NEXT:    ret
+entry:
+  tail call void asm sideeffect "fmv.w.x fs0, zero", "~{fs0}"()
+  ret void
+}

>From 170908ad4a39aa69d098f2f15ed4a9347d2fe490 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Thu, 14 Sep 2023 17:08:53 +0800
Subject: [PATCH 2/2] [RISCV] Use right pushed register number when max pushed
 register is s10/s11.

---
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 31 +++++----
 llvm/test/CodeGen/RISCV/callee-saved-gprs.ll | 70 ++++++++++----------
 2 files changed, 50 insertions(+), 51 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 898412ff446b075..19cd5c7738917c5 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -228,35 +228,36 @@ getRestoreLibCallName(const MachineFunction &MF,
 
 // Return encoded value for PUSH/POP instruction, representing
 // registers to store/load.
-static unsigned getPushPopEncoding(const Register MaxReg) {
+static std::pair<unsigned, unsigned>
+getPushPopEncodingAndNum(const Register MaxReg) {
   switch (MaxReg) {
   default:
     llvm_unreachable("Unexpected Reg for Push/Pop Inst");
   case RISCV::X27: /*s11*/
   case RISCV::X26: /*s10*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S11;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S11, 13);
   case RISCV::X25: /*s9*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S9;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S9, 11);
   case RISCV::X24: /*s8*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S8;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S8, 10);
   case RISCV::X23: /*s7*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S7;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S7, 9);
   case RISCV::X22: /*s6*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S6;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S6, 8);
   case RISCV::X21: /*s5*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S5;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S5, 7);
   case RISCV::X20: /*s4*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S4;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S4, 6);
   case RISCV::X19: /*s3*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S3;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S3, 5);
   case RISCV::X18: /*s2*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S2;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S2, 4);
   case RISCV::X9: /*s1*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0_S1;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0_S1, 3);
   case RISCV::X8: /*s0*/
-    return llvm::RISCVZC::RLISTENCODE::RA_S0;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA_S0, 2);
   case RISCV::X1: /*ra*/
-    return llvm::RISCVZC::RLISTENCODE::RA;
+    return std::make_pair(llvm::RISCVZC::RLISTENCODE::RA, 1);
   }
 }
 
@@ -1372,13 +1373,11 @@ bool RISCVFrameLowering::spillCalleeSavedRegisters(
   if (RVFI->isPushable(*MF)) {
     Register MaxReg = getMaxPushPopReg(*MF, CSI);
     if (MaxReg != RISCV::NoRegister) {
-      unsigned PushedRegNum =
-          getPushPopEncoding(MaxReg) - llvm::RISCVZC::RLISTENCODE::RA + 1;
+      auto [RegEnc, PushedRegNum] = getPushPopEncodingAndNum(MaxReg);
       RVFI->setRVPushRegs(PushedRegNum);
       RVFI->setRVPushStackSize(alignTo((STI.getXLen() / 8) * PushedRegNum, 16));
 
       // Use encoded number to represent registers to spill.
-      unsigned RegEnc = getPushPopEncoding(MaxReg);
       RVFI->setRVPushRlist(RegEnc);
       MachineInstrBuilder PushBuilder =
           BuildMI(MBB, MI, DL, TII.get(RISCV::CM_PUSH))
diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
index 30374c13d60fecf..029cbf4624d756f 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -1998,12 +1998,12 @@ define void @foo() {
 ; RV32I:       # %bb.0: # %entry
 ; RV32I-NEXT:    addi sp, sp, -16
 ; RV32I-NEXT:    .cfi_def_cfa_offset 16
-; RV32I-NEXT:    sw s4, 12(sp) # 4-byte Folded Spill
-; RV32I-NEXT:    .cfi_offset s4, -4
+; RV32I-NEXT:    sw s11, 12(sp) # 4-byte Folded Spill
+; RV32I-NEXT:    .cfi_offset s11, -4
 ; RV32I-NEXT:    #APP
-; RV32I-NEXT:    li s4, 0
+; RV32I-NEXT:    li s11, 0
 ; RV32I-NEXT:    #NO_APP
-; RV32I-NEXT:    lw s4, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    lw s11, 12(sp) # 4-byte Folded Reload
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
 ;
@@ -2013,30 +2013,30 @@ define void @foo() {
 ; RV32I-WITH-FP-NEXT:    .cfi_def_cfa_offset 16
 ; RV32I-WITH-FP-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32I-WITH-FP-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
-; RV32I-WITH-FP-NEXT:    sw s4, 4(sp) # 4-byte Folded Spill
+; RV32I-WITH-FP-NEXT:    sw s11, 4(sp) # 4-byte Folded Spill
 ; RV32I-WITH-FP-NEXT:    .cfi_offset ra, -4
 ; RV32I-WITH-FP-NEXT:    .cfi_offset s0, -8
-; RV32I-WITH-FP-NEXT:    .cfi_offset s4, -12
+; RV32I-WITH-FP-NEXT:    .cfi_offset s11, -12
 ; RV32I-WITH-FP-NEXT:    addi s0, sp, 16
 ; RV32I-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32I-WITH-FP-NEXT:    #APP
-; RV32I-WITH-FP-NEXT:    li s4, 0
+; RV32I-WITH-FP-NEXT:    li s11, 0
 ; RV32I-WITH-FP-NEXT:    #NO_APP
 ; RV32I-WITH-FP-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32I-WITH-FP-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
-; RV32I-WITH-FP-NEXT:    lw s4, 4(sp) # 4-byte Folded Reload
+; RV32I-WITH-FP-NEXT:    lw s11, 4(sp) # 4-byte Folded Reload
 ; RV32I-WITH-FP-NEXT:    addi sp, sp, 16
 ; RV32I-WITH-FP-NEXT:    ret
 ;
 ; RV32IZCMP-LABEL: foo:
 ; RV32IZCMP:       # %bb.0: # %entry
-; RV32IZCMP-NEXT:    cm.push {ra, s0-s4}, -32
-; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 32
-; RV32IZCMP-NEXT:    .cfi_offset s4, -4
+; RV32IZCMP-NEXT:    cm.push {ra, s0-s11}, -64
+; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 64
+; RV32IZCMP-NEXT:    .cfi_offset s11, -4
 ; RV32IZCMP-NEXT:    #APP
-; RV32IZCMP-NEXT:    li s4, 0
+; RV32IZCMP-NEXT:    li s11, 0
 ; RV32IZCMP-NEXT:    #NO_APP
-; RV32IZCMP-NEXT:    cm.popret {ra, s0-s4}, 32
+; RV32IZCMP-NEXT:    cm.popret {ra, s0-s11}, 64
 ;
 ; RV32IZCMP-WITH-FP-LABEL: foo:
 ; RV32IZCMP-WITH-FP:       # %bb.0: # %entry
@@ -2044,18 +2044,18 @@ define void @foo() {
 ; RV32IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 16
 ; RV32IZCMP-WITH-FP-NEXT:    sw ra, 12(sp) # 4-byte Folded Spill
 ; RV32IZCMP-WITH-FP-NEXT:    sw s0, 8(sp) # 4-byte Folded Spill
-; RV32IZCMP-WITH-FP-NEXT:    sw s4, 4(sp) # 4-byte Folded Spill
+; RV32IZCMP-WITH-FP-NEXT:    sw s11, 4(sp) # 4-byte Folded Spill
 ; RV32IZCMP-WITH-FP-NEXT:    .cfi_offset ra, -4
 ; RV32IZCMP-WITH-FP-NEXT:    .cfi_offset s0, -8
-; RV32IZCMP-WITH-FP-NEXT:    .cfi_offset s4, -12
+; RV32IZCMP-WITH-FP-NEXT:    .cfi_offset s11, -12
 ; RV32IZCMP-WITH-FP-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-WITH-FP-NEXT:    #APP
-; RV32IZCMP-WITH-FP-NEXT:    li s4, 0
+; RV32IZCMP-WITH-FP-NEXT:    li s11, 0
 ; RV32IZCMP-WITH-FP-NEXT:    #NO_APP
 ; RV32IZCMP-WITH-FP-NEXT:    lw ra, 12(sp) # 4-byte Folded Reload
 ; RV32IZCMP-WITH-FP-NEXT:    lw s0, 8(sp) # 4-byte Folded Reload
-; RV32IZCMP-WITH-FP-NEXT:    lw s4, 4(sp) # 4-byte Folded Reload
+; RV32IZCMP-WITH-FP-NEXT:    lw s11, 4(sp) # 4-byte Folded Reload
 ; RV32IZCMP-WITH-FP-NEXT:    addi sp, sp, 16
 ; RV32IZCMP-WITH-FP-NEXT:    ret
 ;
@@ -2063,12 +2063,12 @@ define void @foo() {
 ; RV64I:       # %bb.0: # %entry
 ; RV64I-NEXT:    addi sp, sp, -16
 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
-; RV64I-NEXT:    sd s4, 8(sp) # 8-byte Folded Spill
-; RV64I-NEXT:    .cfi_offset s4, -8
+; RV64I-NEXT:    sd s11, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT:    .cfi_offset s11, -8
 ; RV64I-NEXT:    #APP
-; RV64I-NEXT:    li s4, 0
+; RV64I-NEXT:    li s11, 0
 ; RV64I-NEXT:    #NO_APP
-; RV64I-NEXT:    ld s4, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    ld s11, 8(sp) # 8-byte Folded Reload
 ; RV64I-NEXT:    addi sp, sp, 16
 ; RV64I-NEXT:    ret
 ;
@@ -2078,30 +2078,30 @@ define void @foo() {
 ; RV64I-WITH-FP-NEXT:    .cfi_def_cfa_offset 32
 ; RV64I-WITH-FP-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
 ; RV64I-WITH-FP-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
-; RV64I-WITH-FP-NEXT:    sd s4, 8(sp) # 8-byte Folded Spill
+; RV64I-WITH-FP-NEXT:    sd s11, 8(sp) # 8-byte Folded Spill
 ; RV64I-WITH-FP-NEXT:    .cfi_offset ra, -8
 ; RV64I-WITH-FP-NEXT:    .cfi_offset s0, -16
-; RV64I-WITH-FP-NEXT:    .cfi_offset s4, -24
+; RV64I-WITH-FP-NEXT:    .cfi_offset s11, -24
 ; RV64I-WITH-FP-NEXT:    addi s0, sp, 32
 ; RV64I-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64I-WITH-FP-NEXT:    #APP
-; RV64I-WITH-FP-NEXT:    li s4, 0
+; RV64I-WITH-FP-NEXT:    li s11, 0
 ; RV64I-WITH-FP-NEXT:    #NO_APP
 ; RV64I-WITH-FP-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
 ; RV64I-WITH-FP-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
-; RV64I-WITH-FP-NEXT:    ld s4, 8(sp) # 8-byte Folded Reload
+; RV64I-WITH-FP-NEXT:    ld s11, 8(sp) # 8-byte Folded Reload
 ; RV64I-WITH-FP-NEXT:    addi sp, sp, 32
 ; RV64I-WITH-FP-NEXT:    ret
 ;
 ; RV64IZCMP-LABEL: foo:
 ; RV64IZCMP:       # %bb.0: # %entry
-; RV64IZCMP-NEXT:    cm.push {ra, s0-s4}, -48
-; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 48
-; RV64IZCMP-NEXT:    .cfi_offset s4, -8
+; RV64IZCMP-NEXT:    cm.push {ra, s0-s11}, -112
+; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 112
+; RV64IZCMP-NEXT:    .cfi_offset s11, -8
 ; RV64IZCMP-NEXT:    #APP
-; RV64IZCMP-NEXT:    li s4, 0
+; RV64IZCMP-NEXT:    li s11, 0
 ; RV64IZCMP-NEXT:    #NO_APP
-; RV64IZCMP-NEXT:    cm.popret {ra, s0-s4}, 48
+; RV64IZCMP-NEXT:    cm.popret {ra, s0-s11}, 112
 ;
 ; RV64IZCMP-WITH-FP-LABEL: foo:
 ; RV64IZCMP-WITH-FP:       # %bb.0: # %entry
@@ -2109,22 +2109,22 @@ define void @foo() {
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 32
 ; RV64IZCMP-WITH-FP-NEXT:    sd ra, 24(sp) # 8-byte Folded Spill
 ; RV64IZCMP-WITH-FP-NEXT:    sd s0, 16(sp) # 8-byte Folded Spill
-; RV64IZCMP-WITH-FP-NEXT:    sd s4, 8(sp) # 8-byte Folded Spill
+; RV64IZCMP-WITH-FP-NEXT:    sd s11, 8(sp) # 8-byte Folded Spill
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_offset ra, -8
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_offset s0, -16
-; RV64IZCMP-WITH-FP-NEXT:    .cfi_offset s4, -24
+; RV64IZCMP-WITH-FP-NEXT:    .cfi_offset s11, -24
 ; RV64IZCMP-WITH-FP-NEXT:    addi s0, sp, 32
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-WITH-FP-NEXT:    #APP
-; RV64IZCMP-WITH-FP-NEXT:    li s4, 0
+; RV64IZCMP-WITH-FP-NEXT:    li s11, 0
 ; RV64IZCMP-WITH-FP-NEXT:    #NO_APP
 ; RV64IZCMP-WITH-FP-NEXT:    ld ra, 24(sp) # 8-byte Folded Reload
 ; RV64IZCMP-WITH-FP-NEXT:    ld s0, 16(sp) # 8-byte Folded Reload
-; RV64IZCMP-WITH-FP-NEXT:    ld s4, 8(sp) # 8-byte Folded Reload
+; RV64IZCMP-WITH-FP-NEXT:    ld s11, 8(sp) # 8-byte Folded Reload
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, 32
 ; RV64IZCMP-WITH-FP-NEXT:    ret
 entry:
-  tail call void asm sideeffect "li s4, 0", "~{s4}"()
+  tail call void asm sideeffect "li s11, 0", "~{s11}"()
   ret void
 }
 



More information about the llvm-commits mailing list