From cc3bd4353358858ae3146edc63c7e99242a19516 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 3 Jun 2022 17:58:22 -0700 Subject: [PATCH] [RISCV] Support LUI+ADDIW in doPeepholeLoadStoreADDI. This fixes an inconsistency between RV32 and RV64. Still considering trying to do this peephole during isel, but wanted to fix the inconsistency first. Reviewed By: reames Differential Revision: https://reviews.llvm.org/D126986 --- llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp | 20 +++++++++++++++++--- llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll | 6 ++++-- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp index 2d7b652..8e01c05 100644 --- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp +++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp @@ -2233,9 +2233,23 @@ bool RISCVDAGToDAGISel::doPeepholeLoadStoreADDI(SDNode *N) { if (!Base.isMachineOpcode()) return false; - // If the base is an ADDI, we can merge it in to the load/store. - if (Base.getMachineOpcode() != RISCV::ADDI) - return false; + if (Base.getMachineOpcode() == RISCV::ADDI) { + // If the base is an ADDI, we can merge it in to the load/store. + } else if (Base.getMachineOpcode() == RISCV::ADDIW && + isa(Base.getOperand(1)) && + Base.getOperand(0).isMachineOpcode() && + Base.getOperand(0).getMachineOpcode() == RISCV::LUI && + isa(Base.getOperand(0).getOperand(0))) { + // ADDIW can be merged if it's part of LUI+ADDIW constant materialization + // and LUI+ADDI would have produced the same result. This is true for all + // simm32 values except 0x7ffff800-0x7fffffff. + int64_t Offset = + SignExtend64<32>(Base.getOperand(0).getConstantOperandVal(0) << 12); + Offset += cast(Base.getOperand(1))->getSExtValue(); + if (!isInt<32>(Offset)) + return false; + } else + return false; SDValue ImmOperand = Base.getOperand(1); uint64_t Offset2 = N->getConstantOperandVal(OffsetOpIdx); diff --git a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll index 6771eb6..b3e0ae3 100644 --- a/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll +++ b/llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll @@ -328,14 +328,16 @@ define dso_local i32 @load_const_medium() nounwind { ; RV64I-LABEL: load_const_medium: ; RV64I: # %bb.0: # %entry ; RV64I-NEXT: lui a0, 1 -; RV64I-NEXT: addiw a0, a0, -16 -; RV64I-NEXT: lw a0, 0(a0) +; RV64I-NEXT: lw a0, -16(a0) ; RV64I-NEXT: ret entry: %0 = load i32, i32* inttoptr (i64 4080 to i32*) ret i32 %0 } +; The constant here is 0x7ffff800, this value requires LUI+ADDIW on RV64, +; LUI+ADDI would produce a different constant so we can't fold into the load +; offset. define dso_local i32 @load_const_large() nounwind { ; RV32I-LABEL: load_const_large: ; RV32I: # %bb.0: # %entry -- 2.7.4