[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