Bill Wendling | 2a81f66 | 2018-12-01 08:29:36 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O2 | FileCheck %s |
Bill Wendling | aa77513 | 2018-12-18 22:54:03 +0000 | [diff] [blame] | 2 | // RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -O0 | FileCheck --check-prefix=O0 %s |
Bill Wendling | 2a81f66 | 2018-12-01 08:29:36 +0000 | [diff] [blame] | 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) }; |
Bill Wendling | aa77513 | 2018-12-18 22:54:03 +0000 | [diff] [blame] | 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 | } |