summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorAndrew Trick <atrick@apple.com>2011-05-25 04:42:22 +0000
committerAndrew Trick <atrick@apple.com>2011-05-25 04:42:22 +0000
commiteb3c36e69c2cb93f443d556151fa8591dc1d2b66 (patch)
treea6be42826754299bc1e66a5531f97af0f85217fa /llvm/test/Transforms
parentb0c4f3917319dc1505de0496c788db38f44af0a6 (diff)
downloadbcm5719-llvm-eb3c36e69c2cb93f443d556151fa8591dc1d2b66.tar.gz
bcm5719-llvm-eb3c36e69c2cb93f443d556151fa8591dc1d2b66.zip
indvars: fixed IV cloning in -disable-iv-rewrite mode with associated
cleanup and overdue test cases. llvm-svn: 132038
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/IndVarSimplify/elim-extend.ll93
-rw-r--r--llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll123
2 files changed, 216 insertions, 0 deletions
diff --git a/llvm/test/Transforms/IndVarSimplify/elim-extend.ll b/llvm/test/Transforms/IndVarSimplify/elim-extend.ll
new file mode 100644
index 00000000000..b494a194136
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/elim-extend.ll
@@ -0,0 +1,93 @@
+; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+
+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-n8:16:32:64"
+
+; Tests sign extend elimination in the inner and outer loop.
+; %outercount is straightforward to widen, besides being in an outer loop.
+; %innercount is currently blocked by lcssa, so is not widened.
+; %inneriv can be widened only after proving it has no signed-overflow
+; based on the loop test.
+define void @nestedIV(i8* %address, i32 %limit) nounwind {
+entry:
+ %limitdec = add i32 %limit, -1
+ br label %outerloop
+
+; CHECK: outerloop:
+;
+; Eliminate %ofs1 after widening outercount.
+; CHECK-NOT: sext
+; CHECK: getelementptr
+;
+; IV rewriting hoists a gep into this block. We don't like that.
+; CHECK-NOT: getelementptr
+outerloop:
+ %outercount = phi i32 [ %outerpostcount, %outermerge ], [ 0, %entry ]
+ %innercount = phi i32 [ %innercount.merge, %outermerge ], [ 0, %entry ]
+
+ %outercountdec = add i32 %outercount, -1
+ %ofs1 = sext i32 %outercountdec to i64
+ %adr1 = getelementptr i8* %address, i64 %ofs1
+ store i8 0, i8* %adr1
+
+ br label %innerpreheader
+
+innerpreheader:
+ %innerprecmp = icmp sgt i32 %limitdec, %innercount
+ br i1 %innerprecmp, label %innerloop, label %outermerge
+
+; CHECK: innerloop:
+;
+; Eliminate %ofs2 after widening inneriv.
+; CHECK-NOT: sext
+; CHECK: getelementptr
+;
+; FIXME: We should not increase the number of IVs in this loop.
+; sext elimination plus LFTR results in 3 final IVs.
+;
+; FIXME: eliminate %ofs3 based the loop pre/post conditions
+; even though innerpostiv is not NSW, thus sign extending innerpostiv
+; does not yield the same expression as incrementing the widened inneriv.
+innerloop:
+ %inneriv = phi i32 [ %innerpostiv, %innerloop ], [ %innercount, %innerpreheader ]
+ %innerpostiv = add i32 %inneriv, 1
+
+ %ofs2 = sext i32 %inneriv to i64
+ %adr2 = getelementptr i8* %address, i64 %ofs2
+ store i8 0, i8* %adr2
+
+ %ofs3 = sext i32 %innerpostiv to i64
+ %adr3 = getelementptr i8* %address, i64 %ofs3
+ store i8 0, i8* %adr3
+
+ %innercmp = icmp sgt i32 %limitdec, %innerpostiv
+ br i1 %innercmp, label %innerloop, label %innerexit
+
+innerexit:
+ %innercount.lcssa = phi i32 [ %innerpostiv, %innerloop ]
+ br label %outermerge
+
+; CHECK: outermerge:
+;
+; Eliminate %ofs4 after widening outercount
+; CHECK-NOT: sext
+; CHECK: getelementptr
+;
+; TODO: Eliminate %ofs5 after removing lcssa
+outermerge:
+ %innercount.merge = phi i32 [ %innercount.lcssa, %innerexit ], [ %innercount, %innerpreheader ]
+
+ %ofs4 = sext i32 %outercount to i64
+ %adr4 = getelementptr i8* %address, i64 %ofs4
+ store i8 0, i8* %adr3
+
+ %ofs5 = sext i32 %innercount.merge to i64
+ %adr5 = getelementptr i8* %address, i64 %ofs5
+ store i8 0, i8* %adr4
+
+ %outerpostcount = add i32 %outercount, 1
+ %tmp47 = icmp slt i32 %outerpostcount, %limit
+ br i1 %tmp47, label %outerloop, label %return
+
+return:
+ ret void
+}
diff --git a/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll b/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
new file mode 100644
index 00000000000..c35feef26f9
--- /dev/null
+++ b/llvm/test/Transforms/IndVarSimplify/no-iv-rewrite.ll
@@ -0,0 +1,123 @@
+; RUN: opt < %s -indvars -disable-iv-rewrite -S | FileCheck %s
+;
+; Make sure that indvars isn't inserting canonical IVs.
+; This is kinda hard to do until linear function test replacement is removed.
+
+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-n8:16:32:64"
+
+define i32 @sum(i32* %arr, i32 %n) nounwind {
+entry:
+ %precond = icmp slt i32 0, %n
+ br i1 %precond, label %ph, label %return
+
+ph:
+ br label %loop
+
+; CHECK: loop:
+;
+; We should only have 2 IVs.
+; CHECK: phi
+; CHECK: phi
+; CHECK-NOT: phi
+;
+; sext should be eliminated while preserving gep inboundsness.
+; CHECK-NOT: sext
+; CHECK: getelementptr inbounds
+loop:
+ %i.02 = phi i32 [ 0, %ph ], [ %iinc, %loop ]
+ %s.01 = phi i32 [ 0, %ph ], [ %sinc, %loop ]
+ %ofs = sext i32 %i.02 to i64
+ %adr = getelementptr inbounds i32* %arr, i64 %ofs
+ %val = load i32* %adr
+ %sinc = add nsw i32 %s.01, %val
+ %iinc = add nsw i32 %i.02, 1
+ %cond = icmp slt i32 %iinc, %n
+ br i1 %cond, label %loop, label %exit
+
+exit:
+ %s.lcssa = phi i32 [ %sinc, %loop ]
+ br label %return
+
+return:
+ %s.0.lcssa = phi i32 [ %s.lcssa, %exit ], [ 0, %entry ]
+ ret i32 %s.0.lcssa
+}
+
+define i64 @suml(i32* %arr, i32 %n) nounwind {
+entry:
+ %precond = icmp slt i32 0, %n
+ br i1 %precond, label %ph, label %return
+
+ph:
+ br label %loop
+
+; CHECK: loop:
+;
+; We should only have 2 IVs.
+; CHECK: phi
+; CHECK: phi
+; CHECK-NOT: phi
+;
+; %ofs sext should be eliminated while preserving gep inboundsness.
+; CHECK-NOT: sext
+; CHECK: getelementptr inbounds
+; %vall sext should obviously not be eliminated
+; CHECK: sext
+loop:
+ %i.02 = phi i32 [ 0, %ph ], [ %iinc, %loop ]
+ %s.01 = phi i64 [ 0, %ph ], [ %sinc, %loop ]
+ %ofs = sext i32 %i.02 to i64
+ %adr = getelementptr inbounds i32* %arr, i64 %ofs
+ %val = load i32* %adr
+ %vall = sext i32 %val to i64
+ %sinc = add nsw i64 %s.01, %vall
+ %iinc = add nsw i32 %i.02, 1
+ %cond = icmp slt i32 %iinc, %n
+ br i1 %cond, label %loop, label %exit
+
+exit:
+ %s.lcssa = phi i64 [ %sinc, %loop ]
+ br label %return
+
+return:
+ %s.0.lcssa = phi i64 [ %s.lcssa, %exit ], [ 0, %entry ]
+ ret i64 %s.0.lcssa
+}
+
+define void @outofbounds(i32* %first, i32* %last, i32 %idx) nounwind {
+ %precond = icmp ne i32* %first, %last
+ br i1 %precond, label %ph, label %return
+
+; CHECK: ph:
+; It's not indvars' job to perform LICM on %ofs
+; CHECK-NOT: sext
+ph:
+ br label %loop
+
+; CHECK: loop:
+;
+; Preserve exactly one pointer type IV.
+; CHECK: phi i32*
+; CHECK-NOT: phi
+;
+; Don't create any extra adds.
+; CHECK-NOT: add
+;
+; Preserve gep inboundsness, and don't factor it.
+; CHECK: getelementptr inbounds i32* %ptriv, i32 1
+; CHECK-NOT: add
+loop:
+ %ptriv = phi i32* [ %first, %ph ], [ %ptrpost, %loop ]
+ %ofs = sext i32 %idx to i64
+ %adr = getelementptr inbounds i32* %ptriv, i64 %ofs
+ store i32 3, i32* %adr
+ %ptrpost = getelementptr inbounds i32* %ptriv, i32 1
+ %cond = icmp ne i32* %ptrpost, %last
+ br i1 %cond, label %loop, label %exit
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
OpenPOWER on IntegriCloud