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