[llvm] 1b2de79 - [RISCV] Use two ADDIs to do some stack pointer adjustments.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Tue May 31 10:25:33 PDT 2022
Author: Craig Topper
Date: 2022-05-31T10:25:28-07:00
New Revision: 1b2de79ff4b27f3dee342607ee5285d870be08cb
URL: https://github.com/llvm/llvm-project/commit/1b2de79ff4b27f3dee342607ee5285d870be08cb
DIFF: https://github.com/llvm/llvm-project/commit/1b2de79ff4b27f3dee342607ee5285d870be08cb.diff
LOG: [RISCV] Use two ADDIs to do some stack pointer adjustments.
If the adjustment doesn't fit in 12 bits, try to break it into
two 12 bit values before falling back to movImm+add/sub.
This is based on a similar idea from isel.
Reviewed By: luismarques, reames
Differential Revision: https://reviews.llvm.org/D126392
Added:
Modified:
llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir
llvm/test/CodeGen/RISCV/stack-realignment.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
index 8bc5f54d91481..582a4a9796e5b 100644
--- a/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVFrameLowering.cpp
@@ -303,21 +303,43 @@ void RISCVFrameLowering::adjustReg(MachineBasicBlock &MBB,
.addReg(SrcReg)
.addImm(Val)
.setMIFlag(Flag);
- } else {
- unsigned Opc = RISCV::ADD;
- bool IsSub = Val < 0;
- if (IsSub) {
- Val = -Val;
- Opc = RISCV::SUB;
- }
+ return;
+ }
- Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
- TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag);
- BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
+ // Try to split the offset across two ADDIs. We need to keep the stack pointer
+ // aligned after each ADDI. We need to determine the maximum value we can put
+ // in each ADDI. In the negative direction, we can use -2048 which is always
+ // sufficiently aligned. In the positive direction, we need to find the
+ // largest 12-bit immediate that is aligned. Exclude -4096 since it can be
+ // created with LUI.
+ assert(getStackAlign().value() < 2048 && "Stack alignment too large");
+ int64_t MaxPosAdjStep = 2048 - getStackAlign().value();
+ if (Val > -4096 && Val <= (2 * MaxPosAdjStep)) {
+ int64_t FirstAdj = Val < 0 ? -2048 : MaxPosAdjStep;
+ Val -= FirstAdj;
+ BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
.addReg(SrcReg)
- .addReg(ScratchReg, RegState::Kill)
+ .addImm(FirstAdj)
+ .setMIFlag(Flag);
+ BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DestReg)
+ .addReg(DestReg, RegState::Kill)
+ .addImm(Val)
.setMIFlag(Flag);
+ return;
}
+
+ unsigned Opc = RISCV::ADD;
+ if (Val < 0) {
+ Val = -Val;
+ Opc = RISCV::SUB;
+ }
+
+ Register ScratchReg = MRI.createVirtualRegister(&RISCV::GPRRegClass);
+ TII->movImm(MBB, MBBI, DL, ScratchReg, Val, Flag);
+ BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg)
+ .addReg(SrcReg)
+ .addReg(ScratchReg, RegState::Kill)
+ .setMIFlag(Flag);
}
// Returns the register used to hold the frame pointer.
diff --git a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
index dab67d6c5e075..23c7c8a54aa60 100644
--- a/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/emergency-slot.mir
@@ -153,9 +153,8 @@ body: |
; CHECK-NEXT: PseudoBR %bb.2
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: bb.2:
- ; CHECK-NEXT: $x10 = frame-destroy LUI 1
- ; CHECK-NEXT: $x10 = frame-destroy ADDIW killed $x10, -1792
- ; CHECK-NEXT: $x2 = frame-destroy SUB $x8, killed $x10
+ ; CHECK-NEXT: $x2 = frame-destroy ADDI $x8, -2048
+ ; CHECK-NEXT: $x2 = frame-destroy ADDI killed $x2, -256
; CHECK-NEXT: $x2 = frame-destroy ADDI $x2, 272
; CHECK-NEXT: $x1 = LD $x2, 2024 :: (load (s64) from %stack.3)
; CHECK-NEXT: $x8 = LD $x2, 2016 :: (load (s64) from %stack.4)
diff --git a/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir b/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir
index 41261dcd5535d..579957a854bb1 100644
--- a/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir
+++ b/llvm/test/CodeGen/RISCV/rvv/large-rvv-stack-size.mir
@@ -32,9 +32,8 @@
; CHECK-NEXT: vs1r.v v25, (a0) # Unknown-size Folded Spill
; CHECK-NEXT: ld a0, 8(sp)
; CHECK-NEXT: call spillslot at plt
- ; CHECK-NEXT: lui a0, 1
- ; CHECK-NEXT: addiw a0, a0, -1792
- ; CHECK-NEXT: sub sp, s0, a0
+ ; CHECK-NEXT: addi sp, s0, -2048
+ ; CHECK-NEXT: addi sp, sp, -256
; CHECK-NEXT: addi sp, sp, 272
; CHECK-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload
; CHECK-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload
diff --git a/llvm/test/CodeGen/RISCV/stack-realignment.ll b/llvm/test/CodeGen/RISCV/stack-realignment.ll
index 8d6d097636492..18cb7dd22d45a 100644
--- a/llvm/test/CodeGen/RISCV/stack-realignment.ll
+++ b/llvm/test/CodeGen/RISCV/stack-realignment.ll
@@ -453,9 +453,8 @@ define void @caller2048() {
; RV32I-NEXT: .cfi_offset s0, -8
; RV32I-NEXT: addi s0, sp, 2032
; RV32I-NEXT: .cfi_def_cfa s0, 0
-; RV32I-NEXT: lui a0, 1
-; RV32I-NEXT: addi a0, a0, -2032
-; RV32I-NEXT: sub sp, sp, a0
+; RV32I-NEXT: addi sp, sp, -2048
+; RV32I-NEXT: addi sp, sp, -16
; RV32I-NEXT: andi sp, sp, -2048
; RV32I-NEXT: lui a0, 1
; RV32I-NEXT: addi a0, a0, -2048
@@ -463,9 +462,8 @@ define void @caller2048() {
; RV32I-NEXT: call callee at plt
; RV32I-NEXT: lui a0, 1
; RV32I-NEXT: sub sp, s0, a0
-; RV32I-NEXT: lui a0, 1
-; RV32I-NEXT: addi a0, a0, -2032
-; RV32I-NEXT: add sp, sp, a0
+; RV32I-NEXT: addi sp, sp, 2032
+; RV32I-NEXT: addi sp, sp, 32
; RV32I-NEXT: lw ra, 2028(sp) # 4-byte Folded Reload
; RV32I-NEXT: lw s0, 2024(sp) # 4-byte Folded Reload
; RV32I-NEXT: addi sp, sp, 2032
@@ -481,9 +479,8 @@ define void @caller2048() {
; RV64I-NEXT: .cfi_offset s0, -16
; RV64I-NEXT: addi s0, sp, 2032
; RV64I-NEXT: .cfi_def_cfa s0, 0
-; RV64I-NEXT: lui a0, 1
-; RV64I-NEXT: addiw a0, a0, -2032
-; RV64I-NEXT: sub sp, sp, a0
+; RV64I-NEXT: addi sp, sp, -2048
+; RV64I-NEXT: addi sp, sp, -16
; RV64I-NEXT: andi sp, sp, -2048
; RV64I-NEXT: lui a0, 1
; RV64I-NEXT: addiw a0, a0, -2048
@@ -491,9 +488,8 @@ define void @caller2048() {
; RV64I-NEXT: call callee at plt
; RV64I-NEXT: lui a0, 1
; RV64I-NEXT: sub sp, s0, a0
-; RV64I-NEXT: lui a0, 1
-; RV64I-NEXT: addiw a0, a0, -2032
-; RV64I-NEXT: add sp, sp, a0
+; RV64I-NEXT: addi sp, sp, 2032
+; RV64I-NEXT: addi sp, sp, 32
; RV64I-NEXT: ld ra, 2024(sp) # 8-byte Folded Reload
; RV64I-NEXT: ld s0, 2016(sp) # 8-byte Folded Reload
; RV64I-NEXT: addi sp, sp, 2032
More information about the llvm-commits
mailing list