xref: /aosp_15_r20/external/llvm/test/Transforms/FunctionAttrs/nocapture.ll (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker; RUN: opt < %s -functionattrs -S | FileCheck %s
2*9880d681SAndroid Build Coastguard Worker@g = global i32* null		; <i32**> [#uses=1]
3*9880d681SAndroid Build Coastguard Worker
4*9880d681SAndroid Build Coastguard Worker; CHECK: define i32* @c1(i32* readnone %q)
5*9880d681SAndroid Build Coastguard Workerdefine i32* @c1(i32* %q) {
6*9880d681SAndroid Build Coastguard Worker	ret i32* %q
7*9880d681SAndroid Build Coastguard Worker}
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard Worker; CHECK: define void @c2(i32* %q)
10*9880d681SAndroid Build Coastguard Worker; It would also be acceptable to mark %q as readnone. Update @c3 too.
11*9880d681SAndroid Build Coastguard Workerdefine void @c2(i32* %q) {
12*9880d681SAndroid Build Coastguard Worker	store i32* %q, i32** @g
13*9880d681SAndroid Build Coastguard Worker	ret void
14*9880d681SAndroid Build Coastguard Worker}
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker; CHECK: define void @c3(i32* %q)
17*9880d681SAndroid Build Coastguard Workerdefine void @c3(i32* %q) {
18*9880d681SAndroid Build Coastguard Worker	call void @c2(i32* %q)
19*9880d681SAndroid Build Coastguard Worker	ret void
20*9880d681SAndroid Build Coastguard Worker}
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c4(i32* %q, i32 %bitno)
23*9880d681SAndroid Build Coastguard Workerdefine i1 @c4(i32* %q, i32 %bitno) {
24*9880d681SAndroid Build Coastguard Worker	%tmp = ptrtoint i32* %q to i32
25*9880d681SAndroid Build Coastguard Worker	%tmp2 = lshr i32 %tmp, %bitno
26*9880d681SAndroid Build Coastguard Worker	%bit = trunc i32 %tmp2 to i1
27*9880d681SAndroid Build Coastguard Worker	br i1 %bit, label %l1, label %l0
28*9880d681SAndroid Build Coastguard Workerl0:
29*9880d681SAndroid Build Coastguard Worker	ret i1 0 ; escaping value not caught by def-use chaining.
30*9880d681SAndroid Build Coastguard Workerl1:
31*9880d681SAndroid Build Coastguard Worker	ret i1 1 ; escaping value not caught by def-use chaining.
32*9880d681SAndroid Build Coastguard Worker}
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker@lookup_table = global [2 x i1] [ i1 0, i1 1 ]
35*9880d681SAndroid Build Coastguard Worker
36*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c5(i32* %q, i32 %bitno)
37*9880d681SAndroid Build Coastguard Workerdefine i1 @c5(i32* %q, i32 %bitno) {
38*9880d681SAndroid Build Coastguard Worker	%tmp = ptrtoint i32* %q to i32
39*9880d681SAndroid Build Coastguard Worker	%tmp2 = lshr i32 %tmp, %bitno
40*9880d681SAndroid Build Coastguard Worker	%bit = and i32 %tmp2, 1
41*9880d681SAndroid Build Coastguard Worker        ; subtle escape mechanism follows
42*9880d681SAndroid Build Coastguard Worker	%lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 %bit
43*9880d681SAndroid Build Coastguard Worker	%val = load i1, i1* %lookup
44*9880d681SAndroid Build Coastguard Worker	ret i1 %val
45*9880d681SAndroid Build Coastguard Worker}
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Workerdeclare void @throw_if_bit_set(i8*, i8) readonly
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c6(i8* readonly %q, i8 %bit)
50*9880d681SAndroid Build Coastguard Workerdefine i1 @c6(i8* %q, i8 %bit) personality i32 (...)* @__gxx_personality_v0 {
51*9880d681SAndroid Build Coastguard Worker	invoke void @throw_if_bit_set(i8* %q, i8 %bit)
52*9880d681SAndroid Build Coastguard Worker		to label %ret0 unwind label %ret1
53*9880d681SAndroid Build Coastguard Workerret0:
54*9880d681SAndroid Build Coastguard Worker	ret i1 0
55*9880d681SAndroid Build Coastguard Workerret1:
56*9880d681SAndroid Build Coastguard Worker        %exn = landingpad {i8*, i32}
57*9880d681SAndroid Build Coastguard Worker                 cleanup
58*9880d681SAndroid Build Coastguard Worker	ret i1 1
59*9880d681SAndroid Build Coastguard Worker}
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Workerdeclare i32 @__gxx_personality_v0(...)
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Workerdefine i1* @lookup_bit(i32* %q, i32 %bitno) readnone nounwind {
64*9880d681SAndroid Build Coastguard Worker	%tmp = ptrtoint i32* %q to i32
65*9880d681SAndroid Build Coastguard Worker	%tmp2 = lshr i32 %tmp, %bitno
66*9880d681SAndroid Build Coastguard Worker	%bit = and i32 %tmp2, 1
67*9880d681SAndroid Build Coastguard Worker	%lookup = getelementptr [2 x i1], [2 x i1]* @lookup_table, i32 0, i32 %bit
68*9880d681SAndroid Build Coastguard Worker	ret i1* %lookup
69*9880d681SAndroid Build Coastguard Worker}
70*9880d681SAndroid Build Coastguard Worker
71*9880d681SAndroid Build Coastguard Worker; CHECK: define i1 @c7(i32* readonly %q, i32 %bitno)
72*9880d681SAndroid Build Coastguard Workerdefine i1 @c7(i32* %q, i32 %bitno) {
73*9880d681SAndroid Build Coastguard Worker	%ptr = call i1* @lookup_bit(i32* %q, i32 %bitno)
74*9880d681SAndroid Build Coastguard Worker	%val = load i1, i1* %ptr
75*9880d681SAndroid Build Coastguard Worker	ret i1 %val
76*9880d681SAndroid Build Coastguard Worker}
77*9880d681SAndroid Build Coastguard Worker
78*9880d681SAndroid Build Coastguard Worker
79*9880d681SAndroid Build Coastguard Worker; CHECK: define i32 @nc1(i32* %q, i32* nocapture %p, i1 %b)
80*9880d681SAndroid Build Coastguard Workerdefine i32 @nc1(i32* %q, i32* %p, i1 %b) {
81*9880d681SAndroid Build Coastguard Workere:
82*9880d681SAndroid Build Coastguard Worker	br label %l
83*9880d681SAndroid Build Coastguard Workerl:
84*9880d681SAndroid Build Coastguard Worker	%x = phi i32* [ %p, %e ]
85*9880d681SAndroid Build Coastguard Worker	%y = phi i32* [ %q, %e ]
86*9880d681SAndroid Build Coastguard Worker	%tmp = bitcast i32* %x to i32*		; <i32*> [#uses=2]
87*9880d681SAndroid Build Coastguard Worker	%tmp2 = select i1 %b, i32* %tmp, i32* %y
88*9880d681SAndroid Build Coastguard Worker	%val = load i32, i32* %tmp2		; <i32> [#uses=1]
89*9880d681SAndroid Build Coastguard Worker	store i32 0, i32* %tmp
90*9880d681SAndroid Build Coastguard Worker	store i32* %y, i32** @g
91*9880d681SAndroid Build Coastguard Worker	ret i32 %val
92*9880d681SAndroid Build Coastguard Worker}
93*9880d681SAndroid Build Coastguard Worker
94*9880d681SAndroid Build Coastguard Worker; CHECK: define i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* nocapture %p, i1 %b)
95*9880d681SAndroid Build Coastguard Workerdefine i32 @nc1_addrspace(i32* %q, i32 addrspace(1)* %p, i1 %b) {
96*9880d681SAndroid Build Coastguard Workere:
97*9880d681SAndroid Build Coastguard Worker	br label %l
98*9880d681SAndroid Build Coastguard Workerl:
99*9880d681SAndroid Build Coastguard Worker	%x = phi i32 addrspace(1)* [ %p, %e ]
100*9880d681SAndroid Build Coastguard Worker	%y = phi i32* [ %q, %e ]
101*9880d681SAndroid Build Coastguard Worker	%tmp = addrspacecast i32 addrspace(1)* %x to i32*		; <i32*> [#uses=2]
102*9880d681SAndroid Build Coastguard Worker	%tmp2 = select i1 %b, i32* %tmp, i32* %y
103*9880d681SAndroid Build Coastguard Worker	%val = load i32, i32* %tmp2		; <i32> [#uses=1]
104*9880d681SAndroid Build Coastguard Worker	store i32 0, i32* %tmp
105*9880d681SAndroid Build Coastguard Worker	store i32* %y, i32** @g
106*9880d681SAndroid Build Coastguard Worker	ret i32 %val
107*9880d681SAndroid Build Coastguard Worker}
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc2(i32* nocapture %p, i32* %q)
110*9880d681SAndroid Build Coastguard Workerdefine void @nc2(i32* %p, i32* %q) {
111*9880d681SAndroid Build Coastguard Worker	%1 = call i32 @nc1(i32* %q, i32* %p, i1 0)		; <i32> [#uses=0]
112*9880d681SAndroid Build Coastguard Worker	ret void
113*9880d681SAndroid Build Coastguard Worker}
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc3(void ()* nocapture %p)
116*9880d681SAndroid Build Coastguard Workerdefine void @nc3(void ()* %p) {
117*9880d681SAndroid Build Coastguard Worker	call void %p()
118*9880d681SAndroid Build Coastguard Worker	ret void
119*9880d681SAndroid Build Coastguard Worker}
120*9880d681SAndroid Build Coastguard Worker
121*9880d681SAndroid Build Coastguard Workerdeclare void @external(i8*) readonly nounwind
122*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc4(i8* nocapture readonly %p)
123*9880d681SAndroid Build Coastguard Workerdefine void @nc4(i8* %p) {
124*9880d681SAndroid Build Coastguard Worker	call void @external(i8* %p)
125*9880d681SAndroid Build Coastguard Worker	ret void
126*9880d681SAndroid Build Coastguard Worker}
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker; CHECK: define void @nc5(void (i8*)* nocapture %f, i8* nocapture %p)
129*9880d681SAndroid Build Coastguard Workerdefine void @nc5(void (i8*)* %f, i8* %p) {
130*9880d681SAndroid Build Coastguard Worker	call void %f(i8* %p) readonly nounwind
131*9880d681SAndroid Build Coastguard Worker	call void %f(i8* nocapture %p)
132*9880d681SAndroid Build Coastguard Worker	ret void
133*9880d681SAndroid Build Coastguard Worker}
134*9880d681SAndroid Build Coastguard Worker
135*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test1_1(i8* nocapture readnone %x1_1, i8* %y1_1)
136*9880d681SAndroid Build Coastguard Worker; It would be acceptable to add readnone to %y1_1 and %y1_2.
137*9880d681SAndroid Build Coastguard Workerdefine void @test1_1(i8* %x1_1, i8* %y1_1) {
138*9880d681SAndroid Build Coastguard Worker  call i8* @test1_2(i8* %x1_1, i8* %y1_1)
139*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
140*9880d681SAndroid Build Coastguard Worker  ret void
141*9880d681SAndroid Build Coastguard Worker}
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test1_2(i8* nocapture readnone %x1_2, i8* %y1_2)
144*9880d681SAndroid Build Coastguard Workerdefine i8* @test1_2(i8* %x1_2, i8* %y1_2) {
145*9880d681SAndroid Build Coastguard Worker  call void @test1_1(i8* %x1_2, i8* %y1_2)
146*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
147*9880d681SAndroid Build Coastguard Worker  ret i8* %y1_2
148*9880d681SAndroid Build Coastguard Worker}
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test2(i8* nocapture readnone %x2)
151*9880d681SAndroid Build Coastguard Workerdefine void @test2(i8* %x2) {
152*9880d681SAndroid Build Coastguard Worker  call void @test2(i8* %x2)
153*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
154*9880d681SAndroid Build Coastguard Worker  ret void
155*9880d681SAndroid Build Coastguard Worker}
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test3(i8* nocapture readnone %x3, i8* nocapture readnone %y3, i8* nocapture readnone %z3)
158*9880d681SAndroid Build Coastguard Workerdefine void @test3(i8* %x3, i8* %y3, i8* %z3) {
159*9880d681SAndroid Build Coastguard Worker  call void @test3(i8* %z3, i8* %y3, i8* %x3)
160*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
161*9880d681SAndroid Build Coastguard Worker  ret void
162*9880d681SAndroid Build Coastguard Worker}
163*9880d681SAndroid Build Coastguard Worker
164*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test4_1(i8* %x4_1)
165*9880d681SAndroid Build Coastguard Workerdefine void @test4_1(i8* %x4_1) {
166*9880d681SAndroid Build Coastguard Worker  call i8* @test4_2(i8* %x4_1, i8* %x4_1, i8* %x4_1)
167*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
168*9880d681SAndroid Build Coastguard Worker  ret void
169*9880d681SAndroid Build Coastguard Worker}
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker; CHECK: define i8* @test4_2(i8* nocapture readnone %x4_2, i8* readnone %y4_2, i8* nocapture readnone %z4_2)
172*9880d681SAndroid Build Coastguard Workerdefine i8* @test4_2(i8* %x4_2, i8* %y4_2, i8* %z4_2) {
173*9880d681SAndroid Build Coastguard Worker  call void @test4_1(i8* null)
174*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
175*9880d681SAndroid Build Coastguard Worker  ret i8* %y4_2
176*9880d681SAndroid Build Coastguard Worker}
177*9880d681SAndroid Build Coastguard Worker
178*9880d681SAndroid Build Coastguard Workerdeclare i8* @test5_1(i8* %x5_1)
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test5_2(i8* %x5_2)
181*9880d681SAndroid Build Coastguard Workerdefine void @test5_2(i8* %x5_2) {
182*9880d681SAndroid Build Coastguard Worker  call i8* @test5_1(i8* %x5_2)
183*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
184*9880d681SAndroid Build Coastguard Worker  ret void
185*9880d681SAndroid Build Coastguard Worker}
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Workerdeclare void @test6_1(i8* %x6_1, i8* nocapture %y6_1, ...)
188*9880d681SAndroid Build Coastguard Worker
189*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test6_2(i8* %x6_2, i8* nocapture %y6_2, i8* %z6_2)
190*9880d681SAndroid Build Coastguard Workerdefine void @test6_2(i8* %x6_2, i8* %y6_2, i8* %z6_2) {
191*9880d681SAndroid Build Coastguard Worker  call void (i8*, i8*, ...) @test6_1(i8* %x6_2, i8* %y6_2, i8* %z6_2)
192*9880d681SAndroid Build Coastguard Worker  store i32* null, i32** @g
193*9880d681SAndroid Build Coastguard Worker  ret void
194*9880d681SAndroid Build Coastguard Worker}
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_cmpxchg(i32* nocapture %p)
197*9880d681SAndroid Build Coastguard Workerdefine void @test_cmpxchg(i32* %p) {
198*9880d681SAndroid Build Coastguard Worker  cmpxchg i32* %p, i32 0, i32 1 acquire monotonic
199*9880d681SAndroid Build Coastguard Worker  ret void
200*9880d681SAndroid Build Coastguard Worker}
201*9880d681SAndroid Build Coastguard Worker
202*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_cmpxchg_ptr(i32** nocapture %p, i32* %q)
203*9880d681SAndroid Build Coastguard Workerdefine void @test_cmpxchg_ptr(i32** %p, i32* %q) {
204*9880d681SAndroid Build Coastguard Worker  cmpxchg i32** %p, i32* null, i32* %q acquire monotonic
205*9880d681SAndroid Build Coastguard Worker  ret void
206*9880d681SAndroid Build Coastguard Worker}
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_atomicrmw(i32* nocapture %p)
209*9880d681SAndroid Build Coastguard Workerdefine void @test_atomicrmw(i32* %p) {
210*9880d681SAndroid Build Coastguard Worker  atomicrmw add i32* %p, i32 1 seq_cst
211*9880d681SAndroid Build Coastguard Worker  ret void
212*9880d681SAndroid Build Coastguard Worker}
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker; CHECK: define void @test_volatile(i32* %x)
215*9880d681SAndroid Build Coastguard Workerdefine void @test_volatile(i32* %x) {
216*9880d681SAndroid Build Coastguard Workerentry:
217*9880d681SAndroid Build Coastguard Worker  %gep = getelementptr i32, i32* %x, i64 1
218*9880d681SAndroid Build Coastguard Worker  store volatile i32 0, i32* %gep, align 4
219*9880d681SAndroid Build Coastguard Worker  ret void
220*9880d681SAndroid Build Coastguard Worker}
221