[llvm] [RISCV][GlobalISel] Legalize and select G_PREFETCH (PR #215466)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 13 23:20:27 PDT 2026
================
@@ -593,6 +614,94 @@ RISCVInstructionSelector::selectAddrRegImm(MachineOperand &Root) const {
[=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
}
+InstructionSelector::ComplexRendererFns
+RISCVInstructionSelector::selectAddrRegImmLsb00000(MachineOperand &Root) const {
+ if (!Root.isReg())
+ return std::nullopt;
+
+ MachineInstr *RootDef = MRI->getVRegDef(Root.getReg());
+ if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
+ return {{
+ [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); },
+ [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },
+ }};
+ }
+
+ if (isBaseWithConstantOffset(Root, *MRI)) {
+ MachineOperand &LHS = RootDef->getOperand(1);
+ MachineOperand &RHS = RootDef->getOperand(2);
+ MachineInstr *LHSDef = MRI->getVRegDef(LHS.getReg());
+ MachineInstr *RHSDef = MRI->getVRegDef(RHS.getReg());
+ int64_t RHSC = RHSDef->getOperand(1).getCImm()->getSExtValue();
+
+ if (isInt<12>(RHSC)) {
+ // Not a multiple of 32: can't encode, use the address as-is.
+ if ((RHSC & 0b11111) != 0) {
+ return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Root.getReg()); },
+ [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }}};
+ }
+ // Fold the offset.
+ if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX)
+ return {{
+ [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); },
+ [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); },
+ }};
+ return {{[=](MachineInstrBuilder &MIB) { MIB.add(LHS); },
+ [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }}};
+ }
+
+ // Large constant: fold a -2048/2016 adjustment to save an instruction.
+ if ((-2049 >= RHSC && RHSC >= -4096) || (4063 >= RHSC && RHSC >= 2017)) {
+ int64_t Adj = RHSC < 0 ? -2048 : 2016;
+ int64_t AdjustedOffset = RHSC - Adj;
+ Register BaseReg = LHS.getReg();
+ return {{[=](MachineInstrBuilder &MIB) {
+ Register Tmp = MRI->createVirtualRegister(&RISCV::GPRRegClass);
+ MachineInstr *Addi =
+ BuildMI(*MIB->getParent(), *MIB.getInstr(),
+ MIB->getDebugLoc(), TII.get(RISCV::ADDI), Tmp)
+ .addReg(BaseReg)
+ .addImm(AdjustedOffset);
+ constrainSelectedInstRegOperands(*Addi, TII, TRI, RBI);
+ MIB.addReg(Tmp);
+ },
+ [=](MachineInstrBuilder &MIB) { MIB.addImm(Adj); }}};
+ }
+
+ // Otherwise split the constant into Hi (materialized + added to the base)
+ // and Lo12 (folded offset).
+ if (auto Plan = computeConstAddrPlan(RHSC, /*IsPrefetch=*/true)) {
+ ConstAddrPlan PlanVal = *Plan;
+ Register BaseReg = LHS.getReg();
+ return {{[=](MachineInstrBuilder &MIB) {
----------------
topperc wrote:
Can we put this in computeConstAddrPlan? It's duplicated at the other call site of computeConstAddrPlan. The `ComplexRendererFns` type is a typedef of a std::optional. You can make computeConstAddrPlan return std::nullopt if it isn't a constant and detect it here.
https://github.com/llvm/llvm-project/pull/215466
More information about the llvm-commits
mailing list