1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -instsimplify -S < %s | FileCheck %s
3
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.
7
8; Most basic case, fully identical PHI nodes
9define void @test0(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %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]], i32* [[D0:%.*]], align 4
21; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
22; CHECK-NEXT:    ret void
23;
24entry:
25  br i1 %c, label %b0, label %b1
26
27b0:
28  br label %end
29
30b1:
31  br label %end
32
33end:
34  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
35  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
36  store i32 %i0, i32* %d0
37  store i32 %i1, i32* %d1
38  ret void
39}
40
41; Fully identical PHI nodes, but order of operands differs
42define void @test1(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %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]], i32* [[D0:%.*]], align 4
54; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
55; CHECK-NEXT:    ret void
56;
57entry:
58  br i1 %c, label %b0, label %b1
59
60b0:
61  br label %end
62
63b1:
64  br label %end
65
66end:
67  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
68  %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ]
69  store i32 %i0, i32* %d0
70  store i32 %i1, i32* %d1
71  ret void
72}
73
74; Different incoming values in second PHI
75define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, i32* %d0, i32* %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]], i32* [[D0:%.*]], align 4
87; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
88; CHECK-NEXT:    ret void
89;
90entry:
91  br i1 %c, label %b0, label %b1
92
93b0:
94  br label %end
95
96b1:
97  br label %end
98
99end:
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, i32* %d0
103  store i32 %i1, i32* %d1
104  ret void
105}
106define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, i32* %d0, i32* %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]], i32* [[D0:%.*]], align 4
118; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
119; CHECK-NEXT:    ret void
120;
121entry:
122  br i1 %c, label %b0, label %b1
123
124b0:
125  br label %end
126
127b1:
128  br label %end
129
130end:
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, i32* %d0
134  store i32 %i1, i32* %d1
135  ret void
136}
137define void @negative_test4(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %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]], i32* [[D0:%.*]], align 4
149; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
150; CHECK-NEXT:    ret void
151;
152entry:
153  br i1 %c, label %b0, label %b1
154
155b0:
156  br label %end
157
158b1:
159  br label %end
160
161end:
162  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
163  %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ] ; incoming values are swapped
164  store i32 %i0, i32* %d0
165  store i32 %i1, i32* %d1
166  ret void
167}
168
169; Both PHI's are identical, but the first one has no uses, so ignore it.
170define void @test5(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %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]], i32* [[D1:%.*]], align 4
181; CHECK-NEXT:    ret void
182;
183entry:
184  br i1 %c, label %b0, label %b1
185
186b0:
187  br label %end
188
189b1:
190  br label %end
191
192end:
193  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
194  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
195  store i32 %i1, i32* %d1
196  ret void
197}
198; Second PHI has no uses
199define void @test6(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %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]], i32* [[D0:%.*]], align 4
210; CHECK-NEXT:    ret void
211;
212entry:
213  br i1 %c, label %b0, label %b1
214
215b0:
216  br label %end
217
218b1:
219  br label %end
220
221end:
222  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
223  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
224  store i32 %i0, i32* %d0
225  ret void
226}
227
228; Non-matching PHI node should be ignored without terminating CSE.
229define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %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]], i32* [[D0:%.*]], align 4
242; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
243; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
244; CHECK-NEXT:    ret void
245;
246entry:
247  br i1 %c, label %b0, label %b1
248
249b0:
250  br label %end
251
252b1:
253  br label %end
254
255end:
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, i32* %d0
260  store i32 %i1, i32* %d1
261  store i16 %iBAD, i16* %d2
262  ret void
263}
264define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %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]], i32* [[D0:%.*]], align 4
277; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
278; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
279; CHECK-NEXT:    ret void
280;
281entry:
282  br i1 %c, label %b0, label %b1
283
284b0:
285  br label %end
286
287b1:
288  br label %end
289
290end:
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, i32* %d0
295  store i32 %i1, i32* %d1
296  store i16 %iBAD, i16* %d2
297  ret void
298}
299define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %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]], i32* [[D0:%.*]], align 4
312; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
313; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
314; CHECK-NEXT:    ret void
315;
316entry:
317  br i1 %c, label %b0, label %b1
318
319b0:
320  br label %end
321
322b1:
323  br label %end
324
325end:
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, i32* %d0
330  store i32 %i1, i32* %d1
331  store i16 %iBAD, i16* %d2
332  ret void
333}
334