[llvm-branch-commits] [llvm] a622459 - [RISCV] Fix the CFI offset for callee-saved registers stored by Zcmp push.
Tobias Hieta via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Aug 3 00:03:13 PDT 2023
Author: Jim Lin
Date: 2023-08-03T09:01:18+02:00
New Revision: a6224595f957933392699e4153bfb0fddfb7d495
URL: https://github.com/llvm/llvm-project/commit/a6224595f957933392699e4153bfb0fddfb7d495
DIFF: https://github.com/llvm/llvm-project/commit/a6224595f957933392699e4153bfb0fddfb7d495.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 ca2d9474d1edfd..b38c7ae5e674e9 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(Entry.getFrameIdx()) -
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-branch-commits
mailing list