diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp index 866b2453579cc..38cc119660a89 100644 --- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp +++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp @@ -193,9 +193,16 @@ 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(); + + // Handle rs1 of ADDI is X0. + if (AddiReg == RISCV::X0) { + LLVM_DEBUG(dbgs() << " Offset Instrs: " << OffsetTail); + foldOffset(Hi, Lo, TailAdd, OffLo); + OffsetTail.eraseFromParent(); + return true; + } + MachineInstr &OffsetLui = *MRI->getVRegDef(AddiReg); MachineOperand &LuiImmOp = OffsetLui.getOperand(1); if (OffsetLui.getOpcode() != RISCV::LUI || @@ -206,7 +213,7 @@ bool RISCVMergeBaseOffsetOpt::foldLargeOffset(MachineInstr &Hi, Offset += OffLo; // RV32 ignores the upper 32 bits. ADDIW sign extends the result. if (!ST->is64Bit() || OffsetTail.getOpcode() == RISCV::ADDIW) - Offset = SignExtend64<32>(Offset); + Offset = SignExtend64<32>(Offset); // We can only fold simm32 offsets. if (!isInt<32>(Offset)) return false; diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll index 74652cbc73b60..91e73992bdfa3 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