@@ -9580,15 +9580,45 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
9580
9580
unsigned Width = Lower.getBitWidth ();
9581
9581
const APInt *C;
9582
9582
switch (BO.getOpcode ()) {
9583
- case Instruction::Add :
9584
- if (match (BO.getOperand (1 ), m_APInt (C)) && !C-> isZero ( )) {
9583
+ case Instruction::Sub :
9584
+ if (match (BO.getOperand (0 ), m_APInt (C))) {
9585
9585
bool HasNSW = IIQ.hasNoSignedWrap (&BO);
9586
9586
bool HasNUW = IIQ.hasNoUnsignedWrap (&BO);
9587
9587
9588
9588
// If the caller expects a signed compare, then try to use a signed range.
9589
9589
// Otherwise if both no-wraps are set, use the unsigned range because it
9590
9590
// is never larger than the signed range. Example:
9591
- // "add nuw nsw i8 X, -2" is unsigned [254,255] vs. signed [-128, 125].
9591
+ // "sub nuw nsw i8 -2, x" is unsigned [0, 254] vs. signed [-128, 126].
9592
+ // "sub nuw nsw i8 2, x" is unsigned [0, 2] vs. signed [-125, 127].
9593
+ if (PreferSignedRange && HasNSW && HasNUW)
9594
+ HasNUW = false ;
9595
+
9596
+ if (HasNUW) {
9597
+ // 'sub nuw c, x' produces [0, C].
9598
+ Upper = *C + 1 ;
9599
+ } else if (HasNSW) {
9600
+ if (C->isNegative ()) {
9601
+ // 'sub nsw -C, x' produces [SINT_MIN, -C - SINT_MIN].
9602
+ Lower = APInt::getSignedMinValue (Width);
9603
+ Upper = *C - APInt::getSignedMaxValue (Width);
9604
+ } else {
9605
+ // Note that sub 0, INT_MIN is not NSW. It techically is a signed wrap
9606
+ // 'sub nsw C, x' produces [C - SINT_MAX, SINT_MAX].
9607
+ Lower = *C - APInt::getSignedMaxValue (Width);
9608
+ Upper = APInt::getSignedMinValue (Width);
9609
+ }
9610
+ }
9611
+ }
9612
+ break ;
9613
+ case Instruction::Add:
9614
+ if (match (BO.getOperand (1 ), m_APInt (C)) && !C->isZero ()) {
9615
+ bool HasNSW = IIQ.hasNoSignedWrap (&BO);
9616
+ bool HasNUW = IIQ.hasNoUnsignedWrap (&BO);
9617
+
9618
+ // If the caller expects a signed compare, then try to use a signed
9619
+ // range. Otherwise if both no-wraps are set, use the unsigned range
9620
+ // because it is never larger than the signed range. Example: "add nuw
9621
+ // nsw i8 X, -2" is unsigned [254,255] vs. signed [-128, 125].
9592
9622
if (PreferSignedRange && HasNSW && HasNUW)
9593
9623
HasNUW = false ;
9594
9624
0 commit comments