[llvm] [RISCV] Merge ADDI with X0 into base offset (PR #78940)

via llvm-commits llvm-commits at lists.llvm.org
Sun Jan 21 21:35:56 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-risc-v

Author: Jim Lin (tclin914)

<details>
<summary>Changes</summary>

If offset is `addi rd, x0, imm`, merge imm into base offset.

---
Full diff: https://github.com/llvm/llvm-project/pull/78940.diff


2 Files Affected:

- (modified) llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp (+29-22) 
- (modified) llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll (+8-20) 


``````````diff
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

``````````

</details>


https://github.com/llvm/llvm-project/pull/78940


More information about the llvm-commits mailing list