1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --scrub-attributes
2; RUN: opt -S -attributor -attributor-disable=false < %s | FileCheck %s --check-prefixes=ALL,CHECK
3; RUN: opt -S -aa-pipeline='basic-aa' -passes=attributor -attributor-disable=false -attributor-annotate-decl-cs < %s | FileCheck %s --check-prefixes=ALL,DECL_CS
4;
5; Mostly check we do not crash on these uses
6
7define internal void @internal(void (i8*)* %fp) {
8; CHECK-LABEL: define {{[^@]+}}@internal
9; CHECK-SAME: (void (i8*)* nonnull [[FP:%.*]])
10; CHECK-NEXT:  entry:
11; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
12; CHECK-NEXT:    call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
13; CHECK-NEXT:    call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
14; CHECK-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
15; CHECK-NEXT:    call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
16; CHECK-NEXT:    call void @callback2(void (i8*)* [[FP]])
17; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
18; CHECK-NEXT:    call void [[FP]](i8* [[TMP1]])
19; CHECK-NEXT:    ret void
20;
21; DECL_CS-LABEL: define {{[^@]+}}@internal
22; DECL_CS-SAME: (void (i8*)* nonnull [[FP:%.*]])
23; DECL_CS-NEXT:  entry:
24; DECL_CS-NEXT:    [[A:%.*]] = alloca i32, align 4
25; DECL_CS-NEXT:    call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
26; DECL_CS-NEXT:    call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
27; DECL_CS-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
28; DECL_CS-NEXT:    call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
29; DECL_CS-NEXT:    call void @callback2(void (i8*)* nonnull [[FP]])
30; DECL_CS-NEXT:    [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
31; DECL_CS-NEXT:    call void [[FP]](i8* [[TMP1]])
32; DECL_CS-NEXT:    ret void
33;
34entry:
35  %a = alloca i32, align 4
36  %tmp = bitcast i32* %a to i8*
37  call void @foo(i32* nonnull %a)
38  call void %fp(i8* bitcast (void (i32*)* @foo to i8*))
39  call void @callback1(void (i32*)* nonnull @foo)
40  call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
41  call void @callback2(void (i8*)* %fp)
42  %tmp1 = bitcast i32* %a to i8*
43  call void %fp(i8* %tmp1)
44  ret void
45}
46
47define void @external(void (i8*)* %fp) {
48; CHECK-LABEL: define {{[^@]+}}@external
49; CHECK-SAME: (void (i8*)* [[FP:%.*]])
50; CHECK-NEXT:  entry:
51; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
52; CHECK-NEXT:    call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
53; CHECK-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
54; CHECK-NEXT:    call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
55; CHECK-NEXT:    call void @callback2(void (i8*)* [[FP]])
56; CHECK-NEXT:    call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
57; CHECK-NEXT:    [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
58; CHECK-NEXT:    call void [[FP]](i8* [[TMP1]])
59; CHECK-NEXT:    call void @internal(void (i8*)* nonnull [[FP]])
60; CHECK-NEXT:    ret void
61;
62; DECL_CS-LABEL: define {{[^@]+}}@external
63; DECL_CS-SAME: (void (i8*)* [[FP:%.*]])
64; DECL_CS-NEXT:  entry:
65; DECL_CS-NEXT:    [[A:%.*]] = alloca i32, align 4
66; DECL_CS-NEXT:    call void @foo(i32* noalias nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A]])
67; DECL_CS-NEXT:    call void @callback1(void (i32*)* nonnull @foo)
68; DECL_CS-NEXT:    call void @callback2(void (i8*)* nonnull bitcast (void (i32*)* @foo to void (i8*)*))
69; DECL_CS-NEXT:    call void @callback2(void (i8*)* [[FP]])
70; DECL_CS-NEXT:    call void [[FP]](i8* bitcast (void (i32*)* @foo to i8*))
71; DECL_CS-NEXT:    [[TMP1:%.*]] = bitcast i32* [[A]] to i8*
72; DECL_CS-NEXT:    call void [[FP]](i8* [[TMP1]])
73; DECL_CS-NEXT:    call void @internal(void (i8*)* nonnull [[FP]])
74; DECL_CS-NEXT:    ret void
75;
76entry:
77  %a = alloca i32, align 4
78  %tmp = bitcast i32* %a to i8*
79  call void @foo(i32* nonnull %a)
80  call void @callback1(void (i32*)* nonnull @foo)
81  call void @callback2(void (i8*)* bitcast (void (i32*)* @foo to void (i8*)*))
82  call void @callback2(void (i8*)* %fp)
83  call void %fp(i8* bitcast (void (i32*)* @foo to i8*))
84  %tmp1 = bitcast i32* %a to i8*
85  call void %fp(i8* %tmp1)
86  call void @internal(void (i8*)* %fp)
87  ret void
88}
89
90define internal void @foo(i32* %a) {
91; ALL-LABEL: define {{[^@]+}}@foo
92; ALL-SAME: (i32* nocapture nofree nonnull writeonly align 4 dereferenceable(4) [[A:%.*]])
93; ALL-NEXT:  entry:
94; ALL-NEXT:    store i32 0, i32* [[A]], align 4
95; ALL-NEXT:    ret void
96;
97entry:
98  store i32 0, i32* %a
99  ret void
100}
101
102declare void @callback1(void (i32*)*)
103declare void @callback2(void (i8*)*)
104