blob: 7965dbe93f9a0e40708ce77a6a86bdc52784bbe9 [file] [log] [blame]
// 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()));
}