1 // RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | FileCheck %s --check-prefix=RUN1
2 // RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | FileCheck %s --check-prefix=RUN2
3 // RUN: %clang_cc1 -triple i386-unknown-unknown -fopenmp -O1 %s -emit-llvm -o - | opt -ipconstprop -S | FileCheck --check-prefix=IPCP %s
4 
5 // RUN1-DAG: @broker0({{[^#]*#[0-9]+}} !callback ![[cid0:[0-9]+]]
6 __attribute__((callback(1, 2))) void *broker0(void *(*callee)(void *), void *payload) {
7   return callee(payload);
8 }
9 
10 // RUN1-DAG: @broker1({{[^#]*#[0-9]+}} !callback ![[cid1:[0-9]+]]
11 __attribute__((callback(callee, payload))) void *broker1(void *payload, void *(*callee)(void *)) {
12   return broker0(callee, payload);
13 }
14 
15 void *broker2(void (*callee)(void));
16 
17 // RUN1-DAG: declare !callback ![[cid2:[0-9]+]] i8* @broker2
18 __attribute__((callback(callee))) void *broker2(void (*callee)(void));
19 
20 void *broker2(void (*callee)(void));
21 
22 // RUN1-DAG: declare !callback ![[cid3:[0-9]+]] i8* @broker3
23 __attribute__((callback(4, 1, 2, c))) void *broker3(int, int, int c, int (*callee)(int, int, int), int);
24 
25 // RUN1-DAG: declare !callback ![[cid4:[0-9]+]] i8* @broker4
26 __attribute__((callback(4, -1, a, __))) void *broker4(int a, int, int, int (*callee)(int, int, int), int);
27 
28 // RUN1-DAG: declare !callback ![[cid5:[0-9]+]] i8* @broker5
29 __attribute__((callback(4, d, 5, 2))) void *broker5(int, int, int, int (*callee)(int, int, int), int d);
30 
31 static void *VoidPtr2VoidPtr(void *payload) {
32   // RUN2: ret i8* %payload
33   // IPCP: ret i8* null
34   return payload;
35 }
36 
37 static int ThreeInt2Int(int a, int b, int c) {
38   // RUN2:   define internal i32 @ThreeInt2Int(i32 %a, i32 %b, i32 %c)
39   // RUN2:     %mul = mul nsw i32 %b, %a
40   // RUN2:     %add = add nsw i32 %mul, %c
41   // RUN2:     ret i32 %add
42 
43   // IPCP:   define internal i32 @ThreeInt2Int(i32 %a, i32 %b, i32 %c)
44   // IPCP:     %mul = mul nsw i32 4, %a
45   // IPCP:     %add = add nsw i32 %mul, %c
46   // IPCP:     ret i32 %add
47 
48   return a * b + c;
49 }
50 
51 void foo() {
52   broker0(VoidPtr2VoidPtr, 0l);
53   broker1(0l, VoidPtr2VoidPtr);
54   broker2(foo);
55   broker3(1, 4, 5, ThreeInt2Int, 1);
56   broker4(4, 2, 7, ThreeInt2Int, 0);
57   broker5(8, 0, 3, ThreeInt2Int, 4);
58 }
59 
60 // RUN1-DAG: ![[cid0]] = !{![[cid0b:[0-9]+]]}
61 // RUN1-DAG: ![[cid0b]] = !{i64 0, i64 1, i1 false}
62 // RUN1-DAG: ![[cid1]] = !{![[cid1b:[0-9]+]]}
63 // RUN1-DAG: ![[cid1b]] = !{i64 1, i64 0, i1 false}
64 // RUN1-DAG: ![[cid2]] = !{![[cid2b:[0-9]+]]}
65 // RUN1-DAG: ![[cid2b]] = !{i64 0, i1 false}
66 // RUN1-DAG: ![[cid3]] = !{![[cid3b:[0-9]+]]}
67 // RUN1-DAG: ![[cid3b]] = !{i64 3, i64 0, i64 1, i64 2, i1 false}
68 // RUN1-DAG: ![[cid4]] = !{![[cid4b:[0-9]+]]}
69 // RUN1-DAG: ![[cid4b]] = !{i64 3, i64 -1, i64 0, i64 -1, i1 false}
70 // RUN1-DAG: ![[cid5]] = !{![[cid5b:[0-9]+]]}
71 // RUN1-DAG: ![[cid5b]] = !{i64 3, i64 4, i64 4, i64 1, i1 false}
72