Skip to content

Commit d6a48a3

Browse files
committed
[RISCV] Fix the CFI offset for callee-saved registers stored by Zcmp push.
Issue mentioned: riscvarchive/riscv-code-size-reduction#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
1 parent 9c38a17 commit d6a48a3

File tree

2 files changed

+74
-67
lines changed

2 files changed

+74
-67
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,11 +581,18 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
581581
int64_t Offset;
582582
// Offsets for objects with fixed locations (IE: those saved by libcall) are
583583
// simply calculated from the frame index.
584-
if (FrameIdx < 0)
585-
Offset = FrameIdx * (int64_t) STI.getXLen() / 8;
586-
else
584+
if (FrameIdx < 0) {
585+
if (RVFI->isPushable(MF)) {
586+
// Callee-saved register stored by Zcmp push is in reverse order.
587+
Offset = -(FrameIdx + RVFI->getRVPushRegs() + 1) *
588+
(int64_t)STI.getXLen() / 8;
589+
} else {
590+
Offset = FrameIdx * (int64_t)STI.getXLen() / 8;
591+
}
592+
} else {
587593
Offset = MFI.getObjectOffset(FrameIdx) -
588594
RVFI->getLibCallStackSize();
595+
}
589596
Register Reg = Entry.getReg();
590597
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createOffset(
591598
nullptr, RI->getDwarfRegNum(Reg, true), Offset));

llvm/test/CodeGen/RISCV/push-pop-popret.ll

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ define i32 @pushpopret0(i32 signext %size){
9999
; RV32IZCMP: # %bb.0: # %entry
100100
; RV32IZCMP-NEXT: cm.push {ra, s0}, -16
101101
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16
102-
; RV32IZCMP-NEXT: .cfi_offset ra, -4
103-
; RV32IZCMP-NEXT: .cfi_offset s0, -8
102+
; RV32IZCMP-NEXT: .cfi_offset ra, -8
103+
; RV32IZCMP-NEXT: .cfi_offset s0, -4
104104
; RV32IZCMP-NEXT: addi s0, sp, 16
105105
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
106106
; RV32IZCMP-NEXT: addi a0, a0, 15
@@ -115,8 +115,8 @@ define i32 @pushpopret0(i32 signext %size){
115115
; RV64IZCMP: # %bb.0: # %entry
116116
; RV64IZCMP-NEXT: cm.push {ra, s0}, -16
117117
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
118-
; RV64IZCMP-NEXT: .cfi_offset ra, -8
119-
; RV64IZCMP-NEXT: .cfi_offset s0, -16
118+
; RV64IZCMP-NEXT: .cfi_offset ra, -16
119+
; RV64IZCMP-NEXT: .cfi_offset s0, -8
120120
; RV64IZCMP-NEXT: addi s0, sp, 16
121121
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
122122
; RV64IZCMP-NEXT: slli a0, a0, 32
@@ -221,8 +221,8 @@ define i32 @pushpopret1(i32 signext %size) {
221221
; RV32IZCMP: # %bb.0: # %entry
222222
; RV32IZCMP-NEXT: cm.push {ra, s0}, -16
223223
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16
224-
; RV32IZCMP-NEXT: .cfi_offset ra, -4
225-
; RV32IZCMP-NEXT: .cfi_offset s0, -8
224+
; RV32IZCMP-NEXT: .cfi_offset ra, -8
225+
; RV32IZCMP-NEXT: .cfi_offset s0, -4
226226
; RV32IZCMP-NEXT: addi s0, sp, 16
227227
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
228228
; RV32IZCMP-NEXT: addi a0, a0, 15
@@ -238,8 +238,8 @@ define i32 @pushpopret1(i32 signext %size) {
238238
; RV64IZCMP: # %bb.0: # %entry
239239
; RV64IZCMP-NEXT: cm.push {ra, s0}, -16
240240
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
241-
; RV64IZCMP-NEXT: .cfi_offset ra, -8
242-
; RV64IZCMP-NEXT: .cfi_offset s0, -16
241+
; RV64IZCMP-NEXT: .cfi_offset ra, -16
242+
; RV64IZCMP-NEXT: .cfi_offset s0, -8
243243
; RV64IZCMP-NEXT: addi s0, sp, 16
244244
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
245245
; RV64IZCMP-NEXT: slli a0, a0, 32
@@ -345,8 +345,8 @@ define i32 @pushpopretneg1(i32 signext %size) {
345345
; RV32IZCMP: # %bb.0: # %entry
346346
; RV32IZCMP-NEXT: cm.push {ra, s0}, -16
347347
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16
348-
; RV32IZCMP-NEXT: .cfi_offset ra, -4
349-
; RV32IZCMP-NEXT: .cfi_offset s0, -8
348+
; RV32IZCMP-NEXT: .cfi_offset ra, -8
349+
; RV32IZCMP-NEXT: .cfi_offset s0, -4
350350
; RV32IZCMP-NEXT: addi s0, sp, 16
351351
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
352352
; RV32IZCMP-NEXT: addi a0, a0, 15
@@ -362,8 +362,8 @@ define i32 @pushpopretneg1(i32 signext %size) {
362362
; RV64IZCMP: # %bb.0: # %entry
363363
; RV64IZCMP-NEXT: cm.push {ra, s0}, -16
364364
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
365-
; RV64IZCMP-NEXT: .cfi_offset ra, -8
366-
; RV64IZCMP-NEXT: .cfi_offset s0, -16
365+
; RV64IZCMP-NEXT: .cfi_offset ra, -16
366+
; RV64IZCMP-NEXT: .cfi_offset s0, -8
367367
; RV64IZCMP-NEXT: addi s0, sp, 16
368368
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
369369
; RV64IZCMP-NEXT: slli a0, a0, 32
@@ -469,8 +469,8 @@ define i32 @pushpopret2(i32 signext %size) {
469469
; RV32IZCMP: # %bb.0: # %entry
470470
; RV32IZCMP-NEXT: cm.push {ra, s0}, -16
471471
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16
472-
; RV32IZCMP-NEXT: .cfi_offset ra, -4
473-
; RV32IZCMP-NEXT: .cfi_offset s0, -8
472+
; RV32IZCMP-NEXT: .cfi_offset ra, -8
473+
; RV32IZCMP-NEXT: .cfi_offset s0, -4
474474
; RV32IZCMP-NEXT: addi s0, sp, 16
475475
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
476476
; RV32IZCMP-NEXT: addi a0, a0, 15
@@ -486,8 +486,8 @@ define i32 @pushpopret2(i32 signext %size) {
486486
; RV64IZCMP: # %bb.0: # %entry
487487
; RV64IZCMP-NEXT: cm.push {ra, s0}, -16
488488
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
489-
; RV64IZCMP-NEXT: .cfi_offset ra, -8
490-
; RV64IZCMP-NEXT: .cfi_offset s0, -16
489+
; RV64IZCMP-NEXT: .cfi_offset ra, -16
490+
; RV64IZCMP-NEXT: .cfi_offset s0, -8
491491
; RV64IZCMP-NEXT: addi s0, sp, 16
492492
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
493493
; RV64IZCMP-NEXT: slli a0, a0, 32
@@ -593,8 +593,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
593593
; RV32IZCMP: # %bb.0: # %entry
594594
; RV32IZCMP-NEXT: cm.push {ra, s0}, -16
595595
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 16
596-
; RV32IZCMP-NEXT: .cfi_offset ra, -4
597-
; RV32IZCMP-NEXT: .cfi_offset s0, -8
596+
; RV32IZCMP-NEXT: .cfi_offset ra, -8
597+
; RV32IZCMP-NEXT: .cfi_offset s0, -4
598598
; RV32IZCMP-NEXT: addi s0, sp, 16
599599
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
600600
; RV32IZCMP-NEXT: addi a0, a0, 15
@@ -609,8 +609,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
609609
; RV64IZCMP: # %bb.0: # %entry
610610
; RV64IZCMP-NEXT: cm.push {ra, s0}, -16
611611
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 16
612-
; RV64IZCMP-NEXT: .cfi_offset ra, -8
613-
; RV64IZCMP-NEXT: .cfi_offset s0, -16
612+
; RV64IZCMP-NEXT: .cfi_offset ra, -16
613+
; RV64IZCMP-NEXT: .cfi_offset s0, -8
614614
; RV64IZCMP-NEXT: addi s0, sp, 16
615615
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
616616
; RV64IZCMP-NEXT: slli a0, a0, 32
@@ -627,8 +627,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
627627
; RV32IZCMP-SR: # %bb.0: # %entry
628628
; RV32IZCMP-SR-NEXT: cm.push {ra, s0}, -16
629629
; RV32IZCMP-SR-NEXT: .cfi_def_cfa_offset 16
630-
; RV32IZCMP-SR-NEXT: .cfi_offset ra, -4
631-
; RV32IZCMP-SR-NEXT: .cfi_offset s0, -8
630+
; RV32IZCMP-SR-NEXT: .cfi_offset ra, -8
631+
; RV32IZCMP-SR-NEXT: .cfi_offset s0, -4
632632
; RV32IZCMP-SR-NEXT: addi s0, sp, 16
633633
; RV32IZCMP-SR-NEXT: .cfi_def_cfa s0, 0
634634
; RV32IZCMP-SR-NEXT: addi a0, a0, 15
@@ -643,8 +643,8 @@ define dso_local i32 @tailcall(i32 signext %size) local_unnamed_addr #0 {
643643
; RV64IZCMP-SR: # %bb.0: # %entry
644644
; RV64IZCMP-SR-NEXT: cm.push {ra, s0}, -16
645645
; RV64IZCMP-SR-NEXT: .cfi_def_cfa_offset 16
646-
; RV64IZCMP-SR-NEXT: .cfi_offset ra, -8
647-
; RV64IZCMP-SR-NEXT: .cfi_offset s0, -16
646+
; RV64IZCMP-SR-NEXT: .cfi_offset ra, -16
647+
; RV64IZCMP-SR-NEXT: .cfi_offset s0, -8
648648
; RV64IZCMP-SR-NEXT: addi s0, sp, 16
649649
; RV64IZCMP-SR-NEXT: .cfi_def_cfa s0, 0
650650
; RV64IZCMP-SR-NEXT: slli a0, a0, 32
@@ -710,16 +710,16 @@ define i32 @nocompress(i32 signext %size) {
710710
; RV32IZCMP: # %bb.0: # %entry
711711
; RV32IZCMP-NEXT: cm.push {ra, s0-s8}, -48
712712
; RV32IZCMP-NEXT: .cfi_def_cfa_offset 48
713-
; RV32IZCMP-NEXT: .cfi_offset ra, -4
714-
; RV32IZCMP-NEXT: .cfi_offset s0, -8
715-
; RV32IZCMP-NEXT: .cfi_offset s1, -12
716-
; RV32IZCMP-NEXT: .cfi_offset s2, -16
717-
; RV32IZCMP-NEXT: .cfi_offset s3, -20
718-
; RV32IZCMP-NEXT: .cfi_offset s4, -24
719-
; RV32IZCMP-NEXT: .cfi_offset s5, -28
720-
; RV32IZCMP-NEXT: .cfi_offset s6, -32
721-
; RV32IZCMP-NEXT: .cfi_offset s7, -36
722-
; RV32IZCMP-NEXT: .cfi_offset s8, -40
713+
; RV32IZCMP-NEXT: .cfi_offset ra, -40
714+
; RV32IZCMP-NEXT: .cfi_offset s0, -36
715+
; RV32IZCMP-NEXT: .cfi_offset s1, -32
716+
; RV32IZCMP-NEXT: .cfi_offset s2, -28
717+
; RV32IZCMP-NEXT: .cfi_offset s3, -24
718+
; RV32IZCMP-NEXT: .cfi_offset s4, -20
719+
; RV32IZCMP-NEXT: .cfi_offset s5, -16
720+
; RV32IZCMP-NEXT: .cfi_offset s6, -12
721+
; RV32IZCMP-NEXT: .cfi_offset s7, -8
722+
; RV32IZCMP-NEXT: .cfi_offset s8, -4
723723
; RV32IZCMP-NEXT: addi s0, sp, 48
724724
; RV32IZCMP-NEXT: .cfi_def_cfa s0, 0
725725
; RV32IZCMP-NEXT: addi a0, a0, 15
@@ -749,16 +749,16 @@ define i32 @nocompress(i32 signext %size) {
749749
; RV64IZCMP: # %bb.0: # %entry
750750
; RV64IZCMP-NEXT: cm.push {ra, s0-s8}, -80
751751
; RV64IZCMP-NEXT: .cfi_def_cfa_offset 80
752-
; RV64IZCMP-NEXT: .cfi_offset ra, -8
753-
; RV64IZCMP-NEXT: .cfi_offset s0, -16
754-
; RV64IZCMP-NEXT: .cfi_offset s1, -24
755-
; RV64IZCMP-NEXT: .cfi_offset s2, -32
756-
; RV64IZCMP-NEXT: .cfi_offset s3, -40
757-
; RV64IZCMP-NEXT: .cfi_offset s4, -48
758-
; RV64IZCMP-NEXT: .cfi_offset s5, -56
759-
; RV64IZCMP-NEXT: .cfi_offset s6, -64
760-
; RV64IZCMP-NEXT: .cfi_offset s7, -72
761-
; RV64IZCMP-NEXT: .cfi_offset s8, -80
752+
; RV64IZCMP-NEXT: .cfi_offset ra, -80
753+
; RV64IZCMP-NEXT: .cfi_offset s0, -72
754+
; RV64IZCMP-NEXT: .cfi_offset s1, -64
755+
; RV64IZCMP-NEXT: .cfi_offset s2, -56
756+
; RV64IZCMP-NEXT: .cfi_offset s3, -48
757+
; RV64IZCMP-NEXT: .cfi_offset s4, -40
758+
; RV64IZCMP-NEXT: .cfi_offset s5, -32
759+
; RV64IZCMP-NEXT: .cfi_offset s6, -24
760+
; RV64IZCMP-NEXT: .cfi_offset s7, -16
761+
; RV64IZCMP-NEXT: .cfi_offset s8, -8
762762
; RV64IZCMP-NEXT: addi s0, sp, 80
763763
; RV64IZCMP-NEXT: .cfi_def_cfa s0, 0
764764
; RV64IZCMP-NEXT: slli a0, a0, 32
@@ -790,16 +790,16 @@ define i32 @nocompress(i32 signext %size) {
790790
; RV32IZCMP-SR: # %bb.0: # %entry
791791
; RV32IZCMP-SR-NEXT: cm.push {ra, s0-s8}, -48
792792
; RV32IZCMP-SR-NEXT: .cfi_def_cfa_offset 48
793-
; RV32IZCMP-SR-NEXT: .cfi_offset ra, -4
794-
; RV32IZCMP-SR-NEXT: .cfi_offset s0, -8
795-
; RV32IZCMP-SR-NEXT: .cfi_offset s1, -12
796-
; RV32IZCMP-SR-NEXT: .cfi_offset s2, -16
797-
; RV32IZCMP-SR-NEXT: .cfi_offset s3, -20
798-
; RV32IZCMP-SR-NEXT: .cfi_offset s4, -24
799-
; RV32IZCMP-SR-NEXT: .cfi_offset s5, -28
800-
; RV32IZCMP-SR-NEXT: .cfi_offset s6, -32
801-
; RV32IZCMP-SR-NEXT: .cfi_offset s7, -36
802-
; RV32IZCMP-SR-NEXT: .cfi_offset s8, -40
793+
; RV32IZCMP-SR-NEXT: .cfi_offset ra, -40
794+
; RV32IZCMP-SR-NEXT: .cfi_offset s0, -36
795+
; RV32IZCMP-SR-NEXT: .cfi_offset s1, -32
796+
; RV32IZCMP-SR-NEXT: .cfi_offset s2, -28
797+
; RV32IZCMP-SR-NEXT: .cfi_offset s3, -24
798+
; RV32IZCMP-SR-NEXT: .cfi_offset s4, -20
799+
; RV32IZCMP-SR-NEXT: .cfi_offset s5, -16
800+
; RV32IZCMP-SR-NEXT: .cfi_offset s6, -12
801+
; RV32IZCMP-SR-NEXT: .cfi_offset s7, -8
802+
; RV32IZCMP-SR-NEXT: .cfi_offset s8, -4
803803
; RV32IZCMP-SR-NEXT: addi s0, sp, 48
804804
; RV32IZCMP-SR-NEXT: .cfi_def_cfa s0, 0
805805
; RV32IZCMP-SR-NEXT: addi a0, a0, 15
@@ -829,16 +829,16 @@ define i32 @nocompress(i32 signext %size) {
829829
; RV64IZCMP-SR: # %bb.0: # %entry
830830
; RV64IZCMP-SR-NEXT: cm.push {ra, s0-s8}, -80
831831
; RV64IZCMP-SR-NEXT: .cfi_def_cfa_offset 80
832-
; RV64IZCMP-SR-NEXT: .cfi_offset ra, -8
833-
; RV64IZCMP-SR-NEXT: .cfi_offset s0, -16
834-
; RV64IZCMP-SR-NEXT: .cfi_offset s1, -24
835-
; RV64IZCMP-SR-NEXT: .cfi_offset s2, -32
836-
; RV64IZCMP-SR-NEXT: .cfi_offset s3, -40
837-
; RV64IZCMP-SR-NEXT: .cfi_offset s4, -48
838-
; RV64IZCMP-SR-NEXT: .cfi_offset s5, -56
839-
; RV64IZCMP-SR-NEXT: .cfi_offset s6, -64
840-
; RV64IZCMP-SR-NEXT: .cfi_offset s7, -72
841-
; RV64IZCMP-SR-NEXT: .cfi_offset s8, -80
832+
; RV64IZCMP-SR-NEXT: .cfi_offset ra, -80
833+
; RV64IZCMP-SR-NEXT: .cfi_offset s0, -72
834+
; RV64IZCMP-SR-NEXT: .cfi_offset s1, -64
835+
; RV64IZCMP-SR-NEXT: .cfi_offset s2, -56
836+
; RV64IZCMP-SR-NEXT: .cfi_offset s3, -48
837+
; RV64IZCMP-SR-NEXT: .cfi_offset s4, -40
838+
; RV64IZCMP-SR-NEXT: .cfi_offset s5, -32
839+
; RV64IZCMP-SR-NEXT: .cfi_offset s6, -24
840+
; RV64IZCMP-SR-NEXT: .cfi_offset s7, -16
841+
; RV64IZCMP-SR-NEXT: .cfi_offset s8, -8
842842
; RV64IZCMP-SR-NEXT: addi s0, sp, 80
843843
; RV64IZCMP-SR-NEXT: .cfi_def_cfa s0, 0
844844
; RV64IZCMP-SR-NEXT: slli a0, a0, 32

0 commit comments

Comments
 (0)