From 9386574d4a7c211af7872aca9ae43e2fd1cfa83b Mon Sep 17 00:00:00 2001 From: Jim Lin 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 866b2453579cc..9513d858b15b4 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 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 From 35104ab1629bededc41a84d6cd0cdfa2aadecb7b Mon Sep 17 00:00:00 2001 From: Jim Lin 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 9513d858b15b4..1e05e0917f965 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 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 1e05e0917f965..38cc119660a89 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; }