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