Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RISCV] Merge ADDI with X0 into base offset #78940

Merged
merged 3 commits into from
Jan 23, 2024

Conversation

tclin914
Copy link
Contributor

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

If offset is `addi rd, x0, imm`, merge imm into base offset.
@llvmbot
Copy link
Collaborator

llvmbot commented Jan 22, 2024

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

Author: Jim Lin (tclin914)

Changes

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

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tclin914 tclin914 merged commit b8e708b into llvm:main Jan 23, 2024
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants