[RISCV] Fix CFA when doing split sp adjustment with fp
authorLuís Marques <luismarques@lowrisc.org>
Sun, 10 Nov 2019 16:04:43 +0000 (16:04 +0000)
committerLuís Marques <luismarques@lowrisc.org>
Sun, 10 Nov 2019 16:09:14 +0000 (16:09 +0000)
Summary: When using the split sp adjustment and using the frame-pointer
we were still emitting CFI CFA directives based on the sp value. The
final sp-based offset also didn't reflect the two-stage sp adjust. There
remain CFI issues that aren't related to the split sp adjustment, and
thus will be addressed in a separate patch.

Reviewers: asb, lenary, shiva0217
Reviewed By: lenary, shiva0217
Tags: #llvm
Differential Revision: https://reviews.llvm.org/D69385

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
llvm/test/CodeGen/RISCV/large-stack.ll
llvm/test/CodeGen/RISCV/vararg.ll

index 6344ed4..1aef67f 100644 (file)
@@ -195,11 +195,16 @@ void RISCVFrameLowering::emitPrologue(MachineFunction &MF,
            "SecondSPAdjustAmount should be greater than zero");
     adjustReg(MBB, MBBI, DL, SPReg, SPReg, -SecondSPAdjustAmount,
               MachineInstr::FrameSetup);
-    // Emit ".cfi_def_cfa_offset StackSize"
-    unsigned CFIIndex = MF.addFrameInst(
-        MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize()));
-    BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex);
+
+    // If we are using a frame-pointer, and thus emitted ".cfi_def_cfa fp, 0",
+    // don't emit an sp-based .cfi_def_cfa_offset
+    if (!hasFP(MF)) {
+      // Emit ".cfi_def_cfa_offset StackSize"
+      unsigned CFIIndex = MF.addFrameInst(
+          MCCFIInstruction::createDefCfaOffset(nullptr, -MFI.getStackSize()));
+      BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
+          .addCFIIndex(CFIIndex);
+    }
   }
 
   if (hasFP(MF)) {
@@ -267,13 +272,14 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
     adjustReg(MBB, LastFrameDestroy, DL, SPReg, SPReg, SecondSPAdjustAmount,
               MachineInstr::FrameDestroy);
 
-    // Emit ".cfi_def_cfa_offset FirstSPAdjustAmount"
-    unsigned CFIIndex =
-        MF.addFrameInst(
-             MCCFIInstruction::createDefCfaOffset(nullptr,
-                                                  -FirstSPAdjustAmount));
-    BuildMI(MBB, LastFrameDestroy, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
-        .addCFIIndex(CFIIndex);
+    // Emit ".cfi_def_cfa_offset FirstSPAdjustAmount" if using an sp-based CFA
+    if (!hasFP(MF)) {
+      unsigned CFIIndex = MF.addFrameInst(
+          MCCFIInstruction::createDefCfaOffset(nullptr, -FirstSPAdjustAmount));
+      BuildMI(MBB, LastFrameDestroy, DL,
+              TII->get(TargetOpcode::CFI_INSTRUCTION))
+          .addCFIIndex(CFIIndex);
+    }
   }
 
   if (hasFP(MF)) {
@@ -283,10 +289,14 @@ void RISCVFrameLowering::emitEpilogue(MachineFunction &MF,
         Register DestReg = I->getOperand(0).getReg();
         if (DestReg == FPReg) {
           // If there is frame pointer, after restoring $fp registers, we
-          // need adjust CFA to ($sp - FPOffset).
-          // Emit ".cfi_def_cfa $sp, -FPOffset"
+          // need adjust CFA back to the correct sp-based offset.
+          // Emit ".cfi_def_cfa $sp, CFAOffset"
+          uint64_t CFAOffset =
+              FirstSPAdjustAmount
+                  ? -FirstSPAdjustAmount + RVFI->getVarArgsSaveSize()
+                  : -FPOffset;
           unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
-              nullptr, RI->getDwarfRegNum(SPReg, true), -FPOffset));
+              nullptr, RI->getDwarfRegNum(SPReg, true), CFAOffset));
           BuildMI(MBB, std::next(I), DL,
                   TII->get(TargetOpcode::CFI_INSTRUCTION))
               .addCFIIndex(CFIIndex);
index 48e09eb..7808698 100644 (file)
@@ -32,13 +32,11 @@ define void @test() {
 ; RV32I-WITHFP-NEXT:    lui a0, 74565
 ; RV32I-WITHFP-NEXT:    addi a0, a0, -352
 ; RV32I-WITHFP-NEXT:    sub sp, sp, a0
-; RV32I-WITHFP-NEXT:    .cfi_def_cfa_offset 305419920
 ; RV32I-WITHFP-NEXT:    lui a0, 74565
 ; RV32I-WITHFP-NEXT:    addi a0, a0, -352
 ; RV32I-WITHFP-NEXT:    add sp, sp, a0
-; RV32I-WITHFP-NEXT:    .cfi_def_cfa_offset 2032
 ; RV32I-WITHFP-NEXT:    lw s0, 2024(sp)
-; RV32I-WITHFP-NEXT:    .cfi_def_cfa sp, 305419920
+; RV32I-WITHFP-NEXT:    .cfi_def_cfa sp, 2032
 ; RV32I-WITHFP-NEXT:    lw ra, 2028(sp)
 ; RV32I-WITHFP-NEXT:    .cfi_restore ra
 ; RV32I-WITHFP-NEXT:    .cfi_restore s0
@@ -105,7 +103,6 @@ define void @test_emergency_spill_slot(i32 %a) {
 ; RV32I-WITHFP-NEXT:    lui a1, 97
 ; RV32I-WITHFP-NEXT:    addi a1, a1, 688
 ; RV32I-WITHFP-NEXT:    sub sp, sp, a1
-; RV32I-WITHFP-NEXT:    .cfi_def_cfa_offset 400032
 ; RV32I-WITHFP-NEXT:    lui a1, 78
 ; RV32I-WITHFP-NEXT:    addi a1, a1, 512
 ; RV32I-WITHFP-NEXT:    lui a2, 1048478
@@ -123,11 +120,10 @@ define void @test_emergency_spill_slot(i32 %a) {
 ; RV32I-WITHFP-NEXT:    lui a0, 97
 ; RV32I-WITHFP-NEXT:    addi a0, a0, 688
 ; RV32I-WITHFP-NEXT:    add sp, sp, a0
-; RV32I-WITHFP-NEXT:    .cfi_def_cfa_offset 2032
 ; RV32I-WITHFP-NEXT:    lw s2, 2016(sp)
 ; RV32I-WITHFP-NEXT:    lw s1, 2020(sp)
 ; RV32I-WITHFP-NEXT:    lw s0, 2024(sp)
-; RV32I-WITHFP-NEXT:    .cfi_def_cfa sp, 400032
+; RV32I-WITHFP-NEXT:    .cfi_def_cfa sp, 2032
 ; RV32I-WITHFP-NEXT:    lw ra, 2028(sp)
 ; RV32I-WITHFP-NEXT:    .cfi_restore ra
 ; RV32I-WITHFP-NEXT:    .cfi_restore s0
index 82ff64a..0918830 100644 (file)
@@ -1825,7 +1825,6 @@ define i32 @va_large_stack(i8* %fmt, ...) {
 ; ILP32-ILP32F-WITHFP-NEXT:    lui a0, 24414
 ; ILP32-ILP32F-WITHFP-NEXT:    addi a0, a0, -1728
 ; ILP32-ILP32F-WITHFP-NEXT:    sub sp, sp, a0
-; ILP32-ILP32F-WITHFP-NEXT:    .cfi_def_cfa_offset 100000048
 ; ILP32-ILP32F-WITHFP-NEXT:    mv a0, a1
 ; ILP32-ILP32F-WITHFP-NEXT:    sw a7, 28(s0)
 ; ILP32-ILP32F-WITHFP-NEXT:    sw a6, 24(s0)
@@ -1842,9 +1841,8 @@ define i32 @va_large_stack(i8* %fmt, ...) {
 ; ILP32-ILP32F-WITHFP-NEXT:    lui a1, 24414
 ; ILP32-ILP32F-WITHFP-NEXT:    addi a1, a1, -1728
 ; ILP32-ILP32F-WITHFP-NEXT:    add sp, sp, a1
-; ILP32-ILP32F-WITHFP-NEXT:    .cfi_def_cfa_offset 2032
 ; ILP32-ILP32F-WITHFP-NEXT:    lw s0, 1992(sp)
-; ILP32-ILP32F-WITHFP-NEXT:    .cfi_def_cfa sp, 100000016
+; ILP32-ILP32F-WITHFP-NEXT:    .cfi_def_cfa sp, 2000
 ; ILP32-ILP32F-WITHFP-NEXT:    lw ra, 1996(sp)
 ; ILP32-ILP32F-WITHFP-NEXT:    .cfi_restore ra
 ; ILP32-ILP32F-WITHFP-NEXT:    .cfi_restore s0
@@ -1961,7 +1959,6 @@ define i32 @va_large_stack(i8* %fmt, ...) {
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    lui a0, 24414
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    addiw a0, a0, -1680
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    sub sp, sp, a0
-; LP64-LP64F-LP64D-WITHFP-NEXT:    .cfi_def_cfa_offset 100000096
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    sd a1, 8(s0)
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    sd a7, 56(s0)
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    sd a6, 48(s0)
@@ -1979,9 +1976,8 @@ define i32 @va_large_stack(i8* %fmt, ...) {
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    lui a1, 24414
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    addiw a1, a1, -1680
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    add sp, sp, a1
-; LP64-LP64F-LP64D-WITHFP-NEXT:    .cfi_def_cfa_offset 2032
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    ld s0, 1952(sp)
-; LP64-LP64F-LP64D-WITHFP-NEXT:    .cfi_def_cfa sp, 100000032
+; LP64-LP64F-LP64D-WITHFP-NEXT:    .cfi_def_cfa sp, 1968
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    ld ra, 1960(sp)
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    .cfi_restore ra
 ; LP64-LP64F-LP64D-WITHFP-NEXT:    .cfi_restore s0