[ValueTracking] Use computeConstantRange() for signed sub overflow determination
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
llvm-svn: 358020
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 1407f24..944de24 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -4192,12 +4192,10 @@
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));
}
diff --git a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
index f326c08..8b50eb6 100644
--- a/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
+++ b/llvm/test/Transforms/InstCombine/saturating-add-sub.ll
@@ -928,7 +928,7 @@
; 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 @@
; 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 @@
; 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>
diff --git a/llvm/test/Transforms/InstCombine/ssub-with-overflow.ll b/llvm/test/Transforms/InstCombine/ssub-with-overflow.ll
index 143dfc7..5a87a9b 100644
--- a/llvm/test/Transforms/InstCombine/ssub-with-overflow.ll
+++ b/llvm/test/Transforms/InstCombine/ssub-with-overflow.ll
@@ -22,9 +22,9 @@
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)