Skip to content

Commit 9a3efc2

Browse files
committed
[InstCombine] (x mod (C1 * C2) / C2) vs. ((x / C2) mod C1)
Made Changes in InstCombineMulDivRem.cpp to identify the pattern of the form x mod(C1*C2) and replace it with (X/C2) mod C1 Fixes#122442
1 parent 76f64da commit 9a3efc2

File tree

1 file changed

+13
-29
lines changed

1 file changed

+13
-29
lines changed

llvm/lib/Transforms/InstCombine/InstCombineMulDivRem.cpp

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -255,33 +255,6 @@ Instruction *InstCombinerImpl::visitMul(BinaryOperator &I) {
255255
}
256256
}
257257

258-
// mul (shr exact X, N), (2^N + 1) -> add (X, shr exact (X, N))
259-
{
260-
Value *NewOp;
261-
const APInt *ShiftC;
262-
const APInt *MulAP;
263-
if (BitWidth > 2 &&
264-
match(&I, m_Mul(m_Exact(m_Shr(m_Value(NewOp), m_APInt(ShiftC))),
265-
m_APInt(MulAP))) &&
266-
(*MulAP - 1).isPowerOf2() && *ShiftC == MulAP->logBase2()) {
267-
Value *BinOp = Op0;
268-
BinaryOperator *OpBO = cast<BinaryOperator>(Op0);
269-
270-
// mul nuw (ashr exact X, N) -> add nuw (X, lshr exact (X, N))
271-
if (HasNUW && OpBO->getOpcode() == Instruction::AShr && OpBO->hasOneUse())
272-
BinOp = Builder.CreateLShr(NewOp, ConstantInt::get(Ty, *ShiftC), "",
273-
/*isExact=*/true);
274-
275-
auto *NewAdd = BinaryOperator::CreateAdd(NewOp, BinOp);
276-
if (HasNSW && (HasNUW || OpBO->getOpcode() == Instruction::LShr ||
277-
ShiftC->getZExtValue() < BitWidth - 1))
278-
NewAdd->setHasNoSignedWrap(true);
279-
280-
NewAdd->setHasNoUnsignedWrap(HasNUW);
281-
return NewAdd;
282-
}
283-
}
284-
285258
if (Op0->hasOneUse() && match(Op1, m_NegatedPower2())) {
286259
// Interpret X * (-1<<C) as (-X) * (1<<C) and try to sink the negation.
287260
// The "* (1<<C)" thus becomes a potential shifting opportunity.
@@ -1257,8 +1230,10 @@ static Value *foldIDivShl(BinaryOperator &I, InstCombiner::BuilderTy &Builder) {
12571230

12581231
/// Common integer divide/remainder transforms
12591232
Instruction *InstCombinerImpl::commonIDivRemTransforms(BinaryOperator &I) {
1233+
const APInt *C1, *C2;
12601234
assert(I.isIntDivRem() && "Unexpected instruction");
1261-
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1);
1235+
Value *X;
1236+
Value *Op0 = I.getOperand(0), *Op1 = I.getOperand(1), *Op2 = I.getOperand(2);
12621237

12631238
// If any element of a constant divisor fixed width vector is zero or undef
12641239
// the behavior is undefined and we can fold the whole op to poison.
@@ -1296,6 +1271,15 @@ Instruction *InstCombinerImpl::commonIDivRemTransforms(BinaryOperator &I) {
12961271
return R;
12971272
}
12981273

1274+
if (match(Op0, m_OneUse(m_Intrinsic<Intrinsic::smul_fix>(m_APInt(C1), m_APInt(C2)))) &&
1275+
match(Op1, m_OneUse(m_URem(m_Value(X), Op0))) &&
1276+
match(Op2, m_OneUse(m_UDiv(Op1, m_APInt(C2))))) {
1277+
1278+
Value *XDivC2 = Builder.CreateUDiv(X, ConstantInt::get(X->getType(), *C2));
1279+
Value *Result = Builder.CreateURem(XDivC2, ConstantInt::get(X->getType(), *C1));
1280+
return replaceInstUsesWith(I, Result);
1281+
}
1282+
12991283
return nullptr;
13001284
}
13011285

@@ -2071,7 +2055,7 @@ convertFSqrtDivIntoFMul(CallInst *CI, Instruction *X,
20712055
// instructions in R2 and get the most common fpmath metadata and fast-math
20722056
// flags on it.
20732057
auto *FSqrt = cast<CallInst>(CI->clone());
2074-
FSqrt->insertBefore(CI->getIterator());
2058+
FSqrt->insertBefore(CI);
20752059
auto *R2FPMathMDNode = (*R2.begin())->getMetadata(LLVMContext::MD_fpmath);
20762060
FastMathFlags R2FMF = (*R2.begin())->getFastMathFlags(); // Common FMF
20772061
for (Instruction *I : R2) {

0 commit comments

Comments
 (0)