brintos

brintos / llvm-project-archived public Read only

0
0
Text · 49.1 KiB · 7b94743 Raw
1560 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple armv8a-none-none-eabihf -mattr=fullfp16 -asm-verbose=false < %s | FileCheck %s3 4define void @test_fadd(ptr %p, ptr %q) {5; CHECK-LABEL: test_fadd:6; CHECK:         vldr.16 s0, [r1]7; CHECK-NEXT:    vldr.16 s2, [r0]8; CHECK-NEXT:    vadd.f16 s0, s2, s09; CHECK-NEXT:    vstr.16 s0, [r0]10; CHECK-NEXT:    bx lr11  %a = load half, ptr %p, align 212  %b = load half, ptr %q, align 213  %r = fadd half %a, %b14  store half %r, ptr %p15  ret void16}17 18define void @test_fsub(ptr %p, ptr %q) {19; CHECK-LABEL: test_fsub:20; CHECK:         vldr.16 s0, [r1]21; CHECK-NEXT:    vldr.16 s2, [r0]22; CHECK-NEXT:    vsub.f16 s0, s2, s023; CHECK-NEXT:    vstr.16 s0, [r0]24; CHECK-NEXT:    bx lr25  %a = load half, ptr %p, align 226  %b = load half, ptr %q, align 227  %r = fsub half %a, %b28  store half %r, ptr %p29  ret void30}31 32define void @test_fmul(ptr %p, ptr %q) {33; CHECK-LABEL: test_fmul:34; CHECK:         vldr.16 s0, [r1]35; CHECK-NEXT:    vldr.16 s2, [r0]36; CHECK-NEXT:    vmul.f16 s0, s2, s037; CHECK-NEXT:    vstr.16 s0, [r0]38; CHECK-NEXT:    bx lr39  %a = load half, ptr %p, align 240  %b = load half, ptr %q, align 241  %r = fmul half %a, %b42  store half %r, ptr %p43  ret void44}45 46define void @test_fdiv(ptr %p, ptr %q) {47; CHECK-LABEL: test_fdiv:48; CHECK:         vldr.16 s0, [r1]49; CHECK-NEXT:    vldr.16 s2, [r0]50; CHECK-NEXT:    vdiv.f16 s0, s2, s051; CHECK-NEXT:    vstr.16 s0, [r0]52; CHECK-NEXT:    bx lr53  %a = load half, ptr %p, align 254  %b = load half, ptr %q, align 255  %r = fdiv half %a, %b56  store half %r, ptr %p57  ret void58}59 60define arm_aapcs_vfpcc void @test_frem(ptr %p, ptr %q) {61; CHECK-LABEL: test_frem:62; CHECK:         .save {r4, lr}63; CHECK-NEXT:    push {r4, lr}64; CHECK-NEXT:    vldr.16 s0, [r0]65; CHECK-NEXT:    vldr.16 s2, [r1]66; CHECK-NEXT:    mov r4, r067; CHECK-NEXT:    vcvtb.f32.f16 s0, s068; CHECK-NEXT:    vcvtb.f32.f16 s1, s269; CHECK-NEXT:    bl fmodf70; CHECK-NEXT:    vcvtb.f16.f32 s0, s071; CHECK-NEXT:    vstr.16 s0, [r4]72; CHECK-NEXT:    pop {r4, pc}73  %a = load half, ptr %p, align 274  %b = load half, ptr %q, align 275  %r = frem half %a, %b76  store half %r, ptr %p77  ret void78}79 80define void @test_load_store(ptr %p, ptr %q) {81; CHECK-LABEL: test_load_store:82; CHECK:         vldr.16 s0, [r0]83; CHECK-NEXT:    vstr.16 s0, [r1]84; CHECK-NEXT:    bx lr85  %a = load half, ptr %p, align 286  store half %a, ptr %q87  ret void88}89 90define i32 @test_fptosi_i32(ptr %p) {91; CHECK-LABEL: test_fptosi_i32:92; CHECK:         vldr.16 s0, [r0]93; CHECK-NEXT:    vcvt.s32.f16 s0, s094; CHECK-NEXT:    vmov r0, s095; CHECK-NEXT:    bx lr96  %a = load half, ptr %p, align 297  %r = fptosi half %a to i3298  ret i32 %r99}100 101define i64 @test_fptosi_i64(ptr %p) {102; CHECK-LABEL: test_fptosi_i64:103; CHECK:         .save {r11, lr}104; CHECK-NEXT:    push {r11, lr}105; CHECK-NEXT:    ldrh r0, [r0]106; CHECK-NEXT:    vmov s0, r0107; CHECK-NEXT:    bl __fixhfdi108; CHECK-NEXT:    pop {r11, pc}109  %a = load half, ptr %p, align 2110  %r = fptosi half %a to i64111  ret i64 %r112}113 114define i32 @test_fptoui_i32(ptr %p) {115; CHECK-LABEL: test_fptoui_i32:116; CHECK:         vldr.16 s0, [r0]117; CHECK-NEXT:    vcvt.u32.f16 s0, s0118; CHECK-NEXT:    vmov r0, s0119; CHECK-NEXT:    bx lr120  %a = load half, ptr %p, align 2121  %r = fptoui half %a to i32122  ret i32 %r123}124 125define i64 @test_fptoui_i64(ptr %p) {126; CHECK-LABEL: test_fptoui_i64:127; CHECK:         .save {r11, lr}128; CHECK-NEXT:    push {r11, lr}129; CHECK-NEXT:    ldrh r0, [r0]130; CHECK-NEXT:    vmov s0, r0131; CHECK-NEXT:    bl __fixunshfdi132; CHECK-NEXT:    pop {r11, pc}133  %a = load half, ptr %p, align 2134  %r = fptoui half %a to i64135  ret i64 %r136}137 138define void @test_sitofp_i32(i32 %a, ptr %p) {139; CHECK-LABEL: test_sitofp_i32:140; CHECK:         vmov s0, r0141; CHECK-NEXT:    vcvt.f16.s32 s0, s0142; CHECK-NEXT:    vstr.16 s0, [r1]143; CHECK-NEXT:    bx lr144  %r = sitofp i32 %a to half145  store half %r, ptr %p146  ret void147}148 149define void @test_uitofp_i32(i32 %a, ptr %p) {150; CHECK-LABEL: test_uitofp_i32:151; CHECK:         vmov s0, r0152; CHECK-NEXT:    vcvt.f16.u32 s0, s0153; CHECK-NEXT:    vstr.16 s0, [r1]154; CHECK-NEXT:    bx lr155  %r = uitofp i32 %a to half156  store half %r, ptr %p157  ret void158}159 160define void @test_sitofp_i64(i64 %a, ptr %p) {161; CHECK-LABEL: test_sitofp_i64:162; CHECK:         .save {r4, lr}163; CHECK-NEXT:    push {r4, lr}164; CHECK-NEXT:    mov r4, r2165; CHECK-NEXT:    bl __floatdihf166; CHECK-NEXT:    vstr.16 s0, [r4]167; CHECK-NEXT:    pop {r4, pc}168  %r = sitofp i64 %a to half169  store half %r, ptr %p170  ret void171}172 173define void @test_uitofp_i64(i64 %a, ptr %p) {174; CHECK-LABEL: test_uitofp_i64:175; CHECK:         .save {r4, lr}176; CHECK-NEXT:    push {r4, lr}177; CHECK-NEXT:    mov r4, r2178; CHECK-NEXT:    bl __floatundihf179; CHECK-NEXT:    vstr.16 s0, [r4]180; CHECK-NEXT:    pop {r4, pc}181  %r = uitofp i64 %a to half182  store half %r, ptr %p183  ret void184}185 186define void @test_fptrunc_float(float %f, ptr %p) {187; CHECK-LABEL: test_fptrunc_float:188; CHECK:         vcvtb.f16.f32 s0, s0189; CHECK-NEXT:    vstr.16 s0, [r0]190; CHECK-NEXT:    bx lr191  %a = fptrunc float %f to half192  store half %a, ptr %p193  ret void194}195 196define void @test_fptrunc_double(double %d, ptr %p) {197; CHECK-LABEL: test_fptrunc_double:198; CHECK:         vcvtb.f16.f64 s0, d0199; CHECK-NEXT:    vstr.16 s0, [r0]200; CHECK-NEXT:    bx lr201  %a = fptrunc double %d to half202  store half %a, ptr %p203  ret void204}205 206define float @test_fpextend_float(ptr %p) {207; CHECK-LABEL: test_fpextend_float:208; CHECK:         vldr.16 s0, [r0]209; CHECK-NEXT:    vcvtb.f32.f16 s0, s0210; CHECK-NEXT:    bx lr211  %a = load half, ptr %p, align 2212  %r = fpext half %a to float213  ret float %r214}215 216define double @test_fpextend_double(ptr %p) {217; CHECK-LABEL: test_fpextend_double:218; CHECK:         vldr.16 s0, [r0]219; CHECK-NEXT:    vcvtb.f64.f16 d0, s0220; CHECK-NEXT:    bx lr221  %a = load half, ptr %p, align 2222  %r = fpext half %a to double223  ret double %r224}225 226define i16 @test_bitcast_halftoi16(ptr %p) {227; CHECK-LABEL: test_bitcast_halftoi16:228; CHECK:         ldrh r0, [r0]229; CHECK-NEXT:    bx lr230  %a = load half, ptr %p, align 2231  %r = bitcast half %a to i16232  ret i16 %r233}234 235define void @test_bitcast_i16tohalf(i16 %a, ptr %p) {236; CHECK-LABEL: test_bitcast_i16tohalf:237; CHECK:         strh r0, [r1]238; CHECK-NEXT:    bx lr239  %r = bitcast i16 %a to half240  store half %r, ptr %p241  ret void242}243 244define void @test_sqrt(ptr %p) {245; CHECK-LABEL: test_sqrt:246; CHECK:         vldr.16 s0, [r0]247; CHECK-NEXT:    vsqrt.f16 s0, s0248; CHECK-NEXT:    vstr.16 s0, [r0]249; CHECK-NEXT:    bx lr250  %a = load half, ptr %p, align 2251  %r = call half @llvm.sqrt.f16(half %a)252  store half %r, ptr %p253  ret void254}255 256define void @test_fpowi(ptr %p, i32 %b) {257; CHECK-LABEL: test_fpowi:258; CHECK:         .save {r4, lr}259; CHECK-NEXT:    push {r4, lr}260; CHECK-NEXT:    vldr.16 s0, [r0]261; CHECK-NEXT:    mov r4, r0262; CHECK-NEXT:    mov r0, r1263; CHECK-NEXT:    vcvtb.f32.f16 s0, s0264; CHECK-NEXT:    bl __powisf2265; CHECK-NEXT:    vcvtb.f16.f32 s0, s0266; CHECK-NEXT:    vstr.16 s0, [r4]267; CHECK-NEXT:    pop {r4, pc}268  %a = load half, ptr %p, align 2269  %r = call half @llvm.powi.f16.i32(half %a, i32 %b)270  store half %r, ptr %p271  ret void272}273 274define void @test_sin(ptr %p) {275; CHECK-LABEL: test_sin:276; CHECK:         .save {r4, lr}277; CHECK-NEXT:    push {r4, lr}278; CHECK-NEXT:    vldr.16 s0, [r0]279; CHECK-NEXT:    mov r4, r0280; CHECK-NEXT:    vcvtb.f32.f16 s0, s0281; CHECK-NEXT:    bl sinf282; CHECK-NEXT:    vcvtb.f16.f32 s0, s0283; CHECK-NEXT:    vstr.16 s0, [r4]284; CHECK-NEXT:    pop {r4, pc}285  %a = load half, ptr %p, align 2286  %r = call half @llvm.sin.f16(half %a)287  store half %r, ptr %p288  ret void289}290 291define void @test_cos(ptr %p) {292; CHECK-LABEL: test_cos:293; CHECK:         .save {r4, lr}294; CHECK-NEXT:    push {r4, lr}295; CHECK-NEXT:    vldr.16 s0, [r0]296; CHECK-NEXT:    mov r4, r0297; CHECK-NEXT:    vcvtb.f32.f16 s0, s0298; CHECK-NEXT:    bl cosf299; CHECK-NEXT:    vcvtb.f16.f32 s0, s0300; CHECK-NEXT:    vstr.16 s0, [r4]301; CHECK-NEXT:    pop {r4, pc}302  %a = load half, ptr %p, align 2303  %r = call half @llvm.cos.f16(half %a)304  store half %r, ptr %p305  ret void306}307 308define void @test_tan(ptr %p) {309; CHECK-LABEL: test_tan:310; CHECK:         .save {r4, lr}311; CHECK-NEXT:    push {r4, lr}312; CHECK-NEXT:    vldr.16 s0, [r0]313; CHECK-NEXT:    mov r4, r0314; CHECK-NEXT:    vcvtb.f32.f16 s0, s0315; CHECK-NEXT:    bl tanf316; CHECK-NEXT:    vcvtb.f16.f32 s0, s0317; CHECK-NEXT:    vstr.16 s0, [r4]318; CHECK-NEXT:    pop {r4, pc}319  %a = load half, ptr %p, align 2320  %r = call half @llvm.tan.f16(half %a)321  store half %r, ptr %p322  ret void323}324 325define void @test_pow(ptr %p, ptr %q) {326; CHECK-LABEL: test_pow:327; CHECK:         .save {r4, lr}328; CHECK-NEXT:    push {r4, lr}329; CHECK-NEXT:    vldr.16 s0, [r0]330; CHECK-NEXT:    vldr.16 s2, [r1]331; CHECK-NEXT:    mov r4, r0332; CHECK-NEXT:    vcvtb.f32.f16 s0, s0333; CHECK-NEXT:    vcvtb.f32.f16 s1, s2334; CHECK-NEXT:    bl powf335; CHECK-NEXT:    vcvtb.f16.f32 s0, s0336; CHECK-NEXT:    vstr.16 s0, [r4]337; CHECK-NEXT:    pop {r4, pc}338  %a = load half, ptr %p, align 2339  %b = load half, ptr %q, align 2340  %r = call half @llvm.pow.f16(half %a, half %b)341  store half %r, ptr %p342  ret void343}344 345define void @test_exp(ptr %p) {346; CHECK-LABEL: test_exp:347; CHECK:         .save {r4, lr}348; CHECK-NEXT:    push {r4, lr}349; CHECK-NEXT:    vldr.16 s0, [r0]350; CHECK-NEXT:    mov r4, r0351; CHECK-NEXT:    vcvtb.f32.f16 s0, s0352; CHECK-NEXT:    bl expf353; CHECK-NEXT:    vcvtb.f16.f32 s0, s0354; CHECK-NEXT:    vstr.16 s0, [r4]355; CHECK-NEXT:    pop {r4, pc}356  %a = load half, ptr %p, align 2357  %r = call half @llvm.exp.f16(half %a)358  store half %r, ptr %p359  ret void360}361 362define void @test_exp2(ptr %p) {363; CHECK-LABEL: test_exp2:364; CHECK:         .save {r4, lr}365; CHECK-NEXT:    push {r4, lr}366; CHECK-NEXT:    vldr.16 s0, [r0]367; CHECK-NEXT:    mov r4, r0368; CHECK-NEXT:    vcvtb.f32.f16 s0, s0369; CHECK-NEXT:    bl exp2f370; CHECK-NEXT:    vcvtb.f16.f32 s0, s0371; CHECK-NEXT:    vstr.16 s0, [r4]372; CHECK-NEXT:    pop {r4, pc}373  %a = load half, ptr %p, align 2374  %r = call half @llvm.exp2.f16(half %a)375  store half %r, ptr %p376  ret void377}378 379define void @test_log(ptr %p) {380; CHECK-LABEL: test_log:381; CHECK:         .save {r4, lr}382; CHECK-NEXT:    push {r4, lr}383; CHECK-NEXT:    vldr.16 s0, [r0]384; CHECK-NEXT:    mov r4, r0385; CHECK-NEXT:    vcvtb.f32.f16 s0, s0386; CHECK-NEXT:    bl logf387; CHECK-NEXT:    vcvtb.f16.f32 s0, s0388; CHECK-NEXT:    vstr.16 s0, [r4]389; CHECK-NEXT:    pop {r4, pc}390  %a = load half, ptr %p, align 2391  %r = call half @llvm.log.f16(half %a)392  store half %r, ptr %p393  ret void394}395 396define void @test_log10(ptr %p) {397; CHECK-LABEL: test_log10:398; CHECK:         .save {r4, lr}399; CHECK-NEXT:    push {r4, lr}400; CHECK-NEXT:    vldr.16 s0, [r0]401; CHECK-NEXT:    mov r4, r0402; CHECK-NEXT:    vcvtb.f32.f16 s0, s0403; CHECK-NEXT:    bl log10f404; CHECK-NEXT:    vcvtb.f16.f32 s0, s0405; CHECK-NEXT:    vstr.16 s0, [r4]406; CHECK-NEXT:    pop {r4, pc}407  %a = load half, ptr %p, align 2408  %r = call half @llvm.log10.f16(half %a)409  store half %r, ptr %p410  ret void411}412 413define void @test_log2(ptr %p) {414; CHECK-LABEL: test_log2:415; CHECK:         .save {r4, lr}416; CHECK-NEXT:    push {r4, lr}417; CHECK-NEXT:    vldr.16 s0, [r0]418; CHECK-NEXT:    mov r4, r0419; CHECK-NEXT:    vcvtb.f32.f16 s0, s0420; CHECK-NEXT:    bl log2f421; CHECK-NEXT:    vcvtb.f16.f32 s0, s0422; CHECK-NEXT:    vstr.16 s0, [r4]423; CHECK-NEXT:    pop {r4, pc}424  %a = load half, ptr %p, align 2425  %r = call half @llvm.log2.f16(half %a)426  store half %r, ptr %p427  ret void428}429 430define void @test_fma(ptr %p, ptr %q, ptr %r) {431; CHECK-LABEL: test_fma:432; CHECK:         vldr.16 s0, [r1]433; CHECK-NEXT:    vldr.16 s2, [r0]434; CHECK-NEXT:    vldr.16 s4, [r2]435; CHECK-NEXT:    vfma.f16 s4, s2, s0436; CHECK-NEXT:    vstr.16 s4, [r0]437; CHECK-NEXT:    bx lr438  %a = load half, ptr %p, align 2439  %b = load half, ptr %q, align 2440  %c = load half, ptr %r, align 2441  %v = call half @llvm.fma.f16(half %a, half %b, half %c)442  store half %v, ptr %p443  ret void444}445 446define void @test_fabs(ptr %p) {447; CHECK-LABEL: test_fabs:448; CHECK:         vldr.16 s0, [r0]449; CHECK-NEXT:    vabs.f16 s0, s0450; CHECK-NEXT:    vstr.16 s0, [r0]451; CHECK-NEXT:    bx lr452  %a = load half, ptr %p, align 2453  %r = call half @llvm.fabs.f16(half %a)454  store half %r, ptr %p455  ret void456}457 458define void @test_minnum(ptr %p, ptr %q) {459; CHECK-LABEL: test_minnum:460; CHECK:         vldr.16 s0, [r1]461; CHECK-NEXT:    vldr.16 s2, [r0]462; CHECK-NEXT:    vminnm.f16 s0, s2, s0463; CHECK-NEXT:    vstr.16 s0, [r0]464; CHECK-NEXT:    bx lr465  %a = load half, ptr %p, align 2466  %b = load half, ptr %q, align 2467  %r = call half @llvm.minnum.f16(half %a, half %b)468  store half %r, ptr %p469  ret void470}471 472define void @test_maxnum(ptr %p, ptr %q) {473; CHECK-LABEL: test_maxnum:474; CHECK:         vldr.16 s0, [r1]475; CHECK-NEXT:    vldr.16 s2, [r0]476; CHECK-NEXT:    vmaxnm.f16 s0, s2, s0477; CHECK-NEXT:    vstr.16 s0, [r0]478; CHECK-NEXT:    bx lr479  %a = load half, ptr %p, align 2480  %b = load half, ptr %q, align 2481  %r = call half @llvm.maxnum.f16(half %a, half %b)482  store half %r, ptr %p483  ret void484}485 486define void @test_minimum(ptr %p) {487; CHECK-LABEL: test_minimum:488; CHECK:         vldr.16 s2, [r0]489; CHECK-NEXT:    vmov.f16 s0, #1.000000e+00490; CHECK-NEXT:    vcmp.f16 s2, s0491; CHECK-NEXT:    vmrs APSR_nzcv, fpscr492; CHECK-NEXT:    vselge.f16 s0, s0, s2493; CHECK-NEXT:    vstr.16 s0, [r0]494; CHECK-NEXT:    bx lr495  %a = load half, ptr %p, align 2496  %c = fcmp ult half %a, 1.0497  %r = select i1 %c, half %a, half 1.0498  store half %r, ptr %p499  ret void500}501 502define void @test_maximum(ptr %p) {503; CHECK-LABEL: test_maximum:504; CHECK:         vldr.16 s2, [r0]505; CHECK-NEXT:    vmov.f16 s0, #1.000000e+00506; CHECK-NEXT:    vcmp.f16 s0, s2507; CHECK-NEXT:    vmrs APSR_nzcv, fpscr508; CHECK-NEXT:    vselge.f16 s0, s0, s2509; CHECK-NEXT:    vstr.16 s0, [r0]510; CHECK-NEXT:    bx lr511  %a = load half, ptr %p, align 2512  %c = fcmp ugt half %a, 1.0513  %r = select i1 %c, half %a, half 1.0514  store half %r, ptr %p515  ret void516}517 518define void @test_copysign(ptr %p, ptr %q) {519; CHECK-LABEL: test_copysign:520; CHECK:         .pad #4521; CHECK-NEXT:    sub sp, sp, #4522; CHECK-NEXT:    vldr.16 s0, [r1]523; CHECK-NEXT:    vstr.16 s0, [sp]524; CHECK-NEXT:    vldr.16 s0, [r0]525; CHECK-NEXT:    ldrb r1, [sp, #1]526; CHECK-NEXT:    vabs.f16 s0, s0527; CHECK-NEXT:    tst r1, #128528; CHECK-NEXT:    vneg.f16 s2, s0529; CHECK-NEXT:    vseleq.f16 s0, s0, s2530; CHECK-NEXT:    vstr.16 s0, [r0]531; CHECK-NEXT:    add sp, sp, #4532; CHECK-NEXT:    bx lr533  %a = load half, ptr %p, align 2534  %b = load half, ptr %q, align 2535  %r = call half @llvm.copysign.f16(half %a, half %b)536  store half %r, ptr %p537  ret void538}539 540define void @test_floor(ptr %p) {541; CHECK-LABEL: test_floor:542; CHECK:         vldr.16 s0, [r0]543; CHECK-NEXT:    vrintm.f16 s0, s0544; CHECK-NEXT:    vstr.16 s0, [r0]545; CHECK-NEXT:    bx lr546  %a = load half, ptr %p, align 2547  %r = call half @llvm.floor.f16(half %a)548  store half %r, ptr %p549  ret void550}551 552define void @test_ceil(ptr %p) {553; CHECK-LABEL: test_ceil:554; CHECK:         vldr.16 s0, [r0]555; CHECK-NEXT:    vrintp.f16 s0, s0556; CHECK-NEXT:    vstr.16 s0, [r0]557; CHECK-NEXT:    bx lr558  %a = load half, ptr %p, align 2559  %r = call half @llvm.ceil.f16(half %a)560  store half %r, ptr %p561  ret void562}563 564define void @test_trunc(ptr %p) {565; CHECK-LABEL: test_trunc:566; CHECK:         vldr.16 s0, [r0]567; CHECK-NEXT:    vrintz.f16 s0, s0568; CHECK-NEXT:    vstr.16 s0, [r0]569; CHECK-NEXT:    bx lr570  %a = load half, ptr %p, align 2571  %r = call half @llvm.trunc.f16(half %a)572  store half %r, ptr %p573  ret void574}575 576define void @test_rint(ptr %p) {577; CHECK-LABEL: test_rint:578; CHECK:         vldr.16 s0, [r0]579; CHECK-NEXT:    vrintx.f16 s0, s0580; CHECK-NEXT:    vstr.16 s0, [r0]581; CHECK-NEXT:    bx lr582  %a = load half, ptr %p, align 2583  %r = call half @llvm.rint.f16(half %a)584  store half %r, ptr %p585  ret void586}587 588define void @test_nearbyint(ptr %p) {589; CHECK-LABEL: test_nearbyint:590; CHECK:         vldr.16 s0, [r0]591; CHECK-NEXT:    vrintr.f16 s0, s0592; CHECK-NEXT:    vstr.16 s0, [r0]593; CHECK-NEXT:    bx lr594  %a = load half, ptr %p, align 2595  %r = call half @llvm.nearbyint.f16(half %a)596  store half %r, ptr %p597  ret void598}599 600define void @test_round(ptr %p) {601; CHECK-LABEL: test_round:602; CHECK:         vldr.16 s0, [r0]603; CHECK-NEXT:    vrinta.f16 s0, s0604; CHECK-NEXT:    vstr.16 s0, [r0]605; CHECK-NEXT:    bx lr606  %a = load half, ptr %p, align 2607  %r = call half @llvm.round.f16(half %a)608  store half %r, ptr %p609  ret void610}611 612define void @test_roundeven(ptr %p) {613; CHECK-LABEL: test_roundeven:614; CHECK:         vldr.16 s0, [r0]615; CHECK-NEXT:    vrintn.f16 s0, s0616; CHECK-NEXT:    vstr.16 s0, [r0]617; CHECK-NEXT:    bx lr618  %a = load half, ptr %p, align 2619  %r = call half @llvm.roundeven.f16(half %a)620  store half %r, ptr %p621  ret void622}623 624define void @test_fmuladd(ptr %p, ptr %q, ptr %r) {625; CHECK-LABEL: test_fmuladd:626; CHECK:         vldr.16 s0, [r1]627; CHECK-NEXT:    vldr.16 s2, [r0]628; CHECK-NEXT:    vldr.16 s4, [r2]629; CHECK-NEXT:    vfma.f16 s4, s2, s0630; CHECK-NEXT:    vstr.16 s4, [r0]631; CHECK-NEXT:    bx lr632  %a = load half, ptr %p, align 2633  %b = load half, ptr %q, align 2634  %c = load half, ptr %r, align 2635  %v = call half @llvm.fmuladd.f16(half %a, half %b, half %c)636  store half %v, ptr %p637  ret void638}639 640; Half-precision intrinsics641 642define half @add_f16(half %x, half %y) #0 {643; CHECK-LABEL: add_f16:644; CHECK:         vadd.f16 s0, s0, s1645; CHECK-NEXT:    bx lr646  %val = call half @llvm.experimental.constrained.fadd.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0647  ret half %val648}649 650define half @sub_f16(half %x, half %y) #0 {651; CHECK-LABEL: sub_f16:652; CHECK:         vsub.f16 s0, s0, s1653; CHECK-NEXT:    bx lr654  %val = call half @llvm.experimental.constrained.fsub.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0655  ret half %val656}657 658define half @mul_f16(half %x, half %y) #0 {659; CHECK-LABEL: mul_f16:660; CHECK:         vmul.f16 s0, s0, s1661; CHECK-NEXT:    bx lr662  %val = call half @llvm.experimental.constrained.fmul.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0663  ret half %val664}665 666define half @div_f16(half %x, half %y) #0 {667; CHECK-LABEL: div_f16:668; CHECK:         vdiv.f16 s0, s0, s1669; CHECK-NEXT:    bx lr670  %val = call half @llvm.experimental.constrained.fdiv.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0671  ret half %val672}673 674define half @frem_f16(half %x, half %y) #0 {675; CHECK-LABEL: frem_f16:676; CHECK:         .save {r11, lr}677; CHECK-NEXT:    push {r11, lr}678; CHECK-NEXT:    vcvtb.f32.f16 s1, s1679; CHECK-NEXT:    vcvtb.f32.f16 s0, s0680; CHECK-NEXT:    bl fmodf681; CHECK-NEXT:    vcvtb.f16.f32 s0, s0682; CHECK-NEXT:    pop {r11, pc}683  %val = call half @llvm.experimental.constrained.frem.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0684  ret half %val685}686 687define half @fma_f16(half %x, half %y, half %z) #0 {688; CHECK-LABEL: fma_f16:689; CHECK:         vfma.f16 s2, s0, s1690; CHECK-NEXT:    vmov.f32 s0, s2691; CHECK-NEXT:    bx lr692  %val = call half @llvm.experimental.constrained.fma.f16(half %x, half %y, half %z, metadata !"round.tonearest", metadata !"fpexcept.strict") #0693  ret half %val694}695 696define half @fmuladd_f16(half %x, half %y, half %z) #0 {697; CHECK-LABEL: fmuladd_f16:698; CHECK:         vfma.f16 s2, s0, s1699; CHECK-NEXT:    vmov.f32 s0, s2700; CHECK-NEXT:    bx lr701  %val = call half @llvm.experimental.constrained.fmuladd.f16(half %x, half %y, half %z, metadata !"round.tonearest", metadata !"fpexcept.strict") #0702  ret half %val703}704 705define i32 @fptosi_i32_f16(half %x) #0 {706; CHECK-LABEL: fptosi_i32_f16:707; CHECK:         vcvt.s32.f16 s0, s0708; CHECK-NEXT:    vmov r0, s0709; CHECK-NEXT:    bx lr710  %val = call i32 @llvm.experimental.constrained.fptosi.i32.f16(half %x, metadata !"fpexcept.strict") #0711  ret i32 %val712}713 714define i32 @fptoui_i32_f16(half %x) #0 {715; CHECK-LABEL: fptoui_i32_f16:716; CHECK:         vcvt.u32.f16 s0, s0717; CHECK-NEXT:    vmov r0, s0718; CHECK-NEXT:    bx lr719  %val = call i32 @llvm.experimental.constrained.fptoui.i32.f16(half %x, metadata !"fpexcept.strict") #0720  ret i32 %val721}722 723define i64 @fptosi_i64_f16(half %x) #0 {724; CHECK-LABEL: fptosi_i64_f16:725; CHECK:         .save {r11, lr}726; CHECK-NEXT:    push {r11, lr}727; CHECK-NEXT:    vmov.f16 r0, s0728; CHECK-NEXT:    vmov s0, r0729; CHECK-NEXT:    bl __fixhfdi730; CHECK-NEXT:    pop {r11, pc}731  %val = call i64 @llvm.experimental.constrained.fptosi.i64.f16(half %x, metadata !"fpexcept.strict") #0732  ret i64 %val733}734 735define i64 @fptoui_i64_f16(half %x) #0 {736; CHECK-LABEL: fptoui_i64_f16:737; CHECK:         .save {r11, lr}738; CHECK-NEXT:    push {r11, lr}739; CHECK-NEXT:    vmov.f16 r0, s0740; CHECK-NEXT:    vmov s0, r0741; CHECK-NEXT:    bl __fixunshfdi742; CHECK-NEXT:    pop {r11, pc}743  %val = call i64 @llvm.experimental.constrained.fptoui.i64.f16(half %x, metadata !"fpexcept.strict") #0744  ret i64 %val745}746 747define half @sitofp_f16_i32(i32 %x) #0 {748; CHECK-LABEL: sitofp_f16_i32:749; CHECK:         .pad #8750; CHECK-NEXT:    sub sp, sp, #8751; CHECK-NEXT:    movw r1, #0752; CHECK-NEXT:    eor r0, r0, #-2147483648753; CHECK-NEXT:    movt r1, #17200754; CHECK-NEXT:    str r0, [sp]755; CHECK-NEXT:    str r1, [sp, #4]756; CHECK-NEXT:    vldr d16, .LCPI57_0757; CHECK-NEXT:    vldr d17, [sp]758; CHECK-NEXT:    vsub.f64 d16, d17, d16759; CHECK-NEXT:    vcvtb.f16.f64 s0, d16760; CHECK-NEXT:    add sp, sp, #8761; CHECK-NEXT:    bx lr762; CHECK-NEXT:    .p2align 3763; CHECK-NEXT:  .LCPI57_0:764; CHECK-NEXT:    .long 2147483648765; CHECK-NEXT:    .long 1127219200766  %val = call half @llvm.experimental.constrained.sitofp.f16.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0767  ret half %val768}769 770define half @uitofp_f16_i32(i32 %x) #0 {771; CHECK-LABEL: uitofp_f16_i32:772; CHECK:         .pad #8773; CHECK-NEXT:    sub sp, sp, #8774; CHECK-NEXT:    movw r1, #0775; CHECK-NEXT:    str r0, [sp]776; CHECK-NEXT:    movt r1, #17200777; CHECK-NEXT:    vldr d16, .LCPI58_0778; CHECK-NEXT:    str r1, [sp, #4]779; CHECK-NEXT:    vldr d17, [sp]780; CHECK-NEXT:    vsub.f64 d16, d17, d16781; CHECK-NEXT:    vcvtb.f16.f64 s0, d16782; CHECK-NEXT:    add sp, sp, #8783; CHECK-NEXT:    bx lr784; CHECK-NEXT:    .p2align 3785; CHECK-NEXT:  .LCPI58_0:786; CHECK-NEXT:    .long 0787; CHECK-NEXT:    .long 1127219200788  %val = call half @llvm.experimental.constrained.uitofp.f16.i32(i32 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0789  ret half %val790}791 792define half @sitofp_f16_i64(i64 %x) #0 {793; CHECK-LABEL: sitofp_f16_i64:794; CHECK:         .save {r11, lr}795; CHECK-NEXT:    push {r11, lr}796; CHECK-NEXT:    bl __floatdihf797; CHECK-NEXT:    pop {r11, pc}798  %val = call half @llvm.experimental.constrained.sitofp.f16.i64(i64 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0799  ret half %val800}801 802define half @uitofp_f16_i64(i64 %x) #0 {803; CHECK-LABEL: uitofp_f16_i64:804; CHECK:         .save {r11, lr}805; CHECK-NEXT:    push {r11, lr}806; CHECK-NEXT:    bl __floatundihf807; CHECK-NEXT:    pop {r11, pc}808  %val = call half @llvm.experimental.constrained.uitofp.f16.i64(i64 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0809  ret half %val810}811 812define half @sitofp_f16_i128(i128 %x) #0 {813; CHECK-LABEL: sitofp_f16_i128:814; CHECK:         .save {r11, lr}815; CHECK-NEXT:    push {r11, lr}816; CHECK-NEXT:    bl __floattihf817; CHECK-NEXT:    pop {r11, pc}818  %val = call half @llvm.experimental.constrained.sitofp.f16.i128(i128 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0819  ret half %val820}821 822define half @uitofp_f16_i128(i128 %x) #0 {823; CHECK-LABEL: uitofp_f16_i128:824; CHECK:         .save {r11, lr}825; CHECK-NEXT:    push {r11, lr}826; CHECK-NEXT:    bl __floatuntihf827; CHECK-NEXT:    pop {r11, pc}828  %val = call half @llvm.experimental.constrained.uitofp.f16.i128(i128 %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0829  ret half %val830}831 832define half @sqrt_f16(half %x) #0 {833; CHECK-LABEL: sqrt_f16:834; CHECK:         vsqrt.f16 s0, s0835; CHECK-NEXT:    bx lr836  %val = call half @llvm.experimental.constrained.sqrt.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0837  ret half %val838}839 840define half @powi_f16(half %x, i32 %y) #0 {841; CHECK-LABEL: powi_f16:842; CHECK:         .save {r11, lr}843; CHECK-NEXT:    push {r11, lr}844; CHECK-NEXT:    vcvtb.f32.f16 s0, s0845; CHECK-NEXT:    bl __powisf2846; CHECK-NEXT:    vcvtb.f16.f32 s0, s0847; CHECK-NEXT:    pop {r11, pc}848  %val = call half @llvm.experimental.constrained.powi.f16(half %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0849  ret half %val850}851 852define half @sin_f16(half %x) #0 {853; CHECK-LABEL: sin_f16:854; CHECK:         .save {r11, lr}855; CHECK-NEXT:    push {r11, lr}856; CHECK-NEXT:    vcvtb.f32.f16 s0, s0857; CHECK-NEXT:    bl sinf858; CHECK-NEXT:    vcvtb.f16.f32 s0, s0859; CHECK-NEXT:    pop {r11, pc}860  %val = call half @llvm.experimental.constrained.sin.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0861  ret half %val862}863 864define half @cos_f16(half %x) #0 {865; CHECK-LABEL: cos_f16:866; CHECK:         .save {r11, lr}867; CHECK-NEXT:    push {r11, lr}868; CHECK-NEXT:    vcvtb.f32.f16 s0, s0869; CHECK-NEXT:    bl cosf870; CHECK-NEXT:    vcvtb.f16.f32 s0, s0871; CHECK-NEXT:    pop {r11, pc}872  %val = call half @llvm.experimental.constrained.cos.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0873  ret half %val874}875 876define half @tan_f16(half %x) #0 {877; CHECK-LABEL: tan_f16:878; CHECK:         .save {r11, lr}879; CHECK-NEXT:    push {r11, lr}880; CHECK-NEXT:    vcvtb.f32.f16 s0, s0881; CHECK-NEXT:    bl tanf882; CHECK-NEXT:    vcvtb.f16.f32 s0, s0883; CHECK-NEXT:    pop {r11, pc}884  %val = call half @llvm.experimental.constrained.tan.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0885  ret half %val886}887 888define half @asin_f16(half %x) #0 {889; CHECK-LABEL: asin_f16:890; CHECK:         .save {r11, lr}891; CHECK-NEXT:    push {r11, lr}892; CHECK-NEXT:    vcvtb.f32.f16 s0, s0893; CHECK-NEXT:    bl asinf894; CHECK-NEXT:    vcvtb.f16.f32 s0, s0895; CHECK-NEXT:    pop {r11, pc}896  %val = call half @llvm.experimental.constrained.asin.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0897  ret half %val898}899 900define half @acos_f16(half %x) #0 {901; CHECK-LABEL: acos_f16:902; CHECK:         .save {r11, lr}903; CHECK-NEXT:    push {r11, lr}904; CHECK-NEXT:    vcvtb.f32.f16 s0, s0905; CHECK-NEXT:    bl acosf906; CHECK-NEXT:    vcvtb.f16.f32 s0, s0907; CHECK-NEXT:    pop {r11, pc}908  %val = call half @llvm.experimental.constrained.acos.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0909  ret half %val910}911 912define half @atan_f16(half %x) #0 {913; CHECK-LABEL: atan_f16:914; CHECK:         .save {r11, lr}915; CHECK-NEXT:    push {r11, lr}916; CHECK-NEXT:    vcvtb.f32.f16 s0, s0917; CHECK-NEXT:    bl atanf918; CHECK-NEXT:    vcvtb.f16.f32 s0, s0919; CHECK-NEXT:    pop {r11, pc}920  %val = call half @llvm.experimental.constrained.atan.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0921  ret half %val922}923 924define half @atan2_f16(half %x, half %y) #0 {925; CHECK-LABEL: atan2_f16:926; CHECK:         .save {r11, lr}927; CHECK-NEXT:    push {r11, lr}928; CHECK-NEXT:    vcvtb.f32.f16 s1, s1929; CHECK-NEXT:    vcvtb.f32.f16 s0, s0930; CHECK-NEXT:    bl atan2f931; CHECK-NEXT:    vcvtb.f16.f32 s0, s0932; CHECK-NEXT:    pop {r11, pc}933  %val = call half @llvm.experimental.constrained.atan2.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0934  ret half %val935}936 937define half @sinh_f16(half %x) #0 {938; CHECK-LABEL: sinh_f16:939; CHECK:         .save {r11, lr}940; CHECK-NEXT:    push {r11, lr}941; CHECK-NEXT:    vcvtb.f32.f16 s0, s0942; CHECK-NEXT:    bl sinhf943; CHECK-NEXT:    vcvtb.f16.f32 s0, s0944; CHECK-NEXT:    pop {r11, pc}945  %val = call half @llvm.experimental.constrained.sinh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0946  ret half %val947}948 949define half @cosh_f16(half %x) #0 {950; CHECK-LABEL: cosh_f16:951; CHECK:         .save {r11, lr}952; CHECK-NEXT:    push {r11, lr}953; CHECK-NEXT:    vcvtb.f32.f16 s0, s0954; CHECK-NEXT:    bl coshf955; CHECK-NEXT:    vcvtb.f16.f32 s0, s0956; CHECK-NEXT:    pop {r11, pc}957  %val = call half @llvm.experimental.constrained.cosh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0958  ret half %val959}960 961define half @tanh_f16(half %x) #0 {962; CHECK-LABEL: tanh_f16:963; CHECK:         .save {r11, lr}964; CHECK-NEXT:    push {r11, lr}965; CHECK-NEXT:    vcvtb.f32.f16 s0, s0966; CHECK-NEXT:    bl tanhf967; CHECK-NEXT:    vcvtb.f16.f32 s0, s0968; CHECK-NEXT:    pop {r11, pc}969  %val = call half @llvm.experimental.constrained.tanh.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0970  ret half %val971}972 973define half @pow_f16(half %x, half %y) #0 {974; CHECK-LABEL: pow_f16:975; CHECK:         .save {r11, lr}976; CHECK-NEXT:    push {r11, lr}977; CHECK-NEXT:    vcvtb.f32.f16 s1, s1978; CHECK-NEXT:    vcvtb.f32.f16 s0, s0979; CHECK-NEXT:    bl powf980; CHECK-NEXT:    vcvtb.f16.f32 s0, s0981; CHECK-NEXT:    pop {r11, pc}982  %val = call half @llvm.experimental.constrained.pow.f16(half %x, half %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #0983  ret half %val984}985 986define half @log_f16(half %x) #0 {987; CHECK-LABEL: log_f16:988; CHECK:         .save {r11, lr}989; CHECK-NEXT:    push {r11, lr}990; CHECK-NEXT:    vcvtb.f32.f16 s0, s0991; CHECK-NEXT:    bl logf992; CHECK-NEXT:    vcvtb.f16.f32 s0, s0993; CHECK-NEXT:    pop {r11, pc}994  %val = call half @llvm.experimental.constrained.log.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #0995  ret half %val996}997 998define half @log10_f16(half %x) #0 {999; CHECK-LABEL: log10_f16:1000; CHECK:         .save {r11, lr}1001; CHECK-NEXT:    push {r11, lr}1002; CHECK-NEXT:    vcvtb.f32.f16 s0, s01003; CHECK-NEXT:    bl log10f1004; CHECK-NEXT:    vcvtb.f16.f32 s0, s01005; CHECK-NEXT:    pop {r11, pc}1006  %val = call half @llvm.experimental.constrained.log10.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01007  ret half %val1008}1009 1010define half @log2_f16(half %x) #0 {1011; CHECK-LABEL: log2_f16:1012; CHECK:         .save {r11, lr}1013; CHECK-NEXT:    push {r11, lr}1014; CHECK-NEXT:    vcvtb.f32.f16 s0, s01015; CHECK-NEXT:    bl log2f1016; CHECK-NEXT:    vcvtb.f16.f32 s0, s01017; CHECK-NEXT:    pop {r11, pc}1018  %val = call half @llvm.experimental.constrained.log2.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01019  ret half %val1020}1021 1022define half @exp_f16(half %x) #0 {1023; CHECK-LABEL: exp_f16:1024; CHECK:         .save {r11, lr}1025; CHECK-NEXT:    push {r11, lr}1026; CHECK-NEXT:    vcvtb.f32.f16 s0, s01027; CHECK-NEXT:    bl expf1028; CHECK-NEXT:    vcvtb.f16.f32 s0, s01029; CHECK-NEXT:    pop {r11, pc}1030  %val = call half @llvm.experimental.constrained.exp.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01031  ret half %val1032}1033 1034define half @exp2_f16(half %x) #0 {1035; CHECK-LABEL: exp2_f16:1036; CHECK:         .save {r11, lr}1037; CHECK-NEXT:    push {r11, lr}1038; CHECK-NEXT:    vcvtb.f32.f16 s0, s01039; CHECK-NEXT:    bl exp2f1040; CHECK-NEXT:    vcvtb.f16.f32 s0, s01041; CHECK-NEXT:    pop {r11, pc}1042  %val = call half @llvm.experimental.constrained.exp2.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01043  ret half %val1044}1045 1046define half @rint_f16(half %x) #0 {1047; CHECK-LABEL: rint_f16:1048; CHECK:         vrintx.f16 s0, s01049; CHECK-NEXT:    bx lr1050  %val = call half @llvm.experimental.constrained.rint.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01051  ret half %val1052}1053 1054define half @nearbyint_f16(half %x) #0 {1055; CHECK-LABEL: nearbyint_f16:1056; CHECK:         vrintr.f16 s0, s01057; CHECK-NEXT:    bx lr1058  %val = call half @llvm.experimental.constrained.nearbyint.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01059  ret half %val1060}1061 1062define i32 @lrint_f16(half %x) #0 {1063; CHECK-LABEL: lrint_f16:1064; CHECK:         .save {r11, lr}1065; CHECK-NEXT:    push {r11, lr}1066; CHECK-NEXT:    vcvtb.f32.f16 s0, s01067; CHECK-NEXT:    bl lrintf1068; CHECK-NEXT:    pop {r11, pc}1069  %val = call i32 @llvm.experimental.constrained.lrint.i32.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01070  ret i32 %val1071}1072 1073define i64 @llrint_f16(half %x) #0 {1074; CHECK-LABEL: llrint_f16:1075; CHECK:         .save {r11, lr}1076; CHECK-NEXT:    push {r11, lr}1077; CHECK-NEXT:    vcvtb.f32.f16 s0, s01078; CHECK-NEXT:    bl llrintf1079; CHECK-NEXT:    pop {r11, pc}1080  %val = call i64 @llvm.experimental.constrained.llrint.i64.f16(half %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01081  ret i64 %val1082}1083 1084define half @maxnum_f16(half %x, half %y) #0 {1085; CHECK-LABEL: maxnum_f16:1086; CHECK:         vmaxnm.f16 s0, s0, s11087; CHECK-NEXT:    bx lr1088  %val = call half @llvm.experimental.constrained.maxnum.f16(half %x, half %y, metadata !"fpexcept.strict") #01089  ret half %val1090}1091 1092define half @minnum_f16(half %x, half %y) #0 {1093; CHECK-LABEL: minnum_f16:1094; CHECK:         vminnm.f16 s0, s0, s11095; CHECK-NEXT:    bx lr1096  %val = call half @llvm.experimental.constrained.minnum.f16(half %x, half %y, metadata !"fpexcept.strict") #01097  ret half %val1098}1099 1100define half @ceil_f16(half %x) #0 {1101; CHECK-LABEL: ceil_f16:1102; CHECK:         vrintp.f16 s0, s01103; CHECK-NEXT:    bx lr1104  %val = call half @llvm.experimental.constrained.ceil.f16(half %x, metadata !"fpexcept.strict") #01105  ret half %val1106}1107 1108define half @floor_f16(half %x) #0 {1109; CHECK-LABEL: floor_f16:1110; CHECK:         vrintm.f16 s0, s01111; CHECK-NEXT:    bx lr1112  %val = call half @llvm.experimental.constrained.floor.f16(half %x, metadata !"fpexcept.strict") #01113  ret half %val1114}1115 1116define i32 @lround_f16(half %x) #0 {1117; CHECK-LABEL: lround_f16:1118; CHECK:         .save {r11, lr}1119; CHECK-NEXT:    push {r11, lr}1120; CHECK-NEXT:    vcvtb.f32.f16 s0, s01121; CHECK-NEXT:    bl lroundf1122; CHECK-NEXT:    pop {r11, pc}1123  %val = call i32 @llvm.experimental.constrained.lround.i32.f16(half %x, metadata !"fpexcept.strict") #01124  ret i32 %val1125}1126 1127define i64 @llround_f16(half %x) #0 {1128; CHECK-LABEL: llround_f16:1129; CHECK:         .save {r11, lr}1130; CHECK-NEXT:    push {r11, lr}1131; CHECK-NEXT:    vcvtb.f32.f16 s0, s01132; CHECK-NEXT:    bl llroundf1133; CHECK-NEXT:    pop {r11, pc}1134  %val = call i64 @llvm.experimental.constrained.llround.i64.f16(half %x, metadata !"fpexcept.strict") #01135  ret i64 %val1136}1137 1138define half @round_f16(half %x) #0 {1139; CHECK-LABEL: round_f16:1140; CHECK:         vrinta.f16 s0, s01141; CHECK-NEXT:    bx lr1142  %val = call half @llvm.experimental.constrained.round.f16(half %x, metadata !"fpexcept.strict") #01143  ret half %val1144}1145 1146define half @roundeven_f16(half %x) #0 {1147; CHECK-LABEL: roundeven_f16:1148; CHECK:         vrintn.f16 s0, s01149; CHECK-NEXT:    bx lr1150  %val = call half @llvm.experimental.constrained.roundeven.f16(half %x, metadata !"fpexcept.strict") #01151  ret half %val1152}1153 1154define half @trunc_f16(half %x) #0 {1155; CHECK-LABEL: trunc_f16:1156; CHECK:         vrintz.f16 s0, s01157; CHECK-NEXT:    bx lr1158  %val = call half @llvm.experimental.constrained.trunc.f16(half %x, metadata !"fpexcept.strict") #01159  ret half %val1160}1161 1162define half @ldexp_f16(half %x, i32 %y) #0 {1163; CHECK-LABEL: ldexp_f16:1164; CHECK:         .save {r11, lr}1165; CHECK-NEXT:    push {r11, lr}1166; CHECK-NEXT:    vcvtb.f32.f16 s0, s01167; CHECK-NEXT:    bl ldexpf1168; CHECK-NEXT:    vcvtb.f16.f32 s0, s01169; CHECK-NEXT:    pop {r11, pc}1170  %val = call half @llvm.experimental.constrained.ldexp.f16.i32(half %x, i32 %y, metadata !"round.tonearest", metadata !"fpexcept.strict") #01171  ret half %val1172}1173 1174define i32 @fcmp_olt_f16(half %a, half %b) #0 {1175; CHECK-LABEL: fcmp_olt_f16:1176; CHECK:         vcmp.f16 s0, s11177; CHECK-NEXT:    mov r0, #01178; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1179; CHECK-NEXT:    movwmi r0, #11180; CHECK-NEXT:    bx lr1181  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") #01182  %conv = zext i1 %cmp to i321183  ret i32 %conv1184}1185 1186define i32 @fcmp_ole_f16(half %a, half %b) #0 {1187; CHECK-LABEL: fcmp_ole_f16:1188; CHECK:         vcmp.f16 s0, s11189; CHECK-NEXT:    mov r0, #01190; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1191; CHECK-NEXT:    movwls r0, #11192; CHECK-NEXT:    bx lr1193  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") #01194  %conv = zext i1 %cmp to i321195  ret i32 %conv1196}1197 1198define i32 @fcmp_ogt_f16(half %a, half %b) #0 {1199; CHECK-LABEL: fcmp_ogt_f16:1200; CHECK:         vcmp.f16 s0, s11201; CHECK-NEXT:    mov r0, #01202; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1203; CHECK-NEXT:    movwgt r0, #11204; CHECK-NEXT:    bx lr1205  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict") #01206  %conv = zext i1 %cmp to i321207  ret i32 %conv1208}1209 1210define i32 @fcmp_oge_f16(half %a, half %b) #0 {1211; CHECK-LABEL: fcmp_oge_f16:1212; CHECK:         vcmp.f16 s0, s11213; CHECK-NEXT:    mov r0, #01214; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1215; CHECK-NEXT:    movwge r0, #11216; CHECK-NEXT:    bx lr1217  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict") #01218  %conv = zext i1 %cmp to i321219  ret i32 %conv1220}1221 1222define i32 @fcmp_oeq_f16(half %a, half %b) #0 {1223; CHECK-LABEL: fcmp_oeq_f16:1224; CHECK:         vcmp.f16 s0, s11225; CHECK-NEXT:    mov r0, #01226; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1227; CHECK-NEXT:    movweq r0, #11228; CHECK-NEXT:    bx lr1229  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict") #01230  %conv = zext i1 %cmp to i321231  ret i32 %conv1232}1233 1234define i32 @fcmp_one_f16(half %a, half %b) #0 {1235; CHECK-LABEL: fcmp_one_f16:1236; CHECK:         vcmp.f16 s0, s11237; CHECK-NEXT:    mov r0, #01238; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1239; CHECK-NEXT:    movwmi r0, #11240; CHECK-NEXT:    movwgt r0, #11241; CHECK-NEXT:    bx lr1242  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") #01243  %conv = zext i1 %cmp to i321244  ret i32 %conv1245}1246 1247define i32 @fcmp_ult_f16(half %a, half %b) #0 {1248; CHECK-LABEL: fcmp_ult_f16:1249; CHECK:         vcmp.f16 s0, s11250; CHECK-NEXT:    mov r0, #01251; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1252; CHECK-NEXT:    movwlt r0, #11253; CHECK-NEXT:    bx lr1254  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ult", metadata !"fpexcept.strict") #01255  %conv = zext i1 %cmp to i321256  ret i32 %conv1257}1258 1259define i32 @fcmp_ule_f16(half %a, half %b) #0 {1260; CHECK-LABEL: fcmp_ule_f16:1261; CHECK:         vcmp.f16 s0, s11262; CHECK-NEXT:    mov r0, #01263; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1264; CHECK-NEXT:    movwle r0, #11265; CHECK-NEXT:    bx lr1266  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ule", metadata !"fpexcept.strict") #01267  %conv = zext i1 %cmp to i321268  ret i32 %conv1269}1270 1271define i32 @fcmp_ugt_f16(half %a, half %b) #0 {1272; CHECK-LABEL: fcmp_ugt_f16:1273; CHECK:         vcmp.f16 s0, s11274; CHECK-NEXT:    mov r0, #01275; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1276; CHECK-NEXT:    movwhi r0, #11277; CHECK-NEXT:    bx lr1278  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ugt", metadata !"fpexcept.strict") #01279  %conv = zext i1 %cmp to i321280  ret i32 %conv1281}1282 1283define i32 @fcmp_uge_f16(half %a, half %b) #0 {1284; CHECK-LABEL: fcmp_uge_f16:1285; CHECK:         vcmp.f16 s0, s11286; CHECK-NEXT:    mov r0, #01287; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1288; CHECK-NEXT:    movwpl r0, #11289; CHECK-NEXT:    bx lr1290  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"uge", metadata !"fpexcept.strict") #01291  %conv = zext i1 %cmp to i321292  ret i32 %conv1293}1294 1295define i32 @fcmp_ueq_f16(half %a, half %b) #0 {1296; CHECK-LABEL: fcmp_ueq_f16:1297; CHECK:         vcmp.f16 s0, s11298; CHECK-NEXT:    mov r0, #01299; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1300; CHECK-NEXT:    movweq r0, #11301; CHECK-NEXT:    movwvs r0, #11302; CHECK-NEXT:    bx lr1303  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") #01304  %conv = zext i1 %cmp to i321305  ret i32 %conv1306}1307 1308define i32 @fcmp_une_f16(half %a, half %b) #0 {1309; CHECK-LABEL: fcmp_une_f16:1310; CHECK:         vcmp.f16 s0, s11311; CHECK-NEXT:    mov r0, #01312; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1313; CHECK-NEXT:    movwne r0, #11314; CHECK-NEXT:    bx lr1315  %cmp = call i1 @llvm.experimental.constrained.fcmp.f16(half %a, half %b, metadata !"une", metadata !"fpexcept.strict") #01316  %conv = zext i1 %cmp to i321317  ret i32 %conv1318}1319 1320define i32 @fcmps_olt_f16(half %a, half %b) #0 {1321; CHECK-LABEL: fcmps_olt_f16:1322; CHECK:         vcmpe.f16 s0, s11323; CHECK-NEXT:    mov r0, #01324; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1325; CHECK-NEXT:    movwmi r0, #11326; CHECK-NEXT:    bx lr1327  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"olt", metadata !"fpexcept.strict") #01328  %conv = zext i1 %cmp to i321329  ret i32 %conv1330}1331 1332define i32 @fcmps_ole_f16(half %a, half %b) #0 {1333; CHECK-LABEL: fcmps_ole_f16:1334; CHECK:         vcmpe.f16 s0, s11335; CHECK-NEXT:    mov r0, #01336; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1337; CHECK-NEXT:    movwls r0, #11338; CHECK-NEXT:    bx lr1339  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ole", metadata !"fpexcept.strict") #01340  %conv = zext i1 %cmp to i321341  ret i32 %conv1342}1343 1344define i32 @fcmps_ogt_f16(half %a, half %b) #0 {1345; CHECK-LABEL: fcmps_ogt_f16:1346; CHECK:         vcmpe.f16 s0, s11347; CHECK-NEXT:    mov r0, #01348; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1349; CHECK-NEXT:    movwgt r0, #11350; CHECK-NEXT:    bx lr1351  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ogt", metadata !"fpexcept.strict") #01352  %conv = zext i1 %cmp to i321353  ret i32 %conv1354}1355 1356define i32 @fcmps_oge_f16(half %a, half %b) #0 {1357; CHECK-LABEL: fcmps_oge_f16:1358; CHECK:         vcmpe.f16 s0, s11359; CHECK-NEXT:    mov r0, #01360; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1361; CHECK-NEXT:    movwge r0, #11362; CHECK-NEXT:    bx lr1363  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oge", metadata !"fpexcept.strict") #01364  %conv = zext i1 %cmp to i321365  ret i32 %conv1366}1367 1368define i32 @fcmps_oeq_f16(half %a, half %b) #0 {1369; CHECK-LABEL: fcmps_oeq_f16:1370; CHECK:         vcmpe.f16 s0, s11371; CHECK-NEXT:    mov r0, #01372; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1373; CHECK-NEXT:    movweq r0, #11374; CHECK-NEXT:    bx lr1375  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"oeq", metadata !"fpexcept.strict") #01376  %conv = zext i1 %cmp to i321377  ret i32 %conv1378}1379 1380define i32 @fcmps_one_f16(half %a, half %b) #0 {1381; CHECK-LABEL: fcmps_one_f16:1382; CHECK:         vcmpe.f16 s0, s11383; CHECK-NEXT:    mov r0, #01384; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1385; CHECK-NEXT:    movwmi r0, #11386; CHECK-NEXT:    movwgt r0, #11387; CHECK-NEXT:    bx lr1388  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"one", metadata !"fpexcept.strict") #01389  %conv = zext i1 %cmp to i321390  ret i32 %conv1391}1392 1393define i32 @fcmps_ult_f16(half %a, half %b) #0 {1394; CHECK-LABEL: fcmps_ult_f16:1395; CHECK:         vcmpe.f16 s0, s11396; CHECK-NEXT:    mov r0, #01397; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1398; CHECK-NEXT:    movwlt r0, #11399; CHECK-NEXT:    bx lr1400  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ult", metadata !"fpexcept.strict") #01401  %conv = zext i1 %cmp to i321402  ret i32 %conv1403}1404 1405define i32 @fcmps_ule_f16(half %a, half %b) #0 {1406; CHECK-LABEL: fcmps_ule_f16:1407; CHECK:         vcmpe.f16 s0, s11408; CHECK-NEXT:    mov r0, #01409; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1410; CHECK-NEXT:    movwle r0, #11411; CHECK-NEXT:    bx lr1412  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ule", metadata !"fpexcept.strict") #01413  %conv = zext i1 %cmp to i321414  ret i32 %conv1415}1416 1417define i32 @fcmps_ugt_f16(half %a, half %b) #0 {1418; CHECK-LABEL: fcmps_ugt_f16:1419; CHECK:         vcmpe.f16 s0, s11420; CHECK-NEXT:    mov r0, #01421; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1422; CHECK-NEXT:    movwhi r0, #11423; CHECK-NEXT:    bx lr1424  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ugt", metadata !"fpexcept.strict") #01425  %conv = zext i1 %cmp to i321426  ret i32 %conv1427}1428 1429define i32 @fcmps_uge_f16(half %a, half %b) #0 {1430; CHECK-LABEL: fcmps_uge_f16:1431; CHECK:         vcmpe.f16 s0, s11432; CHECK-NEXT:    mov r0, #01433; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1434; CHECK-NEXT:    movwpl r0, #11435; CHECK-NEXT:    bx lr1436  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"uge", metadata !"fpexcept.strict") #01437  %conv = zext i1 %cmp to i321438  ret i32 %conv1439}1440 1441define i32 @fcmps_ueq_f16(half %a, half %b) #0 {1442; CHECK-LABEL: fcmps_ueq_f16:1443; CHECK:         vcmpe.f16 s0, s11444; CHECK-NEXT:    mov r0, #01445; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1446; CHECK-NEXT:    movweq r0, #11447; CHECK-NEXT:    movwvs r0, #11448; CHECK-NEXT:    bx lr1449  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"ueq", metadata !"fpexcept.strict") #01450  %conv = zext i1 %cmp to i321451  ret i32 %conv1452}1453 1454define i32 @fcmps_une_f16(half %a, half %b) #0 {1455; CHECK-LABEL: fcmps_une_f16:1456; CHECK:         vcmpe.f16 s0, s11457; CHECK-NEXT:    mov r0, #01458; CHECK-NEXT:    vmrs APSR_nzcv, fpscr1459; CHECK-NEXT:    movwne r0, #11460; CHECK-NEXT:    bx lr1461  %cmp = call i1 @llvm.experimental.constrained.fcmps.f16(half %a, half %b, metadata !"une", metadata !"fpexcept.strict") #01462  %conv = zext i1 %cmp to i321463  ret i32 %conv1464}1465 1466 1467; Intrinsics to convert between floating-point types1468 1469define half @fptrunc_f16_f32(float %x) #0 {1470; CHECK-LABEL: fptrunc_f16_f32:1471; CHECK:         vcvtb.f16.f32 s0, s01472; CHECK-NEXT:    bx lr1473  %val = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %x, metadata !"round.tonearest", metadata !"fpexcept.strict") #01474  ret half %val1475}1476 1477define float @fpext_f32_f16(half %x) #0 {1478; CHECK-LABEL: fpext_f32_f16:1479; CHECK:         vcvtb.f32.f16 s0, s01480; CHECK-NEXT:    bx lr1481  %val = call float @llvm.experimental.constrained.fpext.f32.f16(half %x, metadata !"fpexcept.strict") #01482  ret float %val1483}1484 1485 1486attributes #0 = { strictfp }1487 1488declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)1489declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata)1490declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)1491declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata)1492declare half @llvm.experimental.constrained.frem.f16(half, half, metadata, metadata)1493declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata)1494declare half @llvm.experimental.constrained.fmuladd.f16(half, half, half, metadata, metadata)1495declare i32 @llvm.experimental.constrained.fptosi.i32.f16(half, metadata)1496declare i32 @llvm.experimental.constrained.fptoui.i32.f16(half, metadata)1497declare i64 @llvm.experimental.constrained.fptosi.i64.f16(half, metadata)1498declare i64 @llvm.experimental.constrained.fptoui.i64.f16(half, metadata)1499declare half @llvm.experimental.constrained.sitofp.f16.i32(i32, metadata, metadata)1500declare half @llvm.experimental.constrained.uitofp.f16.i32(i32, metadata, metadata)1501declare half @llvm.experimental.constrained.sitofp.f16.i64(i64, metadata, metadata)1502declare half @llvm.experimental.constrained.uitofp.f16.i64(i64, metadata, metadata)1503declare half @llvm.experimental.constrained.sitofp.f16.i128(i128, metadata, metadata)1504declare half @llvm.experimental.constrained.uitofp.f16.i128(i128, metadata, metadata)1505declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata)1506declare half @llvm.experimental.constrained.powi.f16(half, i32, metadata, metadata)1507declare half @llvm.experimental.constrained.sin.f16(half, metadata, metadata)1508declare half @llvm.experimental.constrained.cos.f16(half, metadata, metadata)1509declare half @llvm.experimental.constrained.tan.f16(half, metadata, metadata)1510declare half @llvm.experimental.constrained.pow.f16(half, half, metadata, metadata)1511declare half @llvm.experimental.constrained.log.f16(half, metadata, metadata)1512declare half @llvm.experimental.constrained.log10.f16(half, metadata, metadata)1513declare half @llvm.experimental.constrained.log2.f16(half, metadata, metadata)1514declare half @llvm.experimental.constrained.exp.f16(half, metadata, metadata)1515declare half @llvm.experimental.constrained.exp2.f16(half, metadata, metadata)1516declare half @llvm.experimental.constrained.rint.f16(half, metadata, metadata)1517declare half @llvm.experimental.constrained.nearbyint.f16(half, metadata, metadata)1518declare i32 @llvm.experimental.constrained.lrint.i32.f16(half, metadata, metadata)1519declare i64 @llvm.experimental.constrained.llrint.i64.f16(half, metadata, metadata)1520declare half @llvm.experimental.constrained.maxnum.f16(half, half, metadata)1521declare half @llvm.experimental.constrained.minnum.f16(half, half, metadata)1522declare half @llvm.experimental.constrained.ceil.f16(half, metadata)1523declare half @llvm.experimental.constrained.floor.f16(half, metadata)1524declare i32 @llvm.experimental.constrained.lround.i32.f16(half, metadata)1525declare i64 @llvm.experimental.constrained.llround.i64.f16(half, metadata)1526declare half @llvm.experimental.constrained.round.f16(half, metadata)1527declare half @llvm.experimental.constrained.roundeven.f16(half, metadata)1528declare half @llvm.experimental.constrained.trunc.f16(half, metadata)1529declare i1 @llvm.experimental.constrained.fcmps.f16(half, half, metadata, metadata)1530declare i1 @llvm.experimental.constrained.fcmp.f16(half, half, metadata, metadata)1531 1532declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata)1533declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata)1534 1535 1536declare half @llvm.sqrt.f16(half %a)1537declare half @llvm.powi.f16.i32(half %a, i32 %b)1538declare half @llvm.sin.f16(half %a)1539declare half @llvm.cos.f16(half %a)1540declare half @llvm.tan.f16(half %a)1541declare half @llvm.pow.f16(half %a, half %b)1542declare half @llvm.exp.f16(half %a)1543declare half @llvm.exp2.f16(half %a)1544declare half @llvm.log.f16(half %a)1545declare half @llvm.log10.f16(half %a)1546declare half @llvm.log2.f16(half %a)1547declare half @llvm.fma.f16(half %a, half %b, half %c)1548declare half @llvm.fabs.f16(half %a)1549declare half @llvm.minnum.f16(half %a, half %b)1550declare half @llvm.maxnum.f16(half %a, half %b)1551declare half @llvm.copysign.f16(half %a, half %b)1552declare half @llvm.floor.f16(half %a)1553declare half @llvm.ceil.f16(half %a)1554declare half @llvm.trunc.f16(half %a)1555declare half @llvm.rint.f16(half %a)1556declare half @llvm.nearbyint.f16(half %a)1557declare half @llvm.round.f16(half %a)1558declare half @llvm.roundeven.f16(half %a)1559declare half @llvm.fmuladd.f16(half %a, half %b, half %c)1560