From 193bd01e7e738e40dc86f910772b8c21b16cf821 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Thu, 21 Mar 2019 17:23:51 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@356685 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/ValueTracking.cpp | 15 +++++---------- test/Transforms/InstCombine/sub.ll | 4 ++-- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/lib/Analysis/ValueTracking.cpp b/lib/Analysis/ValueTracking.cpp index 52328b174b4..e31ddf0d646 100644 --- a/lib/Analysis/ValueTracking.cpp +++ b/lib/Analysis/ValueTracking.cpp @@ -4190,17 +4190,12 @@ OverflowResult llvm::computeOverflowForSignedSub(const Value *LHS, 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, diff --git a/test/Transforms/InstCombine/sub.ll b/test/Transforms/InstCombine/sub.ll index 9b10017b86e..2a9aa09cbbd 100644 --- a/test/Transforms/InstCombine/sub.ll +++ b/test/Transforms/InstCombine/sub.ll @@ -1271,7 +1271,7 @@ define i32 @nsw_inference1(i32 %x, i32 %y) { ; 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 %y) { ; 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 -- 2.40.0