@@ -4629,31 +4629,38 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
4629
4629
}
4630
4630
4631
4631
bool NoOp0WrapProblem = false , NoOp1WrapProblem = false ;
4632
- if (BO0 && isa<OverflowingBinaryOperator>(BO0))
4633
- NoOp0WrapProblem =
4634
- ICmpInst::isEquality (Pred) ||
4635
- (CmpInst::isUnsigned (Pred) && BO0->hasNoUnsignedWrap ()) ||
4636
- (CmpInst::isSigned (Pred) && BO0->hasNoSignedWrap ());
4637
- if (BO1 && isa<OverflowingBinaryOperator>(BO1))
4638
- NoOp1WrapProblem =
4639
- ICmpInst::isEquality (Pred) ||
4640
- (CmpInst::isUnsigned (Pred) && BO1->hasNoUnsignedWrap ()) ||
4641
- (CmpInst::isSigned (Pred) && BO1->hasNoSignedWrap ());
4642
-
4632
+ bool Op0HasNUW = false , Op1HasNUW = false ;
4633
+ bool Op0HasNSW = false , Op1HasNSW = false ;
4643
4634
// Analyze the case when either Op0 or Op1 is an add instruction.
4644
4635
// Op0 = A + B (or A and B are null); Op1 = C + D (or C and D are null).
4645
4636
Value *A = nullptr , *B = nullptr , *C = nullptr , *D = nullptr ;
4646
- if (BO0 && BO0->getOpcode () == Instruction::Add) {
4647
- A = BO0->getOperand (0 );
4648
- B = BO0->getOperand (1 );
4637
+ auto hasNoWrapProblem = [&](const BinaryOperator &BO, const Value *X,
4638
+ const Value *Y, bool &HasNSW,
4639
+ bool &HasNUW) -> bool {
4640
+ if (isa<OverflowingBinaryOperator>(BO)) {
4641
+ HasNUW = BO.hasNoUnsignedWrap ();
4642
+ HasNSW = BO.hasNoSignedWrap ();
4643
+ return ICmpInst::isEquality (Pred) ||
4644
+ (CmpInst::isUnsigned (Pred) && HasNUW) ||
4645
+ (CmpInst::isSigned (Pred) && HasNSW);
4646
+ } else if (BO0->getOpcode () == Instruction::Or) {
4647
+ HasNUW = true ;
4648
+ HasNSW = true ;
4649
+ return true ;
4650
+ } else {
4651
+ return false ;
4652
+ }
4653
+ };
4654
+
4655
+ if (BO0) {
4656
+ match (BO0, m_AddLike (m_Value (A), m_Value (B)));
4657
+ NoOp0WrapProblem = hasNoWrapProblem (*BO0, A, B, Op0HasNSW, Op0HasNUW);
4649
4658
}
4650
- if (BO1 && BO1-> getOpcode () == Instruction::Add ) {
4651
- C = BO1-> getOperand ( 0 );
4652
- D = BO1-> getOperand ( 1 );
4659
+ if (BO1) {
4660
+ match (BO1, m_AddLike ( m_Value (C), m_Value (D)) );
4661
+ NoOp1WrapProblem = hasNoWrapProblem (*BO1, C, D, Op1HasNSW, Op1HasNUW );
4653
4662
}
4654
4663
4655
- // icmp (A+B), A -> icmp B, 0 for equalities or if there is no overflow.
4656
- // icmp (A+B), B -> icmp A, 0 for equalities or if there is no overflow.
4657
4664
if ((A == Op1 || B == Op1) && NoOp0WrapProblem)
4658
4665
return new ICmpInst (Pred, A == Op1 ? B : A,
4659
4666
Constant::getNullValue (Op1->getType ()));
@@ -4769,17 +4776,15 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
4769
4776
APInt AP2Abs = AP2->abs ();
4770
4777
if (AP1Abs.uge (AP2Abs)) {
4771
4778
APInt Diff = *AP1 - *AP2;
4772
- bool HasNUW = BO0->hasNoUnsignedWrap () && Diff.ule (*AP1);
4773
- bool HasNSW = BO0->hasNoSignedWrap ();
4774
4779
Constant *C3 = Constant::getIntegerValue (BO0->getType (), Diff);
4775
- Value *NewAdd = Builder.CreateAdd (A, C3, " " , HasNUW, HasNSW);
4780
+ Value *NewAdd = Builder.CreateAdd (
4781
+ A, C3, " " , Op0HasNUW && Diff.ule (*AP1), Op0HasNSW);
4776
4782
return new ICmpInst (Pred, NewAdd, C);
4777
4783
} else {
4778
4784
APInt Diff = *AP2 - *AP1;
4779
- bool HasNUW = BO1->hasNoUnsignedWrap () && Diff.ule (*AP2);
4780
- bool HasNSW = BO1->hasNoSignedWrap ();
4781
4785
Constant *C3 = Constant::getIntegerValue (BO0->getType (), Diff);
4782
- Value *NewAdd = Builder.CreateAdd (C, C3, " " , HasNUW, HasNSW);
4786
+ Value *NewAdd = Builder.CreateAdd (
4787
+ C, C3, " " , Op1HasNUW && Diff.ule (*AP1), Op1HasNSW);
4783
4788
return new ICmpInst (Pred, A, NewAdd);
4784
4789
}
4785
4790
}
@@ -4873,16 +4878,14 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
4873
4878
isKnownNonZero (Z, Q.DL , /* Depth=*/ 0 , Q.AC , Q.CxtI , Q.DT );
4874
4879
// if Z != 0 and nsw(X * Z) and nsw(Y * Z)
4875
4880
// X * Z eq/ne Y * Z -> X eq/ne Y
4876
- if (NonZero && BO0 && BO1 && BO0->hasNoSignedWrap () &&
4877
- BO1->hasNoSignedWrap ())
4881
+ if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNSW)
4878
4882
return new ICmpInst (Pred, X, Y);
4879
4883
} else
4880
4884
NonZero = isKnownNonZero (Z, Q.DL , /* Depth=*/ 0 , Q.AC , Q.CxtI , Q.DT );
4881
4885
4882
4886
// If Z != 0 and nuw(X * Z) and nuw(Y * Z)
4883
4887
// X * Z u{lt/le/gt/ge}/eq/ne Y * Z -> X u{lt/le/gt/ge}/eq/ne Y
4884
- if (NonZero && BO0 && BO1 && BO0->hasNoUnsignedWrap () &&
4885
- BO1->hasNoUnsignedWrap ())
4888
+ if (NonZero && BO0 && BO1 && Op0HasNUW && Op1HasNUW)
4886
4889
return new ICmpInst (Pred, X, Y);
4887
4890
}
4888
4891
}
@@ -4982,8 +4985,8 @@ Instruction *InstCombinerImpl::foldICmpBinOp(ICmpInst &I,
4982
4985
return new ICmpInst (Pred, BO0->getOperand (0 ), BO1->getOperand (0 ));
4983
4986
4984
4987
case Instruction::Shl: {
4985
- bool NUW = BO0-> hasNoUnsignedWrap () && BO1-> hasNoUnsignedWrap () ;
4986
- bool NSW = BO0-> hasNoSignedWrap () && BO1-> hasNoSignedWrap () ;
4988
+ bool NUW = Op0HasNUW && Op1HasNUW ;
4989
+ bool NSW = Op0HasNSW && Op1HasNSW ;
4987
4990
if (!NUW && !NSW)
4988
4991
break ;
4989
4992
if (!NSW && I.isSigned ())
0 commit comments