@@ -4065,20 +4065,36 @@ Value *InstCombinerImpl::foldMultiplicationOverflowCheck(ICmpInst &I) {
4065
4065
return Res;
4066
4066
}
4067
4067
4068
- static Instruction *foldICmpXNegX (ICmpInst &I) {
4068
+ static Instruction *foldICmpXNegX (ICmpInst &I,
4069
+ InstCombiner::BuilderTy &Builder) {
4069
4070
CmpInst::Predicate Pred;
4070
4071
Value *X;
4071
- if (!match (&I, m_c_ICmp (Pred, m_NSWNeg (m_Value (X)), m_Deferred (X))))
4072
- return nullptr ;
4072
+ if (match (&I, m_c_ICmp (Pred, m_NSWNeg (m_Value (X)), m_Deferred (X)))) {
4073
4073
4074
- if (ICmpInst::isSigned (Pred))
4075
- Pred = ICmpInst::getSwappedPredicate (Pred);
4076
- else if (ICmpInst::isUnsigned (Pred))
4077
- Pred = ICmpInst::getSignedPredicate (Pred);
4078
- // else for equality-comparisons just keep the predicate.
4074
+ if (ICmpInst::isSigned (Pred))
4075
+ Pred = ICmpInst::getSwappedPredicate (Pred);
4076
+ else if (ICmpInst::isUnsigned (Pred))
4077
+ Pred = ICmpInst::getSignedPredicate (Pred);
4078
+ // else for equality-comparisons just keep the predicate.
4079
+
4080
+ return ICmpInst::Create (Instruction::ICmp, Pred, X,
4081
+ Constant::getNullValue (X->getType ()), I.getName ());
4082
+ }
4079
4083
4080
- return ICmpInst::Create (Instruction::ICmp, Pred, X,
4081
- Constant::getNullValue (X->getType ()), I.getName ());
4084
+ // A value is not equal to its negation unless that value is 0 or
4085
+ // MinSignedValue, ie: a != -a --> (a & MaxSignedVal) != 0
4086
+ if (match (&I, m_c_ICmp (Pred, m_OneUse (m_Neg (m_Value (X))), m_Deferred (X))) &&
4087
+ ICmpInst::isEquality (Pred)) {
4088
+ Type *Ty = X->getType ();
4089
+ uint32_t BitWidth = Ty->getScalarSizeInBits ();
4090
+ Constant *MaxSignedVal =
4091
+ ConstantInt::get (Ty, APInt::getSignedMaxValue (BitWidth));
4092
+ Value *And = Builder.CreateAnd (X, MaxSignedVal);
4093
+ Constant *Zero = Constant::getNullValue (Ty);
4094
+ return CmpInst::Create (Instruction::ICmp, Pred, And, Zero);
4095
+ }
4096
+
4097
+ return nullptr ;
4082
4098
}
4083
4099
4084
4100
// / Try to fold icmp (binop), X or icmp X, (binop).
@@ -4096,7 +4112,7 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
4096
4112
if (!BO0 && !BO1)
4097
4113
return nullptr ;
4098
4114
4099
- if (Instruction *NewICmp = foldICmpXNegX (I))
4115
+ if (Instruction *NewICmp = foldICmpXNegX (I, Builder ))
4100
4116
return NewICmp;
4101
4117
4102
4118
const CmpInst::Predicate Pred = I.getPredicate ();
0 commit comments