[llvm] r356489 - [ValueTracking] Use computeConstantRange() for unsigned add/sub overflow
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 19 10:53:56 PDT 2019
Author: nikic
Date: Tue Mar 19 10:53:56 2019
New Revision: 356489
URL: http://llvm.org/viewvc/llvm-project?rev=356489&view=rev
Log:
[ValueTracking] Use computeConstantRange() for unsigned add/sub overflow
Improve computeOverflowForUnsignedAdd/Sub in ValueTracking by
intersecting the computeConstantRange() result into the ConstantRange
created from computeKnownBits(). This allows us to detect some
additional never/always overflows conditions that can't be determined
from known bits.
This revision also adds basic handling for constants to
computeConstantRange(). Non-splat vectors will be handled in a followup.
The signed case will also be handled in a followup, as it needs some
more groundwork.
Differential Revision: https://reviews.llvm.org/D59386
Modified:
llvm/trunk/lib/Analysis/ValueTracking.cpp
llvm/trunk/test/Transforms/InstCombine/and2.ll
llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll
llvm/trunk/test/Transforms/InstCombine/uadd-with-overflow.ll
llvm/trunk/test/Transforms/LoopVectorize/X86/small-size.ll
Modified: llvm/trunk/lib/Analysis/ValueTracking.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/ValueTracking.cpp?rev=356489&r1=356488&r2=356489&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/ValueTracking.cpp (original)
+++ llvm/trunk/lib/Analysis/ValueTracking.cpp Tue Mar 19 10:53:56 2019
@@ -4077,18 +4077,27 @@ static OverflowResult mapOverflowResult(
llvm_unreachable("Unknown OverflowResult");
}
+/// Combine constant ranges from computeConstantRange() and computeKnownBits().
+static ConstantRange computeConstantRangeIncludingKnownBits(
+ const Value *V, bool ForSigned, const DataLayout &DL, unsigned Depth,
+ AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT,
+ OptimizationRemarkEmitter *ORE = nullptr, bool UseInstrInfo = true) {
+ KnownBits Known = computeKnownBits(
+ V, DL, Depth, AC, CxtI, DT, ORE, UseInstrInfo);
+ ConstantRange CR = computeConstantRange(V, UseInstrInfo);
+ return ConstantRange::fromKnownBits(Known, ForSigned).intersectWith(CR);
+}
+
OverflowResult llvm::computeOverflowForUnsignedAdd(
const Value *LHS, const Value *RHS, const DataLayout &DL,
AssumptionCache *AC, const Instruction *CxtI, const DominatorTree *DT,
bool UseInstrInfo) {
- KnownBits LHSKnown = computeKnownBits(LHS, DL, /*Depth=*/0, AC, CxtI, DT,
- nullptr, UseInstrInfo);
- KnownBits RHSKnown = computeKnownBits(RHS, DL, /*Depth=*/0, AC, CxtI, DT,
- nullptr, UseInstrInfo);
- ConstantRange LHSRange =
- ConstantRange::fromKnownBits(LHSKnown, /*signed*/ false);
- ConstantRange RHSRange =
- ConstantRange::fromKnownBits(RHSKnown, /*signed*/ false);
+ ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
+ LHS, /*ForSigned=*/false, DL, /*Depth=*/0, AC, CxtI, DT,
+ nullptr, UseInstrInfo);
+ ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
+ RHS, /*ForSigned=*/false, DL, /*Depth=*/0, AC, CxtI, DT,
+ nullptr, UseInstrInfo);
return mapOverflowResult(LHSRange.unsignedAddMayOverflow(RHSRange));
}
@@ -4161,12 +4170,10 @@ OverflowResult llvm::computeOverflowForU
AssumptionCache *AC,
const Instruction *CxtI,
const DominatorTree *DT) {
- 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*/ false);
- ConstantRange RHSRange =
- ConstantRange::fromKnownBits(RHSKnown, /*signed*/ false);
+ ConstantRange LHSRange = computeConstantRangeIncludingKnownBits(
+ LHS, /*ForSigned=*/false, DL, /*Depth=*/0, AC, CxtI, DT);
+ ConstantRange RHSRange = computeConstantRangeIncludingKnownBits(
+ RHS, /*ForSigned=*/false, DL, /*Depth=*/0, AC, CxtI, DT);
return mapOverflowResult(LHSRange.unsignedSubMayOverflow(RHSRange));
}
@@ -5690,6 +5697,10 @@ static void setLimitsForSelectPattern(co
ConstantRange llvm::computeConstantRange(const Value *V, bool UseInstrInfo) {
assert(V->getType()->isIntOrIntVectorTy() && "Expected integer instruction");
+ const APInt *C;
+ if (match(V, m_APInt(C)))
+ return ConstantRange(*C);
+
InstrInfoQuery IIQ(UseInstrInfo);
unsigned BitWidth = V->getType()->getScalarSizeInBits();
APInt Lower = APInt(BitWidth, 0);
Modified: llvm/trunk/test/Transforms/InstCombine/and2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/and2.ll?rev=356489&r1=356488&r2=356489&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/and2.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/and2.ll Tue Mar 19 10:53:56 2019
@@ -154,7 +154,7 @@ define i8 @and1_lshr1_is_cmp_eq_0_multiu
; 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 i8 [[SH]], [[AND]]
+; CHECK-NEXT: [[ADD:%.*]] = add nuw i8 [[SH]], [[AND]]
; CHECK-NEXT: ret i8 [[ADD]]
;
%sh = lshr i8 1, %x
Modified: llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll?rev=356489&r1=356488&r2=356489&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/saturating-add-sub.ll Tue Mar 19 10:53:56 2019
@@ -355,7 +355,7 @@ define i8 @test_scalar_uadd_sub_nuw_lost
define i8 @test_scalar_uadd_urem_no_ov(i8 %a) {
; CHECK-LABEL: @test_scalar_uadd_urem_no_ov(
; CHECK-NEXT: [[B:%.*]] = urem i8 [[A:%.*]], 100
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[B]], i8 -100)
+; CHECK-NEXT: [[R:%.*]] = add nuw nsw i8 [[B]], -100
; CHECK-NEXT: ret i8 [[R]]
;
%b = urem i8 %a, 100
@@ -379,7 +379,7 @@ define i8 @test_scalar_uadd_urem_known_b
; CHECK-LABEL: @test_scalar_uadd_urem_known_bits(
; CHECK-NEXT: [[AA:%.*]] = udiv i8 -66, [[A:%.*]]
; CHECK-NEXT: [[BB:%.*]] = and i8 [[B:%.*]], 63
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.uadd.sat.i8(i8 [[AA]], i8 [[BB]])
+; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[AA]], [[BB]]
; CHECK-NEXT: ret i8 [[R]]
;
%aa = udiv i8 190, %a
@@ -768,8 +768,7 @@ define <2 x i8> @test_vector_ssub_neg_nn
define i8 @test_scalar_usub_add_nuw_no_ov(i8 %a) {
; CHECK-LABEL: @test_scalar_usub_add_nuw_no_ov(
-; CHECK-NEXT: [[B:%.*]] = add nuw i8 [[A:%.*]], 10
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 9)
+; CHECK-NEXT: [[R:%.*]] = add i8 [[A:%.*]], 1
; CHECK-NEXT: ret i8 [[R]]
;
%b = add nuw i8 %a, 10
@@ -779,9 +778,7 @@ define i8 @test_scalar_usub_add_nuw_no_o
define i8 @test_scalar_usub_add_nuw_eq(i8 %a) {
; CHECK-LABEL: @test_scalar_usub_add_nuw_eq(
-; CHECK-NEXT: [[B:%.*]] = add nuw i8 [[A:%.*]], 10
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 10)
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 [[A:%.*]]
;
%b = add nuw i8 %a, 10
%r = call i8 @llvm.usub.sat.i8(i8 %b, i8 10)
@@ -801,9 +798,7 @@ define i8 @test_scalar_usub_add_nuw_may_
define i8 @test_scalar_usub_urem_must_ov(i8 %a) {
; CHECK-LABEL: @test_scalar_usub_urem_must_ov(
-; CHECK-NEXT: [[B:%.*]] = urem i8 [[A:%.*]], 10
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[B]], i8 10)
-; CHECK-NEXT: ret i8 [[R]]
+; CHECK-NEXT: ret i8 0
;
%b = urem i8 %a, 10
%r = call i8 @llvm.usub.sat.i8(i8 %b, i8 10)
@@ -828,7 +823,7 @@ define i8 @test_scalar_usub_add_nuw_know
; CHECK-LABEL: @test_scalar_usub_add_nuw_known_bits(
; CHECK-NEXT: [[AA:%.*]] = add nuw i8 [[A:%.*]], 10
; CHECK-NEXT: [[BB:%.*]] = and i8 [[B:%.*]], 7
-; CHECK-NEXT: [[R:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[AA]], i8 [[BB]])
+; CHECK-NEXT: [[R:%.*]] = sub nuw i8 [[AA]], [[BB]]
; CHECK-NEXT: ret i8 [[R]]
;
%aa = add nuw i8 %a, 10
@@ -840,7 +835,7 @@ define i8 @test_scalar_usub_add_nuw_know
define i8 @test_scalar_usub_add_nuw_inferred(i8 %a) {
; CHECK-LABEL: @test_scalar_usub_add_nuw_inferred(
; CHECK-NEXT: [[B:%.*]] = call i8 @llvm.usub.sat.i8(i8 [[A:%.*]], i8 10)
-; CHECK-NEXT: [[R:%.*]] = add i8 [[B]], 9
+; CHECK-NEXT: [[R:%.*]] = add nuw i8 [[B]], 9
; CHECK-NEXT: ret i8 [[R]]
;
%b = call i8 @llvm.usub.sat.i8(i8 %a, i8 10)
@@ -850,8 +845,7 @@ define i8 @test_scalar_usub_add_nuw_infe
define <2 x i8> @test_vector_usub_add_nuw_no_ov(<2 x i8> %a) {
; CHECK-LABEL: @test_vector_usub_add_nuw_no_ov(
-; CHECK-NEXT: [[B:%.*]] = add nuw <2 x i8> [[A:%.*]], <i8 10, i8 10>
-; CHECK-NEXT: [[R:%.*]] = call <2 x i8> @llvm.usub.sat.v2i8(<2 x i8> [[B]], <2 x i8> <i8 9, i8 9>)
+; CHECK-NEXT: [[R:%.*]] = add <2 x i8> [[A:%.*]], <i8 1, i8 1>
; CHECK-NEXT: ret <2 x i8> [[R]]
;
%b = add nuw <2 x i8> %a, <i8 10, i8 10>
Modified: llvm/trunk/test/Transforms/InstCombine/uadd-with-overflow.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/uadd-with-overflow.ll?rev=356489&r1=356488&r2=356489&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/InstCombine/uadd-with-overflow.ll (original)
+++ llvm/trunk/test/Transforms/InstCombine/uadd-with-overflow.ll Tue Mar 19 10:53:56 2019
@@ -33,9 +33,8 @@ define { i8, i1 } @fold_on_constant_add_
define { i8, i1 } @no_fold_on_constant_add_overflow(i8 %x) {
; CHECK-LABEL: @no_fold_on_constant_add_overflow(
-; CHECK-NEXT: [[A:%.*]] = add nuw i8 [[X:%.*]], -56
-; CHECK-NEXT: [[B:%.*]] = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 [[A]], i8 56)
-; CHECK-NEXT: ret { i8, i1 } [[B]]
+; CHECK-NEXT: [[TMP1:%.*]] = insertvalue { i8, i1 } { i8 undef, i1 true }, i8 [[X:%.*]], 0
+; CHECK-NEXT: ret { i8, i1 } [[TMP1]]
;
%a = add nuw i8 %x, 200
%b = tail call { i8, i1 } @llvm.uadd.with.overflow.i8(i8 %a, i8 56)
Modified: llvm/trunk/test/Transforms/LoopVectorize/X86/small-size.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopVectorize/X86/small-size.ll?rev=356489&r1=356488&r2=356489&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/LoopVectorize/X86/small-size.ll (original)
+++ llvm/trunk/test/Transforms/LoopVectorize/X86/small-size.ll Tue Mar 19 10:53:56 2019
@@ -81,7 +81,7 @@ define void @example2(i32 %n, i32 %x) op
; CHECK-NEXT: [[N_RND_UP:%.*]] = add nuw nsw i64 [[TMP3]], 4
; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP2]], 3
; CHECK-NEXT: [[N_MOD_VF:%.*]] = zext i32 [[TMP4]] to i64
-; CHECK-NEXT: [[N_VEC:%.*]] = sub nsw i64 [[N_RND_UP]], [[N_MOD_VF]]
+; CHECK-NEXT: [[N_VEC:%.*]] = sub nuw nsw i64 [[N_RND_UP]], [[N_MOD_VF]]
; CHECK-NEXT: [[BROADCAST_SPLATINSERT1:%.*]] = insertelement <4 x i64> undef, i64 [[TMP3]], i32 0
; CHECK-NEXT: [[BROADCAST_SPLAT2:%.*]] = shufflevector <4 x i64> [[BROADCAST_SPLATINSERT1]], <4 x i64> undef, <4 x i32> zeroinitializer
; CHECK-NEXT: br label [[VECTOR_BODY:%.*]]
More information about the llvm-commits
mailing list