summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/Transforms/IndVarSimplify/post-inc-range.ll175
1 files changed, 175 insertions, 0 deletions
diff --git a/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll b/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll
new file mode 100644
index 00000000000..717f0611a74
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/post-inc-range.ll
@@ -0,0 +1,175 @@
+; RUN: opt < %s -indvars -indvars-post-increment-ranges -S | FileCheck %s
+
+target datalayout = "p:64:64:64-n32:64"
+
+; When the IV in this loop is widened we want to widen this use as well:
+; icmp slt i32 %i.inc, %limit
+; In order to do this indvars need to prove that the narrow IV def (%i.inc)
+; is not-negative from the range check inside of the loop.
+define void @test(i32* %base, i32 %limit, i32 %start) {
+; CHECK-LABEL: @test(
+; CHECK-NOT: trunc
+
+for.body.lr.ph:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
+ %within_limits = icmp ult i32 %i, 64
+ br i1 %within_limits, label %continue, label %for.end
+
+continue:
+ %i.i64 = zext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
+ %val = load i32, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %i.inc = add nsw nuw i32 %i, 1
+ %cmp = icmp slt i32 %i.inc, %limit
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ br label %exit
+
+exit:
+ ret void
+}
+
+define void @test_false_edge(i32* %base, i32 %limit, i32 %start) {
+; CHECK-LABEL: @test_false_edge(
+; CHECK-NOT: trunc
+
+for.body.lr.ph:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
+ %out_of_bounds = icmp ugt i32 %i, 64
+ br i1 %out_of_bounds, label %for.end, label %continue
+
+continue:
+ %i.i64 = zext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
+ %val = load i32, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %i.inc = add nsw nuw i32 %i, 1
+ %cmp = icmp slt i32 %i.inc, %limit
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ br label %exit
+
+exit:
+ ret void
+}
+
+define void @test_range_metadata(i32* %array_length_ptr, i32* %base,
+ i32 %limit, i32 %start) {
+; CHECK-LABEL: @test_range_metadata(
+; CHECK-NOT: trunc
+
+for.body.lr.ph:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
+ %array_length = load i32, i32* %array_length_ptr, !range !{i32 0, i32 64 }
+ %within_limits = icmp ult i32 %i, %array_length
+ br i1 %within_limits, label %continue, label %for.end
+
+continue:
+ %i.i64 = zext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
+ %val = load i32, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %i.inc = add nsw nuw i32 %i, 1
+ %cmp = icmp slt i32 %i.inc, %limit
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ br label %exit
+
+exit:
+ ret void
+}
+
+; Negative version of the test above, we don't know anything about
+; array_length_ptr range.
+define void @test_neg(i32* %array_length_ptr, i32* %base,
+ i32 %limit, i32 %start) {
+; CHECK-LABEL: @test_neg(
+; CHECK: trunc i64
+
+for.body.lr.ph:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
+ %array_length = load i32, i32* %array_length_ptr
+ %within_limits = icmp ult i32 %i, %array_length
+ br i1 %within_limits, label %continue, label %for.end
+
+continue:
+ %i.i64 = zext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
+ %val = load i32, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %i.inc = add nsw nuw i32 %i, 1
+ %cmp = icmp slt i32 %i.inc, %limit
+ br i1 %cmp, label %for.body, label %for.end
+
+for.end:
+ br label %exit
+
+exit:
+ ret void
+}
+
+define void @test_transitive_use(i32* %base, i32 %limit, i32 %start) {
+; CHECK-LABEL: @test_transitive_use(
+; CHECK-NOT: trunc
+; CHECK: %result = icmp slt i64
+
+for.body.lr.ph:
+ br label %for.body
+
+for.body:
+ %i = phi i32 [ %start, %for.body.lr.ph ], [ %i.inc, %for.inc ]
+ %within_limits = icmp ult i32 %i, 64
+ br i1 %within_limits, label %continue, label %for.end
+
+continue:
+ %i.mul.3 = mul nsw nuw i32 %i, 3
+ %mul_within = icmp ult i32 %i.mul.3, 64
+ br i1 %mul_within, label %guarded, label %continue.2
+
+guarded:
+ %i.mul.3.inc = add nsw nuw i32 %i.mul.3, 1
+ %result = icmp slt i32 %i.mul.3.inc, %limit
+ br i1 %result, label %continue.2, label %for.end
+
+continue.2:
+ %i.i64 = zext i32 %i to i64
+ %arrayidx = getelementptr inbounds i32, i32* %base, i64 %i.i64
+ %val = load i32, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %i.inc = add nsw nuw i32 %i, 1
+ %cmp = icmp slt i32 %i.inc, %limit
+ br i1 %cmp, label %for.body, label %for.end
+
+
+for.end:
+ br label %exit
+
+exit:
+ ret void
+}
OpenPOWER on IntegriCloud