• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -early-cse -earlycse-debug-hash -S < %s | FileCheck %s
3; RUN: opt -basic-aa -early-cse-memssa -S < %s | FileCheck %s
4
5; Most basic case, fully identical PHI nodes
6define void @test0(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
7; CHECK-LABEL: @test0(
8; CHECK-NEXT:  entry:
9; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
10; CHECK:       b0:
11; CHECK-NEXT:    br label [[END:%.*]]
12; CHECK:       b1:
13; CHECK-NEXT:    br label [[END]]
14; CHECK:       end:
15; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
16; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
17; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
18; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
19; CHECK-NEXT:    ret void
20;
21entry:
22  br i1 %c, label %b0, label %b1
23
24b0:
25  br label %end
26
27b1:
28  br label %end
29
30end:
31  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
32  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
33  store i32 %i0, i32* %d0
34  store i32 %i1, i32* %d1
35  ret void
36}
37
38; Fully identical PHI nodes, but order of operands differs
39define void @test1(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
40; CHECK-LABEL: @test1(
41; CHECK-NEXT:  entry:
42; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
43; CHECK:       b0:
44; CHECK-NEXT:    br label [[END:%.*]]
45; CHECK:       b1:
46; CHECK-NEXT:    br label [[END]]
47; CHECK:       end:
48; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
49; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]
50; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
51; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
52; CHECK-NEXT:    ret void
53;
54entry:
55  br i1 %c, label %b0, label %b1
56
57b0:
58  br label %end
59
60b1:
61  br label %end
62
63end:
64  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
65  %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ]
66  store i32 %i0, i32* %d0
67  store i32 %i1, i32* %d1
68  ret void
69}
70
71; Different incoming values in second PHI
72define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, i32* %d0, i32* %d1) {
73; CHECK-LABEL: @negative_test2(
74; CHECK-NEXT:  entry:
75; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
76; CHECK:       b0:
77; CHECK-NEXT:    br label [[END:%.*]]
78; CHECK:       b1:
79; CHECK-NEXT:    br label [[END]]
80; CHECK:       end:
81; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
82; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V2:%.*]], [[B1]] ]
83; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
84; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
85; CHECK-NEXT:    ret void
86;
87entry:
88  br i1 %c, label %b0, label %b1
89
90b0:
91  br label %end
92
93b1:
94  br label %end
95
96end:
97  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
98  %i1 = phi i32 [ %v0, %b0 ], [ %v2, %b1 ] ; from %b0 takes %v2 instead of %v1
99  store i32 %i0, i32* %d0
100  store i32 %i1, i32* %d1
101  ret void
102}
103define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, i32* %d0, i32* %d1) {
104; CHECK-LABEL: @negative_test3(
105; CHECK-NEXT:  entry:
106; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
107; CHECK:       b0:
108; CHECK-NEXT:    br label [[END:%.*]]
109; CHECK:       b1:
110; CHECK-NEXT:    br label [[END]]
111; CHECK:       end:
112; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
113; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V2:%.*]], [[B1]] ], [ [[V0]], [[B0]] ]
114; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
115; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
116; CHECK-NEXT:    ret void
117;
118entry:
119  br i1 %c, label %b0, label %b1
120
121b0:
122  br label %end
123
124b1:
125  br label %end
126
127end:
128  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
129  %i1 = phi i32 [ %v2, %b1 ], [ %v0, %b0 ] ; from %b0 takes %v2 instead of %v1
130  store i32 %i0, i32* %d0
131  store i32 %i1, i32* %d1
132  ret void
133}
134define void @negative_test4(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
135; CHECK-LABEL: @negative_test4(
136; CHECK-NEXT:  entry:
137; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
138; CHECK:       b0:
139; CHECK-NEXT:    br label [[END:%.*]]
140; CHECK:       b1:
141; CHECK-NEXT:    br label [[END]]
142; CHECK:       end:
143; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
144; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V1]], [[B1]] ], [ [[V0]], [[B0]] ]
145; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
146; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
147; CHECK-NEXT:    ret void
148;
149entry:
150  br i1 %c, label %b0, label %b1
151
152b0:
153  br label %end
154
155b1:
156  br label %end
157
158end:
159  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
160  %i1 = phi i32 [ %v1, %b1 ], [ %v0, %b0 ] ; incoming values are swapped
161  store i32 %i0, i32* %d0
162  store i32 %i1, i32* %d1
163  ret void
164}
165
166; Both PHI's are identical, but the first one has no uses, so ignore it.
167define void @test5(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
168; CHECK-LABEL: @test5(
169; CHECK-NEXT:  entry:
170; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
171; CHECK:       b0:
172; CHECK-NEXT:    br label [[END:%.*]]
173; CHECK:       b1:
174; CHECK-NEXT:    br label [[END]]
175; CHECK:       end:
176; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
177; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
178; CHECK-NEXT:    ret void
179;
180entry:
181  br i1 %c, label %b0, label %b1
182
183b0:
184  br label %end
185
186b1:
187  br label %end
188
189end:
190  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
191  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
192  store i32 %i1, i32* %d1
193  ret void
194}
195; Second PHI has no uses
196define void @test6(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
197; CHECK-LABEL: @test6(
198; CHECK-NEXT:  entry:
199; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
200; CHECK:       b0:
201; CHECK-NEXT:    br label [[END:%.*]]
202; CHECK:       b1:
203; CHECK-NEXT:    br label [[END]]
204; CHECK:       end:
205; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
206; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
207; CHECK-NEXT:    ret void
208;
209entry:
210  br i1 %c, label %b0, label %b1
211
212b0:
213  br label %end
214
215b1:
216  br label %end
217
218end:
219  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
220  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
221  store i32 %i0, i32* %d0
222  ret void
223}
224
225; Non-matching PHI node should be ignored without terminating CSE.
226define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %d2) {
227; CHECK-LABEL: @test7(
228; CHECK-NEXT:  entry:
229; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
230; CHECK:       b0:
231; CHECK-NEXT:    br label [[END:%.*]]
232; CHECK:       b1:
233; CHECK-NEXT:    br label [[END]]
234; CHECK:       end:
235; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
236; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
237; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
238; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
239; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
240; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
241; CHECK-NEXT:    ret void
242;
243entry:
244  br i1 %c, label %b0, label %b1
245
246b0:
247  br label %end
248
249b1:
250  br label %end
251
252end:
253  %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
254  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
255  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
256  store i32 %i0, i32* %d0
257  store i32 %i1, i32* %d1
258  store i16 %iBAD, i16* %d2
259  ret void
260}
261define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %d2) {
262; CHECK-LABEL: @test8(
263; CHECK-NEXT:  entry:
264; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
265; CHECK:       b0:
266; CHECK-NEXT:    br label [[END:%.*]]
267; CHECK:       b1:
268; CHECK-NEXT:    br label [[END]]
269; CHECK:       end:
270; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
271; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
272; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
273; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
274; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
275; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
276; CHECK-NEXT:    ret void
277;
278entry:
279  br i1 %c, label %b0, label %b1
280
281b0:
282  br label %end
283
284b1:
285  br label %end
286
287end:
288  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
289  %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
290  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
291  store i32 %i0, i32* %d0
292  store i32 %i1, i32* %d1
293  store i16 %iBAD, i16* %d2
294  ret void
295}
296define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %d2) {
297; CHECK-LABEL: @test9(
298; CHECK-NEXT:  entry:
299; CHECK-NEXT:    br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
300; CHECK:       b0:
301; CHECK-NEXT:    br label [[END:%.*]]
302; CHECK:       b1:
303; CHECK-NEXT:    br label [[END]]
304; CHECK:       end:
305; CHECK-NEXT:    [[I0:%.*]] = phi i32 [ [[V0:%.*]], [[B0]] ], [ [[V1:%.*]], [[B1]] ]
306; CHECK-NEXT:    [[I1:%.*]] = phi i32 [ [[V0]], [[B0]] ], [ [[V1]], [[B1]] ]
307; CHECK-NEXT:    [[IBAD:%.*]] = phi i16 [ [[V2:%.*]], [[B0]] ], [ [[V3:%.*]], [[B1]] ]
308; CHECK-NEXT:    store i32 [[I0]], i32* [[D0:%.*]], align 4
309; CHECK-NEXT:    store i32 [[I1]], i32* [[D1:%.*]], align 4
310; CHECK-NEXT:    store i16 [[IBAD]], i16* [[D2:%.*]], align 2
311; CHECK-NEXT:    ret void
312;
313entry:
314  br i1 %c, label %b0, label %b1
315
316b0:
317  br label %end
318
319b1:
320  br label %end
321
322end:
323  %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
324  %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
325  %iBAD = phi i16 [ %v2, %b0 ], [ %v3, %b1 ]
326  store i32 %i0, i32* %d0
327  store i32 %i1, i32* %d1
328  store i16 %iBAD, i16* %d2
329  ret void
330}
331