1 // RUN: %clang_cc1 -triple x86_64-gnu-linux -emit-llvm %s -o - | FileCheck %s
3 #define __maybe_undef __attribute__((maybe_undef))
5 // CHECK: define{{.*}} void @t1(i32 noundef [[TMP1:%.*]], i32 noundef [[TMP2:%.*]], i32 noundef [[TMP3:%.*]])
7 // CHECK-NEXT: [[TMP4:%.*]] = alloca i32, align 4
8 // CHECK-NEXT: [[TMP5:%.*]] = alloca i32, align 4
9 // CHECK-NEXT: [[TMP6:%.*]] = alloca i32, align 4
10 // CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[TMP4:%.*]], align 4
11 // CHECK-NEXT: store i32 [[TMP2:%.*]], ptr [[TMP5:%.*]], align 4
12 // CHECK-NEXT: store i32 [[TMP3:%.*]], ptr [[TMP6:%.*]], align 4
13 // CHECK-NEXT: ret void
15 // CHECK: define{{.*}} void @t2(i32 noundef [[TMP1:%.*]], i32 noundef [[TMP2:%.*]], i32 noundef [[TMP3:%.*]])
17 // CHECK-NEXT: [[TMP4:%.*]] = alloca i32, align 4
18 // CHECK-NEXT: [[TMP5:%.*]] = alloca i32, align 4
19 // CHECK-NEXT: [[TMP6:%.*]] = alloca i32, align 4
20 // CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[TMP4:%.*]], align 4
21 // CHECK-NEXT: store i32 [[TMP2:%.*]], ptr [[TMP5:%.*]], align 4
22 // CHECK-NEXT: store i32 [[TMP3:%.*]], ptr [[TMP6:%.*]], align 4
23 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[TMP4:%.*]], align 4
24 // CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP5:%.*]], align 4
25 // CHECK-NEXT: [[TMP9:%.*]] = load i32, ptr [[TMP6:%.*]], align 4
26 // CHECK-NEXT: [[TMP10:%.*]] = freeze i32 [[TMP8:%.*]]
27 // CHECK-NEXT: call void @t1(i32 noundef [[TMP7:%.*]], i32 noundef [[TMP10:%.*]], i32 noundef [[TMP9:%.*]])
28 // CHECK-NEXT: ret void
30 void t1(int param1
, int __maybe_undef param2
, int param3
) {}
32 void t2(int param1
, int param2
, int param3
) {
33 t1(param1
, param2
, param3
);
36 // CHECK: define{{.*}} void @TestVariadicFunction(i32 noundef [[TMP0:%.*]], ...)
38 // CHECK-NEXT: [[TMP1:%.*]] = alloca i32, align 4
39 // CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4
40 // CHECK-NEXT: store i32 [[TMP0:%.*]], ptr [[TMP1:%.*]], align 4
41 // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
42 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[TMP2:%.*]], align 4
43 // CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[TMP2:%.*]], align 4
44 // CHECK-NEXT: [[TMP5:%.*]] = freeze i32 [[TMP2:%.*]]
45 // CHECK-NEXT: call void (i32, ...) @VariadicFunction(i32 noundef [[TMP6:%.*]], i32 noundef [[TMP4:%.*]], i32 noundef [[TMP5:%.*]])
46 // CHECK-NEXT: ret void
48 // CHECK: declare{{.*}} void @VariadicFunction(i32 noundef, ...)
50 void VariadicFunction(int __maybe_undef x
, ...);
51 void TestVariadicFunction(int x
, ...) {
53 return VariadicFunction(x
, Var
, Var
);
56 // CHECK: define{{.*}} void @other()
58 // CHECK-NEXT: [[TMP1:%.*]] = alloca i32, align 4
59 // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
60 // CHECK-NEXT: call void @func(i32 noundef [[TMP2:%.*]])
61 // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
62 // CHECK-NEXT: [[TMP4:%.*]] = freeze i32 [[TMP3:%.*]]
63 // CHECK-NEXT: call void @func1(i32 noundef [[TMP4:%.*]])
64 // CHECK-NEXT: ret void
66 // CHECK: define{{.*}} void @func(i32 noundef [[TMP1:%.*]])
68 // CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4
69 // CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[TMP2:%.*]], align 4
70 // CHECK-NEXT: ret void
72 // CHECK: define{{.*}} void @func1(i32 noundef [[TMP1:%.*]])
74 // CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4
75 // CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[TMP2:%.*]], align 4
76 // CHECK-NEXT: ret void
79 void func1(int __maybe_undef param
);
87 void func(__maybe_undef
int param
) {}
88 void func1(int param
) {}
90 // CHECK: define{{.*}} void @foo(i32 noundef [[TMP1:%.*]])
92 // CHECK-NEXT: [[TMP2:%.*]] = alloca i32, align 4
93 // CHECK-NEXT: store i32 [[TMP1:%.*]], ptr [[TMP2:%.*]], align 4
94 // CHECK-NEXT: ret void
96 // CHECK: define{{.*}} void @bar()
98 // CHECK-NEXT: [[TMP1:%.*]] = alloca i32, align 4
99 // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
100 // CHECK-NEXT: call void @foo(i32 noundef [[TMP2:%.*]])
101 // CHECK-NEXT: ret void
103 void foo(__maybe_undef
int param
);
104 void foo(int param
) {}