[llvm] d6a48a3 - [RISCV] Fix the CFI offset for callee-saved registers stored by Zcmp push.

Jim Lin via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 1 22:09:26 PDT 2023


Author: Jim Lin
Date: 2023-08-02T13:03:21+08:00
New Revision: d6a48a348ad0096e1e97dadaa6dcbeaf49db718b

URL: https://github.com/llvm/llvm-project/commit/d6a48a348ad0096e1e97dadaa6dcbeaf49db718b
DIFF: https://github.com/llvm/llvm-project/commit/d6a48a348ad0096e1e97dadaa6dcbeaf49db718b.diff

LOG: [RISCV] Fix the CFI offset for callee-saved registers stored by Zcmp push.

Issue mentioned: https://github.com/riscv/riscv-code-size-reduction/issues/182

The order of callee-saved registers stored by Zcmp push in memory is reversed.

Pseudo code for cm.push in https://github.com/riscv/riscv-code-size-reduction/releases/download/v1.0.4-1/Zc.1.0.4-1.pdf

```
if (XLEN==32) bytes=4; else bytes=8;

addr=sp-bytes;
for(i in 27,26,25,24,23,22,21,20,19,18,9,8,1)  {
  //if register i is in xreg_list
  if (xreg_list[i]) {
    switch(bytes) {
      4:  asm("sw x[i], 0(addr)");
      8:  asm("sd x[i], 0(addr)");
    }
    addr-=bytes;
  }
}
```

The placement order for push is s11, s10, ..., ra.

CFI offset should be calculed as reversed order for correct stack unwinding.

Reviewed By: fakepaper56, kito-cheng

Differential Revision: https://reviews.llvm.org/D156437

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
    llvm/test/CodeGen/RISCV/push-pop-popret.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 9c424423eb4a38..7c01991fca0037 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -581,11 +581,18 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
     int64_t Offset;
     // Offsets for objects with fixed locations (IE: those saved by libcall) are
     // simply calculated from the frame index.
-    if (FrameIdx < 0)
-      Offset = FrameIdx * (int64_t) STI.getXLen() / 8;
-    else
+    if (FrameIdx < 0) {
+      if (RVFI->isPushable(MF)) {
+        // Callee-saved register stored by Zcmp push is in reverse order.
+        Offset = -(FrameIdx + RVFI->getRVPushRegs() + 1) *
+                 (int64_t)STI.getXLen() / 8;
+      } else {
+        Offset = FrameIdx * (int64_t)STI.getXLen() / 8;
+      }
+    } else {
       Offset = MFI.getObjectOffset(FrameIdx) -
                RVFI->getLibCallStackSize();
+    }
     Register Reg = Entry.getReg();
     unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
         nullptr, RI->getDwarfRegNum(Reg, true), Offset));

diff  --git a/llvm/test/CodeGen/RISCV/push-pop-popret.ll b/llvm/test/CodeGen/RISCV/push-pop-popret.ll
index 2b50cbbaded7b3..af3828ed7d839c 100644
--- a/llvm/test/CodeGen/RISCV/push-pop-popret.ll
+++ b/llvm/test/CodeGen/RISCV/push-pop-popret.ll
@@ -99,8 +99,8 @@ define i32 @pushpopret0(i32 signext %size){
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV32IZCMP-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-NEXT:    .cfi_offset ra, -8
+; RV32IZCMP-NEXT:    .cfi_offset s0, -4
 ; RV32IZCMP-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-NEXT:    addi a0, a0, 15
@@ -115,8 +115,8 @@ define i32 @pushpopret0(i32 signext %size){
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV64IZCMP-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-NEXT:    .cfi_offset ra, -16
+; RV64IZCMP-NEXT:    .cfi_offset s0, -8
 ; RV64IZCMP-NEXT:    addi s0, sp, 16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-NEXT:    slli a0, a0, 32
@@ -221,8 +221,8 @@ define i32 @pushpopret1(i32 signext %size) {
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV32IZCMP-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-NEXT:    .cfi_offset ra, -8
+; RV32IZCMP-NEXT:    .cfi_offset s0, -4
 ; RV32IZCMP-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-NEXT:    addi a0, a0, 15
@@ -238,8 +238,8 @@ define i32 @pushpopret1(i32 signext %size) {
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV64IZCMP-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-NEXT:    .cfi_offset ra, -16
+; RV64IZCMP-NEXT:    .cfi_offset s0, -8
 ; RV64IZCMP-NEXT:    addi s0, sp, 16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-NEXT:    slli a0, a0, 32
@@ -345,8 +345,8 @@ define i32 @pushpopretneg1(i32 signext %size) {
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV32IZCMP-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-NEXT:    .cfi_offset ra, -8
+; RV32IZCMP-NEXT:    .cfi_offset s0, -4
 ; RV32IZCMP-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-NEXT:    addi a0, a0, 15
@@ -362,8 +362,8 @@ define i32 @pushpopretneg1(i32 signext %size) {
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV64IZCMP-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-NEXT:    .cfi_offset ra, -16
+; RV64IZCMP-NEXT:    .cfi_offset s0, -8
 ; RV64IZCMP-NEXT:    addi s0, sp, 16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-NEXT:    slli a0, a0, 32
@@ -469,8 +469,8 @@ define i32 @pushpopret2(i32 signext %size) {
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV32IZCMP-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-NEXT:    .cfi_offset ra, -8
+; RV32IZCMP-NEXT:    .cfi_offset s0, -4
 ; RV32IZCMP-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-NEXT:    addi a0, a0, 15
@@ -486,8 +486,8 @@ define i32 @pushpopret2(i32 signext %size) {
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV64IZCMP-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-NEXT:    .cfi_offset ra, -16
+; RV64IZCMP-NEXT:    .cfi_offset s0, -8
 ; RV64IZCMP-NEXT:    addi s0, sp, 16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-NEXT:    slli a0, a0, 32
@@ -593,8 +593,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV32IZCMP-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-NEXT:    .cfi_offset ra, -8
+; RV32IZCMP-NEXT:    .cfi_offset s0, -4
 ; RV32IZCMP-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-NEXT:    addi a0, a0, 15
@@ -609,8 +609,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0}, -16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 16
-; RV64IZCMP-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-NEXT:    .cfi_offset ra, -16
+; RV64IZCMP-NEXT:    .cfi_offset s0, -8
 ; RV64IZCMP-NEXT:    addi s0, sp, 16
 ; RV64IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-NEXT:    slli a0, a0, 32
@@ -627,8 +627,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
 ; RV32IZCMP-SR:       # %bb.0: # %entry
 ; RV32IZCMP-SR-NEXT:    cm.push {ra, s0}, -16
 ; RV32IZCMP-SR-NEXT:    .cfi_def_cfa_offset 16
-; RV32IZCMP-SR-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-SR-NEXT:    .cfi_offset s0, -8
+; RV32IZCMP-SR-NEXT:    .cfi_offset ra, -8
+; RV32IZCMP-SR-NEXT:    .cfi_offset s0, -4
 ; RV32IZCMP-SR-NEXT:    addi s0, sp, 16
 ; RV32IZCMP-SR-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-SR-NEXT:    addi a0, a0, 15
@@ -643,8 +643,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
 ; RV64IZCMP-SR:       # %bb.0: # %entry
 ; RV64IZCMP-SR-NEXT:    cm.push {ra, s0}, -16
 ; RV64IZCMP-SR-NEXT:    .cfi_def_cfa_offset 16
-; RV64IZCMP-SR-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-SR-NEXT:    .cfi_offset s0, -16
+; RV64IZCMP-SR-NEXT:    .cfi_offset ra, -16
+; RV64IZCMP-SR-NEXT:    .cfi_offset s0, -8
 ; RV64IZCMP-SR-NEXT:    addi s0, sp, 16
 ; RV64IZCMP-SR-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-SR-NEXT:    slli a0, a0, 32
@@ -710,16 +710,16 @@ define i32 @nocompress(i32 signext %size) {
 ; RV32IZCMP:       # %bb.0: # %entry
 ; RV32IZCMP-NEXT:    cm.push {ra, s0-s8}, -48
 ; RV32IZCMP-NEXT:    .cfi_def_cfa_offset 48
-; RV32IZCMP-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-NEXT:    .cfi_offset s0, -8
-; RV32IZCMP-NEXT:    .cfi_offset s1, -12
-; RV32IZCMP-NEXT:    .cfi_offset s2, -16
-; RV32IZCMP-NEXT:    .cfi_offset s3, -20
-; RV32IZCMP-NEXT:    .cfi_offset s4, -24
-; RV32IZCMP-NEXT:    .cfi_offset s5, -28
-; RV32IZCMP-NEXT:    .cfi_offset s6, -32
-; RV32IZCMP-NEXT:    .cfi_offset s7, -36
-; RV32IZCMP-NEXT:    .cfi_offset s8, -40
+; RV32IZCMP-NEXT:    .cfi_offset ra, -40
+; RV32IZCMP-NEXT:    .cfi_offset s0, -36
+; RV32IZCMP-NEXT:    .cfi_offset s1, -32
+; RV32IZCMP-NEXT:    .cfi_offset s2, -28
+; RV32IZCMP-NEXT:    .cfi_offset s3, -24
+; RV32IZCMP-NEXT:    .cfi_offset s4, -20
+; RV32IZCMP-NEXT:    .cfi_offset s5, -16
+; RV32IZCMP-NEXT:    .cfi_offset s6, -12
+; RV32IZCMP-NEXT:    .cfi_offset s7, -8
+; RV32IZCMP-NEXT:    .cfi_offset s8, -4
 ; RV32IZCMP-NEXT:    addi s0, sp, 48
 ; RV32IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-NEXT:    addi a0, a0, 15
@@ -749,16 +749,16 @@ define i32 @nocompress(i32 signext %size) {
 ; RV64IZCMP:       # %bb.0: # %entry
 ; RV64IZCMP-NEXT:    cm.push {ra, s0-s8}, -80
 ; RV64IZCMP-NEXT:    .cfi_def_cfa_offset 80
-; RV64IZCMP-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-NEXT:    .cfi_offset s0, -16
-; RV64IZCMP-NEXT:    .cfi_offset s1, -24
-; RV64IZCMP-NEXT:    .cfi_offset s2, -32
-; RV64IZCMP-NEXT:    .cfi_offset s3, -40
-; RV64IZCMP-NEXT:    .cfi_offset s4, -48
-; RV64IZCMP-NEXT:    .cfi_offset s5, -56
-; RV64IZCMP-NEXT:    .cfi_offset s6, -64
-; RV64IZCMP-NEXT:    .cfi_offset s7, -72
-; RV64IZCMP-NEXT:    .cfi_offset s8, -80
+; RV64IZCMP-NEXT:    .cfi_offset ra, -80
+; RV64IZCMP-NEXT:    .cfi_offset s0, -72
+; RV64IZCMP-NEXT:    .cfi_offset s1, -64
+; RV64IZCMP-NEXT:    .cfi_offset s2, -56
+; RV64IZCMP-NEXT:    .cfi_offset s3, -48
+; RV64IZCMP-NEXT:    .cfi_offset s4, -40
+; RV64IZCMP-NEXT:    .cfi_offset s5, -32
+; RV64IZCMP-NEXT:    .cfi_offset s6, -24
+; RV64IZCMP-NEXT:    .cfi_offset s7, -16
+; RV64IZCMP-NEXT:    .cfi_offset s8, -8
 ; RV64IZCMP-NEXT:    addi s0, sp, 80
 ; RV64IZCMP-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-NEXT:    slli a0, a0, 32
@@ -790,16 +790,16 @@ define i32 @nocompress(i32 signext %size) {
 ; RV32IZCMP-SR:       # %bb.0: # %entry
 ; RV32IZCMP-SR-NEXT:    cm.push {ra, s0-s8}, -48
 ; RV32IZCMP-SR-NEXT:    .cfi_def_cfa_offset 48
-; RV32IZCMP-SR-NEXT:    .cfi_offset ra, -4
-; RV32IZCMP-SR-NEXT:    .cfi_offset s0, -8
-; RV32IZCMP-SR-NEXT:    .cfi_offset s1, -12
-; RV32IZCMP-SR-NEXT:    .cfi_offset s2, -16
-; RV32IZCMP-SR-NEXT:    .cfi_offset s3, -20
-; RV32IZCMP-SR-NEXT:    .cfi_offset s4, -24
-; RV32IZCMP-SR-NEXT:    .cfi_offset s5, -28
-; RV32IZCMP-SR-NEXT:    .cfi_offset s6, -32
-; RV32IZCMP-SR-NEXT:    .cfi_offset s7, -36
-; RV32IZCMP-SR-NEXT:    .cfi_offset s8, -40
+; RV32IZCMP-SR-NEXT:    .cfi_offset ra, -40
+; RV32IZCMP-SR-NEXT:    .cfi_offset s0, -36
+; RV32IZCMP-SR-NEXT:    .cfi_offset s1, -32
+; RV32IZCMP-SR-NEXT:    .cfi_offset s2, -28
+; RV32IZCMP-SR-NEXT:    .cfi_offset s3, -24
+; RV32IZCMP-SR-NEXT:    .cfi_offset s4, -20
+; RV32IZCMP-SR-NEXT:    .cfi_offset s5, -16
+; RV32IZCMP-SR-NEXT:    .cfi_offset s6, -12
+; RV32IZCMP-SR-NEXT:    .cfi_offset s7, -8
+; RV32IZCMP-SR-NEXT:    .cfi_offset s8, -4
 ; RV32IZCMP-SR-NEXT:    addi s0, sp, 48
 ; RV32IZCMP-SR-NEXT:    .cfi_def_cfa s0, 0
 ; RV32IZCMP-SR-NEXT:    addi a0, a0, 15
@@ -829,16 +829,16 @@ define i32 @nocompress(i32 signext %size) {
 ; RV64IZCMP-SR:       # %bb.0: # %entry
 ; RV64IZCMP-SR-NEXT:    cm.push {ra, s0-s8}, -80
 ; RV64IZCMP-SR-NEXT:    .cfi_def_cfa_offset 80
-; RV64IZCMP-SR-NEXT:    .cfi_offset ra, -8
-; RV64IZCMP-SR-NEXT:    .cfi_offset s0, -16
-; RV64IZCMP-SR-NEXT:    .cfi_offset s1, -24
-; RV64IZCMP-SR-NEXT:    .cfi_offset s2, -32
-; RV64IZCMP-SR-NEXT:    .cfi_offset s3, -40
-; RV64IZCMP-SR-NEXT:    .cfi_offset s4, -48
-; RV64IZCMP-SR-NEXT:    .cfi_offset s5, -56
-; RV64IZCMP-SR-NEXT:    .cfi_offset s6, -64
-; RV64IZCMP-SR-NEXT:    .cfi_offset s7, -72
-; RV64IZCMP-SR-NEXT:    .cfi_offset s8, -80
+; RV64IZCMP-SR-NEXT:    .cfi_offset ra, -80
+; RV64IZCMP-SR-NEXT:    .cfi_offset s0, -72
+; RV64IZCMP-SR-NEXT:    .cfi_offset s1, -64
+; RV64IZCMP-SR-NEXT:    .cfi_offset s2, -56
+; RV64IZCMP-SR-NEXT:    .cfi_offset s3, -48
+; RV64IZCMP-SR-NEXT:    .cfi_offset s4, -40
+; RV64IZCMP-SR-NEXT:    .cfi_offset s5, -32
+; RV64IZCMP-SR-NEXT:    .cfi_offset s6, -24
+; RV64IZCMP-SR-NEXT:    .cfi_offset s7, -16
+; RV64IZCMP-SR-NEXT:    .cfi_offset s8, -8
 ; RV64IZCMP-SR-NEXT:    addi s0, sp, 80
 ; RV64IZCMP-SR-NEXT:    .cfi_def_cfa s0, 0
 ; RV64IZCMP-SR-NEXT:    slli a0, a0, 32


        


More information about the llvm-commits mailing list