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
5 ; Most basic case, fully identical PHI nodes
6 define void @test0(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
9 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
11 ; CHECK-NEXT: br label [[END:%.*]]
13 ; CHECK-NEXT: br label [[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
22 br i1 %c, label %b0, label %b1
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
38 ; Fully identical PHI nodes, but order of operands differs
39 define void @test1(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
40 ; CHECK-LABEL: @test1(
42 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
44 ; CHECK-NEXT: br label [[END:%.*]]
46 ; CHECK-NEXT: br label [[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
55 br i1 %c, label %b0, label %b1
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
71 ; Different incoming values in second PHI
72 define void @negative_test2(i32 %v0, i32 %v1, i32 %v2, i1 %c, i32* %d0, i32* %d1) {
73 ; CHECK-LABEL: @negative_test2(
75 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
77 ; CHECK-NEXT: br label [[END:%.*]]
79 ; CHECK-NEXT: br label [[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
88 br i1 %c, label %b0, label %b1
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
103 define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, i32* %d0, i32* %d1) {
104 ; CHECK-LABEL: @negative_test3(
106 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
108 ; CHECK-NEXT: br label [[END:%.*]]
110 ; CHECK-NEXT: br label [[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
119 br i1 %c, label %b0, label %b1
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
134 define void @negative_test4(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
135 ; CHECK-LABEL: @negative_test4(
137 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
139 ; CHECK-NEXT: br label [[END:%.*]]
141 ; CHECK-NEXT: br label [[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
150 br i1 %c, label %b0, label %b1
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
166 ; Both PHI's are identical, but the first one has no uses, so ignore it.
167 define void @test5(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
168 ; CHECK-LABEL: @test5(
170 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
172 ; CHECK-NEXT: br label [[END:%.*]]
174 ; CHECK-NEXT: br label [[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
181 br i1 %c, label %b0, label %b1
190 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
191 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
192 store i32 %i1, i32* %d1
195 ; Second PHI has no uses
196 define void @test6(i32 %v0, i32 %v1, i1 %c, i32* %d0, i32* %d1) {
197 ; CHECK-LABEL: @test6(
199 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
201 ; CHECK-NEXT: br label [[END:%.*]]
203 ; CHECK-NEXT: br label [[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
210 br i1 %c, label %b0, label %b1
219 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
220 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
221 store i32 %i0, i32* %d0
225 ; Non-matching PHI node should be ignored without terminating CSE.
226 define void @test7(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %d2) {
227 ; CHECK-LABEL: @test7(
229 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
231 ; CHECK-NEXT: br label [[END:%.*]]
233 ; CHECK-NEXT: br label [[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
244 br i1 %c, label %b0, label %b1
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
261 define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %d2) {
262 ; CHECK-LABEL: @test8(
264 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
266 ; CHECK-NEXT: br label [[END:%.*]]
268 ; CHECK-NEXT: br label [[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
279 br i1 %c, label %b0, label %b1
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
296 define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, i32* %d0, i32* %d1, i16* %d2) {
297 ; CHECK-LABEL: @test9(
299 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
301 ; CHECK-NEXT: br label [[END:%.*]]
303 ; CHECK-NEXT: br label [[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
314 br i1 %c, label %b0, label %b1
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