1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; FIXME: Add -attributor-max-iterations-verify -attributor-annotate-decl-cs -attributor-max-iterations below.
3;        This flag was removed because max iterations is 2 in most cases, but in windows it is 1.
4; RUN: opt -S -passes=attributor -aa-pipeline='basic-aa' -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s
5; ModuleID = 'callback_simple.c'
6target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
7
8; Test 0
9;
10; Make sure we propagate information from the caller to the callback callee but
11; only for arguments that are mapped through the callback metadata. Here, the
12; first two arguments of the call and the callback callee do not correspond to
13; each other but argument 3-5 of the transitive call site in the caller match
14; arguments 2-4 of the callback callee. Here we should see information and value
15; transfer in both directions.
16
17define void @t0_caller(i32* %a) {
18; CHECK-LABEL: define {{[^@]+}}@t0_caller
19; CHECK-SAME: (i32* align 256 [[A:%.*]])
20; CHECK-NEXT:  entry:
21; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 32
22; CHECK-NEXT:    [[C:%.*]] = alloca i32*, align 64
23; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 128
24; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
25; CHECK-NEXT:    store i32 42, i32* [[B]], align 32
26; CHECK-NEXT:    store i32* [[B]], i32** [[C]], align 64
27; CHECK-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]])
28; CHECK-NEXT:    ret void
29;
30
31entry:
32  %b = alloca i32, align 32
33  %c = alloca i32*, align 64
34  %ptr = alloca i32, align 128
35  %0 = bitcast i32* %b to i8*
36  store i32 42, i32* %b, align 4
37  store i32* %b, i32** %c, align 8
38  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)
39  ret void
40}
41
42; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
43; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
44define internal void @t0_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
45; CHECK-LABEL: define {{[^@]+}}@t0_callback_callee
46; CHECK-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:%.*]])
47; CHECK-NEXT:  entry:
48; CHECK-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
49; CHECK-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
50; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
51; CHECK-NEXT:    tail call void @t0_check(i32* align 256 [[A]], i64 99, i32* [[TMP0]])
52; CHECK-NEXT:    ret void
53;
54entry:
55  %ptr_val = load i32, i32* %ptr, align 8
56  store i32 %ptr_val, i32* %is_not_null
57  %0 = load i32*, i32** %c, align 8
58  tail call void @t0_check(i32* %a, i64 %b, i32* %0)
59  ret void
60}
61
62declare void @t0_check(i32* align 256, i64, i32*)
63
64declare !callback !0 void @t0_callback_broker(i32*, i32*, void (i32*, i32*, ...)*, ...)
65
66; Test 1
67;
68; Similar to test 0 but with some additional annotations (noalias/nocapute) to make sure
69; we deduce and propagate noalias and others properly.
70
71define void @t1_caller(i32* noalias %a) {
72; CHECK-LABEL: define {{[^@]+}}@t1_caller
73; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
74; CHECK-NEXT:  entry:
75; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 32
76; CHECK-NEXT:    [[C:%.*]] = alloca i32*, align 64
77; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 128
78; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
79; CHECK-NEXT:    store i32 42, i32* [[B]], align 32
80; CHECK-NEXT:    store i32* [[B]], i32** [[C]], align 64
81; CHECK-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]])
82; CHECK-NEXT:    ret void
83;
84entry:
85  %b = alloca i32, align 32
86  %c = alloca i32*, align 64
87  %ptr = alloca i32, align 128
88  %0 = bitcast i32* %b to i8*
89  store i32 42, i32* %b, align 4
90  store i32* %b, i32** %c, align 8
91  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)
92  ret void
93}
94
95; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
96; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
97define internal void @t1_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
98; CHECK-LABEL: define {{[^@]+}}@t1_callback_callee
99; CHECK-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:%.*]])
100; CHECK-NEXT:  entry:
101; CHECK-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
102; CHECK-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
103; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
104; CHECK-NEXT:    tail call void @t1_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
105; CHECK-NEXT:    ret void
106;
107entry:
108  %ptr_val = load i32, i32* %ptr, align 8
109  store i32 %ptr_val, i32* %is_not_null
110  %0 = load i32*, i32** %c, align 8
111  tail call void @t1_check(i32* %a, i64 %b, i32* %0)
112  ret void
113}
114
115declare void @t1_check(i32* nocapture align 256, i64, i32* nocapture) nosync
116
117declare !callback !0 void @t1_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...)
118
119; Test 2
120;
121; Similar to test 1 but checking that the noalias is only placed if potential synchronization through @t2_check is preserved.
122
123define void @t2_caller(i32* noalias %a) {
124; CHECK-LABEL: define {{[^@]+}}@t2_caller
125; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
126; CHECK-NEXT:  entry:
127; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 32
128; CHECK-NEXT:    [[C:%.*]] = alloca i32*, align 64
129; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 128
130; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
131; CHECK-NEXT:    store i32 42, i32* [[B]], align 32
132; CHECK-NEXT:    store i32* [[B]], i32** [[C]], align 64
133; CHECK-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]])
134; CHECK-NEXT:    ret void
135;
136entry:
137  %b = alloca i32, align 32
138  %c = alloca i32*, align 64
139  %ptr = alloca i32, align 128
140  %0 = bitcast i32* %b to i8*
141  store i32 42, i32* %b, align 4
142  store i32* %b, i32** %c, align 8
143  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)
144  ret void
145}
146
147; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
148; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
149;
150; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.
151define internal void @t2_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
152; CHECK-LABEL: define {{[^@]+}}@t2_callback_callee
153; CHECK-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:%.*]])
154; CHECK-NEXT:  entry:
155; CHECK-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
156; CHECK-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
157; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
158; CHECK-NEXT:    tail call void @t2_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
159; CHECK-NEXT:    ret void
160;
161entry:
162  %ptr_val = load i32, i32* %ptr, align 8
163  store i32 %ptr_val, i32* %is_not_null
164  %0 = load i32*, i32** %c, align 8
165  tail call void @t2_check(i32* %a, i64 %b, i32* %0)
166  ret void
167}
168
169declare void @t2_check(i32* nocapture align 256, i64, i32* nocapture)
170
171declare !callback !0 void @t2_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...)
172
173; Test 3
174;
175; Basically test 2 with the casted callback callee used twice.
176
177define void @t3_caller(i32* noalias %a) {
178; CHECK-LABEL: define {{[^@]+}}@t3_caller
179; CHECK-SAME: (i32* noalias nocapture align 256 [[A:%.*]])
180; CHECK-NEXT:  entry:
181; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 32
182; CHECK-NEXT:    [[C:%.*]] = alloca i32*, align 64
183; CHECK-NEXT:    [[PTR:%.*]] = alloca i32, align 128
184; CHECK-NEXT:    [[TMP0:%.*]] = bitcast i32* [[B]] to i8*
185; CHECK-NEXT:    store i32 42, i32* [[B]], align 32
186; CHECK-NEXT:    store i32* [[B]], i32** [[C]], align 64
187; CHECK-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]])
188; CHECK-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]])
189; CHECK-NEXT:    ret void
190;
191entry:
192  %b = alloca i32, align 32
193  %c = alloca i32*, align 64
194  %ptr = alloca i32, align 128
195  %0 = bitcast i32* %b to i8*
196  store i32 42, i32* %b, align 4
197  store i32* %b, i32** %c, align 8
198  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)
199  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)
200  ret void
201}
202
203; Note that the first two arguments are provided by the callback_broker according to the callback in !1 below!
204; The others are annotated with alignment information, amongst others, or even replaced by the constants passed to the call.
205;
206; FIXME: We should derive noalias for %a and add a "fake use" of %a in all potentially synchronizing calls.
207define internal void @t3_callback_callee(i32* %is_not_null, i32* %ptr, i32* %a, i64 %b, i32** %c) {
208; CHECK-LABEL: define {{[^@]+}}@t3_callback_callee
209; CHECK-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:%.*]])
210; CHECK-NEXT:  entry:
211; CHECK-NEXT:    [[PTR_VAL:%.*]] = load i32, i32* [[PTR]], align 8
212; CHECK-NEXT:    store i32 [[PTR_VAL]], i32* [[IS_NOT_NULL]], align 4
213; CHECK-NEXT:    [[TMP0:%.*]] = load i32*, i32** [[C]], align 64
214; CHECK-NEXT:    tail call void @t3_check(i32* nocapture align 256 [[A]], i64 99, i32* [[TMP0]])
215; CHECK-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 @t3_check(i32* %a, i64 %b, i32* %0)
222  ret void
223}
224
225declare void @t3_check(i32* nocapture align 256, i64, i32* nocapture)
226
227declare !callback !0 void @t3_callback_broker(i32* nocapture , i32* nocapture , void (i32*, i32*, ...)* nocapture, ...)
228
229!0 = !{!1}
230!1 = !{i64 2, i64 -1, i64 -1, i1 true}
231