]> granicus.if.org Git - llvm/commitdiff
[ValueTracking] Use computeConstantRange() for signed sub overflow determination
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 9 Apr 2019 17:01:49 +0000 (17:01 +0000)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 9 Apr 2019 17:01:49 +0000 (17:01 +0000)
This is the same change as D60420 but for signed sub rather than
signed add: Range information is intersected into the known bits
result, allows to detect more no/always overflow conditions.

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358020 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/ValueTracking.cpp
test/Transforms/InstCombine/saturating-add-sub.ll
test/Transforms/InstCombine/ssub-with-overflow.ll

index 1407f24e93beaa522834adfe3af71733fa43cd70..944de24a5cb80403ee7b934f03b3e0b546821413 100644 (file)
@@ -4192,12 +4192,10 @@ OverflowResult llvm::computeOverflowForSignedSub(const Value *LHS,
       ComputeNumSignBits(RHS, DL, 0, AC, CxtI, DT) > 1)
     return OverflowResult::NeverOverflows;
 
-  KnownBits LHSKnown = computeKnownBits(LHS, DL, 0, AC, CxtI, DT);
-  KnownBits RHSKnown = computeKnownBits(RHS, DL, 0, AC, CxtI, DT);
-  ConstantRange LHSRange =
-      ConstantRange::fromKnownBits(LHSKnown, /*signed*/ true);
-  ConstantRange RHSRange =
-      ConstantRange::fromKnownBits(RHSKnown, /*signed*/ true);
+  ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
+      LHS, /*ForSigned=*/true, DL, /*Depth=*/0, AC, CxtI, DT);
+  ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
+      RHS, /*ForSigned=*/true, DL, /*Depth=*/0, AC, CxtI, DT);
   return mapOverflowResult(LHSRange.signedSubMayOverflow(RHSRange));
 }
 
index f326c08500c1cead05eb10529866f360301a9259..8b50eb642627118fcc6499fa6ee9fb7834d1ceaf 100644 (file)
@@ -928,7 +928,7 @@ define i8 @test_scalar_ssub_add_nsw_no_ov(i8 %a, i8 %b) {
 ; CHECK-LABEL: @test_scalar_ssub_add_nsw_no_ov(
 ; CHECK-NEXT:    [[AA:%.*]] = add nsw i8 [[A:%.*]], 7
 ; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 7
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.ssub.sat.i8(i8 [[AA]], i8 [[BB]])
+; CHECK-NEXT:    [[R:%.*]] = sub nsw i8 [[AA]], [[BB]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %aa = add nsw i8 %a, 7
@@ -954,7 +954,7 @@ define <2 x i8> @test_vector_ssub_add_nsw_no_ov_splat(<2 x i8> %a, <2 x i8> %b)
 ; CHECK-LABEL: @test_vector_ssub_add_nsw_no_ov_splat(
 ; CHECK-NEXT:    [[AA:%.*]] = add nsw <2 x i8> [[A:%.*]], <i8 7, i8 7>
 ; CHECK-NEXT:    [[BB:%.*]] = and <2 x i8> [[B:%.*]], <i8 7, i8 7>
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[AA]], <2 x i8> [[BB]])
+; CHECK-NEXT:    [[R:%.*]] = sub nsw <2 x i8> [[AA]], [[BB]]
 ; CHECK-NEXT:    ret <2 x i8> [[R]]
 ;
   %aa = add nsw <2 x i8> %a, <i8 7, i8 7>
@@ -967,7 +967,7 @@ define <2 x i8> @test_vector_ssub_add_nsw_no_ov_nonsplat1(<2 x i8> %a, <2 x i8>
 ; CHECK-LABEL: @test_vector_ssub_add_nsw_no_ov_nonsplat1(
 ; CHECK-NEXT:    [[AA:%.*]] = add nsw <2 x i8> [[A:%.*]], <i8 7, i8 7>
 ; CHECK-NEXT:    [[BB:%.*]] = and <2 x i8> [[B:%.*]], <i8 7, i8 6>
-; CHECK-NEXT:    [[R:%.*]] = call <2 x i8> @llvm.ssub.sat.v2i8(<2 x i8> [[AA]], <2 x i8> [[BB]])
+; CHECK-NEXT:    [[R:%.*]] = sub nsw <2 x i8> [[AA]], [[BB]]
 ; CHECK-NEXT:    ret <2 x i8> [[R]]
 ;
   %aa = add nsw <2 x i8> %a, <i8 7, i8 7>
index 143dfc749636de1a7a2f8b50a971ba80f85ccd74..5a87a9bca9f4d8d54dbcd11d38a824709a20e7e3 100644 (file)
@@ -22,9 +22,9 @@ define { i32, i1 } @simple_fold(i32 %x) {
 
 define { i32, i1 } @fold_mixed_signs(i32 %x) {
 ; CHECK-LABEL: @fold_mixed_signs(
-; CHECK-NEXT:    [[A:%.*]] = add nsw i32 [[X:%.*]], -13
-; CHECK-NEXT:    [[B:%.*]] = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[A]], i32 -7)
-; CHECK-NEXT:    ret { i32, i1 } [[B]]
+; CHECK-NEXT:    [[B:%.*]] = add nsw i32 [[X:%.*]], -6
+; CHECK-NEXT:    [[TMP1:%.*]] = insertvalue { i32, i1 } { i32 undef, i1 false }, i32 [[B]], 0
+; CHECK-NEXT:    ret { i32, i1 } [[TMP1]]
 ;
   %a = sub nsw i32 %x, 13
   %b = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %a, i32 -7)