|  | // NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py | 
|  | // 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 | 
|  | // 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 | 
|  | // 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 | 
|  | // 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 | 
|  | // 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 | 
|  | // 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 | 
|  |  | 
|  |  | 
|  | #include <arm_acle.h> | 
|  |  | 
|  | // REQUIRES: arm-registered-target,aarch64-registered-target | 
|  |  | 
|  | /* 8 SYNCHRONIZATION, BARRIER AND HINT INTRINSICS */ | 
|  | /* 8.3 Memory Barriers */ | 
|  |  | 
|  | // AArch32-LABEL: @test_dmb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.dmb(i32 1) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_dmb( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.dmb(i32 1) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_dmb(void) { | 
|  | __dmb(1); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_dsb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.dsb(i32 2) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_dsb( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.dsb(i32 2) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_dsb(void) { | 
|  | __dsb(2); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_isb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.isb(i32 3) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_isb( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.isb(i32 3) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_isb(void) { | 
|  | __isb(3); | 
|  | } | 
|  |  | 
|  | /* 8.4 Hints */ | 
|  | // AArch32-LABEL: @test_yield( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.hint(i32 1) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_yield( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 1) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_yield(void) { | 
|  | __yield(); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_wfe( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.hint(i32 2) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wfe( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 2) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wfe(void) { | 
|  | __wfe(); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_wfi( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.hint(i32 3) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wfi( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 3) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wfi(void) { | 
|  | __wfi(); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_sev( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.hint(i32 4) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_sev( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 4) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_sev(void) { | 
|  | __sev(); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_sevl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.hint(i32 5) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_sevl( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 5) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_sevl(void) { | 
|  | __sevl(); | 
|  | } | 
|  |  | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | // AArch32-LABEL: @test_dbg( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.dbg(i32 0) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | void test_dbg(void) { | 
|  | __dbg(0); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 8.5 Swap */ | 
|  | // ARM-LABEL: @test_swp( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = atomicrmw volatile xchg ptr [[P:%.*]], i32 [[X:%.*]] monotonic, align 4 | 
|  | // ARM-NEXT:    ret void | 
|  | // | 
|  | void test_swp(uint32_t x, volatile void *p) { | 
|  | __swp(x, p); | 
|  | } | 
|  |  | 
|  | /* 8.6 Memory prefetch intrinsics */ | 
|  | /* 8.6.1 Data prefetch */ | 
|  | // AArch32-LABEL: @test_pld( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 1) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_pld( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 0, i32 0, i32 1) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_pld() { | 
|  | __pld(0); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_pldx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.prefetch.p0(ptr null, i32 1, i32 3, i32 1) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_pldx( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.prefetch(ptr null, i32 1, i32 2, i32 0, i32 1) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_pldx() { | 
|  | __pldx(1, 2, 0, 0); | 
|  | } | 
|  |  | 
|  | /* 8.6.2 Instruction prefetch */ | 
|  | // AArch32-LABEL: @test_pli( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 0) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_pli( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 0, i32 0, i32 0) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_pli() { | 
|  | __pli(0); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_plix( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.prefetch.p0(ptr null, i32 0, i32 3, i32 0) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_plix( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.prefetch(ptr null, i32 0, i32 2, i32 0, i32 0) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_plix() { | 
|  | __plix(2, 0, 0); | 
|  | } | 
|  |  | 
|  | /* 8.7 NOP */ | 
|  | // AArch32-LABEL: @test_nop( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.arm.hint(i32 0) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_nop( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.aarch64.hint(i32 0) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_nop(void) { | 
|  | __nop(); | 
|  | } | 
|  |  | 
|  | /* 9 DATA-PROCESSING INTRINSICS */ | 
|  |  | 
|  | /* 9.2 Miscellaneous data-processing intrinsics */ | 
|  | // ARM-LABEL: @test_ror( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[REM_I:%.*]] = urem i32 [[Y:%.*]], 32 | 
|  | // ARM-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 | 
|  | // ARM-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] | 
|  | // ARM:       if.then.i: | 
|  | // ARM-NEXT:    br label [[__ROR_EXIT:%.*]] | 
|  | // ARM:       if.end.i: | 
|  | // ARM-NEXT:    [[SHR_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I]] | 
|  | // ARM-NEXT:    [[SUB_I:%.*]] = sub i32 32, [[REM_I]] | 
|  | // ARM-NEXT:    [[SHL_I:%.*]] = shl i32 [[X]], [[SUB_I]] | 
|  | // ARM-NEXT:    [[OR_I:%.*]] = or i32 [[SHR_I]], [[SHL_I]] | 
|  | // ARM-NEXT:    br label [[__ROR_EXIT]] | 
|  | // ARM:       __ror.exit: | 
|  | // ARM-NEXT:    [[RETVAL_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] | 
|  | // ARM-NEXT:    ret i32 [[RETVAL_I_0]] | 
|  | // | 
|  | uint32_t test_ror(uint32_t x, uint32_t y) { | 
|  | return __ror(x, y); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rorl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[REM_I_I:%.*]] = urem i32 [[Y:%.*]], 32 | 
|  | // AArch32-NEXT:    [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 | 
|  | // AArch32-NEXT:    br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] | 
|  | // AArch32:       if.then.i.i: | 
|  | // AArch32-NEXT:    br label [[__RORL_EXIT:%.*]] | 
|  | // AArch32:       if.end.i.i: | 
|  | // AArch32-NEXT:    [[SHR_I_I:%.*]] = lshr i32 [[X:%.*]], [[REM_I_I]] | 
|  | // AArch32-NEXT:    [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] | 
|  | // AArch32-NEXT:    [[SHL_I_I:%.*]] = shl i32 [[X]], [[SUB_I_I]] | 
|  | // AArch32-NEXT:    [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] | 
|  | // AArch32-NEXT:    br label [[__RORL_EXIT]] | 
|  | // AArch32:       __rorl.exit: | 
|  | // AArch32-NEXT:    [[RETVAL_I_I_0:%.*]] = phi i32 [ [[X]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] | 
|  | // AArch32-NEXT:    ret i32 [[RETVAL_I_I_0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rorl( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64 | 
|  | // AArch64-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 | 
|  | // AArch64-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] | 
|  | // AArch64:       if.then.i: | 
|  | // AArch64-NEXT:    br label [[__RORLL_EXIT:%.*]] | 
|  | // AArch64:       if.end.i: | 
|  | // AArch64-NEXT:    [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64 | 
|  | // AArch64-NEXT:    [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]] | 
|  | // AArch64-NEXT:    [[SUB_I:%.*]] = sub i32 64, [[REM_I]] | 
|  | // AArch64-NEXT:    [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64 | 
|  | // AArch64-NEXT:    [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]] | 
|  | // AArch64-NEXT:    [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]] | 
|  | // AArch64-NEXT:    br label [[__RORLL_EXIT]] | 
|  | // AArch64:       __rorll.exit: | 
|  | // AArch64-NEXT:    [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] | 
|  | // AArch64-NEXT:    ret i64 [[RETVAL_I_0]] | 
|  | // | 
|  | unsigned long test_rorl(unsigned long x, uint32_t y) { | 
|  | return __rorl(x, y); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_rorll( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[REM_I:%.*]] = urem i32 [[Y:%.*]], 64 | 
|  | // ARM-NEXT:    [[CMP_I:%.*]] = icmp eq i32 [[REM_I]], 0 | 
|  | // ARM-NEXT:    br i1 [[CMP_I]], label [[IF_THEN_I:%.*]], label [[IF_END_I:%.*]] | 
|  | // ARM:       if.then.i: | 
|  | // ARM-NEXT:    br label [[__RORLL_EXIT:%.*]] | 
|  | // ARM:       if.end.i: | 
|  | // ARM-NEXT:    [[SH_PROM_I:%.*]] = zext i32 [[REM_I]] to i64 | 
|  | // ARM-NEXT:    [[SHR_I:%.*]] = lshr i64 [[X:%.*]], [[SH_PROM_I]] | 
|  | // ARM-NEXT:    [[SUB_I:%.*]] = sub i32 64, [[REM_I]] | 
|  | // ARM-NEXT:    [[SH_PROM1_I:%.*]] = zext i32 [[SUB_I]] to i64 | 
|  | // ARM-NEXT:    [[SHL_I:%.*]] = shl i64 [[X]], [[SH_PROM1_I]] | 
|  | // ARM-NEXT:    [[OR_I:%.*]] = or i64 [[SHR_I]], [[SHL_I]] | 
|  | // ARM-NEXT:    br label [[__RORLL_EXIT]] | 
|  | // ARM:       __rorll.exit: | 
|  | // ARM-NEXT:    [[RETVAL_I_0:%.*]] = phi i64 [ [[X]], [[IF_THEN_I]] ], [ [[OR_I]], [[IF_END_I]] ] | 
|  | // ARM-NEXT:    ret i64 [[RETVAL_I_0]] | 
|  | // | 
|  | uint64_t test_rorll(uint64_t x, uint32_t y) { | 
|  | return __rorll(x, y); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_clz( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) | 
|  | // ARM-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | unsigned test_clz(uint32_t t) { | 
|  | return __clz(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_clzl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.ctlz.i32(i32 [[T:%.*]], i1 false) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_clzl( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) | 
|  | // AArch64-NEXT:    [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 | 
|  | // AArch64-NEXT:    ret i32 [[CAST_I]] | 
|  | // | 
|  | unsigned test_clzl(unsigned long t) { | 
|  | return __clzl(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_clzll( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i64 @llvm.ctlz.i64(i64 [[T:%.*]], i1 false) | 
|  | // ARM-NEXT:    [[CAST_I:%.*]] = trunc i64 [[TMP0]] to i32 | 
|  | // ARM-NEXT:    ret i32 [[CAST_I]] | 
|  | // | 
|  | unsigned test_clzll(uint64_t t) { | 
|  | return __clzll(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_cls( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[CLS_I]] | 
|  | // | 
|  | // AArch64-LABEL: @test_cls( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls(i32 [[T:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[CLS_I]] | 
|  | // | 
|  | unsigned test_cls(uint32_t t) { | 
|  | return __cls(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_clsl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.arm.cls(i32 [[T:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[CLS_I]] | 
|  | // | 
|  | // AArch64-LABEL: @test_clsl( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[CLS_I]] | 
|  | // | 
|  | unsigned test_clsl(unsigned long t) { | 
|  | return __clsl(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_clsll( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.arm.cls64(i64 [[T:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[CLS_I]] | 
|  | // | 
|  | // AArch64-LABEL: @test_clsll( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[CLS_I:%.*]] = call i32 @llvm.aarch64.cls64(i64 [[T:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[CLS_I]] | 
|  | // | 
|  | unsigned test_clsll(uint64_t t) { | 
|  | return __clsll(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_rev( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) | 
|  | // ARM-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint32_t test_rev(uint32_t t) { | 
|  | return __rev(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_revl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_revl( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) | 
|  | // AArch64-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | long test_revl(long t) { | 
|  | return __revl(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_revll( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i64 @llvm.bswap.i64(i64 [[T:%.*]]) | 
|  | // ARM-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | uint64_t test_revll(uint64_t t) { | 
|  | return __revll(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_rev16( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) | 
|  | // ARM-NEXT:    [[REM_I_I:%.*]] = urem i32 16, 32 | 
|  | // ARM-NEXT:    [[CMP_I_I:%.*]] = icmp eq i32 [[REM_I_I]], 0 | 
|  | // ARM-NEXT:    br i1 [[CMP_I_I]], label [[IF_THEN_I_I:%.*]], label [[IF_END_I_I:%.*]] | 
|  | // ARM:       if.then.i.i: | 
|  | // ARM-NEXT:    br label [[__REV16_EXIT:%.*]] | 
|  | // ARM:       if.end.i.i: | 
|  | // ARM-NEXT:    [[SHR_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I]] | 
|  | // ARM-NEXT:    [[SUB_I_I:%.*]] = sub i32 32, [[REM_I_I]] | 
|  | // ARM-NEXT:    [[SHL_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I]] | 
|  | // ARM-NEXT:    [[OR_I_I:%.*]] = or i32 [[SHR_I_I]], [[SHL_I_I]] | 
|  | // ARM-NEXT:    br label [[__REV16_EXIT]] | 
|  | // ARM:       __rev16.exit: | 
|  | // ARM-NEXT:    [[RETVAL_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I]] ], [ [[OR_I_I]], [[IF_END_I_I]] ] | 
|  | // ARM-NEXT:    ret i32 [[RETVAL_I_I_0]] | 
|  | // | 
|  | uint32_t test_rev16(uint32_t t) { | 
|  | return __rev16(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rev16l( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[T:%.*]]) | 
|  | // AArch32-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32 | 
|  | // AArch32-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 | 
|  | // AArch32-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] | 
|  | // AArch32:       if.then.i.i.i: | 
|  | // AArch32-NEXT:    br label [[__REV16L_EXIT:%.*]] | 
|  | // AArch32:       if.end.i.i.i: | 
|  | // AArch32-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I_I]] | 
|  | // AArch32-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] | 
|  | // AArch32-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I_I]] | 
|  | // AArch32-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] | 
|  | // AArch32-NEXT:    br label [[__REV16L_EXIT]] | 
|  | // AArch32:       __rev16l.exit: | 
|  | // AArch32-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] | 
|  | // AArch32-NEXT:    ret i32 [[RETVAL_I_I_I_0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rev16l( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 | 
|  | // AArch64-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) | 
|  | // AArch64-NEXT:    [[REM_I_I10_I:%.*]] = urem i32 16, 32 | 
|  | // AArch64-NEXT:    [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 | 
|  | // AArch64-NEXT:    br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I17_I:%.*]], label [[IF_END_I_I12_I:%.*]] | 
|  | // AArch64:       if.then.i.i17.i: | 
|  | // AArch64-NEXT:    br label [[__REV16_EXIT18_I:%.*]] | 
|  | // AArch64:       if.end.i.i12.i: | 
|  | // AArch64-NEXT:    [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] | 
|  | // AArch64-NEXT:    [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] | 
|  | // AArch64-NEXT:    [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] | 
|  | // AArch64-NEXT:    [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] | 
|  | // AArch64-NEXT:    br label [[__REV16_EXIT18_I]] | 
|  | // AArch64:       __rev16.exit18.i: | 
|  | // AArch64-NEXT:    [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I17_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I12_I]] ] | 
|  | // AArch64-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 | 
|  | // AArch64-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 | 
|  | // AArch64-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) | 
|  | // AArch64-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32 | 
|  | // AArch64-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 | 
|  | // AArch64-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] | 
|  | // AArch64:       if.then.i.i.i: | 
|  | // AArch64-NEXT:    br label [[__REV16LL_EXIT:%.*]] | 
|  | // AArch64:       if.end.i.i.i: | 
|  | // AArch64-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] | 
|  | // AArch64-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] | 
|  | // AArch64-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] | 
|  | // AArch64-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] | 
|  | // AArch64-NEXT:    br label [[__REV16LL_EXIT]] | 
|  | // AArch64:       __rev16ll.exit: | 
|  | // AArch64-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] | 
|  | // AArch64-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 | 
|  | // AArch64-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] | 
|  | // AArch64-NEXT:    ret i64 [[OR_I]] | 
|  | // | 
|  | long test_rev16l(long t) { | 
|  | return __rev16l(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_rev16ll( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T:%.*]], 32 | 
|  | // ARM-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SHR_I]] to i32 | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV_I]]) | 
|  | // ARM-NEXT:    [[REM_I_I10_I:%.*]] = urem i32 16, 32 | 
|  | // ARM-NEXT:    [[CMP_I_I11_I:%.*]] = icmp eq i32 [[REM_I_I10_I]], 0 | 
|  | // ARM-NEXT:    br i1 [[CMP_I_I11_I]], label [[IF_THEN_I_I17_I:%.*]], label [[IF_END_I_I12_I:%.*]] | 
|  | // ARM:       if.then.i.i17.i: | 
|  | // ARM-NEXT:    br label [[__REV16_EXIT18_I:%.*]] | 
|  | // ARM:       if.end.i.i12.i: | 
|  | // ARM-NEXT:    [[SHR_I_I13_I:%.*]] = lshr i32 [[TMP0]], [[REM_I_I10_I]] | 
|  | // ARM-NEXT:    [[SUB_I_I14_I:%.*]] = sub i32 32, [[REM_I_I10_I]] | 
|  | // ARM-NEXT:    [[SHL_I_I15_I:%.*]] = shl i32 [[TMP0]], [[SUB_I_I14_I]] | 
|  | // ARM-NEXT:    [[OR_I_I16_I:%.*]] = or i32 [[SHR_I_I13_I]], [[SHL_I_I15_I]] | 
|  | // ARM-NEXT:    br label [[__REV16_EXIT18_I]] | 
|  | // ARM:       __rev16.exit18.i: | 
|  | // ARM-NEXT:    [[RETVAL_I_I6_I_0:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN_I_I17_I]] ], [ [[OR_I_I16_I]], [[IF_END_I_I12_I]] ] | 
|  | // ARM-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RETVAL_I_I6_I_0]] to i64 | 
|  | // ARM-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 | 
|  | // ARM-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[T]] to i32 | 
|  | // ARM-NEXT:    [[TMP1:%.*]] = call i32 @llvm.bswap.i32(i32 [[CONV2_I]]) | 
|  | // ARM-NEXT:    [[REM_I_I_I:%.*]] = urem i32 16, 32 | 
|  | // ARM-NEXT:    [[CMP_I_I_I:%.*]] = icmp eq i32 [[REM_I_I_I]], 0 | 
|  | // ARM-NEXT:    br i1 [[CMP_I_I_I]], label [[IF_THEN_I_I_I:%.*]], label [[IF_END_I_I_I:%.*]] | 
|  | // ARM:       if.then.i.i.i: | 
|  | // ARM-NEXT:    br label [[__REV16LL_EXIT:%.*]] | 
|  | // ARM:       if.end.i.i.i: | 
|  | // ARM-NEXT:    [[SHR_I_I_I:%.*]] = lshr i32 [[TMP1]], [[REM_I_I_I]] | 
|  | // ARM-NEXT:    [[SUB_I_I_I:%.*]] = sub i32 32, [[REM_I_I_I]] | 
|  | // ARM-NEXT:    [[SHL_I_I_I:%.*]] = shl i32 [[TMP1]], [[SUB_I_I_I]] | 
|  | // ARM-NEXT:    [[OR_I_I_I:%.*]] = or i32 [[SHR_I_I_I]], [[SHL_I_I_I]] | 
|  | // ARM-NEXT:    br label [[__REV16LL_EXIT]] | 
|  | // ARM:       __rev16ll.exit: | 
|  | // ARM-NEXT:    [[RETVAL_I_I_I_0:%.*]] = phi i32 [ [[TMP1]], [[IF_THEN_I_I_I]] ], [ [[OR_I_I_I]], [[IF_END_I_I_I]] ] | 
|  | // ARM-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RETVAL_I_I_I_0]] to i64 | 
|  | // ARM-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] | 
|  | // ARM-NEXT:    ret i64 [[OR_I]] | 
|  | // | 
|  | uint64_t test_rev16ll(uint64_t t) { | 
|  | return __rev16ll(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_revsh( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[TMP0:%.*]] = call i16 @llvm.bswap.i16(i16 [[T:%.*]]) | 
|  | // ARM-NEXT:    ret i16 [[TMP0]] | 
|  | // | 
|  | int16_t test_revsh(int16_t t) { | 
|  | return __revsh(t); | 
|  | } | 
|  |  | 
|  | // ARM-LABEL: @test_rbit( | 
|  | // ARM-NEXT:  entry: | 
|  | // ARM-NEXT:    [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) | 
|  | // ARM-NEXT:    ret i32 [[RBIT_I]] | 
|  | // | 
|  | uint32_t test_rbit(uint32_t t) { | 
|  | return __rbit(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rbitl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[RBIT_I_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[T:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[RBIT_I_I]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rbitl( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) | 
|  | // AArch64-NEXT:    ret i64 [[RBIT_I]] | 
|  | // | 
|  | long test_rbitl(long t) { | 
|  | return __rbitl(t); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rbitll( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[CONV_I:%.*]] = trunc i64 [[T:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[RBIT_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV_I]]) | 
|  | // AArch32-NEXT:    [[CONV1_I:%.*]] = zext i32 [[RBIT_I]] to i64 | 
|  | // AArch32-NEXT:    [[SHL_I:%.*]] = shl i64 [[CONV1_I]], 32 | 
|  | // AArch32-NEXT:    [[SHR_I:%.*]] = lshr i64 [[T]], 32 | 
|  | // AArch32-NEXT:    [[CONV2_I:%.*]] = trunc i64 [[SHR_I]] to i32 | 
|  | // AArch32-NEXT:    [[RBIT3_I:%.*]] = call i32 @llvm.bitreverse.i32(i32 [[CONV2_I]]) | 
|  | // AArch32-NEXT:    [[CONV4_I:%.*]] = zext i32 [[RBIT3_I]] to i64 | 
|  | // AArch32-NEXT:    [[OR_I:%.*]] = or i64 [[SHL_I]], [[CONV4_I]] | 
|  | // AArch32-NEXT:    ret i64 [[OR_I]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rbitll( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[RBIT_I:%.*]] = call i64 @llvm.bitreverse.i64(i64 [[T:%.*]]) | 
|  | // AArch64-NEXT:    ret i64 [[RBIT_I]] | 
|  | // | 
|  | uint64_t test_rbitll(uint64_t t) { | 
|  | return __rbitll(t); | 
|  | } | 
|  |  | 
|  | /* 9.4 Saturating intrinsics */ | 
|  | #ifdef __ARM_FEATURE_SAT | 
|  | /* 9.4.1 Width-specified saturation intrinsics */ | 
|  | // AArch32-LABEL: @test_ssat( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssat(i32 [[T:%.*]], i32 1) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_ssat(int32_t t) { | 
|  | return __ssat(t, 1); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_usat( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usat(i32 [[T:%.*]], i32 2) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint32_t test_usat(int32_t t) { | 
|  | return __usat(t, 2); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.4.2 Saturating addition and subtraction intrinsics */ | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | // AArch32-LABEL: @test_qadd( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_qadd(int32_t a, int32_t b) { | 
|  | return __qadd(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_qsub( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsub(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_qsub(int32_t a, int32_t b) { | 
|  | return __qsub(a, b); | 
|  | } | 
|  |  | 
|  | extern int32_t f(); | 
|  | // AArch32-LABEL: @test_qdbl( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[CALL:%.*]] = call i32 @f() #[[ATTR9:[0-9]+]] | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd(i32 [[CALL]], i32 [[CALL]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_qdbl() { | 
|  | return __qdbl(f()); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* | 
|  | * 9.3 16-bit multiplications | 
|  | */ | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | // AArch32-LABEL: @test_smulbb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulbb(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smulbb(int32_t a, int32_t b) { | 
|  | return __smulbb(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smulbt( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulbt(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smulbt(int32_t a, int32_t b) { | 
|  | return __smulbt(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smultb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smultb(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smultb(int32_t a, int32_t b) { | 
|  | return __smultb(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smultt( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smultt(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smultt(int32_t a, int32_t b) { | 
|  | return __smultt(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smulwb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulwb(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smulwb(int32_t a, int32_t b) { | 
|  | return __smulwb(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smulwt( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smulwt(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smulwt(int32_t a, int32_t b) { | 
|  | return __smulwt(a, b); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.4.3 Accumultating multiplications */ | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | // AArch32-LABEL: @test_smlabb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlabb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smlabb(int32_t a, int32_t b, int32_t c) { | 
|  | return __smlabb(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlabt( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlabt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smlabt(int32_t a, int32_t b, int32_t c) { | 
|  | return __smlabt(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlatb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlatb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smlatb(int32_t a, int32_t b, int32_t c) { | 
|  | return __smlatb(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlatt( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlatt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smlatt(int32_t a, int32_t b, int32_t c) { | 
|  | return __smlatt(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlawb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlawb(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smlawb(int32_t a, int32_t b, int32_t c) { | 
|  | return __smlawb(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlawt( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlawt(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_DSP | 
|  | __attribute__((target("dsp"))) | 
|  | #endif | 
|  | int32_t test_smlawt(int32_t a, int32_t b, int32_t c) { | 
|  | return __smlawt(a, b, c); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.4 Parallel 16-bit saturation */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_ssat16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssat16(i32 [[A:%.*]], i32 15) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_ssat16(int16x2_t a) { | 
|  | return __ssat16(a, 15); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_usat16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usat16(i32 [[A:%.*]], i32 15) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_usat16(int16x2_t a) { | 
|  | return __usat16(a, 15); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.5 Packing and unpacking */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_sxtab16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_sxtab16(int16x2_t a, int8x4_t b) { | 
|  | return __sxtab16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_sxtb16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sxtb16(i32 [[A:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_sxtb16(int8x4_t a) { | 
|  | return __sxtb16(a); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uxtab16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uxtab16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_uxtab16(int16x2_t a, int8x4_t b) { | 
|  | return __uxtab16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uxtb16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uxtb16(i32 [[A:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_uxtb16(int8x4_t a) { | 
|  | return __uxtb16(a); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.6 Parallel selection */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_sel( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sel(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_sel(uint8x4_t a, uint8x4_t b) { | 
|  | return __sel(a, b); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.7 Parallel 8-bit addition and subtraction */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_qadd8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_qadd8(int8x4_t a, int8x4_t b) { | 
|  | return __qadd8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_qsub8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsub8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int8x4_t test_qsub8(int8x4_t a, int8x4_t b) { | 
|  | return __qsub8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_sadd8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sadd8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int8x4_t test_sadd8(int8x4_t a, int8x4_t b) { | 
|  | return __sadd8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_shadd8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shadd8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int8x4_t test_shadd8(int8x4_t a, int8x4_t b) { | 
|  | return __shadd8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_shsub8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shsub8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int8x4_t test_shsub8(int8x4_t a, int8x4_t b) { | 
|  | return __shsub8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_ssub8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssub8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int8x4_t test_ssub8(int8x4_t a, int8x4_t b) { | 
|  | return __ssub8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uadd8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uadd8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_uadd8(uint8x4_t a, uint8x4_t b) { | 
|  | return __uadd8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uhadd8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhadd8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_uhadd8(uint8x4_t a, uint8x4_t b) { | 
|  | return __uhadd8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uhsub8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhsub8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_uhsub8(uint8x4_t a, uint8x4_t b) { | 
|  | return __uhsub8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uqadd8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqadd8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_uqadd8(uint8x4_t a, uint8x4_t b) { | 
|  | return __uqadd8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uqsub8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqsub8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_uqsub8(uint8x4_t a, uint8x4_t b) { | 
|  | return __uqsub8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_usub8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usub8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint8x4_t test_usub8(uint8x4_t a, uint8x4_t b) { | 
|  | return __usub8(a, b); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.8 Sum of 8-bit absolute differences */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_usad8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usad8(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint32_t test_usad8(uint8x4_t a, uint8x4_t b) { | 
|  | return __usad8(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_usada8( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[CONV:%.*]] = zext i8 [[A:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[CONV1:%.*]] = zext i8 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[CONV2:%.*]] = zext i8 [[C:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usada8(i32 [[CONV]], i32 [[CONV1]], i32 [[CONV2]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint32_t test_usada8(uint8_t a, uint8_t b, uint8_t c) { | 
|  | return __usada8(a, b, c); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.9 Parallel 16-bit addition and subtraction */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_qadd16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qadd16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_qadd16(int16x2_t a, int16x2_t b) { | 
|  | return __qadd16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_qasx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qasx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_qasx(int16x2_t a, int16x2_t b) { | 
|  | return __qasx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_qsax( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsax(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_qsax(int16x2_t a, int16x2_t b) { | 
|  | return __qsax(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_qsub16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.qsub16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_qsub16(int16x2_t a, int16x2_t b) { | 
|  | return __qsub16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_sadd16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sadd16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_sadd16(int16x2_t a, int16x2_t b) { | 
|  | return __sadd16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_sasx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.sasx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_sasx(int16x2_t a, int16x2_t b) { | 
|  | return __sasx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_shadd16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shadd16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_shadd16(int16x2_t a, int16x2_t b) { | 
|  | return __shadd16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_shasx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shasx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_shasx(int16x2_t a, int16x2_t b) { | 
|  | return __shasx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_shsax( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shsax(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_shsax(int16x2_t a, int16x2_t b) { | 
|  | return __shsax(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_shsub16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.shsub16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_shsub16(int16x2_t a, int16x2_t b) { | 
|  | return __shsub16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_ssax( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssax(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_ssax(int16x2_t a, int16x2_t b) { | 
|  | return __ssax(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_ssub16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.ssub16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int16x2_t test_ssub16(int16x2_t a, int16x2_t b) { | 
|  | return __ssub16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uadd16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uadd16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uadd16(uint16x2_t a, uint16x2_t b) { | 
|  | return __uadd16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uasx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uasx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uasx(uint16x2_t a, uint16x2_t b) { | 
|  | return __uasx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uhadd16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhadd16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uhadd16(uint16x2_t a, uint16x2_t b) { | 
|  | return __uhadd16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uhasx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhasx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uhasx(uint16x2_t a, uint16x2_t b) { | 
|  | return __uhasx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uhsax( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhsax(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uhsax(uint16x2_t a, uint16x2_t b) { | 
|  | return __uhsax(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uhsub16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uhsub16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uhsub16(uint16x2_t a, uint16x2_t b) { | 
|  | return __uhsub16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uqadd16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqadd16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uqadd16(uint16x2_t a, uint16x2_t b) { | 
|  | return __uqadd16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uqasx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqasx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uqasx(uint16x2_t a, uint16x2_t b) { | 
|  | return __uqasx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uqsax( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqsax(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uqsax(uint16x2_t a, uint16x2_t b) { | 
|  | return __uqsax(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_uqsub16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.uqsub16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_uqsub16(uint16x2_t a, uint16x2_t b) { | 
|  | return __uqsub16(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_usax( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usax(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_usax(uint16x2_t a, uint16x2_t b) { | 
|  | return __usax(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_usub16( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.usub16(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | uint16x2_t test_usub16(uint16x2_t a, uint16x2_t b) { | 
|  | return __usub16(a, b); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.5.10 Parallel 16-bit multiplications */ | 
|  | #if __ARM_FEATURE_SIMD32 | 
|  | // AArch32-LABEL: @test_smlad( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlad(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smlad(int16x2_t a, int16x2_t b, int32_t c) { | 
|  | return __smlad(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smladx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smladx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smladx(int16x2_t a, int16x2_t b, int32_t c) { | 
|  | return __smladx(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlald( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlald(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | int64_t test_smlald(int16x2_t a, int16x2_t b, int64_t c) { | 
|  | return __smlald(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlaldx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlaldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | int64_t test_smlaldx(int16x2_t a, int16x2_t b, int64_t c) { | 
|  | return __smlaldx(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlsd( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlsd(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smlsd(int16x2_t a, int16x2_t b, int32_t c) { | 
|  | return __smlsd(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlsdx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smlsdx(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smlsdx(int16x2_t a, int16x2_t b, int32_t c) { | 
|  | return __smlsdx(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlsld( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlsld(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | int64_t test_smlsld(int16x2_t a, int16x2_t b, int64_t c) { | 
|  | return __smlsld(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smlsldx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.arm.smlsldx(i32 [[A:%.*]], i32 [[B:%.*]], i64 [[C:%.*]]) | 
|  | // AArch32-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | int64_t test_smlsldx(int16x2_t a, int16x2_t b, int64_t c) { | 
|  | return __smlsldx(a, b, c); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smuad( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smuad(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smuad(int16x2_t a, int16x2_t b) { | 
|  | return __smuad(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smuadx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smuadx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smuadx(int16x2_t a, int16x2_t b) { | 
|  | return __smuadx(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smusd( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smusd(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smusd(int16x2_t a, int16x2_t b) { | 
|  | return __smusd(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_smusdx( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.smusdx(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_smusdx(int16x2_t a, int16x2_t b) { | 
|  | return __smusdx(a, b); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | /* 9.7 CRC32 intrinsics */ | 
|  | // AArch32-LABEL: @test_crc32b( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32b( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32b(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32b(uint32_t a, uint8_t b) { | 
|  | return __crc32b(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32h( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32h( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32h(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32h(uint32_t a, uint16_t b) { | 
|  | return __crc32h(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32w( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32w( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32w(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32w(uint32_t a, uint32_t b) { | 
|  | return __crc32w(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32d( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = lshr i64 [[B]], 32 | 
|  | // AArch32-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 | 
|  | // AArch32-NEXT:    [[TMP3:%.*]] = call i32 @llvm.arm.crc32w(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.arm.crc32w(i32 [[TMP3]], i32 [[TMP2]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP4]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32d( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32x(i32 [[A:%.*]], i64 [[B:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32d(uint32_t a, uint64_t b) { | 
|  | return __crc32d(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32cb( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32cb( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = zext i8 [[B:%.*]] to i32 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32cb(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32cb(uint32_t a, uint8_t b) { | 
|  | return __crc32cb(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32ch( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = call i32 @llvm.arm.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32ch( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = zext i16 [[B:%.*]] to i32 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = call i32 @llvm.aarch64.crc32ch(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32ch(uint32_t a, uint16_t b) { | 
|  | return __crc32ch(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32cw( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32cw( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cw(i32 [[A:%.*]], i32 [[B:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32cw(uint32_t a, uint32_t b) { | 
|  | return __crc32cw(a, b); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_crc32cd( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = trunc i64 [[B:%.*]] to i32 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = lshr i64 [[B]], 32 | 
|  | // AArch32-NEXT:    [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 | 
|  | // AArch32-NEXT:    [[TMP3:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[A:%.*]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    [[TMP4:%.*]] = call i32 @llvm.arm.crc32cw(i32 [[TMP3]], i32 [[TMP2]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP4]] | 
|  | // | 
|  | // AArch64-LABEL: @test_crc32cd( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.crc32cx(i32 [[A:%.*]], i64 [[B:%.*]]) | 
|  | // AArch64-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | #ifndef __ARM_FEATURE_CRC32 | 
|  | __attribute__((target("crc"))) | 
|  | #endif | 
|  | uint32_t test_crc32cd(uint32_t a, uint64_t b) { | 
|  | return __crc32cd(a, b); | 
|  | } | 
|  |  | 
|  | /* 10.1 Special register intrinsics */ | 
|  | // AArch32-LABEL: @test_rsr( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META5:![0-9]+]]) | 
|  | // AArch32-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rsr( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4:![0-9]+]]) | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 | 
|  | // AArch64-NEXT:    ret i32 [[TMP1]] | 
|  | // | 
|  | uint32_t test_rsr() { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | return __arm_rsr("cp1:2:c3:c4:5"); | 
|  | #else | 
|  | return __arm_rsr("1:2:3:4:5"); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rsr64( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META6:![0-9]+]]) | 
|  | // AArch32-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rsr64( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]]) | 
|  | // AArch64-NEXT:    ret i64 [[TMP0]] | 
|  | // | 
|  | uint64_t test_rsr64() { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | return __arm_rsr64("cp1:2:c3"); | 
|  | #else | 
|  | return __arm_rsr64("1:2:3:4:5"); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #ifdef __ARM_FEATURE_SYSREG128 | 
|  | // AArch6494D128-LABEL: @test_rsr128( | 
|  | // AArch6494D128-NEXT:  entry: | 
|  | // AArch6494D128-NEXT:    [[TMP0:%.*]] = call i128 @llvm.read_volatile_register.i128(metadata [[META4]]) | 
|  | // AArch6494D128-NEXT:    ret i128 [[TMP0]] | 
|  | // | 
|  | __uint128_t test_rsr128() { | 
|  | return __arm_rsr128("1:2:3:4:5"); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | // AArch32-LABEL: @test_rsrp( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META7:![0-9]+]]) | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = inttoptr i32 [[TMP0]] to ptr | 
|  | // AArch32-NEXT:    ret ptr [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rsrp( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META5:![0-9]+]]) | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = inttoptr i64 [[TMP0]] to ptr | 
|  | // AArch64-NEXT:    ret ptr [[TMP1]] | 
|  | // | 
|  | void *test_rsrp() { | 
|  | return __arm_rsrp("sysreg"); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_wsr( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.write_register.i32(metadata [[META5]], i32 [[V:%.*]]) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wsr( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = zext i32 [[V:%.*]] to i64 | 
|  | // AArch64-NEXT:    call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wsr(uint32_t v) { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | __arm_wsr("cp1:2:c3:c4:5", v); | 
|  | #else | 
|  | __arm_wsr("1:2:3:4:5", v); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_wsr64( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    call void @llvm.write_register.i64(metadata [[META6]], i64 [[V:%.*]]) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wsr64( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call void @llvm.write_register.i64(metadata [[META4]], i64 [[V:%.*]]) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wsr64(uint64_t v) { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | __arm_wsr64("cp1:2:c3", v); | 
|  | #else | 
|  | __arm_wsr64("1:2:3:4:5", v); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #ifdef __ARM_FEATURE_SYSREG128 | 
|  | // AArch6494D128-LABEL: @test_wsr128( | 
|  | // AArch6494D128-NEXT:  entry: | 
|  | // AArch6494D128-NEXT:    call void @llvm.write_register.i128(metadata [[META4]], i128 [[V:%.*]]) | 
|  | // AArch6494D128-NEXT:    ret void | 
|  | // | 
|  | void test_wsr128(__uint128_t v) { | 
|  | __arm_wsr128("1:2:3:4:5", v); | 
|  |  | 
|  | } | 
|  | #endif | 
|  |  | 
|  | // AArch32-LABEL: @test_wsrp( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i32 | 
|  | // AArch32-NEXT:    call void @llvm.write_register.i32(metadata [[META7]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wsrp( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = ptrtoint ptr [[V:%.*]] to i64 | 
|  | // AArch64-NEXT:    call void @llvm.write_register.i64(metadata [[META5]], i64 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wsrp(void *v) { | 
|  | __arm_wsrp("sysreg", v); | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rsrf( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[REF_TMP:%.*]] = alloca i32, align 4 | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i32 @llvm.read_volatile_register.i32(metadata [[META5]]) | 
|  | // AArch32-NEXT:    store i32 [[TMP0]], ptr [[REF_TMP]], align 4 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = load float, ptr [[REF_TMP]], align 4 | 
|  | // AArch32-NEXT:    ret float [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rsrf( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[REF_TMP:%.*]] = alloca i32, align 4 | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]]) | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = trunc i64 [[TMP0]] to i32 | 
|  | // AArch64-NEXT:    store i32 [[TMP1]], ptr [[REF_TMP]], align 4 | 
|  | // AArch64-NEXT:    [[TMP2:%.*]] = load float, ptr [[REF_TMP]], align 4 | 
|  | // AArch64-NEXT:    ret float [[TMP2]] | 
|  | // | 
|  | float test_rsrf() { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | return __arm_rsrf("cp1:2:c3:c4:5"); | 
|  | #else | 
|  | return __arm_rsrf("1:2:3:4:5"); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_rsrf64( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[REF_TMP:%.*]] = alloca i64, align 8 | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META6]]) | 
|  | // AArch32-NEXT:    store i64 [[TMP0]], ptr [[REF_TMP]], align 8 | 
|  | // AArch32-NEXT:    [[TMP1:%.*]] = load double, ptr [[REF_TMP]], align 8 | 
|  | // AArch32-NEXT:    ret double [[TMP1]] | 
|  | // | 
|  | // AArch64-LABEL: @test_rsrf64( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[REF_TMP:%.*]] = alloca i64, align 8 | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = call i64 @llvm.read_volatile_register.i64(metadata [[META4]]) | 
|  | // AArch64-NEXT:    store i64 [[TMP0]], ptr [[REF_TMP]], align 8 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = load double, ptr [[REF_TMP]], align 8 | 
|  | // AArch64-NEXT:    ret double [[TMP1]] | 
|  | // | 
|  | double test_rsrf64() { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | return __arm_rsrf64("cp1:2:c3"); | 
|  | #else | 
|  | return __arm_rsrf64("1:2:3:4:5"); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_wsrf( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[V_ADDR:%.*]] = alloca float, align 4 | 
|  | // AArch32-NEXT:    store float [[V:%.*]], ptr [[V_ADDR]], align 4 | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4 | 
|  | // AArch32-NEXT:    call void @llvm.write_register.i32(metadata [[META5]], i32 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wsrf( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[V_ADDR:%.*]] = alloca float, align 4 | 
|  | // AArch64-NEXT:    store float [[V:%.*]], ptr [[V_ADDR]], align 4 | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = load i32, ptr [[V_ADDR]], align 4 | 
|  | // AArch64-NEXT:    [[TMP1:%.*]] = zext i32 [[TMP0]] to i64 | 
|  | // AArch64-NEXT:    call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP1]]) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wsrf(float v) { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | __arm_wsrf("cp1:2:c3:c4:5", v); | 
|  | #else | 
|  | __arm_wsrf("1:2:3:4:5", v); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | // AArch32-LABEL: @test_wsrf64( | 
|  | // AArch32-NEXT:  entry: | 
|  | // AArch32-NEXT:    [[V_ADDR:%.*]] = alloca double, align 8 | 
|  | // AArch32-NEXT:    store double [[V:%.*]], ptr [[V_ADDR]], align 8 | 
|  | // AArch32-NEXT:    [[TMP0:%.*]] = load i64, ptr [[V_ADDR]], align 8 | 
|  | // AArch32-NEXT:    call void @llvm.write_register.i64(metadata [[META6]], i64 [[TMP0]]) | 
|  | // AArch32-NEXT:    ret void | 
|  | // | 
|  | // AArch64-LABEL: @test_wsrf64( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    [[V_ADDR:%.*]] = alloca double, align 8 | 
|  | // AArch64-NEXT:    store double [[V:%.*]], ptr [[V_ADDR]], align 8 | 
|  | // AArch64-NEXT:    [[TMP0:%.*]] = load i64, ptr [[V_ADDR]], align 8 | 
|  | // AArch64-NEXT:    call void @llvm.write_register.i64(metadata [[META4]], i64 [[TMP0]]) | 
|  | // AArch64-NEXT:    ret void | 
|  | // | 
|  | void test_wsrf64(double v) { | 
|  | #ifdef __ARM_32BIT_STATE | 
|  | __arm_wsrf64("cp1:2:c3", v); | 
|  | #else | 
|  | __arm_wsrf64("1:2:3:4:5", v); | 
|  | #endif | 
|  | } | 
|  |  | 
|  | #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_JCVT) | 
|  | // AArch6483-LABEL: @test_jcvt( | 
|  | // AArch6483-NEXT:  entry: | 
|  | // AArch6483-NEXT:    [[TMP0:%.*]] = call i32 @llvm.aarch64.fjcvtzs(double [[V:%.*]]) | 
|  | // AArch6483-NEXT:    ret i32 [[TMP0]] | 
|  | // | 
|  | int32_t test_jcvt(double v) { | 
|  | return __jcvt(v); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if defined(__ARM_FEATURE_DIRECTED_ROUNDING) && defined(__ARM_64BIT_STATE) | 
|  |  | 
|  | // AArch64-LABEL: @test_rintn( | 
|  | // AArch64-NEXT:  entry: | 
|  | // AArch64-NEXT:    call double @llvm.roundeven.f64(double [[TMP0:%.*]]) | 
|  | double test_rintn(double a) { | 
|  | return __rintn(a); | 
|  | } | 
|  |  | 
|  | // AArch64-LABEL: @test_rintnf( | 
|  | // AArch64-NEXT: entry: | 
|  | // AArch64-NEXT:      call float @llvm.roundeven.f32(float [[TMP0:%.*]]) | 
|  | float test_rintnf(float b) { | 
|  | return __rintnf(b); | 
|  | } | 
|  | #endif | 
|  |  | 
|  | #if defined(__ARM_64BIT_STATE) && defined(__ARM_FEATURE_RNG) | 
|  |  | 
|  | // AArch6485-LABEL: @test_rndr( | 
|  | // AArch6485-NEXT:  entry: | 
|  | // AArch6485-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndr() | 
|  | // AArch6485-NEXT:    [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 | 
|  | // AArch6485-NEXT:    [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 | 
|  | // AArch6485-NEXT:    store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8 | 
|  | // AArch6485-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 | 
|  | // AArch6485-NEXT:    ret i32 [[TMP3]] | 
|  | // | 
|  | int test_rndr(uint64_t *__addr) { | 
|  | return __rndr(__addr); | 
|  | } | 
|  |  | 
|  | // AArch6485-LABEL: @test_rndrrs( | 
|  | // AArch6485-NEXT:  entry: | 
|  | // AArch6485-NEXT:    [[TMP0:%.*]] = call { i64, i1 } @llvm.aarch64.rndrrs() | 
|  | // AArch6485-NEXT:    [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0 | 
|  | // AArch6485-NEXT:    [[TMP2:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1 | 
|  | // AArch6485-NEXT:    store i64 [[TMP1]], ptr [[__ADDR:%.*]], align 8 | 
|  | // AArch6485-NEXT:    [[TMP3:%.*]] = zext i1 [[TMP2]] to i32 | 
|  | // AArch6485-NEXT:    ret i32 [[TMP3]] | 
|  | // | 
|  | int test_rndrrs(uint64_t *__addr) { | 
|  | return __rndrrs(__addr); | 
|  | } | 
|  | #endif | 
|  |  | 
|  |  |