@@ -9580,15 +9580,45 @@ static void setLimitsForBinOp(const BinaryOperator &BO, APInt &Lower,
95809580 unsigned Width = Lower.getBitWidth ();
95819581 const APInt *C;
95829582 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))) {
95859585 bool HasNSW = IIQ.hasNoSignedWrap (&BO);
95869586 bool HasNUW = IIQ.hasNoUnsignedWrap (&BO);
95879587
95889588 // If the caller expects a signed compare, then try to use a signed range.
95899589 // Otherwise if both no-wraps are set, use the unsigned range because it
95909590 // 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].
95929622 if (PreferSignedRange && HasNSW && HasNUW)
95939623 HasNUW = false ;
95949624
0 commit comments