forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			153 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			153 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			C
		
	
	
	
| // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-optzns -o - %s -O2 | FileCheck %s
 | |
| // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -disable-llvm-optzns -o - %s -O0 | FileCheck %s
 | |
| 
 | |
| int a = 42;
 | |
| 
 | |
| /* --- Compound literals */
 | |
| 
 | |
| struct foo { int x, y; };
 | |
| 
 | |
| int y;
 | |
| struct foo f = (struct foo){ __builtin_constant_p(y), 42 };
 | |
| 
 | |
| struct foo test0(int expr) {
 | |
|   // CHECK-LABEL: test0
 | |
|   // CHECK: call i1 @llvm.is.constant.i32
 | |
|   struct foo f = (struct foo){ __builtin_constant_p(expr), 42 };
 | |
|   return f;
 | |
| }
 | |
| 
 | |
| /* --- Pointer types */
 | |
| 
 | |
| int test1() {
 | |
|   // CHECK-LABEL: test1
 | |
|   // CHECK: ret i32 0
 | |
|   return __builtin_constant_p(&a - 13);
 | |
| }
 | |
| 
 | |
| /* --- Aggregate types */
 | |
| 
 | |
| int b[] = {1, 2, 3};
 | |
| 
 | |
| int test2() {
 | |
|   // CHECK-LABEL: test2
 | |
|   // CHECK: ret i32 0
 | |
|   return __builtin_constant_p(b);
 | |
| }
 | |
| 
 | |
| const char test3_c[] = {1, 2, 3, 0};
 | |
| 
 | |
| int test3() {
 | |
|   // CHECK-LABEL: test3
 | |
|   // CHECK: ret i32 0
 | |
|   return __builtin_constant_p(test3_c);
 | |
| }
 | |
| 
 | |
| inline char test4_i(const char *x) {
 | |
|   return x[1];
 | |
| }
 | |
| 
 | |
| int test4() {
 | |
|   // CHECK: define i32 @test4
 | |
|   // CHECK: ret i32 0
 | |
|   return __builtin_constant_p(test4_i(test3_c));
 | |
| }
 | |
| 
 | |
| /* --- Constant global variables */
 | |
| 
 | |
| const int c = 42;
 | |
| 
 | |
| int test5() {
 | |
|   // CHECK-LABEL: test5
 | |
|   // CHECK: ret i32 1
 | |
|   return __builtin_constant_p(c);
 | |
| }
 | |
| 
 | |
| /* --- Array types */
 | |
| 
 | |
| int arr[] = { 1, 2, 3 };
 | |
| const int c_arr[] = { 1, 2, 3 };
 | |
| 
 | |
| int test6() {
 | |
|   // CHECK-LABEL: test6
 | |
|   // CHECK: call i1 @llvm.is.constant.i32
 | |
|   return __builtin_constant_p(arr[2]);
 | |
| }
 | |
| 
 | |
| int test7() {
 | |
|   // CHECK-LABEL: test7
 | |
|   // CHECK: call i1 @llvm.is.constant.i32
 | |
|   return __builtin_constant_p(c_arr[2]);
 | |
| }
 | |
| 
 | |
| int test8() {
 | |
|   // CHECK-LABEL: test8
 | |
|   // CHECK: ret i32 0
 | |
|   return __builtin_constant_p(c_arr);
 | |
| }
 | |
| 
 | |
| /* --- Function pointers */
 | |
| 
 | |
| int test9() {
 | |
|   // CHECK-LABEL: test9
 | |
|   // CHECK: ret i32 0
 | |
|   return __builtin_constant_p(&test9);
 | |
| }
 | |
| 
 | |
| int test10() {
 | |
|   // CHECK-LABEL: test10
 | |
|   // CHECK: ret i32 1
 | |
|   return __builtin_constant_p(&test10 != 0);
 | |
| }
 | |
| 
 | |
| typedef unsigned long uintptr_t;
 | |
| #define assign(p, v) ({ \
 | |
|   uintptr_t _r_a_p__v = (uintptr_t)(v);                           \
 | |
|   if (__builtin_constant_p(v) && _r_a_p__v == (uintptr_t)0) {     \
 | |
|     union {                                                       \
 | |
|       uintptr_t __val;                                            \
 | |
|       char __c[1];                                                \
 | |
|     } __u = {                                                     \
 | |
|       .__val = (uintptr_t)_r_a_p__v                               \
 | |
|     };                                                            \
 | |
|     *(volatile unsigned int*)&p = *(unsigned int*)(__u.__c);      \
 | |
|     __u.__val;                                                    \
 | |
|   }                                                               \
 | |
|   _r_a_p__v;                                                      \
 | |
| })
 | |
| 
 | |
| typedef void fn_p(void);
 | |
| extern fn_p *dest_p;
 | |
| 
 | |
| static void src_fn(void) {
 | |
| }
 | |
| 
 | |
| void test11() {
 | |
|   assign(dest_p, src_fn);
 | |
| }
 | |
| 
 | |
| extern int test12_v;
 | |
| 
 | |
| struct { const char *t; int a; } test12[] = {
 | |
|     { "tag", __builtin_constant_p(test12_v) && !test12_v ? 1 : 0 }
 | |
| };
 | |
| 
 | |
| extern char test13_v;
 | |
| struct { int a; } test13 = { __builtin_constant_p(test13_v) };
 | |
| 
 | |
| extern unsigned long long test14_v;
 | |
| 
 | |
| void test14() {
 | |
|   // CHECK-LABEL: test14
 | |
|   // CHECK: call void asm sideeffect "", {{.*}}(i32 -1) 
 | |
|   __asm__ __volatile__("" :: "n"( (__builtin_constant_p(test14_v) || 0) ? 1 : -1));
 | |
| }
 | |
| 
 | |
| int test15_f();
 | |
| // CHECK-LABEL: define void @test15
 | |
| // CHECK-NOT: call {{.*}}test15_f
 | |
| void test15() {
 | |
|   int a, b;
 | |
|   (void)__builtin_constant_p((a = b, test15_f()));
 | |
| }
 |