1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt -passes=instcombine,verify -S < %s | FileCheck %s --check-prefixes=ALL,INSTCOMBINE
4 ; Make sure GVN won't undo the transformation:
5 ; RUN: opt -passes=instcombine,gvn -S < %s | FileCheck %s --check-prefixes=ALL,INSTCOMBINEGVN
7 declare i8* @get_ptr.i8()
8 declare i32* @get_ptr.i32()
9 declare void @foo.i8(i8*)
10 declare void @foo.i32(i32*)
12 define i32 @test_gep_and_bitcast(i1 %cond, i1 %cond2) {
13 ; ALL-LABEL: @test_gep_and_bitcast(
15 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
16 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
18 ; ALL-NEXT: br label [[EXIT:%.*]]
20 ; ALL-NEXT: br label [[EXIT]]
22 ; ALL-NEXT: [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
23 ; ALL-NEXT: [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]] to i32*
24 ; ALL-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
25 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
26 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
27 ; ALL-NEXT: ret i32 [[RES]]
30 %obj = call i8* @get_ptr.i8()
31 br i1 %cond, label %bb1, label %bb2
34 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
35 %ptr1.typed = bitcast i8* %ptr1 to i32*
36 %res1 = load i32, i32* %ptr1.typed
40 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
41 %ptr2.typed = bitcast i8* %ptr2 to i32*
42 %res2 = load i32, i32* %ptr2.typed
46 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
47 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
48 store i32 1, i32* %ptr.typed
49 %res.load = load i32, i32* %ptr.typed
50 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
54 define i32 @test_gep_and_bitcast_arg(i8* %obj, i1 %cond, i1 %cond2) {
55 ; ALL-LABEL: @test_gep_and_bitcast_arg(
57 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
59 ; ALL-NEXT: br label [[EXIT:%.*]]
61 ; ALL-NEXT: br label [[EXIT]]
63 ; ALL-NEXT: [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8, i8* [[OBJ:%.*]], i64 16
64 ; ALL-NEXT: [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]] to i32*
65 ; ALL-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
66 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
67 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
68 ; ALL-NEXT: ret i32 [[RES]]
71 br i1 %cond, label %bb1, label %bb2
74 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
75 %ptr1.typed = bitcast i8* %ptr1 to i32*
76 %res1 = load i32, i32* %ptr1.typed
80 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
81 %ptr2.typed = bitcast i8* %ptr2 to i32*
82 %res2 = load i32, i32* %ptr2.typed
86 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
87 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
88 store i32 1, i32* %ptr.typed
89 %res.load = load i32, i32* %ptr.typed
90 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
94 define i32 @test_gep_and_bitcast_phi(i1 %cond, i1 %cond2, i1 %cond3) {
95 ; ALL-LABEL: @test_gep_and_bitcast_phi(
97 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
99 ; ALL-NEXT: [[OBJ1:%.*]] = call i8* @get_ptr.i8()
100 ; ALL-NEXT: br label [[MERGE:%.*]]
102 ; ALL-NEXT: [[OBJ2_TYPED:%.*]] = call i32* @get_ptr.i32()
103 ; ALL-NEXT: [[OBJ2:%.*]] = bitcast i32* [[OBJ2_TYPED]] to i8*
104 ; ALL-NEXT: br label [[MERGE]]
106 ; ALL-NEXT: [[OBJ:%.*]] = phi i8* [ [[OBJ1]], [[BB1]] ], [ [[OBJ2]], [[BB2]] ]
107 ; ALL-NEXT: [[ANOTHER_PHI:%.*]] = phi i8* [ [[OBJ1]], [[BB1]] ], [ null, [[BB2]] ]
108 ; ALL-NEXT: call void @foo.i8(i8* [[ANOTHER_PHI]])
109 ; ALL-NEXT: br i1 [[COND2:%.*]], label [[BB3:%.*]], label [[BB4:%.*]]
111 ; ALL-NEXT: br label [[EXIT:%.*]]
113 ; ALL-NEXT: br label [[EXIT]]
115 ; ALL-NEXT: [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
116 ; ALL-NEXT: [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]] to i32*
117 ; ALL-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
118 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
119 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND3:%.*]], i32 [[RES_PHI]], i32 1
120 ; ALL-NEXT: ret i32 [[RES]]
123 br i1 %cond, label %bb1, label %bb2
126 %obj1 = call i8* @get_ptr.i8()
130 %obj2.typed = call i32* @get_ptr.i32()
131 %obj2 = bitcast i32* %obj2.typed to i8*
135 %obj = phi i8* [ %obj1, %bb1 ], [ %obj2, %bb2 ]
136 %another_phi = phi i8* [ %obj1, %bb1 ], [ null, %bb2 ]
137 call void @foo.i8(i8* %another_phi)
138 br i1 %cond2, label %bb3, label %bb4
141 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
142 %ptr1.typed = bitcast i8* %ptr1 to i32*
143 %res1 = load i32, i32* %ptr1.typed
147 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
148 %ptr2.typed = bitcast i8* %ptr2 to i32*
149 %res2 = load i32, i32* %ptr2.typed
153 %ptr.typed = phi i32* [ %ptr1.typed, %bb3 ], [ %ptr2.typed, %bb4 ]
154 %res.phi = phi i32 [ %res1, %bb3 ], [ %res2, %bb4 ]
155 store i32 1, i32* %ptr.typed
156 %res.load = load i32, i32* %ptr.typed
157 %res = select i1 %cond3, i32 %res.phi, i32 %res.load
161 define i32 @test_gep_i32ptr(i1 %cond, i1 %cond2) {
162 ; ALL-LABEL: @test_gep_i32ptr(
164 ; ALL-NEXT: [[OBJ:%.*]] = call i32* @get_ptr.i32()
165 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
167 ; ALL-NEXT: br label [[EXIT:%.*]]
169 ; ALL-NEXT: br label [[EXIT]]
171 ; ALL-NEXT: [[PTR_TYPED:%.*]] = getelementptr inbounds i32, i32* [[OBJ]], i64 16
172 ; ALL-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
173 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
174 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
175 ; ALL-NEXT: ret i32 [[RES]]
178 %obj = call i32* @get_ptr.i32()
179 br i1 %cond, label %bb1, label %bb2
182 %ptr1.typed = getelementptr inbounds i32, i32* %obj, i64 16
183 %res1 = load i32, i32* %ptr1.typed
187 %ptr2.typed = getelementptr inbounds i32, i32* %obj, i64 16
188 %res2 = load i32, i32* %ptr2.typed
192 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
193 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
194 store i32 1, i32* %ptr.typed
195 %res.load = load i32, i32* %ptr.typed
196 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
200 define i32 @test_gep_and_bitcast_gep_base_ptr(i1 %cond, i1 %cond2) {
201 ; ALL-LABEL: @test_gep_and_bitcast_gep_base_ptr(
203 ; ALL-NEXT: [[OBJ0:%.*]] = call i8* @get_ptr.i8()
204 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
206 ; ALL-NEXT: br label [[EXIT:%.*]]
208 ; ALL-NEXT: br label [[EXIT]]
210 ; ALL-NEXT: [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8, i8* [[OBJ0]], i64 32
211 ; ALL-NEXT: [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]] to i32*
212 ; ALL-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
213 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
214 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
215 ; ALL-NEXT: ret i32 [[RES]]
218 %obj0 = call i8* @get_ptr.i8()
219 %obj = getelementptr inbounds i8, i8* %obj0, i64 16
220 br i1 %cond, label %bb1, label %bb2
223 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
224 %ptr1.typed = bitcast i8* %ptr1 to i32*
225 %res1 = load i32, i32* %ptr1.typed
229 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
230 %ptr2.typed = bitcast i8* %ptr2 to i32*
231 %res2 = load i32, i32* %ptr2.typed
235 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
236 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
237 store i32 1, i32* %ptr.typed
238 %res.load = load i32, i32* %ptr.typed
239 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
243 define i32 @test_gep_and_bitcast_same_bb(i1 %cond, i1 %cond2) {
244 ; ALL-LABEL: @test_gep_and_bitcast_same_bb(
246 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
247 ; ALL-NEXT: br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
249 ; ALL-NEXT: br label [[EXIT]]
251 ; ALL-NEXT: [[PTR_TYPED_IN:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
252 ; ALL-NEXT: [[PTR_TYPED:%.*]] = bitcast i8* [[PTR_TYPED_IN]] to i32*
253 ; ALL-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
254 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
255 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
256 ; ALL-NEXT: ret i32 [[RES]]
259 %obj = call i8* @get_ptr.i8()
260 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
261 %ptr1.typed = bitcast i8* %ptr1 to i32*
262 %res1 = load i32, i32* %ptr1.typed
263 br i1 %cond, label %exit, label %bb2
266 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
267 %ptr2.typed = bitcast i8* %ptr2 to i32*
268 %res2 = load i32, i32* %ptr2.typed
272 %ptr.typed = phi i32* [ %ptr1.typed, %entry ], [ %ptr2.typed, %bb2 ]
273 %res.phi = phi i32 [ %res1, %entry ], [ %res2, %bb2 ]
274 store i32 1, i32* %ptr.typed
275 %res.load = load i32, i32* %ptr.typed
276 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
280 define i32 @test_gep_and_bitcast_same_bb_and_extra_use(i1 %cond, i1 %cond2) {
281 ; INSTCOMBINE-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(
282 ; INSTCOMBINE-NEXT: entry:
283 ; INSTCOMBINE-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
284 ; INSTCOMBINE-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
285 ; INSTCOMBINE-NEXT: [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
286 ; INSTCOMBINE-NEXT: call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
287 ; INSTCOMBINE-NEXT: br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
289 ; INSTCOMBINE-NEXT: [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
290 ; INSTCOMBINE-NEXT: [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
291 ; INSTCOMBINE-NEXT: br label [[EXIT]]
293 ; INSTCOMBINE-NEXT: [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[ENTRY:%.*]] ], [ [[PTR2_TYPED]], [[BB2]] ]
294 ; INSTCOMBINE-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR_TYPED]], align 4
295 ; INSTCOMBINE-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
296 ; INSTCOMBINE-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
297 ; INSTCOMBINE-NEXT: ret i32 [[RES]]
299 ; INSTCOMBINEGVN-LABEL: @test_gep_and_bitcast_same_bb_and_extra_use(
300 ; INSTCOMBINEGVN-NEXT: entry:
301 ; INSTCOMBINEGVN-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
302 ; INSTCOMBINEGVN-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
303 ; INSTCOMBINEGVN-NEXT: [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
304 ; INSTCOMBINEGVN-NEXT: call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
305 ; INSTCOMBINEGVN-NEXT: br i1 [[COND:%.*]], label [[EXIT:%.*]], label [[BB2:%.*]]
306 ; INSTCOMBINEGVN: bb2:
307 ; INSTCOMBINEGVN-NEXT: br label [[EXIT]]
308 ; INSTCOMBINEGVN: exit:
309 ; INSTCOMBINEGVN-NEXT: [[RES_PHI:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
310 ; INSTCOMBINEGVN-NEXT: store i32 1, i32* [[PTR1_TYPED]], align 4
311 ; INSTCOMBINEGVN-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
312 ; INSTCOMBINEGVN-NEXT: ret i32 [[RES]]
315 %obj = call i8* @get_ptr.i8()
316 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
317 %ptr1.typed = bitcast i8* %ptr1 to i32*
318 call void @foo.i32(i32* %ptr1.typed)
319 %res1 = load i32, i32* %ptr1.typed
320 br i1 %cond, label %exit, label %bb2
323 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
324 %ptr2.typed = bitcast i8* %ptr2 to i32*
325 %res2 = load i32, i32* %ptr2.typed
329 %ptr.typed = phi i32* [ %ptr1.typed, %entry ], [ %ptr2.typed, %bb2 ]
330 %res.phi = phi i32 [ %res1, %entry ], [ %res2, %bb2 ]
331 store i32 1, i32* %ptr.typed
332 %res.load = load i32, i32* %ptr.typed
333 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
337 define i8 @test_gep(i1 %cond, i1 %cond2) {
338 ; ALL-LABEL: @test_gep(
340 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
341 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
343 ; ALL-NEXT: br label [[EXIT:%.*]]
345 ; ALL-NEXT: br label [[EXIT]]
347 ; ALL-NEXT: [[PTR_TYPED:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
348 ; ALL-NEXT: [[RES_PHI:%.*]] = load i8, i8* [[PTR_TYPED]], align 1
349 ; ALL-NEXT: store i8 1, i8* [[PTR_TYPED]], align 1
350 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i8 [[RES_PHI]], i8 1
351 ; ALL-NEXT: ret i8 [[RES]]
354 %obj = call i8* @get_ptr.i8()
355 br i1 %cond, label %bb1, label %bb2
358 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
359 %res1 = load i8, i8* %ptr1
363 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
364 %res2 = load i8, i8* %ptr2
368 %ptr.typed = phi i8* [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]
369 %res.phi = phi i8 [ %res1, %bb1 ], [ %res2, %bb2 ]
370 store i8 1, i8* %ptr.typed
371 %res.load = load i8, i8* %ptr.typed
372 %res = select i1 %cond2, i8 %res.phi, i8 %res.load
376 define i32 @test_extra_uses(i1 %cond, i1 %cond2) {
377 ; ALL-LABEL: @test_extra_uses(
379 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
380 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
382 ; ALL-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
383 ; ALL-NEXT: [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
384 ; ALL-NEXT: [[RES1:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
385 ; ALL-NEXT: call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
386 ; ALL-NEXT: br label [[EXIT:%.*]]
388 ; ALL-NEXT: [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
389 ; ALL-NEXT: [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
390 ; ALL-NEXT: [[RES2:%.*]] = load i32, i32* [[PTR2_TYPED]], align 4
391 ; ALL-NEXT: call void @foo.i32(i32* nonnull [[PTR2_TYPED]])
392 ; ALL-NEXT: br label [[EXIT]]
394 ; ALL-NEXT: [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
395 ; ALL-NEXT: [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
396 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
397 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
398 ; ALL-NEXT: ret i32 [[RES]]
401 %obj = call i8* @get_ptr.i8()
402 br i1 %cond, label %bb1, label %bb2
405 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
406 %ptr1.typed = bitcast i8* %ptr1 to i32*
407 %res1 = load i32, i32* %ptr1.typed
408 call void @foo.i32(i32* %ptr1.typed)
412 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
413 %ptr2.typed = bitcast i8* %ptr2 to i32*
414 %res2 = load i32, i32* %ptr2.typed
415 call void @foo.i32(i32* %ptr2.typed)
419 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
420 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
421 store i32 1, i32* %ptr.typed
422 %res.load = load i32, i32* %ptr.typed
423 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
427 define i32 @test_extra_uses_non_inbounds(i1 %cond, i1 %cond2) {
428 ; ALL-LABEL: @test_extra_uses_non_inbounds(
430 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
431 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
433 ; ALL-NEXT: [[PTR1:%.*]] = getelementptr i8, i8* [[OBJ]], i64 16
434 ; ALL-NEXT: [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
435 ; ALL-NEXT: [[RES1:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
436 ; ALL-NEXT: call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
437 ; ALL-NEXT: br label [[EXIT:%.*]]
439 ; ALL-NEXT: [[PTR2:%.*]] = getelementptr i8, i8* [[OBJ]], i64 16
440 ; ALL-NEXT: [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2]] to i32*
441 ; ALL-NEXT: [[RES2:%.*]] = load i32, i32* [[PTR2_TYPED]], align 4
442 ; ALL-NEXT: call void @foo.i32(i32* nonnull [[PTR2_TYPED]])
443 ; ALL-NEXT: br label [[EXIT]]
445 ; ALL-NEXT: [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
446 ; ALL-NEXT: [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
447 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
448 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
449 ; ALL-NEXT: ret i32 [[RES]]
452 %obj = call i8* @get_ptr.i8()
453 br i1 %cond, label %bb1, label %bb2
456 %ptr1 = getelementptr i8, i8* %obj, i64 16
457 %ptr1.typed = bitcast i8* %ptr1 to i32*
458 %res1 = load i32, i32* %ptr1.typed
459 call void @foo.i32(i32* %ptr1.typed)
463 %ptr2 = getelementptr i8, i8* %obj, i64 16
464 %ptr2.typed = bitcast i8* %ptr2 to i32*
465 %res2 = load i32, i32* %ptr2.typed
466 call void @foo.i32(i32* %ptr2.typed)
470 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
471 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
472 store i32 1, i32* %ptr.typed
473 %res.load = load i32, i32* %ptr.typed
474 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
478 define i32 @test_extra_uses_multiple_geps(i1 %cond, i1 %cond2) {
479 ; ALL-LABEL: @test_extra_uses_multiple_geps(
481 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
482 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
484 ; ALL-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
485 ; ALL-NEXT: [[PTR1_TYPED:%.*]] = bitcast i8* [[PTR1]] to i32*
486 ; ALL-NEXT: [[RES1:%.*]] = load i32, i32* [[PTR1_TYPED]], align 4
487 ; ALL-NEXT: call void @foo.i32(i32* nonnull [[PTR1_TYPED]])
488 ; ALL-NEXT: br label [[EXIT:%.*]]
490 ; ALL-NEXT: [[PTR2_1:%.*]] = getelementptr i8, i8* [[OBJ]], i64 16
491 ; ALL-NEXT: [[PTR2_TYPED:%.*]] = bitcast i8* [[PTR2_1]] to i32*
492 ; ALL-NEXT: [[RES2:%.*]] = load i32, i32* [[PTR2_TYPED]], align 4
493 ; ALL-NEXT: call void @foo.i32(i32* nonnull [[PTR2_TYPED]])
494 ; ALL-NEXT: br label [[EXIT]]
496 ; ALL-NEXT: [[PTR_TYPED:%.*]] = phi i32* [ [[PTR1_TYPED]], [[BB1]] ], [ [[PTR2_TYPED]], [[BB2]] ]
497 ; ALL-NEXT: [[RES_PHI:%.*]] = phi i32 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
498 ; ALL-NEXT: store i32 1, i32* [[PTR_TYPED]], align 4
499 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i32 [[RES_PHI]], i32 1
500 ; ALL-NEXT: ret i32 [[RES]]
503 %obj = call i8* @get_ptr.i8()
504 br i1 %cond, label %bb1, label %bb2
507 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
508 %ptr1.typed = bitcast i8* %ptr1 to i32*
509 %res1 = load i32, i32* %ptr1.typed
510 call void @foo.i32(i32* %ptr1.typed)
514 %ptr2.0 = getelementptr i8, i8* %obj, i64 8
515 %ptr2.1 = getelementptr inbounds i8, i8* %ptr2.0, i64 8
516 %ptr2.typed = bitcast i8* %ptr2.1 to i32*
517 %res2 = load i32, i32* %ptr2.typed
518 call void @foo.i32(i32* %ptr2.typed)
522 %ptr.typed = phi i32* [ %ptr1.typed, %bb1 ], [ %ptr2.typed, %bb2 ]
523 %res.phi = phi i32 [ %res1, %bb1 ], [ %res2, %bb2 ]
524 store i32 1, i32* %ptr.typed
525 %res.load = load i32, i32* %ptr.typed
526 %res = select i1 %cond2, i32 %res.phi, i32 %res.load
530 define i8 @test_gep_extra_uses(i1 %cond, i1 %cond2) {
531 ; ALL-LABEL: @test_gep_extra_uses(
533 ; ALL-NEXT: [[OBJ:%.*]] = call i8* @get_ptr.i8()
534 ; ALL-NEXT: br i1 [[COND:%.*]], label [[BB1:%.*]], label [[BB2:%.*]]
536 ; ALL-NEXT: [[PTR1:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
537 ; ALL-NEXT: [[RES1:%.*]] = load i8, i8* [[PTR1]], align 1
538 ; ALL-NEXT: call void @foo.i8(i8* nonnull [[PTR1]])
539 ; ALL-NEXT: br label [[EXIT:%.*]]
541 ; ALL-NEXT: [[PTR2:%.*]] = getelementptr inbounds i8, i8* [[OBJ]], i64 16
542 ; ALL-NEXT: [[RES2:%.*]] = load i8, i8* [[PTR2]], align 1
543 ; ALL-NEXT: call void @foo.i8(i8* nonnull [[PTR2]])
544 ; ALL-NEXT: br label [[EXIT]]
546 ; ALL-NEXT: [[PTR_TYPED:%.*]] = phi i8* [ [[PTR1]], [[BB1]] ], [ [[PTR2]], [[BB2]] ]
547 ; ALL-NEXT: [[RES_PHI:%.*]] = phi i8 [ [[RES1]], [[BB1]] ], [ [[RES2]], [[BB2]] ]
548 ; ALL-NEXT: store i8 1, i8* [[PTR_TYPED]], align 1
549 ; ALL-NEXT: [[RES:%.*]] = select i1 [[COND2:%.*]], i8 [[RES_PHI]], i8 1
550 ; ALL-NEXT: ret i8 [[RES]]
553 %obj = call i8* @get_ptr.i8()
554 br i1 %cond, label %bb1, label %bb2
557 %ptr1 = getelementptr inbounds i8, i8* %obj, i64 16
558 %res1 = load i8, i8* %ptr1
559 call void @foo.i8(i8* %ptr1)
563 %ptr2 = getelementptr inbounds i8, i8* %obj, i64 16
564 %res2 = load i8, i8* %ptr2
565 call void @foo.i8(i8* %ptr2)
569 %ptr.typed = phi i8* [ %ptr1, %bb1 ], [ %ptr2, %bb2 ]
570 %res.phi = phi i8 [ %res1, %bb1 ], [ %res2, %bb2 ]
571 store i8 1, i8* %ptr.typed
572 %res.load = load i8, i8* %ptr.typed
573 %res = select i1 %cond2, i8 %res.phi, i8 %res.load