diff options
15 files changed, 56 insertions, 28 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index a48b935f88a..dee35392692 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -2205,19 +2205,32 @@ StrengthenNoWrapFlags(ScalarEvolution *SE, SCEVTypes Type, SignOrUnsignWrap = ScalarEvolution::maskFlags(Flags, SignOrUnsignMask); - if (SignOrUnsignWrap != SignOrUnsignMask && Type == scAddExpr && - Ops.size() == 2 && isa<SCEVConstant>(Ops[0])) { - - // (A + C) --> (A + C)<nsw> if the addition does not sign overflow - // (A + C) --> (A + C)<nuw> if the addition does not unsign overflow + if (SignOrUnsignWrap != SignOrUnsignMask && + (Type == scAddExpr || Type == scMulExpr) && Ops.size() == 2 && + isa<SCEVConstant>(Ops[0])) { + + auto Opcode = [&] { + switch (Type) { + case scAddExpr: + return Instruction::Add; + case scMulExpr: + return Instruction::Mul; + default: + llvm_unreachable("Unexpected SCEV op."); + } + }(); const APInt &C = cast<SCEVConstant>(Ops[0])->getAPInt(); + + // (A <opcode> C) --> (A <opcode> C)<nsw> if the op doesn't sign overflow. if (!(SignOrUnsignWrap & SCEV::FlagNSW)) { auto NSWRegion = ConstantRange::makeGuaranteedNoWrapRegion( - Instruction::Add, C, OBO::NoSignedWrap); + Opcode, C, OBO::NoSignedWrap); if (NSWRegion.contains(SE->getSignedRange(Ops[1]))) Flags = ScalarEvolution::setFlags(Flags, SCEV::FlagNSW); } + + // (A <opcode> C) --> (A <opcode> C)<nuw> if the op doesn't unsign overflow. if (!(SignOrUnsignWrap & SCEV::FlagNUW)) { auto NUWRegion = ConstantRange::makeGuaranteedNoWrapRegion( Instruction::Add, C, OBO::NoUnsignedWrap); diff --git a/llvm/test/Analysis/Delinearization/a.ll b/llvm/test/Analysis/Delinearization/a.ll index a105c205c5e..df0e2b16f23 100644 --- a/llvm/test/Analysis/Delinearization/a.ll +++ b/llvm/test/Analysis/Delinearization/a.ll @@ -10,7 +10,7 @@ ; AddRec: {{{(28 + (4 * (-4 + (3 * %m)) * %o) + %A),+,(8 * %m * %o)}<%for.i>,+,(12 * %o)}<%for.j>,+,20}<%for.k> ; CHECK: Base offset: %A ; CHECK: ArrayDecl[UnknownSize][%m][%o] with elements of 4 bytes. -; CHECK: ArrayRef[{3,+,2}<%for.i>][{-4,+,3}<nw><%for.j>][{7,+,5}<nw><%for.k>] +; CHECK: ArrayRef[{3,+,2}<nw><%for.i>][{-4,+,3}<nw><%for.j>][{7,+,5}<nw><%for.k>] define void @foo(i64 %n, i64 %m, i64 %o, i32* nocapture %A) #0 { entry: diff --git a/llvm/test/Analysis/Delinearization/iv_times_constant_in_subscript.ll b/llvm/test/Analysis/Delinearization/iv_times_constant_in_subscript.ll index bd2f34df6a1..bd98d0a2b57 100644 --- a/llvm/test/Analysis/Delinearization/iv_times_constant_in_subscript.ll +++ b/llvm/test/Analysis/Delinearization/iv_times_constant_in_subscript.ll @@ -11,7 +11,7 @@ ; AddRec: {{((%m * %b * 8) + %A),+,(2 * %m * 8)}<%for.i>,+,(2 * 8)}<%for.j> ; CHECK: Base offset: %A ; CHECK: ArrayDecl[UnknownSize][%m] with elements of 8 bytes. -; CHECK: ArrayRef[{%b,+,2}<nsw><%for.i>][{0,+,2}<%for.j>] +; CHECK: ArrayRef[{%b,+,2}<nsw><%for.i>][{0,+,2}<nuw><%for.j>] define void @foo(i64 %n, i64 %m, i64 %b, double* %A) { diff --git a/llvm/test/Analysis/IVUsers/quadradic-exit-value.ll b/llvm/test/Analysis/IVUsers/quadradic-exit-value.ll index afc21519821..1597bfa8a37 100644 --- a/llvm/test/Analysis/IVUsers/quadradic-exit-value.ll +++ b/llvm/test/Analysis/IVUsers/quadradic-exit-value.ll @@ -70,7 +70,7 @@ exit: ; sure they aren't marked as post-inc users. ; ; CHECK-LABEL: IV Users for loop %test2.loop -; CHECK-NO-LCSSA: %sub.cond.us = ((-1 * %sub.us)<nsw> + {0,+,1}<nuw><nsw><%test2.loop>) (post-inc with loop %test2.loop) in %sext.us = mul i32 %mul.us, %sub.cond.us +; CHECK-NO-LCSSA: %sub.cond.us = ((-1 * %sub.us)<nuw><nsw> + {0,+,1}<nuw><nsw><%test2.loop>) (post-inc with loop %test2.loop) in %sext.us = mul i32 %mul.us, %sub.cond.us define i32 @test2() { entry: br label %test2.loop diff --git a/llvm/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll b/llvm/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll index 2bae4867870..4528976a09e 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/number-of-memchecks.ll @@ -251,10 +251,10 @@ for.end: ; preds = %for.body ; CHECK-NEXT: Member: {((2 * %offset) + %a)<nsw>,+,2}<nsw><%for.body> ; CHECK-NEXT: Group {{.*}}[[ONE]]: ; CHECK-NEXT: (Low: %a High: (10000 + %a)) -; CHECK-NEXT: Member: {%a,+,2}<%for.body> +; CHECK-NEXT: Member: {%a,+,2}<nw><%for.body> ; CHECK-NEXT: Group {{.*}}[[TWO]]: ; CHECK-NEXT: (Low: (20000 + %a) High: (30000 + %a)) -; CHECK-NEXT: Member: {(20000 + %a),+,2}<%for.body> +; CHECK-NEXT: Member: {(20000 + %a),+,2}<nw><%for.body> define void @testi(i16* %a, i64 %offset) { diff --git a/llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll b/llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll index 75a71b44428..1329761a8e5 100644 --- a/llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll +++ b/llvm/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll @@ -33,7 +33,7 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" ; i64 {0,+,2}<%for.body> ; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext: -; LAA-NEXT: ((2 * (zext i32 {0,+,2}<%for.body> to i64)) + %a) +; LAA-NEXT: ((2 * (zext i32 {0,+,2}<%for.body> to i64))<nuw> + %a) ; LAA-NEXT: --> {%a,+,4}<%for.body> @@ -122,7 +122,7 @@ for.end: ; preds = %for.body ; LAA: Memory dependences are safe{{$}} ; LAA: SCEV assumptions: ; LAA-NEXT: {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> Added Flags: <nusw> -; LAA-NEXT: {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> Added Flags: <nusw> +; LAA-NEXT: {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64))<nuw> + %a),+,-4}<%for.body> Added Flags: <nusw> ; The expression for %mul_ext as analyzed by SCEV is ; (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64) @@ -130,8 +130,8 @@ for.end: ; preds = %for.body ; i64 {zext i32 (2 * (trunc i64 %N to i32)) to i64,+,-2}<%for.body> ; LAA: [PSE] %arrayidxA = getelementptr i16, i16* %a, i64 %mul_ext: -; LAA-NEXT: ((2 * (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64)) + %a) -; LAA-NEXT: --> {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64)) + %a),+,-4}<%for.body> +; LAA-NEXT: ((2 * (zext i32 {(2 * (trunc i64 %N to i32)),+,-2}<%for.body> to i64))<nuw> + %a) +; LAA-NEXT: --> {((2 * (zext i32 (2 * (trunc i64 %N to i32)) to i64))<nuw> + %a),+,-4}<%for.body> ; LV-LABEL: f2 ; LV-LABEL: for.body.lver.check diff --git a/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll b/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll index 8e207ed8147..42d2a3722b1 100644 --- a/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll +++ b/llvm/test/Analysis/ScalarEvolution/different-loops-recs.ll @@ -321,7 +321,7 @@ define void @test_05(i32 %N) { ; CHECK: %SQ = mul i32 %i.0, %i.0 ; CHECK-NEXT: --> {4,+,5,+,2}<%bb3> ; CHECK: %tmp4 = mul i32 %i.0, 2 -; CHECK-NEXT: --> {4,+,2}<%bb3> +; CHECK-NEXT: --> {4,+,2}<nuw><%bb3> ; CHECK: %tmp5 = sub i32 %SQ, %tmp4 ; CHECK-NEXT: --> {0,+,3,+,2}<%bb3> diff --git a/llvm/test/Analysis/ScalarEvolution/mul-nuw.ll b/llvm/test/Analysis/ScalarEvolution/mul-nuw.ll new file mode 100644 index 00000000000..4d996fb07ce --- /dev/null +++ b/llvm/test/Analysis/ScalarEvolution/mul-nuw.ll @@ -0,0 +1,15 @@ +; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s + +; Check that we add nuw to multiplies by a constant where we can infer that the +; multiply does not have unsigned overflow. +declare i32 @get_int(); + +define void @foo() { + %a = call i32 @get_int(), !range !0 + %b = mul i32 %a, 4 + ; CHECK: %b + ; CHECK-NEXT: --> (4 * %a)<nuw> + ret void +} + +!0 = !{i32 0, i32 100} diff --git a/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll b/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll index 5413b477df5..3ef31ff5581 100644 --- a/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll @@ -79,5 +79,5 @@ declare void @llvm.assume(i1) nounwind ; Note: Without the preheader assume, there is an 'smax' in the ; backedge-taken count expression: -; CHECK: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) +; CHECK: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))<nuw>) /u 2) ; CHECK: Loop %bb: max backedge-taken count is 1073741822 diff --git a/llvm/test/Analysis/ScalarEvolution/nsw-offset.ll b/llvm/test/Analysis/ScalarEvolution/nsw-offset.ll index f8ed8f003ff..a5c4b575f13 100644 --- a/llvm/test/Analysis/ScalarEvolution/nsw-offset.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw-offset.ll @@ -73,5 +73,5 @@ return: ; preds = %bb1.return_crit_edg ret void } -; CHECK: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) +; CHECK: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))<nuw>) /u 2) ; CHECK: Loop %bb: max backedge-taken count is 1073741822 diff --git a/llvm/test/Analysis/ScalarEvolution/nsw.ll b/llvm/test/Analysis/ScalarEvolution/nsw.ll index 39b958d3ea0..43e0213ec5f 100644 --- a/llvm/test/Analysis/ScalarEvolution/nsw.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw.ll @@ -25,7 +25,7 @@ bb: ; preds = %bb1, %bb.nph %tmp6 = sext i32 %i.01 to i64 ; <i64> [#uses=1] %tmp7 = getelementptr double, double* %p, i64 %tmp6 ; <double*> [#uses=1] ; CHECK: %tmp7 -; CHECK-NEXT: --> {%p,+,8}<%bb> +; CHECK-NEXT: --> {%p,+,8}<nw><%bb> store double %tmp5, double* %tmp7, align 8 %tmp8 = add nsw i32 %i.01, 1 ; <i32> [#uses=2] ; CHECK: %tmp8 @@ -126,7 +126,7 @@ exit: } ; CHECK-LABEL: PR12375 -; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax (8 + %arg)<nsw>)) /u 4)) + %arg) +; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb1>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax (8 + %arg)<nsw>)) /u 4))<nuw> + %arg) define i32 @PR12375(i32* readnone %arg) { bb: %tmp = getelementptr inbounds i32, i32* %arg, i64 2 @@ -145,7 +145,7 @@ bb7: ; preds = %bb1 } ; CHECK-LABEL: PR12376 -; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax %arg1)) /u 4)) + %arg) +; CHECK: --> {(4 + %arg)<nsw>,+,4}<nuw><%bb2>{{ U: [^ ]+ S: [^ ]+}}{{ *}}Exits: (4 + (4 * ((-1 + (-1 * %arg) + ((4 + %arg)<nsw> umax %arg1)) /u 4))<nuw> + %arg) define void @PR12376(i32* nocapture %arg, i32* nocapture %arg1) { bb: br label %bb2 diff --git a/llvm/test/Analysis/ScalarEvolution/sext-mul.ll b/llvm/test/Analysis/ScalarEvolution/sext-mul.ll index ca25d9e2efa..88002fb0e73 100644 --- a/llvm/test/Analysis/ScalarEvolution/sext-mul.ll +++ b/llvm/test/Analysis/ScalarEvolution/sext-mul.ll @@ -1,7 +1,7 @@ ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s ; CHECK: %tmp9 = shl i64 %tmp8, 33 -; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))) +; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))<nuw>) ; CHECK: %tmp10 = ashr exact i64 %tmp9, 32 ; CHECK-NEXT: --> {{.*}} Exits: (sext i32 (-2 + (2 * %arg2)) to i64) ; CHECK: %tmp11 = getelementptr inbounds i32, i32* %arg, i64 %tmp10 @@ -48,9 +48,9 @@ bb7: ; preds = %bb7, %bb3 } ; CHECK: %t10 = ashr exact i128 %t9, 1 -; CHECK-NEXT: --> {{.*}} Exits: (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))) to i128) +; CHECK-NEXT: --> {{.*}} Exits: (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))<nuw>) to i128) ; CHECK: %t14 = or i128 %t10, 1 -; CHECK-NEXT: --> {{.*}} Exits: (1 + (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))) to i128))<nsw> +; CHECK-NEXT: --> {{.*}} Exits: (1 + (sext i127 (-633825300114114700748351602688 + (633825300114114700748351602688 * (zext i32 %arg5 to i127))<nuw>) to i128))<nsw> ; CHECK: Loop %bb7: backedge-taken count is (-1 + (zext i32 %arg5 to i128))<nsw> ; CHECK-NEXT: Loop %bb7: max backedge-taken count is -1 ; CHECK-NEXT: Loop %bb7: Predicated backedge-taken count is (-1 + (zext i32 %arg5 to i128))<nsw> diff --git a/llvm/test/Analysis/ScalarEvolution/sext-zero.ll b/llvm/test/Analysis/ScalarEvolution/sext-zero.ll index cac42638e95..31c8e50748c 100644 --- a/llvm/test/Analysis/ScalarEvolution/sext-zero.ll +++ b/llvm/test/Analysis/ScalarEvolution/sext-zero.ll @@ -1,9 +1,9 @@ ; RUN: opt < %s -analyze -scalar-evolution | FileCheck %s ; CHECK: %tmp9 = shl i64 %tmp8, 33 -; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))) +; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))<nuw>) ; CHECK-NEXT: %tmp10 = ashr exact i64 %tmp9, 0 -; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))) +; CHECK-NEXT: --> {{.*}} Exits: (-8589934592 + (8589934592 * (zext i32 %arg2 to i64))<nuw>) define void @foo(i32* nocapture %arg, i32 %arg1, i32 %arg2) { bb: diff --git a/llvm/test/Analysis/ScalarEvolution/trip-count-pow2.ll b/llvm/test/Analysis/ScalarEvolution/trip-count-pow2.ll index 04d1b9544ab..3a6f5fec2b8 100644 --- a/llvm/test/Analysis/ScalarEvolution/trip-count-pow2.ll +++ b/llvm/test/Analysis/ScalarEvolution/trip-count-pow2.ll @@ -31,7 +31,7 @@ exit: ret i32 %i ; CHECK-LABEL: @test2 -; CHECK: Loop %loop: backedge-taken count is ((-32 + (32 * (%n /u 32))) /u 32) +; CHECK: Loop %loop: backedge-taken count is ((-32 + (32 * (%n /u 32))<nuw>) /u 32) ; CHECK: Loop %loop: max backedge-taken count is 134217727 } diff --git a/llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll b/llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll index 82b2120c0e8..ad63277db55 100644 --- a/llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll +++ b/llvm/test/Transforms/IndVarSimplify/2011-09-10-widen-nsw.ll @@ -20,7 +20,7 @@ for.body153: ; preds = %for.body153, %for.b ; CHECK: add nuw nsw i64 %indvars.iv, 1 ; CHECK: sub nsw i64 %indvars.iv, 2 ; CHECK: sub nsw i64 4, %indvars.iv -; CHECK: mul nsw i64 %indvars.iv, 8 +; CHECK: mul nuw nsw i64 %indvars.iv, 8 for.body170: ; preds = %for.body170, %for.body153 %i2.19 = phi i32 [ %add249, %for.body170 ], [ 0, %for.body153 ] |