1 // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 2 // RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch32 3 // RUN: %clang_cc1 -ffreestanding -triple armv8a-none-eabi -target-feature +crc -target-feature +dsp -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch32 4 // RUN: %clang_cc1 -ffreestanding -Wno-error=implicit-function-declaration -triple aarch64-none-elf -target-feature +neon -target-feature +crc -target-feature +crypto -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64 5 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v8.3a -target-feature +crc -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483 6 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v8.5a -target-feature +crc -target-feature +rand -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483,AArch6485 7 // RUN: %clang_cc1 -ffreestanding -triple aarch64-none-elf -target-feature +v9.4a -target-feature +crc -target-feature +rand -target-feature +d128 -O0 -disable-O0-optnone -emit-llvm -o - %s | opt -S -passes=mem2reg | FileCheck %s -check-prefixes=ARM,AArch64,AArch6483,AArch6485,AArch6494D128 8 9 10 #include <arm_acle.h> 11 12 // REQUIRES: arm-registered-target,aarch64-registered-target 13 14 /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ 15 /* 8.3 Memory Barriers */ 16 17 // AArch32-LABEL: @test_dmb( 18 // AArch32-NEXT: entry: 19 // AArch32-NEXT: call void @llvm.arm.dmb(i32 1) 20 // AArch32-NEXT: ret void 21 // 22 // AArch64-LABEL: @test_dmb( 23 // AArch64-NEXT: entry: 24 // AArch64-NEXT: call void @llvm.aarch64.dmb(i32 1) 25 // AArch64-NEXT: ret void 26 // 27 void test_dmb(void) { 28 __dmb(1); 29 } 30 31 // AArch32-LABEL: @test_dsb( 32 // AArch32-NEXT: entry: 33 // AArch32-NEXT: call void @llvm.arm.dsb(i32 2) 34 // AArch32-NEXT: ret void 35 // 36 // AArch64-LABEL: @test_dsb( 37 // AArch64-NEXT: entry: 38 // AArch64-NEXT: call void @llvm.aarch64.dsb(i32 2) 39 // AArch64-NEXT: ret void 40 // 41 void test_dsb(void) { 42 __dsb(2); 43 } 44 45 // AArch32-LABEL: @test_isb( 46 // AArch32-NEXT: entry: 47 // AArch32-NEXT: call void @llvm.arm.isb(i32 3) 48 // AArch32-NEXT: ret void 49 // 50 // AArch64-LABEL: @test_isb( 51 // AArch64-NEXT: entry: 52 // AArch64-NEXT: call void @llvm.aarch64.isb(i32 3) 53 // AArch64-NEXT: ret void 54 // 55 void test_isb(void) { 56 __isb(3); 57 } 58 59 /* 8.4 Hints */ 60 // AArch32-LABEL: @test_yield( 61 // AArch32-NEXT: entry: 62 // AArch32-NEXT: call void @llvm.arm.hint(i32 1) 63 // AArch32-NEXT: ret void 64 // 65 // AArch64-LABEL: @test_yield( 66 // AArch64-NEXT: entry: 67 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 1) 68 // AArch64-NEXT: ret void 69 // 70 void test_yield(void) { 71 __yield(); 72 } 73 74 // AArch32-LABEL: @test_wfe( 75 // AArch32-NEXT: entry: 76 // AArch32-NEXT: call void @llvm.arm.hint(i32 2) 77 // AArch32-NEXT: ret void 78 // 79 // AArch64-LABEL: @test_wfe( 80 // AArch64-NEXT: entry: 81 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 2) 82 // AArch64-NEXT: ret void 83 // 84 void test_wfe(void) { 85 __wfe(); 86 } 87 88 // AArch32-LABEL: @test_wfi( 89 // AArch32-NEXT: entry: 90 // AArch32-NEXT: call void @llvm.arm.hint(i32 3) 91 // AArch32-NEXT: ret void 92 // 93 // AArch64-LABEL: @test_wfi( 94 // AArch64-NEXT: entry: 95 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 3) 96 // AArch64-NEXT: ret void 97 // 98 void test_wfi(void) { 99 __wfi(); 100 } 101 102 // AArch32-LABEL: @test_sev( 103 // AArch32-NEXT: entry: 104 // AArch32-NEXT: call void @llvm.arm.hint(i32 4) 105 // AArch32-NEXT: ret void 106 // 107 // AArch64-LABEL: @test_sev( 108 // AArch64-NEXT: entry: 109 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 4) 110 // AArch64-NEXT: ret void 111 // 112 void test_sev(void) { 113 __sev(); 114 } 115 116 // AArch32-LABEL: @test_sevl( 117 // AArch32-NEXT: entry: 118 // AArch32-NEXT: call void @llvm.arm.hint(i32 5) 119 // AArch32-NEXT: ret void 120 // 121 // AArch64-LABEL: @test_sevl( 122 // AArch64-NEXT: entry: 123 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 5) 124 // AArch64-NEXT: ret void 125 // 126 void test_sevl(void) { 127 __sevl(); 128 } 129 130 #ifdef __ARM_32BIT_STATE 131 // AArch32-LABEL: @test_dbg( 132 // AArch32-NEXT: entry: 133 // AArch32-NEXT: call void @llvm.arm.dbg(i32 0) 134 // AArch32-NEXT: ret void 135 // 136 void test_dbg(void) { 137 __dbg(0); 138 } 139 #endif 140 141 /* 8.5 Swap */ 142 // AArch32-LABEL: @test_swp( 143 // AArch32-NEXT: entry: 144 // AArch32-NEXT: br label [[DO_BODY_I:%.*]] 145 // AArch32: do.body.i: 146 // AArch32-NEXT: [[LDREX_I:%.*]] = call i32 @llvm.arm.ldrex.p0(ptr elementtype(i32) [[P:%.*]]) 147 // AArch32-NEXT: [[STREX_I:%.*]] = call i32 @llvm.arm.strex.p0(i32 [[X:%.*]], ptr elementtype(i32) [[P]]) 148 // AArch32-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STREX_I]], 0 149 // AArch32-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], !llvm.loop [[LOOP3:![0-9]+]] 150 // AArch32: __swp.exit: 151 // AArch32-NEXT: ret void 152 // 153 // AArch64-LABEL: @test_swp( 154 // AArch64-NEXT: entry: 155 // AArch64-NEXT: br label [[DO_BODY_I:%.*]] 156 // AArch64: do.body.i: 157 // AArch64-NEXT: [[LDXR_I:%.*]] = call i64 @llvm.aarch64.ldxr.p0(ptr elementtype(i32) [[P:%.*]]) 158 // AArch64-NEXT: [[TMP0:%.*]] = trunc i64 [[LDXR_I]] to i32 159 // AArch64-NEXT: [[TMP1:%.*]] = zext i32 [[X:%.*]] to i64 160 // AArch64-NEXT: [[STXR_I:%.*]] = call i32 @llvm.aarch64.stxr.p0(i64 [[TMP1]], ptr elementtype(i32) [[P]]) 161 // AArch64-NEXT: [[TOBOOL_I:%.*]] = icmp ne i32 [[STXR_I]], 0 162 // AArch64-NEXT: br i1 [[TOBOOL_I]], label [[DO_BODY_I]], label [[__SWP_EXIT:%.*]], !llvm.loop [[LOOP2:![0-9]+]] 163 // AArch64: __swp.exit: 164 // AArch64-NEXT: ret void 165 // 166 void test_swp(uint32_t x, volatile void *p) { 167 __swp(x, p); 168 } 169 170 /* 8.6 Memory prefetch intrinsics */ 171 /* 8.6.1 Data prefetch */ 172 // AArch32-LABEL: @test_pld( 173 // AArch32-NEXT: entry: 174 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 1) 175 // AArch32-NEXT: ret void 176 // 177 // AArch64-LABEL: @test_pld( 178 // AArch64-NEXT: entry: 179 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 0, i32 0, i32 1) 180 // AArch64-NEXT: ret void 181 // 182 void test_pld() { 183 __pld(0); 184 } 185 186 // AArch32-LABEL: @test_pldx( 187 // AArch32-NEXT: entry: 188 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 1, i32 3, i32 1) 189 // AArch32-NEXT: ret void 190 // 191 // AArch64-LABEL: @test_pldx( 192 // AArch64-NEXT: entry: 193 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 1, i32 2, i32 0, i32 1) 194 // AArch64-NEXT: ret void 195 // 196 void test_pldx() { 197 __pldx(1, 2, 0, 0); 198 } 199 200 /* 8.6.2 Instruction prefetch */ 201 // AArch32-LABEL: @test_pli( 202 // AArch32-NEXT: entry: 203 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 0) 204 // AArch32-NEXT: ret void 205 // 206 // AArch64-LABEL: @test_pli( 207 // AArch64-NEXT: entry: 208 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 0, i32 0, i32 0) 209 // AArch64-NEXT: ret void 210 // 211 void test_pli() { 212 __pli(0); 213 } 214 215 // AArch32-LABEL: @test_plix( 216 // AArch32-NEXT: entry: 217 // AArch32-NEXT: call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 0) 218 // AArch32-NEXT: ret void 219 // 220 // AArch64-LABEL: @test_plix( 221 // AArch64-NEXT: entry: 222 // AArch64-NEXT: call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 2, i32 0, i32 0) 223 // AArch64-NEXT: ret void 224 // 225 void test_plix() { 226 __plix(2, 0, 0); 227 } 228 229 /* 8.7 NOP */ 230 // AArch32-LABEL: @test_nop( 231 // AArch32-NEXT: entry: 232 // AArch32-NEXT: call void @llvm.arm.hint(i32 0) 233 // AArch32-NEXT: ret void 234 // 235 // AArch64-LABEL: @test_nop( 236 // AArch64-NEXT: entry: 237 // AArch64-NEXT: call void @llvm.aarch64.hint(i32 0) 238 // AArch64-NEXT: ret void 239 // 240 void test_nop(void) { 241 __nop(); 242 } 243 244 /* 9 DATA-PROCESSING INTRINSICS */ 245 246 /* 9.2 Miscellaneous data-processing intrinsics */ 247 // ARM-LABEL: @test_ror( 248 // ARM-NEXT: entry: 249 // ARM-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 32 250 // ARM-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 251 // ARM-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] 252 // ARM: if.then.i: 253 // ARM-NEXT: br label [[__ROR_EXIT:%.*]] 254 // ARM: if.end.i: 255 // ARM-NEXT: [[SHR_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I]] 256 // ARM-NEXT: [[SUB_I:%.*]] = sub i32 32, [[REM_I]] 257 // ARM-NEXT: [[SHL_I:%.*]] = shl i32 [[X]], [[SUB_I]] 258 // ARM-NEXT: [[OR_I:%.*]] = or i32 [[SHR_I]], [[SHL_I]] 259 // ARM-NEXT: br label [[__ROR_EXIT]] 260 // ARM: __ror.exit: 261 // ARM-NEXT: [[RETVAL_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] 262 // ARM-NEXT: ret i32 [[RETVAL_I_0]] 263 // 264 uint32_t test_ror(uint32_t x, uint32_t y) { 265 return __ror(x, y); 266 } 267 268 // AArch32-LABEL: @test_rorl( 269 // AArch32-NEXT: entry: 270 // AArch32-NEXT: [[REM_I_I:%.*]] = urem i32 [[Y:%.*]], 32 271 // AArch32-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 272 // AArch32-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] 273 // AArch32: if.then.i.i: 274 // AArch32-NEXT: br label [[__RORL_EXIT:%.*]] 275 // AArch32: if.end.i.i: 276 // AArch32-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I_I]] 277 // AArch32-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] 278 // AArch32-NEXT: [[SHL_I_I:%.*]] = shl i32 [[X]], [[SUB_I_I]] 279 // AArch32-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] 280 // AArch32-NEXT: br label [[__RORL_EXIT]] 281 // AArch32: __rorl.exit: 282 // AArch32-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] 283 // AArch32-NEXT: ret i32 [[RETVAL_I_I_0]] 284 // 285 // AArch64-LABEL: @test_rorl( 286 // AArch64-NEXT: entry: 287 // AArch64-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64 288 // AArch64-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 289 // AArch64-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] 290 // AArch64: if.then.i: 291 // AArch64-NEXT: br label [[__RORLL_EXIT:%.*]] 292 // AArch64: if.end.i: 293 // AArch64-NEXT: [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64 294 // AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]] 295 // AArch64-NEXT: [[SUB_I:%.*]] = sub i32 64, [[REM_I]] 296 // AArch64-NEXT: [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64 297 // AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]] 298 // AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]] 299 // AArch64-NEXT: br label [[__RORLL_EXIT]] 300 // AArch64: __rorll.exit: 301 // AArch64-NEXT: [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] 302 // AArch64-NEXT: ret i64 [[RETVAL_I_0]] 303 // 304 unsigned long test_rorl(unsigned long x, uint32_t y) { 305 return __rorl(x, y); 306 } 307 308 // ARM-LABEL: @test_rorll( 309 // ARM-NEXT: entry: 310 // ARM-NEXT: [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64 311 // ARM-NEXT: [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 312 // ARM-NEXT: br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] 313 // ARM: if.then.i: 314 // ARM-NEXT: br label [[__RORLL_EXIT:%.*]] 315 // ARM: if.end.i: 316 // ARM-NEXT: [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64 317 // ARM-NEXT: [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]] 318 // ARM-NEXT: [[SUB_I:%.*]] = sub i32 64, [[REM_I]] 319 // ARM-NEXT: [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64 320 // ARM-NEXT: [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]] 321 // ARM-NEXT: [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]] 322 // ARM-NEXT: br label [[__RORLL_EXIT]] 323 // ARM: __rorll.exit: 324 // ARM-NEXT: [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] 325 // ARM-NEXT: ret i64 [[RETVAL_I_0]] 326 // 327 uint64_t test_rorll(uint64_t x, uint32_t y) { 328 return __rorll(x, y); 329 } 330 331 // ARM-LABEL: @test_clz( 332 // ARM-NEXT: entry: 333 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) 334 // ARM-NEXT: ret i32 [[TMP0]] 335 // 336 unsigned test_clz(uint32_t t) { 337 return __clz(t); 338 } 339 340 // AArch32-LABEL: @test_clzl( 341 // AArch32-NEXT: entry: 342 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) 343 // AArch32-NEXT: ret i32 [[TMP0]] 344 // 345 // AArch64-LABEL: @test_clzl( 346 // AArch64-NEXT: entry: 347 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) 348 // AArch64-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 349 // AArch64-NEXT: ret i32 [[CAST_I]] 350 // 351 unsigned test_clzl(unsigned long t) { 352 return __clzl(t); 353 } 354 355 // ARM-LABEL: @test_clzll( 356 // ARM-NEXT: entry: 357 // ARM-NEXT: [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) 358 // ARM-NEXT: [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 359 // ARM-NEXT: ret i32 [[CAST_I]] 360 // 361 unsigned test_clzll(uint64_t t) { 362 return __clzll(t); 363 } 364 365 // AArch32-LABEL: @test_cls( 366 // AArch32-NEXT: entry: 367 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) 368 // AArch32-NEXT: ret i32 [[CLS_I]] 369 // 370 // AArch64-LABEL: @test_cls( 371 // AArch64-NEXT: entry: 372 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls(i32 [[T:%.*]]) 373 // AArch64-NEXT: ret i32 [[CLS_I]] 374 // 375 unsigned test_cls(uint32_t t) { 376 return __cls(t); 377 } 378 379 // AArch32-LABEL: @test_clsl( 380 // AArch32-NEXT: entry: 381 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) 382 // AArch32-NEXT: ret i32 [[CLS_I]] 383 // 384 // AArch64-LABEL: @test_clsl( 385 // AArch64-NEXT: entry: 386 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) 387 // AArch64-NEXT: ret i32 [[CLS_I]] 388 // 389 unsigned test_clsl(unsigned long t) { 390 return __clsl(t); 391 } 392 393 // AArch32-LABEL: @test_clsll( 394 // AArch32-NEXT: entry: 395 // AArch32-NEXT: [[CLS_I:%.*]] = call i32 @llvm.arm.cls64(i64 [[T:%.*]]) 396 // AArch32-NEXT: ret i32 [[CLS_I]] 397 // 398 // AArch64-LABEL: @test_clsll( 399 // AArch64-NEXT: entry: 400 // AArch64-NEXT: [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) 401 // AArch64-NEXT: ret i32 [[CLS_I]] 402 // 403 unsigned test_clsll(uint64_t t) { 404 return __clsll(t); 405 } 406 407 // ARM-LABEL: @test_rev( 408 // ARM-NEXT: entry: 409 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) 410 // ARM-NEXT: ret i32 [[TMP0]] 411 // 412 uint32_t test_rev(uint32_t t) { 413 return __rev(t); 414 } 415 416 // AArch32-LABEL: @test_revl( 417 // AArch32-NEXT: entry: 418 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) 419 // AArch32-NEXT: ret i32 [[TMP0]] 420 // 421 // AArch64-LABEL: @test_revl( 422 // AArch64-NEXT: entry: 423 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) 424 // AArch64-NEXT: ret i64 [[TMP0]] 425 // 426 long test_revl(long t) { 427 return __revl(t); 428 } 429 430 // ARM-LABEL: @test_revll( 431 // ARM-NEXT: entry: 432 // ARM-NEXT: [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) 433 // ARM-NEXT: ret i64 [[TMP0]] 434 // 435 uint64_t test_revll(uint64_t t) { 436 return __revll(t); 437 } 438 439 // ARM-LABEL: @test_rev16( 440 // ARM-NEXT: entry: 441 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) 442 // ARM-NEXT: [[REM_I_I:%.*]] = urem i32 16, 32 443 // ARM-NEXT: [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 444 // ARM-NEXT: br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] 445 // ARM: if.then.i.i: 446 // ARM-NEXT: br label [[__REV16_EXIT:%.*]] 447 // ARM: if.end.i.i: 448 // ARM-NEXT: [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]] 449 // ARM-NEXT: [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] 450 // ARM-NEXT: [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]] 451 // ARM-NEXT: [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] 452 // ARM-NEXT: br label [[__REV16_EXIT]] 453 // ARM: __rev16.exit: 454 // ARM-NEXT: [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] 455 // ARM-NEXT: ret i32 [[RETVAL_I_I_0]] 456 // 457 uint32_t test_rev16(uint32_t t) { 458 return __rev16(t); 459 } 460 461 // AArch32-LABEL: @test_rev16l( 462 // AArch32-NEXT: entry: 463 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) 464 // AArch32-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 465 // AArch32-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 466 // AArch32-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] 467 // AArch32: if.then.i.i.i: 468 // AArch32-NEXT: br label [[__REV16L_EXIT:%.*]] 469 // AArch32: if.end.i.i.i: 470 // AArch32-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I_I]] 471 // AArch32-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] 472 // AArch32-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I_I]] 473 // AArch32-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] 474 // AArch32-NEXT: br label [[__REV16L_EXIT]] 475 // AArch32: __rev16l.exit: 476 // AArch32-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] 477 // AArch32-NEXT: ret i32 [[RETVAL_I_I_I_0]] 478 // 479 // AArch64-LABEL: @test_rev16l( 480 // AArch64-NEXT: entry: 481 // AArch64-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 482 // AArch64-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 483 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) 484 // AArch64-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32 485 // AArch64-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 486 // AArch64-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I17_I:%.*]], label [[IF_END_I_I12_I:%.*]] 487 // AArch64: if.then.i.i17.i: 488 // AArch64-NEXT: br label [[__REV16_EXIT18_I:%.*]] 489 // AArch64: if.end.i.i12.i: 490 // AArch64-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] 491 // AArch64-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] 492 // AArch64-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] 493 // AArch64-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] 494 // AArch64-NEXT: br label [[__REV16_EXIT18_I]] 495 // AArch64: __rev16.exit18.i: 496 // AArch64-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I17_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I12_I]] ] 497 // AArch64-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 498 // AArch64-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 499 // AArch64-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 500 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) 501 // AArch64-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 502 // AArch64-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 503 // AArch64-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] 504 // AArch64: if.then.i.i.i: 505 // AArch64-NEXT: br label [[__REV16LL_EXIT:%.*]] 506 // AArch64: if.end.i.i.i: 507 // AArch64-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] 508 // AArch64-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] 509 // AArch64-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] 510 // AArch64-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] 511 // AArch64-NEXT: br label [[__REV16LL_EXIT]] 512 // AArch64: __rev16ll.exit: 513 // AArch64-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] 514 // AArch64-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 515 // AArch64-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] 516 // AArch64-NEXT: ret i64 [[OR_I]] 517 // 518 long test_rev16l(long t) { 519 return __rev16l(t); 520 } 521 522 // ARM-LABEL: @test_rev16ll( 523 // ARM-NEXT: entry: 524 // ARM-NEXT: [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 525 // ARM-NEXT: [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 526 // ARM-NEXT: [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) 527 // ARM-NEXT: [[REM_I_I10_I:%.*]] = urem i32 16, 32 528 // ARM-NEXT: [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 529 // ARM-NEXT: br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I17_I:%.*]], label [[IF_END_I_I12_I:%.*]] 530 // ARM: if.then.i.i17.i: 531 // ARM-NEXT: br label [[__REV16_EXIT18_I:%.*]] 532 // ARM: if.end.i.i12.i: 533 // ARM-NEXT: [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] 534 // ARM-NEXT: [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] 535 // ARM-NEXT: [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] 536 // ARM-NEXT: [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] 537 // ARM-NEXT: br label [[__REV16_EXIT18_I]] 538 // ARM: __rev16.exit18.i: 539 // ARM-NEXT: [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I17_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I12_I]] ] 540 // ARM-NEXT: [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 541 // ARM-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 542 // ARM-NEXT: [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 543 // ARM-NEXT: [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) 544 // ARM-NEXT: [[REM_I_I_I:%.*]] = urem i32 16, 32 545 // ARM-NEXT: [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 546 // ARM-NEXT: br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] 547 // ARM: if.then.i.i.i: 548 // ARM-NEXT: br label [[__REV16LL_EXIT:%.*]] 549 // ARM: if.end.i.i.i: 550 // ARM-NEXT: [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] 551 // ARM-NEXT: [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] 552 // ARM-NEXT: [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] 553 // ARM-NEXT: [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] 554 // ARM-NEXT: br label [[__REV16LL_EXIT]] 555 // ARM: __rev16ll.exit: 556 // ARM-NEXT: [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] 557 // ARM-NEXT: [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 558 // ARM-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] 559 // ARM-NEXT: ret i64 [[OR_I]] 560 // 561 uint64_t test_rev16ll(uint64_t t) { 562 return __rev16ll(t); 563 } 564 565 // ARM-LABEL: @test_revsh( 566 // ARM-NEXT: entry: 567 // ARM-NEXT: [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]]) 568 // ARM-NEXT: ret i16 [[TMP0]] 569 // 570 int16_t test_revsh(int16_t t) { 571 return __revsh(t); 572 } 573 574 // ARM-LABEL: @test_rbit( 575 // ARM-NEXT: entry: 576 // ARM-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) 577 // ARM-NEXT: ret i32 [[RBIT_I]] 578 // 579 uint32_t test_rbit(uint32_t t) { 580 return __rbit(t); 581 } 582 583 // AArch32-LABEL: @test_rbitl( 584 // AArch32-NEXT: entry: 585 // AArch32-NEXT: [[RBIT_I_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) 586 // AArch32-NEXT: ret i32 [[RBIT_I_I]] 587 // 588 // AArch64-LABEL: @test_rbitl( 589 // AArch64-NEXT: entry: 590 // AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) 591 // AArch64-NEXT: ret i64 [[RBIT_I]] 592 // 593 long test_rbitl(long t) { 594 return __rbitl(t); 595 } 596 597 // AArch32-LABEL: @test_rbitll( 598 // AArch32-NEXT: entry: 599 // AArch32-NEXT: [[CONV_I:%.*]] = trunc i64 [[T:%.*]] to i32 600 // AArch32-NEXT: [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV_I]]) 601 // AArch32-NEXT: [[CONV1_I:%.*]] = zext i32 [[RBIT_I]] to i64 602 // AArch32-NEXT: [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 603 // AArch32-NEXT: [[SHR_I:%.*]] = lshr i64 [[T]], 32 604 // AArch32-NEXT: [[CONV2_I:%.*]] = trunc i64 [[SHR_I]] to i32 605 // AArch32-NEXT: [[RBIT3_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV2_I]]) 606 // AArch32-NEXT: [[CONV4_I:%.*]] = zext i32 [[RBIT3_I]] to i64 607 // AArch32-NEXT: [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] 608 // AArch32-NEXT: ret i64 [[OR_I]] 609 // 610 // AArch64-LABEL: @test_rbitll( 611 // AArch64-NEXT: entry: 612 // AArch64-NEXT: [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) 613 // AArch64-NEXT: ret i64 [[RBIT_I]] 614 // 615 uint64_t test_rbitll(uint64_t t) { 616 return __rbitll(t); 617 } 618 619 /* 9.4 Saturating intrinsics */ 620 #ifdef __ARM_FEATURE_SAT 621 /* 9.4.1 Width-specified saturation intrinsics */ 622 // AArch32-LABEL: @test_ssat( 623 // AArch32-NEXT: entry: 624 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat(i32 [[T:%.*]], i32 1) 625 // AArch32-NEXT: ret i32 [[TMP0]] 626 // 627 int32_t test_ssat(int32_t t) { 628 return __ssat(t, 1); 629 } 630 631 // AArch32-LABEL: @test_usat( 632 // AArch32-NEXT: entry: 633 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat(i32 [[T:%.*]], i32 2) 634 // AArch32-NEXT: ret i32 [[TMP0]] 635 // 636 uint32_t test_usat(int32_t t) { 637 return __usat(t, 2); 638 } 639 #endif 640 641 /* 9.4.2 Saturating addition and subtraction intrinsics */ 642 #ifdef __ARM_32BIT_STATE 643 // AArch32-LABEL: @test_qadd( 644 // AArch32-NEXT: entry: 645 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]]) 646 // AArch32-NEXT: ret i32 [[TMP0]] 647 // 648 #ifndef __ARM_FEATURE_DSP 649 __attribute__((target("dsp"))) 650 #endif 651 int32_t test_qadd(int32_t a, int32_t b) { 652 return __qadd(a, b); 653 } 654 655 // AArch32-LABEL: @test_qsub( 656 // AArch32-NEXT: entry: 657 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]]) 658 // AArch32-NEXT: ret i32 [[TMP0]] 659 // 660 #ifndef __ARM_FEATURE_DSP 661 __attribute__((target("dsp"))) 662 #endif 663 int32_t test_qsub(int32_t a, int32_t b) { 664 return __qsub(a, b); 665 } 666 667 extern int32_t f(); 668 // AArch32-LABEL: @test_qdbl( 669 // AArch32-NEXT: entry: 670 // AArch32-NEXT: [[CALL:%.*]] = call i32 @f() #[[ATTR9:[0-9]+]] 671 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]]) 672 // AArch32-NEXT: ret i32 [[TMP0]] 673 // 674 #ifndef __ARM_FEATURE_DSP 675 __attribute__((target("dsp"))) 676 #endif 677 int32_t test_qdbl() { 678 return __qdbl(f()); 679 } 680 #endif 681 682 /* 683 * 9.3 16-bit multiplications 684 */ 685 #ifdef __ARM_32BIT_STATE 686 // AArch32-LABEL: @test_smulbb( 687 // AArch32-NEXT: entry: 688 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]]) 689 // AArch32-NEXT: ret i32 [[TMP0]] 690 // 691 #ifndef __ARM_FEATURE_DSP 692 __attribute__((target("dsp"))) 693 #endif 694 int32_t test_smulbb(int32_t a, int32_t b) { 695 return __smulbb(a, b); 696 } 697 698 // AArch32-LABEL: @test_smulbt( 699 // AArch32-NEXT: entry: 700 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]]) 701 // AArch32-NEXT: ret i32 [[TMP0]] 702 // 703 #ifndef __ARM_FEATURE_DSP 704 __attribute__((target("dsp"))) 705 #endif 706 int32_t test_smulbt(int32_t a, int32_t b) { 707 return __smulbt(a, b); 708 } 709 710 // AArch32-LABEL: @test_smultb( 711 // AArch32-NEXT: entry: 712 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]]) 713 // AArch32-NEXT: ret i32 [[TMP0]] 714 // 715 #ifndef __ARM_FEATURE_DSP 716 __attribute__((target("dsp"))) 717 #endif 718 int32_t test_smultb(int32_t a, int32_t b) { 719 return __smultb(a, b); 720 } 721 722 // AArch32-LABEL: @test_smultt( 723 // AArch32-NEXT: entry: 724 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]]) 725 // AArch32-NEXT: ret i32 [[TMP0]] 726 // 727 #ifndef __ARM_FEATURE_DSP 728 __attribute__((target("dsp"))) 729 #endif 730 int32_t test_smultt(int32_t a, int32_t b) { 731 return __smultt(a, b); 732 } 733 734 // AArch32-LABEL: @test_smulwb( 735 // AArch32-NEXT: entry: 736 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]]) 737 // AArch32-NEXT: ret i32 [[TMP0]] 738 // 739 #ifndef __ARM_FEATURE_DSP 740 __attribute__((target("dsp"))) 741 #endif 742 int32_t test_smulwb(int32_t a, int32_t b) { 743 return __smulwb(a, b); 744 } 745 746 // AArch32-LABEL: @test_smulwt( 747 // AArch32-NEXT: entry: 748 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]]) 749 // AArch32-NEXT: ret i32 [[TMP0]] 750 // 751 #ifndef __ARM_FEATURE_DSP 752 __attribute__((target("dsp"))) 753 #endif 754 int32_t test_smulwt(int32_t a, int32_t b) { 755 return __smulwt(a, b); 756 } 757 #endif 758 759 /* 9.4.3 Accumultating multiplications */ 760 #ifdef __ARM_32BIT_STATE 761 // AArch32-LABEL: @test_smlabb( 762 // AArch32-NEXT: entry: 763 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 764 // AArch32-NEXT: ret i32 [[TMP0]] 765 // 766 #ifndef __ARM_FEATURE_DSP 767 __attribute__((target("dsp"))) 768 #endif 769 int32_t test_smlabb(int32_t a, int32_t b, int32_t c) { 770 return __smlabb(a, b, c); 771 } 772 773 // AArch32-LABEL: @test_smlabt( 774 // AArch32-NEXT: entry: 775 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 776 // AArch32-NEXT: ret i32 [[TMP0]] 777 // 778 #ifndef __ARM_FEATURE_DSP 779 __attribute__((target("dsp"))) 780 #endif 781 int32_t test_smlabt(int32_t a, int32_t b, int32_t c) { 782 return __smlabt(a, b, c); 783 } 784 785 // AArch32-LABEL: @test_smlatb( 786 // AArch32-NEXT: entry: 787 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 788 // AArch32-NEXT: ret i32 [[TMP0]] 789 // 790 #ifndef __ARM_FEATURE_DSP 791 __attribute__((target("dsp"))) 792 #endif 793 int32_t test_smlatb(int32_t a, int32_t b, int32_t c) { 794 return __smlatb(a, b, c); 795 } 796 797 // AArch32-LABEL: @test_smlatt( 798 // AArch32-NEXT: entry: 799 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 800 // AArch32-NEXT: ret i32 [[TMP0]] 801 // 802 #ifndef __ARM_FEATURE_DSP 803 __attribute__((target("dsp"))) 804 #endif 805 int32_t test_smlatt(int32_t a, int32_t b, int32_t c) { 806 return __smlatt(a, b, c); 807 } 808 809 // AArch32-LABEL: @test_smlawb( 810 // AArch32-NEXT: entry: 811 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 812 // AArch32-NEXT: ret i32 [[TMP0]] 813 // 814 #ifndef __ARM_FEATURE_DSP 815 __attribute__((target("dsp"))) 816 #endif 817 int32_t test_smlawb(int32_t a, int32_t b, int32_t c) { 818 return __smlawb(a, b, c); 819 } 820 821 // AArch32-LABEL: @test_smlawt( 822 // AArch32-NEXT: entry: 823 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 824 // AArch32-NEXT: ret i32 [[TMP0]] 825 // 826 #ifndef __ARM_FEATURE_DSP 827 __attribute__((target("dsp"))) 828 #endif 829 int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { 830 return __smlawt(a, b, c); 831 } 832 #endif 833 834 /* 9.5.4 Parallel 16-bit saturation */ 835 #if __ARM_FEATURE_SIMD32 836 // AArch32-LABEL: @test_ssat16( 837 // AArch32-NEXT: entry: 838 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssat16(i32 [[A:%.*]], i32 15) 839 // AArch32-NEXT: ret i32 [[TMP0]] 840 // 841 int16x2_t test_ssat16(int16x2_t a) { 842 return __ssat16(a, 15); 843 } 844 845 // AArch32-LABEL: @test_usat16( 846 // AArch32-NEXT: entry: 847 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usat16(i32 [[A:%.*]], i32 15) 848 // AArch32-NEXT: ret i32 [[TMP0]] 849 // 850 uint16x2_t test_usat16(int16x2_t a) { 851 return __usat16(a, 15); 852 } 853 #endif 854 855 /* 9.5.5 Packing and unpacking */ 856 #if __ARM_FEATURE_SIMD32 857 // AArch32-LABEL: @test_sxtab16( 858 // AArch32-NEXT: entry: 859 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) 860 // AArch32-NEXT: ret i32 [[TMP0]] 861 // 862 int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) { 863 return __sxtab16(a, b); 864 } 865 866 // AArch32-LABEL: @test_sxtb16( 867 // AArch32-NEXT: entry: 868 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sxtb16(i32 [[A:%.*]]) 869 // AArch32-NEXT: ret i32 [[TMP0]] 870 // 871 int16x2_t test_sxtb16(int8x4_t a) { 872 return __sxtb16(a); 873 } 874 875 // AArch32-LABEL: @test_uxtab16( 876 // AArch32-NEXT: entry: 877 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) 878 // AArch32-NEXT: ret i32 [[TMP0]] 879 // 880 int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) { 881 return __uxtab16(a, b); 882 } 883 884 // AArch32-LABEL: @test_uxtb16( 885 // AArch32-NEXT: entry: 886 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uxtb16(i32 [[A:%.*]]) 887 // AArch32-NEXT: ret i32 [[TMP0]] 888 // 889 int16x2_t test_uxtb16(int8x4_t a) { 890 return __uxtb16(a); 891 } 892 #endif 893 894 /* 9.5.6 Parallel selection */ 895 #if __ARM_FEATURE_SIMD32 896 // AArch32-LABEL: @test_sel( 897 // AArch32-NEXT: entry: 898 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sel(i32 [[A:%.*]], i32 [[B:%.*]]) 899 // AArch32-NEXT: ret i32 [[TMP0]] 900 // 901 uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { 902 return __sel(a, b); 903 } 904 #endif 905 906 /* 9.5.7 Parallel 8-bit addition and subtraction */ 907 #if __ARM_FEATURE_SIMD32 908 // AArch32-LABEL: @test_qadd8( 909 // AArch32-NEXT: entry: 910 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd8(i32 [[A:%.*]], i32 [[B:%.*]]) 911 // AArch32-NEXT: ret i32 [[TMP0]] 912 // 913 int16x2_t test_qadd8(int8x4_t a, int8x4_t b) { 914 return __qadd8(a, b); 915 } 916 917 // AArch32-LABEL: @test_qsub8( 918 // AArch32-NEXT: entry: 919 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub8(i32 [[A:%.*]], i32 [[B:%.*]]) 920 // AArch32-NEXT: ret i32 [[TMP0]] 921 // 922 int8x4_t test_qsub8(int8x4_t a, int8x4_t b) { 923 return __qsub8(a, b); 924 } 925 926 // AArch32-LABEL: @test_sadd8( 927 // AArch32-NEXT: entry: 928 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd8(i32 [[A:%.*]], i32 [[B:%.*]]) 929 // AArch32-NEXT: ret i32 [[TMP0]] 930 // 931 int8x4_t test_sadd8(int8x4_t a, int8x4_t b) { 932 return __sadd8(a, b); 933 } 934 935 // AArch32-LABEL: @test_shadd8( 936 // AArch32-NEXT: entry: 937 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd8(i32 [[A:%.*]], i32 [[B:%.*]]) 938 // AArch32-NEXT: ret i32 [[TMP0]] 939 // 940 int8x4_t test_shadd8(int8x4_t a, int8x4_t b) { 941 return __shadd8(a, b); 942 } 943 944 // AArch32-LABEL: @test_shsub8( 945 // AArch32-NEXT: entry: 946 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub8(i32 [[A:%.*]], i32 [[B:%.*]]) 947 // AArch32-NEXT: ret i32 [[TMP0]] 948 // 949 int8x4_t test_shsub8(int8x4_t a, int8x4_t b) { 950 return __shsub8(a, b); 951 } 952 953 // AArch32-LABEL: @test_ssub8( 954 // AArch32-NEXT: entry: 955 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub8(i32 [[A:%.*]], i32 [[B:%.*]]) 956 // AArch32-NEXT: ret i32 [[TMP0]] 957 // 958 int8x4_t test_ssub8(int8x4_t a, int8x4_t b) { 959 return __ssub8(a, b); 960 } 961 962 // AArch32-LABEL: @test_uadd8( 963 // AArch32-NEXT: entry: 964 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd8(i32 [[A:%.*]], i32 [[B:%.*]]) 965 // AArch32-NEXT: ret i32 [[TMP0]] 966 // 967 uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) { 968 return __uadd8(a, b); 969 } 970 971 // AArch32-LABEL: @test_uhadd8( 972 // AArch32-NEXT: entry: 973 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd8(i32 [[A:%.*]], i32 [[B:%.*]]) 974 // AArch32-NEXT: ret i32 [[TMP0]] 975 // 976 uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) { 977 return __uhadd8(a, b); 978 } 979 980 // AArch32-LABEL: @test_uhsub8( 981 // AArch32-NEXT: entry: 982 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub8(i32 [[A:%.*]], i32 [[B:%.*]]) 983 // AArch32-NEXT: ret i32 [[TMP0]] 984 // 985 uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) { 986 return __uhsub8(a, b); 987 } 988 989 // AArch32-LABEL: @test_uqadd8( 990 // AArch32-NEXT: entry: 991 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd8(i32 [[A:%.*]], i32 [[B:%.*]]) 992 // AArch32-NEXT: ret i32 [[TMP0]] 993 // 994 uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) { 995 return __uqadd8(a, b); 996 } 997 998 // AArch32-LABEL: @test_uqsub8( 999 // AArch32-NEXT: entry: 1000 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub8(i32 [[A:%.*]], i32 [[B:%.*]]) 1001 // AArch32-NEXT: ret i32 [[TMP0]] 1002 // 1003 uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) { 1004 return __uqsub8(a, b); 1005 } 1006 1007 // AArch32-LABEL: @test_usub8( 1008 // AArch32-NEXT: entry: 1009 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub8(i32 [[A:%.*]], i32 [[B:%.*]]) 1010 // AArch32-NEXT: ret i32 [[TMP0]] 1011 // 1012 uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { 1013 return __usub8(a, b); 1014 } 1015 #endif 1016 1017 /* 9.5.8 Sum of 8-bit absolute differences */ 1018 #if __ARM_FEATURE_SIMD32 1019 // AArch32-LABEL: @test_usad8( 1020 // AArch32-NEXT: entry: 1021 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usad8(i32 [[A:%.*]], i32 [[B:%.*]]) 1022 // AArch32-NEXT: ret i32 [[TMP0]] 1023 // 1024 uint32_t test_usad8(uint8x4_t a, uint8x4_t b) { 1025 return __usad8(a, b); 1026 } 1027 1028 // AArch32-LABEL: @test_usada8( 1029 // AArch32-NEXT: entry: 1030 // AArch32-NEXT: [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 1031 // AArch32-NEXT: [[CONV1:%.*]] = zext i8 [[B:%.*]] to i32 1032 // AArch32-NEXT: [[CONV2:%.*]] = zext i8 [[C:%.*]] to i32 1033 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usada8(i32 [[CONV]], i32 [[CONV1]], i32 [[CONV2]]) 1034 // AArch32-NEXT: ret i32 [[TMP0]] 1035 // 1036 uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { 1037 return __usada8(a, b, c); 1038 } 1039 #endif 1040 1041 /* 9.5.9 Parallel 16-bit addition and subtraction */ 1042 #if __ARM_FEATURE_SIMD32 1043 // AArch32-LABEL: @test_qadd16( 1044 // AArch32-NEXT: entry: 1045 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qadd16(i32 [[A:%.*]], i32 [[B:%.*]]) 1046 // AArch32-NEXT: ret i32 [[TMP0]] 1047 // 1048 int16x2_t test_qadd16(int16x2_t a, int16x2_t b) { 1049 return __qadd16(a, b); 1050 } 1051 1052 // AArch32-LABEL: @test_qasx( 1053 // AArch32-NEXT: entry: 1054 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qasx(i32 [[A:%.*]], i32 [[B:%.*]]) 1055 // AArch32-NEXT: ret i32 [[TMP0]] 1056 // 1057 int16x2_t test_qasx(int16x2_t a, int16x2_t b) { 1058 return __qasx(a, b); 1059 } 1060 1061 // AArch32-LABEL: @test_qsax( 1062 // AArch32-NEXT: entry: 1063 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsax(i32 [[A:%.*]], i32 [[B:%.*]]) 1064 // AArch32-NEXT: ret i32 [[TMP0]] 1065 // 1066 int16x2_t test_qsax(int16x2_t a, int16x2_t b) { 1067 return __qsax(a, b); 1068 } 1069 1070 // AArch32-LABEL: @test_qsub16( 1071 // AArch32-NEXT: entry: 1072 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.qsub16(i32 [[A:%.*]], i32 [[B:%.*]]) 1073 // AArch32-NEXT: ret i32 [[TMP0]] 1074 // 1075 int16x2_t test_qsub16(int16x2_t a, int16x2_t b) { 1076 return __qsub16(a, b); 1077 } 1078 1079 // AArch32-LABEL: @test_sadd16( 1080 // AArch32-NEXT: entry: 1081 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sadd16(i32 [[A:%.*]], i32 [[B:%.*]]) 1082 // AArch32-NEXT: ret i32 [[TMP0]] 1083 // 1084 int16x2_t test_sadd16(int16x2_t a, int16x2_t b) { 1085 return __sadd16(a, b); 1086 } 1087 1088 // AArch32-LABEL: @test_sasx( 1089 // AArch32-NEXT: entry: 1090 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.sasx(i32 [[A:%.*]], i32 [[B:%.*]]) 1091 // AArch32-NEXT: ret i32 [[TMP0]] 1092 // 1093 int16x2_t test_sasx(int16x2_t a, int16x2_t b) { 1094 return __sasx(a, b); 1095 } 1096 1097 // AArch32-LABEL: @test_shadd16( 1098 // AArch32-NEXT: entry: 1099 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shadd16(i32 [[A:%.*]], i32 [[B:%.*]]) 1100 // AArch32-NEXT: ret i32 [[TMP0]] 1101 // 1102 int16x2_t test_shadd16(int16x2_t a, int16x2_t b) { 1103 return __shadd16(a, b); 1104 } 1105 1106 // AArch32-LABEL: @test_shasx( 1107 // AArch32-NEXT: entry: 1108 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shasx(i32 [[A:%.*]], i32 [[B:%.*]]) 1109 // AArch32-NEXT: ret i32 [[TMP0]] 1110 // 1111 int16x2_t test_shasx(int16x2_t a, int16x2_t b) { 1112 return __shasx(a, b); 1113 } 1114 1115 // AArch32-LABEL: @test_shsax( 1116 // AArch32-NEXT: entry: 1117 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsax(i32 [[A:%.*]], i32 [[B:%.*]]) 1118 // AArch32-NEXT: ret i32 [[TMP0]] 1119 // 1120 int16x2_t test_shsax(int16x2_t a, int16x2_t b) { 1121 return __shsax(a, b); 1122 } 1123 1124 // AArch32-LABEL: @test_shsub16( 1125 // AArch32-NEXT: entry: 1126 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.shsub16(i32 [[A:%.*]], i32 [[B:%.*]]) 1127 // AArch32-NEXT: ret i32 [[TMP0]] 1128 // 1129 int16x2_t test_shsub16(int16x2_t a, int16x2_t b) { 1130 return __shsub16(a, b); 1131 } 1132 1133 // AArch32-LABEL: @test_ssax( 1134 // AArch32-NEXT: entry: 1135 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssax(i32 [[A:%.*]], i32 [[B:%.*]]) 1136 // AArch32-NEXT: ret i32 [[TMP0]] 1137 // 1138 int16x2_t test_ssax(int16x2_t a, int16x2_t b) { 1139 return __ssax(a, b); 1140 } 1141 1142 // AArch32-LABEL: @test_ssub16( 1143 // AArch32-NEXT: entry: 1144 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.ssub16(i32 [[A:%.*]], i32 [[B:%.*]]) 1145 // AArch32-NEXT: ret i32 [[TMP0]] 1146 // 1147 int16x2_t test_ssub16(int16x2_t a, int16x2_t b) { 1148 return __ssub16(a, b); 1149 } 1150 1151 // AArch32-LABEL: @test_uadd16( 1152 // AArch32-NEXT: entry: 1153 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uadd16(i32 [[A:%.*]], i32 [[B:%.*]]) 1154 // AArch32-NEXT: ret i32 [[TMP0]] 1155 // 1156 uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) { 1157 return __uadd16(a, b); 1158 } 1159 1160 // AArch32-LABEL: @test_uasx( 1161 // AArch32-NEXT: entry: 1162 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uasx(i32 [[A:%.*]], i32 [[B:%.*]]) 1163 // AArch32-NEXT: ret i32 [[TMP0]] 1164 // 1165 uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) { 1166 return __uasx(a, b); 1167 } 1168 1169 // AArch32-LABEL: @test_uhadd16( 1170 // AArch32-NEXT: entry: 1171 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhadd16(i32 [[A:%.*]], i32 [[B:%.*]]) 1172 // AArch32-NEXT: ret i32 [[TMP0]] 1173 // 1174 uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) { 1175 return __uhadd16(a, b); 1176 } 1177 1178 // AArch32-LABEL: @test_uhasx( 1179 // AArch32-NEXT: entry: 1180 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhasx(i32 [[A:%.*]], i32 [[B:%.*]]) 1181 // AArch32-NEXT: ret i32 [[TMP0]] 1182 // 1183 uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) { 1184 return __uhasx(a, b); 1185 } 1186 1187 // AArch32-LABEL: @test_uhsax( 1188 // AArch32-NEXT: entry: 1189 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsax(i32 [[A:%.*]], i32 [[B:%.*]]) 1190 // AArch32-NEXT: ret i32 [[TMP0]] 1191 // 1192 uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) { 1193 return __uhsax(a, b); 1194 } 1195 1196 // AArch32-LABEL: @test_uhsub16( 1197 // AArch32-NEXT: entry: 1198 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uhsub16(i32 [[A:%.*]], i32 [[B:%.*]]) 1199 // AArch32-NEXT: ret i32 [[TMP0]] 1200 // 1201 uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) { 1202 return __uhsub16(a, b); 1203 } 1204 1205 // AArch32-LABEL: @test_uqadd16( 1206 // AArch32-NEXT: entry: 1207 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqadd16(i32 [[A:%.*]], i32 [[B:%.*]]) 1208 // AArch32-NEXT: ret i32 [[TMP0]] 1209 // 1210 uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) { 1211 return __uqadd16(a, b); 1212 } 1213 1214 // AArch32-LABEL: @test_uqasx( 1215 // AArch32-NEXT: entry: 1216 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqasx(i32 [[A:%.*]], i32 [[B:%.*]]) 1217 // AArch32-NEXT: ret i32 [[TMP0]] 1218 // 1219 uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) { 1220 return __uqasx(a, b); 1221 } 1222 1223 // AArch32-LABEL: @test_uqsax( 1224 // AArch32-NEXT: entry: 1225 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsax(i32 [[A:%.*]], i32 [[B:%.*]]) 1226 // AArch32-NEXT: ret i32 [[TMP0]] 1227 // 1228 uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) { 1229 return __uqsax(a, b); 1230 } 1231 1232 // AArch32-LABEL: @test_uqsub16( 1233 // AArch32-NEXT: entry: 1234 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.uqsub16(i32 [[A:%.*]], i32 [[B:%.*]]) 1235 // AArch32-NEXT: ret i32 [[TMP0]] 1236 // 1237 uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) { 1238 return __uqsub16(a, b); 1239 } 1240 1241 // AArch32-LABEL: @test_usax( 1242 // AArch32-NEXT: entry: 1243 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usax(i32 [[A:%.*]], i32 [[B:%.*]]) 1244 // AArch32-NEXT: ret i32 [[TMP0]] 1245 // 1246 uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) { 1247 return __usax(a, b); 1248 } 1249 1250 // AArch32-LABEL: @test_usub16( 1251 // AArch32-NEXT: entry: 1252 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.usub16(i32 [[A:%.*]], i32 [[B:%.*]]) 1253 // AArch32-NEXT: ret i32 [[TMP0]] 1254 // 1255 uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { 1256 return __usub16(a, b); 1257 } 1258 #endif 1259 1260 /* 9.5.10 Parallel 16-bit multiplications */ 1261 #if __ARM_FEATURE_SIMD32 1262 // AArch32-LABEL: @test_smlad( 1263 // AArch32-NEXT: entry: 1264 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlad(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 1265 // AArch32-NEXT: ret i32 [[TMP0]] 1266 // 1267 int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) { 1268 return __smlad(a, b, c); 1269 } 1270 1271 // AArch32-LABEL: @test_smladx( 1272 // AArch32-NEXT: entry: 1273 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smladx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 1274 // AArch32-NEXT: ret i32 [[TMP0]] 1275 // 1276 int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) { 1277 return __smladx(a, b, c); 1278 } 1279 1280 // AArch32-LABEL: @test_smlald( 1281 // AArch32-NEXT: entry: 1282 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlald(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) 1283 // AArch32-NEXT: ret i64 [[TMP0]] 1284 // 1285 int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) { 1286 return __smlald(a, b, c); 1287 } 1288 1289 // AArch32-LABEL: @test_smlaldx( 1290 // AArch32-NEXT: entry: 1291 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) 1292 // AArch32-NEXT: ret i64 [[TMP0]] 1293 // 1294 int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) { 1295 return __smlaldx(a, b, c); 1296 } 1297 1298 // AArch32-LABEL: @test_smlsd( 1299 // AArch32-NEXT: entry: 1300 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsd(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 1301 // AArch32-NEXT: ret i32 [[TMP0]] 1302 // 1303 int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) { 1304 return __smlsd(a, b, c); 1305 } 1306 1307 // AArch32-LABEL: @test_smlsdx( 1308 // AArch32-NEXT: entry: 1309 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smlsdx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) 1310 // AArch32-NEXT: ret i32 [[TMP0]] 1311 // 1312 int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) { 1313 return __smlsdx(a, b, c); 1314 } 1315 1316 // AArch32-LABEL: @test_smlsld( 1317 // AArch32-NEXT: entry: 1318 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsld(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) 1319 // AArch32-NEXT: ret i64 [[TMP0]] 1320 // 1321 int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) { 1322 return __smlsld(a, b, c); 1323 } 1324 1325 // AArch32-LABEL: @test_smlsldx( 1326 // AArch32-NEXT: entry: 1327 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.arm.smlsldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) 1328 // AArch32-NEXT: ret i64 [[TMP0]] 1329 // 1330 int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) { 1331 return __smlsldx(a, b, c); 1332 } 1333 1334 // AArch32-LABEL: @test_smuad( 1335 // AArch32-NEXT: entry: 1336 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuad(i32 [[A:%.*]], i32 [[B:%.*]]) 1337 // AArch32-NEXT: ret i32 [[TMP0]] 1338 // 1339 int32_t test_smuad(int16x2_t a, int16x2_t b) { 1340 return __smuad(a, b); 1341 } 1342 1343 // AArch32-LABEL: @test_smuadx( 1344 // AArch32-NEXT: entry: 1345 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smuadx(i32 [[A:%.*]], i32 [[B:%.*]]) 1346 // AArch32-NEXT: ret i32 [[TMP0]] 1347 // 1348 int32_t test_smuadx(int16x2_t a, int16x2_t b) { 1349 return __smuadx(a, b); 1350 } 1351 1352 // AArch32-LABEL: @test_smusd( 1353 // AArch32-NEXT: entry: 1354 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusd(i32 [[A:%.*]], i32 [[B:%.*]]) 1355 // AArch32-NEXT: ret i32 [[TMP0]] 1356 // 1357 int32_t test_smusd(int16x2_t a, int16x2_t b) { 1358 return __smusd(a, b); 1359 } 1360 1361 // AArch32-LABEL: @test_smusdx( 1362 // AArch32-NEXT: entry: 1363 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.smusdx(i32 [[A:%.*]], i32 [[B:%.*]]) 1364 // AArch32-NEXT: ret i32 [[TMP0]] 1365 // 1366 int32_t test_smusdx(int16x2_t a, int16x2_t b) { 1367 return __smusdx(a, b); 1368 } 1369 #endif 1370 1371 /* 9.7 CRC32 intrinsics */ 1372 // AArch32-LABEL: @test_crc32b( 1373 // AArch32-NEXT: entry: 1374 // AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 1375 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) 1376 // AArch32-NEXT: ret i32 [[TMP1]] 1377 // 1378 // AArch64-LABEL: @test_crc32b( 1379 // AArch64-NEXT: entry: 1380 // AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 1381 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) 1382 // AArch64-NEXT: ret i32 [[TMP1]] 1383 // 1384 #ifndef __ARM_FEATURE_CRC32 1385 __attribute__((target("crc"))) 1386 #endif 1387 uint32_t test_crc32b(uint32_t a, uint8_t b) { 1388 return __crc32b(a, b); 1389 } 1390 1391 // AArch32-LABEL: @test_crc32h( 1392 // AArch32-NEXT: entry: 1393 // AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 1394 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) 1395 // AArch32-NEXT: ret i32 [[TMP1]] 1396 // 1397 // AArch64-LABEL: @test_crc32h( 1398 // AArch64-NEXT: entry: 1399 // AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 1400 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) 1401 // AArch64-NEXT: ret i32 [[TMP1]] 1402 // 1403 #ifndef __ARM_FEATURE_CRC32 1404 __attribute__((target("crc"))) 1405 #endif 1406 uint32_t test_crc32h(uint32_t a, uint16_t b) { 1407 return __crc32h(a, b); 1408 } 1409 1410 // AArch32-LABEL: @test_crc32w( 1411 // AArch32-NEXT: entry: 1412 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) 1413 // AArch32-NEXT: ret i32 [[TMP0]] 1414 // 1415 // AArch64-LABEL: @test_crc32w( 1416 // AArch64-NEXT: entry: 1417 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) 1418 // AArch64-NEXT: ret i32 [[TMP0]] 1419 // 1420 #ifndef __ARM_FEATURE_CRC32 1421 __attribute__((target("crc"))) 1422 #endif 1423 uint32_t test_crc32w(uint32_t a, uint32_t b) { 1424 return __crc32w(a, b); 1425 } 1426 1427 // AArch32-LABEL: @test_crc32d( 1428 // AArch32-NEXT: entry: 1429 // AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32 1430 // AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32 1431 // AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 1432 // AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[TMP0]]) 1433 // AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32w(i32 [[TMP3]], i32 [[TMP2]]) 1434 // AArch32-NEXT: ret i32 [[TMP4]] 1435 // 1436 // AArch64-LABEL: @test_crc32d( 1437 // AArch64-NEXT: entry: 1438 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]]) 1439 // AArch64-NEXT: ret i32 [[TMP0]] 1440 // 1441 #ifndef __ARM_FEATURE_CRC32 1442 __attribute__((target("crc"))) 1443 #endif 1444 uint32_t test_crc32d(uint32_t a, uint64_t b) { 1445 return __crc32d(a, b); 1446 } 1447 1448 // AArch32-LABEL: @test_crc32cb( 1449 // AArch32-NEXT: entry: 1450 // AArch32-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 1451 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) 1452 // AArch32-NEXT: ret i32 [[TMP1]] 1453 // 1454 // AArch64-LABEL: @test_crc32cb( 1455 // AArch64-NEXT: entry: 1456 // AArch64-NEXT: [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 1457 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) 1458 // AArch64-NEXT: ret i32 [[TMP1]] 1459 // 1460 #ifndef __ARM_FEATURE_CRC32 1461 __attribute__((target("crc"))) 1462 #endif 1463 uint32_t test_crc32cb(uint32_t a, uint8_t b) { 1464 return __crc32cb(a, b); 1465 } 1466 1467 // AArch32-LABEL: @test_crc32ch( 1468 // AArch32-NEXT: entry: 1469 // AArch32-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 1470 // AArch32-NEXT: [[TMP1:%.*]] = call i32 @llvm.arm.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) 1471 // AArch32-NEXT: ret i32 [[TMP1]] 1472 // 1473 // AArch64-LABEL: @test_crc32ch( 1474 // AArch64-NEXT: entry: 1475 // AArch64-NEXT: [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 1476 // AArch64-NEXT: [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) 1477 // AArch64-NEXT: ret i32 [[TMP1]] 1478 // 1479 #ifndef __ARM_FEATURE_CRC32 1480 __attribute__((target("crc"))) 1481 #endif 1482 uint32_t test_crc32ch(uint32_t a, uint16_t b) { 1483 return __crc32ch(a, b); 1484 } 1485 1486 // AArch32-LABEL: @test_crc32cw( 1487 // AArch32-NEXT: entry: 1488 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) 1489 // AArch32-NEXT: ret i32 [[TMP0]] 1490 // 1491 // AArch64-LABEL: @test_crc32cw( 1492 // AArch64-NEXT: entry: 1493 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) 1494 // AArch64-NEXT: ret i32 [[TMP0]] 1495 // 1496 #ifndef __ARM_FEATURE_CRC32 1497 __attribute__((target("crc"))) 1498 #endif 1499 uint32_t test_crc32cw(uint32_t a, uint32_t b) { 1500 return __crc32cw(a, b); 1501 } 1502 1503 // AArch32-LABEL: @test_crc32cd( 1504 // AArch32-NEXT: entry: 1505 // AArch32-NEXT: [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32 1506 // AArch32-NEXT: [[TMP1:%.*]] = lshr i64 [[B]], 32 1507 // AArch32-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 1508 // AArch32-NEXT: [[TMP3:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[TMP0]]) 1509 // AArch32-NEXT: [[TMP4:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[TMP3]], i32 [[TMP2]]) 1510 // AArch32-NEXT: ret i32 [[TMP4]] 1511 // 1512 // AArch64-LABEL: @test_crc32cd( 1513 // AArch64-NEXT: entry: 1514 // AArch64-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]]) 1515 // AArch64-NEXT: ret i32 [[TMP0]] 1516 // 1517 #ifndef __ARM_FEATURE_CRC32 1518 __attribute__((target("crc"))) 1519 #endif 1520 uint32_t test_crc32cd(uint32_t a, uint64_t b) { 1521 return __crc32cd(a, b); 1522 } 1523 1524 /* 10.1 Special register intrinsics */ 1525 // AArch32-LABEL: @test_rsr( 1526 // AArch32-NEXT: entry: 1527 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META5:![0-9]+]]) 1528 // AArch32-NEXT: ret i32 [[TMP0]] 1529 // 1530 // AArch64-LABEL: @test_rsr( 1531 // AArch64-NEXT: entry: 1532 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4:![0-9]+]]) 1533 // AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 1534 // AArch64-NEXT: ret i32 [[TMP1]] 1535 // 1536 uint32_t test_rsr() { 1537 #ifdef __ARM_32BIT_STATE 1538 return __arm_rsr("cp1:2:c3:c4:5"); 1539 #else 1540 return __arm_rsr("1:2:3:4:5"); 1541 #endif 1542 } 1543 1544 // AArch32-LABEL: @test_rsr64( 1545 // AArch32-NEXT: entry: 1546 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META6:![0-9]+]]) 1547 // AArch32-NEXT: ret i64 [[TMP0]] 1548 // 1549 // AArch64-LABEL: @test_rsr64( 1550 // AArch64-NEXT: entry: 1551 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]]) 1552 // AArch64-NEXT: ret i64 [[TMP0]] 1553 // 1554 uint64_t test_rsr64() { 1555 #ifdef __ARM_32BIT_STATE 1556 return __arm_rsr64("cp1:2:c3"); 1557 #else 1558 return __arm_rsr64("1:2:3:4:5"); 1559 #endif 1560 } 1561 1562 #ifdef __ARM_FEATURE_SYSREG128 1563 // AArch6494D128-LABEL: @test_rsr128( 1564 // AArch6494D128-NEXT: entry: 1565 // AArch6494D128-NEXT: [[TMP0:%.*]] = call i128 @llvm.read_volatile_register.i128(metadata [[META4]]) 1566 // AArch6494D128-NEXT: ret i128 [[TMP0]] 1567 // 1568 __uint128_t test_rsr128() { 1569 return __arm_rsr128("1:2:3:4:5"); 1570 } 1571 #endif 1572 1573 // AArch32-LABEL: @test_rsrp( 1574 // AArch32-NEXT: entry: 1575 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META7:![0-9]+]]) 1576 // AArch32-NEXT: [[TMP1:%.*]] = inttoptr i32 [[TMP0]] to ptr 1577 // AArch32-NEXT: ret ptr [[TMP1]] 1578 // 1579 // AArch64-LABEL: @test_rsrp( 1580 // AArch64-NEXT: entry: 1581 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META5:![0-9]+]]) 1582 // AArch64-NEXT: [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to ptr 1583 // AArch64-NEXT: ret ptr [[TMP1]] 1584 // 1585 void *test_rsrp() { 1586 return __arm_rsrp("sysreg"); 1587 } 1588 1589 // AArch32-LABEL: @test_wsr( 1590 // AArch32-NEXT: entry: 1591 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META5]], i32 [[V:%.*]]) 1592 // AArch32-NEXT: ret void 1593 // 1594 // AArch64-LABEL: @test_wsr( 1595 // AArch64-NEXT: entry: 1596 // AArch64-NEXT: [[TMP0:%.*]] = zext i32 [[V:%.*]] to i64 1597 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP0]]) 1598 // AArch64-NEXT: ret void 1599 // 1600 void test_wsr(uint32_t v) { 1601 #ifdef __ARM_32BIT_STATE 1602 __arm_wsr("cp1:2:c3:c4:5", v); 1603 #else 1604 __arm_wsr("1:2:3:4:5", v); 1605 #endif 1606 } 1607 1608 // AArch32-LABEL: @test_wsr64( 1609 // AArch32-NEXT: entry: 1610 // AArch32-NEXT: call void @llvm.write_register.i64(metadata [[META6]], i64 [[V:%.*]]) 1611 // AArch32-NEXT: ret void 1612 // 1613 // AArch64-LABEL: @test_wsr64( 1614 // AArch64-NEXT: entry: 1615 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[V:%.*]]) 1616 // AArch64-NEXT: ret void 1617 // 1618 void test_wsr64(uint64_t v) { 1619 #ifdef __ARM_32BIT_STATE 1620 __arm_wsr64("cp1:2:c3", v); 1621 #else 1622 __arm_wsr64("1:2:3:4:5", v); 1623 #endif 1624 } 1625 1626 #ifdef __ARM_FEATURE_SYSREG128 1627 // AArch6494D128-LABEL: @test_wsr128( 1628 // AArch6494D128-NEXT: entry: 1629 // AArch6494D128-NEXT: call void @llvm.write_register.i128(metadata [[META4]], i128 [[V:%.*]]) 1630 // AArch6494D128-NEXT: ret void 1631 // 1632 void test_wsr128(__uint128_t v) { 1633 __arm_wsr128("1:2:3:4:5", v); 1634 1635 } 1636 #endif 1637 1638 // AArch32-LABEL: @test_wsrp( 1639 // AArch32-NEXT: entry: 1640 // AArch32-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i32 1641 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META7]], i32 [[TMP0]]) 1642 // AArch32-NEXT: ret void 1643 // 1644 // AArch64-LABEL: @test_wsrp( 1645 // AArch64-NEXT: entry: 1646 // AArch64-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i64 1647 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META5]], i64 [[TMP0]]) 1648 // AArch64-NEXT: ret void 1649 // 1650 void test_wsrp(void *v) { 1651 __arm_wsrp("sysreg", v); 1652 } 1653 1654 // AArch32-LABEL: @test_rsrf( 1655 // AArch32-NEXT: entry: 1656 // AArch32-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4 1657 // AArch32-NEXT: [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META5]]) 1658 // AArch32-NEXT: store i32 [[TMP0]], ptr [[REF_TMP]], align 4 1659 // AArch32-NEXT: [[TMP1:%.*]] = load float, ptr [[REF_TMP]], align 4 1660 // AArch32-NEXT: ret float [[TMP1]] 1661 // 1662 // AArch64-LABEL: @test_rsrf( 1663 // AArch64-NEXT: entry: 1664 // AArch64-NEXT: [[REF_TMP:%.*]] = alloca i32, align 4 1665 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]]) 1666 // AArch64-NEXT: [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 1667 // AArch64-NEXT: store i32 [[TMP1]], ptr [[REF_TMP]], align 4 1668 // AArch64-NEXT: [[TMP2:%.*]] = load float, ptr [[REF_TMP]], align 4 1669 // AArch64-NEXT: ret float [[TMP2]] 1670 // 1671 float test_rsrf() { 1672 #ifdef __ARM_32BIT_STATE 1673 return __arm_rsrf("cp1:2:c3:c4:5"); 1674 #else 1675 return __arm_rsrf("1:2:3:4:5"); 1676 #endif 1677 } 1678 1679 // AArch32-LABEL: @test_rsrf64( 1680 // AArch32-NEXT: entry: 1681 // AArch32-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8 1682 // AArch32-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META6]]) 1683 // AArch32-NEXT: store i64 [[TMP0]], ptr [[REF_TMP]], align 8 1684 // AArch32-NEXT: [[TMP1:%.*]] = load double, ptr [[REF_TMP]], align 8 1685 // AArch32-NEXT: ret double [[TMP1]] 1686 // 1687 // AArch64-LABEL: @test_rsrf64( 1688 // AArch64-NEXT: entry: 1689 // AArch64-NEXT: [[REF_TMP:%.*]] = alloca i64, align 8 1690 // AArch64-NEXT: [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]]) 1691 // AArch64-NEXT: store i64 [[TMP0]], ptr [[REF_TMP]], align 8 1692 // AArch64-NEXT: [[TMP1:%.*]] = load double, ptr [[REF_TMP]], align 8 1693 // AArch64-NEXT: ret double [[TMP1]] 1694 // 1695 double test_rsrf64() { 1696 #ifdef __ARM_32BIT_STATE 1697 return __arm_rsrf64("cp1:2:c3"); 1698 #else 1699 return __arm_rsrf64("1:2:3:4:5"); 1700 #endif 1701 } 1702 1703 // AArch32-LABEL: @test_wsrf( 1704 // AArch32-NEXT: entry: 1705 // AArch32-NEXT: [[V_ADDR:%.*]] = alloca float, align 4 1706 // AArch32-NEXT: store float [[V:%.*]], ptr [[V_ADDR]], align 4 1707 // AArch32-NEXT: [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4 1708 // AArch32-NEXT: call void @llvm.write_register.i32(metadata [[META5]], i32 [[TMP0]]) 1709 // AArch32-NEXT: ret void 1710 // 1711 // AArch64-LABEL: @test_wsrf( 1712 // AArch64-NEXT: entry: 1713 // AArch64-NEXT: [[V_ADDR:%.*]] = alloca float, align 4 1714 // AArch64-NEXT: store float [[V:%.*]], ptr [[V_ADDR]], align 4 1715 // AArch64-NEXT: [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4 1716 // AArch64-NEXT: [[TMP1:%.*]] = zext i32 [[TMP0]] to i64 1717 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP1]]) 1718 // AArch64-NEXT: ret void 1719 // 1720 void test_wsrf(float v) { 1721 #ifdef __ARM_32BIT_STATE 1722 __arm_wsrf("cp1:2:c3:c4:5", v); 1723 #else 1724 __arm_wsrf("1:2:3:4:5", v); 1725 #endif 1726 } 1727 1728 // AArch32-LABEL: @test_wsrf64( 1729 // AArch32-NEXT: entry: 1730 // AArch32-NEXT: [[V_ADDR:%.*]] = alloca double, align 8 1731 // AArch32-NEXT: store double [[V:%.*]], ptr [[V_ADDR]], align 8 1732 // AArch32-NEXT: [[TMP0:%.*]] = load i64, ptr [[V_ADDR]], align 8 1733 // AArch32-NEXT: call void @llvm.write_register.i64(metadata [[META6]], i64 [[TMP0]]) 1734 // AArch32-NEXT: ret void 1735 // 1736 // AArch64-LABEL: @test_wsrf64( 1737 // AArch64-NEXT: entry: 1738 // AArch64-NEXT: [[V_ADDR:%.*]] = alloca double, align 8 1739 // AArch64-NEXT: store double [[V:%.*]], ptr [[V_ADDR]], align 8 1740 // AArch64-NEXT: [[TMP0:%.*]] = load i64, ptr [[V_ADDR]], align 8 1741 // AArch64-NEXT: call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP0]]) 1742 // AArch64-NEXT: ret void 1743 // 1744 void test_wsrf64(double v) { 1745 #ifdef __ARM_32BIT_STATE 1746 __arm_wsrf64("cp1:2:c3", v); 1747 #else 1748 __arm_wsrf64("1:2:3:4:5", v); 1749 #endif 1750 } 1751 1752 #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_JCVT) 1753 // AArch6483-LABEL: @test_jcvt( 1754 // AArch6483-NEXT: entry: 1755 // AArch6483-NEXT: [[TMP0:%.*]] = call i32 @llvm.aarch64.fjcvtzs(double [[V:%.*]]) 1756 // AArch6483-NEXT: ret i32 [[TMP0]] 1757 // 1758 int32_t test_jcvt(double v) { 1759 return __jcvt(v); 1760 } 1761 #endif 1762 1763 #if defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_64BIT_STATE) 1764 1765 // AArch64-LABEL: @test_rintn( 1766 // AArch64-NEXT: entry: 1767 // AArch64-NEXT: call double @llvm.roundeven.f64(double [[TMP0:%.*]]) 1768 double test_rintn(double a) { 1769 return __rintn(a); 1770 } 1771 1772 // AArch64-LABEL: @test_rintnf( 1773 // AArch64-NEXT: entry: 1774 // AArch64-NEXT: call float @llvm.roundeven.f32(float [[TMP0:%.*]]) 1775 float test_rintnf(float b) { 1776 return __rintnf(b); 1777 } 1778 #endif 1779 1780 #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_RNG) 1781 1782 // AArch6485-LABEL: @test_rndr( 1783 // AArch6485-NEXT: entry: 1784 // AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr() 1785 // AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 1786 // AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 1787 // AArch6485-NEXT: store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8 1788 // AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 1789 // AArch6485-NEXT: ret i32 [[TMP3]] 1790 // 1791 int test_rndr(uint64_t *__addr) { 1792 return __rndr(__addr); 1793 } 1794 1795 // AArch6485-LABEL: @test_rndrrs( 1796 // AArch6485-NEXT: entry: 1797 // AArch6485-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs() 1798 // AArch6485-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 1799 // AArch6485-NEXT: [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 1800 // AArch6485-NEXT: store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8 1801 // AArch6485-NEXT: [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 1802 // AArch6485-NEXT: ret i32 [[TMP3]] 1803 // 1804 int test_rndrrs(uint64_t *__addr) { 1805 return __rndrrs(__addr); 1806 } 1807 #endif 1808 1809 1810