brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.7 KiB · 7ded513 Raw
415 lines · c
1// REQUIRES: x86-registered-target2// RUN: %clang_cc1 -emit-llvm -triple x86_64-darwin-apple -o - %s | FileCheck %s --check-prefixes=CHECK3 4 5// Removed from builtins.c as the behavior of __builtin_os_log differs between6// platforms, so we only test on X86 however having this embedded in builtins.c7// makes testing more obtuse for non-X86 dependent behaviours.8 9// CHECK-LABEL: define{{.*}} void @test_builtin_os_log10// CHECK: (ptr noundef %[[BUF:.*]], i32 noundef %[[I:.*]], ptr noundef %[[DATA:.*]])11void test_builtin_os_log(void *buf, int i, const char *data) {12  volatile int len;13  // CHECK: %[[BUF_ADDR:.*]] = alloca ptr, align 814  // CHECK: %[[I_ADDR:.*]] = alloca i32, align 415  // CHECK: %[[DATA_ADDR:.*]] = alloca ptr, align 816  // CHECK: %[[LEN:.*]] = alloca i32, align 417  // CHECK: store ptr %[[BUF]], ptr %[[BUF_ADDR]], align 818  // CHECK: store i32 %[[I]], ptr %[[I_ADDR]], align 419  // CHECK: store ptr %[[DATA]], ptr %[[DATA_ADDR]], align 820 21  // CHECK: store volatile i32 34, ptr %[[LEN]]22  len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data);23 24  // CHECK: %[[V1:.*]] = load ptr, ptr %[[BUF_ADDR]]25  // CHECK: %[[V2:.*]] = load i32, ptr %[[I_ADDR]]26  // CHECK: %[[V3:.*]] = load ptr, ptr %[[DATA_ADDR]]27  // CHECK: %[[V4:.*]] = ptrtoint ptr %[[V3]] to i6428  // CHECK: %[[V5:.*]] = load ptr, ptr %[[DATA_ADDR]]29  // CHECK: %[[V6:.*]] = ptrtoint ptr %[[V5]] to i6430  // CHECK: call void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49(ptr noundef %[[V1]], i32 noundef %[[V2]], i64 noundef %[[V4]], i32 noundef 16, i64 noundef %[[V6]])31  __builtin_os_log_format(buf, "%d %{public}s %{private}.16P", i, data, data);32 33  // privacy annotations aren't recognized when they are preceded or followed34  // by non-whitespace characters.35 36  // CHECK: call void @__os_log_helper_1_2_1_8_32(37  __builtin_os_log_format(buf, "%{xyz public}s", data);38 39  // CHECK: call void @__os_log_helper_1_2_1_8_32(40  __builtin_os_log_format(buf, "%{ public xyz}s", data);41 42  // CHECK: call void @__os_log_helper_1_2_1_8_32(43  __builtin_os_log_format(buf, "%{ public1}s", data);44 45  // Privacy annotations do not have to be in the first comma-delimited string.46 47  // CHECK: call void @__os_log_helper_1_2_1_8_34(48  __builtin_os_log_format(buf, "%{ xyz, public }s", "abc");49 50  // CHECK: call void @__os_log_helper_1_3_1_8_33(51  __builtin_os_log_format(buf, "%{ xyz, private }s", "abc");52 53  // CHECK: call void @__os_log_helper_1_3_1_8_37(54  __builtin_os_log_format(buf, "%{ xyz, sensitive }s", "abc");55 56  // The strictest privacy annotation in the string wins.57 58  // CHECK: call void @__os_log_helper_1_3_1_8_33(59  __builtin_os_log_format(buf, "%{ private, public, private, public}s", "abc");60 61  // CHECK: call void @__os_log_helper_1_3_1_8_37(62  __builtin_os_log_format(buf, "%{ private, sensitive, private, public}s",63                          "abc");64 65  // CHECK: store volatile i32 22, ptr %[[LEN]], align 466  len = __builtin_os_log_format_buffer_size("%{mask.xyz}s", "abc");67 68  // CHECK: call void @__os_log_helper_1_2_2_8_112_8_34(ptr noundef {{.*}}, i64 noundef 802648869  __builtin_os_log_format(buf, "%{mask.xyz, public}s", "abc");70 71  // CHECK: call void @__os_log_helper_1_3_2_8_112_4_1(ptr noundef {{.*}}, i64 noundef 802648872  __builtin_os_log_format(buf, "%{ mask.xyz, private }d", 11);73 74  // Mask type is silently ignored.75  // CHECK: call void @__os_log_helper_1_2_1_8_32(76  __builtin_os_log_format(buf, "%{ mask. xyz }s", "abc");77 78  // CHECK: call void @__os_log_helper_1_2_1_8_32(79  __builtin_os_log_format(buf, "%{ mask.xy z }s", "abc");80}81 82// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_4983// CHECK: (ptr noundef %[[BUFFER:.*]], i32 noundef %[[ARG0:.*]], i64 noundef %[[ARG1:.*]], i32 noundef %[[ARG2:.*]], i64 noundef %[[ARG3:.*]])84 85// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 886// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 487// CHECK: %[[ARG1_ADDR:.*]] = alloca i64, align 888// CHECK: %[[ARG2_ADDR:.*]] = alloca i32, align 489// CHECK: %[[ARG3_ADDR:.*]] = alloca i64, align 890// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 891// CHECK: store i32 %[[ARG0]], ptr %[[ARG0_ADDR]], align 492// CHECK: store i64 %[[ARG1]], ptr %[[ARG1_ADDR]], align 893// CHECK: store i32 %[[ARG2]], ptr %[[ARG2_ADDR]], align 494// CHECK: store i64 %[[ARG3]], ptr %[[ARG3_ADDR]], align 895// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 896// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 097// CHECK: store i8 3, ptr %[[SUMMARY]], align 198// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 199// CHECK: store i8 4, ptr %[[NUMARGS]], align 1100// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2101// CHECK: store i8 0, ptr %[[ARGDESCRIPTOR]], align 1102// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3103// CHECK: store i8 4, ptr %[[ARGSIZE]], align 1104// CHECK: %[[ARGDATA:.*]] = getelementptr i8, ptr %[[BUF]], i64 4105// CHECK: %[[V0:.*]] = load i32, ptr %[[ARG0_ADDR]], align 4106// CHECK: store i32 %[[V0]], ptr %[[ARGDATA]], align 1107// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, ptr %[[BUF]], i64 8108// CHECK: store i8 34, ptr %[[ARGDESCRIPTOR1]], align 1109// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, ptr %[[BUF]], i64 9110// CHECK: store i8 8, ptr %[[ARGSIZE2]], align 1111// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, ptr %[[BUF]], i64 10112// CHECK: %[[V1:.*]] = load i64, ptr %[[ARG1_ADDR]], align 8113// CHECK: store i64 %[[V1]], ptr %[[ARGDATA3]], align 1114// CHECK: %[[ARGDESCRIPTOR5:.*]] = getelementptr i8, ptr %[[BUF]], i64 18115// CHECK: store i8 17, ptr %[[ARGDESCRIPTOR5]], align 1116// CHECK: %[[ARGSIZE6:.*]] = getelementptr i8, ptr %[[BUF]], i64 19117// CHECK: store i8 4, ptr %[[ARGSIZE6]], align 1118// CHECK: %[[ARGDATA7:.*]] = getelementptr i8, ptr %[[BUF]], i64 20119// CHECK: %[[V2:.*]] = load i32, ptr %[[ARG2_ADDR]], align 4120// CHECK: store i32 %[[V2]], ptr %[[ARGDATA7]], align 1121// CHECK: %[[ARGDESCRIPTOR9:.*]] = getelementptr i8, ptr %[[BUF]], i64 24122// CHECK: store i8 49, ptr %[[ARGDESCRIPTOR9]], align 1123// CHECK: %[[ARGSIZE10:.*]] = getelementptr i8, ptr %[[BUF]], i64 25124// CHECK: store i8 8, ptr %[[ARGSIZE10]], align 1125// CHECK: %[[ARGDATA11:.*]] = getelementptr i8, ptr %[[BUF]], i64 26126// CHECK: %[[V3:.*]] = load i64, ptr %[[ARG3_ADDR]], align 8127// CHECK: store i64 %[[V3]], ptr %[[ARGDATA11]], align 1128 129// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_wide130// CHECK: (ptr noundef %[[BUF:.*]], ptr noundef %[[DATA:.*]], ptr noundef %[[STR:.*]])131typedef int wchar_t;132void test_builtin_os_log_wide(void *buf, const char *data, wchar_t *str) {133  volatile int len;134 135  // CHECK: %[[BUF_ADDR:.*]] = alloca ptr, align 8136  // CHECK: %[[DATA_ADDR:.*]] = alloca ptr, align 8137  // CHECK: %[[STR_ADDR:.*]] = alloca ptr, align 8138  // CHECK: %[[LEN:.*]] = alloca i32, align 4139  // CHECK: store ptr %[[BUF]], ptr %[[BUF_ADDR]], align 8140  // CHECK: store ptr %[[DATA]], ptr %[[DATA_ADDR]], align 8141  // CHECK: store ptr %[[STR]], ptr %[[STR_ADDR]], align 8142 143  // CHECK: store volatile i32 12, ptr %[[LEN]], align 4144  len = __builtin_os_log_format_buffer_size("%S", str);145 146  // CHECK: %[[V1:.*]] = load ptr, ptr %[[BUF_ADDR]], align 8147  // CHECK: %[[V2:.*]] = load ptr, ptr %[[STR_ADDR]], align 8148  // CHECK: %[[V3:.*]] = ptrtoint ptr %[[V2]] to i64149  // CHECK: call void @__os_log_helper_1_2_1_8_80(ptr noundef %[[V1]], i64 noundef %[[V3]])150 151  __builtin_os_log_format(buf, "%S", str);152}153 154// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_8_80155// CHECK: (ptr noundef %[[BUFFER:.*]], i64 noundef %[[ARG0:.*]])156 157// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 8158// CHECK: %[[ARG0_ADDR:.*]] = alloca i64, align 8159// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 8160// CHECK: store i64 %[[ARG0]], ptr %[[ARG0_ADDR]], align 8161// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 8162// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 0163// CHECK: store i8 2, ptr %[[SUMMARY]], align 1164// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 1165// CHECK: store i8 1, ptr %[[NUMARGS]], align 1166// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2167// CHECK: store i8 80, ptr %[[ARGDESCRIPTOR]], align 1168// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3169// CHECK: store i8 8, ptr %[[ARGSIZE]], align 1170// CHECK: %[[ARGDATA:.*]] = getelementptr i8, ptr %[[BUF]], i64 4171// CHECK: %[[V0:.*]] = load i64, ptr %[[ARG0_ADDR]], align 8172// CHECK: store i64 %[[V0]], ptr %[[ARGDATA]], align 1173 174// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_precision_width175// CHECK: (ptr noundef %[[BUF:.*]], ptr noundef %[[DATA:.*]], i32 noundef %[[PRECISION:.*]], i32 noundef %[[WIDTH:.*]])176void test_builtin_os_log_precision_width(void *buf, const char *data,177                                         int precision, int width) {178  volatile int len;179  // CHECK: %[[BUF_ADDR:.*]] = alloca ptr, align 8180  // CHECK: %[[DATA_ADDR:.*]] = alloca ptr, align 8181  // CHECK: %[[PRECISION_ADDR:.*]] = alloca i32, align 4182  // CHECK: %[[WIDTH_ADDR:.*]] = alloca i32, align 4183  // CHECK: %[[LEN:.*]] = alloca i32, align 4184  // CHECK: store ptr %[[BUF]], ptr %[[BUF_ADDR]], align 8185  // CHECK: store ptr %[[DATA]], ptr %[[DATA_ADDR]], align 8186  // CHECK: store i32 %[[PRECISION]], ptr %[[PRECISION_ADDR]], align 4187  // CHECK: store i32 %[[WIDTH]], ptr %[[WIDTH_ADDR]], align 4188 189  // CHECK: store volatile i32 24, ptr %[[LEN]], align 4190  len = __builtin_os_log_format_buffer_size("Hello %*.*s World", precision, width, data);191 192  // CHECK: %[[V1:.*]] = load ptr, ptr %[[BUF_ADDR]], align 8193  // CHECK: %[[V2:.*]] = load i32, ptr %[[PRECISION_ADDR]], align 4194  // CHECK: %[[V3:.*]] = load i32, ptr %[[WIDTH_ADDR]], align 4195  // CHECK: %[[V4:.*]] = load ptr, ptr %[[DATA_ADDR]], align 8196  // CHECK: %[[V5:.*]] = ptrtoint ptr %[[V4]] to i64197  // CHECK: call void @__os_log_helper_1_2_3_4_0_4_16_8_32(ptr noundef %[[V1]], i32 noundef %[[V2]], i32 noundef %[[V3]], i64 noundef %[[V5]])198  __builtin_os_log_format(buf, "Hello %*.*s World", precision, width, data);199}200 201// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_3_4_0_4_16_8_32202// CHECK: (ptr noundef %[[BUFFER:.*]], i32 noundef %[[ARG0:.*]], i32 noundef %[[ARG1:.*]], i64 noundef %[[ARG2:.*]])203 204// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 8205// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4206// CHECK: %[[ARG1_ADDR:.*]] = alloca i32, align 4207// CHECK: %[[ARG2_ADDR:.*]] = alloca i64, align 8208// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 8209// CHECK: store i32 %[[ARG0]], ptr %[[ARG0_ADDR]], align 4210// CHECK: store i32 %[[ARG1]], ptr %[[ARG1_ADDR]], align 4211// CHECK: store i64 %[[ARG2]], ptr %[[ARG2_ADDR]], align 8212// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 8213// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 0214// CHECK: store i8 2, ptr %[[SUMMARY]], align 1215// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 1216// CHECK: store i8 3, ptr %[[NUMARGS]], align 1217// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2218// CHECK: store i8 0, ptr %[[ARGDESCRIPTOR]], align 1219// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3220// CHECK: store i8 4, ptr %[[ARGSIZE]], align 1221// CHECK: %[[ARGDATA:.*]] = getelementptr i8, ptr %[[BUF]], i64 4222// CHECK: %[[V0:.*]] = load i32, ptr %[[ARG0_ADDR]], align 4223// CHECK: store i32 %[[V0]], ptr %[[ARGDATA]], align 1224// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, ptr %[[BUF]], i64 8225// CHECK: store i8 16, ptr %[[ARGDESCRIPTOR1]], align 1226// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, ptr %[[BUF]], i64 9227// CHECK: store i8 4, ptr %[[ARGSIZE2]], align 1228// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, ptr %[[BUF]], i64 10229// CHECK: %[[V1:.*]] = load i32, ptr %[[ARG1_ADDR]], align 4230// CHECK: store i32 %[[V1]], ptr %[[ARGDATA3]], align 1231// CHECK: %[[ARGDESCRIPTOR5:.*]] = getelementptr i8, ptr %[[BUF]], i64 14232// CHECK: store i8 32, ptr %[[ARGDESCRIPTOR5]], align 1233// CHECK: %[[ARGSIZE6:.*]] = getelementptr i8, ptr %[[BUF]], i64 15234// CHECK: store i8 8, ptr %[[ARGSIZE6]], align 1235// CHECK: %[[ARGDATA7:.*]] = getelementptr i8, ptr %[[BUF]], i64 16236// CHECK: %[[V2:.*]] = load i64, ptr %[[ARG2_ADDR]], align 8237// CHECK: store i64 %[[V2]], ptr %[[ARGDATA7]], align 1238 239// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_invalid240// CHECK: (ptr noundef %[[BUF:.*]], i32 noundef %[[DATA:.*]])241void test_builtin_os_log_invalid(void *buf, int data) {242  volatile int len;243  // CHECK: %[[BUF_ADDR:.*]] = alloca ptr, align 8244  // CHECK: %[[DATA_ADDR:.*]] = alloca i32, align 4245  // CHECK: %[[LEN:.*]] = alloca i32, align 4246  // CHECK: store ptr %[[BUF]], ptr %[[BUF_ADDR]], align 8247  // CHECK: store i32 %[[DATA]], ptr %[[DATA_ADDR]], align 4248 249  // CHECK: store volatile i32 8, ptr %[[LEN]], align 4250  len = __builtin_os_log_format_buffer_size("invalid specifier %: %d even a trailing one%", data);251 252  // CHECK: %[[V1:.*]] = load ptr, ptr %[[BUF_ADDR]], align 8253  // CHECK: %[[V2:.*]] = load i32, ptr %[[DATA_ADDR]], align 4254  // CHECK: call void @__os_log_helper_1_0_1_4_0(ptr noundef %[[V1]], i32 noundef %[[V2]])255 256  __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing one%", data);257}258 259// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_1_4_0260// CHECK: (ptr noundef %[[BUFFER:.*]], i32 noundef %[[ARG0:.*]])261 262// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 8263// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4264// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 8265// CHECK: store i32 %[[ARG0]], ptr %[[ARG0_ADDR]], align 4266// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 8267// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 0268// CHECK: store i8 0, ptr %[[SUMMARY]], align 1269// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 1270// CHECK: store i8 1, ptr %[[NUMARGS]], align 1271// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2272// CHECK: store i8 0, ptr %[[ARGDESCRIPTOR]], align 1273// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3274// CHECK: store i8 4, ptr %[[ARGSIZE]], align 1275// CHECK: %[[ARGDATA:.*]] = getelementptr i8, ptr %[[BUF]], i64 4276// CHECK: %[[V0:.*]] = load i32, ptr %[[ARG0_ADDR]], align 4277// CHECK: store i32 %[[V0]], ptr %[[ARGDATA]], align 1278 279// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_percent280// CHECK: (ptr noundef %[[BUF:.*]], ptr noundef %[[DATA1:.*]], ptr noundef %[[DATA2:.*]])281// Check that the %% which does not consume any argument is correctly handled282void test_builtin_os_log_percent(void *buf, const char *data1, const char *data2) {283  volatile int len;284  // CHECK: %[[BUF_ADDR:.*]] = alloca ptr, align 8285  // CHECK: %[[DATA1_ADDR:.*]] = alloca ptr, align 8286  // CHECK: %[[DATA2_ADDR:.*]] = alloca ptr, align 8287  // CHECK: %[[LEN:.*]] = alloca i32, align 4288  // CHECK: store ptr %[[BUF]], ptr %[[BUF_ADDR]], align 8289  // CHECK: store ptr %[[DATA1]], ptr %[[DATA1_ADDR]], align 8290  // CHECK: store ptr %[[DATA2]], ptr %[[DATA2_ADDR]], align 8291  // CHECK: store volatile i32 22, ptr %[[LEN]], align 4292 293  len = __builtin_os_log_format_buffer_size("%s %% %s", data1, data2);294 295  // CHECK: %[[V1:.*]] = load ptr, ptr %[[BUF_ADDR]], align 8296  // CHECK: %[[V2:.*]] = load ptr, ptr %[[DATA1_ADDR]], align 8297  // CHECK: %[[V3:.*]] = ptrtoint ptr %[[V2]] to i64298  // CHECK: %[[V4:.*]] = load ptr, ptr %[[DATA2_ADDR]], align 8299  // CHECK: %[[V5:.*]] = ptrtoint ptr %[[V4]] to i64300  // CHECK: call void @__os_log_helper_1_2_2_8_32_8_32(ptr noundef %[[V1]], i64 noundef %[[V3]], i64 noundef %[[V5]])301 302  __builtin_os_log_format(buf, "%s %% %s", data1, data2);303}304 305// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_2_8_32_8_32306// CHECK: (ptr noundef %[[BUFFER:.*]], i64 noundef %[[ARG0:.*]], i64 noundef %[[ARG1:.*]])307 308// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 8309// CHECK: %[[ARG0_ADDR:.*]] = alloca i64, align 8310// CHECK: %[[ARG1_ADDR:.*]] = alloca i64, align 8311// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 8312// CHECK: store i64 %[[ARG0]], ptr %[[ARG0_ADDR]], align 8313// CHECK: store i64 %[[ARG1]], ptr %[[ARG1_ADDR]], align 8314// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 8315// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 0316// CHECK: store i8 2, ptr %[[SUMMARY]], align 1317// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 1318// CHECK: store i8 2, ptr %[[NUMARGS]], align 1319// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2320// CHECK: store i8 32, ptr %[[ARGDESCRIPTOR]], align 1321// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3322// CHECK: store i8 8, ptr %[[ARGSIZE]], align 1323// CHECK: %[[ARGDATA:.*]] = getelementptr i8, ptr %[[BUF]], i64 4324// CHECK: %[[V0:.*]] = load i64, ptr %[[ARG0_ADDR]], align 8325// CHECK: store i64 %[[V0]], ptr %[[ARGDATA]], align 1326// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, ptr %[[BUF]], i64 12327// CHECK: store i8 32, ptr %[[ARGDESCRIPTOR1]], align 1328// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, ptr %[[BUF]], i64 13329// CHECK: store i8 8, ptr %[[ARGSIZE2]], align 1330// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, ptr %[[BUF]], i64 14331// CHECK: %[[V1:.*]] = load i64, ptr %[[ARG1_ADDR]], align 8332// CHECK: store i64 %[[V1]], ptr %[[ARGDATA3]], align 1333 334// Check that the following two functions call the same helper function.335 336// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_merge_helper0337// CHECK: call void @__os_log_helper_1_0_2_4_0_8_0(338void test_builtin_os_log_merge_helper0(void *buf, int i, double d) {339  __builtin_os_log_format(buf, "%d %f", i, d);340}341 342// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_2_4_0_8_0(343 344// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_merge_helper1345// CHECK: call void @__os_log_helper_1_0_2_4_0_8_0(346void test_builtin_os_log_merge_helper1(void *buf, unsigned u, long long ll) {347  __builtin_os_log_format(buf, "%u %lld", u, ll);348}349 350// Check that this function doesn't write past the end of array 'buf'.351 352// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_errno353void test_builtin_os_log_errno(void) {354  // CHECK-NOT: @stacksave355  // CHECK: %[[BUF:.*]] = alloca [4 x i8], align 1356  // CHECK: %[[DECAY:.*]] = getelementptr inbounds [4 x i8], ptr %[[BUF]], i64 0, i64 0357  // CHECK: call void @__os_log_helper_1_2_1_0_96(ptr noundef %[[DECAY]])358  // CHECK-NOT: @stackrestore359 360  char buf[__builtin_os_log_format_buffer_size("%m")];361  __builtin_os_log_format(buf, "%m");362}363 364// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_0_96365// CHECK: (ptr noundef %[[BUFFER:.*]])366 367// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 8368// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 8369// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 8370// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 0371// CHECK: store i8 2, ptr %[[SUMMARY]], align 1372// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 1373// CHECK: store i8 1, ptr %[[NUMARGS]], align 1374// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2375// CHECK: store i8 96, ptr %[[ARGDESCRIPTOR]], align 1376// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3377// CHECK: store i8 0, ptr %[[ARGSIZE]], align 1378// CHECK-NEXT: ret void379 380// CHECK-LABEL: define{{.*}} void @test_builtin_os_log_long_double381// CHECK: (ptr noundef %[[BUF:.*]], x86_fp80 noundef %[[LD:.*]])382void test_builtin_os_log_long_double(void *buf, long double ld) {383  // CHECK: %[[BUF_ADDR:.*]] = alloca ptr, align 8384  // CHECK: %[[LD_ADDR:.*]] = alloca x86_fp80, align 16385  // CHECK: store ptr %[[BUF]], ptr %[[BUF_ADDR]], align 8386  // CHECK: store x86_fp80 %[[LD]], ptr %[[LD_ADDR]], align 16387  // CHECK: %[[V0:.*]] = load ptr, ptr %[[BUF_ADDR]], align 8388  // CHECK: %[[V1:.*]] = load x86_fp80, ptr %[[LD_ADDR]], align 16389  // CHECK: %[[V2:.*]] = bitcast x86_fp80 %[[V1]] to i80390  // CHECK: %[[V3:.*]] = zext i80 %[[V2]] to i128391  // CHECK: call void @__os_log_helper_1_0_1_16_0(ptr noundef %[[V0]], i128 noundef %[[V3]])392 393  __builtin_os_log_format(buf, "%Lf", ld);394}395 396// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_1_16_0397// CHECK: (ptr noundef %[[BUFFER:.*]], i128 noundef %[[ARG0:.*]])398 399// CHECK: %[[BUFFER_ADDR:.*]] = alloca ptr, align 8400// CHECK: %[[ARG0_ADDR:.*]] = alloca i128, align 16401// CHECK: store ptr %[[BUFFER]], ptr %[[BUFFER_ADDR]], align 8402// CHECK: store i128 %[[ARG0]], ptr %[[ARG0_ADDR]], align 16403// CHECK: %[[BUF:.*]] = load ptr, ptr %[[BUFFER_ADDR]], align 8404// CHECK: %[[SUMMARY:.*]] = getelementptr i8, ptr %[[BUF]], i64 0405// CHECK: store i8 0, ptr %[[SUMMARY]], align 1406// CHECK: %[[NUMARGS:.*]] = getelementptr i8, ptr %[[BUF]], i64 1407// CHECK: store i8 1, ptr %[[NUMARGS]], align 1408// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, ptr %[[BUF]], i64 2409// CHECK: store i8 0, ptr %[[ARGDESCRIPTOR]], align 1410// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, ptr %[[BUF]], i64 3411// CHECK: store i8 16, ptr %[[ARGSIZE]], align 1412// CHECK: %[[ARGDATA:.*]] = getelementptr i8, ptr %[[BUF]], i64 4413// CHECK: %[[V3:.*]] = load i128, ptr %[[ARG0_ADDR]], align 16414// CHECK: store i128 %[[V3]], ptr %[[ARGDATA]], align 1415