1 // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O2 -fno-experimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 -check-prefix=ARM-LEGACY -check-prefix=AArch32-LEGACY 2 // RUN: %clang_cc1 -ffreestanding -triple armv8-eabi -target-cpu cortex-a57 -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch32 -check-prefix=ARM-NEWPM -check-prefix=AArch32-NEWPM 3 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O2 -fno-experimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 -check-prefix=ARM-LEGACY -check-prefix=AArch64-LEGACY 4 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +neon -target-feature +crc -target-feature +crypto -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=ARM -check-prefix=AArch64 -check-prefix=ARM-NEWPM -check-prefix=AArch64-NEWPM 5 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.3a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3 6 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.4a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3 7 // RUN: %clang_cc1 -ffreestanding -triple aarch64-eabi -target-cpu cortex-a57 -target-feature +v8.5a -O2 -fexperimental-new-pass-manager -S -emit-llvm -o - %s | FileCheck %s -check-prefix=AArch64-v8_3 8 9 // REQUIRES: rewrite 10 11 #include <arm_acle.h> 12 13 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ 14 /* 8.3 Memory Barriers */ 15 // ARM-LABEL: test_dmb 16 // AArch32: call void @llvm.arm.dmb(i32 1) 17 // AArch64: call void @llvm.aarch64.dmb(i32 1) 18 void test_dmb(void) { 19 __dmb(1); 20 } 21 22 // ARM-LABEL: test_dsb 23 // AArch32: call void @llvm.arm.dsb(i32 2) 24 // AArch64: call void @llvm.aarch64.dsb(i32 2) 25 void test_dsb(void) { 26 __dsb(2); 27 } 28 29 // ARM-LABEL: test_isb 30 // AArch32: call void @llvm.arm.isb(i32 3) 31 // AArch64: call void @llvm.aarch64.isb(i32 3) 32 void test_isb(void) { 33 __isb(3); 34 } 35 36 /* 8.4 Hints */ 37 // ARM-LABEL: test_yield 38 // AArch32: call void @llvm.arm.hint(i32 1) 39 // AArch64: call void @llvm.aarch64.hint(i32 1) 40 void test_yield(void) { 41 __yield(); 42 } 43 44 // ARM-LABEL: test_wfe 45 // AArch32: call void @llvm.arm.hint(i32 2) 46 // AArch64: call void @llvm.aarch64.hint(i32 2) 47 void test_wfe(void) { 48 __wfe(); 49 } 50 51 // ARM-LABEL: test_wfi 52 // AArch32: call void @llvm.arm.hint(i32 3) 53 // AArch64: call void @llvm.aarch64.hint(i32 3) 54 void test_wfi(void) { 55 __wfi(); 56 } 57 58 // ARM-LABEL: test_sev 59 // AArch32: call void @llvm.arm.hint(i32 4) 60 // AArch64: call void @llvm.aarch64.hint(i32 4) 61 void test_sev(void) { 62 __sev(); 63 } 64 65 // ARM-LABEL: test_sevl 66 // AArch32: call void @llvm.arm.hint(i32 5) 67 // AArch64: call void @llvm.aarch64.hint(i32 5) 68 void test_sevl(void) { 69 __sevl(); 70 } 71 72 #if __ARM_32BIT_STATE 73 // AArch32-LABEL: test_dbg 74 // AArch32: call void @llvm.arm.dbg(i32 0) 75 void test_dbg(void) { 76 __dbg(0); 77 } 78 #endif 79 80 /* 8.5 Swap */ 81 // ARM-LABEL: test_swp 82 // AArch32: call i32 @llvm.arm.ldrex 83 // AArch32: call i32 @llvm.arm.strex 84 // AArch64: call i64 @llvm.aarch64.ldxr 85 // AArch64: call i32 @llvm.aarch64.stxr 86 void test_swp(uint32_t x, volatile void *p) { 87 __swp(x, p); 88 } 89 90 /* 8.6 Memory prefetch intrinsics */ 91 /* 8.6.1 Data prefetch */ 92 // ARM-LABEL: test_pld 93 // ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 1) 94 void test_pld() { 95 __pld(0); 96 } 97 98 // ARM-LABEL: test_pldx 99 // AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 3, i32 1) 100 // AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 1, i32 1, i32 1) 101 void test_pldx() { 102 __pldx(1, 2, 0, 0); 103 } 104 105 /* 8.6.2 Instruction prefetch */ 106 // ARM-LABEL: test_pli 107 // ARM: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0) 108 void test_pli() { 109 __pli(0); 110 } 111 112 // ARM-LABEL: test_plix 113 // AArch32: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 3, i32 0) 114 // AArch64: call void @llvm.prefetch.p0i8(i8* null, i32 0, i32 1, i32 0) 115 void test_plix() { 116 __plix(2, 0, 0); 117 } 118 119 /* 8.7 NOP */ 120 // ARM-LABEL: test_nop 121 // AArch32: call void @llvm.arm.hint(i32 0) 122 // AArch64: call void @llvm.aarch64.hint(i32 0) 123 void test_nop(void) { 124 __nop(); 125 } 126 127 /* 9 DATA-PROCESSING INTRINSICS */ 128 129 /* 9.2 Miscellaneous data-processing intrinsics */ 130 // ARM-LABEL: test_ror 131 // ARM-LEGACY: lshr 132 // ARM-LEGACY: sub 133 // ARM-LEGACY: shl 134 // ARM-LEGACY: or 135 // ARM-NEWPM: call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y) 136 uint32_t test_ror(uint32_t x, uint32_t y) { 137 return __ror(x, y); 138 } 139 140 // ARM-LABEL: test_rorl 141 // ARM-LEGACY: lshr 142 // ARM-LEGACY: sub 143 // ARM-LEGACY: shl 144 // ARM-LEGACY: or 145 // AArch32-NEWPM: call i32 @llvm.fshr.i32(i32 %x, i32 %x, i32 %y) 146 unsigned long test_rorl(unsigned long x, uint32_t y) { 147 return __rorl(x, y); 148 } 149 150 // ARM-LABEL: test_rorll 151 // ARM: lshr 152 // ARM: sub 153 // ARM: shl 154 // ARM: or 155 uint64_t test_rorll(uint64_t x, uint32_t y) { 156 return __rorll(x, y); 157 } 158 159 // ARM-LABEL: test_clz 160 // ARM: call i32 @llvm.ctlz.i32(i32 %t, i1 false) 161 uint32_t test_clz(uint32_t t) { 162 return __clz(t); 163 } 164 165 // ARM-LABEL: test_clzl 166 // AArch32: call i32 @llvm.ctlz.i32(i32 %t, i1 false) 167 // AArch64: call i64 @llvm.ctlz.i64(i64 %t, i1 false) 168 long test_clzl(long t) { 169 return __clzl(t); 170 } 171 172 // ARM-LABEL: test_clzll 173 // ARM: call i64 @llvm.ctlz.i64(i64 %t, i1 false) 174 uint64_t test_clzll(uint64_t t) { 175 return __clzll(t); 176 } 177 178 // ARM-LABEL: test_cls 179 // ARM: call i32 @llvm.arm.cls(i32 %t) 180 unsigned test_cls(uint32_t t) { 181 return __cls(t); 182 } 183 184 // ARM-LABEL: test_clsl 185 // AArch32: call i32 @llvm.arm.cls(i32 %t) 186 // AArch64: call i32 @llvm.arm.cls64(i64 %t) 187 unsigned test_clsl(unsigned long t) { 188 return __clsl(t); 189 } 190 // ARM-LABEL: test_clsll 191 // ARM: call i32 @llvm.arm.cls64(i64 %t) 192 unsigned test_clsll(uint64_t t) { 193 return __clsll(t); 194 } 195 196 // ARM-LABEL: test_rev 197 // ARM: call i32 @llvm.bswap.i32(i32 %t) 198 uint32_t test_rev(uint32_t t) { 199 return __rev(t); 200 } 201 202 // ARM-LABEL: test_revl 203 // AArch32: call i32 @llvm.bswap.i32(i32 %t) 204 // AArch64: call i64 @llvm.bswap.i64(i64 %t) 205 long test_revl(long t) { 206 return __revl(t); 207 } 208 209 // ARM-LABEL: test_revll 210 // ARM: call i64 @llvm.bswap.i64(i64 %t) 211 uint64_t test_revll(uint64_t t) { 212 return __revll(t); 213 } 214 215 // ARM-LABEL: test_rev16 216 // ARM: llvm.bswap 217 // ARM-LEGACY: lshr {{.*}}, 16 218 // ARM-LEGACY: shl {{.*}}, 16 219 // ARM-LEGACY: or 220 // ARM-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16) 221 uint32_t test_rev16(uint32_t t) { 222 return __rev16(t); 223 } 224 225 // ARM-LABEL: test_rev16l 226 // AArch32: llvm.bswap 227 // AArch32-LEGACY: lshr {{.*}}, 16 228 // AArch32-LEGACY: shl {{.*}}, 16 229 // AArch32-LEGACY: or 230 // AArch32-NEWPM: call i32 @llvm.fshl.i32(i32 %0, i32 %0, i32 16) 231 // AArch64: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 232 // AArch64: [[T2:%.*]] = trunc i64 [[T1]] to i32 233 // AArch64: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) 234 // AArch64-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16 235 // AArch64-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16 236 // AArch64-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]] 237 // AArch64-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16) 238 // AArch64: [[T7:%.*]] = zext i32 [[T6]] to i64 239 // AArch64: [[T8:%.*]] = shl nuw i64 [[T7]], 32 240 // AArch64: [[T9:%.*]] = trunc i64 [[IN]] to i32 241 // AArch64: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) 242 // AArch64-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16 243 // AArch64-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16 244 // AArch64-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]] 245 // AArch64-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16) 246 // AArch64: [[T14:%.*]] = zext i32 [[T13]] to i64 247 // AArch64: [[T15:%.*]] = or i64 [[T8]], [[T14]] 248 long test_rev16l(long t) { 249 return __rev16l(t); 250 } 251 252 // ARM-LABEL: test_rev16ll 253 // ARM: [[T1:%.*]] = lshr i64 [[IN:%.*]], 32 254 // ARM: [[T2:%.*]] = trunc i64 [[T1]] to i32 255 // ARM: [[T3:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T2]]) 256 // ARM-LEGACY: [[T4:%.*]] = lshr i32 [[T3]], 16 257 // ARM-LEGACY: [[T5:%.*]] = shl i32 [[T3]], 16 258 // ARM-LEGACY: [[T6:%.*]] = or i32 [[T5]], [[T4]] 259 // ARM-NEWPM: [[T6:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T3]], i32 [[T3]], i32 16) 260 // ARM: [[T7:%.*]] = zext i32 [[T6]] to i64 261 // ARM: [[T8:%.*]] = shl nuw i64 [[T7]], 32 262 // ARM: [[T9:%.*]] = trunc i64 [[IN]] to i32 263 // ARM: [[T10:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[T9]]) 264 // ARM-LEGACY: [[T11:%.*]] = lshr i32 [[T10]], 16 265 // ARM-LEGACY: [[T12:%.*]] = shl i32 [[T10]], 16 266 // ARM-LEGACY: [[T13:%.*]] = or i32 [[T12]], [[T11]] 267 // ARM-NEWPM: [[T13:%.*]] = tail call i32 @llvm.fshl.i32(i32 [[T10]], i32 [[T10]], i32 16) 268 // ARM: [[T14:%.*]] = zext i32 [[T13]] to i64 269 // ARM: [[T15:%.*]] = or i64 [[T8]], [[T14]] 270 uint64_t test_rev16ll(uint64_t t) { 271 return __rev16ll(t); 272 } 273 274 // ARM-LABEL: test_revsh 275 // ARM: call i16 @llvm.bswap.i16(i16 %t) 276 int16_t test_revsh(int16_t t) { 277 return __revsh(t); 278 } 279 280 // ARM-LABEL: test_rbit 281 // AArch32: call i32 @llvm.bitreverse.i32 282 // AArch64: call i32 @llvm.bitreverse.i32 283 uint32_t test_rbit(uint32_t t) { 284 return __rbit(t); 285 } 286 287 // ARM-LABEL: test_rbitl 288 // AArch32: call i32 @llvm.bitreverse.i32 289 // AArch64: call i64 @llvm.bitreverse.i64 290 long test_rbitl(long t) { 291 return __rbitl(t); 292 } 293 294 // ARM-LABEL: test_rbitll 295 // AArch32: call i32 @llvm.bitreverse.i32 296 // AArch32: call i32 @llvm.bitreverse.i32 297 // AArch64: call i64 @llvm.bitreverse.i64 298 uint64_t test_rbitll(uint64_t t) { 299 return __rbitll(t); 300 } 301 302 /* 9.4 Saturating intrinsics */ 303 #ifdef __ARM_FEATURE_SAT 304 /* 9.4.1 Width-specified saturation intrinsics */ 305 // AArch32-LABEL: test_ssat 306 // AArch32: call i32 @llvm.arm.ssat(i32 %t, i32 1) 307 int32_t test_ssat(int32_t t) { 308 return __ssat(t, 1); 309 } 310 311 // AArch32-LABEL: test_usat 312 // AArch32: call i32 @llvm.arm.usat(i32 %t, i32 2) 313 uint32_t test_usat(int32_t t) { 314 return __usat(t, 2); 315 } 316 #endif 317 318 /* 9.4.2 Saturating addition and subtraction intrinsics */ 319 #ifdef __ARM_FEATURE_DSP 320 // AArch32-LABEL: test_qadd 321 // AArch32: call i32 @llvm.arm.qadd(i32 %a, i32 %b) 322 int32_t test_qadd(int32_t a, int32_t b) { 323 return __qadd(a, b); 324 } 325 326 // AArch32-LABEL: test_qsub 327 // AArch32: call i32 @llvm.arm.qsub(i32 %a, i32 %b) 328 int32_t test_qsub(int32_t a, int32_t b) { 329 return __qsub(a, b); 330 } 331 332 extern int32_t f(); 333 // AArch32-LABEL: test_qdbl 334 // AArch32: [[VAR:%[a-z0-9]+]] = {{.*}} call {{.*}} @f 335 // AArch32-NOT: call {{.*}} @f 336 // AArch32: call i32 @llvm.arm.qadd(i32 [[VAR]], i32 [[VAR]]) 337 int32_t test_qdbl() { 338 return __qdbl(f()); 339 } 340 #endif 341 342 /* 343 * 9.3 16-bit multiplications 344 */ 345 #if __ARM_FEATURE_DSP 346 // AArch32-LABEL: test_smulbb 347 // AArch32: call i32 @llvm.arm.smulbb 348 int32_t test_smulbb(int32_t a, int32_t b) { 349 return __smulbb(a, b); 350 } 351 // AArch32-LABEL: test_smulbt 352 // AArch32: call i32 @llvm.arm.smulbt 353 int32_t test_smulbt(int32_t a, int32_t b) { 354 return __smulbt(a, b); 355 } 356 // AArch32-LABEL: test_smultb 357 // AArch32: call i32 @llvm.arm.smultb 358 int32_t test_smultb(int32_t a, int32_t b) { 359 return __smultb(a, b); 360 } 361 // AArch32-LABEL: test_smultt 362 // AArch32: call i32 @llvm.arm.smultt 363 int32_t test_smultt(int32_t a, int32_t b) { 364 return __smultt(a, b); 365 } 366 // AArch32-LABEL: test_smulwb 367 // AArch32: call i32 @llvm.arm.smulwb 368 int32_t test_smulwb(int32_t a, int32_t b) { 369 return __smulwb(a, b); 370 } 371 // AArch32-LABEL: test_smulwt 372 // AArch32: call i32 @llvm.arm.smulwt 373 int32_t test_smulwt(int32_t a, int32_t b) { 374 return __smulwt(a, b); 375 } 376 #endif 377 378 /* 9.4.3 Accumultating multiplications */ 379 #if __ARM_FEATURE_DSP 380 // AArch32-LABEL: test_smlabb 381 // AArch32: call i32 @llvm.arm.smlabb(i32 %a, i32 %b, i32 %c) 382 int32_t test_smlabb(int32_t a, int32_t b, int32_t c) { 383 return __smlabb(a, b, c); 384 } 385 // AArch32-LABEL: test_smlabt 386 // AArch32: call i32 @llvm.arm.smlabt(i32 %a, i32 %b, i32 %c) 387 int32_t test_smlabt(int32_t a, int32_t b, int32_t c) { 388 return __smlabt(a, b, c); 389 } 390 // AArch32-LABEL: test_smlatb 391 // AArch32: call i32 @llvm.arm.smlatb(i32 %a, i32 %b, i32 %c) 392 int32_t test_smlatb(int32_t a, int32_t b, int32_t c) { 393 return __smlatb(a, b, c); 394 } 395 // AArch32-LABEL: test_smlatt 396 // AArch32: call i32 @llvm.arm.smlatt(i32 %a, i32 %b, i32 %c) 397 int32_t test_smlatt(int32_t a, int32_t b, int32_t c) { 398 return __smlatt(a, b, c); 399 } 400 // AArch32-LABEL: test_smlawb 401 // AArch32: call i32 @llvm.arm.smlawb(i32 %a, i32 %b, i32 %c) 402 int32_t test_smlawb(int32_t a, int32_t b, int32_t c) { 403 return __smlawb(a, b, c); 404 } 405 // AArch32-LABEL: test_smlawt 406 // AArch32: call i32 @llvm.arm.smlawt(i32 %a, i32 %b, i32 %c) 407 int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { 408 return __smlawt(a, b, c); 409 } 410 #endif 411 412 /* 9.5.4 Parallel 16-bit saturation */ 413 #if __ARM_FEATURE_SIMD32 414 // AArch32-LABEL: test_ssat16 415 // AArch32: call i32 @llvm.arm.ssat16 416 int16x2_t test_ssat16(int16x2_t a) { 417 return __ssat16(a, 15); 418 } 419 // AArch32-LABEL: test_usat16 420 // AArch32: call i32 @llvm.arm.usat16 421 uint16x2_t test_usat16(int16x2_t a) { 422 return __usat16(a, 15); 423 } 424 #endif 425 426 /* 9.5.5 Packing and unpacking */ 427 #if __ARM_FEATURE_SIMD32 428 // AArch32-LABEL: test_sxtab16 429 // AArch32: call i32 @llvm.arm.sxtab16 430 int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) { 431 return __sxtab16(a, b); 432 } 433 // AArch32-LABEL: test_sxtb16 434 // AArch32: call i32 @llvm.arm.sxtb16 435 int16x2_t test_sxtb16(int8x4_t a) { 436 return __sxtb16(a); 437 } 438 // AArch32-LABEL: test_uxtab16 439 // AArch32: call i32 @llvm.arm.uxtab16 440 int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) { 441 return __uxtab16(a, b); 442 } 443 // AArch32-LABEL: test_uxtb16 444 // AArch32: call i32 @llvm.arm.uxtb16 445 int16x2_t test_uxtb16(int8x4_t a) { 446 return __uxtb16(a); 447 } 448 #endif 449 450 /* 9.5.6 Parallel selection */ 451 #if __ARM_FEATURE_SIMD32 452 // AArch32-LABEL: test_sel 453 // AArch32: call i32 @llvm.arm.sel 454 uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { 455 return __sel(a, b); 456 } 457 #endif 458 459 /* 9.5.7 Parallel 8-bit addition and subtraction */ 460 #if __ARM_FEATURE_SIMD32 461 // AArch32-LABEL: test_qadd8 462 // AArch32: call i32 @llvm.arm.qadd8 463 int16x2_t test_qadd8(int8x4_t a, int8x4_t b) { 464 return __qadd8(a, b); 465 } 466 // AArch32-LABEL: test_qsub8 467 // AArch32: call i32 @llvm.arm.qsub8 468 int8x4_t test_qsub8(int8x4_t a, int8x4_t b) { 469 return __qsub8(a, b); 470 } 471 // AArch32-LABEL: test_sadd8 472 // AArch32: call i32 @llvm.arm.sadd8 473 int8x4_t test_sadd8(int8x4_t a, int8x4_t b) { 474 return __sadd8(a, b); 475 } 476 // AArch32-LABEL: test_shadd8 477 // AArch32: call i32 @llvm.arm.shadd8 478 int8x4_t test_shadd8(int8x4_t a, int8x4_t b) { 479 return __shadd8(a, b); 480 } 481 // AArch32-LABEL: test_shsub8 482 // AArch32: call i32 @llvm.arm.shsub8 483 int8x4_t test_shsub8(int8x4_t a, int8x4_t b) { 484 return __shsub8(a, b); 485 } 486 // AArch32-LABEL: test_ssub8 487 // AArch32: call i32 @llvm.arm.ssub8 488 int8x4_t test_ssub8(int8x4_t a, int8x4_t b) { 489 return __ssub8(a, b); 490 } 491 // AArch32-LABEL: test_uadd8 492 // AArch32: call i32 @llvm.arm.uadd8 493 uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) { 494 return __uadd8(a, b); 495 } 496 // AArch32-LABEL: test_uhadd8 497 // AArch32: call i32 @llvm.arm.uhadd8 498 uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) { 499 return __uhadd8(a, b); 500 } 501 // AArch32-LABEL: test_uhsub8 502 // AArch32: call i32 @llvm.arm.uhsub8 503 uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) { 504 return __uhsub8(a, b); 505 } 506 // AArch32-LABEL: test_uqadd8 507 // AArch32: call i32 @llvm.arm.uqadd8 508 uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) { 509 return __uqadd8(a, b); 510 } 511 // AArch32-LABEL: test_uqsub8 512 // AArch32: call i32 @llvm.arm.uqsub8 513 uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) { 514 return __uqsub8(a, b); 515 } 516 // AArch32-LABEL: test_usub8 517 // AArch32: call i32 @llvm.arm.usub8 518 uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { 519 return __usub8(a, b); 520 } 521 #endif 522 523 /* 9.5.8 Sum of 8-bit absolute differences */ 524 #if __ARM_FEATURE_SIMD32 525 // AArch32-LABEL: test_usad8 526 // AArch32: call i32 @llvm.arm.usad8 527 uint32_t test_usad8(uint8x4_t a, uint8x4_t b) { 528 return __usad8(a, b); 529 } 530 // AArch32-LABEL: test_usada8 531 // AArch32: call i32 @llvm.arm.usada8 532 uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { 533 return __usada8(a, b, c); 534 } 535 #endif 536 537 /* 9.5.9 Parallel 16-bit addition and subtraction */ 538 #if __ARM_FEATURE_SIMD32 539 // AArch32-LABEL: test_qadd16 540 // AArch32: call i32 @llvm.arm.qadd16 541 int16x2_t test_qadd16(int16x2_t a, int16x2_t b) { 542 return __qadd16(a, b); 543 } 544 // AArch32-LABEL: test_qasx 545 // AArch32: call i32 @llvm.arm.qasx 546 int16x2_t test_qasx(int16x2_t a, int16x2_t b) { 547 return __qasx(a, b); 548 } 549 // AArch32-LABEL: test_qsax 550 // AArch32: call i32 @llvm.arm.qsax 551 int16x2_t test_qsax(int16x2_t a, int16x2_t b) { 552 return __qsax(a, b); 553 } 554 // AArch32-LABEL: test_qsub16 555 // AArch32: call i32 @llvm.arm.qsub16 556 int16x2_t test_qsub16(int16x2_t a, int16x2_t b) { 557 return __qsub16(a, b); 558 } 559 // AArch32-LABEL: test_sadd16 560 // AArch32: call i32 @llvm.arm.sadd16 561 int16x2_t test_sadd16(int16x2_t a, int16x2_t b) { 562 return __sadd16(a, b); 563 } 564 // AArch32-LABEL: test_sasx 565 // AArch32: call i32 @llvm.arm.sasx 566 int16x2_t test_sasx(int16x2_t a, int16x2_t b) { 567 return __sasx(a, b); 568 } 569 // AArch32-LABEL: test_shadd16 570 // AArch32: call i32 @llvm.arm.shadd16 571 int16x2_t test_shadd16(int16x2_t a, int16x2_t b) { 572 return __shadd16(a, b); 573 } 574 // AArch32-LABEL: test_shasx 575 // AArch32: call i32 @llvm.arm.shasx 576 int16x2_t test_shasx(int16x2_t a, int16x2_t b) { 577 return __shasx(a, b); 578 } 579 // AArch32-LABEL: test_shsax 580 // AArch32: call i32 @llvm.arm.shsax 581 int16x2_t test_shsax(int16x2_t a, int16x2_t b) { 582 return __shsax(a, b); 583 } 584 // AArch32-LABEL: test_shsub16 585 // AArch32: call i32 @llvm.arm.shsub16 586 int16x2_t test_shsub16(int16x2_t a, int16x2_t b) { 587 return __shsub16(a, b); 588 } 589 // AArch32-LABEL: test_ssax 590 // AArch32: call i32 @llvm.arm.ssax 591 int16x2_t test_ssax(int16x2_t a, int16x2_t b) { 592 return __ssax(a, b); 593 } 594 // AArch32-LABEL: test_ssub16 595 // AArch32: call i32 @llvm.arm.ssub16 596 int16x2_t test_ssub16(int16x2_t a, int16x2_t b) { 597 return __ssub16(a, b); 598 } 599 // AArch32-LABEL: test_uadd16 600 // AArch32: call i32 @llvm.arm.uadd16 601 uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) { 602 return __uadd16(a, b); 603 } 604 // AArch32-LABEL: test_uasx 605 // AArch32: call i32 @llvm.arm.uasx 606 uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) { 607 return __uasx(a, b); 608 } 609 // AArch32-LABEL: test_uhadd16 610 // AArch32: call i32 @llvm.arm.uhadd16 611 uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) { 612 return __uhadd16(a, b); 613 } 614 // AArch32-LABEL: test_uhasx 615 // AArch32: call i32 @llvm.arm.uhasx 616 uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) { 617 return __uhasx(a, b); 618 } 619 // AArch32-LABEL: test_uhsax 620 // AArch32: call i32 @llvm.arm.uhsax 621 uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) { 622 return __uhsax(a, b); 623 } 624 // AArch32-LABEL: test_uhsub16 625 // AArch32: call i32 @llvm.arm.uhsub16 626 uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) { 627 return __uhsub16(a, b); 628 } 629 // AArch32-LABEL: test_uqadd16 630 // AArch32: call i32 @llvm.arm.uqadd16 631 uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) { 632 return __uqadd16(a, b); 633 } 634 // AArch32-LABEL: test_uqasx 635 // AArch32: call i32 @llvm.arm.uqasx 636 uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) { 637 return __uqasx(a, b); 638 } 639 // AArch32-LABEL: test_uqsax 640 // AArch32: call i32 @llvm.arm.uqsax 641 uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) { 642 return __uqsax(a, b); 643 } 644 // AArch32-LABEL: test_uqsub16 645 // AArch32: call i32 @llvm.arm.uqsub16 646 uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) { 647 return __uqsub16(a, b); 648 } 649 // AArch32-LABEL: test_usax 650 // AArch32: call i32 @llvm.arm.usax 651 uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) { 652 return __usax(a, b); 653 } 654 // AArch32-LABEL: test_usub16 655 // AArch32: call i32 @llvm.arm.usub16 656 uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { 657 return __usub16(a, b); 658 } 659 #endif 660 661 /* 9.5.10 Parallel 16-bit multiplications */ 662 #if __ARM_FEATURE_SIMD32 663 // AArch32-LABEL: test_smlad 664 // AArch32: call i32 @llvm.arm.smlad 665 int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) { 666 return __smlad(a, b, c); 667 } 668 // AArch32-LABEL: test_smladx 669 // AArch32: call i32 @llvm.arm.smladx 670 int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) { 671 return __smladx(a, b, c); 672 } 673 // AArch32-LABEL: test_smlald 674 // AArch32: call i64 @llvm.arm.smlald 675 int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) { 676 return __smlald(a, b, c); 677 } 678 // AArch32-LABEL: test_smlaldx 679 // AArch32: call i64 @llvm.arm.smlaldx 680 int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) { 681 return __smlaldx(a, b, c); 682 } 683 // AArch32-LABEL: test_smlsd 684 // AArch32: call i32 @llvm.arm.smlsd 685 int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) { 686 return __smlsd(a, b, c); 687 } 688 // AArch32-LABEL: test_smlsdx 689 // AArch32: call i32 @llvm.arm.smlsdx 690 int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) { 691 return __smlsdx(a, b, c); 692 } 693 // AArch32-LABEL: test_smlsld 694 // AArch32: call i64 @llvm.arm.smlsld 695 int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) { 696 return __smlsld(a, b, c); 697 } 698 // AArch32-LABEL: test_smlsldx 699 // AArch32: call i64 @llvm.arm.smlsldx 700 int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) { 701 return __smlsldx(a, b, c); 702 } 703 // AArch32-LABEL: test_smuad 704 // AArch32: call i32 @llvm.arm.smuad 705 int32_t test_smuad(int16x2_t a, int16x2_t b) { 706 return __smuad(a, b); 707 } 708 // AArch32-LABEL: test_smuadx 709 // AArch32: call i32 @llvm.arm.smuadx 710 int32_t test_smuadx(int16x2_t a, int16x2_t b) { 711 return __smuadx(a, b); 712 } 713 // AArch32-LABEL: test_smusd 714 // AArch32: call i32 @llvm.arm.smusd 715 int32_t test_smusd(int16x2_t a, int16x2_t b) { 716 return __smusd(a, b); 717 } 718 // AArch32-LABEL: test_smusdx 719 // AArch32: call i32 @llvm.arm.smusdx 720 int32_t test_smusdx(int16x2_t a, int16x2_t b) { 721 return __smusdx(a, b); 722 } 723 #endif 724 725 /* 9.7 CRC32 intrinsics */ 726 // ARM-LABEL: test_crc32b 727 // AArch32: call i32 @llvm.arm.crc32b 728 // AArch64: call i32 @llvm.aarch64.crc32b 729 uint32_t test_crc32b(uint32_t a, uint8_t b) { 730 return __crc32b(a, b); 731 } 732 733 // ARM-LABEL: test_crc32h 734 // AArch32: call i32 @llvm.arm.crc32h 735 // AArch64: call i32 @llvm.aarch64.crc32h 736 uint32_t test_crc32h(uint32_t a, uint16_t b) { 737 return __crc32h(a, b); 738 } 739 740 // ARM-LABEL: test_crc32w 741 // AArch32: call i32 @llvm.arm.crc32w 742 // AArch64: call i32 @llvm.aarch64.crc32w 743 uint32_t test_crc32w(uint32_t a, uint32_t b) { 744 return __crc32w(a, b); 745 } 746 747 // ARM-LABEL: test_crc32d 748 // AArch32: call i32 @llvm.arm.crc32w 749 // AArch32: call i32 @llvm.arm.crc32w 750 // AArch64: call i32 @llvm.aarch64.crc32x 751 uint32_t test_crc32d(uint32_t a, uint64_t b) { 752 return __crc32d(a, b); 753 } 754 755 // ARM-LABEL: test_crc32cb 756 // AArch32: call i32 @llvm.arm.crc32cb 757 // AArch64: call i32 @llvm.aarch64.crc32cb 758 uint32_t test_crc32cb(uint32_t a, uint8_t b) { 759 return __crc32cb(a, b); 760 } 761 762 // ARM-LABEL: test_crc32ch 763 // AArch32: call i32 @llvm.arm.crc32ch 764 // AArch64: call i32 @llvm.aarch64.crc32ch 765 uint32_t test_crc32ch(uint32_t a, uint16_t b) { 766 return __crc32ch(a, b); 767 } 768 769 // ARM-LABEL: test_crc32cw 770 // AArch32: call i32 @llvm.arm.crc32cw 771 // AArch64: call i32 @llvm.aarch64.crc32cw 772 uint32_t test_crc32cw(uint32_t a, uint32_t b) { 773 return __crc32cw(a, b); 774 } 775 776 // ARM-LABEL: test_crc32cd 777 // AArch32: call i32 @llvm.arm.crc32cw 778 // AArch32: call i32 @llvm.arm.crc32cw 779 // AArch64: call i32 @llvm.aarch64.crc32cx 780 uint32_t test_crc32cd(uint32_t a, uint64_t b) { 781 return __crc32cd(a, b); 782 } 783 784 /* 10.1 Special register intrinsics */ 785 // ARM-LABEL: test_rsr 786 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) 787 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]]) 788 uint32_t test_rsr() { 789 #ifdef __ARM_32BIT_STATE 790 return __arm_rsr("cp1:2:c3:c4:5"); 791 #else 792 return __arm_rsr("1:2:3:4:5"); 793 #endif 794 } 795 796 // ARM-LABEL: test_rsr64 797 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) 798 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]]) 799 uint64_t test_rsr64() { 800 #ifdef __ARM_32BIT_STATE 801 return __arm_rsr64("cp1:2:c3"); 802 #else 803 return __arm_rsr64("1:2:3:4:5"); 804 #endif 805 } 806 807 // ARM-LABEL: test_rsrp 808 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M1:[0-9]]]) 809 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M4:[0-9]]]) 810 void *test_rsrp() { 811 return __arm_rsrp("sysreg"); 812 } 813 814 // ARM-LABEL: test_wsr 815 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) 816 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}}) 817 void test_wsr(uint32_t v) { 818 #ifdef __ARM_32BIT_STATE 819 __arm_wsr("cp1:2:c3:c4:5", v); 820 #else 821 __arm_wsr("1:2:3:4:5", v); 822 #endif 823 } 824 825 // ARM-LABEL: test_wsr64 826 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) 827 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}}) 828 void test_wsr64(uint64_t v) { 829 #ifdef __ARM_32BIT_STATE 830 __arm_wsr64("cp1:2:c3", v); 831 #else 832 __arm_wsr64("1:2:3:4:5", v); 833 #endif 834 } 835 836 // ARM-LABEL: test_wsrp 837 // AArch64: call void @llvm.write_register.i64(metadata ![[M1:[0-9]]], i64 %{{.*}}) 838 // AArch32: call void @llvm.write_register.i32(metadata ![[M4:[0-9]]], i32 %{{.*}}) 839 void test_wsrp(void *v) { 840 __arm_wsrp("sysreg", v); 841 } 842 843 // ARM-LABEL: test_rsrf 844 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) 845 // AArch32: call i32 @llvm.read_register.i32(metadata ![[M2:[0-9]]]) 846 // ARM-NOT: uitofp 847 // ARM: bitcast 848 float test_rsrf() { 849 #ifdef __ARM_32BIT_STATE 850 return __arm_rsrf("cp1:2:c3:c4:5"); 851 #else 852 return __arm_rsrf("1:2:3:4:5"); 853 #endif 854 } 855 // ARM-LABEL: test_rsrf64 856 // AArch64: call i64 @llvm.read_register.i64(metadata ![[M0:[0-9]]]) 857 // AArch32: call i64 @llvm.read_register.i64(metadata ![[M3:[0-9]]]) 858 // ARM-NOT: uitofp 859 // ARM: bitcast 860 double test_rsrf64() { 861 #ifdef __ARM_32BIT_STATE 862 return __arm_rsrf64("cp1:2:c3"); 863 #else 864 return __arm_rsrf64("1:2:3:4:5"); 865 #endif 866 } 867 // ARM-LABEL: test_wsrf 868 // ARM-NOT: fptoui 869 // ARM: bitcast 870 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) 871 // AArch32: call void @llvm.write_register.i32(metadata ![[M2:[0-9]]], i32 %{{.*}}) 872 void test_wsrf(float v) { 873 #ifdef __ARM_32BIT_STATE 874 __arm_wsrf("cp1:2:c3:c4:5", v); 875 #else 876 __arm_wsrf("1:2:3:4:5", v); 877 #endif 878 } 879 // ARM-LABEL: test_wsrf64 880 // ARM-NOT: fptoui 881 // ARM: bitcast 882 // AArch64: call void @llvm.write_register.i64(metadata ![[M0:[0-9]]], i64 %{{.*}}) 883 // AArch32: call void @llvm.write_register.i64(metadata ![[M3:[0-9]]], i64 %{{.*}}) 884 void test_wsrf64(double v) { 885 #ifdef __ARM_32BIT_STATE 886 __arm_wsrf64("cp1:2:c3", v); 887 #else 888 __arm_wsrf64("1:2:3:4:5", v); 889 #endif 890 } 891 892 // AArch32: ![[M2]] = !{!"cp1:2:c3:c4:5"} 893 // AArch32: ![[M3]] = !{!"cp1:2:c3"} 894 // AArch32: ![[M4]] = !{!"sysreg"} 895 896 // AArch64: ![[M0]] = !{!"1:2:3:4:5"} 897 // AArch64: ![[M1]] = !{!"sysreg"} 898 899 // AArch64-v8_3-LABEL: @test_jcvt( 900 // AArch64-v8_3: call i32 @llvm.aarch64.fjcvtzs 901 #ifdef __ARM_64BIT_STATE 902 int32_t test_jcvt(double v) { 903 return __jcvt(v); 904 } 905 #endif 906