Skip to content

Commit 2112379

Browse files
jrbyrnesarsenmdtcxzyw
authored
Reland: [InstCombine] Combine and->cmp->sel->or-disjoint into and->mul (#142035)
Reland of #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 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 <arsenm2@gmail.com> Co-authored-by: Yingwei Zheng <dtcxzyw@qq.com>
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)