Follow up to d0858bffa11, add missing REQUIRES x86
[llvm-project.git] / llvm / test / Transforms / InstSimplify / phi-cse.ll
blob327cf24be1740cb84c30ea99863a9a3f43dfca37
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instsimplify -S < %s | FileCheck %s
4 ; All these are negative cases, we are not allowed to perform this
5 ; simplification in InstSimplify, because the PHI's aren't def-reachable
6 ; from one another.
8 ; Most basic case, fully identical PHI nodes
9 define void @test0(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
10 ; CHECK-LABEL: @test0(
11 ; CHECK-NEXT:  entry:
12 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
13 ; CHECK:       b0:
14 ; CHECK-NEXT:    br label [[END:%.*]]
15 ; CHECK:       b1:
16 ; CHECK-NEXT:    br label [[END]]
17 ; CHECK:       end:
18 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
19 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
20 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
21 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
22 ; CHECK-NEXT:    ret void
24 entry:
25   br i1 %c, label %b0, label %b1
27 b0:
28   br label %end
30 b1:
31   br label %end
33 end:
34   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
35   %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
36   store i32 %i0, ptr %d0
37   store i32 %i1, ptr %d1
38   ret void
41 ; Fully identical PHI nodes, but order of operands differs
42 define void @test1(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
43 ; CHECK-LABEL: @test1(
44 ; CHECK-NEXT:  entry:
45 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
46 ; CHECK:       b0:
47 ; CHECK-NEXT:    br label [[END:%.*]]
48 ; CHECK:       b1:
49 ; CHECK-NEXT:    br label [[END]]
50 ; CHECK:       end:
51 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
52 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]
53 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
54 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
55 ; CHECK-NEXT:    ret void
57 entry:
58   br i1 %c, label %b0, label %b1
60 b0:
61   br label %end
63 b1:
64   br label %end
66 end:
67   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
68   %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ]
69   store i32 %i0, ptr %d0
70   store i32 %i1, ptr %d1
71   ret void
74 ; Different incoming values in second PHI
75 define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {
76 ; CHECK-LABEL: @negative_test2(
77 ; CHECK-NEXT:  entry:
78 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
79 ; CHECK:       b0:
80 ; CHECK-NEXT:    br label [[END:%.*]]
81 ; CHECK:       b1:
82 ; CHECK-NEXT:    br label [[END]]
83 ; CHECK:       end:
84 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
85 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V2:%.*]], [[B1]] ]
86 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
87 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
88 ; CHECK-NEXT:    ret void
90 entry:
91   br i1 %c, label %b0, label %b1
93 b0:
94   br label %end
96 b1:
97   br label %end
99 end:
100   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
101   %i1 = phi i32 [ %v0, %b0 ], [ %v2, %b1 ] ; from %b0 takes %v2 instead of %v1
102   store i32 %i0, ptr %d0
103   store i32 %i1, ptr %d1
104   ret void
106 define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {
107 ; CHECK-LABEL: @negative_test3(
108 ; CHECK-NEXT:  entry:
109 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
110 ; CHECK:       b0:
111 ; CHECK-NEXT:    br label [[END:%.*]]
112 ; CHECK:       b1:
113 ; CHECK-NEXT:    br label [[END]]
114 ; CHECK:       end:
115 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
116 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V2:%.*]], [[B1]] ], [ [[V0]], [[B0]] ]
117 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
118 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
119 ; CHECK-NEXT:    ret void
121 entry:
122   br i1 %c, label %b0, label %b1
125   br label %end
128   br label %end
130 end:
131   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
132   %i1 = phi i32 [ %v2, %b1 ], [ %v0, %b0 ] ; from %b0 takes %v2 instead of %v1
133   store i32 %i0, ptr %d0
134   store i32 %i1, ptr %d1
135   ret void
137 define void @negative_test4(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
138 ; CHECK-LABEL: @negative_test4(
139 ; CHECK-NEXT:  entry:
140 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
141 ; CHECK:       b0:
142 ; CHECK-NEXT:    br label [[END:%.*]]
143 ; CHECK:       b1:
144 ; CHECK-NEXT:    br label [[END]]
145 ; CHECK:       end:
146 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
147 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]
148 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
149 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
150 ; CHECK-NEXT:    ret void
152 entry:
153   br i1 %c, label %b0, label %b1
156   br label %end
159   br label %end
161 end:
162   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
163   %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ] ; incoming values are swapped
164   store i32 %i0, ptr %d0
165   store i32 %i1, ptr %d1
166   ret void
169 ; Both PHI's are identical, but the first one has no uses, so ignore it.
170 define void @test5(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
171 ; CHECK-LABEL: @test5(
172 ; CHECK-NEXT:  entry:
173 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
174 ; CHECK:       b0:
175 ; CHECK-NEXT:    br label [[END:%.*]]
176 ; CHECK:       b1:
177 ; CHECK-NEXT:    br label [[END]]
178 ; CHECK:       end:
179 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
180 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
181 ; CHECK-NEXT:    ret void
183 entry:
184   br i1 %c, label %b0, label %b1
187   br label %end
190   br label %end
192 end:
193   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
194   %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
195   store i32 %i1, ptr %d1
196   ret void
198 ; Second PHI has no uses
199 define void @test6(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
200 ; CHECK-LABEL: @test6(
201 ; CHECK-NEXT:  entry:
202 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
203 ; CHECK:       b0:
204 ; CHECK-NEXT:    br label [[END:%.*]]
205 ; CHECK:       b1:
206 ; CHECK-NEXT:    br label [[END]]
207 ; CHECK:       end:
208 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
209 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
210 ; CHECK-NEXT:    ret void
212 entry:
213   br i1 %c, label %b0, label %b1
216   br label %end
219   br label %end
221 end:
222   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
223   %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
224   store i32 %i0, ptr %d0
225   ret void
228 ; Non-matching PHI node should be ignored without terminating CSE.
229 define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
230 ; CHECK-LABEL: @test7(
231 ; CHECK-NEXT:  entry:
232 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
233 ; CHECK:       b0:
234 ; CHECK-NEXT:    br label [[END:%.*]]
235 ; CHECK:       b1:
236 ; CHECK-NEXT:    br label [[END]]
237 ; CHECK:       end:
238 ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
239 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
240 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
241 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
242 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
243 ; CHECK-NEXT:    store i16 [[IBAD]], ptr [[D2:%.*]], align 2
244 ; CHECK-NEXT:    ret void
246 entry:
247   br i1 %c, label %b0, label %b1
250   br label %end
253   br label %end
255 end:
256   %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
257   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
258   %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
259   store i32 %i0, ptr %d0
260   store i32 %i1, ptr %d1
261   store i16 %iBAD, ptr %d2
262   ret void
264 define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
265 ; CHECK-LABEL: @test8(
266 ; CHECK-NEXT:  entry:
267 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
268 ; CHECK:       b0:
269 ; CHECK-NEXT:    br label [[END:%.*]]
270 ; CHECK:       b1:
271 ; CHECK-NEXT:    br label [[END]]
272 ; CHECK:       end:
273 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
274 ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
275 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
276 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
277 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
278 ; CHECK-NEXT:    store i16 [[IBAD]], ptr [[D2:%.*]], align 2
279 ; CHECK-NEXT:    ret void
281 entry:
282   br i1 %c, label %b0, label %b1
285   br label %end
288   br label %end
290 end:
291   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
292   %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
293   %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
294   store i32 %i0, ptr %d0
295   store i32 %i1, ptr %d1
296   store i16 %iBAD, ptr %d2
297   ret void
299 define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
300 ; CHECK-LABEL: @test9(
301 ; CHECK-NEXT:  entry:
302 ; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
303 ; CHECK:       b0:
304 ; CHECK-NEXT:    br label [[END:%.*]]
305 ; CHECK:       b1:
306 ; CHECK-NEXT:    br label [[END]]
307 ; CHECK:       end:
308 ; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
309 ; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
310 ; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
311 ; CHECK-NEXT:    store i32 [[I0]], ptr [[D0:%.*]], align 4
312 ; CHECK-NEXT:    store i32 [[I1]], ptr [[D1:%.*]], align 4
313 ; CHECK-NEXT:    store i16 [[IBAD]], ptr [[D2:%.*]], align 2
314 ; CHECK-NEXT:    ret void
316 entry:
317   br i1 %c, label %b0, label %b1
320   br label %end
323   br label %end
325 end:
326   %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
327   %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
328   %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
329   store i32 %i0, ptr %d0
330   store i32 %i1, ptr %d1
331   store i16 %iBAD, ptr %d2
332   ret void