[llvm] 9c6a220 - [RISCV] Support folding constant addresses in SelectAddrRegImm.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Sat Jul 9 13:22:37 PDT 2022
Author: Craig Topper
Date: 2022-07-09T13:12:02-07:00
New Revision: 9c6a2200e280a8612d698e1ba727a6f68b906bc8
URL: https://github.com/llvm/llvm-project/commit/9c6a2200e280a8612d698e1ba727a6f68b906bc8
DIFF: https://github.com/llvm/llvm-project/commit/9c6a2200e280a8612d698e1ba727a6f68b906bc8.diff
LOG: [RISCV] Support folding constant addresses in SelectAddrRegImm.
We already handled this by folding an ADDI in the post-isel peephole.
My goal is to remove that peephole so this adds the functionality
to isel.
Added:
Modified:
llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index a73422ab95264..42ee859a0d957 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1887,6 +1887,53 @@ bool RISCVDAGToDAGISel::SelectFrameAddrRegImm(SDValue Addr, SDValue &Base,
return false;
}
+// Fold constant addresses.
+static bool selectConstantAddr(SelectionDAG *CurDAG, const SDLoc &DL,
+ const MVT VT, const RISCVSubtarget *Subtarget,
+ SDValue Addr, SDValue &Base, SDValue &Offset) {
+ if (!isa<ConstantSDNode>(Addr))
+ return false;
+
+ int64_t CVal = cast<ConstantSDNode>(Addr)->getSExtValue();
+
+ // If the constant is a simm12, we can fold the whole constant and use X0 as
+ // the base. If the constant can be materialized with LUI+simm12, use LUI as
+ // the base. We can't use generateInstSeq because it favors LUI+ADDIW.
+ int64_t Lo12 = SignExtend64<12>(CVal);
+ int64_t Hi = (uint64_t)CVal - (uint64_t)Lo12;
+ if (!Subtarget->is64Bit() || isInt<32>(Hi)) {
+ if (Hi) {
+ int64_t Hi20 = (Hi >> 12) & 0xfffff;
+ Base = SDValue(
+ CurDAG->getMachineNode(RISCV::LUI, DL, VT,
+ CurDAG->getTargetConstant(Hi20, DL, VT)),
+ 0);
+ } else {
+ Base = CurDAG->getRegister(RISCV::X0, VT);
+ }
+ Offset = CurDAG->getTargetConstant(Lo12, DL, VT);
+ return true;
+ }
+
+ // Ask how constant materialization would handle this constant.
+ RISCVMatInt::InstSeq Seq =
+ RISCVMatInt::generateInstSeq(CVal, Subtarget->getFeatureBits());
+
+ // If the last instruction would be an ADDI, we can fold its immediate and
+ // emit the rest of the sequence as the base.
+ if (Seq.back().Opc != RISCV::ADDI)
+ return false;
+ Lo12 = Seq.back().Imm;
+
+ // Drop the last instruction.
+ Seq.pop_back();
+ assert(!Seq.empty() && "Expected more instructions in sequence");
+
+ Base = SDValue(selectImmSeq(CurDAG, DL, VT, Seq), 0);
+ Offset = CurDAG->getTargetConstant(Lo12, DL, VT);
+ return true;
+}
+
bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
SDValue &Offset) {
if (SelectAddrFrameIndex(Addr, Base, Offset))
@@ -1952,6 +1999,9 @@ bool RISCVDAGToDAGISel::SelectAddrRegImm(SDValue Addr, SDValue &Base,
}
}
+ if (selectConstantAddr(CurDAG, DL, VT, Subtarget, Addr, Base, Offset))
+ return true;
+
Base = Addr;
Offset = CurDAG->getTargetConstant(0, DL, VT);
return true;
More information about the llvm-commits
mailing list