[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / test / Transforms / GVN / invariant.group.ll
blob6cdd44d16c0667ed3084457d83de520e9c7bacba
1 ; RUN: opt < %s -gvn -S | FileCheck %s
3 %struct.A = type { i32 (...)** }
4 @_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
5 @_ZTI1A = external constant i8*
7 @unknownPtr = external global i8
9 ; CHECK-LABEL: define i8 @simple() {
10 define i8 @simple() {
11 entry:
12     %ptr = alloca i8
13     store i8 42, i8* %ptr, !invariant.group !0
14     call void @foo(i8* %ptr)
16     %a = load i8, i8* %ptr, !invariant.group !0
17     %b = load i8, i8* %ptr, !invariant.group !0
18     %c = load i8, i8* %ptr, !invariant.group !0
19 ; CHECK: ret i8 42
20     ret i8 %a
23 ; CHECK-LABEL: define i8 @optimizable1() {
24 define i8 @optimizable1() {
25 entry:
26     %ptr = alloca i8
27     store i8 42, i8* %ptr, !invariant.group !0
28     %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
29     %a = load i8, i8* %ptr, !invariant.group !0
30     
31     call void @foo(i8* %ptr2); call to use %ptr2
32 ; CHECK: ret i8 42
33     ret i8 %a
36 ; CHECK-LABEL: define i8 @optimizable2() {
37 define i8 @optimizable2() {
38 entry:
39     %ptr = alloca i8
40     store i8 42, i8* %ptr, !invariant.group !0
41     call void @foo(i8* %ptr)
42     
43     store i8 13, i8* %ptr ; can't use this store with invariant.group
44     %a = load i8, i8* %ptr 
45     call void @bar(i8 %a) ; call to use %a
46     
47     call void @foo(i8* %ptr)
48     %b = load i8, i8* %ptr, !invariant.group !0
49     
50 ; CHECK: ret i8 42
51     ret i8 %b
54 ; CHECK-LABEL: define i1 @proveEqualityForStrip(
55 define i1 @proveEqualityForStrip(i8* %a) {
56 ; FIXME: The first call could be also removed by GVN. Right now
57 ; DCE removes it. The second call is CSE'd with the first one.
58 ; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
59   %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
60 ; CHECK-NOT: llvm.strip.invariant.group
61   %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
62   %r = icmp eq i8* %b1, %b2
63 ; CHECK: ret i1 true
64   ret i1 %r
66 ; CHECK-LABEL: define i8 @unoptimizable1() {
67 define i8 @unoptimizable1() {
68 entry:
69     %ptr = alloca i8
70     store i8 42, i8* %ptr
71     call void @foo(i8* %ptr)
72     %a = load i8, i8* %ptr, !invariant.group !0
73 ; CHECK: ret i8 %a
74     ret i8 %a
77 ; CHECK-LABEL: define void @indirectLoads() {
78 define void @indirectLoads() {
79 entry:
80   %a = alloca %struct.A*, align 8
81   %0 = bitcast %struct.A** %a to i8*
82   
83   %call = call i8* @getPointer(i8* null) 
84   %1 = bitcast i8* %call to %struct.A*
85   call void @_ZN1AC1Ev(%struct.A* %1)
86   %2 = bitcast %struct.A* %1 to i8***
87   
88 ; CHECK: %vtable = load {{.*}} !invariant.group
89   %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
90   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
91   call void @llvm.assume(i1 %cmp.vtables)
92   
93   store %struct.A* %1, %struct.A** %a, align 8
94   %3 = load %struct.A*, %struct.A** %a, align 8
95   %4 = bitcast %struct.A* %3 to void (%struct.A*)***
97 ; CHECK: call void @_ZN1A3fooEv(
98   %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
99   %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
100   %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
101   call void %5(%struct.A* %3)
102   %6 = load %struct.A*, %struct.A** %a, align 8
103   %7 = bitcast %struct.A* %6 to void (%struct.A*)***
105 ; CHECK: call void @_ZN1A3fooEv(
106   %vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !0
107   %vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
108   %8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8
109   
110   call void %8(%struct.A* %6)
111   %9 = load %struct.A*, %struct.A** %a, align 8
112   %10 = bitcast %struct.A* %9 to void (%struct.A*)***
113   
114   %vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !0
115   %vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
116   %11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
117 ; CHECK: call void @_ZN1A3fooEv(
118   call void %11(%struct.A* %9)
120   %vtable5 = load i8**, i8*** %2, align 8, !invariant.group !0
121   %vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
122   %12 = bitcast i8** %vfn6 to void (%struct.A*)**
123   %13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
124 ; CHECK: call void @_ZN1A3fooEv(
125   call void %13(%struct.A* %9)
126   
127   ret void
130 ; CHECK-LABEL: define void @combiningBitCastWithLoad() {
131 define void @combiningBitCastWithLoad() {
132 entry:
133   %a = alloca %struct.A*, align 8
134   %0 = bitcast %struct.A** %a to i8*
135   
136   %call = call i8* @getPointer(i8* null) 
137   %1 = bitcast i8* %call to %struct.A*
138   call void @_ZN1AC1Ev(%struct.A* %1)
139   %2 = bitcast %struct.A* %1 to i8***
140   
141 ; CHECK: %vtable = load {{.*}} !invariant.group
142   %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
143   %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
144   
145   store %struct.A* %1, %struct.A** %a, align 8
146 ; CHECK-NOT: !invariant.group
147   %3 = load %struct.A*, %struct.A** %a, align 8
148   %4 = bitcast %struct.A* %3 to void (%struct.A*)***
150   %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
151   %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
152   %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
153   call void %5(%struct.A* %3)
155   ret void
158 ; CHECK-LABEL:define void @loadCombine() {
159 define void @loadCombine() {
160 enter:
161   %ptr = alloca i8
162   store i8 42, i8* %ptr
163   call void @foo(i8* %ptr)
164 ; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
165   %a = load i8, i8* %ptr, !invariant.group !0
166 ; CHECK-NOT: load
167   %b = load i8, i8* %ptr, !invariant.group !0
168 ; CHECK: call void @bar(i8 %[[A]])
169   call void @bar(i8 %a)
170 ; CHECK: call void @bar(i8 %[[A]])
171   call void @bar(i8 %b)
172   ret void
175 ; CHECK-LABEL: define void @loadCombine1() {
176 define void @loadCombine1() {
177 enter:
178   %ptr = alloca i8
179   store i8 42, i8* %ptr
180   call void @foo(i8* %ptr)
181 ; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
182   %c = load i8, i8* %ptr
183 ; CHECK-NOT: load
184   %d = load i8, i8* %ptr, !invariant.group !0
185 ; CHECK: call void @bar(i8 %[[D]])
186   call void @bar(i8 %c)
187 ; CHECK: call void @bar(i8 %[[D]])
188   call void @bar(i8 %d)
189   ret void
192 ; CHECK-LABEL: define void @loadCombine2() {    
193 define void @loadCombine2() {
194 enter:
195   %ptr = alloca i8
196   store i8 42, i8* %ptr
197   call void @foo(i8* %ptr)
198 ; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
199   %e = load i8, i8* %ptr, !invariant.group !0
200 ; CHECK-NOT: load
201   %f = load i8, i8* %ptr
202 ; CHECK: call void @bar(i8 %[[E]])
203   call void @bar(i8 %e)
204 ; CHECK: call void @bar(i8 %[[E]])
205   call void @bar(i8 %f)
206   ret void
209 ; CHECK-LABEL: define void @loadCombine3() {
210 define void @loadCombine3() {
211 enter:
212   %ptr = alloca i8
213   store i8 42, i8* %ptr
214   call void @foo(i8* %ptr)
215 ; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
216   %e = load i8, i8* %ptr, !invariant.group !0
217 ; CHECK-NOT: load
218   %f = load i8, i8* %ptr, !invariant.group !0
219 ; CHECK: call void @bar(i8 %[[E]])
220   call void @bar(i8 %e)
221 ; CHECK: call void @bar(i8 %[[E]])
222   call void @bar(i8 %f)
223   ret void
226 ; CHECK-LABEL: define i8 @unoptimizable2() {
227 define i8 @unoptimizable2() {
228 entry:
229     %ptr = alloca i8
230     store i8 42, i8* %ptr
231     call void @foo(i8* %ptr)
232     %a = load i8, i8* %ptr
233     call void @foo(i8* %ptr)
234     %b = load i8, i8* %ptr, !invariant.group !0
235     
236 ; CHECK: ret i8 %a
237     ret i8 %a
240 ; CHECK-LABEL: define i8 @unoptimizable3() {
241 define i8 @unoptimizable3() {
242 entry:
243     %ptr = alloca i8
244     store i8 42, i8* %ptr, !invariant.group !0
245     %ptr2 = call i8* @getPointer(i8* %ptr)
246     %a = load i8, i8* %ptr2, !invariant.group !0
247     
248 ; CHECK: ret i8 %a
249     ret i8 %a
252 ; CHECK-LABEL: define i8 @optimizable4() {
253 define i8 @optimizable4() {
254 entry:
255     %ptr = alloca i8
256     store i8 42, i8* %ptr, !invariant.group !0
257     %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
258 ; CHECK-NOT: load
259     %a = load i8, i8* %ptr2, !invariant.group !0
260     
261 ; CHECK: ret i8 42
262     ret i8 %a
265 ; CHECK-LABEL: define i8 @volatile1() {
266 define i8 @volatile1() {
267 entry:
268     %ptr = alloca i8
269     store i8 42, i8* %ptr, !invariant.group !0
270     call void @foo(i8* %ptr)
271     %a = load i8, i8* %ptr, !invariant.group !0
272     %b = load volatile i8, i8* %ptr
273 ; CHECK: call void @bar(i8 %b)
274     call void @bar(i8 %b)
276     %c = load volatile i8, i8* %ptr, !invariant.group !0
277 ; FIXME: we could change %c to 42, preserving volatile load
278 ; CHECK: call void @bar(i8 %c)
279     call void @bar(i8 %c)
280 ; CHECK: ret i8 42
281     ret i8 %a
284 ; CHECK-LABEL: define i8 @volatile2() {
285 define i8 @volatile2() {
286 entry:
287     %ptr = alloca i8
288     store i8 42, i8* %ptr, !invariant.group !0
289     call void @foo(i8* %ptr)
290     %a = load i8, i8* %ptr, !invariant.group !0
291     %b = load volatile i8, i8* %ptr
292 ; CHECK: call void @bar(i8 %b)
293     call void @bar(i8 %b)
295     %c = load volatile i8, i8* %ptr, !invariant.group !0
296 ; FIXME: we could change %c to 42, preserving volatile load
297 ; CHECK: call void @bar(i8 %c)
298     call void @bar(i8 %c)
299 ; CHECK: ret i8 42
300     ret i8 %a
303 ; CHECK-LABEL: define i8 @fun() {
304 define i8 @fun() {
305 entry:
306     %ptr = alloca i8
307     store i8 42, i8* %ptr, !invariant.group !0
308     call void @foo(i8* %ptr)
310     %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
311 ; CHECK: call void @bar(i8 42)
312     call void @bar(i8 %a)
314     %newPtr = call i8* @getPointer(i8* %ptr) 
315     %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
316 ; CHECK: call void @bar(i8 %c)
317     call void @bar(i8 %c)
318     
319     %unknownValue = load i8, i8* @unknownPtr
320 ; FIXME: Can assume that %unknownValue == 42
321 ; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
322     store i8 %unknownValue, i8* %ptr, !invariant.group !0 
324     %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
325 ; CHECK-NOT: load
326     %d = load i8, i8* %newPtr2, !invariant.group !0
327 ; CHECK: ret i8 %unknownValue
328     ret i8 %d
331 ; This test checks if invariant.group understands gep with zeros
332 ; CHECK-LABEL: define void @testGEP0() {
333 define void @testGEP0() {
334   %a = alloca %struct.A, align 8
335   %1 = bitcast %struct.A* %a to i8*
336   %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
337   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
338 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a)
339   call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a) ; This call may change vptr
340   %3 = load i8, i8* @unknownPtr, align 4
341   %4 = icmp eq i8 %3, 0
342   br i1 %4, label %_Z1gR1A.exit, label %5
344 ; This should be devirtualized by invariant.group
345   %6 = bitcast %struct.A* %a to void (%struct.A*)***
346   %7 = load void (%struct.A*)**, void (%struct.A*)*** %6, align 8, !invariant.group !0
347   %8 = load void (%struct.A*)*, void (%struct.A*)** %7, align 8
348 ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
349   call void %8(%struct.A* nonnull %a)
350   br label %_Z1gR1A.exit
352 _Z1gR1A.exit:                                     ; preds = %0, %5
353   ret void
356 ; Check if no optimizations are performed with global pointers.
357 ; FIXME: we could do the optimizations if we would check if dependency comes
358 ; from the same function.
359 ; CHECK-LABEL: define void @testGlobal() {
360 define void @testGlobal() {
361 ; CHECK:  %a = load i8, i8* @unknownPtr, !invariant.group !0
362    %a = load i8, i8* @unknownPtr, !invariant.group !0
363    call void @foo2(i8* @unknownPtr, i8 %a)
364 ; CHECK:  %1 = load i8, i8* @unknownPtr, !invariant.group !0
365    %1 = load i8, i8* @unknownPtr, !invariant.group !0
366    call void @bar(i8 %1)
368    %b0 = bitcast i8* @unknownPtr to i1*
369    call void @fooBit(i1* %b0, i1 1)
370 ; Adding regex because of canonicalization of bitcasts
371 ; CHECK: %2 = load i1, i1* {{.*}}, !invariant.group !0
372    %2 = load i1, i1* %b0, !invariant.group !0
373    call void @fooBit(i1* %b0, i1 %2)
374 ; CHECK:  %3 = load i1, i1* {{.*}}, !invariant.group !0
375    %3 = load i1, i1* %b0, !invariant.group !0
376    call void @fooBit(i1* %b0, i1 %3)
377    ret void
379 ; And in the case it is not global
380 ; CHECK-LABEL: define void @testNotGlobal() {
381 define void @testNotGlobal() {
382    %a = alloca i8
383    call void @foo(i8* %a)
384 ; CHECK:  %b = load i8, i8* %a, !invariant.group !0
385    %b = load i8, i8* %a, !invariant.group !0
386    call void @foo2(i8* %a, i8 %b)
388    %1 = load i8, i8* %a, !invariant.group !0
389 ; CHECK: call void @bar(i8 %b)
390    call void @bar(i8 %1)
392    %b0 = bitcast i8* %a to i1*
393    call void @fooBit(i1* %b0, i1 1)
394 ; CHECK: %1 = trunc i8 %b to i1
395    %2 = load i1, i1* %b0, !invariant.group !0
396 ; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
397    call void @fooBit(i1* %b0, i1 %2)
398    %3 = load i1, i1* %b0, !invariant.group !0
399 ; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
400    call void @fooBit(i1* %b0, i1 %3)
401    ret void
404 ; CHECK-LABEL: define void @handling_loops()
405 define void @handling_loops() {
406   %a = alloca %struct.A, align 8
407   %1 = bitcast %struct.A* %a to i8*
408   %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
409   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
410   %3 = load i8, i8* @unknownPtr, align 4
411   %4 = icmp sgt i8 %3, 0
412   br i1 %4, label %.lr.ph.i, label %_Z2g2R1A.exit
414 .lr.ph.i:                                         ; preds = %0
415   %5 = bitcast %struct.A* %a to void (%struct.A*)***
416   %6 = load i8, i8* @unknownPtr, align 4
417   %7 = icmp sgt i8 %6, 1
418   br i1 %7, label %._crit_edge.preheader, label %_Z2g2R1A.exit
420 ._crit_edge.preheader:                            ; preds = %.lr.ph.i
421   br label %._crit_edge
423 ._crit_edge:                                      ; preds = %._crit_edge.preheader, %._crit_edge
424   %8 = phi i8 [ %10, %._crit_edge ], [ 1, %._crit_edge.preheader ]
425   %.pre = load void (%struct.A*)**, void (%struct.A*)*** %5, align 8, !invariant.group !0
426   %9 = load void (%struct.A*)*, void (%struct.A*)** %.pre, align 8
427   ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
428   call void %9(%struct.A* nonnull %a) #3
429   ; CHECK-NOT: call void %
430   %10 = add nuw nsw i8 %8, 1
431   %11 = load i8, i8* @unknownPtr, align 4
432   %12 = icmp slt i8 %10, %11
433   br i1 %12, label %._crit_edge, label %_Z2g2R1A.exit.loopexit
435 _Z2g2R1A.exit.loopexit:                           ; preds = %._crit_edge
436   br label %_Z2g2R1A.exit
438 _Z2g2R1A.exit:                                    ; preds = %_Z2g2R1A.exit.loopexit, %.lr.ph.i, %0
439   ret void
443 declare void @foo(i8*)
444 declare void @foo2(i8*, i8)
445 declare void @bar(i8)
446 declare i8* @getPointer(i8*)
447 declare void @_ZN1A3fooEv(%struct.A*)
448 declare void @_ZN1AC1Ev(%struct.A*)
449 declare void @fooBit(i1*, i1)
451 declare i8* @llvm.launder.invariant.group.p0i8(i8*)
452 declare i8* @llvm.strip.invariant.group.p0i8(i8*)
455 declare void @llvm.assume(i1 %cmp.vtables)
458 !0 = !{}