diff options
author | Mehdi Amini <mehdi.amini@apple.com> | 2016-10-24 16:56:23 +0000 |
---|---|---|
committer | Mehdi Amini <mehdi.amini@apple.com> | 2016-10-24 16:56:23 +0000 |
commit | 29034362ae872dfc46fd994893d2def8f32d7a18 (patch) | |
tree | f0df5c91d2e55149043d5cc4edbdee2a1e3090a9 /clang/test/CodeGen/builtins.c | |
parent | b05bac940da334e10dee66f4d1d88c53014bcf5d (diff) | |
download | bcm5719-llvm-29034362ae872dfc46fd994893d2def8f32d7a18.tar.gz bcm5719-llvm-29034362ae872dfc46fd994893d2def8f32d7a18.zip |
Add support for __builtin_os_log_format[_buffer_size]
These new builtins support a mechanism for logging OS events, using a
printf-like format string to specify the layout of data in a buffer.
The _buffer_size version of the builtin can be used to determine the size
of the buffer to allocate to hold the data, and then __builtin_os_log_format
can write data into that buffer. This implements format checking to report
mismatches between the format string and the data arguments. Most of this
code was written by Chris Willmore.
Differential Revision: https://reviews.llvm.org/D25888
llvm-svn: 284990
Diffstat (limited to 'clang/test/CodeGen/builtins.c')
-rw-r--r-- | clang/test/CodeGen/builtins.c | 141 |
1 files changed, 138 insertions, 3 deletions
diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c index 7d2a5d80e40..c55a6cf987c 100644 --- a/clang/test/CodeGen/builtins.c +++ b/clang/test/CodeGen/builtins.c @@ -355,8 +355,6 @@ void test_float_builtin_ops(float F, double D, long double LD) { } -// __builtin_longjmp isn't supported on all platforms, so only test it on X86. -#ifdef __x86_64__ // CHECK-LABEL: define void @test_builtin_longjmp void test_builtin_longjmp(void **buffer) { // CHECK: [[BITCAST:%.*]] = bitcast @@ -364,10 +362,147 @@ void test_builtin_longjmp(void **buffer) { __builtin_longjmp(buffer, 1); // CHECK-NEXT: unreachable } -#endif // CHECK-LABEL: define i64 @test_builtin_readcyclecounter long long test_builtin_readcyclecounter() { // CHECK: call i64 @llvm.readcyclecounter() return __builtin_readcyclecounter(); } + +// CHECK-LABEL: define void @test_builtin_os_log +// CHECK: (i8* [[BUF:%.*]], i32 [[I:%.*]], i8* [[DATA:%.*]]) +void test_builtin_os_log(void *buf, int i, const char *data) { + volatile int len; + // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 + // CHECK: store i32 [[I]], i32* [[I_ADDR:%.*]], align 4 + // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 + + // CHECK: store volatile i32 34 + len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data); + + // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] + // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 + // CHECK: store i8 3, i8* [[SUMMARY]] + // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 + // CHECK: store i8 4, i8* [[NUM_ARGS]] + // + // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 + // CHECK: store i8 0, i8* [[ARG1_DESC]] + // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 + // CHECK: store i8 4, i8* [[ARG1_SIZE]] + // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 + // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32* + // CHECK: [[I2:%.*]] = load i32, i32* [[I_ADDR]] + // CHECK: store i32 [[I2]], i32* [[ARG1_INT]] + + // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8 + // CHECK: store i8 34, i8* [[ARG2_DESC]] + // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9 + // CHECK: store i8 8, i8* [[ARG2_SIZE]] + // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10 + // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8** + // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]] + // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]] + + // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 18 + // CHECK: store i8 17, i8* [[ARG3_DESC]] + // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 19 + // CHECK: store i8 4, i8* [[ARG3_SIZE]] + // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 20 + // CHECK: [[ARG3_INT:%.*]] = bitcast i8* [[ARG3]] to i32* + // CHECK: store i32 16, i32* [[ARG3_INT]] + + // CHECK: [[ARG4_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 24 + // CHECK: store i8 49, i8* [[ARG4_DESC]] + // CHECK: [[ARG4_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 25 + // CHECK: store i8 8, i8* [[ARG4_SIZE]] + // CHECK: [[ARG4:%.*]] = getelementptr i8, i8* [[BUF2]], i64 26 + // CHECK: [[ARG4_PTR:%.*]] = bitcast i8* [[ARG4]] to i8** + // CHECK: [[DATA3:%.*]] = load i8*, i8** [[DATA_ADDR]] + // CHECK: store i8* [[DATA3]], i8** [[ARG4_PTR]] + + __builtin_os_log_format(buf, "%d %{public}s %{private}.16P", i, data, data); +} + +// CHECK-LABEL: define void @test_builtin_os_log_errno +// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]]) +void test_builtin_os_log_errno(void *buf, const char *data) { + volatile int len; + // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 + // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 + + // CHECK: store volatile i32 2 + len = __builtin_os_log_format_buffer_size("%S"); + + // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] + // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 + // CHECK: store i8 2, i8* [[SUMMARY]] + // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 + // CHECK: store i8 1, i8* [[NUM_ARGS]] + + // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 + // CHECK: store i8 96, i8* [[ARG1_DESC]] + // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 + // CHECK: store i8 0, i8* [[ARG1_SIZE]] + // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 + // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32* + // CHECK: store i32 0, i32* [[ARG1_INT]] + + __builtin_os_log_format(buf, "%m"); +} + +// CHECK-LABEL: define void @test_builtin_os_log_wide +// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32* [[STR:%.*]]) +typedef int wchar_t; +void test_builtin_os_log_wide(void *buf, const char *data, wchar_t *str) { + volatile int len; + // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 + // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 + // CHECK: store i32* [[STR]], i32** [[STR_ADDR:%.*]], + + // CHECK: store volatile i32 12 + len = __builtin_os_log_format_buffer_size("%S", str); + + // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] + // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 + // CHECK: store i8 2, i8* [[SUMMARY]] + // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 + // CHECK: store i8 1, i8* [[NUM_ARGS]] + + // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 + // CHECK: store i8 80, i8* [[ARG1_DESC]] + // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 + // CHECK: store i8 8, i8* [[ARG1_SIZE]] + // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 + // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i32** + // CHECK: [[STR2:%.*]] = load i32*, i32** [[STR_ADDR]] + // CHECK: store i32* [[STR2]], i32** [[ARG1_PTR]] + + __builtin_os_log_format(buf, "%S", str); +} + +// CHECK-LABEL: define void @test_builtin_os_log_percent +// Check that the %% which does not consume any argument is correctly handled +void test_builtin_os_log_percent(void *buf, const char *data) { + volatile int len; + // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8 + // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8 + // CHECK: store volatile i32 12 + len = __builtin_os_log_format_buffer_size("%s %%", data); + + // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]] + // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0 + // CHECK: store i8 2, i8* [[SUMMARY]] + // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1 + // CHECK: store i8 1, i8* [[NUM_ARGS]] + // + // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2 + // CHECK: store i8 32, i8* [[ARG1_DESC]] + // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3 + // CHECK: store i8 8, i8* [[ARG1_SIZE]] + // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4 + // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i8** + // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]] + // CHECK: store i8* [[DATA2]], i8** [[ARG1_PTR]] + __builtin_os_log_format(buf, "%s %%", data); +} |