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
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(
12 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
14 ; CHECK-NEXT: br label [[END:%.*]]
16 ; CHECK-NEXT: br label [[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
25 br i1 %c, label %b0, label %b1
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
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(
45 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
47 ; CHECK-NEXT: br label [[END:%.*]]
49 ; CHECK-NEXT: br label [[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
58 br i1 %c, label %b0, label %b1
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
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(
78 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
80 ; CHECK-NEXT: br label [[END:%.*]]
82 ; CHECK-NEXT: br label [[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
91 br i1 %c, label %b0, label %b1
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
106 define void @negative_test3(i32 %v0, i32 %v1, i32 %v2, i1 %c, ptr %d0, ptr %d1) {
107 ; CHECK-LABEL: @negative_test3(
109 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
111 ; CHECK-NEXT: br label [[END:%.*]]
113 ; CHECK-NEXT: br label [[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
122 br i1 %c, label %b0, label %b1
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
137 define void @negative_test4(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
138 ; CHECK-LABEL: @negative_test4(
140 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
142 ; CHECK-NEXT: br label [[END:%.*]]
144 ; CHECK-NEXT: br label [[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
153 br i1 %c, label %b0, label %b1
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
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(
173 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
175 ; CHECK-NEXT: br label [[END:%.*]]
177 ; CHECK-NEXT: br label [[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
184 br i1 %c, label %b0, label %b1
193 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
194 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
195 store i32 %i1, ptr %d1
198 ; Second PHI has no uses
199 define void @test6(i32 %v0, i32 %v1, i1 %c, ptr %d0, ptr %d1) {
200 ; CHECK-LABEL: @test6(
202 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
204 ; CHECK-NEXT: br label [[END:%.*]]
206 ; CHECK-NEXT: br label [[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
213 br i1 %c, label %b0, label %b1
222 %i0 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ]
223 %i1 = phi i32 [ %v0, %b0 ], [ %v1, %b1 ] ; unused
224 store i32 %i0, ptr %d0
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(
232 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
234 ; CHECK-NEXT: br label [[END:%.*]]
236 ; CHECK-NEXT: br label [[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
247 br i1 %c, label %b0, label %b1
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
264 define void @test8(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
265 ; CHECK-LABEL: @test8(
267 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
269 ; CHECK-NEXT: br label [[END:%.*]]
271 ; CHECK-NEXT: br label [[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
282 br i1 %c, label %b0, label %b1
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
299 define void @test9(i32 %v0, i32 %v1, i16 %v2, i16 %v3, i1 %c, ptr %d0, ptr %d1, ptr %d2) {
300 ; CHECK-LABEL: @test9(
302 ; CHECK-NEXT: br i1 [[C:%.*]], label [[B0:%.*]], label [[B1:%.*]]
304 ; CHECK-NEXT: br label [[END:%.*]]
306 ; CHECK-NEXT: br label [[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
317 br i1 %c, label %b0, label %b1
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