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