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