Mercurial > hg > CbC > CbC_llvm
diff test/Transforms/IndVarSimplify/elim-extend.ll @ 0:95c75e76d11b LLVM3.4
LLVM 3.4
author | Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 12 Dec 2013 13:56:28 +0900 |
parents | |
children | afa8332a0e37 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/Transforms/IndVarSimplify/elim-extend.ll Thu Dec 12 13:56:28 2013 +0900 @@ -0,0 +1,153 @@ +; RUN: opt < %s -indvars -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" + +; IV with constant start, preinc and postinc sign extends, with and without NSW. +; IV rewrite only removes one sext. WidenIVs removes all three. +define void @postincConstIV(i8* %base, i32 %limit) nounwind { +entry: + br label %loop +; CHECK: loop: +; CHECK-NOT: sext +; CHECK: exit: +loop: + %iv = phi i32 [ %postiv, %loop ], [ 0, %entry ] + %ivnsw = phi i32 [ %postivnsw, %loop ], [ 0, %entry ] + %preofs = sext i32 %iv to i64 + %preadr = getelementptr i8* %base, i64 %preofs + store i8 0, i8* %preadr + %postiv = add i32 %iv, 1 + %postofs = sext i32 %postiv to i64 + %postadr = getelementptr i8* %base, i64 %postofs + store i8 0, i8* %postadr + %postivnsw = add nsw i32 %ivnsw, 1 + %postofsnsw = sext i32 %postivnsw to i64 + %postadrnsw = getelementptr i8* %base, i64 %postofsnsw + store i8 0, i8* %postadrnsw + %cond = icmp sgt i32 %limit, %iv + br i1 %cond, label %loop, label %exit +exit: + br label %return +return: + ret void +} + +; IV with nonconstant start, preinc and postinc sign extends, +; with and without NSW. +; As with postincConstIV, WidenIVs removes all three sexts. +define void @postincVarIV(i8* %base, i32 %init, i32 %limit) nounwind { +entry: + %precond = icmp sgt i32 %limit, %init + br i1 %precond, label %loop, label %return +; CHECK: loop: +; CHECK-NOT: sext +; CHECK: exit: +loop: + %iv = phi i32 [ %postiv, %loop ], [ %init, %entry ] + %ivnsw = phi i32 [ %postivnsw, %loop ], [ %init, %entry ] + %preofs = sext i32 %iv to i64 + %preadr = getelementptr i8* %base, i64 %preofs + store i8 0, i8* %preadr + %postiv = add i32 %iv, 1 + %postofs = sext i32 %postiv to i64 + %postadr = getelementptr i8* %base, i64 %postofs + store i8 0, i8* %postadr + %postivnsw = add nsw i32 %ivnsw, 1 + %postofsnsw = sext i32 %postivnsw to i64 + %postadrnsw = getelementptr i8* %base, i64 %postofsnsw + store i8 0, i8* %postadrnsw + %cond = icmp sgt i32 %limit, %postiv + br i1 %cond, label %loop, label %exit +exit: + br label %return +return: + ret void +} + +; Test 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. +; Eliminate %ofs3 after normalizing sext(innerpostiv) +; CHECK-NOT: sext +; CHECK: getelementptr +; +; FIXME: We should check that indvars does not increase the number of +; IVs in this loop. sext elimination plus LFTR currently results in 2 final +; IVs. Waiting to remove LFTR. +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* %adr4 + + %ofs5 = sext i32 %innercount.merge to i64 + %adr5 = getelementptr i8* %address, i64 %ofs5 + store i8 0, i8* %adr5 + + %outerpostcount = add i32 %outercount, 1 + %tmp47 = icmp slt i32 %outerpostcount, %limit + br i1 %tmp47, label %outerloop, label %return + +return: + ret void +}