Skip to content

Commit f3ce91e

Browse files
jrbyrnesarsenmdtcxzyw
committed
Reland: [InstCombine] Combine and->cmp->sel->or-disjoint into and->mul (llvm#142035)
Reland of llvm#135274 The commit to land the original PR was blamelisted for two types of failures: https://lab.llvm.org/buildbot/#/builders/24/builds/8932 https://lab.llvm.org/buildbot/#/builders/198/builds/4844 The second of which seems to be unrelated to the PR and seemingly fixed by llvm@6ee2453 I've addressed the fix to the other issue with the latest commit in this PR b24f473 . This is the only difference between this PR and the previously accepted PR. --------- Co-authored-by: Matt Arsenault <[email protected]> Co-authored-by: Yingwei Zheng <[email protected]>
1 parent d32f15e commit f3ce91e

File tree

2 files changed

+412
-0
lines changed

2 files changed

+412
-0
lines changed

llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3636,6 +3636,52 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36363636
foldAddLikeCommutative(I.getOperand(1), I.getOperand(0),
36373637
/*NSW=*/true, /*NUW=*/true))
36383638
return R;
3639+
3640+
Value *Cond0 = nullptr, *Cond1 = nullptr;
3641+
const APInt *Op0Eq = nullptr, *Op0Ne = nullptr;
3642+
const APInt *Op1Eq = nullptr, *Op1Ne = nullptr;
3643+
3644+
// (!(A & N) ? 0 : N * C) + (!(A & M) ? 0 : M * C) -> A & (N + M) * C
3645+
if (match(I.getOperand(0),
3646+
m_Select(m_Value(Cond0), m_APInt(Op0Eq), m_APInt(Op0Ne))) &&
3647+
match(I.getOperand(1),
3648+
m_Select(m_Value(Cond1), m_APInt(Op1Eq), m_APInt(Op1Ne)))) {
3649+
3650+
auto LHSDecompose =
3651+
decomposeBitTest(Cond0, /*LookThruTrunc=*/true,
3652+
/*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
3653+
auto RHSDecompose =
3654+
decomposeBitTest(Cond1, /*LookThruTrunc=*/true,
3655+
/*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
3656+
3657+
if (LHSDecompose && RHSDecompose && LHSDecompose->X == RHSDecompose->X &&
3658+
RHSDecompose->Mask.isPowerOf2() && LHSDecompose->Mask.isPowerOf2() &&
3659+
LHSDecompose->Mask != RHSDecompose->Mask &&
3660+
LHSDecompose->Mask.getBitWidth() == Op0Ne->getBitWidth() &&
3661+
RHSDecompose->Mask.getBitWidth() == Op1Ne->getBitWidth()) {
3662+
assert(Op0Ne->getBitWidth() == Op1Ne->getBitWidth());
3663+
assert(ICmpInst::isEquality(LHSDecompose->Pred));
3664+
if (LHSDecompose->Pred == ICmpInst::ICMP_NE)
3665+
std::swap(Op0Eq, Op0Ne);
3666+
if (RHSDecompose->Pred == ICmpInst::ICMP_NE)
3667+
std::swap(Op1Eq, Op1Ne);
3668+
3669+
if (!Op0Ne->isZero() && !Op1Ne->isZero() && Op0Eq->isZero() &&
3670+
Op1Eq->isZero() && Op0Ne->urem(LHSDecompose->Mask).isZero() &&
3671+
Op1Ne->urem(RHSDecompose->Mask).isZero() &&
3672+
Op0Ne->udiv(LHSDecompose->Mask) ==
3673+
Op1Ne->udiv(RHSDecompose->Mask)) {
3674+
auto NewAnd = Builder.CreateAnd(
3675+
LHSDecompose->X,
3676+
ConstantInt::get(LHSDecompose->X->getType(),
3677+
(LHSDecompose->Mask + RHSDecompose->Mask)));
3678+
3679+
return BinaryOperator::CreateMul(
3680+
NewAnd, ConstantInt::get(NewAnd->getType(),
3681+
Op0Ne->udiv(LHSDecompose->Mask)));
3682+
}
3683+
}
3684+
}
36393685
}
36403686

36413687
Value *X, *Y;

0 commit comments

Comments
 (0)