1 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-optzns -o - %s -O2 | FileCheck %s
2 // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-optzns -o - %s -O0 | FileCheck %s
3
4 int a = 42;
5
6 /* --- Compound literals */
7
8 struct foo { int x, y; };
9
10 int y;
11 struct foo f = (struct foo){ __builtin_constant_p(y), 42 };
12
test0(int expr)13 struct foo test0(int expr) {
14 // CHECK-LABEL: test0
15 // CHECK: call i1 @llvm.is.constant.i32
16 struct foo f = (struct foo){ __builtin_constant_p(expr), 42 };
17 return f;
18 }
19
20 /* --- Pointer types */
21
test1()22 int test1() {
23 // CHECK-LABEL: test1
24 // CHECK: ret i32 0
25 return __builtin_constant_p(&a - 13);
26 }
27
28 /* --- Aggregate types */
29
30 int b[] = {1, 2, 3};
31
test2()32 int test2() {
33 // CHECK-LABEL: test2
34 // CHECK: ret i32 0
35 return __builtin_constant_p(b);
36 }
37
38 const char test3_c[] = {1, 2, 3, 0};
39
test3()40 int test3() {
41 // CHECK-LABEL: test3
42 // CHECK: ret i32 0
43 return __builtin_constant_p(test3_c);
44 }
45
test4_i(const char * x)46 inline char test4_i(const char *x) {
47 return x[1];
48 }
49
test4()50 int test4() {
51 // CHECK: define i32 @test4
52 // CHECK: ret i32 0
53 return __builtin_constant_p(test4_i(test3_c));
54 }
55
56 /* --- Constant global variables */
57
58 const int c = 42;
59
test5()60 int test5() {
61 // CHECK-LABEL: test5
62 // CHECK: ret i32 1
63 return __builtin_constant_p(c);
64 }
65
66 /* --- Array types */
67
68 int arr[] = { 1, 2, 3 };
69 const int c_arr[] = { 1, 2, 3 };
70
test6()71 int test6() {
72 // CHECK-LABEL: test6
73 // CHECK: call i1 @llvm.is.constant.i32
74 return __builtin_constant_p(arr[2]);
75 }
76
test7()77 int test7() {
78 // CHECK-LABEL: test7
79 // CHECK: call i1 @llvm.is.constant.i32
80 return __builtin_constant_p(c_arr[2]);
81 }
82
test8()83 int test8() {
84 // CHECK-LABEL: test8
85 // CHECK: ret i32 0
86 return __builtin_constant_p(c_arr);
87 }
88
89 /* --- Function pointers */
90
test9()91 int test9() {
92 // CHECK-LABEL: test9
93 // CHECK: ret i32 0
94 return __builtin_constant_p(&test9);
95 }
96
test10()97 int test10() {
98 // CHECK-LABEL: test10
99 // CHECK: ret i32 1
100 return __builtin_constant_p(&test10 != 0);
101 }
102
103 typedef unsigned long uintptr_t;
104 #define assign(p, v) ({ \
105 uintptr_t _r_a_p__v = (uintptr_t)(v); \
106 if (__builtin_constant_p(v) && _r_a_p__v == (uintptr_t)0) { \
107 union { \
108 uintptr_t __val; \
109 char __c[1]; \
110 } __u = { \
111 .__val = (uintptr_t)_r_a_p__v \
112 }; \
113 *(volatile unsigned int*)&p = *(unsigned int*)(__u.__c); \
114 __u.__val; \
115 } \
116 _r_a_p__v; \
117 })
118
119 typedef void fn_p(void);
120 extern fn_p *dest_p;
121
src_fn(void)122 static void src_fn(void) {
123 }
124
test11()125 void test11() {
126 assign(dest_p, src_fn);
127 }
128
129 extern int test12_v;
130
131 struct { const char *t; int a; } test12[] = {
132 { "tag", __builtin_constant_p(test12_v) && !test12_v ? 1 : 0 }
133 };
134
135 extern char test13_v;
136 struct { int a; } test13 = { __builtin_constant_p(test13_v) };
137
138 extern unsigned long long test14_v;
139
test14()140 void test14() {
141 // CHECK-LABEL: test14
142 // CHECK: call void asm sideeffect "", {{.*}}(i32 -1)
143 __asm__ __volatile__("" :: "n"( (__builtin_constant_p(test14_v) || 0) ? 1 : -1));
144 }
145
146 int test15_f();
147 // CHECK-LABEL: define void @test15
148 // CHECK-NOT: call {{.*}}test15_f
test15()149 void test15() {
150 int a, b;
151 (void)__builtin_constant_p((a = b, test15_f()));
152 }
153