diff --git a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll index ba50055dd916..ed6fbc0bda7e 100644 --- a/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll +++ b/llvm/test/Analysis/ScalarEvolution/flags-from-poison.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py ; RUN: opt < %s -S -disable-output "-passes=print" 2>&1 | FileCheck %s ; Positive and negative tests for inferring flags like nsw from @@ -5,24 +6,42 @@ ; undefined behavior. define void @foo() { +; CHECK-LABEL: 'foo' +; CHECK-NEXT: Classifying expressions for: @foo +; CHECK-NEXT: Determining loop execution counts for: @foo +; ret void } ; Example where an add should get the nsw flag, so that a sext can be ; distributed over the add. define void @test-add-nsw(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-nsw +; CHECK-LABEL: 'test-add-nsw' +; CHECK-NEXT: Classifying expressions for: @test-add-nsw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {(sext i32 %offset to i64),+,1}<%loop> U: [-2147483648,6442450943) S: [-2147483648,6442450943) Exits: ((zext i32 (-1 + %numIterations) to i64) + (sext i32 %offset to i64)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset -; CHECK: %index64 = -; CHECK: --> {(sext i32 %offset to i64),+,1} %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -37,14 +56,28 @@ exit: ; Example where an add should get the nuw flag. define void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-nuw +; CHECK-LABEL: 'test-add-nuw' +; CHECK-NEXT: Classifying expressions for: @test-add-nuw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nuw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-nuw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nuw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -58,15 +91,31 @@ exit: } define void @test-add-nuw-from-icmp(float* %input, i32 %offset, - i32 %numIterations) { -; CHECK-LABEL: @test-add-nuw-from-icmp +; CHECK-LABEL: 'test-add-nuw-from-icmp' +; CHECK-NEXT: Classifying expressions for: @test-add-nuw-from-icmp +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nuw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %cmp.idx = sext i1 %cmp to i32 +; CHECK-NEXT: --> (sext i1 %cmp to i32) U: [-1,1) S: [-1,1) Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %cmp.idx +; CHECK-NEXT: --> ((4 * (sext i1 %cmp to i64)) + %input) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-nuw-from-icmp +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; + i32 %numIterations) { entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nuw i32 %i, %offset %cmp = icmp sgt i32 %index32, 0 %cmp.idx = sext i1 %cmp to i32 @@ -83,14 +132,28 @@ exit: ; With no load to trigger UB from poison, we cannot infer nsw. define void @test-add-no-load(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-no-load +; CHECK-LABEL: 'test-add-no-load' +; CHECK-NEXT: Classifying expressions for: @test-add-no-load +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-no-load +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -106,7 +169,23 @@ exit: ; it should not infer nsw in this case, as that would require looking ; outside the loop header. define void @test-add-not-header(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-not-header +; CHECK-LABEL: 'test-add-not-header' +; CHECK-NEXT: Classifying expressions for: @test-add-not-header +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: @@ -114,8 +193,6 @@ loop: br label %loop2 loop2: -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -130,14 +207,28 @@ exit: ; Same thing as test-add-not-header, but in this case only the load ; instruction is outside the loop header. define void @test-add-not-header2(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-not-header2 +; CHECK-LABEL: 'test-add-not-header2' +; CHECK-NEXT: Classifying expressions for: @test-add-not-header2 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header2 +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -154,15 +245,31 @@ exit: ; Similar to test-add-not-header, but in this case the load ; instruction may not be executed. define void @test-add-not-header3(float* %input, i32 %offset, i32 %numIterations, - i1* %cond_buf) { -; CHECK-LABEL: @test-add-not-header3 +; CHECK-LABEL: 'test-add-not-header3' +; CHECK-NEXT: Classifying expressions for: @test-add-not-header3 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %cond = load volatile i1, i1* %cond_buf, align 1 +; CHECK-NEXT: --> %cond U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header3 +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: exit count for loop2: (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; + i1* %cond_buf) { entry: br label %loop loop: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -180,14 +287,28 @@ exit: ; Same thing as test-add-not-header2, except we have a few extra ; blocks. define void @test-add-not-header4(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-not-header4 +; CHECK-LABEL: 'test-add-not-header4' +; CHECK-NEXT: Classifying expressions for: @test-add-not-header4 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header4 +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -207,14 +328,26 @@ exit: ; Demonstrate why we need a Visited set in llvm::programUndefinedIfPoison. define void @test-add-not-header5(float* %input, i32 %offset) { -; CHECK-LABEL: @test-add-not-header5 +; CHECK-LABEL: 'test-add-not-header5' +; CHECK-NEXT: Classifying expressions for: @test-add-not-header5 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-not-header5 +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable max backedge-taken count. +; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -229,14 +362,28 @@ exit: ; executed, since it could run forever or throw an exception, so we ; cannot assume that the UB is realized. define void @test-add-call(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-call +; CHECK-LABEL: 'test-add-call' +; CHECK-NEXT: Classifying expressions for: @test-add-call +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-call +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} call void @foo() %index32 = add nsw i32 %i, %offset @@ -252,14 +399,28 @@ exit: ; Same issue as test-add-call, but this time the call is between the ; producer of poison and the load that consumes it. define void @test-add-call2(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-call2 +; CHECK-LABEL: 'test-add-call2' +; CHECK-NEXT: Classifying expressions for: @test-add-call2 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {%offset,+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-1 + %offset + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-call2 +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -274,14 +435,28 @@ exit: ; Any poison input makes getelementptr produce poison define void @test-gep-propagates-poison(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-gep-propagates-poison +; CHECK-LABEL: 'test-gep-propagates-poison' +; CHECK-NEXT: Classifying expressions for: @test-gep-propagates-poison +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr float, float* %input, i32 %index32 +; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-gep-propagates-poison +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr float, float* %input, i32 %index32 @@ -296,14 +471,30 @@ exit: ; Multiplication by a non-zero constant propagates poison if there is ; a nuw or nsw flag on the multiplication. define void @test-add-mul-propagates(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-mul-propagates +; CHECK-LABEL: 'test-add-mul-propagates' +; CHECK-NEXT: Classifying expressions for: @test-add-mul-propagates +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %indexmul = mul nuw i32 %index32, 2 +; CHECK-NEXT: --> {(2 * %offset),+,2}<%loop> U: [0,-1) S: [-2147483648,2147483647) Exits: (-2 + (2 * %offset) + (2 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %indexmul +; CHECK-NEXT: --> ((4 * (sext i32 {(2 * %offset),+,2}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2 + (2 * %offset) + (2 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-mul-propagates +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %indexmul = mul nuw i32 %index32, 2 @@ -318,14 +509,30 @@ exit: ; Any poison input to multiplication propages poison. define void @test-mul-propagates-poison(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-mul-propagates-poison +; CHECK-LABEL: 'test-mul-propagates-poison' +; CHECK-NEXT: Classifying expressions for: @test-mul-propagates-poison +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %indexmul = mul nsw i32 %index32, %offset +; CHECK-NEXT: --> {(%offset * %offset),+,%offset}<%loop> U: full-set S: full-set Exits: ((-1 + %offset + %numIterations) * %offset) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %indexmul +; CHECK-NEXT: --> {((4 * (sext i32 (%offset * %offset) to i64)) + %input),+,(4 * (sext i32 %offset to i64))}<%loop> U: full-set S: full-set Exits: ((4 * (sext i32 (%offset * %offset) to i64)) + (4 * (zext i32 (-1 + %numIterations) to i64) * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-mul-propagates-poison +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %indexmul = mul nsw i32 %index32, %offset @@ -339,14 +546,30 @@ exit: } define void @test-mul-propagates-poison-2(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-mul-propagates-poison-2 +; CHECK-LABEL: 'test-mul-propagates-poison-2' +; CHECK-NEXT: Classifying expressions for: @test-mul-propagates-poison-2 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %indexmul = mul i32 %index32, 2 +; CHECK-NEXT: --> {(2 * %offset),+,2}<%loop> U: [0,-1) S: [-2147483648,2147483647) Exits: (-2 + (2 * %offset) + (2 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %indexmul +; CHECK-NEXT: --> ((4 * (sext i32 {(2 * %offset),+,2}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2 + (2 * %offset) + (2 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-mul-propagates-poison-2 +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %indexmul = mul i32 %index32, 2 @@ -361,14 +584,28 @@ exit: ; Division by poison triggers UB. define void @test-add-div(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-div +; CHECK-LABEL: 'test-add-div' +; CHECK-NEXT: Classifying expressions for: @test-add-div +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %j = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %q = sdiv i32 %numIterations, %j +; CHECK-NEXT: --> %q U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-div +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %j = -; CHECK: --> {%offset,+,1} %j = add nsw i32 %i, %offset %q = sdiv i32 %numIterations, %j @@ -381,14 +618,28 @@ exit: ; Remainder of poison by non-poison divisor does not trigger UB. define void @test-add-div2(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-div2 +; CHECK-LABEL: 'test-add-div2' +; CHECK-NEXT: Classifying expressions for: @test-add-div2 +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %j = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %q = sdiv i32 %j, %numIterations +; CHECK-NEXT: --> %q U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-div2 +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %j = -; CHECK: --> {%offset,+,1} %j = add nsw i32 %i, %offset %q = sdiv i32 %j, %numIterations @@ -401,14 +652,28 @@ exit: ; Store to poison address triggers UB. define void @test-add-store(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-store +; CHECK-LABEL: 'test-add-store' +; CHECK-NEXT: Classifying expressions for: @test-add-store +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %i, %offset +; CHECK-NEXT: --> {%offset,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {((4 * (sext i32 %offset to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-store +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {%offset,+,1} %index32 = add nsw i32 %i, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -425,12 +690,30 @@ exit: ; put the final add first in the program since otherwise the special case ; is not triggered, hence the strange basic block ordering. define void @test-add-twice(float* %input, i32 %offset, i32 %numIterations) { -; CHECK-LABEL: @test-add-twice +; CHECK-LABEL: 'test-add-twice' +; CHECK-NEXT: Classifying expressions for: @test-add-twice +; CHECK-NEXT: %seq = add nuw nsw i32 %index32, 1 +; CHECK-NEXT: --> {(2 + %offset),+,1}<%loop> U: full-set S: full-set Exits: (1 + %offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %j = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %j, %offset +; CHECK-NEXT: --> {(1 + %offset),+,1}<%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: (%offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {(4 + (4 * (sext i32 %offset to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: (4 + (4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 %offset to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-twice +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop2: -; CHECK: %seq = -; CHECK: --> {(2 + %offset),+,1} %seq = add nsw nuw i32 %index32, 1 %exitcond = icmp eq i32 %nexti, %numIterations br i1 %exitcond, label %exit, label %loop @@ -439,8 +722,6 @@ loop: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] %j = add nsw i32 %i, 1 -; CHECK: %index32 = -; CHECK: --> {(1 + %offset),+,1} %index32 = add nsw i32 %j, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -454,18 +735,32 @@ exit: ; Example where a mul should get the nsw flag, so that a sext can be ; distributed over the mul. define void @test-mul-nsw(float* %input, i32 %stride, i32 %numIterations) { -; CHECK-LABEL: @test-mul-nsw +; CHECK-LABEL: 'test-mul-nsw' +; CHECK-NEXT: Classifying expressions for: @test-mul-nsw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = mul nsw i32 %i, %stride +; CHECK-NEXT: --> {0,+,%stride}<%loop> U: full-set S: full-set Exits: ((-1 + %numIterations) * %stride) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {0,+,(sext i32 %stride to i64)}<%loop> U: [-9223372034707292160,9223372030412324866) S: [-9223372034707292160,9223372030412324866) Exits: ((zext i32 (-1 + %numIterations) to i64) * (sext i32 %stride to i64)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {%input,+,(4 * (sext i32 %stride to i64))}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64) * (sext i32 %stride to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-mul-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {0,+,%stride} %index32 = mul nsw i32 %i, %stride -; CHECK: %index64 = -; CHECK: --> {0,+,(sext i32 %stride to i64)} %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -479,14 +774,28 @@ exit: ; Example where a mul should get the nuw flag. define void @test-mul-nuw(float* %input, i32 %stride, i32 %numIterations) { -; CHECK-LABEL: @test-mul-nuw +; CHECK-LABEL: 'test-mul-nuw' +; CHECK-NEXT: Classifying expressions for: @test-mul-nuw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = mul nuw i32 %i, %stride +; CHECK-NEXT: --> {0,+,%stride}<%loop> U: full-set S: full-set Exits: ((-1 + %numIterations) * %stride) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {0,+,%stride}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 ((-1 + %numIterations) * %stride) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-mul-nuw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {0,+,%stride} %index32 = mul nuw i32 %i, %stride %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -502,18 +811,32 @@ exit: ; Example where a shl should get the nsw flag, so that a sext can be ; distributed over the shl. define void @test-shl-nsw(float* %input, i32 %start, i32 %numIterations) { -; CHECK-LABEL: @test-shl-nsw +; CHECK-LABEL: 'test-shl-nsw' +; CHECK-NEXT: Classifying expressions for: @test-shl-nsw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = shl nsw i32 %i, 8 +; CHECK-NEXT: --> {(256 * %start),+,256}<%loop> U: [0,-255) S: [-2147483648,2147483393) Exits: (-256 + (256 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {(sext i32 (256 * %start) to i64),+,256}<%loop> U: [0,-255) S: [-2147483648,1101659110913) Exits: ((sext i32 (256 * %start) to i64) + (256 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((4 * (sext i32 (256 * %start) to i64)) + %input),+,1024}<%loop> U: full-set S: full-set Exits: ((4 * (sext i32 (256 * %start) to i64)) + (1024 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-shl-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {(256 * %start),+,256} %index32 = shl nsw i32 %i, 8 -; CHECK: %index64 = -; CHECK: --> {(sext i32 (256 * %start) to i64),+,256} %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -527,18 +850,32 @@ exit: ; Example where a shl should get the nuw flag define void @test-shl-nuw-edgecase(float* %input, i32 %start, i32 %numIterations) { -; CHECK-LABEL: @test-shl-nuw-edgecase +; CHECK-LABEL: 'test-shl-nuw-edgecase' +; CHECK-NEXT: Classifying expressions for: @test-shl-nuw-edgecase +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = shl nuw i32 %i, 31 +; CHECK-NEXT: --> {(-2147483648 * %start),+,-2147483648}<%loop> U: [0,-2147483647) S: [-2147483648,1) Exits: (-2147483648 + (-2147483648 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64) U: [0,-2147483647) S: [-2147483648,1) Exits: (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> ((4 * (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-shl-nuw-edgecase +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {(-2147483648 * %start),+,-2147483648}<%loop> %index32 = shl nuw i32 %i, 31 -; CHECK: %index64 = -; CHECK: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -552,18 +889,32 @@ exit: ; Example where a shl should get the nuw flag define void @test-shl-nuw-nsw(float* %input, i32 %start, i32 %numIterations) { -; CHECK-LABEL: @test-shl-nuw-nsw +; CHECK-LABEL: 'test-shl-nuw-nsw' +; CHECK-NEXT: Classifying expressions for: @test-shl-nuw-nsw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = shl nuw nsw i32 %i, 31 +; CHECK-NEXT: --> {(-2147483648 * %start),+,-2147483648}<%loop> U: [0,-2147483647) S: [-2147483648,1) Exits: (-2147483648 + (-2147483648 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {(sext i32 (-2147483648 * %start) to i64),+,-2147483648}<%loop> U: [0,-2147483647) S: [-9223372036854775808,1) Exits: ((sext i32 (-2147483648 * %start) to i64) + (-2147483648 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((4 * (sext i32 (-2147483648 * %start) to i64)) + %input),+,-8589934592}<%loop> U: full-set S: full-set Exits: ((4 * (sext i32 (-2147483648 * %start) to i64)) + (-8589934592 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-shl-nuw-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {(-2147483648 * %start),+,-2147483648}<%loop> %index32 = shl nuw nsw i32 %i, 31 -; CHECK: %index64 = -; CHECK: --> {(sext i32 (-2147483648 * %start) to i64),+,-2147483648}<%loop> %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -577,18 +928,32 @@ exit: ; Example where a shl should not get the nsw flag define void @test-shl-no-nsw(float* %input, i32 %start, i32 %numIterations) { -; CHECK-LABEL: @test-shl-no-nsw +; CHECK-LABEL: 'test-shl-no-nsw' +; CHECK-NEXT: Classifying expressions for: @test-shl-no-nsw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = shl nsw i32 %i, 31 +; CHECK-NEXT: --> {(-2147483648 * %start),+,-2147483648}<%loop> U: [0,-2147483647) S: [-2147483648,1) Exits: (-2147483648 + (-2147483648 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64) U: [0,-2147483647) S: [-2147483648,1) Exits: (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> ((4 * (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-2147483648 + (-2147483648 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-shl-no-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {(-2147483648 * %start),+,-2147483648}<%loop> %index32 = shl nsw i32 %i, 31 -; CHECK: %index64 = -; CHECK: --> (sext i32 {(-2147483648 * %start),+,-2147483648}<%loop> %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -602,18 +967,32 @@ exit: ; Example where a shl should get the nsw flag. define void @test-shl-nsw-edgecase(float* %input, i32 %start, i32 %numIterations) { -; CHECK-LABEL: @test-shl-nsw-edgecase +; CHECK-LABEL: 'test-shl-nsw-edgecase' +; CHECK-NEXT: Classifying expressions for: @test-shl-nsw-edgecase +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = shl nsw i32 %i, 30 +; CHECK-NEXT: --> {(1073741824 * %start),+,1073741824}<%loop> U: [0,-1073741823) S: [-2147483648,1073741825) Exits: (-1073741824 + (1073741824 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {(sext i32 (1073741824 * %start) to i64),+,1073741824}<%loop> U: [0,-1073741823) S: [-2147483648,4611686018427387905) Exits: ((sext i32 (1073741824 * %start) to i64) + (1073741824 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((4 * (sext i32 (1073741824 * %start) to i64)) + %input),+,4294967296}<%loop> U: full-set S: full-set Exits: ((4 * (sext i32 (1073741824 * %start) to i64)) + (4294967296 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-shl-nsw-edgecase +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {(1073741824 * %start),+,1073741824}<%loop> %index32 = shl nsw i32 %i, 30 -; CHECK: %index64 = -; CHECK: --> {(sext i32 (1073741824 * %start) to i64),+,1073741824}<%loop> %index64 = sext i32 %index32 to i64 %ptr = getelementptr inbounds float, float* %input, i64 %index64 @@ -627,14 +1006,28 @@ exit: ; Example where a shl should get the nuw flag. define void @test-shl-nuw(float* %input, i32 %numIterations) { -; CHECK-LABEL: @test-shl-nuw +; CHECK-LABEL: 'test-shl-nuw' +; CHECK-NEXT: Classifying expressions for: @test-shl-nuw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = shl nuw i32 %i, 9 +; CHECK-NEXT: --> {0,+,512}<%loop> U: [0,-511) S: [-2147483648,2147483137) Exits: (-512 + (512 * %numIterations)) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {0,+,512}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (-512 + (512 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-shl-nuw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {0,+,512} %index32 = shl nuw i32 %i, 9 %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -651,14 +1044,30 @@ exit: ; scalar evolution represents A - B as A + (-B) and -B can wrap even ; in cases where A - B does not. define void @test-sub-no-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { -; CHECK-LABEL: @test-sub-no-nsw +; CHECK-LABEL: 'test-sub-no-nsw' +; CHECK-NEXT: Classifying expressions for: @test-sub-no-nsw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = sub nsw i32 %i, %sub +; CHECK-NEXT: --> {((-1 * %sub) + %start),+,1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * %sub) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {((sext i32 %start to i64) + (-1 * (sext i32 %sub to i64))),+,1}<%loop> U: [-4294967295,8589934591) S: [-4294967295,8589934591) Exits: ((zext i32 (-1 + (-1 * %start) + %numIterations) to i64) + (sext i32 %start to i64) + (-1 * (sext i32 %sub to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((4 * (sext i32 %start to i64)) + (-4 * (sext i32 %sub to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64)) + (4 * (sext i32 %start to i64)) + (-4 * (sext i32 %sub to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-sub-no-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {((-1 * %sub) + %start),+,1} %index32 = sub nsw i32 %i, %sub %index64 = sext i32 %index32 to i64 @@ -674,15 +1083,33 @@ exit: ; Example where a sub should get the nsw flag as the RHS cannot be the ; minimal signed value. define void @test-sub-nsw(float* %input, i32 %start, i32 %sub, i32 %numIterations) { -; CHECK-LABEL: @test-sub-nsw +; CHECK-LABEL: 'test-sub-nsw' +; CHECK-NEXT: Classifying expressions for: @test-sub-nsw +; CHECK-NEXT: %halfsub = ashr i32 %sub, 1 +; CHECK-NEXT: --> %halfsub U: [-1073741824,1073741824) S: [-1073741824,1073741824) +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] +; CHECK-NEXT: --> {%start,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = sub nsw i32 %i, %halfsub +; CHECK-NEXT: --> {((-1 * %halfsub) + %start),+,1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * %halfsub) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {((sext i32 %start to i64) + (-1 * (sext i32 %halfsub to i64))),+,1}<%loop> U: [-3221225471,7516192767) S: [-3221225471,7516192767) Exits: ((zext i32 (-1 + (-1 * %start) + %numIterations) to i64) + (sext i32 %start to i64) + (-1 * (sext i32 %halfsub to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((4 * (sext i32 %start to i64)) + (-4 * (sext i32 %halfsub to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + (-1 * %start) + %numIterations) to i64)) + (4 * (sext i32 %start to i64)) + (-4 * (sext i32 %halfsub to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {(1 + %start),+,1}<%loop> U: full-set S: full-set Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-sub-nsw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %start) + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: %halfsub = ashr i32 %sub, 1 br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ %start, %entry ] -; CHECK: %index32 = -; CHECK: --> {((-1 * %halfsub) + %start),+,1} %index32 = sub nsw i32 %i, %halfsub %index64 = sext i32 %index32 to i64 @@ -698,18 +1125,32 @@ exit: ; Example where a sub should get the nsw flag, since the LHS is non-negative, ; which implies that the RHS cannot be the minimal signed value. define void @test-sub-nsw-lhs-non-negative(float* %input, i32 %sub, i32 %numIterations) { -; CHECK-LABEL: @test-sub-nsw-lhs-non-negative +; CHECK-LABEL: 'test-sub-nsw-lhs-non-negative' +; CHECK-NEXT: Classifying expressions for: @test-sub-nsw-lhs-non-negative +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = sub nsw i32 %i, %sub +; CHECK-NEXT: --> {(-1 * %sub),+,1}<%loop> U: full-set S: full-set Exits: (-1 + (-1 * %sub) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index64 = sext i32 %index32 to i64 +; CHECK-NEXT: --> {(-1 * (sext i32 %sub to i64)),+,1}<%loop> U: [-2147483647,6442450944) S: [-2147483647,6442450944) Exits: ((zext i32 (-1 + %numIterations) to i64) + (-1 * (sext i32 %sub to i64))) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((-4 * (sext i32 %sub to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: ((4 * (zext i32 (-1 + %numIterations) to i64)) + (-4 * (sext i32 %sub to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-sub-nsw-lhs-non-negative +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] -; CHECK: %index32 = -; CHECK: --> {(-1 * %sub),+,1} %index32 = sub nsw i32 %i, %sub -; CHECK: %index64 = -; CHECK: --> {(-1 * (sext i32 %sub to i64)),+,1} {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %val = extractvalue { i32, i1 } %ssub, 0 +; CHECK-NEXT: --> {(-1 * %sub),+,1}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ovfl = extractvalue { i32, i1 } %ssub, 1 +; CHECK-NEXT: --> %ovfl U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Variant } +; CHECK-NEXT: %index64 = sext i32 %val to i64 +; CHECK-NEXT: --> {(-1 * (sext i32 %sub to i64)),+,1}<%loop> U: [-2147483647,6442450944) S: [-2147483647,6442450944) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i64 %index64 +; CHECK-NEXT: --> {((-4 * (sext i32 %sub to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: <> LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-sext-sub +; CHECK-NEXT: Loop %loop: Unpredictable backedge-taken count. +; CHECK-NEXT: exit count for loop: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: exit count for cont: (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Unpredictable predicated backedge-taken count. +; entry: br label %loop loop: %i = phi i32 [ %nexti, %cont ], [ 0, %entry ] -; CHECK: %val = extractvalue { i32, i1 } %ssub, 0 -; CHECK: --> {(-1 * %sub),+,1} %ssub = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %i, i32 %sub) %val = extractvalue { i32, i1 } %ssub, 0 %ovfl = extractvalue { i32, i1 } %ssub, 1 @@ -742,8 +1201,6 @@ trap: unreachable cont: -; CHECK: %index64 = -; CHECK: --> {(-1 * (sext i32 %sub to i64)),+,1} {(2 + (-1 * %offset)),+,1}<%loop> U: full-set S: full-set Exits: (1 + (-1 * %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %j = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = sub nsw i32 %j, %offset +; CHECK-NEXT: --> {(1 + (-1 * %offset)),+,1}<%loop> U: [-2147483647,-2147483648) S: [-2147483647,-2147483648) Exits: ((-1 * %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {(4 + (4 * (sext i32 (-1 * %offset) to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: (4 + (4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 (-1 * %offset) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-sub-with-add +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop2: -; CHECK: %seq = -; CHECK: --> {(2 + (-1 * %offset)),+,1} %seq = add nsw nuw i32 %index32, 1 %exitcond = icmp eq i32 %nexti, %numIterations br i1 %exitcond, label %exit, label %loop @@ -774,8 +1249,6 @@ loop: %i = phi i32 [ %nexti, %loop2 ], [ 0, %entry ] %j = add nsw i32 %i, 1 -; CHECK: %index32 = -; CHECK: --> {(1 + (-1 * %offset)),+,1} %index32 = sub nsw i32 %j, %offset %ptr = getelementptr inbounds float, float* %input, i32 %index32 @@ -791,8 +1264,35 @@ exit: ; maps to is NSW, but the negation of the RHS does not since that ; recurrence could be the most negative representable value. define void @subrecurrences(i32 %outer_l, i32 %inner_l, i32 %val) { -; CHECK-LABEL: @subrecurrences - entry: +; CHECK-LABEL: 'subrecurrences' +; CHECK-NEXT: Classifying expressions for: @subrecurrences +; CHECK-NEXT: %o_idx = phi i32 [ 0, %entry ], [ %o_idx.inc, %outer.be ] +; CHECK-NEXT: --> {0,+,1}<%outer> U: [0,-2147483648) S: [0,-2147483648) Exits: %outer_l LoopDispositions: { %outer: Computable, %inner: Invariant } +; CHECK-NEXT: %o_idx.inc = add nsw i32 %o_idx, 1 +; CHECK-NEXT: --> {1,+,1}<%outer> U: [1,0) S: [1,0) Exits: (1 + %outer_l) LoopDispositions: { %outer: Computable, %inner: Invariant } +; CHECK-NEXT: %i_idx = phi i32 [ 0, %outer ], [ %i_idx.inc, %inner ] +; CHECK-NEXT: --> {0,+,1}<%inner> U: [0,-2147483648) S: [0,-2147483648) Exits: %inner_l LoopDispositions: { %inner: Computable, %outer: Variant } +; CHECK-NEXT: %i_idx.inc = add nsw i32 %i_idx, 1 +; CHECK-NEXT: --> {1,+,1}<%inner> U: [1,0) S: [1,0) Exits: (1 + %inner_l) LoopDispositions: { %inner: Computable, %outer: Variant } +; CHECK-NEXT: %v = sub nsw i32 %i_idx, %o_idx.inc +; CHECK-NEXT: --> +; NOTE: Line deleted from autogen output due to format confusing regex matcher +; CHECK-NEXT: %forub = udiv i32 1, %v +; CHECK-NEXT: --> +; NOTE: Line deleted from autogen output due to format confusing regex matcher +; CHECK-NEXT: Determining loop execution counts for: @subrecurrences +; CHECK-NEXT: Loop %inner: backedge-taken count is %inner_l +; CHECK-NEXT: Loop %inner: max backedge-taken count is -1 +; CHECK-NEXT: Loop %inner: Predicated backedge-taken count is %inner_l +; CHECK-NEXT: Predicates: +; CHECK: Loop %inner: Trip multiple is 1 +; CHECK-NEXT: Loop %outer: backedge-taken count is %outer_l +; CHECK-NEXT: Loop %outer: max backedge-taken count is -1 +; CHECK-NEXT: Loop %outer: Predicated backedge-taken count is %outer_l +; CHECK-NEXT: Predicates: +; CHECK: Loop %outer: Trip multiple is 1 +; +entry: br label %outer outer: @@ -804,8 +1304,6 @@ outer: inner: %i_idx = phi i32 [ 0, %outer ], [ %i_idx.inc, %inner ] %i_idx.inc = add nsw i32 %i_idx, 1 -; CHECK: %v = -; CHECK-NEXT: --> {{[{][{]}}-1,+,-1}<%outer>,+,1}<%inner> %v = sub nsw i32 %i_idx, %o_idx.inc %forub = udiv i32 1, %v %cond2 = icmp eq i32 %i_idx, %inner_l @@ -827,14 +1325,51 @@ exit: declare { i32, i1 } @llvm.ssub.with.overflow.i32(i32, i32) declare void @llvm.trap() define i32 @pr28932() { +; CHECK-LABEL: 'pr28932' +; CHECK-NEXT: Classifying expressions for: @pr28932 +; CHECK-NEXT: %pre = load %struct.anon*, %struct.anon** @a, align 8 +; CHECK-NEXT: --> %pre U: full-set S: full-set +; CHECK-NEXT: %pre7 = load i32, i32* @b, align 4 +; CHECK-NEXT: --> %pre7 U: full-set S: full-set +; CHECK-NEXT: %0 = phi i32 [ %3, %cont6 ], [ %pre7, %entry ] +; CHECK-NEXT: --> {%pre7,+,-1}<%for.cond> U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Computable } +; CHECK-NEXT: %1 = phi %struct.anon* [ %ph, %cont6 ], [ %pre, %entry ] +; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %3 = extractvalue { i32, i1 } %2, 0 +; CHECK-NEXT: --> {(-1 + %pre7),+,-1}<%for.cond> U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Computable } +; CHECK-NEXT: %4 = extractvalue { i32, i1 } %2, 1 +; CHECK-NEXT: --> %4 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %idxprom = sext i32 %3 to i64 +; CHECK-NEXT: --> (sext i32 {(-1 + %pre7),+,-1}<%for.cond> to i64) U: [-2147483648,2147483648) S: [-2147483648,2147483648) Exits: <> LoopDispositions: { %for.cond: Computable } +; CHECK-NEXT: %5 = getelementptr inbounds %struct.anon, %struct.anon* %1, i64 0, i32 0 +; CHECK-NEXT: --> %1 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %6 = load i8*, i8** %5, align 8 +; CHECK-NEXT: --> %6 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %7 = getelementptr inbounds i8, i8* %6, i64 %idxprom +; CHECK-NEXT: --> ((sext i32 {(-1 + %pre7),+,-1}<%for.cond> to i64) + %6) U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %8 = load i8, i8* %7, align 1 +; CHECK-NEXT: --> %8 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %conv5 = sext i8 %8 to i64 +; CHECK-NEXT: --> (sext i8 %8 to i64) U: [-128,128) S: [-128,128) Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %9 = inttoptr i64 %conv5 to %struct.anon* +; CHECK-NEXT: --> %9 U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: %ph = phi %struct.anon* [ %9, %cont1 ], [ %1, %if.then ] +; CHECK-NEXT: --> %ph U: full-set S: full-set Exits: <> LoopDispositions: { %for.cond: Variant } +; CHECK-NEXT: Determining loop execution counts for: @pr28932 +; CHECK-NEXT: Loop %for.cond: Unpredictable backedge-taken count. +; CHECK-NEXT: exit count for if.then: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: exit count for if.else: ***COULDNOTCOMPUTE*** +; CHECK-NEXT: Loop %for.cond: Unpredictable max backedge-taken count. +; CHECK-NEXT: Loop %for.cond: Unpredictable predicated backedge-taken count. +; entry: - %.pre = load %struct.anon*, %struct.anon** @a, align 8 - %.pre7 = load i32, i32* @b, align 4 + %pre = load %struct.anon*, %struct.anon** @a, align 8 + %pre7 = load i32, i32* @b, align 4 br label %for.cond for.cond: ; preds = %cont6, %entry - %0 = phi i32 [ %3, %cont6 ], [ %.pre7, %entry ] - %1 = phi %struct.anon* [ %.ph, %cont6 ], [ %.pre, %entry ] + %0 = phi i32 [ %3, %cont6 ], [ %pre7, %entry ] + %1 = phi %struct.anon* [ %ph, %cont6 ], [ %pre, %entry ] %tobool = icmp eq %struct.anon* %1, null %2 = tail call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 %0, i32 1) %3 = extractvalue { i32, i1 } %2, 0 @@ -863,7 +1398,7 @@ cont1: ; preds = %if.else br label %cont6 cont6: ; preds = %cont1, %if.then - %.ph = phi %struct.anon* [ %9, %cont1 ], [ %1, %if.then ] + %ph = phi %struct.anon* [ %9, %cont1 ], [ %1, %if.then ] store i32 %3, i32* @b, align 4 br label %for.cond } diff --git a/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll b/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll index 0237f554ff6f..a796d84598fd 100644 --- a/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw-offset-assume.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py ; RUN: opt < %s -S -disable-output "-passes=print" 2>&1 | FileCheck %s ; ScalarEvolution should be able to fold away the sign-extensions @@ -7,7 +8,48 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +; Note: Without the preheader assume, there is an 'smax' in the +; backedge-taken count expression: define void @foo(i32 %no, double* nocapture %d, double* nocapture %q) nounwind { +; CHECK-LABEL: 'foo' +; CHECK-NEXT: Classifying expressions for: @foo +; CHECK-NEXT: %n = and i32 %no, -2 +; CHECK-NEXT: --> (2 * (%no /u 2)) U: [0,-1) S: [-2147483648,2147483647) +; CHECK-NEXT: %i.01 = phi i32 [ %16, %bb1 ], [ 0, %bb.nph ] +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((-1 + (2 * (%no /u 2))) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %1 = sext i32 %i.01 to i64 +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %2 = getelementptr inbounds double, double* %d, i64 %1 +; CHECK-NEXT: --> {%d,+,16}<%bb> U: full-set S: full-set Exits: ((16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %d) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %4 = sext i32 %i.01 to i64 +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %5 = getelementptr inbounds double, double* %q, i64 %4 +; CHECK-NEXT: --> {%q,+,16}<%bb> U: full-set S: full-set Exits: ((16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %q) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %7 = or i32 %i.01, 1 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((-1 + (2 * (%no /u 2))) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %8 = sext i32 %7 to i64 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %9 = getelementptr inbounds double, double* %q, i64 %8 +; CHECK-NEXT: --> {(8 + %q),+,16}<%bb> U: [8,0) S: [8,0) Exits: (8 + (16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %q) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %t7 = add nsw i32 %i.01, 1 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((-1 + (2 * (%no /u 2))) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %t8 = sext i32 %t7 to i64 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %t9 = getelementptr inbounds double, double* %q, i64 %t8 +; CHECK-NEXT: --> {(8 + %q),+,16}<%bb> U: [8,0) S: [8,0) Exits: (8 + (16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %q) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %14 = sext i32 %i.01 to i64 +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %15 = getelementptr inbounds double, double* %d, i64 %14 +; CHECK-NEXT: --> {%d,+,16}<%bb> U: full-set S: full-set Exits: ((16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %d) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %16 = add nsw i32 %i.01, 2 +; CHECK-NEXT: --> {2,+,2}<%bb> U: [2,2147483647) S: [2,2147483647) Exits: (2 + (2 * ((-1 + (2 * (%no /u 2))) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: Determining loop execution counts for: @foo +; CHECK-NEXT: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) +; CHECK-NEXT: Loop %bb: max backedge-taken count is 1073741822 +; CHECK-NEXT: Loop %bb: Predicated backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) +; CHECK-NEXT: Predicates: +; CHECK: Loop %bb: Trip multiple is 1 +; entry: %n = and i32 %no, 4294967294 %0 = icmp sgt i32 %n, 0 ; [#uses=1] @@ -20,12 +62,8 @@ bb.nph: ; preds = %entry bb: ; preds = %bb.nph, %bb1 %i.01 = phi i32 [ %16, %bb1 ], [ 0, %bb.nph ] ; [#uses=5] -; CHECK: %1 = sext i32 %i.01 to i64 -; CHECK: --> {0,+,2}<%bb> %1 = sext i32 %i.01 to i64 ; [#uses=1] -; CHECK: %2 = getelementptr inbounds double, double* %d, i64 %1 -; CHECK: --> {%d,+,16}<%bb> %2 = getelementptr inbounds double, double* %d, i64 %1 ; [#uses=1] %3 = load double, double* %2, align 8 ; [#uses=1] @@ -34,24 +72,16 @@ bb: ; preds = %bb.nph, %bb1 %6 = load double, double* %5, align 8 ; [#uses=1] %7 = or i32 %i.01, 1 ; [#uses=1] -; CHECK: %8 = sext i32 %7 to i64 -; CHECK: --> {1,+,2}<%bb> %8 = sext i32 %7 to i64 ; [#uses=1] -; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8 -; CHECK: {(8 + %q),+,16}<%bb> %9 = getelementptr inbounds double, double* %q, i64 %8 ; [#uses=1] ; Artificially repeat the above three instructions, this time using ; add nsw instead of or. %t7 = add nsw i32 %i.01, 1 ; [#uses=1] -; CHECK: %t8 = sext i32 %t7 to i64 -; CHECK: --> {1,+,2}<%bb> %t8 = sext i32 %t7 to i64 ; [#uses=1] -; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8 -; CHECK: {(8 + %q),+,16}<%bb> %t9 = getelementptr inbounds double, double* %q, i64 %t8 ; [#uses=1] %10 = load double, double* %9, align 8 ; [#uses=1] @@ -76,8 +106,3 @@ return: ; preds = %bb1.return_crit_edg } 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: 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 02a9aa8f03d6..3e39fc9c34ac 100644 --- a/llvm/test/Analysis/ScalarEvolution/nsw-offset.ll +++ b/llvm/test/Analysis/ScalarEvolution/nsw-offset.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py ; RUN: opt < %s -S -disable-output "-passes=print" 2>&1 | FileCheck %s ; ScalarEvolution should be able to fold away the sign-extensions @@ -7,6 +8,45 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" define void @foo(i32 %no, double* nocapture %d, double* nocapture %q) nounwind { +; CHECK-LABEL: 'foo' +; CHECK-NEXT: Classifying expressions for: @foo +; CHECK-NEXT: %n = and i32 %no, -2 +; CHECK-NEXT: --> (2 * (%no /u 2)) U: [0,-1) S: [-2147483648,2147483647) +; CHECK-NEXT: %i.01 = phi i32 [ %16, %bb1 ], [ 0, %bb.nph ] +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((-1 + (2 * (%no /u 2))) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %1 = sext i32 %i.01 to i64 +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %2 = getelementptr inbounds double, double* %d, i64 %1 +; CHECK-NEXT: --> {%d,+,16}<%bb> U: full-set S: full-set Exits: ((16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %d) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %4 = sext i32 %i.01 to i64 +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %5 = getelementptr inbounds double, double* %q, i64 %4 +; CHECK-NEXT: --> {%q,+,16}<%bb> U: full-set S: full-set Exits: ((16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %q) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %7 = or i32 %i.01, 1 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((-1 + (2 * (%no /u 2))) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %8 = sext i32 %7 to i64 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %9 = getelementptr inbounds double, double* %q, i64 %8 +; CHECK-NEXT: --> {(8 + %q),+,16}<%bb> U: [8,0) S: [8,0) Exits: (8 + (16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %q) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %t7 = add nsw i32 %i.01, 1 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((-1 + (2 * (%no /u 2))) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %t8 = sext i32 %t7 to i64 +; CHECK-NEXT: --> {1,+,2}<%bb> U: [1,2147483646) S: [1,2147483646) Exits: (1 + (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %t9 = getelementptr inbounds double, double* %q, i64 %t8 +; CHECK-NEXT: --> {(8 + %q),+,16}<%bb> U: [8,0) S: [8,0) Exits: (8 + (16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %q) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %14 = sext i32 %i.01 to i64 +; CHECK-NEXT: --> {0,+,2}<%bb> U: [0,2147483645) S: [0,2147483645) Exits: (2 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %15 = getelementptr inbounds double, double* %d, i64 %14 +; CHECK-NEXT: --> {%d,+,16}<%bb> U: full-set S: full-set Exits: ((16 * ((1 + (zext i32 (-2 + (2 * (%no /u 2))) to i64)) /u 2)) + %d) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: %16 = add nsw i32 %i.01, 2 +; CHECK-NEXT: --> {2,+,2}<%bb> U: [2,2147483647) S: [2,2147483647) Exits: (2 + (2 * ((-1 + (2 * (%no /u 2))) /u 2))) LoopDispositions: { %bb: Computable } +; CHECK-NEXT: Determining loop execution counts for: @foo +; CHECK-NEXT: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) +; CHECK-NEXT: Loop %bb: max backedge-taken count is 1073741822 +; CHECK-NEXT: Loop %bb: Predicated backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) +; CHECK-NEXT: Predicates: +; CHECK: Loop %bb: Trip multiple is 1 +; entry: %n = and i32 %no, 4294967294 %0 = icmp sgt i32 %n, 0 ; [#uses=1] @@ -18,12 +58,8 @@ bb.nph: ; preds = %entry bb: ; preds = %bb.nph, %bb1 %i.01 = phi i32 [ %16, %bb1 ], [ 0, %bb.nph ] ; [#uses=5] -; CHECK: %1 = sext i32 %i.01 to i64 -; CHECK: --> {0,+,2}<%bb> %1 = sext i32 %i.01 to i64 ; [#uses=1] -; CHECK: %2 = getelementptr inbounds double, double* %d, i64 %1 -; CHECK: --> {%d,+,16}<%bb> %2 = getelementptr inbounds double, double* %d, i64 %1 ; [#uses=1] %3 = load double, double* %2, align 8 ; [#uses=1] @@ -32,24 +68,16 @@ bb: ; preds = %bb.nph, %bb1 %6 = load double, double* %5, align 8 ; [#uses=1] %7 = or i32 %i.01, 1 ; [#uses=1] -; CHECK: %8 = sext i32 %7 to i64 -; CHECK: --> {1,+,2}<%bb> %8 = sext i32 %7 to i64 ; [#uses=1] -; CHECK: %9 = getelementptr inbounds double, double* %q, i64 %8 -; CHECK: {(8 + %q),+,16}<%bb> %9 = getelementptr inbounds double, double* %q, i64 %8 ; [#uses=1] ; Artificially repeat the above three instructions, this time using ; add nsw instead of or. %t7 = add nsw i32 %i.01, 1 ; [#uses=1] -; CHECK: %t8 = sext i32 %t7 to i64 -; CHECK: --> {1,+,2}<%bb> %t8 = sext i32 %t7 to i64 ; [#uses=1] -; CHECK: %t9 = getelementptr inbounds double, double* %q, i64 %t8 -; CHECK: {(8 + %q),+,16}<%bb> %t9 = getelementptr inbounds double, double* %q, i64 %t8 ; [#uses=1] %10 = load double, double* %9, align 8 ; [#uses=1] @@ -72,6 +100,3 @@ bb1.return_crit_edge: ; preds = %bb1 return: ; preds = %bb1.return_crit_edge, %entry ret void } - -; CHECK: Loop %bb: backedge-taken count is ((-1 + (2 * (%no /u 2))) /u 2) -; CHECK: Loop %bb: max backedge-taken count is 1073741822 diff --git a/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll b/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll index 31a3487eea3e..6859a338efd9 100644 --- a/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll +++ b/llvm/test/Analysis/ScalarEvolution/range_nw_flag.ll @@ -1,9 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py ; RUN: opt < %s -S -disable-output "-passes=print" 2>&1 | FileCheck %s ; copied from flags-from-poison.ll -; CHECK-LABEL: @test-add-nuw -; CHECK: --> {(1 + %offset),+,1}<%loop> U: [1,0) S: [1,0) define void @test-add-nuw(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: 'test-add-nuw' +; CHECK-NEXT: Classifying expressions for: @test-add-nuw +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nuw i32 %nexti, %offset +; CHECK-NEXT: --> {(1 + %offset),+,1}<%loop> U: [1,0) S: [1,0) Exits: (%offset + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {(1 + %offset),+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 (%offset + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-add-nuw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: br label %loop loop: @@ -19,9 +35,26 @@ exit: ret void } -; CHECK-LABEL: @test-addrec-nuw -; CHECK: --> {(1 + (10 smax %offset)),+,1}<%loop> U: [11,0) S: [11,0) define void @test-addrec-nuw(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: 'test-addrec-nuw' +; CHECK-NEXT: Classifying expressions for: @test-addrec-nuw +; CHECK-NEXT: %min.10 = select i1 %cmp, i32 %offset, i32 10 +; CHECK-NEXT: --> (10 smax %offset) U: [10,-2147483648) S: [10,-2147483648) +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: full-set S: full-set Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nuw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,0) S: [1,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nuw i32 %nexti, %min.10 +; CHECK-NEXT: --> {(1 + (10 smax %offset)),+,1}<%loop> U: [11,0) S: [11,0) Exits: ((10 smax %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> ((4 * (sext i32 {(1 + (10 smax %offset)),+,1}<%loop> to i64)) + %input) U: full-set S: full-set Exits: ((4 * (sext i32 ((10 smax %offset) + %numIterations) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-addrec-nuw +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: %cmp = icmp sgt i32 %offset, 10 %min.10 = select i1 %cmp, i32 %offset, i32 10 @@ -39,9 +72,26 @@ exit: ret void } -; CHECK-LABEL: @test-addrec-nsw-start-neg-strip-neg -; CHECK: --> {(-1 + (-10 smin %offset)),+,-1}<%loop> U: [-2147483648,-10) S: [-2147483648,-10) define void @test-addrec-nsw-start-neg-strip-neg(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: 'test-addrec-nsw-start-neg-strip-neg' +; CHECK-NEXT: Classifying expressions for: @test-addrec-nsw-start-neg-strip-neg +; CHECK-NEXT: %max = select i1 %cmp, i32 %offset, i32 -10 +; CHECK-NEXT: --> (-10 smin %offset) U: [-2147483648,-9) S: [-2147483648,-9) +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,-1}<%loop> U: [-2147483648,1) S: [-2147483648,1) Exits: (1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, -1 +; CHECK-NEXT: --> {-1,+,-1}<%loop> U: [-2147483648,0) S: [-2147483648,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %nexti, %max +; CHECK-NEXT: --> {(-1 + (-10 smin %offset)),+,-1}<%loop> U: [-2147483648,-10) S: [-2147483648,-10) Exits: ((-10 smin %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {(-4 + (4 * (sext i32 (-10 smin %offset) to i64)) + %input),+,-4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * (sext i32 (-10 smin %offset) to i64)) + (-4 * (zext i32 (-1 + (-1 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-addrec-nsw-start-neg-strip-neg +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %numIterations)) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %numIterations)) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: %cmp = icmp slt i32 %offset, -10 %max = select i1 %cmp, i32 %offset, i32 -10 @@ -59,9 +109,26 @@ exit: ret void } -; CHECK-LABEL: @test-addrec-nsw-start-pos-strip-neg -; CHECK: --> {(-1 + (10 smin %offset)),+,-1}<%loop> U: [-2147483648,10) S: [-2147483648,10) define void @test-addrec-nsw-start-pos-strip-neg(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: 'test-addrec-nsw-start-pos-strip-neg' +; CHECK-NEXT: Classifying expressions for: @test-addrec-nsw-start-pos-strip-neg +; CHECK-NEXT: %max = select i1 %cmp, i32 %offset, i32 10 +; CHECK-NEXT: --> (10 smin %offset) U: [-2147483648,11) S: [-2147483648,11) +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,-1}<%loop> U: [-2147483648,1) S: [-2147483648,1) Exits: (1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, -1 +; CHECK-NEXT: --> {-1,+,-1}<%loop> U: [-2147483648,0) S: [-2147483648,0) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %nexti, %max +; CHECK-NEXT: --> {(-1 + (10 smin %offset)),+,-1}<%loop> U: [-2147483648,10) S: [-2147483648,10) Exits: ((10 smin %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {(-4 + (4 * (sext i32 (10 smin %offset) to i64)) + %input),+,-4}<%loop> U: full-set S: full-set Exits: (-4 + (4 * (sext i32 (10 smin %offset) to i64)) + (-4 * (zext i32 (-1 + (-1 * %numIterations)) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-addrec-nsw-start-pos-strip-neg +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + (-1 * %numIterations)) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + (-1 * %numIterations)) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: %cmp = icmp slt i32 %offset, 10 %max = select i1 %cmp, i32 %offset, i32 10 @@ -79,9 +146,26 @@ exit: ret void } -; CHECK-LABEL: @test-addrec-nsw-start-pos-strip-pos -; CHECK: --> {(1 + (10 smax %offset)),+,1}<%loop> U: [11,-2147483648) S: [11,-2147483648) define void @test-addrec-nsw-start-pos-strip-pos(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: 'test-addrec-nsw-start-pos-strip-pos' +; CHECK-NEXT: Classifying expressions for: @test-addrec-nsw-start-pos-strip-pos +; CHECK-NEXT: %min = select i1 %cmp, i32 %offset, i32 10 +; CHECK-NEXT: --> (10 smax %offset) U: [10,-2147483648) S: [10,-2147483648) +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %nexti, %min +; CHECK-NEXT: --> {(1 + (10 smax %offset)),+,1}<%loop> U: [11,-2147483648) S: [11,-2147483648) Exits: ((10 smax %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {(4 + (4 * (zext i32 (10 smax %offset) to i64)) + %input),+,4}<%loop> U: [44,0) S: [44,0) Exits: (4 + (4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (zext i32 (10 smax %offset) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-addrec-nsw-start-pos-strip-pos +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: %cmp = icmp sgt i32 %offset, 10 %min = select i1 %cmp, i32 %offset, i32 10 @@ -99,9 +183,26 @@ exit: ret void } -; CHECK-LABEL: @test-addrec-nsw-start-neg-strip-pos -; CHECK: --> {(1 + (-10 smax %offset)),+,1}<%loop> U: [-9,-2147483648) S: [-9,-2147483648) define void @test-addrec-nsw-start-neg-strip-pos(float* %input, i32 %offset, i32 %numIterations) { +; CHECK-LABEL: 'test-addrec-nsw-start-neg-strip-pos' +; CHECK-NEXT: Classifying expressions for: @test-addrec-nsw-start-neg-strip-pos +; CHECK-NEXT: %min = select i1 %cmp, i32 %offset, i32 -10 +; CHECK-NEXT: --> (-10 smax %offset) U: [-10,-2147483648) S: [-10,-2147483648) +; CHECK-NEXT: %i = phi i32 [ %nexti, %loop ], [ 0, %entry ] +; CHECK-NEXT: --> {0,+,1}<%loop> U: [0,-2147483648) S: [0,-2147483648) Exits: (-1 + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %nexti = add nsw i32 %i, 1 +; CHECK-NEXT: --> {1,+,1}<%loop> U: [1,-2147483648) S: [1,-2147483648) Exits: %numIterations LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %index32 = add nsw i32 %nexti, %min +; CHECK-NEXT: --> {(1 + (-10 smax %offset)),+,1}<%loop> U: [-9,-2147483648) S: [-9,-2147483648) Exits: ((-10 smax %offset) + %numIterations) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: %ptr = getelementptr inbounds float, float* %input, i32 %index32 +; CHECK-NEXT: --> {(4 + (4 * (sext i32 (-10 smax %offset) to i64)) + %input),+,4}<%loop> U: full-set S: full-set Exits: (4 + (4 * (zext i32 (-1 + %numIterations) to i64)) + (4 * (sext i32 (-10 smax %offset) to i64)) + %input) LoopDispositions: { %loop: Computable } +; CHECK-NEXT: Determining loop execution counts for: @test-addrec-nsw-start-neg-strip-pos +; CHECK-NEXT: Loop %loop: backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Loop %loop: max backedge-taken count is -1 +; CHECK-NEXT: Loop %loop: Predicated backedge-taken count is (-1 + %numIterations) +; CHECK-NEXT: Predicates: +; CHECK: Loop %loop: Trip multiple is 1 +; entry: %cmp = icmp sgt i32 %offset, -10 %min = select i1 %cmp, i32 %offset, i32 -10