Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Transforms / Attributor / callbacks.ll
blob6ace218afcf36b68a8b17478492393adf8d41b3d
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-attributes --check-globals
2 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal  -attributor-annotate-decl-cs  -S < %s | FileCheck %s --check-prefixes=CHECK,TUNIT
3 ; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal  -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,CGSCC
5 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
7 ; Test 0
9 ; Make sure we propagate information from the caller to the callback callee but
10 ; only for arguments that are mapped through the callback metadata. Here, the
11 ; first two arguments of the call and the callback callee do not correspond to
12 ; each other but argument 3-5 of the transitive call site in the caller match
13 ; arguments 2-4 of the callback callee. Here we should see information and value
14 ; transfer in both directions.
16 define void @t0_caller(ptr %a) {
17 ; TUNIT-LABEL: define {{[^@]+}}@t0_caller
18 ; TUNIT-SAME: (ptr align 256 [[A:%.*]]) {
19 ; TUNIT-NEXT:  entry:
20 ; TUNIT-NEXT:    [[B:%.*]] = alloca i32, align 32
21 ; TUNIT-NEXT:    [[C:%.*]] = alloca ptr, align 64
22 ; TUNIT-NEXT:    [[PTR:%.*]] = alloca i32, align 128
23 ; TUNIT-NEXT:    store i32 42, ptr [[B]], align 32
24 ; TUNIT-NEXT:    store ptr [[B]], ptr [[C]], align 64
25 ; TUNIT-NEXT:    call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr noundef align 4294967296 null, ptr noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr noundef nonnull @t0_callback_callee, ptr align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
26 ; TUNIT-NEXT:    ret void
28 ; CGSCC-LABEL: define {{[^@]+}}@t0_caller
29 ; CGSCC-SAME: (ptr align 256 [[A:%.*]]) {
30 ; CGSCC-NEXT:  entry:
31 ; CGSCC-NEXT:    [[B:%.*]] = alloca i32, align 32
32 ; CGSCC-NEXT:    [[C:%.*]] = alloca ptr, align 64
33 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
34 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
35 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
36 ; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr noundef align 4294967296 null, ptr noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr noundef nonnull @t0_callback_callee, ptr align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
37 ; CGSCC-NEXT:    ret void
39 entry:
40   %b = alloca i32, align 32
41   %c = alloca ptr, align 64
42   %ptr = alloca i32, align 128
43   store i32 42, ptr %b, align 4
44   store ptr %b, ptr %c, align 8
45   call void (ptr, ptr, ptr, ...) @t0_callback_broker(ptr null, ptr %ptr, ptr @t0_callback_callee, ptr %a, i64 99, ptr %c)
46   ret void
49 ; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
50 ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
51 define internal void @t0_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {
53 ; TUNIT-LABEL: define {{[^@]+}}@t0_callback_callee
54 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) {
55 ; TUNIT-NEXT:  entry:
56 ; TUNIT-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
57 ; TUNIT-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
58 ; TUNIT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
59 ; TUNIT-NEXT:    tail call void @t0_check(ptr align 256 [[A]], i64 noundef 99, ptr align 32 [[TMP0]])
60 ; TUNIT-NEXT:    ret void
62 ; CGSCC-LABEL: define {{[^@]+}}@t0_callback_callee
63 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) {
64 ; CGSCC-NEXT:  entry:
65 ; CGSCC-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
66 ; CGSCC-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
67 ; CGSCC-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
68 ; CGSCC-NEXT:    tail call void @t0_check(ptr align 256 [[A]], i64 noundef 99, ptr [[TMP0]])
69 ; CGSCC-NEXT:    ret void
71 entry:
72   %ptr_val = load i32, ptr %ptr, align 8
73   store i32 %ptr_val, ptr %is_not_null
74   %0 = load ptr, ptr %c, align 8
75   tail call void @t0_check(ptr %a, i64 %b, ptr %0)
76   ret void
79 declare void @t0_check(ptr align 256, i64, ptr)
81 declare !callback !0 void @t0_callback_broker(ptr, ptr, ptr, ...)
83 ; Test 1
85 ; Similar to test 0 but with some additional annotations (noalias/nocapute) to make sure
86 ; we deduce and propagate noalias and others properly.
88 define void @t1_caller(ptr noalias %a) {
90 ; TUNIT-LABEL: define {{[^@]+}}@t1_caller
91 ; TUNIT-SAME: (ptr noalias nocapture align 256 [[A:%.*]]) {
92 ; TUNIT-NEXT:  entry:
93 ; TUNIT-NEXT:    [[B:%.*]] = alloca i32, align 32
94 ; TUNIT-NEXT:    [[C:%.*]] = alloca ptr, align 64
95 ; TUNIT-NEXT:    [[PTR:%.*]] = alloca i32, align 128
96 ; TUNIT-NEXT:    store i32 42, ptr [[B]], align 32
97 ; TUNIT-NEXT:    store ptr [[B]], ptr [[C]], align 64
98 ; TUNIT-NEXT:    call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t1_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
99 ; TUNIT-NEXT:    ret void
101 ; CGSCC-LABEL: define {{[^@]+}}@t1_caller
102 ; CGSCC-SAME: (ptr noalias nocapture align 256 [[A:%.*]]) {
103 ; CGSCC-NEXT:  entry:
104 ; CGSCC-NEXT:    [[B:%.*]] = alloca i32, align 32
105 ; CGSCC-NEXT:    [[C:%.*]] = alloca ptr, align 64
106 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
107 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
108 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
109 ; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t1_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
110 ; CGSCC-NEXT:    ret void
112 entry:
113   %b = alloca i32, align 32
114   %c = alloca ptr, align 64
115   %ptr = alloca i32, align 128
116   store i32 42, ptr %b, align 4
117   store ptr %b, ptr %c, align 8
118   call void (ptr, ptr, ptr, ...) @t1_callback_broker(ptr null, ptr %ptr, ptr @t1_callback_callee, ptr %a, i64 99, ptr %c)
119   ret void
122 ; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
123 ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
124 define internal void @t1_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {
126 ; TUNIT: Function Attrs: nosync
127 ; TUNIT-LABEL: define {{[^@]+}}@t1_callback_callee
128 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr nocapture align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
129 ; TUNIT-NEXT:  entry:
130 ; TUNIT-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
131 ; TUNIT-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
132 ; TUNIT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
133 ; TUNIT-NEXT:    tail call void @t1_check(ptr nocapture align 256 [[A]], i64 noundef 99, ptr nocapture align 32 [[TMP0]])
134 ; TUNIT-NEXT:    ret void
136 ; CGSCC: Function Attrs: nosync
137 ; CGSCC-LABEL: define {{[^@]+}}@t1_callback_callee
138 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr nocapture align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) #[[ATTR0:[0-9]+]] {
139 ; CGSCC-NEXT:  entry:
140 ; CGSCC-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
141 ; CGSCC-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
142 ; CGSCC-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
143 ; CGSCC-NEXT:    tail call void @t1_check(ptr nocapture align 256 [[A]], i64 noundef 99, ptr nocapture [[TMP0]])
144 ; CGSCC-NEXT:    ret void
146 entry:
147   %ptr_val = load i32, ptr %ptr, align 8
148   store i32 %ptr_val, ptr %is_not_null
149   %0 = load ptr, ptr %c, align 8
150   tail call void @t1_check(ptr %a, i64 %b, ptr %0)
151   ret void
154 declare void @t1_check(ptr nocapture align 256, i64, ptr nocapture) nosync
156 declare !callback !0 void @t1_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)
158 ; Test 2
160 ; Similar to test 1 but checking that the noalias is only placed if potential synchronization through @t2_check is preserved.
162 define void @t2_caller(ptr noalias %a) {
163 ; TUNIT-LABEL: define {{[^@]+}}@t2_caller
164 ; TUNIT-SAME: (ptr noalias nocapture align 256 [[A:%.*]]) {
165 ; TUNIT-NEXT:  entry:
166 ; TUNIT-NEXT:    [[B:%.*]] = alloca i32, align 32
167 ; TUNIT-NEXT:    [[C:%.*]] = alloca ptr, align 64
168 ; TUNIT-NEXT:    [[PTR:%.*]] = alloca i32, align 128
169 ; TUNIT-NEXT:    store i32 42, ptr [[B]], align 32
170 ; TUNIT-NEXT:    store ptr [[B]], ptr [[C]], align 64
171 ; TUNIT-NEXT:    call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t2_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
172 ; TUNIT-NEXT:    ret void
174 ; CGSCC-LABEL: define {{[^@]+}}@t2_caller
175 ; CGSCC-SAME: (ptr noalias nocapture align 256 [[A:%.*]]) {
176 ; CGSCC-NEXT:  entry:
177 ; CGSCC-NEXT:    [[B:%.*]] = alloca i32, align 32
178 ; CGSCC-NEXT:    [[C:%.*]] = alloca ptr, align 64
179 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
180 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
181 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
182 ; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t2_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
183 ; CGSCC-NEXT:    ret void
185 entry:
186   %b = alloca i32, align 32
187   %c = alloca ptr, align 64
188   %ptr = alloca i32, align 128
189   store i32 42, ptr %b, align 4
190   store ptr %b, ptr %c, align 8
191   call void (ptr, ptr, ptr, ...) @t2_callback_broker(ptr null, ptr %ptr, ptr @t2_callback_callee, ptr %a, i64 99, ptr %c)
192   ret void
195 ; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
196 ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
198 ; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.
199 define internal void @t2_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {
201 ; TUNIT-LABEL: define {{[^@]+}}@t2_callback_callee
202 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr nocapture align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) {
203 ; TUNIT-NEXT:  entry:
204 ; TUNIT-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
205 ; TUNIT-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
206 ; TUNIT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
207 ; TUNIT-NEXT:    tail call void @t2_check(ptr nocapture align 256 [[A]], i64 noundef 99, ptr nocapture align 32 [[TMP0]])
208 ; TUNIT-NEXT:    ret void
210 ; CGSCC-LABEL: define {{[^@]+}}@t2_callback_callee
211 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr nocapture align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) {
212 ; CGSCC-NEXT:  entry:
213 ; CGSCC-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
214 ; CGSCC-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
215 ; CGSCC-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
216 ; CGSCC-NEXT:    tail call void @t2_check(ptr nocapture align 256 [[A]], i64 noundef 99, ptr nocapture [[TMP0]])
217 ; CGSCC-NEXT:    ret void
219 entry:
220   %ptr_val = load i32, ptr %ptr, align 8
221   store i32 %ptr_val, ptr %is_not_null
222   %0 = load ptr, ptr %c, align 8
223   tail call void @t2_check(ptr %a, i64 %b, ptr %0)
224   ret void
227 declare void @t2_check(ptr nocapture align 256, i64, ptr nocapture)
229 declare !callback !0 void @t2_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)
231 ; Test 3
233 ; Basically test 2 with the casted callback callee used twice.
235 define void @t3_caller(ptr noalias %a) {
236 ; TUNIT-LABEL: define {{[^@]+}}@t3_caller
237 ; TUNIT-SAME: (ptr noalias nocapture align 256 [[A:%.*]]) {
238 ; TUNIT-NEXT:  entry:
239 ; TUNIT-NEXT:    [[B:%.*]] = alloca i32, align 32
240 ; TUNIT-NEXT:    [[C:%.*]] = alloca ptr, align 64
241 ; TUNIT-NEXT:    [[PTR:%.*]] = alloca i32, align 128
242 ; TUNIT-NEXT:    store i32 42, ptr [[B]], align 32
243 ; TUNIT-NEXT:    store ptr [[B]], ptr [[C]], align 64
244 ; TUNIT-NEXT:    call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
245 ; TUNIT-NEXT:    call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 undef, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
246 ; TUNIT-NEXT:    ret void
248 ; CGSCC-LABEL: define {{[^@]+}}@t3_caller
249 ; CGSCC-SAME: (ptr noalias nocapture align 256 [[A:%.*]]) {
250 ; CGSCC-NEXT:  entry:
251 ; CGSCC-NEXT:    [[B:%.*]] = alloca i32, align 32
252 ; CGSCC-NEXT:    [[C:%.*]] = alloca ptr, align 64
253 ; CGSCC-NEXT:    [[PTR:%.*]] = alloca i32, align 128
254 ; CGSCC-NEXT:    store i32 42, ptr [[B]], align 32
255 ; CGSCC-NEXT:    store ptr [[B]], ptr [[C]], align 64
256 ; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
257 ; CGSCC-NEXT:    call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr noundef align 4294967296 null, ptr noalias nocapture noundef nonnull align 128 dereferenceable(4) [[PTR]], ptr nocapture noundef nonnull @t3_callback_callee, ptr nocapture align 256 [[A]], i64 noundef 99, ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C]])
258 ; CGSCC-NEXT:    ret void
260 entry:
261   %b = alloca i32, align 32
262   %c = alloca ptr, align 64
263   %ptr = alloca i32, align 128
264   store i32 42, ptr %b, align 4
265   store ptr %b, ptr %c, align 8
266   call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr null, ptr %ptr, ptr @t3_callback_callee, ptr %a, i64 99, ptr %c)
267   call void (ptr, ptr, ptr, ...) @t3_callback_broker(ptr null, ptr %ptr, ptr @t3_callback_callee, ptr %a, i64 99, ptr %c)
268   ret void
271 ; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
272 ; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
274 ; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.
275 define internal void @t3_callback_callee(ptr %is_not_null, ptr %ptr, ptr %a, i64 %b, ptr %c) {
277 ; TUNIT-LABEL: define {{[^@]+}}@t3_callback_callee
278 ; TUNIT-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr nocapture align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) {
279 ; TUNIT-NEXT:  entry:
280 ; TUNIT-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
281 ; TUNIT-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
282 ; TUNIT-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
283 ; TUNIT-NEXT:    tail call void @t3_check(ptr nocapture align 256 [[A]], i64 noundef 99, ptr nocapture align 32 [[TMP0]])
284 ; TUNIT-NEXT:    ret void
286 ; CGSCC-LABEL: define {{[^@]+}}@t3_callback_callee
287 ; CGSCC-SAME: (ptr nocapture nofree noundef nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], ptr nocapture nofree noundef nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], ptr nocapture align 256 [[A:%.*]], i64 [[B:%.*]], ptr noalias nocapture nofree noundef nonnull readonly align 64 dereferenceable(8) [[C:%.*]]) {
288 ; CGSCC-NEXT:  entry:
289 ; CGSCC-NEXT:    [[PTR_VAL:%.*]] = load i32, ptr [[PTR]], align 8
290 ; CGSCC-NEXT:    store i32 [[PTR_VAL]], ptr [[IS_NOT_NULL]], align 4
291 ; CGSCC-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[C]], align 64
292 ; CGSCC-NEXT:    tail call void @t3_check(ptr nocapture align 256 [[A]], i64 noundef 99, ptr nocapture [[TMP0]])
293 ; CGSCC-NEXT:    ret void
295 entry:
296   %ptr_val = load i32, ptr %ptr, align 8
297   store i32 %ptr_val, ptr %is_not_null
298   %0 = load ptr, ptr %c, align 8
299   tail call void @t3_check(ptr %a, i64 %b, ptr %0)
300   ret void
303 declare void @t3_check(ptr nocapture align 256, i64, ptr nocapture)
305 declare !callback !0 void @t3_callback_broker(ptr nocapture , ptr nocapture , ptr nocapture, ...)
307 !0 = !{!1}
308 !1 = !{i64 2, i64 -1, i64 -1, i1 true}
310 ; CHECK: attributes #[[ATTR0:[0-9]+]] = { nosync }
312 ; CHECK: [[META0:![0-9]+]] = !{!1}
313 ; CHECK: [[META1:![0-9]+]] = !{i64 2, i64 -1, i64 -1, i1 true}
315 ;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
316 ; CHECK: {{.*}}