1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; RUN: opt -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_NPM,NOT_CGSCC_OPM,NOT_TUNIT_NPM,IS__TUNIT____,IS________OPM,IS__TUNIT_OPM
3; RUN: opt -aa-pipeline=basic-aa -passes=attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations=3 -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_CGSCC_OPM,NOT_CGSCC_NPM,NOT_TUNIT_OPM,IS__TUNIT____,IS________NPM,IS__TUNIT_NPM
4; RUN: opt -attributor-cgscc -attributor-manifest-internal -attributor-disable=false -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_NPM,IS__CGSCC____,IS________OPM,IS__CGSCC_OPM
5; RUN: opt -aa-pipeline=basic-aa -passes=attributor-cgscc -attributor-manifest-internal -attributor-disable=false -attributor-annotate-decl-cs -S < %s | FileCheck %s --check-prefixes=CHECK,NOT_TUNIT_NPM,NOT_TUNIT_OPM,NOT_CGSCC_OPM,IS__CGSCC____,IS________NPM,IS__CGSCC_NPM
6
7target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
8
9; Test 0
10;
11; Make sure we propagate information from the caller to the callback callee but
12; only for arguments that are mapped through the callback metadata. Here, the
13; first two arguments of the call and the callback callee do not correspond to
14; each other but argument 3-5 of the transitive call site in the caller match
15; arguments 2-4 of the callback callee. Here we should see information and value
16; transfer in both directions.
17
18define void @t0_caller(i32* %a) {
19; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t0_caller
20; IS__TUNIT_OPM-SAME: (i32* align 256 [[A:%.*]])
21; IS__TUNIT_OPM-NEXT:  entry:
22; IS__TUNIT_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
23; IS__TUNIT_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
24; IS__TUNIT_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
25; IS__TUNIT_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
26; IS__TUNIT_OPM-NEXT:    store i32 42, i32* [[B]], align 32
27; IS__TUNIT_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
28; IS__TUNIT_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
29; IS__TUNIT_OPM-NEXT:    ret void
30;
31; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_caller
32; IS__TUNIT_NPM-SAME: (i32* align 256 [[A:%.*]])
33; IS__TUNIT_NPM-NEXT:  entry:
34; IS__TUNIT_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
35; IS__TUNIT_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
36; IS__TUNIT_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
37; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
38; IS__TUNIT_NPM-NEXT:    store i32 42, i32* [[B]], align 32
39; IS__TUNIT_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
40; IS__TUNIT_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
41; IS__TUNIT_NPM-NEXT:    ret void
42;
43; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t0_caller
44; IS__CGSCC_OPM-SAME: (i32* [[A:%.*]])
45; IS__CGSCC_OPM-NEXT:  entry:
46; IS__CGSCC_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
47; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
48; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
49; IS__CGSCC_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
50; IS__CGSCC_OPM-NEXT:    store i32 42, i32* [[B]], align 32
51; IS__CGSCC_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
52; IS__CGSCC_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
53; IS__CGSCC_OPM-NEXT:    ret void
54;
55; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_caller
56; IS__CGSCC_NPM-SAME: (i32* align 256 [[A:%.*]])
57; IS__CGSCC_NPM-NEXT:  entry:
58; IS__CGSCC_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
59; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
60; IS__CGSCC_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
61; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
62; IS__CGSCC_NPM-NEXT:    store i32 42, i32* [[B]], align 32
63; IS__CGSCC_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
64; IS__CGSCC_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
65; IS__CGSCC_NPM-NEXT:    ret void
66;
67entry:
68  %b = alloca i32, align 32
69  %c = alloca i32*, align 64
70  %ptr = alloca i32, align 128
71  %0 = bitcast i32* %b to i8*
72  store i32 42, i32* %b, align 4
73  store i32* %b, i32** %c, align 8
74  call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t0_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t0_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c)
75  ret void
76}
77
78; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
79; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
80define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
81;
82; IS________OPM-LABEL: define {{[^@]+}}@t0_callback_callee
83; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
84; IS________OPM-NEXT:  entry:
85; IS________OPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
86; IS________OPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
87; IS________OPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
88; IS________OPM-NEXT:    tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]])
89; IS________OPM-NEXT:    ret void
90;
91; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t0_callback_callee
92; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
93; IS__TUNIT_NPM-NEXT:  entry:
94; IS__TUNIT_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
95; IS__TUNIT_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
96; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
97; IS__TUNIT_NPM-NEXT:    tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]])
98; IS__TUNIT_NPM-NEXT:    ret void
99;
100; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t0_callback_callee
101; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]])
102; IS__CGSCC_NPM-NEXT:  entry:
103; IS__CGSCC_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
104; IS__CGSCC_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
105; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
106; IS__CGSCC_NPM-NEXT:    tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]])
107; IS__CGSCC_NPM-NEXT:    ret void
108;
109entry:
110  %ptr_val = load i32, i32* %ptr, align 8
111  store i32 %ptr_val, i32* %is_not_null
112  %0 = load i32*, i32** %c, align 8
113  tail call void @t0_check(i32* %a, i64 %b, i32* %0)
114  ret void
115}
116
117declare void @t0_check(i32* align 256, i64, i32*)
118
119declare !callback !0 void @t0_callback_broker(i32*, i32*, void (i32*, i32*, ...)*, ...)
120
121; Test 1
122;
123; Similar to test 0 but with some additional annotations (noalias/nocapute) to make sure
124; we deduce and propagate noalias and others properly.
125
126define void @t1_caller(i32* noalias %a) {
127; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t1_caller
128; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
129; IS__TUNIT_OPM-NEXT:  entry:
130; IS__TUNIT_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
131; IS__TUNIT_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
132; IS__TUNIT_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
133; IS__TUNIT_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
134; IS__TUNIT_OPM-NEXT:    store i32 42, i32* [[B]], align 32
135; IS__TUNIT_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
136; IS__TUNIT_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
137; IS__TUNIT_OPM-NEXT:    ret void
138;
139; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_caller
140; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
141; IS__TUNIT_NPM-NEXT:  entry:
142; IS__TUNIT_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
143; IS__TUNIT_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
144; IS__TUNIT_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
145; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
146; IS__TUNIT_NPM-NEXT:    store i32 42, i32* [[B]], align 32
147; IS__TUNIT_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
148; IS__TUNIT_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
149; IS__TUNIT_NPM-NEXT:    ret void
150;
151; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t1_caller
152; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]])
153; IS__CGSCC_OPM-NEXT:  entry:
154; IS__CGSCC_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
155; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
156; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
157; IS__CGSCC_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
158; IS__CGSCC_OPM-NEXT:    store i32 42, i32* [[B]], align 32
159; IS__CGSCC_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
160; IS__CGSCC_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
161; IS__CGSCC_OPM-NEXT:    ret void
162;
163; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_caller
164; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
165; IS__CGSCC_NPM-NEXT:  entry:
166; IS__CGSCC_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
167; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
168; IS__CGSCC_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
169; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
170; IS__CGSCC_NPM-NEXT:    store i32 42, i32* [[B]], align 32
171; IS__CGSCC_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
172; IS__CGSCC_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
173; IS__CGSCC_NPM-NEXT:    ret void
174;
175entry:
176  %b = alloca i32, align 32
177  %c = alloca i32*, align 64
178  %ptr = alloca i32, align 128
179  %0 = bitcast i32* %b to i8*
180  store i32 42, i32* %b, align 4
181  store i32* %b, i32** %c, align 8
182  call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t1_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t1_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c)
183  ret void
184}
185
186; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
187; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
188define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
189;
190; IS________OPM-LABEL: define {{[^@]+}}@t1_callback_callee
191; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
192; IS________OPM-NEXT:  entry:
193; IS________OPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
194; IS________OPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
195; IS________OPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
196; IS________OPM-NEXT:    tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
197; IS________OPM-NEXT:    ret void
198;
199; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t1_callback_callee
200; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* noalias nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
201; IS__TUNIT_NPM-NEXT:  entry:
202; IS__TUNIT_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
203; IS__TUNIT_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
204; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
205; IS__TUNIT_NPM-NEXT:    tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
206; IS__TUNIT_NPM-NEXT:    ret void
207;
208; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t1_callback_callee
209; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]])
210; IS__CGSCC_NPM-NEXT:  entry:
211; IS__CGSCC_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
212; IS__CGSCC_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
213; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
214; IS__CGSCC_NPM-NEXT:    tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
215; IS__CGSCC_NPM-NEXT:    ret void
216;
217entry:
218  %ptr_val = load i32, i32* %ptr, align 8
219  store i32 %ptr_val, i32* %is_not_null
220  %0 = load i32*, i32** %c, align 8
221  tail call void @t1_check(i32* %a, i64 %b, i32* %0)
222  ret void
223}
224
225declare void @t1_check(i32* nocapture align 256, i64, i32* nocapture) nosync
226
227declare !callback !0 void @t1_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...)
228
229; Test 2
230;
231; Similar to test 1 but checking that the noalias is only placed if potential synchronization through @t2_check is preserved.
232
233define void @t2_caller(i32* noalias %a) {
234; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t2_caller
235; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
236; IS__TUNIT_OPM-NEXT:  entry:
237; IS__TUNIT_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
238; IS__TUNIT_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
239; IS__TUNIT_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
240; IS__TUNIT_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
241; IS__TUNIT_OPM-NEXT:    store i32 42, i32* [[B]], align 32
242; IS__TUNIT_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
243; IS__TUNIT_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
244; IS__TUNIT_OPM-NEXT:    ret void
245;
246; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_caller
247; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
248; IS__TUNIT_NPM-NEXT:  entry:
249; IS__TUNIT_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
250; IS__TUNIT_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
251; IS__TUNIT_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
252; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
253; IS__TUNIT_NPM-NEXT:    store i32 42, i32* [[B]], align 32
254; IS__TUNIT_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
255; IS__TUNIT_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
256; IS__TUNIT_NPM-NEXT:    ret void
257;
258; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t2_caller
259; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]])
260; IS__CGSCC_OPM-NEXT:  entry:
261; IS__CGSCC_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
262; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
263; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
264; IS__CGSCC_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
265; IS__CGSCC_OPM-NEXT:    store i32 42, i32* [[B]], align 32
266; IS__CGSCC_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
267; IS__CGSCC_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
268; IS__CGSCC_OPM-NEXT:    ret void
269;
270; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_caller
271; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
272; IS__CGSCC_NPM-NEXT:  entry:
273; IS__CGSCC_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
274; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
275; IS__CGSCC_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
276; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
277; IS__CGSCC_NPM-NEXT:    store i32 42, i32* [[B]], align 32
278; IS__CGSCC_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
279; IS__CGSCC_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
280; IS__CGSCC_NPM-NEXT:    ret void
281;
282entry:
283  %b = alloca i32, align 32
284  %c = alloca i32*, align 64
285  %ptr = alloca i32, align 128
286  %0 = bitcast i32* %b to i8*
287  store i32 42, i32* %b, align 4
288  store i32* %b, i32** %c, align 8
289  call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t2_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t2_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c)
290  ret void
291}
292
293; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
294; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
295;
296; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.
297define internal void @t2_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
298;
299; IS________OPM-LABEL: define {{[^@]+}}@t2_callback_callee
300; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
301; IS________OPM-NEXT:  entry:
302; IS________OPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
303; IS________OPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
304; IS________OPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
305; IS________OPM-NEXT:    tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
306; IS________OPM-NEXT:    ret void
307;
308; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t2_callback_callee
309; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
310; IS__TUNIT_NPM-NEXT:  entry:
311; IS__TUNIT_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
312; IS__TUNIT_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
313; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
314; IS__TUNIT_NPM-NEXT:    tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
315; IS__TUNIT_NPM-NEXT:    ret void
316;
317; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t2_callback_callee
318; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]])
319; IS__CGSCC_NPM-NEXT:  entry:
320; IS__CGSCC_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
321; IS__CGSCC_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
322; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
323; IS__CGSCC_NPM-NEXT:    tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
324; IS__CGSCC_NPM-NEXT:    ret void
325;
326entry:
327  %ptr_val = load i32, i32* %ptr, align 8
328  store i32 %ptr_val, i32* %is_not_null
329  %0 = load i32*, i32** %c, align 8
330  tail call void @t2_check(i32* %a, i64 %b, i32* %0)
331  ret void
332}
333
334declare void @t2_check(i32* nocapture align 256, i64, i32* nocapture)
335
336declare !callback !0 void @t2_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...)
337
338; Test 3
339;
340; Basically test 2 with the casted callback callee used twice.
341
342define void @t3_caller(i32* noalias %a) {
343; IS__TUNIT_OPM-LABEL: define {{[^@]+}}@t3_caller
344; IS__TUNIT_OPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
345; IS__TUNIT_OPM-NEXT:  entry:
346; IS__TUNIT_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
347; IS__TUNIT_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
348; IS__TUNIT_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
349; IS__TUNIT_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
350; IS__TUNIT_OPM-NEXT:    store i32 42, i32* [[B]], align 32
351; IS__TUNIT_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
352; IS__TUNIT_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
353; IS__TUNIT_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* nocapture align 256 [[A]], i64 undef, i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
354; IS__TUNIT_OPM-NEXT:    ret void
355;
356; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_caller
357; IS__TUNIT_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
358; IS__TUNIT_NPM-NEXT:  entry:
359; IS__TUNIT_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
360; IS__TUNIT_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
361; IS__TUNIT_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
362; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
363; IS__TUNIT_NPM-NEXT:    store i32 42, i32* [[B]], align 32
364; IS__TUNIT_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
365; IS__TUNIT_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
366; IS__TUNIT_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* nonnull bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 undef, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
367; IS__TUNIT_NPM-NEXT:    ret void
368;
369; IS__CGSCC_OPM-LABEL: define {{[^@]+}}@t3_caller
370; IS__CGSCC_OPM-SAME: (i32* noalias [[A:%.*]])
371; IS__CGSCC_OPM-NEXT:  entry:
372; IS__CGSCC_OPM-NEXT:    [[B:%.*]] = alloca i32, align 32
373; IS__CGSCC_OPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
374; IS__CGSCC_OPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
375; IS__CGSCC_OPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
376; IS__CGSCC_OPM-NEXT:    store i32 42, i32* [[B]], align 32
377; IS__CGSCC_OPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
378; IS__CGSCC_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
379; IS__CGSCC_OPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* [[A]], i64 99, i32** nonnull align 64 dereferenceable(8) [[C]])
380; IS__CGSCC_OPM-NEXT:    ret void
381;
382; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_caller
383; IS__CGSCC_NPM-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
384; IS__CGSCC_NPM-NEXT:  entry:
385; IS__CGSCC_NPM-NEXT:    [[B:%.*]] = alloca i32, align 32
386; IS__CGSCC_NPM-NEXT:    [[C:%.*]] = alloca i32*, align 64
387; IS__CGSCC_NPM-NEXT:    [[PTR:%.*]] = alloca i32, align 128
388; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
389; IS__CGSCC_NPM-NEXT:    store i32 42, i32* [[B]], align 32
390; IS__CGSCC_NPM-NEXT:    store i32* [[B]], i32** [[C]], align 64
391; IS__CGSCC_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
392; IS__CGSCC_NPM-NEXT:    call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* noalias align 536870912 null, i32* noalias nonnull align 128 dereferenceable(4) [[PTR]], void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* noalias nocapture align 256 [[A]], i64 99, i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C]])
393; IS__CGSCC_NPM-NEXT:    ret void
394;
395entry:
396  %b = alloca i32, align 32
397  %c = alloca i32*, align 64
398  %ptr = alloca i32, align 128
399  %0 = bitcast i32* %b to i8*
400  store i32 42, i32* %b, align 4
401  store i32* %b, i32** %c, align 8
402  call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c)
403  call void (i32*, i32*, void (i32*, i32*, ...)*, ...) @t3_callback_broker(i32* null, i32* %ptr, void (i32*, i32*, ...)* bitcast (void (i32*, i32*, i32*, i64, i32**)* @t3_callback_callee to void (i32*, i32*, ...)*), i32* %a, i64 99, i32** %c)
404  ret void
405}
406
407; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
408; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
409;
410; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.
411define internal void @t3_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
412;
413; IS________OPM-LABEL: define {{[^@]+}}@t3_callback_callee
414; IS________OPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
415; IS________OPM-NEXT:  entry:
416; IS________OPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
417; IS________OPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
418; IS________OPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
419; IS________OPM-NEXT:    tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
420; IS________OPM-NEXT:    ret void
421;
422; IS__TUNIT_NPM-LABEL: define {{[^@]+}}@t3_callback_callee
423; IS__TUNIT_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** noalias nocapture nonnull readonly align 64 dereferenceable(8) [[C:%.*]])
424; IS__TUNIT_NPM-NEXT:  entry:
425; IS__TUNIT_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
426; IS__TUNIT_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
427; IS__TUNIT_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
428; IS__TUNIT_NPM-NEXT:    tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
429; IS__TUNIT_NPM-NEXT:    ret void
430;
431; IS__CGSCC_NPM-LABEL: define {{[^@]+}}@t3_callback_callee
432; IS__CGSCC_NPM-SAME: (i32* nocapture nonnull writeonly align 4 dereferenceable(4) [[IS_NOT_NULL:%.*]], i32* nocapture nonnull readonly align 8 dereferenceable(4) [[PTR:%.*]], i32* nocapture align 256 [[A:%.*]], i64 [[B:%.*]], i32** nocapture nonnull readonly align 8 dereferenceable(8) [[C:%.*]])
433; IS__CGSCC_NPM-NEXT:  entry:
434; IS__CGSCC_NPM-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
435; IS__CGSCC_NPM-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
436; IS__CGSCC_NPM-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 8
437; IS__CGSCC_NPM-NEXT:    tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
438; IS__CGSCC_NPM-NEXT:    ret void
439;
440entry:
441  %ptr_val = load i32, i32* %ptr, align 8
442  store i32 %ptr_val, i32* %is_not_null
443  %0 = load i32*, i32** %c, align 8
444  tail call void @t3_check(i32* %a, i64 %b, i32* %0)
445  ret void
446}
447
448declare void @t3_check(i32* nocapture align 256, i64, i32* nocapture)
449
450declare !callback !0 void @t3_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...)
451
452!0 = !{!1}
453!1 = !{i64 2, i64 -1, i64 -1, i1 true}
454