@@ -2053,80 +2053,78 @@ Instruction *InstCombinerImpl::foldICmpOrConstant(ICmpInst &Cmp,
2053
2053
Instruction *InstCombinerImpl::foldICmpMulConstant (ICmpInst &Cmp,
2054
2054
BinaryOperator *Mul,
2055
2055
const APInt &C) {
2056
+ ICmpInst::Predicate Pred = Cmp.getPredicate ();
2057
+ Type *MulTy = Mul->getType ();
2058
+ Value *X = Mul->getOperand (0 );
2059
+
2056
2060
// If there's no overflow:
2057
2061
// X * X == 0 --> X == 0
2058
2062
// X * X != 0 --> X != 0
2059
- Type *MulTy = Mul->getType ();
2060
- if (Cmp.isEquality () && C.isZero () &&
2061
- Mul->getOperand (0 ) == Mul->getOperand (1 ) &&
2063
+ if (Cmp.isEquality () && C.isZero () && X == Mul->getOperand (1 ) &&
2062
2064
(Mul->hasNoUnsignedWrap () || Mul->hasNoSignedWrap ()))
2063
- return new ICmpInst (Cmp.getPredicate (), Mul->getOperand (0 ),
2064
- ConstantInt::getNullValue (MulTy));
2065
+ return new ICmpInst (Pred, X, ConstantInt::getNullValue (MulTy));
2065
2066
2066
2067
const APInt *MulC;
2067
2068
if (!match (Mul->getOperand (1 ), m_APInt (MulC)))
2068
2069
return nullptr ;
2069
2070
2070
2071
// If this is a test of the sign bit and the multiply is sign-preserving with
2071
- // a constant operand, use the multiply LHS operand instead.
2072
- ICmpInst::Predicate Pred = Cmp.getPredicate ();
2072
+ // a constant operand, use the multiply LHS operand instead:
2073
+ // (X * +MulC) < 0 --> X < 0
2074
+ // (X * -MulC) < 0 --> X > 0
2073
2075
if (isSignTest (Pred, C) && Mul->hasNoSignedWrap ()) {
2074
2076
if (MulC->isNegative ())
2075
2077
Pred = ICmpInst::getSwappedPredicate (Pred);
2076
- return new ICmpInst (Pred, Mul->getOperand (0 ),
2077
- Constant::getNullValue (Mul->getType ()));
2078
+ return new ICmpInst (Pred, X, ConstantInt::getNullValue (MulTy));
2078
2079
}
2079
2080
2080
- if (MulC->isZero () || !( Mul->hasNoSignedWrap () || Mul->hasNoUnsignedWrap ()))
2081
+ if (MulC->isZero () || (! Mul->hasNoSignedWrap () && ! Mul->hasNoUnsignedWrap ()))
2081
2082
return nullptr ;
2082
2083
2083
2084
// If the multiply does not wrap, try to divide the compare constant by the
2084
2085
// multiplication factor.
2085
2086
if (Cmp.isEquality ()) {
2086
2087
// (mul nsw X, MulC) == C --> X == C /s MulC
2087
2088
if (Mul->hasNoSignedWrap () && C.srem (*MulC).isZero ()) {
2088
- Constant *NewC = ConstantInt::get (Mul-> getType () , C.sdiv (*MulC));
2089
- return new ICmpInst (Pred, Mul-> getOperand ( 0 ) , NewC);
2089
+ Constant *NewC = ConstantInt::get (MulTy , C.sdiv (*MulC));
2090
+ return new ICmpInst (Pred, X , NewC);
2090
2091
}
2091
2092
// (mul nuw X, MulC) == C --> X == C /u MulC
2092
2093
if (Mul->hasNoUnsignedWrap () && C.urem (*MulC).isZero ()) {
2093
- Constant *NewC = ConstantInt::get (Mul-> getType () , C.udiv (*MulC));
2094
- return new ICmpInst (Pred, Mul-> getOperand ( 0 ) , NewC);
2094
+ Constant *NewC = ConstantInt::get (MulTy , C.udiv (*MulC));
2095
+ return new ICmpInst (Pred, X , NewC);
2095
2096
}
2096
2097
}
2097
2098
2099
+ // With a matching no-overflow guarantee, fold the constants:
2100
+ // (X * MulC) < C --> X < (C / MulC)
2101
+ // (X * MulC) > C --> X > (C / MulC)
2102
+ // TODO: Assert that Pred is not equal to SGE, SLE, UGE, ULE?
2098
2103
Constant *NewC = nullptr ;
2099
-
2100
- // FIXME: Add assert that Pred is not equal to ICMP_SGE, ICMP_SLE,
2101
- // ICMP_UGE, ICMP_ULE.
2102
-
2103
2104
if (Mul->hasNoSignedWrap ()) {
2104
- if (MulC-> isNegative ()) {
2105
- // MININT / -1 --> overflow.
2106
- if (C. isMinSignedValue () && MulC-> isAllOnes ())
2107
- return nullptr ;
2105
+ // MININT / -1 --> overflow.
2106
+ if (C. isMinSignedValue () && MulC-> isAllOnes ())
2107
+ return nullptr ;
2108
+ if (MulC-> isNegative ())
2108
2109
Pred = ICmpInst::getSwappedPredicate (Pred);
2109
- }
2110
+
2110
2111
if (Pred == ICmpInst::ICMP_SLT || Pred == ICmpInst::ICMP_SGE)
2111
2112
NewC = ConstantInt::get (
2112
- Mul->getType (),
2113
- APIntOps::RoundingSDiv (C, *MulC, APInt::Rounding::UP));
2113
+ MulTy, APIntOps::RoundingSDiv (C, *MulC, APInt::Rounding::UP));
2114
2114
if (Pred == ICmpInst::ICMP_SLE || Pred == ICmpInst::ICMP_SGT)
2115
2115
NewC = ConstantInt::get (
2116
- Mul-> getType (),
2117
- APIntOps::RoundingSDiv (C, *MulC, APInt::Rounding::DOWN));
2118
- } else if (Mul->hasNoUnsignedWrap ()) {
2116
+ MulTy, APIntOps::RoundingSDiv (C, *MulC, APInt::Rounding::DOWN));
2117
+ } else {
2118
+ assert (Mul->hasNoUnsignedWrap () && " Expected mul nuw " );
2119
2119
if (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_UGE)
2120
2120
NewC = ConstantInt::get (
2121
- Mul->getType (),
2122
- APIntOps::RoundingUDiv (C, *MulC, APInt::Rounding::UP));
2121
+ MulTy, APIntOps::RoundingUDiv (C, *MulC, APInt::Rounding::UP));
2123
2122
if (Pred == ICmpInst::ICMP_ULE || Pred == ICmpInst::ICMP_UGT)
2124
2123
NewC = ConstantInt::get (
2125
- Mul->getType (),
2126
- APIntOps::RoundingUDiv (C, *MulC, APInt::Rounding::DOWN));
2124
+ MulTy, APIntOps::RoundingUDiv (C, *MulC, APInt::Rounding::DOWN));
2127
2125
}
2128
2126
2129
- return NewC ? new ICmpInst (Pred, Mul-> getOperand ( 0 ) , NewC) : nullptr ;
2127
+ return NewC ? new ICmpInst (Pred, X , NewC) : nullptr ;
2130
2128
}
2131
2129
2132
2130
// / Fold icmp (shl 1, Y), C.
0 commit comments