@@ -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