Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / test / Transforms / IndVarSimplify / elim-extend.ll
blob6b6d597416599cf5d832efad4c748227452dac4f
1 ; RUN: opt < %s -indvars -S | FileCheck %s
3 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"
5 ; IV with constant start, preinc and postinc sign extends, with and without NSW.
6 ; IV rewrite only removes one sext. WidenIVs removes all three.
7 define void @postincConstIV(i8* %base, i32 %limit) nounwind {
8 entry:
9   br label %loop
10 ; CHECK: loop:
11 ; CHECK-NOT: sext
12 ; CHECK: exit:
13 loop:
14   %iv = phi i32 [ %postiv, %loop ], [ 0, %entry ]
15   %ivnsw = phi i32 [ %postivnsw, %loop ], [ 0, %entry ]
16   %preofs = sext i32 %iv to i64
17   %preadr = getelementptr i8, i8* %base, i64 %preofs
18   store i8 0, i8* %preadr
19   %postiv = add i32 %iv, 1
20   %postofs = sext i32 %postiv to i64
21   %postadr = getelementptr i8, i8* %base, i64 %postofs
22   store i8 0, i8* %postadr
23   %postivnsw = add nsw i32 %ivnsw, 1
24   %postofsnsw = sext i32 %postivnsw to i64
25   %postadrnsw = getelementptr inbounds i8, i8* %base, i64 %postofsnsw
26   store i8 0, i8* %postadrnsw
27   %cond = icmp sgt i32 %limit, %iv
28   br i1 %cond, label %loop, label %exit
29 exit:
30   br label %return
31 return:
32   ret void
35 ; IV with nonconstant start, preinc and postinc sign extends,
36 ; with and without NSW.
37 ; As with postincConstIV, WidenIVs removes all three sexts.
38 define void @postincVarIV(i8* %base, i32 %init, i32 %limit) nounwind {
39 entry:
40   %precond = icmp sgt i32 %limit, %init
41   br i1 %precond, label %loop, label %return
42 ; CHECK: loop:
43 ; CHECK-NOT: sext
44 ; CHECK: wide.trip.count = sext
45 ; CHECK-NOT: sext
46 ; CHECK: exit:
47 loop:
48   %iv = phi i32 [ %postiv, %loop ], [ %init, %entry ]
49   %ivnsw = phi i32 [ %postivnsw, %loop ], [ %init, %entry ]
50   %preofs = sext i32 %iv to i64
51   %preadr = getelementptr i8, i8* %base, i64 %preofs
52   store i8 0, i8* %preadr
53   %postiv = add i32 %iv, 1
54   %postofs = sext i32 %postiv to i64
55   %postadr = getelementptr i8, i8* %base, i64 %postofs
56   store i8 0, i8* %postadr
57   %postivnsw = add nsw i32 %ivnsw, 1
58   %postofsnsw = sext i32 %postivnsw to i64
59   %postadrnsw = getelementptr i8, i8* %base, i64 %postofsnsw
60   store i8 0, i8* %postadrnsw
61   %cond = icmp sgt i32 %limit, %postiv
62   br i1 %cond, label %loop, label %exit
63 exit:
64   br label %return
65 return:
66   ret void
69 ; Test sign extend elimination in the inner and outer loop.
70 ; %outercount is straightforward to widen, besides being in an outer loop.
71 ; %innercount is currently blocked by lcssa, so is not widened.
72 ; %inneriv can be widened only after proving it has no signed-overflow
73 ;   based on the loop test.
74 define void @nestedIV(i8* %address, i32 %limit) nounwind {
75 entry:
76   %limitdec = add i32 %limit, -1
77   br label %outerloop
79 ; CHECK: outerloop:
81 ; Eliminate %ofs1 after widening outercount.
82 ; CHECK-NOT: sext
83 ; CHECK: getelementptr
85 ; IV rewriting hoists a gep into this block. We don't like that.
86 ; CHECK-NOT: getelementptr
87 outerloop:
88   %outercount   = phi i32 [ %outerpostcount, %outermerge ], [ 0, %entry ]
89   %innercount = phi i32 [ %innercount.merge, %outermerge ], [ 0, %entry ]
91   %outercountdec = add i32 %outercount, -1
92   %ofs1 = sext i32 %outercountdec to i64
93   %adr1 = getelementptr i8, i8* %address, i64 %ofs1
94   store i8 0, i8* %adr1
96   br label %innerpreheader
98 innerpreheader:
99   %innerprecmp = icmp sgt i32 %limitdec, %innercount
100   br i1 %innerprecmp, label %innerloop, label %outermerge
102 ; CHECK: innerloop:
104 ; Eliminate %ofs2 after widening inneriv.
105 ; Eliminate %ofs3 after normalizing sext(innerpostiv)
106 ; CHECK-NOT: sext
107 ; CHECK: getelementptr
109 ; FIXME: We should check that indvars does not increase the number of
110 ; IVs in this loop. sext elimination plus LFTR currently results in 2 final
111 ; IVs. Waiting to remove LFTR.
112 innerloop:
113   %inneriv = phi i32 [ %innerpostiv, %innerloop ], [ %innercount, %innerpreheader ]
114   %innerpostiv = add i32 %inneriv, 1
116   %ofs2 = sext i32 %inneriv to i64
117   %adr2 = getelementptr i8, i8* %address, i64 %ofs2
118   store i8 0, i8* %adr2
120   %ofs3 = sext i32 %innerpostiv to i64
121   %adr3 = getelementptr i8, i8* %address, i64 %ofs3
122   store i8 0, i8* %adr3
124   %innercmp = icmp sgt i32 %limitdec, %innerpostiv
125   br i1 %innercmp, label %innerloop, label %innerexit
127 innerexit:
128   %innercount.lcssa = phi i32 [ %innerpostiv, %innerloop ]
129   br label %outermerge
131 ; CHECK: outermerge:
133 ; Eliminate %ofs4 after widening outercount
134 ; CHECK-NOT: sext
135 ; CHECK: getelementptr
137 ; TODO: Eliminate %ofs5 after removing lcssa
138 outermerge:
139   %innercount.merge = phi i32 [ %innercount.lcssa, %innerexit ], [ %innercount, %innerpreheader ]
141   %ofs4 = sext i32 %outercount to i64
142   %adr4 = getelementptr i8, i8* %address, i64 %ofs4
143   store i8 0, i8* %adr4
145   %ofs5 = sext i32 %innercount.merge to i64
146   %adr5 = getelementptr i8, i8* %address, i64 %ofs5
147   store i8 0, i8* %adr5
149   %outerpostcount = add i32 %outercount, 1
150   %tmp47 = icmp slt i32 %outerpostcount, %limit
151   br i1 %tmp47, label %outerloop, label %return
153 return:
154   ret void