[llvm] [GlobalISel] Handle div-by-pow2 (PR #83155)
Kai Nacke via llvm-commits
llvm-commits at lists.llvm.org
Tue Feb 27 10:32:58 PST 2024
================
@@ -5286,6 +5286,62 @@ MachineInstr *CombinerHelper::buildSDivUsingMul(MachineInstr &MI) {
return MIB.buildMul(Ty, Res, Factor);
}
+bool CombinerHelper::matchSDivByPow2(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SDIV && "Expected SDIV");
+ auto &SDiv = cast<GenericMachineInstr>(MI);
+ Register RHS = SDiv.getReg(2);
+ auto MatchPow2 = [&](const Constant *C) {
+ if (auto *CI = dyn_cast<ConstantInt>(C))
+ return CI->getValue().isPowerOf2() || CI->getValue().isNegatedPowerOf2();
+ return false;
+ };
+ return matchUnaryPredicate(MRI, RHS, MatchPow2, /* AllowUndefs */ false);
+}
+
+void CombinerHelper::applySDivByPow2(MachineInstr &MI) {
+ assert(MI.getOpcode() == TargetOpcode::G_SDIV && "Expected SDIV");
+ auto &SDiv = cast<GenericMachineInstr>(MI);
+ Register Dst = SDiv.getReg(0);
+ Register LHS = SDiv.getReg(1);
+ Register RHS = SDiv.getReg(2);
+ LLT Ty = MRI.getType(Dst);
+ LLT ShiftAmtTy = getTargetLowering().getPreferredShiftAmountTy(Ty);
+ LLT CVT = LLT::scalar(1);
+
+ Builder.setInstrAndDebugLoc(MI);
+
+ unsigned Bitwidth = Ty.getScalarSizeInBits();
+ auto Bits = Builder.buildConstant(ShiftAmtTy, Bitwidth);
+ auto C1 = Builder.buildCTTZ(Ty, RHS);
----------------
redstar wrote:
`matchSDivByPow2` only matches if the RHS is a constant which is a power of 2. You can use that knowledge to calculate ln(RHS) here instead of generating instruction.
The same comment applies below to deciding if the divisor is positive. Instead of generating the G_ICMP instruction you already know the result. I assume that will make the generated code much shorter.
https://github.com/llvm/llvm-project/pull/83155
More information about the llvm-commits
mailing list