2 ; RUN: opt < %s -newgvn -S | FileCheck %s
4 %struct.A = type { i32 (...)** }
5 @_ZTV1A = available_externally unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast (i8** @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A3fooEv to i8*)], align 8
6 @_ZTI1A = external constant i8*
8 @unknownPtr = external global i8
10 ; CHECK-LABEL: define i8 @simple() {
14 store i8 42, i8* %ptr, !invariant.group !0
15 call void @foo(i8* %ptr)
17 %a = load i8, i8* %ptr, !invariant.group !0
18 %b = load i8, i8* %ptr, !invariant.group !0
19 %c = load i8, i8* %ptr, !invariant.group !0
24 ; CHECK-LABEL: define i8 @optimizable1() {
25 define i8 @optimizable1() {
28 store i8 42, i8* %ptr, !invariant.group !0
29 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
30 %a = load i8, i8* %ptr, !invariant.group !0
32 call void @foo(i8* %ptr2); call to use %ptr2
37 ; CHECK-LABEL: define i8 @optimizable2() {
38 define i8 @optimizable2() {
41 store i8 42, i8* %ptr, !invariant.group !0
42 call void @foo(i8* %ptr)
44 store i8 13, i8* %ptr ; can't use this store with invariant.group
45 %a = load i8, i8* %ptr
46 call void @bar(i8 %a) ; call to use %a
48 call void @foo(i8* %ptr)
49 %b = load i8, i8* %ptr, !invariant.group !0
55 ; CHECK-LABEL: define i1 @proveEqualityForStrip(
56 define i1 @proveEqualityForStrip(i8* %a) {
57 ; FIXME: The first call could be also removed by GVN. Right now
58 ; DCE removes it. The second call is CSE'd with the first one.
59 ; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
60 %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
61 ; CHECK-NOT: llvm.strip.invariant.group
62 %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
63 %r = icmp eq i8* %b1, %b2
68 ; CHECK-LABEL: define i8 @unoptimizable1() {
69 define i8 @unoptimizable1() {
73 call void @foo(i8* %ptr)
74 %a = load i8, i8* %ptr, !invariant.group !0
79 ; CHECK-LABEL: define void @indirectLoads() {
80 define void @indirectLoads() {
82 %a = alloca %struct.A*, align 8
83 %0 = bitcast %struct.A** %a to i8*
85 %call = call i8* @getPointer(i8* null)
86 %1 = bitcast i8* %call to %struct.A*
87 call void @_ZN1AC1Ev(%struct.A* %1)
88 %2 = bitcast %struct.A* %1 to i8***
90 ; CHECK: %vtable = load {{.*}} !invariant.group
91 %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
92 %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
93 call void @llvm.assume(i1 %cmp.vtables)
95 store %struct.A* %1, %struct.A** %a, align 8
96 %3 = load %struct.A*, %struct.A** %a, align 8
97 %4 = bitcast %struct.A* %3 to void (%struct.A*)***
99 ; CHECK: call void @_ZN1A3fooEv(
100 %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
101 %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
102 %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
103 call void %5(%struct.A* %3)
104 %6 = load %struct.A*, %struct.A** %a, align 8
105 %7 = bitcast %struct.A* %6 to void (%struct.A*)***
107 ; CHECK: call void @_ZN1A3fooEv(
108 %vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !0
109 %vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
110 %8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8
112 call void %8(%struct.A* %6)
113 %9 = load %struct.A*, %struct.A** %a, align 8
114 %10 = bitcast %struct.A* %9 to void (%struct.A*)***
116 %vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !0
117 %vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
118 %11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
119 ; CHECK: call void @_ZN1A3fooEv(
120 call void %11(%struct.A* %9)
122 %vtable5 = load i8**, i8*** %2, align 8, !invariant.group !0
123 %vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
124 %12 = bitcast i8** %vfn6 to void (%struct.A*)**
125 %13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
126 ; CHECK: call void @_ZN1A3fooEv(
127 call void %13(%struct.A* %9)
132 ; CHECK-LABEL: define void @combiningBitCastWithLoad() {
133 define void @combiningBitCastWithLoad() {
135 %a = alloca %struct.A*, align 8
136 %0 = bitcast %struct.A** %a to i8*
138 %call = call i8* @getPointer(i8* null)
139 %1 = bitcast i8* %call to %struct.A*
140 call void @_ZN1AC1Ev(%struct.A* %1)
141 %2 = bitcast %struct.A* %1 to i8***
143 ; CHECK: %vtable = load {{.*}} !invariant.group
144 %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
145 %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
147 store %struct.A* %1, %struct.A** %a, align 8
148 ; CHECK-NOT: !invariant.group
149 %3 = load %struct.A*, %struct.A** %a, align 8
150 %4 = bitcast %struct.A* %3 to void (%struct.A*)***
152 %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
153 %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
154 %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
155 call void %5(%struct.A* %3)
160 ; CHECK-LABEL:define void @loadCombine() {
161 define void @loadCombine() {
164 store i8 42, i8* %ptr
165 call void @foo(i8* %ptr)
166 ; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
167 %a = load i8, i8* %ptr, !invariant.group !0
169 %b = load i8, i8* %ptr, !invariant.group !0
170 ; CHECK: call void @bar(i8 %[[A]])
171 call void @bar(i8 %a)
172 ; CHECK: call void @bar(i8 %[[A]])
173 call void @bar(i8 %b)
177 ; CHECK-LABEL: define void @loadCombine1() {
178 define void @loadCombine1() {
181 store i8 42, i8* %ptr
182 call void @foo(i8* %ptr)
183 ; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
184 %c = load i8, i8* %ptr
186 %d = load i8, i8* %ptr, !invariant.group !0
187 ; CHECK: call void @bar(i8 %[[D]])
188 call void @bar(i8 %c)
189 ; CHECK: call void @bar(i8 %[[D]])
190 call void @bar(i8 %d)
194 ; CHECK-LABEL: define void @loadCombine2() {
195 define void @loadCombine2() {
198 store i8 42, i8* %ptr
199 call void @foo(i8* %ptr)
200 ; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
201 %e = load i8, i8* %ptr, !invariant.group !0
203 %f = load i8, i8* %ptr
204 ; CHECK: call void @bar(i8 %[[E]])
205 call void @bar(i8 %e)
206 ; CHECK: call void @bar(i8 %[[E]])
207 call void @bar(i8 %f)
211 ; CHECK-LABEL: define void @loadCombine3() {
212 define void @loadCombine3() {
215 store i8 42, i8* %ptr
216 call void @foo(i8* %ptr)
217 ; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
218 %e = load i8, i8* %ptr, !invariant.group !0
220 %f = load i8, i8* %ptr, !invariant.group !0
221 ; CHECK: call void @bar(i8 %[[E]])
222 call void @bar(i8 %e)
223 ; CHECK: call void @bar(i8 %[[E]])
224 call void @bar(i8 %f)
228 ; CHECK-LABEL: define i8 @unoptimizable2() {
229 define i8 @unoptimizable2() {
232 store i8 42, i8* %ptr
233 call void @foo(i8* %ptr)
234 %a = load i8, i8* %ptr
235 call void @foo(i8* %ptr)
236 %b = load i8, i8* %ptr, !invariant.group !0
242 ; CHECK-LABEL: define i8 @unoptimizable3() {
243 define i8 @unoptimizable3() {
246 store i8 42, i8* %ptr, !invariant.group !0
247 %ptr2 = call i8* @getPointer(i8* %ptr)
248 %a = load i8, i8* %ptr2, !invariant.group !0
254 ; CHECK-LABEL: define i8 @optimizable4() {
255 define i8 @optimizable4() {
258 store i8 42, i8* %ptr, !invariant.group !0
259 %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
261 %a = load i8, i8* %ptr2, !invariant.group !0
267 ; CHECK-LABEL: define i8 @volatile1() {
268 define i8 @volatile1() {
271 store i8 42, i8* %ptr, !invariant.group !0
272 call void @foo(i8* %ptr)
273 %a = load i8, i8* %ptr, !invariant.group !0
274 %b = load volatile i8, i8* %ptr
275 ; CHECK: call void @bar(i8 %b)
276 call void @bar(i8 %b)
278 %c = load volatile i8, i8* %ptr, !invariant.group !0
279 ; FIXME: we could change %c to 42, preserving volatile load
280 ; CHECK: call void @bar(i8 %c)
281 call void @bar(i8 %c)
286 ; CHECK-LABEL: define i8 @volatile2() {
287 define i8 @volatile2() {
290 store i8 42, i8* %ptr, !invariant.group !0
291 call void @foo(i8* %ptr)
292 %a = load i8, i8* %ptr, !invariant.group !0
293 %b = load volatile i8, i8* %ptr
294 ; CHECK: call void @bar(i8 %b)
295 call void @bar(i8 %b)
297 %c = load volatile i8, i8* %ptr, !invariant.group !0
298 ; FIXME: we could change %c to 42, preserving volatile load
299 ; CHECK: call void @bar(i8 %c)
300 call void @bar(i8 %c)
305 ; CHECK-LABEL: define i8 @fun() {
309 store i8 42, i8* %ptr, !invariant.group !0
310 call void @foo(i8* %ptr)
312 %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
313 ; CHECK: call void @bar(i8 42)
314 call void @bar(i8 %a)
316 %newPtr = call i8* @getPointer(i8* %ptr)
317 %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
318 ; CHECK: call void @bar(i8 %c)
319 call void @bar(i8 %c)
321 %unknownValue = load i8, i8* @unknownPtr
322 ; FIXME: Can assume that %unknownValue == 42
323 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
324 store i8 %unknownValue, i8* %ptr, !invariant.group !0
326 %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
328 %d = load i8, i8* %newPtr2, !invariant.group !0
329 ; CHECK: ret i8 %unknownValue
333 ; This test checks if invariant.group understands gep with zeros
334 ; CHECK-LABEL: define void @testGEP0() {
335 define void @testGEP0() {
336 %a = alloca %struct.A, align 8
337 %1 = bitcast %struct.A* %a to i8*
338 %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
339 store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !invariant.group !0
340 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a)
341 call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a) ; This call may change vptr
342 %3 = load i8, i8* @unknownPtr, align 4
343 %4 = icmp eq i8 %3, 0
344 br i1 %4, label %_Z1gR1A.exit, label %5
346 ; This should be devirtualized by invariant.group
347 %6 = bitcast %struct.A* %a to void (%struct.A*)***
348 %7 = load void (%struct.A*)**, void (%struct.A*)*** %6, align 8, !invariant.group !0
349 %8 = load void (%struct.A*)*, void (%struct.A*)** %7, align 8
350 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
351 call void %8(%struct.A* nonnull %a)
352 br label %_Z1gR1A.exit
354 _Z1gR1A.exit: ; preds = %0, %5
358 ; Check if no optimizations are performed with global pointers.
359 ; FIXME: we could do the optimizations if we would check if dependency comes
360 ; from the same function.
361 ; CHECK-LABEL: define void @testGlobal() {
362 define void @testGlobal() {
363 ; CHECK: %a = load i8, i8* @unknownPtr, !invariant.group !0
364 %a = load i8, i8* @unknownPtr, !invariant.group !0
365 call void @foo2(i8* @unknownPtr, i8 %a)
366 ; CHECK: %1 = load i8, i8* @unknownPtr, !invariant.group !0
367 %1 = load i8, i8* @unknownPtr, !invariant.group !0
368 call void @bar(i8 %1)
370 %b0 = bitcast i8* @unknownPtr to i1*
371 call void @fooBit(i1* %b0, i1 1)
372 ; Adding regex because of canonicalization of bitcasts
373 ; CHECK: %2 = load i1, i1* {{.*}}, !invariant.group !0
374 %2 = load i1, i1* %b0, !invariant.group !0
375 call void @fooBit(i1* %b0, i1 %2)
376 ; CHECK: %3 = load i1, i1* {{.*}}, !invariant.group !0
377 %3 = load i1, i1* %b0, !invariant.group !0
378 call void @fooBit(i1* %b0, i1 %3)
381 ; And in the case it is not global
382 ; CHECK-LABEL: define void @testNotGlobal() {
383 define void @testNotGlobal() {
385 call void @foo(i8* %a)
386 ; CHECK: %b = load i8, i8* %a, !invariant.group !0
387 %b = load i8, i8* %a, !invariant.group !0
388 call void @foo2(i8* %a, i8 %b)
390 %1 = load i8, i8* %a, !invariant.group !0
391 ; CHECK: call void @bar(i8 %b)
392 call void @bar(i8 %1)
394 %b0 = bitcast i8* %a to i1*
395 call void @fooBit(i1* %b0, i1 1)
396 ; CHECK: %1 = trunc i8 %b to i1
397 %2 = load i1, i1* %b0, !invariant.group !0
398 ; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
399 call void @fooBit(i1* %b0, i1 %2)
400 %3 = load i1, i1* %b0, !invariant.group !0
401 ; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
402 call void @fooBit(i1* %b0, i1 %3)
406 ; CHECK-LABEL: define void @handling_loops()
407 define void @handling_loops() {
408 %a = alloca %struct.A, align 8
409 %1 = bitcast %struct.A* %a to i8*
410 %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
411 store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !invariant.group !0
412 %3 = load i8, i8* @unknownPtr, align 4
413 %4 = icmp sgt i8 %3, 0
414 br i1 %4, label %.lr.ph.i, label %_Z2g2R1A.exit
416 .lr.ph.i: ; preds = %0
417 %5 = bitcast %struct.A* %a to void (%struct.A*)***
418 %6 = load i8, i8* @unknownPtr, align 4
419 %7 = icmp sgt i8 %6, 1
420 br i1 %7, label %._crit_edge.preheader, label %_Z2g2R1A.exit
422 ._crit_edge.preheader: ; preds = %.lr.ph.i
423 br label %._crit_edge
425 ._crit_edge: ; preds = %._crit_edge.preheader, %._crit_edge
426 %8 = phi i8 [ %10, %._crit_edge ], [ 1, %._crit_edge.preheader ]
427 %.pre = load void (%struct.A*)**, void (%struct.A*)*** %5, align 8, !invariant.group !0
428 %9 = load void (%struct.A*)*, void (%struct.A*)** %.pre, align 8
429 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
430 call void %9(%struct.A* nonnull %a) #3
431 ; CHECK-NOT: call void %
432 %10 = add nuw nsw i8 %8, 1
433 %11 = load i8, i8* @unknownPtr, align 4
434 %12 = icmp slt i8 %10, %11
435 br i1 %12, label %._crit_edge, label %_Z2g2R1A.exit.loopexit
437 _Z2g2R1A.exit.loopexit: ; preds = %._crit_edge
438 br label %_Z2g2R1A.exit
440 _Z2g2R1A.exit: ; preds = %_Z2g2R1A.exit.loopexit, %.lr.ph.i, %0
445 declare void @foo(i8*)
446 declare void @foo2(i8*, i8)
447 declare void @bar(i8)
448 declare i8* @getPointer(i8*)
449 declare void @_ZN1A3fooEv(%struct.A*)
450 declare void @_ZN1AC1Ev(%struct.A*)
451 declare void @fooBit(i1*, i1)
453 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
455 ; Function Attrs: nounwind
456 declare void @llvm.assume(i1 %cmp.vtables) #0
459 attributes #0 = { nounwind }