Skip to content

Commit 2112379

Browse files
jrbyrnesarsenmdtcxzyw
authored
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 665148d commit 2112379

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
@@ -3674,6 +3674,52 @@ Instruction *InstCombinerImpl::visitOr(BinaryOperator &I) {
36743674
foldAddLikeCommutative(I.getOperand(1), I.getOperand(0),
36753675
/*NSW=*/true, /*NUW=*/true))
36763676
return R;
3677+
3678+
Value *Cond0 = nullptr, *Cond1 = nullptr;
3679+
const APInt *Op0Eq = nullptr, *Op0Ne = nullptr;
3680+
const APInt *Op1Eq = nullptr, *Op1Ne = nullptr;
3681+
3682+
// (!(A & N) ? 0 : N * C) + (!(A & M) ? 0 : M * C) -> A & (N + M) * C
3683+
if (match(I.getOperand(0),
3684+
m_Select(m_Value(Cond0), m_APInt(Op0Eq), m_APInt(Op0Ne))) &&
3685+
match(I.getOperand(1),
3686+
m_Select(m_Value(Cond1), m_APInt(Op1Eq), m_APInt(Op1Ne)))) {
3687+
3688+
auto LHSDecompose =
3689+
decomposeBitTest(Cond0, /*LookThruTrunc=*/true,
3690+
/*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
3691+
auto RHSDecompose =
3692+
decomposeBitTest(Cond1, /*LookThruTrunc=*/true,
3693+
/*AllowNonZeroC=*/false, /*DecomposeAnd=*/true);
3694+
3695+
if (LHSDecompose && RHSDecompose && LHSDecompose->X == RHSDecompose->X &&
3696+
RHSDecompose->Mask.isPowerOf2() && LHSDecompose->Mask.isPowerOf2() &&
3697+
LHSDecompose->Mask != RHSDecompose->Mask &&
3698+
LHSDecompose->Mask.getBitWidth() == Op0Ne->getBitWidth() &&
3699+
RHSDecompose->Mask.getBitWidth() == Op1Ne->getBitWidth()) {
3700+
assert(Op0Ne->getBitWidth() == Op1Ne->getBitWidth());
3701+
assert(ICmpInst::isEquality(LHSDecompose->Pred));
3702+
if (LHSDecompose->Pred == ICmpInst::ICMP_NE)
3703+
std::swap(Op0Eq, Op0Ne);
3704+
if (RHSDecompose->Pred == ICmpInst::ICMP_NE)
3705+
std::swap(Op1Eq, Op1Ne);
3706+
3707+
if (!Op0Ne->isZero() && !Op1Ne->isZero() && Op0Eq->isZero() &&
3708+
Op1Eq->isZero() && Op0Ne->urem(LHSDecompose->Mask).isZero() &&
3709+
Op1Ne->urem(RHSDecompose->Mask).isZero() &&
3710+
Op0Ne->udiv(LHSDecompose->Mask) ==
3711+
Op1Ne->udiv(RHSDecompose->Mask)) {
3712+
auto NewAnd = Builder.CreateAnd(
3713+
LHSDecompose->X,
3714+
ConstantInt::get(LHSDecompose->X->getType(),
3715+
(LHSDecompose->Mask + RHSDecompose->Mask)));
3716+
3717+
return BinaryOperator::CreateMul(
3718+
NewAnd, ConstantInt::get(NewAnd->getType(),
3719+
Op0Ne->udiv(LHSDecompose->Mask)));
3720+
}
3721+
}
3722+
}
36773723
}
36783724

36793725
Value *X, *Y;

0 commit comments

Comments
 (0)