1 // RUN: %clang_cc1 -triple arm64-windows -Wno-implicit-function-declaration -fms-compatibility -emit-llvm -o - %s \ 2 // RUN: | FileCheck %s --check-prefix=CHECK-MSVC --check-prefix=CHECK-MSCOMPAT 3 4 // RUN: not %clang_cc1 -triple arm64-linux -Werror -S -o /dev/null %s 2>&1 \ 5 // RUN: | FileCheck %s -check-prefix CHECK-LINUX 6 7 // RUN: %clang_cc1 -triple arm64-darwin -Wno-implicit-function-declaration -fms-compatibility -emit-llvm -o - %s \ 8 // RUN: | FileCheck %s -check-prefix CHECK-MSCOMPAT 9 10 long test_InterlockedAdd(long volatile *Addend, long Value) { 11 return _InterlockedAdd(Addend, Value); 12 } 13 14 long test_InterlockedAdd_constant(long volatile *Addend) { 15 return _InterlockedAdd(Addend, -1); 16 } 17 18 // CHECK-LABEL: define {{.*}} i32 @test_InterlockedAdd(ptr %Addend, i32 %Value) {{.*}} { 19 // CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i32 %2 seq_cst, align 4 20 // CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i32 %[[OLDVAL:[0-9]+]], %2 21 // CHECK-MSVC: ret i32 %[[NEWVAL:[0-9]+]] 22 // CHECK-LINUX: error: call to undeclared function '_InterlockedAdd' 23 24 __int64 test_InterlockedAdd64(__int64 volatile *Addend, __int64 Value) { 25 return _InterlockedAdd64(Addend, Value); 26 } 27 28 __int64 test_InterlockedAdd64_constant(__int64 volatile *Addend) { 29 return _InterlockedAdd64(Addend, -1); 30 } 31 32 // CHECK-LABEL: define {{.*}} i64 @test_InterlockedAdd64(ptr %Addend, i64 %Value) {{.*}} { 33 // CHECK-MSVC: %[[OLDVAL:[0-9]+]] = atomicrmw add ptr %1, i64 %2 seq_cst, align 8 34 // CHECK-MSVC: %[[NEWVAL:[0-9]+]] = add i64 %[[OLDVAL:[0-9]+]], %2 35 // CHECK-MSVC: ret i64 %[[NEWVAL:[0-9]+]] 36 // CHECK-LINUX: error: call to undeclared function '_InterlockedAdd64' 37 38 void check__dmb(void) { 39 __dmb(0); 40 } 41 42 // CHECK-MSVC: @llvm.aarch64.dmb(i32 0) 43 // CHECK-LINUX: error: call to undeclared function '__dmb' 44 45 void check__dsb(void) { 46 __dsb(0); 47 } 48 49 // CHECK-MSVC: @llvm.aarch64.dsb(i32 0) 50 // CHECK-LINUX: error: call to undeclared function '__dsb' 51 52 void check__isb(void) { 53 __isb(0); 54 } 55 56 // CHECK-MSVC: @llvm.aarch64.isb(i32 0) 57 // CHECK-LINUX: error: call to undeclared function '__isb' 58 59 void check__yield(void) { 60 __yield(); 61 } 62 63 // CHECK-MSVC: @llvm.aarch64.hint(i32 1) 64 // CHECK-LINUX: error: call to undeclared function '__yield' 65 66 void check__wfe(void) { 67 __wfe(); 68 } 69 70 // CHECK-MSVC: @llvm.aarch64.hint(i32 2) 71 // CHECK-LINUX: error: call to undeclared function '__wfe' 72 73 void check__wfi(void) { 74 __wfi(); 75 } 76 77 // CHECK-MSVC: @llvm.aarch64.hint(i32 3) 78 // CHECK-LINUX: error: call to undeclared function '__wfi' 79 80 void check__sev(void) { 81 __sev(); 82 } 83 84 // CHECK-MSVC: @llvm.aarch64.hint(i32 4) 85 // CHECK-LINUX: error: call to undeclared function '__sev' 86 87 void check__sevl(void) { 88 __sevl(); 89 } 90 91 // CHECK-MSVC: @llvm.aarch64.hint(i32 5) 92 // CHECK-LINUX: error: call to undeclared function '__sevl' 93 94 void check_ReadWriteBarrier(void) { 95 _ReadWriteBarrier(); 96 } 97 98 // CHECK-MSVC: fence syncscope("singlethread") 99 // CHECK-LINUX: error: call to undeclared function '_ReadWriteBarrier' 100 101 long long check_mulh(long long a, long long b) { 102 return __mulh(a, b); 103 } 104 105 // CHECK-MSVC: %[[ARG1:.*]] = sext i64 {{.*}} to i128 106 // CHECK-MSVC: %[[ARG2:.*]] = sext i64 {{.*}} to i128 107 // CHECK-MSVC: %[[PROD:.*]] = mul nsw i128 %[[ARG1]], %[[ARG2]] 108 // CHECK-MSVC: %[[HIGH:.*]] = ashr i128 %[[PROD]], 64 109 // CHECK-MSVC: %[[RES:.*]] = trunc i128 %[[HIGH]] to i64 110 // CHECK-LINUX: error: call to undeclared function '__mulh' 111 112 unsigned long long check_umulh(unsigned long long a, unsigned long long b) { 113 return __umulh(a, b); 114 } 115 116 // CHECK-MSVC: %[[ARG1:.*]] = zext i64 {{.*}} to i128 117 // CHECK-MSVC: %[[ARG2:.*]] = zext i64 {{.*}} to i128 118 // CHECK-MSVC: %[[PROD:.*]] = mul nuw i128 %[[ARG1]], %[[ARG2]] 119 // CHECK-MSVC: %[[HIGH:.*]] = lshr i128 %[[PROD]], 64 120 // CHECK-MSVC: %[[RES:.*]] = trunc i128 %[[HIGH]] to i64 121 // CHECK-LINUX: error: call to undeclared function '__umulh' 122 123 void check__break() { 124 __break(0); 125 } 126 127 // CHECK-MSVC: call void @llvm.aarch64.break(i32 0) 128 // CHECK-LINUX: error: call to undeclared function '__break' 129 130 void check__hlt() { 131 __hlt(0); 132 __hlt(1, 2, 3, 4, 5); 133 int x = __hlt(0); 134 } 135 136 // CHECK-MSVC: call void @llvm.aarch64.hlt(i32 0) 137 // CHECK-LINUX: error: call to undeclared function '__hlt' 138 139 unsigned __int64 check__getReg(void) { 140 unsigned volatile __int64 reg; 141 reg = __getReg(18); 142 reg = __getReg(31); 143 return reg; 144 } 145 146 // CHECK-MSCOMPAT: call i64 @llvm.read_register.i64(metadata ![[MD2:.*]]) 147 // CHECK-MSCOMPAT: call i64 @llvm.read_register.i64(metadata ![[MD3:.*]]) 148 149 #ifdef __LP64__ 150 #define LONG __int32 151 #else 152 #define LONG long 153 #endif 154 155 #ifdef __LP64__ 156 void check__writex18byte(unsigned char data, unsigned LONG offset) { 157 #else 158 void check__writex18byte(unsigned LONG offset, unsigned char data) { 159 #endif 160 __writex18byte(offset, data); 161 } 162 163 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i8, align 1 164 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 165 // CHECK-MSCOMPAT: store i8 %data, ptr %[[DATA_ADDR]], align 1 166 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 167 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 168 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i8, ptr %[[DATA_ADDR]], align 1 169 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 170 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 171 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 172 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 173 // CHECK-MSCOMPAT: store i8 %[[DATA]], ptr %[[PTR]], align 1 174 175 #ifdef __LP64__ 176 void check__writex18word(unsigned short data, unsigned LONG offset) { 177 #else 178 void check__writex18word(unsigned LONG offset, unsigned short data) { 179 #endif 180 __writex18word(offset, data); 181 } 182 183 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i16, align 2 184 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 185 // CHECK-MSCOMPAT: store i16 %data, ptr %[[DATA_ADDR]], align 2 186 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 187 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 188 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i16, ptr %[[DATA_ADDR]], align 2 189 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 190 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 191 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 192 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 193 // CHECK-MSCOMPAT: store i16 %[[DATA]], ptr %[[PTR]], align 1 194 195 #ifdef __LP64__ 196 void check__writex18dword(unsigned LONG data, unsigned LONG offset) { 197 #else 198 void check__writex18dword(unsigned LONG offset, unsigned LONG data) { 199 #endif 200 __writex18dword(offset, data); 201 } 202 203 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i32, align 4 204 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 205 // CHECK-MSCOMPAT: store i32 %data, ptr %[[DATA_ADDR]], align 4 206 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 207 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 208 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i32, ptr %[[DATA_ADDR]], align 4 209 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 210 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 211 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 212 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 213 // CHECK-MSCOMPAT: store i32 %[[DATA]], ptr %[[PTR]], align 1 214 215 #ifdef __LP64__ 216 void check__writex18qword(unsigned __int64 data, unsigned LONG offset) { 217 #else 218 void check__writex18qword(unsigned LONG offset, unsigned __int64 data) { 219 #endif 220 __writex18qword(offset, data); 221 } 222 223 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i64, align 8 224 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 225 // CHECK-MSCOMPAT: store i64 %data, ptr %[[DATA_ADDR]], align 8 226 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 227 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 228 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i64, ptr %[[DATA_ADDR]], align 8 229 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 230 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 231 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 232 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 233 // CHECK-MSCOMPAT: store i64 %[[DATA]], ptr %[[PTR]], align 1 234 235 unsigned char check__readx18byte(unsigned LONG offset) { 236 return __readx18byte(offset); 237 } 238 239 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 240 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 241 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 242 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 243 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 244 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 245 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 246 // CHECK-MSCOMPAT: %[[RETVAL:.*]] = load i8, ptr %[[PTR]], align 1 247 // CHECK-MSCOMPAT: ret i8 %[[RETVAL]] 248 249 unsigned short check__readx18word(unsigned LONG offset) { 250 return __readx18word(offset); 251 } 252 253 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 254 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 255 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 256 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 257 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 258 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 259 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 260 // CHECK-MSCOMPAT: %[[RETVAL:.*]] = load i16, ptr %[[PTR]], align 1 261 // CHECK-MSCOMPAT: ret i16 %[[RETVAL]] 262 263 unsigned LONG check__readx18dword(unsigned LONG offset) { 264 return __readx18dword(offset); 265 } 266 267 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 268 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 269 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 270 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 271 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 272 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 273 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 274 // CHECK-MSCOMPAT: %[[RETVAL:.*]] = load i32, ptr %[[PTR]], align 1 275 // CHECK-MSCOMPAT: ret i32 %[[RETVAL]] 276 277 unsigned __int64 check__readx18qword(unsigned LONG offset) { 278 return __readx18qword(offset); 279 } 280 281 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 282 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 283 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 284 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 285 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 286 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 287 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 288 // CHECK-MSCOMPAT: %[[RETVAL:.*]] = load i64, ptr %[[PTR]], align 1 289 // CHECK-MSCOMPAT: ret i64 %[[RETVAL]] 290 291 #ifdef __LP64__ 292 void check__addx18byte(unsigned char data, unsigned LONG offset) { 293 #else 294 void check__addx18byte(unsigned LONG offset, unsigned char data) { 295 #endif 296 __addx18byte(offset, data); 297 } 298 299 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i8, align 1 300 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 301 // CHECK-MSCOMPAT: store i8 %data, ptr %[[DATA_ADDR]], align 1 302 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 303 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 304 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i8, ptr %[[DATA_ADDR]], align 1 305 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 306 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 307 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 308 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 309 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i8, ptr %[[PTR]], align 1 310 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i8 %[[ORIG_VAL]], %[[DATA]] 311 // CHECK-MSCOMPAT: store i8 %[[SUM]], ptr %[[PTR]], align 1 312 313 #ifdef __LP64__ 314 void check__addx18word(unsigned short data, unsigned LONG offset) { 315 #else 316 void check__addx18word(unsigned LONG offset, unsigned short data) { 317 #endif 318 __addx18word(offset, data); 319 } 320 321 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i16, align 2 322 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 323 // CHECK-MSCOMPAT: store i16 %data, ptr %[[DATA_ADDR]], align 2 324 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 325 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 326 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i16, ptr %[[DATA_ADDR]], align 2 327 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 328 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 329 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 330 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 331 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i16, ptr %[[PTR]], align 1 332 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i16 %[[ORIG_VAL]], %[[DATA]] 333 // CHECK-MSCOMPAT: store i16 %[[SUM]], ptr %[[PTR]], align 1 334 335 #ifdef __LP64__ 336 void check__addx18dword(unsigned LONG data, unsigned LONG offset) { 337 #else 338 void check__addx18dword(unsigned LONG offset, unsigned LONG data) { 339 #endif 340 __addx18dword(offset, data); 341 } 342 343 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i32, align 4 344 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 345 // CHECK-MSCOMPAT: store i32 %data, ptr %[[DATA_ADDR]], align 4 346 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 347 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 348 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i32, ptr %[[DATA_ADDR]], align 4 349 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 350 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 351 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 352 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 353 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i32, ptr %[[PTR]], align 1 354 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i32 %[[ORIG_VAL]], %[[DATA]] 355 // CHECK-MSCOMPAT: store i32 %[[SUM]], ptr %[[PTR]], align 1 356 357 #ifdef __LP64__ 358 void check__addx18qword(unsigned __int64 data, unsigned LONG offset) { 359 #else 360 void check__addx18qword(unsigned LONG offset, unsigned __int64 data) { 361 #endif 362 __addx18qword(offset, data); 363 } 364 365 // CHECK-MSCOMPAT: %[[DATA_ADDR:.*]] = alloca i64, align 8 366 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 367 // CHECK-MSCOMPAT: store i64 %data, ptr %[[DATA_ADDR]], align 8 368 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 369 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 370 // CHECK-MSCOMPAT: %[[DATA:.*]] = load i64, ptr %[[DATA_ADDR]], align 8 371 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 372 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 373 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 374 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 375 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i64, ptr %[[PTR]], align 1 376 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i64 %[[ORIG_VAL]], %[[DATA]] 377 // CHECK-MSCOMPAT: store i64 %[[SUM]], ptr %[[PTR]], align 1 378 379 void check__incx18byte(unsigned LONG offset) { 380 __incx18byte(offset); 381 } 382 383 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 384 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 385 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 386 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 387 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 388 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 389 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 390 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i8, ptr %[[PTR]], align 1 391 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i8 %[[ORIG_VAL]], 1 392 // CHECK-MSCOMPAT: store i8 %[[SUM]], ptr %[[PTR]], align 1 393 394 void check__incx18word(unsigned LONG offset) { 395 __incx18word(offset); 396 } 397 398 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 399 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 400 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 401 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 402 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 403 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 404 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 405 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i16, ptr %[[PTR]], align 1 406 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i16 %[[ORIG_VAL]], 1 407 // CHECK-MSCOMPAT: store i16 %[[SUM]], ptr %[[PTR]], align 1 408 409 void check__incx18dword(unsigned LONG offset) { 410 __incx18dword(offset); 411 } 412 413 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 414 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 415 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 416 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 417 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 418 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 419 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 420 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i32, ptr %[[PTR]], align 1 421 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i32 %[[ORIG_VAL]], 1 422 // CHECK-MSCOMPAT: store i32 %[[SUM]], ptr %[[PTR]], align 1 423 424 void check__incx18qword(unsigned LONG offset) { 425 __incx18qword(offset); 426 } 427 428 // CHECK-MSCOMPAT: %[[OFFSET_ADDR:.*]] = alloca i32, align 4 429 // CHECK-MSCOMPAT: store i32 %offset, ptr %[[OFFSET_ADDR]], align 4 430 // CHECK-MSCOMPAT: %[[OFFSET:.*]] = load i32, ptr %[[OFFSET_ADDR]], align 4 431 // CHECK-MSCOMPAT: %[[X18:.*]] = call i64 @llvm.read_register.i64(metadata ![[MD2]]) 432 // CHECK-MSCOMPAT: %[[X18_AS_PTR:.*]] = inttoptr i64 %[[X18]] to ptr 433 // CHECK-MSCOMPAT: %[[ZEXT_OFFSET:.*]] = zext i32 %[[OFFSET]] to i64 434 // CHECK-MSCOMPAT: %[[PTR:.*]] = getelementptr i8, ptr %[[X18_AS_PTR]], i64 %[[ZEXT_OFFSET]] 435 // CHECK-MSCOMPAT: %[[ORIG_VAL:.*]] = load i64, ptr %[[PTR]], align 1 436 // CHECK-MSCOMPAT: %[[SUM:.*]] = add i64 %[[ORIG_VAL]], 1 437 // CHECK-MSCOMPAT: store i64 %[[SUM]], ptr %[[PTR]], align 1 438 439 double check__CopyDoubleFromInt64(__int64 arg1) { 440 return _CopyDoubleFromInt64(arg1); 441 } 442 443 // CHECK-MSCOMPAT: %[[ARG:.*]].addr = alloca i64, align 8 444 // CHECK-MSCOMPAT: store i64 %[[ARG]], ptr %[[ARG]].addr, align 8 445 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i64, ptr %[[ARG]].addr, align 8 446 // CHECK-MSCOMPAT: %[[VAR1:.*]] = bitcast i64 %[[VAR0]] to double 447 // CHECK-MSCOMPAT: ret double %[[VAR1]] 448 // CHECK-LINUX: error: call to undeclared function '_CopyDoubleFromInt64' 449 450 float check__CopyFloatFromInt32(__int32 arg1) { 451 return _CopyFloatFromInt32(arg1); 452 } 453 454 // CHECK-MSCOMPAT: %[[ARG:.*]].addr = alloca i32, align 4 455 // CHECK-MSCOMPAT: store i32 %[[ARG]], ptr %[[ARG]].addr, align 4 456 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i32, ptr %[[ARG]].addr, align 4 457 // CHECK-MSCOMPAT: %[[VAR1:.*]] = bitcast i32 %[[VAR0]] to float 458 // CHECK-MSCOMPAT: ret float %[[VAR1]] 459 // CHECK-LINUX: error: call to undeclared function '_CopyFloatFromInt32' 460 461 __int32 check__CopyInt32FromFloat(float arg1) { 462 return _CopyInt32FromFloat(arg1); 463 } 464 465 // CHECK-MSCOMPAT: %[[ARG:.*]].addr = alloca float, align 4 466 // CHECK-MSCOMPAT: store float %[[ARG]], ptr %[[ARG]].addr, align 4 467 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load float, ptr %[[ARG]].addr, align 4 468 // CHECK-MSCOMPAT: %[[VAR1:.*]] = bitcast float %[[VAR0]] to i32 469 // CHECK-MSCOMPAT: ret i32 %[[VAR1]] 470 // CHECK-LINUX: error: call to undeclared function '_CopyInt32FromFloat' 471 472 __int64 check__CopyInt64FromDouble(double arg1) { 473 return _CopyInt64FromDouble(arg1); 474 } 475 476 // CHECK-MSCOMPAT: %[[ARG:.*]].addr = alloca double, align 8 477 // CHECK-MSCOMPAT: store double %[[ARG]], ptr %[[ARG]].addr, align 8 478 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load double, ptr %[[ARG]].addr, align 8 479 // CHECK-MSCOMPAT: %[[VAR1:.*]] = bitcast double %[[VAR0]] to i64 480 // CHECK-MSCOMPAT: ret i64 %[[VAR1]] 481 // CHECK-LINUX: error: call to undeclared function '_CopyInt64FromDouble' 482 483 unsigned int check__CountLeadingOnes(unsigned LONG arg1) { 484 return _CountLeadingOnes(arg1); 485 } 486 487 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i32, align 4 488 // CHECK-MSCOMPAT: store i32 %[[ARG1]], ptr %[[ARG1]].addr, align 4 489 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i32, ptr %[[ARG1]].addr, align 4 490 // CHECK-MSCOMPAT: %[[VAR1:.*]] = xor i32 %[[VAR0]], -1 491 // CHECK-MSCOMPAT: %[[VAR2:.*]] = call i32 @llvm.ctlz.i32(i32 %1, i1 false) 492 // CHECK-MSCOMPAT: ret i32 %[[VAR2]] 493 // CHECK-LINUX: error: call to undeclared function '_CountLeadingOnes' 494 495 unsigned int check__CountLeadingOnes64(unsigned __int64 arg1) { 496 return _CountLeadingOnes64(arg1); 497 } 498 499 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i64, align 8 500 // CHECK-MSCOMPAT: store i64 %[[ARG1]], ptr %[[ARG1]].addr, align 8 501 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i64, ptr %[[ARG1]].addr, align 8 502 // CHECK-MSCOMPAT: %[[VAR1:.*]] = xor i64 %[[VAR0]], -1 503 // CHECK-MSCOMPAT: %[[VAR2:.*]] = call i64 @llvm.ctlz.i64(i64 %1, i1 false) 504 // CHECK-MSCOMPAT: %[[VAR3:.*]] = trunc i64 %2 to i32 505 // CHECK-MSCOMPAT: ret i32 %[[VAR3]] 506 // CHECK-LINUX: error: call to undeclared function '_CountLeadingOnes64' 507 508 unsigned int check__CountLeadingSigns(__int32 arg1) { 509 return _CountLeadingSigns(arg1); 510 } 511 512 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i32, align 4 513 // CHECK-MSCOMPAT: store i32 %[[ARG1]], ptr %[[ARG1]].addr, align 4 514 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i32, ptr %[[ARG1]].addr, align 4 515 // CHECK-MSCOMPAT: %[[CLS:.*]] = call i32 @llvm.aarch64.cls(i32 %[[VAR0]]) 516 // CHECK-MSCOMPAT: ret i32 %[[CLS]] 517 // CHECK-LINUX: error: call to undeclared function '_CountLeadingSigns' 518 519 unsigned int check__CountLeadingSigns64(__int64 arg1) { 520 return _CountLeadingSigns64(arg1); 521 } 522 523 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i64, align 8 524 // CHECK-MSCOMPAT: store i64 %[[ARG1]], ptr %[[ARG1]].addr, align 8 525 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i64, ptr %[[ARG1]].addr, align 8 526 // CHECK-MSCOMPAT: %[[CLS:.*]] = call i32 @llvm.aarch64.cls64(i64 %[[VAR0]]) 527 // CHECK-MSCOMPAT: ret i32 %[[CLS]] 528 // CHECK-LINUX: error: call to undeclared function '_CountLeadingSigns64' 529 530 unsigned int check__CountLeadingZeros(__int32 arg1) { 531 return _CountLeadingZeros(arg1); 532 } 533 534 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i32, align 4 535 // CHECK-MSCOMPAT: store i32 %[[ARG1]], ptr %[[ARG1]].addr, align 4 536 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i32, ptr %[[ARG1]].addr, align 4 537 // CHECK-MSCOMPAT: %[[VAR1:.*]] = call i32 @llvm.ctlz.i32(i32 %[[VAR0]], i1 false) 538 // CHECK-MSCOMPAT: ret i32 %[[VAR1]] 539 // CHECK-LINUX: error: call to undeclared function '_CountLeadingZeros' 540 541 unsigned int check__CountLeadingZeros64(__int64 arg1) { 542 return _CountLeadingZeros64(arg1); 543 } 544 545 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i64, align 8 546 // CHECK-MSCOMPAT: store i64 %[[ARG1]], ptr %[[ARG1]].addr, align 8 547 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i64, ptr %[[ARG1]].addr, align 8 548 // CHECK-MSCOMPAT: %[[VAR1:.*]] = call i64 @llvm.ctlz.i64(i64 %[[VAR0]], i1 false) 549 // CHECK-MSCOMPAT: %[[VAR2:.*]] = trunc i64 %[[VAR1]] to i32 550 // CHECK-MSCOMPAT: ret i32 %[[VAR2]] 551 // CHECK-LINUX: error: call to undeclared function '_CountLeadingZeros64' 552 553 unsigned int check_CountOneBits(unsigned LONG arg1) { 554 return _CountOneBits(arg1); 555 } 556 557 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i32, align 4 558 // CHECK-MSCOMPAT: store i32 %[[ARG1]], ptr %[[ARG1]].addr, align 4 559 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i32, ptr %[[ARG1]].addr, align 4 560 // CHECK-MSCOMPAT: %[[VAR1:.*]] = call i32 @llvm.ctpop.i32(i32 %0) 561 // CHECK-MSCOMPAT: ret i32 %[[VAR1]] 562 // CHECK-LINUX: error: call to undeclared function '_CountOneBits' 563 564 unsigned int check_CountOneBits64(unsigned __int64 arg1) { 565 return _CountOneBits64(arg1); 566 } 567 568 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca i64, align 8 569 // CHECK-MSCOMPAT: store i64 %[[ARG1]], ptr %[[ARG1]].addr, align 8 570 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load i64, ptr %[[ARG1]].addr, align 8 571 // CHECK-MSCOMPAT: %[[VAR1:.*]] = call i64 @llvm.ctpop.i64(i64 %0) 572 // CHECK-MSCOMPAT: %[[VAR2:.*]] = trunc i64 %1 to i32 573 // CHECK-MSCOMPAT: ret i32 %[[VAR2]] 574 // CHECK-LINUX: error: call to undeclared function '_CountOneBits64' 575 576 void check__prefetch(void *arg1) { 577 return __prefetch(arg1); 578 } 579 580 // CHECK-MSCOMPAT: %[[ARG1:.*]].addr = alloca ptr, align 8 581 // CHECK-MSCOMPAT: store ptr %[[ARG1]], ptr %[[ARG1]].addr, align 8 582 // CHECK-MSCOMPAT: %[[VAR0:.*]] = load ptr, ptr %[[ARG1]].addr, align 8 583 // CHECK-MSCOMPAT: call void @llvm.prefetch.p0(ptr %[[VAR0]], i32 0, i32 3, i32 1) 584 // CHECK-MSCOMPAT: ret void 585 586 587 // CHECK-MSCOMPAT: ![[MD2]] = !{!"x18"} 588 // CHECK-MSCOMPAT: ![[MD3]] = !{!"sp"} 589