diff --git a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp --- a/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp +++ b/llvm/lib/Target/RISCV/RISCVMergeBaseOffset.cpp @@ -207,6 +207,19 @@ case RISCV::ADDI: { // Offset is simply an immediate operand. int64_t Offset = Tail.getOperand(2).getImm(); + + // We might have two ADDIs in a row. + Register TailDestReg = Tail.getOperand(0).getReg(); + if (MRI->hasOneUse(TailDestReg)) { + MachineInstr &TailTail = *MRI->use_instr_begin(TailDestReg); + if (TailTail.getOpcode() == RISCV::ADDI) { + Offset += TailTail.getOperand(2).getImm(); + DeadInstrs.insert(&Tail); + foldOffset(HiLUI, LoADDI, TailTail, Offset); + return true; + } + } + LLVM_DEBUG(dbgs() << " Offset Instr: " << Tail); foldOffset(HiLUI, LoADDI, Tail, Offset); return true; diff --git a/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll b/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll --- a/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll +++ b/llvm/test/CodeGen/RISCV/hoist-global-addr-base.ll @@ -221,3 +221,21 @@ ; RV64-NEXT: ret ret i8* getelementptr inbounds ([0 x i8], [0 x i8]* @bar, i32 0, i64 -2147485013) } + +define i8* @offset_addi_addi() { +; CHECK-LABEL: offset_addi_addi: +; CHECK: # %bb.0: +; CHECK-NEXT: lui a0, %hi(bar+3211) +; CHECK-NEXT: addi a0, a0, %lo(bar+3211) +; CHECK-NEXT: ret + ret i8* getelementptr inbounds ([0 x i8], [0 x i8]* @bar, i32 0, i64 3211) +} + +define i8* @offset_addi_addi_neg() { +; CHECK-LABEL: offset_addi_addi_neg: +; CHECK: # %bb.0: +; CHECK-NEXT: lui a0, %hi(bar-4000) +; CHECK-NEXT: addi a0, a0, %lo(bar-4000) +; CHECK-NEXT: ret + ret i8* getelementptr inbounds ([0 x i8], [0 x i8]* @bar, i32 0, i64 -4000) +}