[llvm] [RISCV] Merge ADDI with X0 into base offset (PR #78940)
Jim Lin via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 21 21:53:26 PST 2024
https://github.com/tclin914 updated https://github.com/llvm/llvm-project/pull/78940
>From 9386574d4a7c211af7872aca9ae43e2fd1cfa83b Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Mon, 22 Jan 2024 13:18:44 +0800
Subject: [PATCH 1/2] [RISCV] Merge ADDI with X0 into base offset
If offset is `addi rd, x0, imm`, merge imm into base offset.
---
.../lib/Target/RISCV/RISCVMergeBaseOffset.cpp | 51 +++++++++++--------
.../test/CodeGen/RISCV/fold-addi-loadstore.ll | 28 +++-------
2 files changed, 37 insertions(+), 42 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index 866b2453579cc3..9513d858b15b48 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -193,29 +193,36 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
if (AddiImmOp.getTargetFlags() != RISCVII::MO_None)
return false;
Register AddiReg = OffsetTail.getOperand(1).getReg();
- if (!AddiReg.isVirtual())
- return false;
int64_t OffLo = AddiImmOp.getImm();
- MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg);
- MachineOperand &LuiImmOp = OffsetLui.getOperand(1);
- if (OffsetLui.getOpcode() != RISCV::LUI ||
- LuiImmOp.getTargetFlags() != RISCVII::MO_None ||
- !MRI->hasOneUse(OffsetLui.getOperand(0).getReg()))
- return false;
- int64_t Offset = SignExtend64<32>(LuiImmOp.getImm() << 12);
- Offset += OffLo;
- // RV32 ignores the upper 32 bits. ADDIW sign extends the result.
- if (!ST->is64Bit() || OffsetTail.getOpcode() == RISCV::ADDIW)
- Offset = SignExtend64<32>(Offset);
- // We can only fold simm32 offsets.
- if (!isInt<32>(Offset))
- return false;
- LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail
- << " " << OffsetLui);
- foldOffset(Hi, Lo, TailAdd, Offset);
- OffsetTail.eraseFromParent();
- OffsetLui.eraseFromParent();
- return true;
+ // Handle rs1 of ADDI is X0.
+ if (AddiReg == RISCV::X0) {
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail);
+ int64_t Offset = OffLo;
+ foldOffset(Hi, Lo, TailAdd, Offset);
+ OffsetTail.eraseFromParent();
+ return true;
+ } else {
+ MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg);
+ MachineOperand &LuiImmOp = OffsetLui.getOperand(1);
+ if (OffsetLui.getOpcode() != RISCV::LUI ||
+ LuiImmOp.getTargetFlags() != RISCVII::MO_None ||
+ !MRI->hasOneUse(OffsetLui.getOperand(0).getReg()))
+ return false;
+ int64_t Offset = SignExtend64<32>(LuiImmOp.getImm() << 12);
+ Offset += OffLo;
+ // RV32 ignores the upper 32 bits. ADDIW sign extends the result.
+ if (!ST->is64Bit() || OffsetTail.getOpcode() == RISCV::ADDIW)
+ Offset = SignExtend64<32>(Offset);
+ // We can only fold simm32 offsets.
+ if (!isInt<32>(Offset))
+ return false;
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail
+ << " " << OffsetLui);
+ foldOffset(Hi, Lo, TailAdd, Offset);
+ OffsetTail.eraseFromParent();
+ OffsetLui.eraseFromParent();
+ return true;
+ }
} else if (OffsetTail.getOpcode() == RISCV::LUI) {
// The offset value has all zero bits in the lower 12 bits. Only LUI
// exists.
diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
index 74652cbc73b601..91e73992bdfa3b 100644
--- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
+++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll
@@ -971,11 +971,8 @@ declare void @f(ptr)
define i32 @crash() {
; RV32I-LABEL: crash:
; RV32I: # %bb.0: # %entry
-; RV32I-NEXT: li a0, 1
-; RV32I-NEXT: lui a1, %hi(g)
-; RV32I-NEXT: addi a1, a1, %lo(g)
-; RV32I-NEXT: add a0, a1, a0
-; RV32I-NEXT: lbu a0, 400(a0)
+; RV32I-NEXT: lui a0, %hi(g+401)
+; RV32I-NEXT: lbu a0, %lo(g+401)(a0)
; RV32I-NEXT: seqz a0, a0
; RV32I-NEXT: sw a0, 0(zero)
; RV32I-NEXT: li a0, 0
@@ -983,12 +980,9 @@ define i32 @crash() {
;
; RV32I-MEDIUM-LABEL: crash:
; RV32I-MEDIUM: # %bb.0: # %entry
-; RV32I-MEDIUM-NEXT: li a0, 1
; RV32I-MEDIUM-NEXT: .Lpcrel_hi14:
-; RV32I-MEDIUM-NEXT: auipc a1, %pcrel_hi(g)
-; RV32I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi14)
-; RV32I-MEDIUM-NEXT: add a0, a1, a0
-; RV32I-MEDIUM-NEXT: lbu a0, 400(a0)
+; RV32I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g+401)
+; RV32I-MEDIUM-NEXT: lbu a0, %pcrel_lo(.Lpcrel_hi14)(a0)
; RV32I-MEDIUM-NEXT: seqz a0, a0
; RV32I-MEDIUM-NEXT: sw a0, 0(zero)
; RV32I-MEDIUM-NEXT: li a0, 0
@@ -996,11 +990,8 @@ define i32 @crash() {
;
; RV64I-LABEL: crash:
; RV64I: # %bb.0: # %entry
-; RV64I-NEXT: li a0, 1
-; RV64I-NEXT: lui a1, %hi(g)
-; RV64I-NEXT: addi a1, a1, %lo(g)
-; RV64I-NEXT: add a0, a1, a0
-; RV64I-NEXT: lbu a0, 400(a0)
+; RV64I-NEXT: lui a0, %hi(g+401)
+; RV64I-NEXT: lbu a0, %lo(g+401)(a0)
; RV64I-NEXT: seqz a0, a0
; RV64I-NEXT: sw a0, 0(zero)
; RV64I-NEXT: li a0, 0
@@ -1008,12 +999,9 @@ define i32 @crash() {
;
; RV64I-MEDIUM-LABEL: crash:
; RV64I-MEDIUM: # %bb.0: # %entry
-; RV64I-MEDIUM-NEXT: li a0, 1
; RV64I-MEDIUM-NEXT: .Lpcrel_hi14:
-; RV64I-MEDIUM-NEXT: auipc a1, %pcrel_hi(g)
-; RV64I-MEDIUM-NEXT: addi a1, a1, %pcrel_lo(.Lpcrel_hi14)
-; RV64I-MEDIUM-NEXT: add a0, a1, a0
-; RV64I-MEDIUM-NEXT: lbu a0, 400(a0)
+; RV64I-MEDIUM-NEXT: auipc a0, %pcrel_hi(g+401)
+; RV64I-MEDIUM-NEXT: lbu a0, %pcrel_lo(.Lpcrel_hi14)(a0)
; RV64I-MEDIUM-NEXT: seqz a0, a0
; RV64I-MEDIUM-NEXT: sw a0, 0(zero)
; RV64I-MEDIUM-NEXT: li a0, 0
>From 35104ab1629bededc41a84d6cd0cdfa2aadecb7b Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Mon, 22 Jan 2024 13:48:54 +0800
Subject: [PATCH 2/2] Remove unnecessary the else.
---
.../lib/Target/RISCV/RISCVMergeBaseOffset.cpp | 43 ++++++++++---------
1 file changed, 22 insertions(+), 21 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index 9513d858b15b48..1e05e0917f9652 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -194,6 +194,7 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
return false;
Register AddiReg = OffsetTail.getOperand(1).getReg();
int64_t OffLo = AddiImmOp.getImm();
+
// Handle rs1 of ADDI is X0.
if (AddiReg == RISCV::X0) {
LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail);
@@ -201,28 +202,28 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
foldOffset(Hi, Lo, TailAdd, Offset);
OffsetTail.eraseFromParent();
return true;
- } else {
- MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg);
- MachineOperand &LuiImmOp = OffsetLui.getOperand(1);
- if (OffsetLui.getOpcode() != RISCV::LUI ||
- LuiImmOp.getTargetFlags() != RISCVII::MO_None ||
- !MRI->hasOneUse(OffsetLui.getOperand(0).getReg()))
- return false;
- int64_t Offset = SignExtend64<32>(LuiImmOp.getImm() << 12);
- Offset += OffLo;
- // RV32 ignores the upper 32 bits. ADDIW sign extends the result.
- if (!ST->is64Bit() || OffsetTail.getOpcode() == RISCV::ADDIW)
- Offset = SignExtend64<32>(Offset);
- // We can only fold simm32 offsets.
- if (!isInt<32>(Offset))
- return false;
- LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail
- << " " << OffsetLui);
- foldOffset(Hi, Lo, TailAdd, Offset);
- OffsetTail.eraseFromParent();
- OffsetLui.eraseFromParent();
- return true;
}
+
+ MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg);
+ MachineOperand &LuiImmOp = OffsetLui.getOperand(1);
+ if (OffsetLui.getOpcode() != RISCV::LUI ||
+ LuiImmOp.getTargetFlags() != RISCVII::MO_None ||
+ !MRI->hasOneUse(OffsetLui.getOperand(0).getReg()))
+ return false;
+ int64_t Offset = SignExtend64<32>(LuiImmOp.getImm() << 12);
+ Offset += OffLo;
+ // RV32 ignores the upper 32 bits. ADDIW sign extends the result.
+ if (!ST->is64Bit() || OffsetTail.getOpcode() == RISCV::ADDIW)
+ Offset = SignExtend64<32>(Offset);
+ // We can only fold simm32 offsets.
+ if (!isInt<32>(Offset))
+ return false;
+ LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail
+ << " " << OffsetLui);
+ foldOffset(Hi, Lo, TailAdd, Offset);
+ OffsetTail.eraseFromParent();
+ OffsetLui.eraseFromParent();
+ return true;
} else if (OffsetTail.getOpcode() == RISCV::LUI) {
// The offset value has all zero bits in the lower 12 bits. Only LUI
// exists.
More information about the llvm-commits
mailing list