[llvm] [RISCV] Cost UDIV/UREM by a constant power of 2 as a SHL/AND in getArithmeticInstrCost() (PR #179570)

Ryan Buchner via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 17 10:17:52 PDT 2026


================
@@ -2669,6 +2669,30 @@ RISCVTTIImpl::getIndexedVectorInstrCostFromEnd(unsigned Opcode, Type *Val,
                             nullptr);
 }
 
+/// Check to see if this instruction is expected to be combined to a simpler
+/// operation during/before lowering. If so return the cost of the combined
+/// operation rather than provided one. For instance, `udiv i16 %X, 2` is likely
+/// to be combined to `lshr i16 %X, 1`, so return the cost of a `lshr` rather
+/// than the cost of a `udiv`
+std::optional<InstructionCost>
+RISCVTTIImpl::getCombinedArithmeticInstructionCost(
+    unsigned ISDOpcode, Type *Ty, TTI::TargetCostKind CostKind,
+    TTI::OperandValueInfo Opd1Info, TTI::OperandValueInfo Opd2Info,
+    ArrayRef<const Value *> Args, const Instruction *CxtI) const {
+  // Vector unsigned division/remainder will be simplified to shifts/masks.
+  if ((ISDOpcode == ISD::UDIV || ISDOpcode == ISD::UREM) &&
+      Opd2Info.isConstant() && Opd2Info.isPowerOf2()) {
+    if (ISDOpcode == ISD::UDIV)
+      return getArithmeticInstrCost(Instruction::LShr, Ty, CostKind,
+                                    Opd1Info.getNoProps(),
+                                    Opd2Info.getNoProps());
----------------
bababuck wrote:

Good catch. My only concern is why the other backends strip the info from LHS? I can't think of a reason for why they would have though.

https://github.com/llvm/llvm-project/pull/179570


More information about the llvm-commits mailing list