if (Op0 == Op1)
return Constant::getNullValue(Op0->getType());
+ // undef >> X -> 0
+ // undef >> X -> undef (if it's exact)
+ if (match(Op0, m_Undef()))
+ return isExact ? Op0 : Constant::getNullValue(Op0->getType());
+
// The low bit cannot be shifted out of an exact shift if it is set.
if (isExact) {
unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
return V;
// undef << X -> 0
+ // undef << X -> undef if (if it's NSW/NUW)
if (match(Op0, m_Undef()))
- return Constant::getNullValue(Op0->getType());
+ return isNSW || isNUW ? Op0 : Constant::getNullValue(Op0->getType());
// (X >> A) << A -> X
Value *X;
MaxRecurse))
return V;
- // undef >>l X -> 0
- if (match(Op0, m_Undef()))
- return Constant::getNullValue(Op0->getType());
-
// (X << A) >> A -> X
Value *X;
if (match(Op0, m_NUWShl(m_Value(X), m_Specific(Op1))))
if (match(Op0, m_AllOnes()))
return Op0;
- // undef >>a X -> all ones
- if (match(Op0, m_Undef()))
- return Constant::getAllOnesValue(Op0->getType());
-
// (X << A) >> A -> X
Value *X;
if (match(Op0, m_NSWShl(m_Value(X), m_Specific(Op1))))
if (const auto *ICI = dyn_cast<ICmpInst>(CondVal)) {
Value *X;
const APInt *Y;
- if (ICI->isEquality() &&
+ ICmpInst::Predicate Pred = ICI->getPredicate();
+ if (ICmpInst::isEquality(Pred) &&
match(ICI->getOperand(0), m_And(m_Value(X), m_APInt(Y))) &&
match(ICI->getOperand(1), m_Zero())) {
- ICmpInst::Predicate Pred = ICI->getPredicate();
const APInt *C;
// (X & Y) == 0 ? X & ~Y : X --> X
// (X & Y) != 0 ? X & ~Y : X --> X & ~Y
return Pred == ICmpInst::ICMP_EQ ? TrueVal : FalseVal;
}
}
+ if (Pred == ICmpInst::ICMP_SLT && match(ICI->getOperand(1), m_Zero())) {
+ // (X < 0) ? X : X | SignBit --> X | SignBit
+ if (TrueVal == ICI->getOperand(0) &&
+ match(FalseVal, m_Or(m_Specific(TrueVal), m_SignBit())))
+ return FalseVal;
+ // (X < 0) ? X | SignBit : X --> X
+ if (FalseVal == ICI->getOperand(0) &&
+ match(TrueVal, m_Or(m_Specific(FalseVal), m_SignBit())))
+ return FalseVal;
+ // (X < 0) ? X & INT_MAX : X --> X & INT_MAX
+ if (FalseVal == ICI->getOperand(0) &&
+ match(TrueVal, m_And(m_Specific(FalseVal), m_MaxSignedValue())))
+ return TrueVal;
+ // (X < 0) ? X : X & INT_MAX --> X
+ if (TrueVal == ICI->getOperand(0) &&
+ match(FalseVal, m_And(m_Specific(TrueVal), m_MaxSignedValue())))
+ return TrueVal;
+ }
+ if (Pred == ICmpInst::ICMP_SGT && match(ICI->getOperand(1), m_AllOnes())) {
+ // (X > -1) ? X : X | SignBit --> X
+ if (TrueVal == ICI->getOperand(0) &&
+ match(FalseVal, m_Or(m_Specific(TrueVal), m_SignBit())))
+ return TrueVal;
+ // (X > -1) ? X | SignBit : X --> X | SignBit
+ if (FalseVal == ICI->getOperand(0) &&
+ match(TrueVal, m_Or(m_Specific(FalseVal), m_SignBit())))
+ return TrueVal;
+ // (X > -1) ? X & INT_MAX : X --> X
+ if (FalseVal == ICI->getOperand(0) &&
+ match(TrueVal, m_And(m_Specific(FalseVal), m_MaxSignedValue())))
+ return FalseVal;
+ // (X > -1) ? X : X & INT_MAX --> X & INT_MAX
+ if (TrueVal == ICI->getOperand(0) &&
+ match(FalseVal, m_And(m_Specific(TrueVal), m_MaxSignedValue())))
+ return FalseVal;
+ }
}
return nullptr;