xref: /aosp_15_r20/external/llvm/test/Transforms/GVN/invariant.group.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -gvn -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker
3*9880d681SAndroid Build Coastguard Worker%struct.A = type { i32 (...)** }
4*9880d681SAndroid Build Coastguard Worker@_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*9880d681SAndroid Build Coastguard Worker@_ZTI1A = external constant i8*
6*9880d681SAndroid Build Coastguard Worker
7*9880d681SAndroid Build Coastguard Worker@unknownPtr = external global i8
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @simple() {
10*9880d681SAndroid Build Coastguard Workerdefine i8 @simple() {
11*9880d681SAndroid Build Coastguard Workerentry:
12*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
13*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
14*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr, !invariant.group !0
17*9880d681SAndroid Build Coastguard Worker    %b = load i8, i8* %ptr, !invariant.group !0
18*9880d681SAndroid Build Coastguard Worker    %c = load i8, i8* %ptr, !invariant.group !0
19*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42
20*9880d681SAndroid Build Coastguard Worker    ret i8 %a
21*9880d681SAndroid Build Coastguard Worker}
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @optimizable1() {
24*9880d681SAndroid Build Coastguard Workerdefine i8 @optimizable1() {
25*9880d681SAndroid Build Coastguard Workerentry:
26*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
27*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
28*9880d681SAndroid Build Coastguard Worker    %ptr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
29*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr, !invariant.group !0
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr2); call to use %ptr2
32*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42
33*9880d681SAndroid Build Coastguard Worker    ret i8 %a
34*9880d681SAndroid Build Coastguard Worker}
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @optimizable2() {
37*9880d681SAndroid Build Coastguard Workerdefine i8 @optimizable2() {
38*9880d681SAndroid Build Coastguard Workerentry:
39*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
40*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
41*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard Worker    store i8 13, i8* %ptr ; can't use this store with invariant.group
44*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr
45*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %a) ; call to use %a
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
48*9880d681SAndroid Build Coastguard Worker    %b = load i8, i8* %ptr, !invariant.group !0
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42
51*9880d681SAndroid Build Coastguard Worker    ret i8 %b
52*9880d681SAndroid Build Coastguard Worker}
53*9880d681SAndroid Build Coastguard Worker
54*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable1() {
55*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable1() {
56*9880d681SAndroid Build Coastguard Workerentry:
57*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
58*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr
59*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
60*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr, !invariant.group !0
61*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a
62*9880d681SAndroid Build Coastguard Worker    ret i8 %a
63*9880d681SAndroid Build Coastguard Worker}
64*9880d681SAndroid Build Coastguard Worker
65*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @indirectLoads() {
66*9880d681SAndroid Build Coastguard Workerdefine void @indirectLoads() {
67*9880d681SAndroid Build Coastguard Workerentry:
68*9880d681SAndroid Build Coastguard Worker  %a = alloca %struct.A*, align 8
69*9880d681SAndroid Build Coastguard Worker  %0 = bitcast %struct.A** %a to i8*
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker  %call = call i8* @getPointer(i8* null)
72*9880d681SAndroid Build Coastguard Worker  %1 = bitcast i8* %call to %struct.A*
73*9880d681SAndroid Build Coastguard Worker  call void @_ZN1AC1Ev(%struct.A* %1)
74*9880d681SAndroid Build Coastguard Worker  %2 = bitcast %struct.A* %1 to i8***
75*9880d681SAndroid Build Coastguard Worker
76*9880d681SAndroid Build Coastguard Worker; CHECK: %vtable = load {{.*}} !invariant.group
77*9880d681SAndroid Build Coastguard Worker  %vtable = load i8**, i8*** %2, align 8, !invariant.group !2
78*9880d681SAndroid Build Coastguard Worker  %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
79*9880d681SAndroid Build Coastguard Worker  call void @llvm.assume(i1 %cmp.vtables)
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker  store %struct.A* %1, %struct.A** %a, align 8
82*9880d681SAndroid Build Coastguard Worker  %3 = load %struct.A*, %struct.A** %a, align 8
83*9880d681SAndroid Build Coastguard Worker  %4 = bitcast %struct.A* %3 to void (%struct.A*)***
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv(
86*9880d681SAndroid Build Coastguard Worker  %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2
87*9880d681SAndroid Build Coastguard Worker  %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
88*9880d681SAndroid Build Coastguard Worker  %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
89*9880d681SAndroid Build Coastguard Worker  call void %5(%struct.A* %3)
90*9880d681SAndroid Build Coastguard Worker  %6 = load %struct.A*, %struct.A** %a, align 8
91*9880d681SAndroid Build Coastguard Worker  %7 = bitcast %struct.A* %6 to void (%struct.A*)***
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv(
94*9880d681SAndroid Build Coastguard Worker  %vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !2
95*9880d681SAndroid Build Coastguard Worker  %vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
96*9880d681SAndroid Build Coastguard Worker  %8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8
97*9880d681SAndroid Build Coastguard Worker
98*9880d681SAndroid Build Coastguard Worker  call void %8(%struct.A* %6)
99*9880d681SAndroid Build Coastguard Worker  %9 = load %struct.A*, %struct.A** %a, align 8
100*9880d681SAndroid Build Coastguard Worker  %10 = bitcast %struct.A* %9 to void (%struct.A*)***
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker  %vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !2
103*9880d681SAndroid Build Coastguard Worker  %vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
104*9880d681SAndroid Build Coastguard Worker  %11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
105*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv(
106*9880d681SAndroid Build Coastguard Worker  call void %11(%struct.A* %9)
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker  %vtable5 = load i8**, i8*** %2, align 8, !invariant.group !2
109*9880d681SAndroid Build Coastguard Worker  %vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
110*9880d681SAndroid Build Coastguard Worker  %12 = bitcast i8** %vfn6 to void (%struct.A*)**
111*9880d681SAndroid Build Coastguard Worker  %13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
112*9880d681SAndroid Build Coastguard Worker; CHECK: call void @_ZN1A3fooEv(
113*9880d681SAndroid Build Coastguard Worker  call void %13(%struct.A* %9)
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker  ret void
116*9880d681SAndroid Build Coastguard Worker}
117*9880d681SAndroid Build Coastguard Worker
118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @combiningBitCastWithLoad() {
119*9880d681SAndroid Build Coastguard Workerdefine void @combiningBitCastWithLoad() {
120*9880d681SAndroid Build Coastguard Workerentry:
121*9880d681SAndroid Build Coastguard Worker  %a = alloca %struct.A*, align 8
122*9880d681SAndroid Build Coastguard Worker  %0 = bitcast %struct.A** %a to i8*
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker  %call = call i8* @getPointer(i8* null)
125*9880d681SAndroid Build Coastguard Worker  %1 = bitcast i8* %call to %struct.A*
126*9880d681SAndroid Build Coastguard Worker  call void @_ZN1AC1Ev(%struct.A* %1)
127*9880d681SAndroid Build Coastguard Worker  %2 = bitcast %struct.A* %1 to i8***
128*9880d681SAndroid Build Coastguard Worker
129*9880d681SAndroid Build Coastguard Worker; CHECK: %vtable = load {{.*}} !invariant.group
130*9880d681SAndroid Build Coastguard Worker  %vtable = load i8**, i8*** %2, align 8, !invariant.group !2
131*9880d681SAndroid Build Coastguard Worker  %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
132*9880d681SAndroid Build Coastguard Worker
133*9880d681SAndroid Build Coastguard Worker  store %struct.A* %1, %struct.A** %a, align 8
134*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: !invariant.group
135*9880d681SAndroid Build Coastguard Worker  %3 = load %struct.A*, %struct.A** %a, align 8
136*9880d681SAndroid Build Coastguard Worker  %4 = bitcast %struct.A* %3 to void (%struct.A*)***
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker  %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !2
139*9880d681SAndroid Build Coastguard Worker  %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
140*9880d681SAndroid Build Coastguard Worker  %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
141*9880d681SAndroid Build Coastguard Worker  call void %5(%struct.A* %3)
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker  ret void
144*9880d681SAndroid Build Coastguard Worker}
145*9880d681SAndroid Build Coastguard Worker
146*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL:define void @loadCombine() {
147*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine() {
148*9880d681SAndroid Build Coastguard Workerenter:
149*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i8
150*9880d681SAndroid Build Coastguard Worker  store i8 42, i8* %ptr
151*9880d681SAndroid Build Coastguard Worker  call void @foo(i8* %ptr)
152*9880d681SAndroid Build Coastguard Worker; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
153*9880d681SAndroid Build Coastguard Worker  %a = load i8, i8* %ptr, !invariant.group !0
154*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
155*9880d681SAndroid Build Coastguard Worker  %b = load i8, i8* %ptr, !invariant.group !1
156*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[A]])
157*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %a)
158*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[A]])
159*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %b)
160*9880d681SAndroid Build Coastguard Worker  ret void
161*9880d681SAndroid Build Coastguard Worker}
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @loadCombine1() {
164*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine1() {
165*9880d681SAndroid Build Coastguard Workerenter:
166*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i8
167*9880d681SAndroid Build Coastguard Worker  store i8 42, i8* %ptr
168*9880d681SAndroid Build Coastguard Worker  call void @foo(i8* %ptr)
169*9880d681SAndroid Build Coastguard Worker; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
170*9880d681SAndroid Build Coastguard Worker  %c = load i8, i8* %ptr
171*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
172*9880d681SAndroid Build Coastguard Worker  %d = load i8, i8* %ptr, !invariant.group !1
173*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[D]])
174*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %c)
175*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[D]])
176*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %d)
177*9880d681SAndroid Build Coastguard Worker  ret void
178*9880d681SAndroid Build Coastguard Worker}
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @loadCombine2() {
181*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine2() {
182*9880d681SAndroid Build Coastguard Workerenter:
183*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i8
184*9880d681SAndroid Build Coastguard Worker  store i8 42, i8* %ptr
185*9880d681SAndroid Build Coastguard Worker  call void @foo(i8* %ptr)
186*9880d681SAndroid Build Coastguard Worker; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
187*9880d681SAndroid Build Coastguard Worker  %e = load i8, i8* %ptr, !invariant.group !1
188*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
189*9880d681SAndroid Build Coastguard Worker  %f = load i8, i8* %ptr
190*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]])
191*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %e)
192*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]])
193*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %f)
194*9880d681SAndroid Build Coastguard Worker  ret void
195*9880d681SAndroid Build Coastguard Worker}
196*9880d681SAndroid Build Coastguard Worker
197*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define void @loadCombine3() {
198*9880d681SAndroid Build Coastguard Workerdefine void @loadCombine3() {
199*9880d681SAndroid Build Coastguard Workerenter:
200*9880d681SAndroid Build Coastguard Worker  %ptr = alloca i8
201*9880d681SAndroid Build Coastguard Worker  store i8 42, i8* %ptr
202*9880d681SAndroid Build Coastguard Worker  call void @foo(i8* %ptr)
203*9880d681SAndroid Build Coastguard Worker; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group ![[OneMD:[0-9]]]
204*9880d681SAndroid Build Coastguard Worker  %e = load i8, i8* %ptr, !invariant.group !1
205*9880d681SAndroid Build Coastguard Worker; CHECK-NOT: load
206*9880d681SAndroid Build Coastguard Worker  %f = load i8, i8* %ptr, !invariant.group !1
207*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]])
208*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %e)
209*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %[[E]])
210*9880d681SAndroid Build Coastguard Worker  call void @bar(i8 %f)
211*9880d681SAndroid Build Coastguard Worker  ret void
212*9880d681SAndroid Build Coastguard Worker}
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable2() {
215*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable2() {
216*9880d681SAndroid Build Coastguard Workerentry:
217*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
218*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr
219*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
220*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr
221*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
222*9880d681SAndroid Build Coastguard Worker    %b = load i8, i8* %ptr, !invariant.group !0
223*9880d681SAndroid Build Coastguard Worker
224*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a
225*9880d681SAndroid Build Coastguard Worker    ret i8 %a
226*9880d681SAndroid Build Coastguard Worker}
227*9880d681SAndroid Build Coastguard Worker
228*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable3() {
229*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable3() {
230*9880d681SAndroid Build Coastguard Workerentry:
231*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
232*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
233*9880d681SAndroid Build Coastguard Worker    %ptr2 = call i8* @getPointer(i8* %ptr)
234*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr2, !invariant.group !0
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a
237*9880d681SAndroid Build Coastguard Worker    ret i8 %a
238*9880d681SAndroid Build Coastguard Worker}
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @unoptimizable4() {
241*9880d681SAndroid Build Coastguard Workerdefine i8 @unoptimizable4() {
242*9880d681SAndroid Build Coastguard Workerentry:
243*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
244*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
245*9880d681SAndroid Build Coastguard Worker    %ptr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
246*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr2, !invariant.group !0
247*9880d681SAndroid Build Coastguard Worker
248*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %a
249*9880d681SAndroid Build Coastguard Worker    ret i8 %a
250*9880d681SAndroid Build Coastguard Worker}
251*9880d681SAndroid Build Coastguard Worker
252*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @volatile1() {
253*9880d681SAndroid Build Coastguard Workerdefine i8 @volatile1() {
254*9880d681SAndroid Build Coastguard Workerentry:
255*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
256*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
257*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
258*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr, !invariant.group !0
259*9880d681SAndroid Build Coastguard Worker    %b = load volatile i8, i8* %ptr
260*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %b)
261*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %b)
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker    %c = load volatile i8, i8* %ptr, !invariant.group !0
264*9880d681SAndroid Build Coastguard Worker; FIXME: we could change %c to 42, preserving volatile load
265*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %c)
266*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %c)
267*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42
268*9880d681SAndroid Build Coastguard Worker    ret i8 %a
269*9880d681SAndroid Build Coastguard Worker}
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @volatile2() {
272*9880d681SAndroid Build Coastguard Workerdefine i8 @volatile2() {
273*9880d681SAndroid Build Coastguard Workerentry:
274*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
275*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
276*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
277*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr, !invariant.group !0
278*9880d681SAndroid Build Coastguard Worker    %b = load volatile i8, i8* %ptr
279*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %b)
280*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %b)
281*9880d681SAndroid Build Coastguard Worker
282*9880d681SAndroid Build Coastguard Worker    %c = load volatile i8, i8* %ptr, !invariant.group !0
283*9880d681SAndroid Build Coastguard Worker; FIXME: we could change %c to 42, preserving volatile load
284*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %c)
285*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %c)
286*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 42
287*9880d681SAndroid Build Coastguard Worker    ret i8 %a
288*9880d681SAndroid Build Coastguard Worker}
289*9880d681SAndroid Build Coastguard Worker
290*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: define i8 @fun() {
291*9880d681SAndroid Build Coastguard Workerdefine i8 @fun() {
292*9880d681SAndroid Build Coastguard Workerentry:
293*9880d681SAndroid Build Coastguard Worker    %ptr = alloca i8
294*9880d681SAndroid Build Coastguard Worker    store i8 42, i8* %ptr, !invariant.group !0
295*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker    %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
298*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 42)
299*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %a)
300*9880d681SAndroid Build Coastguard Worker
301*9880d681SAndroid Build Coastguard Worker    call void @foo(i8* %ptr)
302*9880d681SAndroid Build Coastguard Worker    %b = load i8, i8* %ptr, !invariant.group !1 ; Can't assume anything, because group changed
303*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %b)
304*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %b)
305*9880d681SAndroid Build Coastguard Worker
306*9880d681SAndroid Build Coastguard Worker    %newPtr = call i8* @getPointer(i8* %ptr)
307*9880d681SAndroid Build Coastguard Worker    %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
308*9880d681SAndroid Build Coastguard Worker; CHECK: call void @bar(i8 %c)
309*9880d681SAndroid Build Coastguard Worker    call void @bar(i8 %c)
310*9880d681SAndroid Build Coastguard Worker
311*9880d681SAndroid Build Coastguard Worker    %unknownValue = load i8, i8* @unknownPtr
312*9880d681SAndroid Build Coastguard Worker; FIXME: Can assume that %unknownValue == 42
313*9880d681SAndroid Build Coastguard Worker; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
314*9880d681SAndroid Build Coastguard Worker    store i8 %unknownValue, i8* %ptr, !invariant.group !0
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker    %newPtr2 = call i8* @llvm.invariant.group.barrier(i8* %ptr)
317*9880d681SAndroid Build Coastguard Worker    %d = load i8, i8* %newPtr2, !invariant.group !0  ; Can't step through invariant.group.barrier to get value of %ptr
318*9880d681SAndroid Build Coastguard Worker; CHECK: ret i8 %d
319*9880d681SAndroid Build Coastguard Worker    ret i8 %d
320*9880d681SAndroid Build Coastguard Worker}
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Workerdeclare void @foo(i8*)
323*9880d681SAndroid Build Coastguard Workerdeclare void @bar(i8)
324*9880d681SAndroid Build Coastguard Workerdeclare i8* @getPointer(i8*)
325*9880d681SAndroid Build Coastguard Workerdeclare void @_ZN1A3fooEv(%struct.A*)
326*9880d681SAndroid Build Coastguard Workerdeclare void @_ZN1AC1Ev(%struct.A*)
327*9880d681SAndroid Build Coastguard Workerdeclare i8* @llvm.invariant.group.barrier(i8*)
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker; Function Attrs: nounwind
330*9880d681SAndroid Build Coastguard Workerdeclare void @llvm.assume(i1 %cmp.vtables) #0
331*9880d681SAndroid Build Coastguard Worker
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Workerattributes #0 = { nounwind }
334*9880d681SAndroid Build Coastguard Worker; CHECK: ![[OneMD]] = !{!"other ptr"}
335*9880d681SAndroid Build Coastguard Worker!0 = !{!"magic ptr"}
336*9880d681SAndroid Build Coastguard Worker!1 = !{!"other ptr"}
337*9880d681SAndroid Build Coastguard Worker!2 = !{!"vtable_of_a"}
338