[ARM] Adjust how NEON shifts are lowered
[llvm-core.git] / test / Transforms / GVN / PRE / phi-translate-2.ll
blobb40c745ea13c97cf27286383f75bd26b4535769e
1 ; RUN: opt < %s -debugify -gvn -S | FileCheck %s
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
4 @a = common global [100 x i64] zeroinitializer, align 16
5 @b = common global [100 x i64] zeroinitializer, align 16
6 @g1 = common global i64 0, align 8
7 @g2 = common global i64 0, align 8
8 @g3 = common global i64 0, align 8
9 declare i64 @goo(...) local_unnamed_addr #1
11 define void @test1(i64 %a, i64 %b, i64 %c, i64 %d) {
12 entry:
13   %mul = mul nsw i64 %b, %a
14   store i64 %mul, i64* @g1, align 8
15   %t0 = load i64, i64* @g2, align 8
16   %cmp = icmp sgt i64 %t0, 3
17   br i1 %cmp, label %if.then, label %if.end
19 if.then:                                          ; preds = %entry
20   %mul2 = mul nsw i64 %d, %c
21   store i64 %mul2, i64* @g2, align 8
22   br label %if.end
24 ; Check phi-translate works and mul is removed.
25 ; CHECK-LABEL: @test1(
26 ; CHECK: if.end:
27 ; CHECK: %[[MULPHI:.*]] = phi i64 [ {{.*}}, %if.then ], [ %mul, %entry ]
28 ; CHECK-NOT: = mul
29 ; CHECK: store i64 %[[MULPHI]], i64* @g3, align 8
30 if.end:                                           ; preds = %if.then, %entry
31   %b.addr.0 = phi i64 [ %d, %if.then ], [ %b, %entry ]
32   %a.addr.0 = phi i64 [ %c, %if.then ], [ %a, %entry ]
33   %mul3 = mul nsw i64 %a.addr.0, %b.addr.0
34   store i64 %mul3, i64* @g3, align 8
35   ret void
38 define void @test2(i64 %i) {
39 entry:
40   %arrayidx = getelementptr inbounds [100 x i64], [100 x i64]* @a, i64 0, i64 %i
41   %t0 = load i64, i64* %arrayidx, align 8
42   %arrayidx1 = getelementptr inbounds [100 x i64], [100 x i64]* @b, i64 0, i64 %i
43   %t1 = load i64, i64* %arrayidx1, align 8
44   %mul = mul nsw i64 %t1, %t0
45   store i64 %mul, i64* @g1, align 8
46   %cmp = icmp sgt i64 %mul, 3
47   br i1 %cmp, label %if.then, label %if.end
49 ; Check phi-translate works for the phi generated by loadpre. A new mul will be
50 ; inserted in if.then block.
51 ; CHECK-LABEL: @test2(
52 ; CHECK: if.then:
53 ; CHECK: %[[MUL_THEN:.*]] = mul
54 ; CHECK: br label %if.end
55 if.then:                                          ; preds = %entry
56   %call = tail call i64 (...) @goo() #2
57   store i64 %call, i64* @g2, align 8
58   br label %if.end
60 ; CHECK: if.end:
61 ; CHECK: %[[MULPHI:.*]] = phi i64 [ %[[MUL_THEN]], %if.then ], [ %mul, %entry ]
62 ; CHECK-NOT: = mul
63 ; CHECK: store i64 %[[MULPHI]], i64* @g3, align 8
64 if.end:                                           ; preds = %if.then, %entry
65   %i.addr.0 = phi i64 [ 3, %if.then ], [ %i, %entry ]
66   %arrayidx3 = getelementptr inbounds [100 x i64], [100 x i64]* @a, i64 0, i64 %i.addr.0
67   %t2 = load i64, i64* %arrayidx3, align 8
68   %arrayidx4 = getelementptr inbounds [100 x i64], [100 x i64]* @b, i64 0, i64 %i.addr.0
69   %t3 = load i64, i64* %arrayidx4, align 8
70   %mul5 = mul nsw i64 %t3, %t2
71   store i64 %mul5, i64* @g3, align 8
72   ret void
75 ; Check phi-translate doesn't go through backedge, which may lead to incorrect
76 ; pre transformation.
77 ; CHECK: for.end:
78 ; CHECK-NOT: %{{.*pre-phi}} = phi
79 ; CHECK: ret void
80 define void @test3(i64 %N, i64* nocapture readonly %a) {
81 entry:
82   br label %for.cond
84 for.cond:                                         ; preds = %for.body, %entry
85   %i.0 = phi i64 [ 0, %entry ], [ %add, %for.body ]
86   %add = add nuw nsw i64 %i.0, 1
87   %arrayidx = getelementptr inbounds i64, i64* %a, i64 %add
88   %tmp0 = load i64, i64* %arrayidx, align 8
89   %cmp = icmp slt i64 %i.0, %N
90   br i1 %cmp, label %for.body, label %for.end
92 for.body:                                         ; preds = %for.cond
93   %call = tail call i64 (...) @goo() #2
94   %add1 = sub nsw i64 0, %call
95   %tobool = icmp eq i64 %tmp0, %add1
96   br i1 %tobool, label %for.cond, label %for.end
98 for.end:                                          ; preds = %for.body, %for.cond
99   %i.0.lcssa = phi i64 [ %i.0, %for.body ], [ %i.0, %for.cond ]
100   %arrayidx2 = getelementptr inbounds i64, i64* %a, i64 %i.0.lcssa
101   %tmp1 = load i64, i64* %arrayidx2, align 8
102   store i64 %tmp1, i64* @g1, align 8
103   ret void
106 ; It is incorrect to use the value of %andres in last loop iteration
107 ; to do pre.
108 ; CHECK-LABEL: @test4(
109 ; CHECK: for.body:
110 ; CHECK-NOT: %andres.pre-phi = phi i32
111 ; CHECK: br i1 %tobool1
113 define i32 @test4(i32 %cond, i32 %SectionAttrs.0231.ph, i32 *%AttrFlag) {
114 for.body.preheader:
115   %t514 = load volatile i32, i32* %AttrFlag
116   br label %for.body
118 for.body:
119   %t320 = phi i32 [ %t334, %bb343 ], [ %t514, %for.body.preheader ]
120   %andres = and i32 %t320, %SectionAttrs.0231.ph
121   %tobool1 = icmp eq i32 %andres, 0
122   br i1 %tobool1, label %bb343, label %critedge.loopexit
124 bb343:
125   %t334 = load volatile i32, i32* %AttrFlag
126   %tobool2 = icmp eq i32 %cond, 0
127   br i1 %tobool2, label %critedge.loopexit, label %for.body
129 critedge.loopexit:
130   unreachable
133 ; Check sub expression will be pre transformed.
134 ; CHECK-LABEL: @test5(
135 ; CHECK: entry:
136 ; CHECK: %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
137 ; CHECK: br i1 %cmp
138 ; CHECK: if.then2:
139 ; CHECK: %[[PTRTOINT:.*]] = ptrtoint i32* %add.ptr to i64
140 ; CHECK: %[[SUB:.*]] = sub i64 %sub.ptr.lhs.cast, %[[PTRTOINT]]
141 ; CHECK: br label %if.end3
142 ; CHECK: if.end3:
143 ; CHECK: %[[PREPHI:.*]] = phi i64 [ %sub.ptr.sub, %if.else ], [ %[[SUB]], %if.then2 ], [ %sub.ptr.sub, %entry ]
144 ; CHECK: call void @llvm.dbg.value(metadata i32* %p.0, metadata [[var_p0:![0-9]+]], metadata !DIExpression())
145 ; CHECK: call void @llvm.dbg.value(metadata i64 %sub.ptr.rhs.cast5.pre-phi, metadata [[var_sub_ptr:![0-9]+]], metadata !DIExpression())
146 ; CHECK: %[[DIV:.*]] = ashr exact i64 %[[PREPHI]], 2
147 ; CHECK: ret i64 %[[DIV]]
149 declare void @bar(...) local_unnamed_addr #1
151 ; Function Attrs: nounwind uwtable
152 define i64 @test5(i32* %start, i32* %e, i32 %n1, i32 %n2) local_unnamed_addr #0 {
153 entry:
154   %sub.ptr.lhs.cast = ptrtoint i32* %e to i64
155   %sub.ptr.rhs.cast = ptrtoint i32* %start to i64
156   %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast
157   %cmp = icmp sgt i64 %sub.ptr.sub, 4000
158   br i1 %cmp, label %if.then, label %if.end3
160 if.then:                                          ; preds = %entry
161   %cmp1 = icmp sgt i32 %n1, %n2
162   br i1 %cmp1, label %if.then2, label %if.else
164 if.then2:                                         ; preds = %if.then
165   %add.ptr = getelementptr inbounds i32, i32* %start, i64 800
166   br label %if.end3
168 if.else:                                          ; preds = %if.then
169   tail call void (...) @bar() #2
170   br label %if.end3
172 if.end3:                                          ; preds = %if.then2, %if.else, %entry
173   %p.0 = phi i32* [ %add.ptr, %if.then2 ], [ %start, %if.else ], [ %start, %entry ]
174   %sub.ptr.rhs.cast5 = ptrtoint i32* %p.0 to i64
175   %sub.ptr.sub6 = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast5
176   %sub.ptr.div7 = ashr exact i64 %sub.ptr.sub6, 2
177   ret i64 %sub.ptr.div7
180 ; Here the load from arrayidx1 is partially redundant, but its value is
181 ; available in if.then. Check that we correctly phi-translate to the phi that
182 ; the load has been replaced with.
183 ; CHECK-LABEL: @test6
184 define void @test6(i32* %ptr) {
185 ; CHECK: entry:
186 ; CHECK: %[[PREGEP:.*]] = getelementptr inbounds i32, i32* %ptr, i64 1
187 ; CHECK: %[[PRE:.*]] = load i32, i32* %[[PREGEP]]
188 entry:
189   br label %while
191 ; CHECK: while:
192 ; CHECK: %[[PHI1:.*]] = phi i32 [ %[[PRE]], %entry ], [ %[[PHI2:.*]], %if.end ]
193 ; CHECK-NOT: load i32, i32* %arrayidx1
194 ; CHECK: %[[LOAD:.*]] = load i32, i32* %arrayidx2
195 while:
196   %i = phi i64 [ 1, %entry ], [ %i.next, %if.end ]
197   %arrayidx1 = getelementptr inbounds i32, i32* %ptr, i64 %i
198   %0 = load i32, i32* %arrayidx1, align 4
199   %i.next = add nuw nsw i64 %i, 1
200   %arrayidx2 = getelementptr inbounds i32, i32* %ptr, i64 %i.next
201   %1 = load i32, i32* %arrayidx2, align 4
202   %cmp = icmp sgt i32 %0, %1
203   br i1 %cmp, label %if.then, label %if.end
205 if.then:
206   store i32 %1, i32* %arrayidx1, align 4
207   store i32 %0, i32* %arrayidx2, align 4
208   br label %if.end
210 ; CHECK: if.then:
211 ; CHECK: %[[PHI2]] = phi i32 [ %[[PHI1]], %if.then ], [ %[[LOAD]], %while ]
212 if.end:
213   br i1 undef, label %while.end, label %while
215 while.end:
216   ret void
219 ; CHECK: [[var_p0]] = !DILocalVariable
220 ; CHECK: [[var_sub_ptr]] = !DILocalVariable