[llvm] r356685 - [ValueTracking] Use ConstantRange based overflow check for signed sub

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 21 10:23:51 PDT 2019


Author: nikic
Date: Thu Mar 21 10:23:51 2019
New Revision: 356685

URL: http://llvm.org/viewvc/llvm-project?rev=356685&view=rev
Log:
[ValueTracking] Use ConstantRange based overflow check for signed sub

This is D59450, but for signed sub. This case is not NFC, because
the overflow logic in ConstantRange is more powerful than the existing
check. This resolves the TODO in the function.

I've added two tests to show that this indeed catches more cases than
the previous logic, but the main correctness test coverage here is in
the existing ConstantRange unit tests.

Differential Revision: https://reviews.llvm.org/D59617

Modified:
    llvm/trunk/lib/Analysis/ValueTracking.cpp
    llvm/trunk/test/Transforms/InstCombine/sub.ll

Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=356685&r1=356684&r2=356685&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Thu Mar 21 10:23:51 2019
@@ -4190,17 +4190,12 @@ OverflowResult llvm::computeOverflowForS
     return OverflowResult::NeverOverflows;
 
   KnownBits LHSKnown = computeKnownBits(LHS, DL, 0, AC, CxtI, DT);
-
   KnownBits RHSKnown = computeKnownBits(RHS, DL, 0, AC, CxtI, DT);
-
-  // Subtraction of two 2's complement numbers having identical signs will
-  // never overflow.
-  if ((LHSKnown.isNegative() && RHSKnown.isNegative()) ||
-      (LHSKnown.isNonNegative() && RHSKnown.isNonNegative()))
-    return OverflowResult::NeverOverflows;
-
-  // TODO: implement logic similar to checkRippleForAdd
-  return OverflowResult::MayOverflow;
+  ConstantRange LHSRange =
+      ConstantRange::fromKnownBits(LHSKnown, /*signed*/ true);
+  ConstantRange RHSRange =
+      ConstantRange::fromKnownBits(RHSKnown, /*signed*/ true);
+  return mapOverflowResult(LHSRange.signedSubMayOverflow(RHSRange));
 }
 
 bool llvm::isOverflowIntrinsicNoWrap(const IntrinsicInst *II,

Modified: llvm/trunk/test/Transforms/InstCombine/sub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/sub.ll?rev=356685&r1=356684&r2=356685&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/sub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/sub.ll Thu Mar 21 10:23:51 2019
@@ -1271,7 +1271,7 @@ define i32 @nsw_inference1(i32 %x, i32 %
 ; CHECK-LABEL: @nsw_inference1(
 ; CHECK-NEXT:    [[X2:%.*]] = or i32 [[X:%.*]], 1024
 ; CHECK-NEXT:    [[Y2:%.*]] = and i32 [[Y:%.*]], 1
-; CHECK-NEXT:    [[Z:%.*]] = sub nuw i32 [[X2]], [[Y2]]
+; CHECK-NEXT:    [[Z:%.*]] = sub nuw nsw i32 [[X2]], [[Y2]]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ;
   %x2 = or i32 %x, 1024
@@ -1284,7 +1284,7 @@ define i32 @nsw_inference2(i32 %x, i32 %
 ; CHECK-LABEL: @nsw_inference2(
 ; CHECK-NEXT:    [[X2:%.*]] = and i32 [[X:%.*]], -1025
 ; CHECK-NEXT:    [[Y2:%.*]] = or i32 [[Y:%.*]], -2
-; CHECK-NEXT:    [[Z:%.*]] = sub i32 [[X2]], [[Y2]]
+; CHECK-NEXT:    [[Z:%.*]] = sub nsw i32 [[X2]], [[Y2]]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ;
   %x2 = and i32 %x, -1025




More information about the llvm-commits mailing list