]> granicus.if.org Git - llvm/commitdiff
[ValueTracking] Use computeConstantRange() in signed add overflow determination
authorNikita Popov <nikita.ppv@gmail.com>
Tue, 9 Apr 2019 16:12:59 +0000 (16:12 +0000)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 9 Apr 2019 16:12:59 +0000 (16:12 +0000)
This is D59386 for the signed add case. The computeConstantRange()
result is now intersected into the existing known bits information,
allowing to detect additional no-overflow/always-overflow conditions
(though the latter isn't used yet).

This (finally...) covers the motivating case from D59071.

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

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

lib/Analysis/ValueTracking.cpp
test/Transforms/InstCombine/and2.ll
test/Transforms/InstCombine/icmp-add.ll
test/Transforms/InstCombine/minmax-fold.ll
test/Transforms/InstCombine/sadd-with-overflow.ll
test/Transforms/InstCombine/saturating-add-sub.ll
test/Transforms/InstCombine/sub.ll

index ce55b9ee96a00ebbafe1725f59ee685190b40012..1407f24e93beaa522834adfe3af71733fa43cd70 100644 (file)
@@ -4086,8 +4086,8 @@ static ConstantRange computeConstantRangeIncludingKnownBits(
       V, DL, Depth, AC, CxtI, DT, ORE, UseInstrInfo);
   ConstantRange CR1 = ConstantRange::fromKnownBits(Known, ForSigned);
   ConstantRange CR2 = computeConstantRange(V, UseInstrInfo);
-  // TODO: Use ForSigned to determine preferred range.
-  ConstantRange::PreferredRangeType RangeType = ConstantRange::Smallest;
+  ConstantRange::PreferredRangeType RangeType =
+      ForSigned ? ConstantRange::Signed : ConstantRange::Unsigned;
   return CR1.intersectWith(CR2, RangeType);
 }
 
@@ -4133,12 +4133,10 @@ static OverflowResult computeOverflowForSignedAdd(const Value *LHS,
       ComputeNumSignBits(RHS, DL, 0, AC, CxtI, DT) > 1)
     return OverflowResult::NeverOverflows;
 
-  KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT);
-  KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/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);
   OverflowResult OR =
       mapOverflowResult(LHSRange.signedAddMayOverflow(RHSRange));
   if (OR != OverflowResult::MayOverflow)
index 3cae1cfb2c908bbbb3f80dccc86d6658c82686db..7d056266440965b77933b9391db03e3ed84689e6 100644 (file)
@@ -154,7 +154,7 @@ define i8 @and1_lshr1_is_cmp_eq_0_multiuse(i8 %x) {
 ; CHECK-LABEL: @and1_lshr1_is_cmp_eq_0_multiuse(
 ; CHECK-NEXT:    [[SH:%.*]] = lshr i8 1, %x
 ; CHECK-NEXT:    [[AND:%.*]] = and i8 [[SH]], 1
-; CHECK-NEXT:    [[ADD:%.*]] = add nuw i8 [[SH]], [[AND]]
+; CHECK-NEXT:    [[ADD:%.*]] = add nuw nsw i8 [[SH]], [[AND]]
 ; CHECK-NEXT:    ret i8 [[ADD]]
 ;
   %sh = lshr i8 1, %x
index 24593640af28e87fd1f9dcf534252cfbe5624be7..86d4d7c5735deaa973d649b985416a130e28f7c0 100644 (file)
@@ -407,7 +407,7 @@ define i1 @sum_ugt_op_uses(i8 %p1, i8 %p2, i8* %p3) {
 ; CHECK-LABEL: @sum_ugt_op_uses(
 ; CHECK-NEXT:    [[X:%.*]] = sdiv i8 42, [[P1:%.*]]
 ; CHECK-NEXT:    [[Y:%.*]] = sdiv i8 42, [[P2:%.*]]
-; CHECK-NEXT:    [[A:%.*]] = add i8 [[X]], [[Y]]
+; CHECK-NEXT:    [[A:%.*]] = add nsw i8 [[X]], [[Y]]
 ; CHECK-NEXT:    store i8 [[A]], i8* [[P3:%.*]], align 1
 ; CHECK-NEXT:    [[C:%.*]] = icmp ugt i8 [[X]], [[A]]
 ; CHECK-NEXT:    ret i1 [[C]]
index 8588b36fa6546400fa9c2e523bc14323b90ea9be..264e579db1d6f1b4019d1238945bb2a158014d71 100644 (file)
@@ -1423,7 +1423,7 @@ define i8 @PR14613_smin(i8 %x) {
 ; CHECK-LABEL: @PR14613_smin(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i8 [[X:%.*]], 40
 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 40
-; CHECK-NEXT:    [[U7:%.*]] = add i8 [[TMP2]], 15
+; CHECK-NEXT:    [[U7:%.*]] = add nsw i8 [[TMP2]], 15
 ; CHECK-NEXT:    ret i8 [[U7]]
 ;
   %u4 = sext i8 %x to i32
index bdeaf6c57fd3a43780802437791c01552c3bd90a..0acf603662434039fa8713146775c7512c432059 100644 (file)
@@ -19,7 +19,8 @@ define { i32, i1 } @simple_fold(i32 %x) {
 
 define { i32, i1 } @fold_mixed_signs(i32 %x) {
 ; CHECK-LABEL: @fold_mixed_signs(
-; CHECK-NEXT:    [[TMP1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X:%.*]], i32 6)
+; 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 = add nsw i32 %x, 13
index 41203c4339f7eec30de3095055c7ed57b7095e0c..f326c08500c1cead05eb10529866f360301a9259 100644 (file)
@@ -391,7 +391,7 @@ define i8 @test_scalar_uadd_udiv_known_bits(i8 %a, i8 %b) {
 define i8 @test_scalar_sadd_srem_no_ov(i8 %a) {
 ; CHECK-LABEL: @test_scalar_sadd_srem_no_ov(
 ; CHECK-NEXT:    [[B:%.*]] = srem i8 [[A:%.*]], 100
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[B]], i8 28)
+; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[B]], 28
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %b = srem i8 %a, 100
@@ -414,7 +414,7 @@ define i8 @test_scalar_sadd_srem_and_no_ov(i8 %a, i8 %b) {
 ; CHECK-LABEL: @test_scalar_sadd_srem_and_no_ov(
 ; CHECK-NEXT:    [[AA:%.*]] = srem i8 [[A:%.*]], 100
 ; CHECK-NEXT:    [[BB:%.*]] = and i8 [[B:%.*]], 15
-; CHECK-NEXT:    [[R:%.*]] = call i8 @llvm.sadd.sat.i8(i8 [[AA]], i8 [[BB]])
+; CHECK-NEXT:    [[R:%.*]] = add nsw i8 [[AA]], [[BB]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %aa = srem i8 %a, 100
index e30e39a84e9815ea12437f8919bbe8d953de9509..6e1f34868f2cc4e67c321c40581de65c29516661 100644 (file)
@@ -1185,7 +1185,7 @@ define i32 @test64(i32 %x) {
 ; CHECK-LABEL: @test64(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i32 [[X:%.*]], 255
 ; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i32 [[X]], i32 255
-; CHECK-NEXT:    [[RES:%.*]] = add i32 [[TMP2]], 1
+; CHECK-NEXT:    [[RES:%.*]] = add nsw i32 [[TMP2]], 1
 ; CHECK-NEXT:    ret i32 [[RES]]
 ;
   %1 = xor i32 %x, -1
@@ -1242,7 +1242,7 @@ define <2 x i32> @test68(<2 x i32> %x) {
 ; CHECK-LABEL: @test68(
 ; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i32> [[X:%.*]], <i32 255, i32 255>
 ; CHECK-NEXT:    [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> [[X]], <2 x i32> <i32 255, i32 255>
-; CHECK-NEXT:    [[RES:%.*]] = add <2 x i32> [[TMP2]], <i32 1, i32 1>
+; CHECK-NEXT:    [[RES:%.*]] = add nsw <2 x i32> [[TMP2]], <i32 1, i32 1>
 ; CHECK-NEXT:    ret <2 x i32> [[RES]]
 ;
   %1 = xor <2 x i32> %x, <i32 -1, i32 -1>