[llvm] [RISCV] Fix bugs about getting register list of Zcmp push/pop. (PR #66073)

Yeting Kuo via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 18 07:04:16 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/5] [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/5] [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
 }
 

>From 2df605c8e3eea12cd90ad643c5c59b6b1a1d426d Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Fri, 15 Sep 2023 10:44:22 +0800
Subject: [PATCH 3/5] [RISCV] Preserve original test which check case only
 using s4.

---
 llvm/test/CodeGen/RISCV/callee-saved-gprs.ll | 150 ++++++++++++++++++-
 1 file changed, 143 insertions(+), 7 deletions(-)

diff --git a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
index 029cbf4624d756f..32f5a5d76c5926b 100644
--- a/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
+++ b/llvm/test/CodeGen/RISCV/callee-saved-gprs.ll
@@ -1998,6 +1998,142 @@ 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:    #APP
+; RV32I-NEXT:    li s4, 0
+; RV32I-NEXT:    #NO_APP
+; RV32I-NEXT:    lw s4, 12(sp) # 4-byte Folded Reload
+; RV32I-NEXT:    addi sp, sp, 16
+; RV32I-NEXT:    ret
+;
+; RV32I-WITH-FP-LABEL: foo:
+; RV32I-WITH-FP:       # %bb.0: # %entry
+; RV32I-WITH-FP-NEXT:    addi sp, sp, -16
+; 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:    .cfi_offset ra, -4
+; RV32I-WITH-FP-NEXT:    .cfi_offset s0, -8
+; RV32I-WITH-FP-NEXT:    .cfi_offset s4, -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:    #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:    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:    #APP
+; RV32IZCMP-NEXT:    li s4, 0
+; RV32IZCMP-NEXT:    #NO_APP
+; RV32IZCMP-NEXT:    cm.popret {ra, s0-s4}, 32
+;
+; RV32IZCMP-WITH-FP-LABEL: foo:
+; RV32IZCMP-WITH-FP:       # %bb.0: # %entry
+; RV32IZCMP-WITH-FP-NEXT:    addi sp, sp, -16
+; 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:    .cfi_offset ra, -4
+; RV32IZCMP-WITH-FP-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-WITH-FP-NEXT:    .cfi_offset s4, -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:    #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:    addi sp, sp, 16
+; RV32IZCMP-WITH-FP-NEXT:    ret
+;
+; RV64I-LABEL: 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:    #APP
+; RV64I-NEXT:    li s4, 0
+; RV64I-NEXT:    #NO_APP
+; RV64I-NEXT:    ld s4, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT:    addi sp, sp, 16
+; RV64I-NEXT:    ret
+;
+; RV64I-WITH-FP-LABEL: foo:
+; RV64I-WITH-FP:       # %bb.0: # %entry
+; RV64I-WITH-FP-NEXT:    addi sp, sp, -32
+; 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:    .cfi_offset ra, -8
+; RV64I-WITH-FP-NEXT:    .cfi_offset s0, -16
+; RV64I-WITH-FP-NEXT:    .cfi_offset s4, -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:    #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:    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:    #APP
+; RV64IZCMP-NEXT:    li s4, 0
+; RV64IZCMP-NEXT:    #NO_APP
+; RV64IZCMP-NEXT:    cm.popret {ra, s0-s4}, 48
+;
+; RV64IZCMP-WITH-FP-LABEL: foo:
+; RV64IZCMP-WITH-FP:       # %bb.0: # %entry
+; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, -32
+; 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:    .cfi_offset ra, -8
+; RV64IZCMP-WITH-FP-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-WITH-FP-NEXT:    .cfi_offset s4, -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:    #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:    addi sp, sp, 32
+; RV64IZCMP-WITH-FP-NEXT:    ret
+entry:
+  tail call void asm sideeffect "li s4, 0", "~{s4}"()
+  ret void
+}
+
+; Check .cfi_offset of s11 is correct for Zcmp.
+define void @bar() {
+; RV32I-LABEL: bar:
+; RV32I:       # %bb.0: # %entry
+; RV32I-NEXT:    addi sp, sp, -16
+; RV32I-NEXT:    .cfi_def_cfa_offset 16
 ; RV32I-NEXT:    sw s11, 12(sp) # 4-byte Folded Spill
 ; RV32I-NEXT:    .cfi_offset s11, -4
 ; RV32I-NEXT:    #APP
@@ -2007,7 +2143,7 @@ define void @foo() {
 ; RV32I-NEXT:    addi sp, sp, 16
 ; RV32I-NEXT:    ret
 ;
-; RV32I-WITH-FP-LABEL: foo:
+; RV32I-WITH-FP-LABEL: bar:
 ; RV32I-WITH-FP:       # %bb.0: # %entry
 ; RV32I-WITH-FP-NEXT:    addi sp, sp, -16
 ; RV32I-WITH-FP-NEXT:    .cfi_def_cfa_offset 16
@@ -2028,7 +2164,7 @@ define void @foo() {
 ; RV32I-WITH-FP-NEXT:    addi sp, sp, 16
 ; RV32I-WITH-FP-NEXT:    ret
 ;
-; RV32IZCMP-LABEL: foo:
+; RV32IZCMP-LABEL: bar:
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0-s11}, -64
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 64
@@ -2038,7 +2174,7 @@ define void @foo() {
 ; RV32IZCMP-NEXT:    #NO_APP
 ; RV32IZCMP-NEXT:    cm.popret {ra, s0-s11}, 64
 ;
-; RV32IZCMP-WITH-FP-LABEL: foo:
+; RV32IZCMP-WITH-FP-LABEL: bar:
 ; RV32IZCMP-WITH-FP:       # %bb.0: # %entry
 ; RV32IZCMP-WITH-FP-NEXT:    addi sp, sp, -16
 ; RV32IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 16
@@ -2059,7 +2195,7 @@ define void @foo() {
 ; RV32IZCMP-WITH-FP-NEXT:    addi sp, sp, 16
 ; RV32IZCMP-WITH-FP-NEXT:    ret
 ;
-; RV64I-LABEL: foo:
+; RV64I-LABEL: bar:
 ; RV64I:       # %bb.0: # %entry
 ; RV64I-NEXT:    addi sp, sp, -16
 ; RV64I-NEXT:    .cfi_def_cfa_offset 16
@@ -2072,7 +2208,7 @@ define void @foo() {
 ; RV64I-NEXT:    addi sp, sp, 16
 ; RV64I-NEXT:    ret
 ;
-; RV64I-WITH-FP-LABEL: foo:
+; RV64I-WITH-FP-LABEL: bar:
 ; RV64I-WITH-FP:       # %bb.0: # %entry
 ; RV64I-WITH-FP-NEXT:    addi sp, sp, -32
 ; RV64I-WITH-FP-NEXT:    .cfi_def_cfa_offset 32
@@ -2093,7 +2229,7 @@ define void @foo() {
 ; RV64I-WITH-FP-NEXT:    addi sp, sp, 32
 ; RV64I-WITH-FP-NEXT:    ret
 ;
-; RV64IZCMP-LABEL: foo:
+; RV64IZCMP-LABEL: bar:
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0-s11}, -112
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 112
@@ -2103,7 +2239,7 @@ define void @foo() {
 ; RV64IZCMP-NEXT:    #NO_APP
 ; RV64IZCMP-NEXT:    cm.popret {ra, s0-s11}, 112
 ;
-; RV64IZCMP-WITH-FP-LABEL: foo:
+; RV64IZCMP-WITH-FP-LABEL: bar:
 ; RV64IZCMP-WITH-FP:       # %bb.0: # %entry
 ; RV64IZCMP-WITH-FP-NEXT:    addi sp, sp, -32
 ; RV64IZCMP-WITH-FP-NEXT:    .cfi_def_cfa_offset 32

>From 9f8d8d5fd2b387ae1cc77dd62c382699112c8b77 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Fri, 15 Sep 2023 14:02:13 +0800
Subject: [PATCH 4/5] [RISCV] Update comments.

---
 llvm/lib/Target/RISCV/RISCVFrameLowering.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 19cd5c7738917c5..516687229024ad4 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -226,8 +226,8 @@ getRestoreLibCallName(const MachineFunction &MF,
   return RestoreLibCalls[LibCallID];
 }
 
-// Return encoded value for PUSH/POP instruction, representing
-// registers to store/load.
+// Return encoded value and register count for PUSH/POP instruction,
+// representing registers to store/load.
 static std::pair<unsigned, unsigned>
 getPushPopEncodingAndNum(const Register MaxReg) {
   switch (MaxReg) {

>From 44dc55fe3f33f2fed6f69210616c78a45b70db43 Mon Sep 17 00:00:00 2001
From: Yeting Kuo <yeting.kuo at sifive.com>
Date: Mon, 18 Sep 2023 22:02:06 +0800
Subject: [PATCH 5/5] [RISCV] Update test to not use inline asm and rename
 zcmp-crash.ll to zcmp-with-float.ll.

---
 llvm/test/CodeGen/RISCV/zcmp-crash.ll      | 21 ------------
 llvm/test/CodeGen/RISCV/zcmp-with-float.ll | 38 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 21 deletions(-)
 delete mode 100644 llvm/test/CodeGen/RISCV/zcmp-crash.ll
 create mode 100644 llvm/test/CodeGen/RISCV/zcmp-with-float.ll

diff --git a/llvm/test/CodeGen/RISCV/zcmp-crash.ll b/llvm/test/CodeGen/RISCV/zcmp-crash.ll
deleted file mode 100644
index b22085f95a3d1b0..000000000000000
--- a/llvm/test/CodeGen/RISCV/zcmp-crash.ll
+++ /dev/null
@@ -1,21 +0,0 @@
-; 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
-}
diff --git a/llvm/test/CodeGen/RISCV/zcmp-with-float.ll b/llvm/test/CodeGen/RISCV/zcmp-with-float.ll
new file mode 100644
index 000000000000000..05ee92c89db7ca2
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/zcmp-with-float.ll
@@ -0,0 +1,38 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
+; RUN: llc -mtriple=riscv32 -mattr=+f,+zcmp -target-abi ilp32f -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV32
+; RUN: llc -mtriple=riscv64 -mattr=+f,+zcmp -target-abi lp64f -verify-machineinstrs < %s | FileCheck %s --check-prefix=RV64
+
+declare void @callee()
+
+; Test the file could be compiled successfully.
+; .cfi_offset of fs0 is wrong here. It should be fixed by #66613.
+define float @foo(float %arg) {
+; RV32-LABEL: foo:
+; RV32:       # %bb.0: # %entry
+; RV32-NEXT:    cm.push {ra}, -32
+; RV32-NEXT:    .cfi_def_cfa_offset 32
+; RV32-NEXT:    fsw fs0, 12(sp) # 4-byte Folded Spill
+; RV32-NEXT:    .cfi_offset ra, -4
+; RV32-NEXT:    .cfi_offset fs0, -4
+; RV32-NEXT:    fmv.s fs0, fa0
+; RV32-NEXT:    call callee at plt
+; RV32-NEXT:    fmv.s fa0, fs0
+; RV32-NEXT:    flw fs0, 12(sp) # 4-byte Folded Reload
+; RV32-NEXT:    cm.popret {ra}, 32
+;
+; RV64-LABEL: foo:
+; RV64:       # %bb.0: # %entry
+; RV64-NEXT:    cm.push {ra}, -32
+; RV64-NEXT:    .cfi_def_cfa_offset 32
+; RV64-NEXT:    fsw fs0, 12(sp) # 4-byte Folded Spill
+; RV64-NEXT:    .cfi_offset ra, -8
+; RV64-NEXT:    .cfi_offset fs0, -4
+; RV64-NEXT:    fmv.s fs0, fa0
+; RV64-NEXT:    call callee at plt
+; RV64-NEXT:    fmv.s fa0, fs0
+; RV64-NEXT:    flw fs0, 12(sp) # 4-byte Folded Reload
+; RV64-NEXT:    cm.popret {ra}, 32
+entry:
+  call void @callee()
+  ret float %arg
+}



More information about the llvm-commits mailing list