[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 23:22:04 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/3] [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/3] 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.

>From 33c33c4095cfd4fb433b48447544f1e6c9f25bdf Mon Sep 17 00:00:00 2001
From: Jim Lin <jim at andestech.com>
Date: Mon, 22 Jan 2024 15:15:29 +0800
Subject: [PATCH 3/3] Remove new variable `Offset`

---
 llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
index 1e05e0917f9652..38cc119660a89c 100644
--- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
+++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp
@@ -198,8 +198,7 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi,
     // 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);
+      foldOffset(Hi, Lo, TailAdd, OffLo);
       OffsetTail.eraseFromParent();
       return true;
     }



More information about the llvm-commits mailing list