return nullptr;
}
-/// Fold icmp (and X, C2), C1.
-Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
- BinaryOperator *And,
- const APInt *C1) {
+/// Fold icmp (and (sh X, Y), C2), C1.
+Instruction *InstCombiner::foldICmpAndShift(ICmpInst &Cmp, BinaryOperator *And,
+ const APInt *C1) {
// FIXME: This check restricts all folds under here to scalar types.
ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1));
if (!RHS)
return nullptr;
+ // FIXME: This could be passed in as APInt.
auto *C2 = dyn_cast<ConstantInt>(And->getOperand(1));
if (!C2)
return nullptr;
- if (!And->hasOneUse() || !And->getOperand(0)->hasOneUse())
- return nullptr;
-
- // If the LHS is an AND of a truncating cast, we can widen the and/compare to
- // be the input width without changing the value produced, eliminating a cast.
- if (TruncInst *Cast = dyn_cast<TruncInst>(And->getOperand(0))) {
- // We can do this transformation if either the AND constant does not have
- // its sign bit set or if it is an equality comparison. Extending a
- // relational comparison when we're checking the sign bit would not work.
- if (Cmp.isEquality() || (!C2->isNegative() && C1->isNonNegative())) {
- Value *NewAnd = Builder->CreateAnd(
- Cast->getOperand(0), ConstantExpr::getZExt(C2, Cast->getSrcTy()));
- NewAnd->takeName(And);
- return new ICmpInst(Cmp.getPredicate(), NewAnd,
- ConstantExpr::getZExt(RHS, Cast->getSrcTy()));
- }
- }
-
- // If the LHS is an AND of a zext, and we have an equality compare, we can
- // shrink the and/compare to the smaller type, eliminating the cast.
- if (ZExtInst *Cast = dyn_cast<ZExtInst>(And->getOperand(0))) {
- IntegerType *Ty = cast<IntegerType>(Cast->getSrcTy());
- // Make sure we don't compare the upper bits, SimplifyDemandedBits
- // should fold the icmp to true/false in that case.
- if (Cmp.isEquality() && C1->getActiveBits() <= Ty->getBitWidth()) {
- Value *NewAnd = Builder->CreateAnd(Cast->getOperand(0),
- ConstantExpr::getTrunc(C2, Ty));
- NewAnd->takeName(And);
- return new ICmpInst(Cmp.getPredicate(), NewAnd,
- ConstantExpr::getTrunc(RHS, Ty));
- }
- }
-
// If this is: (X >> C3) & C2 != C1 (where any shift and any compare could
// exist), turn it into (X & (C2 << C3)) != (C1 << C3). This happens a LOT in
// code produced by the clang front-end, for bitfield access.
BinaryOperator *Shift = dyn_cast<BinaryOperator>(And->getOperand(0));
- if (Shift && !Shift->isShift())
- Shift = nullptr;
-
- ConstantInt *ShAmt;
- ShAmt = Shift ? dyn_cast<ConstantInt>(Shift->getOperand(1)) : nullptr;
+ if (!Shift || !Shift->isShift())
+ return nullptr;
// This seemingly simple opportunity to fold away a shift turns out to be
// rather complicated. See PR17827 for details.
- if (ShAmt) {
+ if (auto *ShAmt = dyn_cast<ConstantInt>(Shift->getOperand(1))) {
bool CanFold = false;
unsigned ShiftOpcode = Shift->getOpcode();
if (ShiftOpcode == Instruction::AShr) {
// Turn ((X >> Y) & C2) == 0 into (X & (C2 << Y)) == 0. The latter is
// preferable because it allows the C2 << Y expression to be hoisted out of a
// loop if Y is invariant and X is not.
- if (Shift && Shift->hasOneUse() && *C1 == 0 && Cmp.isEquality() &&
+ if (Shift->hasOneUse() && *C1 == 0 && Cmp.isEquality() &&
!Shift->isArithmeticShift() && !isa<Constant>(Shift->getOperand(0))) {
// Compute C2 << Y.
Value *NS;
return &Cmp;
}
+ return nullptr;
+}
+
+/// Fold icmp (and X, C2), C1.
+Instruction *InstCombiner::foldICmpAndConstConst(ICmpInst &Cmp,
+ BinaryOperator *And,
+ const APInt *C1) {
+ // FIXME: This check restricts all folds under here to scalar types.
+ ConstantInt *RHS = dyn_cast<ConstantInt>(Cmp.getOperand(1));
+ if (!RHS)
+ return nullptr;
+
+ // FIXME: Use m_APInt.
+ auto *C2 = dyn_cast<ConstantInt>(And->getOperand(1));
+ if (!C2)
+ return nullptr;
+
+ if (!And->hasOneUse() || !And->getOperand(0)->hasOneUse())
+ return nullptr;
+
+ // If the LHS is an AND of a truncating cast, we can widen the and/compare to
+ // be the input width without changing the value produced, eliminating a cast.
+ if (TruncInst *Cast = dyn_cast<TruncInst>(And->getOperand(0))) {
+ // We can do this transformation if either the AND constant does not have
+ // its sign bit set or if it is an equality comparison. Extending a
+ // relational comparison when we're checking the sign bit would not work.
+ if (Cmp.isEquality() || (!C2->isNegative() && C1->isNonNegative())) {
+ Value *NewAnd = Builder->CreateAnd(
+ Cast->getOperand(0), ConstantExpr::getZExt(C2, Cast->getSrcTy()));
+ NewAnd->takeName(And);
+ return new ICmpInst(Cmp.getPredicate(), NewAnd,
+ ConstantExpr::getZExt(RHS, Cast->getSrcTy()));
+ }
+ }
+
+ // If the LHS is an AND of a zext, and we have an equality compare, we can
+ // shrink the and/compare to the smaller type, eliminating the cast.
+ if (ZExtInst *Cast = dyn_cast<ZExtInst>(And->getOperand(0))) {
+ IntegerType *Ty = cast<IntegerType>(Cast->getSrcTy());
+ // Make sure we don't compare the upper bits, SimplifyDemandedBits
+ // should fold the icmp to true/false in that case.
+ if (Cmp.isEquality() && C1->getActiveBits() <= Ty->getBitWidth()) {
+ Value *NewAnd = Builder->CreateAnd(Cast->getOperand(0),
+ ConstantExpr::getTrunc(C2, Ty));
+ NewAnd->takeName(And);
+ return new ICmpInst(Cmp.getPredicate(), NewAnd,
+ ConstantExpr::getTrunc(RHS, Ty));
+ }
+ }
+
+ if (Instruction *I = foldICmpAndShift(Cmp, And, C1))
+ return I;
+
// (icmp pred (and (or (lshr A, B), A), 1), 0) -->
// (icmp pred (and A, (or (shl 1, B), 1), 0))
//