2454 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 52; RUN: llc -asm-verbose=false < %s -mattr=+vfp3,+fp16 | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-VFP,CHECK-FP163; RUN: llc -asm-verbose=false < %s | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-LIBCALL,CHECK-VFP,CHECK-LIBCALL-VFP4; RUN: llc -asm-verbose=false < %s -mattr=-fpregs | FileCheck %s --check-prefixes=CHECK-ALL,CHECK-LIBCALL,CHECK-NOVFP5 6target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32"7target triple = "armv7---eabihf"8 9define void @test_fadd(ptr %p, ptr %q) #0 {10; CHECK-FP16-LABEL: test_fadd:11; CHECK-FP16: ldrh r2, [r0]12; CHECK-FP16-NEXT: ldrh r1, [r1]13; CHECK-FP16-NEXT: vmov s0, r214; CHECK-FP16-NEXT: vmov s2, r115; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s016; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s217; CHECK-FP16-NEXT: vadd.f32 s0, s0, s218; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s019; CHECK-FP16-NEXT: vmov r1, s020; CHECK-FP16-NEXT: strh r1, [r0]21; CHECK-FP16-NEXT: bx lr22;23; CHECK-LIBCALL-VFP-LABEL: test_fadd:24; CHECK-LIBCALL-VFP: .save {r4, lr}25; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}26; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}27; CHECK-LIBCALL-VFP-NEXT: vpush {d8}28; CHECK-LIBCALL-VFP-NEXT: mov r4, r029; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]30; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f31; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]32; CHECK-LIBCALL-VFP-NEXT: vmov s16, r033; CHECK-LIBCALL-VFP-NEXT: mov r0, r134; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f35; CHECK-LIBCALL-VFP-NEXT: vmov s0, r036; CHECK-LIBCALL-VFP-NEXT: vadd.f32 s0, s0, s1637; CHECK-LIBCALL-VFP-NEXT: vmov r0, s038; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h39; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]40; CHECK-LIBCALL-VFP-NEXT: vpop {d8}41; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}42;43; CHECK-NOVFP-LABEL: test_fadd:44; CHECK-NOVFP: .save {r4, r5, r11, lr}45; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}46; CHECK-NOVFP-NEXT: mov r4, r047; CHECK-NOVFP-NEXT: ldrh r0, [r1]48; CHECK-NOVFP-NEXT: bl __aeabi_h2f49; CHECK-NOVFP-NEXT: mov r5, r050; CHECK-NOVFP-NEXT: ldrh r0, [r4]51; CHECK-NOVFP-NEXT: bl __aeabi_h2f52; CHECK-NOVFP-NEXT: mov r1, r553; CHECK-NOVFP-NEXT: bl __aeabi_fadd54; CHECK-NOVFP-NEXT: bl __aeabi_f2h55; CHECK-NOVFP-NEXT: strh r0, [r4]56; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}57 %a = load half, ptr %p, align 258 %b = load half, ptr %q, align 259 %r = fadd half %a, %b60 store half %r, ptr %p61 ret void62}63 64define void @test_fsub(ptr %p, ptr %q) #0 {65; CHECK-FP16-LABEL: test_fsub:66; CHECK-FP16: ldrh r2, [r0]67; CHECK-FP16-NEXT: ldrh r1, [r1]68; CHECK-FP16-NEXT: vmov s0, r269; CHECK-FP16-NEXT: vmov s2, r170; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s071; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s272; CHECK-FP16-NEXT: vsub.f32 s0, s0, s273; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s074; CHECK-FP16-NEXT: vmov r1, s075; CHECK-FP16-NEXT: strh r1, [r0]76; CHECK-FP16-NEXT: bx lr77;78; CHECK-LIBCALL-VFP-LABEL: test_fsub:79; CHECK-LIBCALL-VFP: .save {r4, lr}80; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}81; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}82; CHECK-LIBCALL-VFP-NEXT: vpush {d8}83; CHECK-LIBCALL-VFP-NEXT: mov r4, r084; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]85; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f86; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]87; CHECK-LIBCALL-VFP-NEXT: vmov s16, r088; CHECK-LIBCALL-VFP-NEXT: mov r0, r189; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f90; CHECK-LIBCALL-VFP-NEXT: vmov s0, r091; CHECK-LIBCALL-VFP-NEXT: vsub.f32 s0, s0, s1692; CHECK-LIBCALL-VFP-NEXT: vmov r0, s093; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h94; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]95; CHECK-LIBCALL-VFP-NEXT: vpop {d8}96; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}97;98; CHECK-NOVFP-LABEL: test_fsub:99; CHECK-NOVFP: .save {r4, r5, r11, lr}100; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}101; CHECK-NOVFP-NEXT: mov r4, r0102; CHECK-NOVFP-NEXT: ldrh r0, [r1]103; CHECK-NOVFP-NEXT: bl __aeabi_h2f104; CHECK-NOVFP-NEXT: mov r5, r0105; CHECK-NOVFP-NEXT: ldrh r0, [r4]106; CHECK-NOVFP-NEXT: bl __aeabi_h2f107; CHECK-NOVFP-NEXT: mov r1, r5108; CHECK-NOVFP-NEXT: bl __aeabi_fsub109; CHECK-NOVFP-NEXT: bl __aeabi_f2h110; CHECK-NOVFP-NEXT: strh r0, [r4]111; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}112 %a = load half, ptr %p, align 2113 %b = load half, ptr %q, align 2114 %r = fsub half %a, %b115 store half %r, ptr %p116 ret void117}118 119define void @test_fmul(ptr %p, ptr %q) #0 {120; CHECK-FP16-LABEL: test_fmul:121; CHECK-FP16: ldrh r2, [r0]122; CHECK-FP16-NEXT: ldrh r1, [r1]123; CHECK-FP16-NEXT: vmov s0, r2124; CHECK-FP16-NEXT: vmov s2, r1125; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0126; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s2127; CHECK-FP16-NEXT: vmul.f32 s0, s0, s2128; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0129; CHECK-FP16-NEXT: vmov r1, s0130; CHECK-FP16-NEXT: strh r1, [r0]131; CHECK-FP16-NEXT: bx lr132;133; CHECK-LIBCALL-VFP-LABEL: test_fmul:134; CHECK-LIBCALL-VFP: .save {r4, lr}135; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}136; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}137; CHECK-LIBCALL-VFP-NEXT: vpush {d8}138; CHECK-LIBCALL-VFP-NEXT: mov r4, r0139; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]140; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f141; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]142; CHECK-LIBCALL-VFP-NEXT: vmov s16, r0143; CHECK-LIBCALL-VFP-NEXT: mov r0, r1144; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f145; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0146; CHECK-LIBCALL-VFP-NEXT: vmul.f32 s0, s0, s16147; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0148; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h149; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]150; CHECK-LIBCALL-VFP-NEXT: vpop {d8}151; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}152;153; CHECK-NOVFP-LABEL: test_fmul:154; CHECK-NOVFP: .save {r4, r5, r11, lr}155; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}156; CHECK-NOVFP-NEXT: mov r4, r0157; CHECK-NOVFP-NEXT: ldrh r0, [r1]158; CHECK-NOVFP-NEXT: bl __aeabi_h2f159; CHECK-NOVFP-NEXT: mov r5, r0160; CHECK-NOVFP-NEXT: ldrh r0, [r4]161; CHECK-NOVFP-NEXT: bl __aeabi_h2f162; CHECK-NOVFP-NEXT: mov r1, r5163; CHECK-NOVFP-NEXT: bl __aeabi_fmul164; CHECK-NOVFP-NEXT: bl __aeabi_f2h165; CHECK-NOVFP-NEXT: strh r0, [r4]166; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}167 %a = load half, ptr %p, align 2168 %b = load half, ptr %q, align 2169 %r = fmul half %a, %b170 store half %r, ptr %p171 ret void172}173 174define void @test_fdiv(ptr %p, ptr %q) #0 {175; CHECK-FP16-LABEL: test_fdiv:176; CHECK-FP16: ldrh r2, [r0]177; CHECK-FP16-NEXT: ldrh r1, [r1]178; CHECK-FP16-NEXT: vmov s0, r2179; CHECK-FP16-NEXT: vmov s2, r1180; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0181; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s2182; CHECK-FP16-NEXT: vdiv.f32 s0, s0, s2183; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0184; CHECK-FP16-NEXT: vmov r1, s0185; CHECK-FP16-NEXT: strh r1, [r0]186; CHECK-FP16-NEXT: bx lr187;188; CHECK-LIBCALL-VFP-LABEL: test_fdiv:189; CHECK-LIBCALL-VFP: .save {r4, lr}190; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}191; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}192; CHECK-LIBCALL-VFP-NEXT: vpush {d8}193; CHECK-LIBCALL-VFP-NEXT: mov r4, r0194; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]195; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f196; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]197; CHECK-LIBCALL-VFP-NEXT: vmov s16, r0198; CHECK-LIBCALL-VFP-NEXT: mov r0, r1199; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f200; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0201; CHECK-LIBCALL-VFP-NEXT: vdiv.f32 s0, s0, s16202; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0203; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h204; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]205; CHECK-LIBCALL-VFP-NEXT: vpop {d8}206; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}207;208; CHECK-NOVFP-LABEL: test_fdiv:209; CHECK-NOVFP: .save {r4, r5, r11, lr}210; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}211; CHECK-NOVFP-NEXT: mov r4, r0212; CHECK-NOVFP-NEXT: ldrh r0, [r1]213; CHECK-NOVFP-NEXT: bl __aeabi_h2f214; CHECK-NOVFP-NEXT: mov r5, r0215; CHECK-NOVFP-NEXT: ldrh r0, [r4]216; CHECK-NOVFP-NEXT: bl __aeabi_h2f217; CHECK-NOVFP-NEXT: mov r1, r5218; CHECK-NOVFP-NEXT: bl __aeabi_fdiv219; CHECK-NOVFP-NEXT: bl __aeabi_f2h220; CHECK-NOVFP-NEXT: strh r0, [r4]221; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}222 %a = load half, ptr %p, align 2223 %b = load half, ptr %q, align 2224 %r = fdiv half %a, %b225 store half %r, ptr %p226 ret void227}228 229define void @test_frem(ptr %p, ptr %q) #0 {230; CHECK-FP16-LABEL: test_frem:231; CHECK-FP16: .save {r4, lr}232; CHECK-FP16-NEXT: push {r4, lr}233; CHECK-FP16-NEXT: mov r4, r0234; CHECK-FP16-NEXT: ldrh r0, [r0]235; CHECK-FP16-NEXT: ldrh r1, [r1]236; CHECK-FP16-NEXT: vmov s0, r0237; CHECK-FP16-NEXT: vmov s2, r1238; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0239; CHECK-FP16-NEXT: vcvtb.f32.f16 s1, s2240; CHECK-FP16-NEXT: bl fmodf241; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0242; CHECK-FP16-NEXT: vmov r0, s0243; CHECK-FP16-NEXT: strh r0, [r4]244; CHECK-FP16-NEXT: pop {r4, pc}245;246; CHECK-LIBCALL-VFP-LABEL: test_frem:247; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}248; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}249; CHECK-LIBCALL-VFP-NEXT: mov r4, r0250; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]251; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f252; CHECK-LIBCALL-VFP-NEXT: mov r5, r0253; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r4]254; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f255; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0256; CHECK-LIBCALL-VFP-NEXT: vmov s1, r5257; CHECK-LIBCALL-VFP-NEXT: bl fmodf258; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0259; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h260; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]261; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}262;263; CHECK-NOVFP-LABEL: test_frem:264; CHECK-NOVFP: .save {r4, r5, r11, lr}265; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}266; CHECK-NOVFP-NEXT: mov r4, r0267; CHECK-NOVFP-NEXT: ldrh r0, [r1]268; CHECK-NOVFP-NEXT: bl __aeabi_h2f269; CHECK-NOVFP-NEXT: mov r5, r0270; CHECK-NOVFP-NEXT: ldrh r0, [r4]271; CHECK-NOVFP-NEXT: bl __aeabi_h2f272; CHECK-NOVFP-NEXT: mov r1, r5273; CHECK-NOVFP-NEXT: bl fmodf274; CHECK-NOVFP-NEXT: bl __aeabi_f2h275; CHECK-NOVFP-NEXT: strh r0, [r4]276; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}277 %a = load half, ptr %p, align 2278 %b = load half, ptr %q, align 2279 %r = frem half %a, %b280 store half %r, ptr %p281 ret void282}283 284define void @test_load_store(ptr %p, ptr %q) #0 {285; CHECK-ALL-LABEL: test_load_store:286; CHECK-ALL: ldrh r0, [r0]287; CHECK-ALL-NEXT: strh r0, [r1]288; CHECK-ALL-NEXT: bx lr289 %a = load half, ptr %p, align 2290 store half %a, ptr %q291 ret void292}293 294; Testing only successfull compilation of function calls. In ARM ABI, half295; args and returns are handled as f32.296 297declare half @test_callee(half %a, half %b) #0298 299define half @test_call(half %a, half %b) #0 {300; CHECK-ALL-LABEL: test_call:301; CHECK-ALL: .save {r11, lr}302; CHECK-ALL-NEXT: push {r11, lr}303; CHECK-ALL-NEXT: bl test_callee304; CHECK-ALL-NEXT: pop {r11, pc}305 %r = call half @test_callee(half %a, half %b)306 ret half %r307}308 309define half @test_call_flipped(half %a, half %b) #0 {310; CHECK-VFP-LABEL: test_call_flipped:311; CHECK-VFP: .save {r11, lr}312; CHECK-VFP-NEXT: push {r11, lr}313; CHECK-VFP-NEXT: vmov.f32 s2, s0314; CHECK-VFP-NEXT: vmov.f32 s0, s1315; CHECK-VFP-NEXT: vmov.f32 s1, s2316; CHECK-VFP-NEXT: bl test_callee317; CHECK-VFP-NEXT: pop {r11, pc}318;319; CHECK-NOVFP-LABEL: test_call_flipped:320; CHECK-NOVFP: .save {r11, lr}321; CHECK-NOVFP-NEXT: push {r11, lr}322; CHECK-NOVFP-NEXT: mov r2, r0323; CHECK-NOVFP-NEXT: mov r0, r1324; CHECK-NOVFP-NEXT: mov r1, r2325; CHECK-NOVFP-NEXT: bl test_callee326; CHECK-NOVFP-NEXT: pop {r11, pc}327 %r = call half @test_callee(half %b, half %a)328 ret half %r329}330 331define half @test_tailcall_flipped(half %a, half %b) #0 {332; CHECK-VFP-LABEL: test_tailcall_flipped:333; CHECK-VFP: vmov.f32 s2, s0334; CHECK-VFP-NEXT: vmov.f32 s0, s1335; CHECK-VFP-NEXT: vmov.f32 s1, s2336; CHECK-VFP-NEXT: b test_callee337;338; CHECK-NOVFP-LABEL: test_tailcall_flipped:339; CHECK-NOVFP: mov r2, r0340; CHECK-NOVFP-NEXT: mov r0, r1341; CHECK-NOVFP-NEXT: mov r1, r2342; CHECK-NOVFP-NEXT: b test_callee343 %r = tail call half @test_callee(half %b, half %a)344 ret half %r345}346 347; Optimizer picks %p or %q based on %c and only loads that value348; No conversion is needed349define void @test_select(ptr %p, ptr %q, i1 zeroext %c) #0 {350; CHECK-ALL-LABEL: test_select:351; CHECK-ALL: cmp r2, #0352; CHECK-ALL-NEXT: movne r1, r0353; CHECK-ALL-NEXT: ldrh r1, [r1]354; CHECK-ALL-NEXT: strh r1, [r0]355; CHECK-ALL-NEXT: bx lr356 %a = load half, ptr %p, align 2357 %b = load half, ptr %q, align 2358 %r = select i1 %c, half %a, half %b359 store half %r, ptr %p360 ret void361}362 363; Test only two variants of fcmp. These get translated to f32 vcmp364; instructions anyway.365define i1 @test_fcmp_une(ptr %p, ptr %q) #0 {366; CHECK-FP16-LABEL: test_fcmp_une:367; CHECK-FP16: ldrh r2, [r0]368; CHECK-FP16-NEXT: mov r0, #0369; CHECK-FP16-NEXT: ldrh r1, [r1]370; CHECK-FP16-NEXT: vmov s0, r2371; CHECK-FP16-NEXT: vmov s2, r1372; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0373; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s2374; CHECK-FP16-NEXT: vcmp.f32 s0, s2375; CHECK-FP16-NEXT: vmrs APSR_nzcv, fpscr376; CHECK-FP16-NEXT: movwne r0, #1377; CHECK-FP16-NEXT: bx lr378;379; CHECK-LIBCALL-VFP-LABEL: test_fcmp_une:380; CHECK-LIBCALL-VFP: .save {r4, lr}381; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}382; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}383; CHECK-LIBCALL-VFP-NEXT: vpush {d8}384; CHECK-LIBCALL-VFP-NEXT: mov r4, r0385; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]386; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f387; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]388; CHECK-LIBCALL-VFP-NEXT: vmov s16, r0389; CHECK-LIBCALL-VFP-NEXT: mov r0, r1390; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f391; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0392; CHECK-LIBCALL-VFP-NEXT: mov r0, #0393; CHECK-LIBCALL-VFP-NEXT: vcmp.f32 s0, s16394; CHECK-LIBCALL-VFP-NEXT: vmrs APSR_nzcv, fpscr395; CHECK-LIBCALL-VFP-NEXT: movwne r0, #1396; CHECK-LIBCALL-VFP-NEXT: vpop {d8}397; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}398;399; CHECK-NOVFP-LABEL: test_fcmp_une:400; CHECK-NOVFP: .save {r4, r5, r11, lr}401; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}402; CHECK-NOVFP-NEXT: mov r4, r0403; CHECK-NOVFP-NEXT: ldrh r0, [r1]404; CHECK-NOVFP-NEXT: bl __aeabi_h2f405; CHECK-NOVFP-NEXT: mov r5, r0406; CHECK-NOVFP-NEXT: ldrh r0, [r4]407; CHECK-NOVFP-NEXT: bl __aeabi_h2f408; CHECK-NOVFP-NEXT: mov r1, r5409; CHECK-NOVFP-NEXT: bl __aeabi_fcmpeq410; CHECK-NOVFP-NEXT: clz r0, r0411; CHECK-NOVFP-NEXT: lsr r0, r0, #5412; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}413 %a = load half, ptr %p, align 2414 %b = load half, ptr %q, align 2415 %r = fcmp une half %a, %b416 ret i1 %r417}418 419define i1 @test_fcmp_ueq(ptr %p, ptr %q) #0 {420; CHECK-FP16-LABEL: test_fcmp_ueq:421; CHECK-FP16: ldrh r2, [r0]422; CHECK-FP16-NEXT: mov r0, #0423; CHECK-FP16-NEXT: ldrh r1, [r1]424; CHECK-FP16-NEXT: vmov s0, r2425; CHECK-FP16-NEXT: vmov s2, r1426; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0427; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s2428; CHECK-FP16-NEXT: vcmp.f32 s0, s2429; CHECK-FP16-NEXT: vmrs APSR_nzcv, fpscr430; CHECK-FP16-NEXT: movweq r0, #1431; CHECK-FP16-NEXT: movwvs r0, #1432; CHECK-FP16-NEXT: bx lr433;434; CHECK-LIBCALL-VFP-LABEL: test_fcmp_ueq:435; CHECK-LIBCALL-VFP: .save {r4, lr}436; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}437; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}438; CHECK-LIBCALL-VFP-NEXT: vpush {d8}439; CHECK-LIBCALL-VFP-NEXT: mov r4, r0440; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]441; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f442; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]443; CHECK-LIBCALL-VFP-NEXT: vmov s16, r0444; CHECK-LIBCALL-VFP-NEXT: mov r0, r1445; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f446; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0447; CHECK-LIBCALL-VFP-NEXT: mov r0, #0448; CHECK-LIBCALL-VFP-NEXT: vcmp.f32 s0, s16449; CHECK-LIBCALL-VFP-NEXT: vmrs APSR_nzcv, fpscr450; CHECK-LIBCALL-VFP-NEXT: movweq r0, #1451; CHECK-LIBCALL-VFP-NEXT: movwvs r0, #1452; CHECK-LIBCALL-VFP-NEXT: vpop {d8}453; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}454;455; CHECK-NOVFP-LABEL: test_fcmp_ueq:456; CHECK-NOVFP: .save {r4, r5, r6, lr}457; CHECK-NOVFP-NEXT: push {r4, r5, r6, lr}458; CHECK-NOVFP-NEXT: mov r4, r0459; CHECK-NOVFP-NEXT: ldrh r0, [r1]460; CHECK-NOVFP-NEXT: bl __aeabi_h2f461; CHECK-NOVFP-NEXT: mov r5, r0462; CHECK-NOVFP-NEXT: ldrh r0, [r4]463; CHECK-NOVFP-NEXT: bl __aeabi_h2f464; CHECK-NOVFP-NEXT: mov r1, r5465; CHECK-NOVFP-NEXT: mov r4, r0466; CHECK-NOVFP-NEXT: bl __aeabi_fcmpeq467; CHECK-NOVFP-NEXT: mov r6, r0468; CHECK-NOVFP-NEXT: mov r0, r4469; CHECK-NOVFP-NEXT: mov r1, r5470; CHECK-NOVFP-NEXT: bl __aeabi_fcmpun471; CHECK-NOVFP-NEXT: orrs r0, r0, r6472; CHECK-NOVFP-NEXT: movwne r0, #1473; CHECK-NOVFP-NEXT: pop {r4, r5, r6, pc}474 %a = load half, ptr %p, align 2475 %b = load half, ptr %q, align 2476 %r = fcmp ueq half %a, %b477 ret i1 %r478}479 480define void @test_br_cc(ptr %p, ptr %q, ptr %p1, ptr %p2) #0 {481; CHECK-FP16-LABEL: test_br_cc:482; CHECK-FP16: ldrh r0, [r0]483; CHECK-FP16-NEXT: ldrh r1, [r1]484; CHECK-FP16-NEXT: vmov s0, r0485; CHECK-FP16-NEXT: mov r0, #0486; CHECK-FP16-NEXT: vmov s2, r1487; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0488; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s2489; CHECK-FP16-NEXT: vcmp.f32 s0, s2490; CHECK-FP16-NEXT: vmrs APSR_nzcv, fpscr491; CHECK-FP16-NEXT: movmi r2, r3492; CHECK-FP16-NEXT: str r0, [r2]493; CHECK-FP16-NEXT: bx lr494;495; CHECK-LIBCALL-VFP-LABEL: test_br_cc:496; CHECK-LIBCALL-VFP: .save {r4, r5, r6, lr}497; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r6, lr}498; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}499; CHECK-LIBCALL-VFP-NEXT: vpush {d8}500; CHECK-LIBCALL-VFP-NEXT: mov r6, r0501; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]502; CHECK-LIBCALL-VFP-NEXT: mov r4, r3503; CHECK-LIBCALL-VFP-NEXT: mov r5, r2504; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f505; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r6]506; CHECK-LIBCALL-VFP-NEXT: vmov s16, r0507; CHECK-LIBCALL-VFP-NEXT: mov r0, r1508; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f509; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0510; CHECK-LIBCALL-VFP-NEXT: mov r0, #0511; CHECK-LIBCALL-VFP-NEXT: vcmp.f32 s0, s16512; CHECK-LIBCALL-VFP-NEXT: vmrs APSR_nzcv, fpscr513; CHECK-LIBCALL-VFP-NEXT: movmi r5, r4514; CHECK-LIBCALL-VFP-NEXT: str r0, [r5]515; CHECK-LIBCALL-VFP-NEXT: vpop {d8}516; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r6, pc}517;518; CHECK-NOVFP-LABEL: test_br_cc:519; CHECK-NOVFP: .save {r4, r5, r6, r7, r11, lr}520; CHECK-NOVFP-NEXT: push {r4, r5, r6, r7, r11, lr}521; CHECK-NOVFP-NEXT: mov r6, r0522; CHECK-NOVFP-NEXT: ldrh r0, [r1]523; CHECK-NOVFP-NEXT: mov r4, r3524; CHECK-NOVFP-NEXT: mov r5, r2525; CHECK-NOVFP-NEXT: bl __aeabi_h2f526; CHECK-NOVFP-NEXT: mov r7, r0527; CHECK-NOVFP-NEXT: ldrh r0, [r6]528; CHECK-NOVFP-NEXT: bl __aeabi_h2f529; CHECK-NOVFP-NEXT: mov r1, r7530; CHECK-NOVFP-NEXT: bl __aeabi_fcmplt531; CHECK-NOVFP-NEXT: cmp r0, #0532; CHECK-NOVFP-NEXT: mov r0, #0533; CHECK-NOVFP-NEXT: movne r5, r4534; CHECK-NOVFP-NEXT: str r0, [r5]535; CHECK-NOVFP-NEXT: pop {r4, r5, r6, r7, r11, pc}536 %a = load half, ptr %p, align 2537 %b = load half, ptr %q, align 2538 %c = fcmp uge half %a, %b539 br i1 %c, label %then, label %else540then:541 store i32 0, ptr %p1542 ret void543else:544 store i32 0, ptr %p2545 ret void546}547 548declare i1 @test_dummy(ptr %p) #0549 550define void @test_phi(ptr %p) #0 {551; CHECK-VFP-LABEL: test_phi:552; CHECK-VFP: .save {r4, r5, r6, lr}553; CHECK-VFP-NEXT: push {r4, r5, r6, lr}554; CHECK-VFP-NEXT: ldrh r6, [r0]555; CHECK-VFP-NEXT: mov r4, r0556; CHECK-VFP-NEXT: .LBB13_1:557; CHECK-VFP-NEXT: mov r0, r4558; CHECK-VFP-NEXT: mov r5, r6559; CHECK-VFP-NEXT: ldrh r6, [r4]560; CHECK-VFP-NEXT: bl test_dummy561; CHECK-VFP-NEXT: tst r0, #1562; CHECK-VFP-NEXT: bne .LBB13_1563; CHECK-VFP-NEXT: strh r5, [r4]564; CHECK-VFP-NEXT: pop {r4, r5, r6, pc}565;566; CHECK-NOVFP-LABEL: test_phi:567; CHECK-NOVFP: .save {r4, r5, r6, lr}568; CHECK-NOVFP-NEXT: push {r4, r5, r6, lr}569; CHECK-NOVFP-NEXT: ldrh r5, [r0]570; CHECK-NOVFP-NEXT: mov r4, r0571; CHECK-NOVFP-NEXT: .LBB13_1:572; CHECK-NOVFP-NEXT: mov r0, r4573; CHECK-NOVFP-NEXT: mov r6, r5574; CHECK-NOVFP-NEXT: ldrh r5, [r4]575; CHECK-NOVFP-NEXT: bl test_dummy576; CHECK-NOVFP-NEXT: tst r0, #1577; CHECK-NOVFP-NEXT: bne .LBB13_1578; CHECK-NOVFP-NEXT: strh r6, [r4]579; CHECK-NOVFP-NEXT: pop {r4, r5, r6, pc}580entry:581 %a = load half, ptr %p582 br label %loop583loop:584 %r = phi half [%a, %entry], [%b, %loop]585 %b = load half, ptr %p586 %c = call i1 @test_dummy(ptr %p)587 br i1 %c, label %loop, label %return588return:589 store half %r, ptr %p590 ret void591}592 593define i32 @test_fptosi_i32(ptr %p) #0 {594; CHECK-FP16-LABEL: test_fptosi_i32:595; CHECK-FP16: ldrh r0, [r0]596; CHECK-FP16-NEXT: vmov s0, r0597; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0598; CHECK-FP16-NEXT: vcvt.s32.f32 s0, s0599; CHECK-FP16-NEXT: vmov r0, s0600; CHECK-FP16-NEXT: bx lr601;602; CHECK-LIBCALL-VFP-LABEL: test_fptosi_i32:603; CHECK-LIBCALL-VFP: .save {r11, lr}604; CHECK-LIBCALL-VFP-NEXT: push {r11, lr}605; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]606; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f607; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0608; CHECK-LIBCALL-VFP-NEXT: vcvt.s32.f32 s0, s0609; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0610; CHECK-LIBCALL-VFP-NEXT: pop {r11, pc}611;612; CHECK-NOVFP-LABEL: test_fptosi_i32:613; CHECK-NOVFP: .save {r11, lr}614; CHECK-NOVFP-NEXT: push {r11, lr}615; CHECK-NOVFP-NEXT: ldrh r0, [r0]616; CHECK-NOVFP-NEXT: bl __aeabi_h2f617; CHECK-NOVFP-NEXT: bl __aeabi_f2iz618; CHECK-NOVFP-NEXT: pop {r11, pc}619 %a = load half, ptr %p, align 2620 %r = fptosi half %a to i32621 ret i32 %r622}623 624define i64 @test_fptosi_i64(ptr %p) #0 {625; CHECK-FP16-LABEL: test_fptosi_i64:626; CHECK-FP16: .save {r11, lr}627; CHECK-FP16-NEXT: push {r11, lr}628; CHECK-FP16-NEXT: ldrh r0, [r0]629; CHECK-FP16-NEXT: vmov s0, r0630; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0631; CHECK-FP16-NEXT: vmov r0, s0632; CHECK-FP16-NEXT: bl __aeabi_f2lz633; CHECK-FP16-NEXT: pop {r11, pc}634;635; CHECK-LIBCALL-LABEL: test_fptosi_i64:636; CHECK-LIBCALL: .save {r11, lr}637; CHECK-LIBCALL-NEXT: push {r11, lr}638; CHECK-LIBCALL-NEXT: ldrh r0, [r0]639; CHECK-LIBCALL-NEXT: bl __aeabi_h2f640; CHECK-LIBCALL-NEXT: bl __aeabi_f2lz641; CHECK-LIBCALL-NEXT: pop {r11, pc}642 %a = load half, ptr %p, align 2643 %r = fptosi half %a to i64644 ret i64 %r645}646 647define i32 @test_fptoui_i32(ptr %p) #0 {648; CHECK-FP16-LABEL: test_fptoui_i32:649; CHECK-FP16: ldrh r0, [r0]650; CHECK-FP16-NEXT: vmov s0, r0651; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0652; CHECK-FP16-NEXT: vcvt.u32.f32 s0, s0653; CHECK-FP16-NEXT: vmov r0, s0654; CHECK-FP16-NEXT: bx lr655;656; CHECK-LIBCALL-VFP-LABEL: test_fptoui_i32:657; CHECK-LIBCALL-VFP: .save {r11, lr}658; CHECK-LIBCALL-VFP-NEXT: push {r11, lr}659; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]660; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f661; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0662; CHECK-LIBCALL-VFP-NEXT: vcvt.u32.f32 s0, s0663; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0664; CHECK-LIBCALL-VFP-NEXT: pop {r11, pc}665;666; CHECK-NOVFP-LABEL: test_fptoui_i32:667; CHECK-NOVFP: .save {r11, lr}668; CHECK-NOVFP-NEXT: push {r11, lr}669; CHECK-NOVFP-NEXT: ldrh r0, [r0]670; CHECK-NOVFP-NEXT: bl __aeabi_h2f671; CHECK-NOVFP-NEXT: bl __aeabi_f2uiz672; CHECK-NOVFP-NEXT: pop {r11, pc}673 %a = load half, ptr %p, align 2674 %r = fptoui half %a to i32675 ret i32 %r676}677 678define i64 @test_fptoui_i64(ptr %p) #0 {679; CHECK-FP16-LABEL: test_fptoui_i64:680; CHECK-FP16: .save {r11, lr}681; CHECK-FP16-NEXT: push {r11, lr}682; CHECK-FP16-NEXT: ldrh r0, [r0]683; CHECK-FP16-NEXT: vmov s0, r0684; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0685; CHECK-FP16-NEXT: vmov r0, s0686; CHECK-FP16-NEXT: bl __aeabi_f2ulz687; CHECK-FP16-NEXT: pop {r11, pc}688;689; CHECK-LIBCALL-LABEL: test_fptoui_i64:690; CHECK-LIBCALL: .save {r11, lr}691; CHECK-LIBCALL-NEXT: push {r11, lr}692; CHECK-LIBCALL-NEXT: ldrh r0, [r0]693; CHECK-LIBCALL-NEXT: bl __aeabi_h2f694; CHECK-LIBCALL-NEXT: bl __aeabi_f2ulz695; CHECK-LIBCALL-NEXT: pop {r11, pc}696 %a = load half, ptr %p, align 2697 %r = fptoui half %a to i64698 ret i64 %r699}700 701define void @test_sitofp_i32(i32 %a, ptr %p) #0 {702; CHECK-FP16-LABEL: test_sitofp_i32:703; CHECK-FP16: vmov s0, r0704; CHECK-FP16-NEXT: vcvt.f32.s32 s0, s0705; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0706; CHECK-FP16-NEXT: vmov r0, s0707; CHECK-FP16-NEXT: strh r0, [r1]708; CHECK-FP16-NEXT: bx lr709;710; CHECK-LIBCALL-VFP-LABEL: test_sitofp_i32:711; CHECK-LIBCALL-VFP: .save {r4, lr}712; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}713; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0714; CHECK-LIBCALL-VFP-NEXT: mov r4, r1715; CHECK-LIBCALL-VFP-NEXT: vcvt.f32.s32 s0, s0716; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0717; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h718; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]719; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}720;721; CHECK-NOVFP-LABEL: test_sitofp_i32:722; CHECK-NOVFP: .save {r4, lr}723; CHECK-NOVFP-NEXT: push {r4, lr}724; CHECK-NOVFP-NEXT: mov r4, r1725; CHECK-NOVFP-NEXT: bl __aeabi_i2f726; CHECK-NOVFP-NEXT: bl __aeabi_f2h727; CHECK-NOVFP-NEXT: strh r0, [r4]728; CHECK-NOVFP-NEXT: pop {r4, pc}729 %r = sitofp i32 %a to half730 store half %r, ptr %p731 ret void732}733 734define void @test_uitofp_i32(i32 %a, ptr %p) #0 {735; CHECK-FP16-LABEL: test_uitofp_i32:736; CHECK-FP16: vmov s0, r0737; CHECK-FP16-NEXT: vcvt.f32.u32 s0, s0738; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0739; CHECK-FP16-NEXT: vmov r0, s0740; CHECK-FP16-NEXT: strh r0, [r1]741; CHECK-FP16-NEXT: bx lr742;743; CHECK-LIBCALL-VFP-LABEL: test_uitofp_i32:744; CHECK-LIBCALL-VFP: .save {r4, lr}745; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}746; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0747; CHECK-LIBCALL-VFP-NEXT: mov r4, r1748; CHECK-LIBCALL-VFP-NEXT: vcvt.f32.u32 s0, s0749; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0750; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h751; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]752; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}753;754; CHECK-NOVFP-LABEL: test_uitofp_i32:755; CHECK-NOVFP: .save {r4, lr}756; CHECK-NOVFP-NEXT: push {r4, lr}757; CHECK-NOVFP-NEXT: mov r4, r1758; CHECK-NOVFP-NEXT: bl __aeabi_ui2f759; CHECK-NOVFP-NEXT: bl __aeabi_f2h760; CHECK-NOVFP-NEXT: strh r0, [r4]761; CHECK-NOVFP-NEXT: pop {r4, pc}762 %r = uitofp i32 %a to half763 store half %r, ptr %p764 ret void765}766 767define void @test_sitofp_i64(i64 %a, ptr %p) #0 {768; CHECK-FP16-LABEL: test_sitofp_i64:769; CHECK-FP16: .save {r4, lr}770; CHECK-FP16-NEXT: push {r4, lr}771; CHECK-FP16-NEXT: mov r4, r2772; CHECK-FP16-NEXT: bl __aeabi_l2f773; CHECK-FP16-NEXT: vmov s0, r0774; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0775; CHECK-FP16-NEXT: vmov r0, s0776; CHECK-FP16-NEXT: strh r0, [r4]777; CHECK-FP16-NEXT: pop {r4, pc}778;779; CHECK-LIBCALL-LABEL: test_sitofp_i64:780; CHECK-LIBCALL: .save {r4, lr}781; CHECK-LIBCALL-NEXT: push {r4, lr}782; CHECK-LIBCALL-NEXT: mov r4, r2783; CHECK-LIBCALL-NEXT: bl __aeabi_l2f784; CHECK-LIBCALL-NEXT: bl __aeabi_f2h785; CHECK-LIBCALL-NEXT: strh r0, [r4]786; CHECK-LIBCALL-NEXT: pop {r4, pc}787 %r = sitofp i64 %a to half788 store half %r, ptr %p789 ret void790}791 792define void @test_uitofp_i64(i64 %a, ptr %p) #0 {793; CHECK-FP16-LABEL: test_uitofp_i64:794; CHECK-FP16: .save {r4, lr}795; CHECK-FP16-NEXT: push {r4, lr}796; CHECK-FP16-NEXT: mov r4, r2797; CHECK-FP16-NEXT: bl __aeabi_ul2f798; CHECK-FP16-NEXT: vmov s0, r0799; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0800; CHECK-FP16-NEXT: vmov r0, s0801; CHECK-FP16-NEXT: strh r0, [r4]802; CHECK-FP16-NEXT: pop {r4, pc}803;804; CHECK-LIBCALL-LABEL: test_uitofp_i64:805; CHECK-LIBCALL: .save {r4, lr}806; CHECK-LIBCALL-NEXT: push {r4, lr}807; CHECK-LIBCALL-NEXT: mov r4, r2808; CHECK-LIBCALL-NEXT: bl __aeabi_ul2f809; CHECK-LIBCALL-NEXT: bl __aeabi_f2h810; CHECK-LIBCALL-NEXT: strh r0, [r4]811; CHECK-LIBCALL-NEXT: pop {r4, pc}812 %r = uitofp i64 %a to half813 store half %r, ptr %p814 ret void815}816 817define void @test_fptrunc_float(float %f, ptr %p) #0 {818; CHECK-FP16-LABEL: test_fptrunc_float:819; CHECK-FP16: vcvtb.f16.f32 s0, s0820; CHECK-FP16-NEXT: vmov r1, s0821; CHECK-FP16-NEXT: strh r1, [r0]822; CHECK-FP16-NEXT: bx lr823;824; CHECK-LIBCALL-VFP-LABEL: test_fptrunc_float:825; CHECK-LIBCALL-VFP: .save {r4, lr}826; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}827; CHECK-LIBCALL-VFP-NEXT: mov r4, r0828; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0829; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h830; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]831; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}832;833; CHECK-NOVFP-LABEL: test_fptrunc_float:834; CHECK-NOVFP: .save {r4, lr}835; CHECK-NOVFP-NEXT: push {r4, lr}836; CHECK-NOVFP-NEXT: mov r4, r1837; CHECK-NOVFP-NEXT: bl __aeabi_f2h838; CHECK-NOVFP-NEXT: strh r0, [r4]839; CHECK-NOVFP-NEXT: pop {r4, pc}840 %a = fptrunc float %f to half841 store half %a, ptr %p842 ret void843}844 845define void @test_fptrunc_double(double %d, ptr %p) #0 {846; CHECK-VFP-LABEL: test_fptrunc_double:847; CHECK-VFP: .save {r4, lr}848; CHECK-VFP-NEXT: push {r4, lr}849; CHECK-VFP-NEXT: mov r4, r0850; CHECK-VFP-NEXT: vmov r0, r1, d0851; CHECK-VFP-NEXT: bl __aeabi_d2h852; CHECK-VFP-NEXT: strh r0, [r4]853; CHECK-VFP-NEXT: pop {r4, pc}854;855; CHECK-NOVFP-LABEL: test_fptrunc_double:856; CHECK-NOVFP: .save {r4, lr}857; CHECK-NOVFP-NEXT: push {r4, lr}858; CHECK-NOVFP-NEXT: mov r4, r2859; CHECK-NOVFP-NEXT: bl __aeabi_d2h860; CHECK-NOVFP-NEXT: strh r0, [r4]861; CHECK-NOVFP-NEXT: pop {r4, pc}862 %a = fptrunc double %d to half863 store half %a, ptr %p864 ret void865}866 867define float @test_fpextend_float(ptr %p) {868; CHECK-FP16-LABEL: test_fpextend_float:869; CHECK-FP16: ldrh r0, [r0]870; CHECK-FP16-NEXT: vmov s0, r0871; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0872; CHECK-FP16-NEXT: bx lr873;874; CHECK-LIBCALL-VFP-LABEL: test_fpextend_float:875; CHECK-LIBCALL-VFP: .save {r11, lr}876; CHECK-LIBCALL-VFP-NEXT: push {r11, lr}877; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]878; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f879; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0880; CHECK-LIBCALL-VFP-NEXT: pop {r11, pc}881;882; CHECK-NOVFP-LABEL: test_fpextend_float:883; CHECK-NOVFP: .save {r11, lr}884; CHECK-NOVFP-NEXT: push {r11, lr}885; CHECK-NOVFP-NEXT: ldrh r0, [r0]886; CHECK-NOVFP-NEXT: bl __aeabi_h2f887; CHECK-NOVFP-NEXT: pop {r11, pc}888 %a = load half, ptr %p, align 2889 %r = fpext half %a to float890 ret float %r891}892 893define double @test_fpextend_double(ptr %p) {894; CHECK-FP16-LABEL: test_fpextend_double:895; CHECK-FP16: ldrh r0, [r0]896; CHECK-FP16-NEXT: vmov s0, r0897; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0898; CHECK-FP16-NEXT: vcvt.f64.f32 d0, s0899; CHECK-FP16-NEXT: bx lr900;901; CHECK-LIBCALL-VFP-LABEL: test_fpextend_double:902; CHECK-LIBCALL-VFP: .save {r11, lr}903; CHECK-LIBCALL-VFP-NEXT: push {r11, lr}904; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]905; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f906; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0907; CHECK-LIBCALL-VFP-NEXT: vcvt.f64.f32 d0, s0908; CHECK-LIBCALL-VFP-NEXT: pop {r11, pc}909;910; CHECK-NOVFP-LABEL: test_fpextend_double:911; CHECK-NOVFP: .save {r11, lr}912; CHECK-NOVFP-NEXT: push {r11, lr}913; CHECK-NOVFP-NEXT: ldrh r0, [r0]914; CHECK-NOVFP-NEXT: bl __aeabi_h2f915; CHECK-NOVFP-NEXT: bl __aeabi_f2d916; CHECK-NOVFP-NEXT: pop {r11, pc}917 %a = load half, ptr %p, align 2918 %r = fpext half %a to double919 ret double %r920}921 922define i16 @test_bitcast_halftoi16(ptr %p) #0 {923; CHECK-ALL-LABEL: test_bitcast_halftoi16:924; CHECK-ALL: ldrh r0, [r0]925; CHECK-ALL-NEXT: bx lr926 %a = load half, ptr %p, align 2927 %r = bitcast half %a to i16928 ret i16 %r929}930 931define void @test_bitcast_i16tohalf(i16 %a, ptr %p) #0 {932; CHECK-ALL-LABEL: test_bitcast_i16tohalf:933; CHECK-ALL: strh r0, [r1]934; CHECK-ALL-NEXT: bx lr935 %r = bitcast i16 %a to half936 store half %r, ptr %p937 ret void938}939 940declare half @llvm.sqrt.f16(half %a) #0941declare half @llvm.powi.f16.i32(half %a, i32 %b) #0942declare half @llvm.sin.f16(half %a) #0943declare half @llvm.cos.f16(half %a) #0944declare half @llvm.tan.f16(half %a) #0945declare half @llvm.pow.f16(half %a, half %b) #0946declare half @llvm.exp.f16(half %a) #0947declare half @llvm.exp2.f16(half %a) #0948declare half @llvm.log.f16(half %a) #0949declare half @llvm.log10.f16(half %a) #0950declare half @llvm.log2.f16(half %a) #0951declare half @llvm.fma.f16(half %a, half %b, half %c) #0952declare half @llvm.fabs.f16(half %a) #0953declare half @llvm.minnum.f16(half %a, half %b) #0954declare half @llvm.maxnum.f16(half %a, half %b) #0955declare half @llvm.copysign.f16(half %a, half %b) #0956declare half @llvm.floor.f16(half %a) #0957declare half @llvm.ceil.f16(half %a) #0958declare half @llvm.trunc.f16(half %a) #0959declare half @llvm.rint.f16(half %a) #0960declare half @llvm.nearbyint.f16(half %a) #0961declare half @llvm.round.f16(half %a) #0962declare half @llvm.roundeven.f16(half %a) #0963declare half @llvm.fmuladd.f16(half %a, half %b, half %c) #0964 965define void @test_sqrt(ptr %p) #0 {966; CHECK-FP16-LABEL: test_sqrt:967; CHECK-FP16: ldrh r1, [r0]968; CHECK-FP16-NEXT: vmov s0, r1969; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0970; CHECK-FP16-NEXT: vsqrt.f32 s0, s0971; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0972; CHECK-FP16-NEXT: vmov r1, s0973; CHECK-FP16-NEXT: strh r1, [r0]974; CHECK-FP16-NEXT: bx lr975;976; CHECK-LIBCALL-VFP-LABEL: test_sqrt:977; CHECK-LIBCALL-VFP: .save {r4, lr}978; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}979; CHECK-LIBCALL-VFP-NEXT: mov r4, r0980; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]981; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f982; CHECK-LIBCALL-VFP-NEXT: vmov s0, r0983; CHECK-LIBCALL-VFP-NEXT: vsqrt.f32 s0, s0984; CHECK-LIBCALL-VFP-NEXT: vmov r0, s0985; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h986; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]987; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}988;989; CHECK-NOVFP-LABEL: test_sqrt:990; CHECK-NOVFP: .save {r4, lr}991; CHECK-NOVFP-NEXT: push {r4, lr}992; CHECK-NOVFP-NEXT: mov r4, r0993; CHECK-NOVFP-NEXT: ldrh r0, [r0]994; CHECK-NOVFP-NEXT: bl __aeabi_h2f995; CHECK-NOVFP-NEXT: bl sqrtf996; CHECK-NOVFP-NEXT: bl __aeabi_f2h997; CHECK-NOVFP-NEXT: strh r0, [r4]998; CHECK-NOVFP-NEXT: pop {r4, pc}999 %a = load half, ptr %p, align 21000 %r = call half @llvm.sqrt.f16(half %a)1001 store half %r, ptr %p1002 ret void1003}1004 1005define void @test_fpowi(ptr %p, i32 %b) #0 {1006; CHECK-FP16-LABEL: test_fpowi:1007; CHECK-FP16: .save {r4, lr}1008; CHECK-FP16-NEXT: push {r4, lr}1009; CHECK-FP16-NEXT: mov r4, r01010; CHECK-FP16-NEXT: ldrh r0, [r0]1011; CHECK-FP16-NEXT: vmov s0, r01012; CHECK-FP16-NEXT: mov r0, r11013; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01014; CHECK-FP16-NEXT: bl __powisf21015; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01016; CHECK-FP16-NEXT: vmov r0, s01017; CHECK-FP16-NEXT: strh r0, [r4]1018; CHECK-FP16-NEXT: pop {r4, pc}1019;1020; CHECK-LIBCALL-VFP-LABEL: test_fpowi:1021; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}1022; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}1023; CHECK-LIBCALL-VFP-NEXT: mov r5, r01024; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1025; CHECK-LIBCALL-VFP-NEXT: mov r4, r11026; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1027; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01028; CHECK-LIBCALL-VFP-NEXT: mov r0, r41029; CHECK-LIBCALL-VFP-NEXT: bl __powisf21030; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01031; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1032; CHECK-LIBCALL-VFP-NEXT: strh r0, [r5]1033; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}1034;1035; CHECK-NOVFP-LABEL: test_fpowi:1036; CHECK-NOVFP: .save {r4, r5, r11, lr}1037; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}1038; CHECK-NOVFP-NEXT: mov r5, r01039; CHECK-NOVFP-NEXT: ldrh r0, [r0]1040; CHECK-NOVFP-NEXT: mov r4, r11041; CHECK-NOVFP-NEXT: bl __aeabi_h2f1042; CHECK-NOVFP-NEXT: mov r1, r41043; CHECK-NOVFP-NEXT: bl __powisf21044; CHECK-NOVFP-NEXT: bl __aeabi_f2h1045; CHECK-NOVFP-NEXT: strh r0, [r5]1046; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}1047 %a = load half, ptr %p, align 21048 %r = call half @llvm.powi.f16.i32(half %a, i32 %b)1049 store half %r, ptr %p1050 ret void1051}1052 1053define void @test_sin(ptr %p) #0 {1054; CHECK-FP16-LABEL: test_sin:1055; CHECK-FP16: .save {r4, lr}1056; CHECK-FP16-NEXT: push {r4, lr}1057; CHECK-FP16-NEXT: mov r4, r01058; CHECK-FP16-NEXT: ldrh r0, [r0]1059; CHECK-FP16-NEXT: vmov s0, r01060; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01061; CHECK-FP16-NEXT: bl sinf1062; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01063; CHECK-FP16-NEXT: vmov r0, s01064; CHECK-FP16-NEXT: strh r0, [r4]1065; CHECK-FP16-NEXT: pop {r4, pc}1066;1067; CHECK-LIBCALL-VFP-LABEL: test_sin:1068; CHECK-LIBCALL-VFP: .save {r4, lr}1069; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1070; CHECK-LIBCALL-VFP-NEXT: mov r4, r01071; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1072; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1073; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01074; CHECK-LIBCALL-VFP-NEXT: bl sinf1075; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01076; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1077; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1078; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1079;1080; CHECK-NOVFP-LABEL: test_sin:1081; CHECK-NOVFP: .save {r4, lr}1082; CHECK-NOVFP-NEXT: push {r4, lr}1083; CHECK-NOVFP-NEXT: mov r4, r01084; CHECK-NOVFP-NEXT: ldrh r0, [r0]1085; CHECK-NOVFP-NEXT: bl __aeabi_h2f1086; CHECK-NOVFP-NEXT: bl sinf1087; CHECK-NOVFP-NEXT: bl __aeabi_f2h1088; CHECK-NOVFP-NEXT: strh r0, [r4]1089; CHECK-NOVFP-NEXT: pop {r4, pc}1090 %a = load half, ptr %p, align 21091 %r = call half @llvm.sin.f16(half %a)1092 store half %r, ptr %p1093 ret void1094}1095 1096define void @test_cos(ptr %p) #0 {1097; CHECK-FP16-LABEL: test_cos:1098; CHECK-FP16: .save {r4, lr}1099; CHECK-FP16-NEXT: push {r4, lr}1100; CHECK-FP16-NEXT: mov r4, r01101; CHECK-FP16-NEXT: ldrh r0, [r0]1102; CHECK-FP16-NEXT: vmov s0, r01103; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01104; CHECK-FP16-NEXT: bl cosf1105; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01106; CHECK-FP16-NEXT: vmov r0, s01107; CHECK-FP16-NEXT: strh r0, [r4]1108; CHECK-FP16-NEXT: pop {r4, pc}1109;1110; CHECK-LIBCALL-VFP-LABEL: test_cos:1111; CHECK-LIBCALL-VFP: .save {r4, lr}1112; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1113; CHECK-LIBCALL-VFP-NEXT: mov r4, r01114; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1115; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1116; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01117; CHECK-LIBCALL-VFP-NEXT: bl cosf1118; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01119; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1120; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1121; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1122;1123; CHECK-NOVFP-LABEL: test_cos:1124; CHECK-NOVFP: .save {r4, lr}1125; CHECK-NOVFP-NEXT: push {r4, lr}1126; CHECK-NOVFP-NEXT: mov r4, r01127; CHECK-NOVFP-NEXT: ldrh r0, [r0]1128; CHECK-NOVFP-NEXT: bl __aeabi_h2f1129; CHECK-NOVFP-NEXT: bl cosf1130; CHECK-NOVFP-NEXT: bl __aeabi_f2h1131; CHECK-NOVFP-NEXT: strh r0, [r4]1132; CHECK-NOVFP-NEXT: pop {r4, pc}1133 %a = load half, ptr %p, align 21134 %r = call half @llvm.cos.f16(half %a)1135 store half %r, ptr %p1136 ret void1137}1138 1139define void @test_tan(ptr %p) #0 {1140; CHECK-FP16-LABEL: test_tan:1141; CHECK-FP16: .save {r4, lr}1142; CHECK-FP16-NEXT: push {r4, lr}1143; CHECK-FP16-NEXT: mov r4, r01144; CHECK-FP16-NEXT: ldrh r0, [r0]1145; CHECK-FP16-NEXT: vmov s0, r01146; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01147; CHECK-FP16-NEXT: bl tanf1148; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01149; CHECK-FP16-NEXT: vmov r0, s01150; CHECK-FP16-NEXT: strh r0, [r4]1151; CHECK-FP16-NEXT: pop {r4, pc}1152;1153; CHECK-LIBCALL-VFP-LABEL: test_tan:1154; CHECK-LIBCALL-VFP: .save {r4, lr}1155; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1156; CHECK-LIBCALL-VFP-NEXT: mov r4, r01157; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1158; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1159; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01160; CHECK-LIBCALL-VFP-NEXT: bl tanf1161; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01162; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1163; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1164; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1165;1166; CHECK-NOVFP-LABEL: test_tan:1167; CHECK-NOVFP: .save {r4, lr}1168; CHECK-NOVFP-NEXT: push {r4, lr}1169; CHECK-NOVFP-NEXT: mov r4, r01170; CHECK-NOVFP-NEXT: ldrh r0, [r0]1171; CHECK-NOVFP-NEXT: bl __aeabi_h2f1172; CHECK-NOVFP-NEXT: bl tanf1173; CHECK-NOVFP-NEXT: bl __aeabi_f2h1174; CHECK-NOVFP-NEXT: strh r0, [r4]1175; CHECK-NOVFP-NEXT: pop {r4, pc}1176 %a = load half, ptr %p, align 21177 %r = call half @llvm.tan.f16(half %a)1178 store half %r, ptr %p1179 ret void1180}1181 1182define void @test_pow(ptr %p, ptr %q) #0 {1183; CHECK-FP16-LABEL: test_pow:1184; CHECK-FP16: .save {r4, lr}1185; CHECK-FP16-NEXT: push {r4, lr}1186; CHECK-FP16-NEXT: mov r4, r01187; CHECK-FP16-NEXT: ldrh r0, [r0]1188; CHECK-FP16-NEXT: ldrh r1, [r1]1189; CHECK-FP16-NEXT: vmov s0, r01190; CHECK-FP16-NEXT: vmov s2, r11191; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01192; CHECK-FP16-NEXT: vcvtb.f32.f16 s1, s21193; CHECK-FP16-NEXT: bl powf1194; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01195; CHECK-FP16-NEXT: vmov r0, s01196; CHECK-FP16-NEXT: strh r0, [r4]1197; CHECK-FP16-NEXT: pop {r4, pc}1198;1199; CHECK-LIBCALL-VFP-LABEL: test_pow:1200; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}1201; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}1202; CHECK-LIBCALL-VFP-NEXT: mov r4, r01203; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]1204; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1205; CHECK-LIBCALL-VFP-NEXT: mov r5, r01206; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r4]1207; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1208; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01209; CHECK-LIBCALL-VFP-NEXT: vmov s1, r51210; CHECK-LIBCALL-VFP-NEXT: bl powf1211; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01212; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1213; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1214; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}1215;1216; CHECK-NOVFP-LABEL: test_pow:1217; CHECK-NOVFP: .save {r4, r5, r11, lr}1218; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}1219; CHECK-NOVFP-NEXT: mov r4, r01220; CHECK-NOVFP-NEXT: ldrh r0, [r1]1221; CHECK-NOVFP-NEXT: bl __aeabi_h2f1222; CHECK-NOVFP-NEXT: mov r5, r01223; CHECK-NOVFP-NEXT: ldrh r0, [r4]1224; CHECK-NOVFP-NEXT: bl __aeabi_h2f1225; CHECK-NOVFP-NEXT: mov r1, r51226; CHECK-NOVFP-NEXT: bl powf1227; CHECK-NOVFP-NEXT: bl __aeabi_f2h1228; CHECK-NOVFP-NEXT: strh r0, [r4]1229; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}1230 %a = load half, ptr %p, align 21231 %b = load half, ptr %q, align 21232 %r = call half @llvm.pow.f16(half %a, half %b)1233 store half %r, ptr %p1234 ret void1235}1236 1237define void @test_cbrt(ptr %p) #0 {1238; CHECK-FP16-LABEL: test_cbrt:1239; CHECK-FP16: .save {r4, lr}1240; CHECK-FP16-NEXT: push {r4, lr}1241; CHECK-FP16-NEXT: mov r4, r01242; CHECK-FP16-NEXT: ldrh r0, [r0]1243; CHECK-FP16-NEXT: vldr s1, .LCPI34_01244; CHECK-FP16-NEXT: vmov s0, r01245; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01246; CHECK-FP16-NEXT: bl powf1247; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01248; CHECK-FP16-NEXT: vmov r0, s01249; CHECK-FP16-NEXT: strh r0, [r4]1250; CHECK-FP16-NEXT: pop {r4, pc}1251; CHECK-FP16-NEXT: .p2align 21252; CHECK-FP16-NEXT: .LCPI34_0:1253; CHECK-FP16-NEXT: .long 0x3eaaa0001254;1255; CHECK-LIBCALL-VFP-LABEL: test_cbrt:1256; CHECK-LIBCALL-VFP: .save {r4, lr}1257; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1258; CHECK-LIBCALL-VFP-NEXT: mov r4, r01259; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1260; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1261; CHECK-LIBCALL-VFP-NEXT: vldr s1, .LCPI34_01262; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01263; CHECK-LIBCALL-VFP-NEXT: bl powf1264; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01265; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1266; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1267; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1268; CHECK-LIBCALL-VFP-NEXT: .p2align 21269; CHECK-LIBCALL-VFP-NEXT: .LCPI34_0:1270; CHECK-LIBCALL-VFP-NEXT: .long 0x3eaaa0001271;1272; CHECK-NOVFP-LABEL: test_cbrt:1273; CHECK-NOVFP: .save {r4, lr}1274; CHECK-NOVFP-NEXT: push {r4, lr}1275; CHECK-NOVFP-NEXT: mov r4, r01276; CHECK-NOVFP-NEXT: ldrh r0, [r0]1277; CHECK-NOVFP-NEXT: bl __aeabi_h2f1278; CHECK-NOVFP-NEXT: movw r1, #409601279; CHECK-NOVFP-NEXT: movt r1, #160421280; CHECK-NOVFP-NEXT: bl powf1281; CHECK-NOVFP-NEXT: bl __aeabi_f2h1282; CHECK-NOVFP-NEXT: strh r0, [r4]1283; CHECK-NOVFP-NEXT: pop {r4, pc}1284 %a = load half, ptr %p, align 21285 %r = call half @llvm.pow.f16(half %a, half 0x3FD5540000000000)1286 store half %r, ptr %p1287 ret void1288}1289 1290define void @test_exp(ptr %p) #0 {1291; CHECK-FP16-LABEL: test_exp:1292; CHECK-FP16: .save {r4, lr}1293; CHECK-FP16-NEXT: push {r4, lr}1294; CHECK-FP16-NEXT: mov r4, r01295; CHECK-FP16-NEXT: ldrh r0, [r0]1296; CHECK-FP16-NEXT: vmov s0, r01297; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01298; CHECK-FP16-NEXT: bl expf1299; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01300; CHECK-FP16-NEXT: vmov r0, s01301; CHECK-FP16-NEXT: strh r0, [r4]1302; CHECK-FP16-NEXT: pop {r4, pc}1303;1304; CHECK-LIBCALL-VFP-LABEL: test_exp:1305; CHECK-LIBCALL-VFP: .save {r4, lr}1306; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1307; CHECK-LIBCALL-VFP-NEXT: mov r4, r01308; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1309; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1310; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01311; CHECK-LIBCALL-VFP-NEXT: bl expf1312; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01313; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1314; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1315; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1316;1317; CHECK-NOVFP-LABEL: test_exp:1318; CHECK-NOVFP: .save {r4, lr}1319; CHECK-NOVFP-NEXT: push {r4, lr}1320; CHECK-NOVFP-NEXT: mov r4, r01321; CHECK-NOVFP-NEXT: ldrh r0, [r0]1322; CHECK-NOVFP-NEXT: bl __aeabi_h2f1323; CHECK-NOVFP-NEXT: bl expf1324; CHECK-NOVFP-NEXT: bl __aeabi_f2h1325; CHECK-NOVFP-NEXT: strh r0, [r4]1326; CHECK-NOVFP-NEXT: pop {r4, pc}1327 %a = load half, ptr %p, align 21328 %r = call half @llvm.exp.f16(half %a)1329 store half %r, ptr %p1330 ret void1331}1332 1333define void @test_exp2(ptr %p) #0 {1334; CHECK-FP16-LABEL: test_exp2:1335; CHECK-FP16: .save {r4, lr}1336; CHECK-FP16-NEXT: push {r4, lr}1337; CHECK-FP16-NEXT: mov r4, r01338; CHECK-FP16-NEXT: ldrh r0, [r0]1339; CHECK-FP16-NEXT: vmov s0, r01340; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01341; CHECK-FP16-NEXT: bl exp2f1342; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01343; CHECK-FP16-NEXT: vmov r0, s01344; CHECK-FP16-NEXT: strh r0, [r4]1345; CHECK-FP16-NEXT: pop {r4, pc}1346;1347; CHECK-LIBCALL-VFP-LABEL: test_exp2:1348; CHECK-LIBCALL-VFP: .save {r4, lr}1349; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1350; CHECK-LIBCALL-VFP-NEXT: mov r4, r01351; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1352; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1353; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01354; CHECK-LIBCALL-VFP-NEXT: bl exp2f1355; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01356; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1357; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1358; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1359;1360; CHECK-NOVFP-LABEL: test_exp2:1361; CHECK-NOVFP: .save {r4, lr}1362; CHECK-NOVFP-NEXT: push {r4, lr}1363; CHECK-NOVFP-NEXT: mov r4, r01364; CHECK-NOVFP-NEXT: ldrh r0, [r0]1365; CHECK-NOVFP-NEXT: bl __aeabi_h2f1366; CHECK-NOVFP-NEXT: bl exp2f1367; CHECK-NOVFP-NEXT: bl __aeabi_f2h1368; CHECK-NOVFP-NEXT: strh r0, [r4]1369; CHECK-NOVFP-NEXT: pop {r4, pc}1370 %a = load half, ptr %p, align 21371 %r = call half @llvm.exp2.f16(half %a)1372 store half %r, ptr %p1373 ret void1374}1375 1376define void @test_log(ptr %p) #0 {1377; CHECK-FP16-LABEL: test_log:1378; CHECK-FP16: .save {r4, lr}1379; CHECK-FP16-NEXT: push {r4, lr}1380; CHECK-FP16-NEXT: mov r4, r01381; CHECK-FP16-NEXT: ldrh r0, [r0]1382; CHECK-FP16-NEXT: vmov s0, r01383; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01384; CHECK-FP16-NEXT: bl logf1385; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01386; CHECK-FP16-NEXT: vmov r0, s01387; CHECK-FP16-NEXT: strh r0, [r4]1388; CHECK-FP16-NEXT: pop {r4, pc}1389;1390; CHECK-LIBCALL-VFP-LABEL: test_log:1391; CHECK-LIBCALL-VFP: .save {r4, lr}1392; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1393; CHECK-LIBCALL-VFP-NEXT: mov r4, r01394; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1395; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1396; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01397; CHECK-LIBCALL-VFP-NEXT: bl logf1398; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01399; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1400; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1401; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1402;1403; CHECK-NOVFP-LABEL: test_log:1404; CHECK-NOVFP: .save {r4, lr}1405; CHECK-NOVFP-NEXT: push {r4, lr}1406; CHECK-NOVFP-NEXT: mov r4, r01407; CHECK-NOVFP-NEXT: ldrh r0, [r0]1408; CHECK-NOVFP-NEXT: bl __aeabi_h2f1409; CHECK-NOVFP-NEXT: bl logf1410; CHECK-NOVFP-NEXT: bl __aeabi_f2h1411; CHECK-NOVFP-NEXT: strh r0, [r4]1412; CHECK-NOVFP-NEXT: pop {r4, pc}1413 %a = load half, ptr %p, align 21414 %r = call half @llvm.log.f16(half %a)1415 store half %r, ptr %p1416 ret void1417}1418 1419define void @test_log10(ptr %p) #0 {1420; CHECK-FP16-LABEL: test_log10:1421; CHECK-FP16: .save {r4, lr}1422; CHECK-FP16-NEXT: push {r4, lr}1423; CHECK-FP16-NEXT: mov r4, r01424; CHECK-FP16-NEXT: ldrh r0, [r0]1425; CHECK-FP16-NEXT: vmov s0, r01426; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01427; CHECK-FP16-NEXT: bl log10f1428; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01429; CHECK-FP16-NEXT: vmov r0, s01430; CHECK-FP16-NEXT: strh r0, [r4]1431; CHECK-FP16-NEXT: pop {r4, pc}1432;1433; CHECK-LIBCALL-VFP-LABEL: test_log10:1434; CHECK-LIBCALL-VFP: .save {r4, lr}1435; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1436; CHECK-LIBCALL-VFP-NEXT: mov r4, r01437; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1438; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1439; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01440; CHECK-LIBCALL-VFP-NEXT: bl log10f1441; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01442; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1443; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1444; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1445;1446; CHECK-NOVFP-LABEL: test_log10:1447; CHECK-NOVFP: .save {r4, lr}1448; CHECK-NOVFP-NEXT: push {r4, lr}1449; CHECK-NOVFP-NEXT: mov r4, r01450; CHECK-NOVFP-NEXT: ldrh r0, [r0]1451; CHECK-NOVFP-NEXT: bl __aeabi_h2f1452; CHECK-NOVFP-NEXT: bl log10f1453; CHECK-NOVFP-NEXT: bl __aeabi_f2h1454; CHECK-NOVFP-NEXT: strh r0, [r4]1455; CHECK-NOVFP-NEXT: pop {r4, pc}1456 %a = load half, ptr %p, align 21457 %r = call half @llvm.log10.f16(half %a)1458 store half %r, ptr %p1459 ret void1460}1461 1462define void @test_log2(ptr %p) #0 {1463; CHECK-FP16-LABEL: test_log2:1464; CHECK-FP16: .save {r4, lr}1465; CHECK-FP16-NEXT: push {r4, lr}1466; CHECK-FP16-NEXT: mov r4, r01467; CHECK-FP16-NEXT: ldrh r0, [r0]1468; CHECK-FP16-NEXT: vmov s0, r01469; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01470; CHECK-FP16-NEXT: bl log2f1471; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01472; CHECK-FP16-NEXT: vmov r0, s01473; CHECK-FP16-NEXT: strh r0, [r4]1474; CHECK-FP16-NEXT: pop {r4, pc}1475;1476; CHECK-LIBCALL-VFP-LABEL: test_log2:1477; CHECK-LIBCALL-VFP: .save {r4, lr}1478; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1479; CHECK-LIBCALL-VFP-NEXT: mov r4, r01480; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1481; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1482; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01483; CHECK-LIBCALL-VFP-NEXT: bl log2f1484; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01485; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1486; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1487; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1488;1489; CHECK-NOVFP-LABEL: test_log2:1490; CHECK-NOVFP: .save {r4, lr}1491; CHECK-NOVFP-NEXT: push {r4, lr}1492; CHECK-NOVFP-NEXT: mov r4, r01493; CHECK-NOVFP-NEXT: ldrh r0, [r0]1494; CHECK-NOVFP-NEXT: bl __aeabi_h2f1495; CHECK-NOVFP-NEXT: bl log2f1496; CHECK-NOVFP-NEXT: bl __aeabi_f2h1497; CHECK-NOVFP-NEXT: strh r0, [r4]1498; CHECK-NOVFP-NEXT: pop {r4, pc}1499 %a = load half, ptr %p, align 21500 %r = call half @llvm.log2.f16(half %a)1501 store half %r, ptr %p1502 ret void1503}1504 1505define void @test_fma(ptr %p, ptr %q, ptr %r) #0 {1506; CHECK-FP16-LABEL: test_fma:1507; CHECK-FP16: .save {r4, lr}1508; CHECK-FP16-NEXT: push {r4, lr}1509; CHECK-FP16-NEXT: mov r4, r01510; CHECK-FP16-NEXT: ldrh r0, [r1]1511; CHECK-FP16-NEXT: ldrh r1, [r4]1512; CHECK-FP16-NEXT: ldrh r2, [r2]1513; CHECK-FP16-NEXT: vmov s2, r01514; CHECK-FP16-NEXT: vmov s0, r11515; CHECK-FP16-NEXT: vcvtb.f32.f16 s1, s21516; CHECK-FP16-NEXT: vmov s2, r21517; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01518; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s21519; CHECK-FP16-NEXT: bl fmaf1520; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01521; CHECK-FP16-NEXT: vmov r0, s01522; CHECK-FP16-NEXT: strh r0, [r4]1523; CHECK-FP16-NEXT: pop {r4, pc}1524;1525; CHECK-LIBCALL-VFP-LABEL: test_fma:1526; CHECK-LIBCALL-VFP: .save {r4, r5, r6, lr}1527; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r6, lr}1528; CHECK-LIBCALL-VFP-NEXT: mov r4, r01529; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r2]1530; CHECK-LIBCALL-VFP-NEXT: mov r5, r11531; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1532; CHECK-LIBCALL-VFP-NEXT: mov r6, r01533; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r5]1534; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1535; CHECK-LIBCALL-VFP-NEXT: mov r5, r01536; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r4]1537; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1538; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01539; CHECK-LIBCALL-VFP-NEXT: vmov s1, r51540; CHECK-LIBCALL-VFP-NEXT: vmov s2, r61541; CHECK-LIBCALL-VFP-NEXT: bl fmaf1542; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01543; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1544; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1545; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r6, pc}1546;1547; CHECK-NOVFP-LABEL: test_fma:1548; CHECK-NOVFP: .save {r4, r5, r6, lr}1549; CHECK-NOVFP-NEXT: push {r4, r5, r6, lr}1550; CHECK-NOVFP-NEXT: mov r4, r01551; CHECK-NOVFP-NEXT: ldrh r0, [r1]1552; CHECK-NOVFP-NEXT: mov r5, r21553; CHECK-NOVFP-NEXT: bl __aeabi_h2f1554; CHECK-NOVFP-NEXT: mov r6, r01555; CHECK-NOVFP-NEXT: ldrh r0, [r5]1556; CHECK-NOVFP-NEXT: bl __aeabi_h2f1557; CHECK-NOVFP-NEXT: mov r5, r01558; CHECK-NOVFP-NEXT: ldrh r0, [r4]1559; CHECK-NOVFP-NEXT: bl __aeabi_h2f1560; CHECK-NOVFP-NEXT: mov r1, r61561; CHECK-NOVFP-NEXT: mov r2, r51562; CHECK-NOVFP-NEXT: bl fmaf1563; CHECK-NOVFP-NEXT: bl __aeabi_f2h1564; CHECK-NOVFP-NEXT: strh r0, [r4]1565; CHECK-NOVFP-NEXT: pop {r4, r5, r6, pc}1566 %a = load half, ptr %p, align 21567 %b = load half, ptr %q, align 21568 %c = load half, ptr %r, align 21569 %v = call half @llvm.fma.f16(half %a, half %b, half %c)1570 store half %v, ptr %p1571 ret void1572}1573 1574define void @test_fabs(ptr %p) {1575; CHECK-ALL-LABEL: test_fabs:1576; CHECK-ALL: ldrh r1, [r0]1577; CHECK-ALL-NEXT: bfc r1, #15, #171578; CHECK-ALL-NEXT: strh r1, [r0]1579; CHECK-ALL-NEXT: bx lr1580 %a = load half, ptr %p, align 21581 %r = call half @llvm.fabs.f16(half %a)1582 store half %r, ptr %p1583 ret void1584}1585 1586define void @test_minnum(ptr %p, ptr %q) #0 {1587; CHECK-FP16-LABEL: test_minnum:1588; CHECK-FP16: .save {r4, lr}1589; CHECK-FP16-NEXT: push {r4, lr}1590; CHECK-FP16-NEXT: mov r4, r01591; CHECK-FP16-NEXT: ldrh r0, [r0]1592; CHECK-FP16-NEXT: ldrh r1, [r1]1593; CHECK-FP16-NEXT: vmov s0, r01594; CHECK-FP16-NEXT: vmov s2, r11595; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01596; CHECK-FP16-NEXT: vcvtb.f32.f16 s1, s21597; CHECK-FP16-NEXT: bl fminf1598; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01599; CHECK-FP16-NEXT: vmov r0, s01600; CHECK-FP16-NEXT: strh r0, [r4]1601; CHECK-FP16-NEXT: pop {r4, pc}1602;1603; CHECK-LIBCALL-VFP-LABEL: test_minnum:1604; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}1605; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}1606; CHECK-LIBCALL-VFP-NEXT: mov r4, r01607; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]1608; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1609; CHECK-LIBCALL-VFP-NEXT: mov r5, r01610; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r4]1611; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1612; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01613; CHECK-LIBCALL-VFP-NEXT: vmov s1, r51614; CHECK-LIBCALL-VFP-NEXT: bl fminf1615; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01616; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1617; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1618; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}1619;1620; CHECK-NOVFP-LABEL: test_minnum:1621; CHECK-NOVFP: .save {r4, r5, r11, lr}1622; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}1623; CHECK-NOVFP-NEXT: mov r4, r01624; CHECK-NOVFP-NEXT: ldrh r0, [r1]1625; CHECK-NOVFP-NEXT: bl __aeabi_h2f1626; CHECK-NOVFP-NEXT: mov r5, r01627; CHECK-NOVFP-NEXT: ldrh r0, [r4]1628; CHECK-NOVFP-NEXT: bl __aeabi_h2f1629; CHECK-NOVFP-NEXT: mov r1, r51630; CHECK-NOVFP-NEXT: bl fminf1631; CHECK-NOVFP-NEXT: bl __aeabi_f2h1632; CHECK-NOVFP-NEXT: strh r0, [r4]1633; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}1634 %a = load half, ptr %p, align 21635 %b = load half, ptr %q, align 21636 %r = call half @llvm.minnum.f16(half %a, half %b)1637 store half %r, ptr %p1638 ret void1639}1640 1641define void @test_maxnum(ptr %p, ptr %q) #0 {1642; CHECK-FP16-LABEL: test_maxnum:1643; CHECK-FP16: .save {r4, lr}1644; CHECK-FP16-NEXT: push {r4, lr}1645; CHECK-FP16-NEXT: mov r4, r01646; CHECK-FP16-NEXT: ldrh r0, [r0]1647; CHECK-FP16-NEXT: ldrh r1, [r1]1648; CHECK-FP16-NEXT: vmov s0, r01649; CHECK-FP16-NEXT: vmov s2, r11650; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01651; CHECK-FP16-NEXT: vcvtb.f32.f16 s1, s21652; CHECK-FP16-NEXT: bl fmaxf1653; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01654; CHECK-FP16-NEXT: vmov r0, s01655; CHECK-FP16-NEXT: strh r0, [r4]1656; CHECK-FP16-NEXT: pop {r4, pc}1657;1658; CHECK-LIBCALL-VFP-LABEL: test_maxnum:1659; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}1660; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}1661; CHECK-LIBCALL-VFP-NEXT: mov r4, r01662; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]1663; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1664; CHECK-LIBCALL-VFP-NEXT: mov r5, r01665; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r4]1666; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1667; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01668; CHECK-LIBCALL-VFP-NEXT: vmov s1, r51669; CHECK-LIBCALL-VFP-NEXT: bl fmaxf1670; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01671; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1672; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1673; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}1674;1675; CHECK-NOVFP-LABEL: test_maxnum:1676; CHECK-NOVFP: .save {r4, r5, r11, lr}1677; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}1678; CHECK-NOVFP-NEXT: mov r4, r01679; CHECK-NOVFP-NEXT: ldrh r0, [r1]1680; CHECK-NOVFP-NEXT: bl __aeabi_h2f1681; CHECK-NOVFP-NEXT: mov r5, r01682; CHECK-NOVFP-NEXT: ldrh r0, [r4]1683; CHECK-NOVFP-NEXT: bl __aeabi_h2f1684; CHECK-NOVFP-NEXT: mov r1, r51685; CHECK-NOVFP-NEXT: bl fmaxf1686; CHECK-NOVFP-NEXT: bl __aeabi_f2h1687; CHECK-NOVFP-NEXT: strh r0, [r4]1688; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}1689 %a = load half, ptr %p, align 21690 %b = load half, ptr %q, align 21691 %r = call half @llvm.maxnum.f16(half %a, half %b)1692 store half %r, ptr %p1693 ret void1694}1695 1696define void @test_minimum(ptr %p) #0 {1697; CHECK-FP16-LABEL: test_minimum:1698; CHECK-FP16: vmov.f32 s0, #1.000000e+001699; CHECK-FP16-NEXT: ldrh r1, [r0]1700; CHECK-FP16-NEXT: vmov s2, r11701; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s21702; CHECK-FP16-NEXT: vcmp.f32 s2, s01703; CHECK-FP16-NEXT: vmrs APSR_nzcv, fpscr1704; CHECK-FP16-NEXT: movge r1, #153601705; CHECK-FP16-NEXT: strh r1, [r0]1706; CHECK-FP16-NEXT: bx lr1707;1708; CHECK-LIBCALL-VFP-LABEL: test_minimum:1709; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}1710; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}1711; CHECK-LIBCALL-VFP-NEXT: ldrh r5, [r0]1712; CHECK-LIBCALL-VFP-NEXT: mov r4, r01713; CHECK-LIBCALL-VFP-NEXT: mov r0, r51714; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1715; CHECK-LIBCALL-VFP-NEXT: vmov.f32 s0, #1.000000e+001716; CHECK-LIBCALL-VFP-NEXT: vmov s2, r01717; CHECK-LIBCALL-VFP-NEXT: vcmp.f32 s2, s01718; CHECK-LIBCALL-VFP-NEXT: vmrs APSR_nzcv, fpscr1719; CHECK-LIBCALL-VFP-NEXT: movge r5, #153601720; CHECK-LIBCALL-VFP-NEXT: strh r5, [r4]1721; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}1722;1723; CHECK-NOVFP-LABEL: test_minimum:1724; CHECK-NOVFP: .save {r4, r5, r11, lr}1725; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}1726; CHECK-NOVFP-NEXT: ldrh r5, [r0]1727; CHECK-NOVFP-NEXT: mov r4, r01728; CHECK-NOVFP-NEXT: mov r0, r51729; CHECK-NOVFP-NEXT: bl __aeabi_h2f1730; CHECK-NOVFP-NEXT: mov r1, #10653532161731; CHECK-NOVFP-NEXT: bl __aeabi_fcmpge1732; CHECK-NOVFP-NEXT: cmp r0, #01733; CHECK-NOVFP-NEXT: movne r5, #153601734; CHECK-NOVFP-NEXT: strh r5, [r4]1735; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}1736 %a = load half, ptr %p, align 21737 %c = fcmp ult half %a, 1.01738 %r = select i1 %c, half %a, half 1.01739 store half %r, ptr %p1740 ret void1741}1742 1743define void @test_maximum(ptr %p) #0 {1744; CHECK-FP16-LABEL: test_maximum:1745; CHECK-FP16: vmov.f32 s0, #1.000000e+001746; CHECK-FP16-NEXT: ldrh r1, [r0]1747; CHECK-FP16-NEXT: vmov s2, r11748; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s21749; CHECK-FP16-NEXT: vcmp.f32 s2, s01750; CHECK-FP16-NEXT: vmrs APSR_nzcv, fpscr1751; CHECK-FP16-NEXT: movls r1, #153601752; CHECK-FP16-NEXT: strh r1, [r0]1753; CHECK-FP16-NEXT: bx lr1754;1755; CHECK-LIBCALL-VFP-LABEL: test_maximum:1756; CHECK-LIBCALL-VFP: .save {r4, r5, r11, lr}1757; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r11, lr}1758; CHECK-LIBCALL-VFP-NEXT: ldrh r5, [r0]1759; CHECK-LIBCALL-VFP-NEXT: mov r4, r01760; CHECK-LIBCALL-VFP-NEXT: mov r0, r51761; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1762; CHECK-LIBCALL-VFP-NEXT: vmov.f32 s0, #1.000000e+001763; CHECK-LIBCALL-VFP-NEXT: vmov s2, r01764; CHECK-LIBCALL-VFP-NEXT: vcmp.f32 s2, s01765; CHECK-LIBCALL-VFP-NEXT: vmrs APSR_nzcv, fpscr1766; CHECK-LIBCALL-VFP-NEXT: movls r5, #153601767; CHECK-LIBCALL-VFP-NEXT: strh r5, [r4]1768; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r11, pc}1769;1770; CHECK-NOVFP-LABEL: test_maximum:1771; CHECK-NOVFP: .save {r4, r5, r11, lr}1772; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}1773; CHECK-NOVFP-NEXT: ldrh r5, [r0]1774; CHECK-NOVFP-NEXT: mov r4, r01775; CHECK-NOVFP-NEXT: mov r0, r51776; CHECK-NOVFP-NEXT: bl __aeabi_h2f1777; CHECK-NOVFP-NEXT: mov r1, #10653532161778; CHECK-NOVFP-NEXT: bl __aeabi_fcmple1779; CHECK-NOVFP-NEXT: cmp r0, #01780; CHECK-NOVFP-NEXT: movne r5, #153601781; CHECK-NOVFP-NEXT: strh r5, [r4]1782; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}1783 %a = load half, ptr %p, align 21784 %c = fcmp ugt half %a, 1.01785 %r = select i1 %c, half %a, half 1.01786 store half %r, ptr %p1787 ret void1788}1789 1790define void @test_copysign(ptr %p, ptr %q) #0 {1791; CHECK-ALL-LABEL: test_copysign:1792; CHECK-ALL: ldrh r2, [r0]1793; CHECK-ALL-NEXT: ldrh r1, [r1]1794; CHECK-ALL-NEXT: and r1, r1, #327681795; CHECK-ALL-NEXT: bfc r2, #15, #171796; CHECK-ALL-NEXT: orr r1, r2, r11797; CHECK-ALL-NEXT: strh r1, [r0]1798; CHECK-ALL-NEXT: bx lr1799 %a = load half, ptr %p, align 21800 %b = load half, ptr %q, align 21801 %r = call half @llvm.copysign.f16(half %a, half %b)1802 store half %r, ptr %p1803 ret void1804}1805 1806define void @test_floor(ptr %p) {1807; CHECK-FP16-LABEL: test_floor:1808; CHECK-FP16: .save {r4, lr}1809; CHECK-FP16-NEXT: push {r4, lr}1810; CHECK-FP16-NEXT: mov r4, r01811; CHECK-FP16-NEXT: ldrh r0, [r0]1812; CHECK-FP16-NEXT: vmov s0, r01813; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01814; CHECK-FP16-NEXT: bl floorf1815; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01816; CHECK-FP16-NEXT: vmov r0, s01817; CHECK-FP16-NEXT: strh r0, [r4]1818; CHECK-FP16-NEXT: pop {r4, pc}1819;1820; CHECK-LIBCALL-VFP-LABEL: test_floor:1821; CHECK-LIBCALL-VFP: .save {r4, lr}1822; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1823; CHECK-LIBCALL-VFP-NEXT: mov r4, r01824; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1825; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1826; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01827; CHECK-LIBCALL-VFP-NEXT: bl floorf1828; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01829; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1830; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1831; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1832;1833; CHECK-NOVFP-LABEL: test_floor:1834; CHECK-NOVFP: .save {r4, lr}1835; CHECK-NOVFP-NEXT: push {r4, lr}1836; CHECK-NOVFP-NEXT: mov r4, r01837; CHECK-NOVFP-NEXT: ldrh r0, [r0]1838; CHECK-NOVFP-NEXT: bl __aeabi_h2f1839; CHECK-NOVFP-NEXT: bl floorf1840; CHECK-NOVFP-NEXT: bl __aeabi_f2h1841; CHECK-NOVFP-NEXT: strh r0, [r4]1842; CHECK-NOVFP-NEXT: pop {r4, pc}1843 %a = load half, ptr %p, align 21844 %r = call half @llvm.floor.f16(half %a)1845 store half %r, ptr %p1846 ret void1847}1848 1849define void @test_ceil(ptr %p) {1850; CHECK-FP16-LABEL: test_ceil:1851; CHECK-FP16: .save {r4, lr}1852; CHECK-FP16-NEXT: push {r4, lr}1853; CHECK-FP16-NEXT: mov r4, r01854; CHECK-FP16-NEXT: ldrh r0, [r0]1855; CHECK-FP16-NEXT: vmov s0, r01856; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01857; CHECK-FP16-NEXT: bl ceilf1858; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01859; CHECK-FP16-NEXT: vmov r0, s01860; CHECK-FP16-NEXT: strh r0, [r4]1861; CHECK-FP16-NEXT: pop {r4, pc}1862;1863; CHECK-LIBCALL-VFP-LABEL: test_ceil:1864; CHECK-LIBCALL-VFP: .save {r4, lr}1865; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1866; CHECK-LIBCALL-VFP-NEXT: mov r4, r01867; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1868; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1869; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01870; CHECK-LIBCALL-VFP-NEXT: bl ceilf1871; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01872; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1873; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1874; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1875;1876; CHECK-NOVFP-LABEL: test_ceil:1877; CHECK-NOVFP: .save {r4, lr}1878; CHECK-NOVFP-NEXT: push {r4, lr}1879; CHECK-NOVFP-NEXT: mov r4, r01880; CHECK-NOVFP-NEXT: ldrh r0, [r0]1881; CHECK-NOVFP-NEXT: bl __aeabi_h2f1882; CHECK-NOVFP-NEXT: bl ceilf1883; CHECK-NOVFP-NEXT: bl __aeabi_f2h1884; CHECK-NOVFP-NEXT: strh r0, [r4]1885; CHECK-NOVFP-NEXT: pop {r4, pc}1886 %a = load half, ptr %p, align 21887 %r = call half @llvm.ceil.f16(half %a)1888 store half %r, ptr %p1889 ret void1890}1891 1892define void @test_trunc(ptr %p) {1893; CHECK-FP16-LABEL: test_trunc:1894; CHECK-FP16: .save {r4, lr}1895; CHECK-FP16-NEXT: push {r4, lr}1896; CHECK-FP16-NEXT: mov r4, r01897; CHECK-FP16-NEXT: ldrh r0, [r0]1898; CHECK-FP16-NEXT: vmov s0, r01899; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01900; CHECK-FP16-NEXT: bl truncf1901; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01902; CHECK-FP16-NEXT: vmov r0, s01903; CHECK-FP16-NEXT: strh r0, [r4]1904; CHECK-FP16-NEXT: pop {r4, pc}1905;1906; CHECK-LIBCALL-VFP-LABEL: test_trunc:1907; CHECK-LIBCALL-VFP: .save {r4, lr}1908; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1909; CHECK-LIBCALL-VFP-NEXT: mov r4, r01910; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1911; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1912; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01913; CHECK-LIBCALL-VFP-NEXT: bl truncf1914; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01915; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1916; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1917; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1918;1919; CHECK-NOVFP-LABEL: test_trunc:1920; CHECK-NOVFP: .save {r4, lr}1921; CHECK-NOVFP-NEXT: push {r4, lr}1922; CHECK-NOVFP-NEXT: mov r4, r01923; CHECK-NOVFP-NEXT: ldrh r0, [r0]1924; CHECK-NOVFP-NEXT: bl __aeabi_h2f1925; CHECK-NOVFP-NEXT: bl truncf1926; CHECK-NOVFP-NEXT: bl __aeabi_f2h1927; CHECK-NOVFP-NEXT: strh r0, [r4]1928; CHECK-NOVFP-NEXT: pop {r4, pc}1929 %a = load half, ptr %p, align 21930 %r = call half @llvm.trunc.f16(half %a)1931 store half %r, ptr %p1932 ret void1933}1934 1935define void @test_rint(ptr %p) {1936; CHECK-FP16-LABEL: test_rint:1937; CHECK-FP16: .save {r4, lr}1938; CHECK-FP16-NEXT: push {r4, lr}1939; CHECK-FP16-NEXT: mov r4, r01940; CHECK-FP16-NEXT: ldrh r0, [r0]1941; CHECK-FP16-NEXT: vmov s0, r01942; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01943; CHECK-FP16-NEXT: bl rintf1944; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01945; CHECK-FP16-NEXT: vmov r0, s01946; CHECK-FP16-NEXT: strh r0, [r4]1947; CHECK-FP16-NEXT: pop {r4, pc}1948;1949; CHECK-LIBCALL-VFP-LABEL: test_rint:1950; CHECK-LIBCALL-VFP: .save {r4, lr}1951; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1952; CHECK-LIBCALL-VFP-NEXT: mov r4, r01953; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1954; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1955; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01956; CHECK-LIBCALL-VFP-NEXT: bl rintf1957; CHECK-LIBCALL-VFP-NEXT: vmov r0, s01958; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h1959; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]1960; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}1961;1962; CHECK-NOVFP-LABEL: test_rint:1963; CHECK-NOVFP: .save {r4, lr}1964; CHECK-NOVFP-NEXT: push {r4, lr}1965; CHECK-NOVFP-NEXT: mov r4, r01966; CHECK-NOVFP-NEXT: ldrh r0, [r0]1967; CHECK-NOVFP-NEXT: bl __aeabi_h2f1968; CHECK-NOVFP-NEXT: bl rintf1969; CHECK-NOVFP-NEXT: bl __aeabi_f2h1970; CHECK-NOVFP-NEXT: strh r0, [r4]1971; CHECK-NOVFP-NEXT: pop {r4, pc}1972 %a = load half, ptr %p, align 21973 %r = call half @llvm.rint.f16(half %a)1974 store half %r, ptr %p1975 ret void1976}1977 1978define void @test_nearbyint(ptr %p) {1979; CHECK-FP16-LABEL: test_nearbyint:1980; CHECK-FP16: .save {r4, lr}1981; CHECK-FP16-NEXT: push {r4, lr}1982; CHECK-FP16-NEXT: mov r4, r01983; CHECK-FP16-NEXT: ldrh r0, [r0]1984; CHECK-FP16-NEXT: vmov s0, r01985; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s01986; CHECK-FP16-NEXT: bl nearbyintf1987; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s01988; CHECK-FP16-NEXT: vmov r0, s01989; CHECK-FP16-NEXT: strh r0, [r4]1990; CHECK-FP16-NEXT: pop {r4, pc}1991;1992; CHECK-LIBCALL-VFP-LABEL: test_nearbyint:1993; CHECK-LIBCALL-VFP: .save {r4, lr}1994; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}1995; CHECK-LIBCALL-VFP-NEXT: mov r4, r01996; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]1997; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f1998; CHECK-LIBCALL-VFP-NEXT: vmov s0, r01999; CHECK-LIBCALL-VFP-NEXT: bl nearbyintf2000; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02001; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2002; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]2003; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}2004;2005; CHECK-NOVFP-LABEL: test_nearbyint:2006; CHECK-NOVFP: .save {r4, lr}2007; CHECK-NOVFP-NEXT: push {r4, lr}2008; CHECK-NOVFP-NEXT: mov r4, r02009; CHECK-NOVFP-NEXT: ldrh r0, [r0]2010; CHECK-NOVFP-NEXT: bl __aeabi_h2f2011; CHECK-NOVFP-NEXT: bl nearbyintf2012; CHECK-NOVFP-NEXT: bl __aeabi_f2h2013; CHECK-NOVFP-NEXT: strh r0, [r4]2014; CHECK-NOVFP-NEXT: pop {r4, pc}2015 %a = load half, ptr %p, align 22016 %r = call half @llvm.nearbyint.f16(half %a)2017 store half %r, ptr %p2018 ret void2019}2020 2021define void @test_round(ptr %p) {2022; CHECK-FP16-LABEL: test_round:2023; CHECK-FP16: .save {r4, lr}2024; CHECK-FP16-NEXT: push {r4, lr}2025; CHECK-FP16-NEXT: mov r4, r02026; CHECK-FP16-NEXT: ldrh r0, [r0]2027; CHECK-FP16-NEXT: vmov s0, r02028; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s02029; CHECK-FP16-NEXT: bl roundf2030; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s02031; CHECK-FP16-NEXT: vmov r0, s02032; CHECK-FP16-NEXT: strh r0, [r4]2033; CHECK-FP16-NEXT: pop {r4, pc}2034;2035; CHECK-LIBCALL-VFP-LABEL: test_round:2036; CHECK-LIBCALL-VFP: .save {r4, lr}2037; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}2038; CHECK-LIBCALL-VFP-NEXT: mov r4, r02039; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]2040; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2041; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02042; CHECK-LIBCALL-VFP-NEXT: bl roundf2043; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02044; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2045; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]2046; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}2047;2048; CHECK-NOVFP-LABEL: test_round:2049; CHECK-NOVFP: .save {r4, lr}2050; CHECK-NOVFP-NEXT: push {r4, lr}2051; CHECK-NOVFP-NEXT: mov r4, r02052; CHECK-NOVFP-NEXT: ldrh r0, [r0]2053; CHECK-NOVFP-NEXT: bl __aeabi_h2f2054; CHECK-NOVFP-NEXT: bl roundf2055; CHECK-NOVFP-NEXT: bl __aeabi_f2h2056; CHECK-NOVFP-NEXT: strh r0, [r4]2057; CHECK-NOVFP-NEXT: pop {r4, pc}2058 %a = load half, ptr %p, align 22059 %r = call half @llvm.round.f16(half %a)2060 store half %r, ptr %p2061 ret void2062}2063 2064define void @test_roundeven(ptr %p) {2065; CHECK-FP16-LABEL: test_roundeven:2066; CHECK-FP16: .save {r4, lr}2067; CHECK-FP16-NEXT: push {r4, lr}2068; CHECK-FP16-NEXT: mov r4, r02069; CHECK-FP16-NEXT: ldrh r0, [r0]2070; CHECK-FP16-NEXT: vmov s0, r02071; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s02072; CHECK-FP16-NEXT: bl roundevenf2073; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s02074; CHECK-FP16-NEXT: vmov r0, s02075; CHECK-FP16-NEXT: strh r0, [r4]2076; CHECK-FP16-NEXT: pop {r4, pc}2077;2078; CHECK-LIBCALL-VFP-LABEL: test_roundeven:2079; CHECK-LIBCALL-VFP: .save {r4, lr}2080; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}2081; CHECK-LIBCALL-VFP-NEXT: mov r4, r02082; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r0]2083; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2084; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02085; CHECK-LIBCALL-VFP-NEXT: bl roundevenf2086; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02087; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2088; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]2089; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}2090;2091; CHECK-NOVFP-LABEL: test_roundeven:2092; CHECK-NOVFP: .save {r4, lr}2093; CHECK-NOVFP-NEXT: push {r4, lr}2094; CHECK-NOVFP-NEXT: mov r4, r02095; CHECK-NOVFP-NEXT: ldrh r0, [r0]2096; CHECK-NOVFP-NEXT: bl __aeabi_h2f2097; CHECK-NOVFP-NEXT: bl roundevenf2098; CHECK-NOVFP-NEXT: bl __aeabi_f2h2099; CHECK-NOVFP-NEXT: strh r0, [r4]2100; CHECK-NOVFP-NEXT: pop {r4, pc}2101 %a = load half, ptr %p, align 22102 %r = call half @llvm.roundeven.f16(half %a)2103 store half %r, ptr %p2104 ret void2105}2106 2107define void @test_fmuladd(ptr %p, ptr %q, ptr %r) #0 {2108; CHECK-FP16-LABEL: test_fmuladd:2109; CHECK-FP16: ldrh r3, [r0]2110; CHECK-FP16-NEXT: ldrh r1, [r1]2111; CHECK-FP16-NEXT: ldrh r2, [r2]2112; CHECK-FP16-NEXT: vmov s0, r32113; CHECK-FP16-NEXT: vmov s2, r12114; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s02115; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s22116; CHECK-FP16-NEXT: vmul.f32 s0, s0, s22117; CHECK-FP16-NEXT: vmov s2, r22118; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s02119; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s22120; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s02121; CHECK-FP16-NEXT: vadd.f32 s0, s0, s22122; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s02123; CHECK-FP16-NEXT: vmov r1, s02124; CHECK-FP16-NEXT: strh r1, [r0]2125; CHECK-FP16-NEXT: bx lr2126;2127; CHECK-LIBCALL-VFP-LABEL: test_fmuladd:2128; CHECK-LIBCALL-VFP: .save {r4, r5, r6, lr}2129; CHECK-LIBCALL-VFP-NEXT: push {r4, r5, r6, lr}2130; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}2131; CHECK-LIBCALL-VFP-NEXT: vpush {d8}2132; CHECK-LIBCALL-VFP-NEXT: mov r4, r02133; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r1]2134; CHECK-LIBCALL-VFP-NEXT: mov r5, r22135; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2136; CHECK-LIBCALL-VFP-NEXT: ldrh r1, [r4]2137; CHECK-LIBCALL-VFP-NEXT: vmov s16, r02138; CHECK-LIBCALL-VFP-NEXT: mov r0, r12139; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2140; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02141; CHECK-LIBCALL-VFP-NEXT: vmul.f32 s0, s0, s162142; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02143; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2144; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2145; CHECK-LIBCALL-VFP-NEXT: mov r6, r02146; CHECK-LIBCALL-VFP-NEXT: ldrh r0, [r5]2147; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2148; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02149; CHECK-LIBCALL-VFP-NEXT: vmov s2, r62150; CHECK-LIBCALL-VFP-NEXT: vadd.f32 s0, s2, s02151; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02152; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2153; CHECK-LIBCALL-VFP-NEXT: strh r0, [r4]2154; CHECK-LIBCALL-VFP-NEXT: vpop {d8}2155; CHECK-LIBCALL-VFP-NEXT: pop {r4, r5, r6, pc}2156;2157; CHECK-NOVFP-LABEL: test_fmuladd:2158; CHECK-NOVFP: .save {r4, r5, r6, lr}2159; CHECK-NOVFP-NEXT: push {r4, r5, r6, lr}2160; CHECK-NOVFP-NEXT: mov r4, r02161; CHECK-NOVFP-NEXT: ldrh r0, [r1]2162; CHECK-NOVFP-NEXT: mov r5, r22163; CHECK-NOVFP-NEXT: bl __aeabi_h2f2164; CHECK-NOVFP-NEXT: mov r6, r02165; CHECK-NOVFP-NEXT: ldrh r0, [r4]2166; CHECK-NOVFP-NEXT: bl __aeabi_h2f2167; CHECK-NOVFP-NEXT: mov r1, r62168; CHECK-NOVFP-NEXT: bl __aeabi_fmul2169; CHECK-NOVFP-NEXT: bl __aeabi_f2h2170; CHECK-NOVFP-NEXT: mov r6, r02171; CHECK-NOVFP-NEXT: ldrh r0, [r5]2172; CHECK-NOVFP-NEXT: bl __aeabi_h2f2173; CHECK-NOVFP-NEXT: mov r5, r02174; CHECK-NOVFP-NEXT: uxth r0, r62175; CHECK-NOVFP-NEXT: bl __aeabi_h2f2176; CHECK-NOVFP-NEXT: mov r1, r52177; CHECK-NOVFP-NEXT: bl __aeabi_fadd2178; CHECK-NOVFP-NEXT: bl __aeabi_f2h2179; CHECK-NOVFP-NEXT: strh r0, [r4]2180; CHECK-NOVFP-NEXT: pop {r4, r5, r6, pc}2181 %a = load half, ptr %p, align 22182 %b = load half, ptr %q, align 22183 %c = load half, ptr %r, align 22184 %v = call half @llvm.fmuladd.f16(half %a, half %b, half %c)2185 store half %v, ptr %p2186 ret void2187}2188 2189; f16 vectors are not legal in the backend. Vector elements are not assigned2190; to the register, but are stored in the stack instead. Hence insertelement2191; and extractelement have these extra loads and stores.2192define void @test_insertelement(ptr %p, ptr %q, i32 %i) #0 {2193; CHECK-VFP-LABEL: test_insertelement:2194; CHECK-VFP: .save {r4, r5, r11, lr}2195; CHECK-VFP-NEXT: push {r4, r5, r11, lr}2196; CHECK-VFP-NEXT: .pad #82197; CHECK-VFP-NEXT: sub sp, sp, #82198; CHECK-VFP-NEXT: and r2, r2, #32199; CHECK-VFP-NEXT: mov r3, sp2200; CHECK-VFP-NEXT: ldrd r4, r5, [r1]2201; CHECK-VFP-NEXT: orr r2, r3, r2, lsl #12202; CHECK-VFP-NEXT: ldrh r0, [r0]2203; CHECK-VFP-NEXT: stm sp, {r4, r5}2204; CHECK-VFP-NEXT: strh r0, [r2]2205; CHECK-VFP-NEXT: ldrh r0, [sp, #6]2206; CHECK-VFP-NEXT: ldrh r2, [sp, #4]2207; CHECK-VFP-NEXT: ldrh r3, [sp, #2]2208; CHECK-VFP-NEXT: ldrh r5, [sp]2209; CHECK-VFP-NEXT: strh r0, [r1, #6]2210; CHECK-VFP-NEXT: strh r2, [r1, #4]2211; CHECK-VFP-NEXT: strh r3, [r1, #2]2212; CHECK-VFP-NEXT: strh r5, [r1]2213; CHECK-VFP-NEXT: add sp, sp, #82214; CHECK-VFP-NEXT: pop {r4, r5, r11, pc}2215;2216; CHECK-NOVFP-LABEL: test_insertelement:2217; CHECK-NOVFP: .save {r4, r5, r11, lr}2218; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}2219; CHECK-NOVFP-NEXT: .pad #82220; CHECK-NOVFP-NEXT: sub sp, sp, #82221; CHECK-NOVFP-NEXT: ldrd r4, r5, [r1]2222; CHECK-NOVFP-NEXT: and r2, r2, #32223; CHECK-NOVFP-NEXT: mov r3, sp2224; CHECK-NOVFP-NEXT: stm sp, {r4, r5}2225; CHECK-NOVFP-NEXT: orr r2, r3, r2, lsl #12226; CHECK-NOVFP-NEXT: ldrh r0, [r0]2227; CHECK-NOVFP-NEXT: strh r0, [r2]2228; CHECK-NOVFP-NEXT: ldrh r0, [sp, #6]2229; CHECK-NOVFP-NEXT: strh r0, [r1, #6]2230; CHECK-NOVFP-NEXT: ldrh r0, [sp, #4]2231; CHECK-NOVFP-NEXT: strh r0, [r1, #4]2232; CHECK-NOVFP-NEXT: ldrh r0, [sp, #2]2233; CHECK-NOVFP-NEXT: strh r0, [r1, #2]2234; CHECK-NOVFP-NEXT: ldrh r0, [sp]2235; CHECK-NOVFP-NEXT: strh r0, [r1]2236; CHECK-NOVFP-NEXT: add sp, sp, #82237; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}2238 2239 2240 %a = load half, ptr %p, align 22241 %b = load <4 x half>, ptr %q, align 82242 %c = insertelement <4 x half> %b, half %a, i32 %i2243 store volatile <4 x half> %c, ptr %q2244 ret void2245}2246 2247define void @test_extractelement(ptr %p, ptr %q, i32 %i) #0 {2248; CHECK-ALL-LABEL: test_extractelement:2249; CHECK-ALL: .save {r4, r5, r11, lr}2250; CHECK-ALL-NEXT: push {r4, r5, r11, lr}2251; CHECK-ALL-NEXT: .pad #82252; CHECK-ALL-NEXT: sub sp, sp, #82253; CHECK-ALL-NEXT: ldrd r4, r5, [r1]2254; CHECK-ALL-NEXT: and r1, r2, #32255; CHECK-ALL-NEXT: mov r2, sp2256; CHECK-ALL-NEXT: orr r1, r2, r1, lsl #12257; CHECK-ALL-NEXT: stm sp, {r4, r5}2258; CHECK-ALL-NEXT: ldrh r1, [r1]2259; CHECK-ALL-NEXT: strh r1, [r0]2260; CHECK-ALL-NEXT: add sp, sp, #82261; CHECK-ALL-NEXT: pop {r4, r5, r11, pc}2262 %a = load <4 x half>, ptr %q, align 82263 %b = extractelement <4 x half> %a, i32 %i2264 store half %b, ptr %p2265 ret void2266}2267 2268; test struct operations2269 2270%struct.dummy = type { i32, half }2271 2272define void @test_insertvalue(ptr %p, ptr %q) {2273; CHECK-ALL-LABEL: test_insertvalue:2274; CHECK-ALL: ldrh r1, [r1]2275; CHECK-ALL-NEXT: strh r1, [r0, #4]2276; CHECK-ALL-NEXT: bx lr2277 %a = load %struct.dummy, ptr %p2278 %b = load half, ptr %q2279 %c = insertvalue %struct.dummy %a, half %b, 12280 store %struct.dummy %c, ptr %p2281 ret void2282}2283 2284define void @test_extractvalue(ptr %p, ptr %q) {2285; CHECK-ALL-LABEL: test_extractvalue:2286; CHECK-ALL: ldrh r0, [r0, #4]2287; CHECK-ALL-NEXT: strh r0, [r1]2288; CHECK-ALL-NEXT: bx lr2289 %a = load %struct.dummy, ptr %p2290 %b = extractvalue %struct.dummy %a, 12291 store half %b, ptr %q2292 ret void2293}2294 2295define %struct.dummy @test_struct_return(ptr %p) {2296; CHECK-VFP-LABEL: test_struct_return:2297; CHECK-VFP: ldrh r1, [r0, #4]2298; CHECK-VFP-NEXT: ldr r0, [r0]2299; CHECK-VFP-NEXT: vmov s0, r12300; CHECK-VFP-NEXT: bx lr2301;2302; CHECK-NOVFP-LABEL: test_struct_return:2303; CHECK-NOVFP: ldr r2, [r0]2304; CHECK-NOVFP-NEXT: ldrh r1, [r0, #4]2305; CHECK-NOVFP-NEXT: mov r0, r22306; CHECK-NOVFP-NEXT: bx lr2307; CHECK-VFP-LIBCALL: bl __aeabi_h2f2308 %a = load %struct.dummy, ptr %p2309 ret %struct.dummy %a2310}2311 2312define half @test_struct_arg(%struct.dummy %p) {2313; CHECK-VFP-LABEL: test_struct_arg:2314; CHECK-VFP: bx lr2315;2316; CHECK-NOVFP-LABEL: test_struct_arg:2317; CHECK-NOVFP: mov r0, r12318; CHECK-NOVFP-NEXT: bx lr2319 %a = extractvalue %struct.dummy %p, 12320 ret half %a2321}2322 2323define half @test_uitofp_i32_fadd(i32 %a, half %b) #0 {2324; CHECK-FP16-LABEL: test_uitofp_i32_fadd:2325; CHECK-FP16: vmov s2, r02326; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s02327; CHECK-FP16-NEXT: vcvt.f32.u32 s2, s22328; CHECK-FP16-NEXT: vcvtb.f16.f32 s2, s22329; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s22330; CHECK-FP16-NEXT: vadd.f32 s0, s0, s22331; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s02332; CHECK-FP16-NEXT: bx lr2333;2334; CHECK-LIBCALL-VFP-LABEL: test_uitofp_i32_fadd:2335; CHECK-LIBCALL-VFP: .save {r4, lr}2336; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}2337; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}2338; CHECK-LIBCALL-VFP-NEXT: vpush {d8}2339; CHECK-LIBCALL-VFP-NEXT: vmov r1, s02340; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02341; CHECK-LIBCALL-VFP-NEXT: vcvt.f32.u32 s16, s02342; CHECK-LIBCALL-VFP-NEXT: mov r0, r12343; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2344; CHECK-LIBCALL-VFP-NEXT: mov r4, r02345; CHECK-LIBCALL-VFP-NEXT: vmov r0, s162346; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2347; CHECK-LIBCALL-VFP-NEXT: vmov s16, r42348; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2349; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02350; CHECK-LIBCALL-VFP-NEXT: vadd.f32 s0, s16, s02351; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02352; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2353; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02354; CHECK-LIBCALL-VFP-NEXT: vpop {d8}2355; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}2356;2357; CHECK-NOVFP-LABEL: test_uitofp_i32_fadd:2358; CHECK-NOVFP: .save {r4, r5, r11, lr}2359; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}2360; CHECK-NOVFP-NEXT: mov r4, r12361; CHECK-NOVFP-NEXT: bl __aeabi_ui2f2362; CHECK-NOVFP-NEXT: bl __aeabi_f2h2363; CHECK-NOVFP-NEXT: mov r5, r02364; CHECK-NOVFP-NEXT: uxth r0, r42365; CHECK-NOVFP-NEXT: bl __aeabi_h2f2366; CHECK-NOVFP-NEXT: mov r4, r02367; CHECK-NOVFP-NEXT: uxth r0, r52368; CHECK-NOVFP-NEXT: bl __aeabi_h2f2369; CHECK-NOVFP-NEXT: mov r1, r02370; CHECK-NOVFP-NEXT: mov r0, r42371; CHECK-NOVFP-NEXT: bl __aeabi_fadd2372; CHECK-NOVFP-NEXT: bl __aeabi_f2h2373; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}2374 2375 2376 2377 %c = uitofp i32 %a to half2378 %r = fadd half %b, %c2379 ret half %r2380}2381 2382define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 {2383; CHECK-FP16-LABEL: test_sitofp_i32_fadd:2384; CHECK-FP16: vmov s2, r02385; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s02386; CHECK-FP16-NEXT: vcvt.f32.s32 s2, s22387; CHECK-FP16-NEXT: vcvtb.f16.f32 s2, s22388; CHECK-FP16-NEXT: vcvtb.f32.f16 s2, s22389; CHECK-FP16-NEXT: vadd.f32 s0, s0, s22390; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s02391; CHECK-FP16-NEXT: bx lr2392;2393; CHECK-LIBCALL-VFP-LABEL: test_sitofp_i32_fadd:2394; CHECK-LIBCALL-VFP: .save {r4, lr}2395; CHECK-LIBCALL-VFP-NEXT: push {r4, lr}2396; CHECK-LIBCALL-VFP-NEXT: .vsave {d8}2397; CHECK-LIBCALL-VFP-NEXT: vpush {d8}2398; CHECK-LIBCALL-VFP-NEXT: vmov r1, s02399; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02400; CHECK-LIBCALL-VFP-NEXT: vcvt.f32.s32 s16, s02401; CHECK-LIBCALL-VFP-NEXT: mov r0, r12402; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2403; CHECK-LIBCALL-VFP-NEXT: mov r4, r02404; CHECK-LIBCALL-VFP-NEXT: vmov r0, s162405; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2406; CHECK-LIBCALL-VFP-NEXT: vmov s16, r42407; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_h2f2408; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02409; CHECK-LIBCALL-VFP-NEXT: vadd.f32 s0, s16, s02410; CHECK-LIBCALL-VFP-NEXT: vmov r0, s02411; CHECK-LIBCALL-VFP-NEXT: bl __aeabi_f2h2412; CHECK-LIBCALL-VFP-NEXT: vmov s0, r02413; CHECK-LIBCALL-VFP-NEXT: vpop {d8}2414; CHECK-LIBCALL-VFP-NEXT: pop {r4, pc}2415;2416; CHECK-NOVFP-LABEL: test_sitofp_i32_fadd:2417; CHECK-NOVFP: .save {r4, r5, r11, lr}2418; CHECK-NOVFP-NEXT: push {r4, r5, r11, lr}2419; CHECK-NOVFP-NEXT: mov r4, r12420; CHECK-NOVFP-NEXT: bl __aeabi_i2f2421; CHECK-NOVFP-NEXT: bl __aeabi_f2h2422; CHECK-NOVFP-NEXT: mov r5, r02423; CHECK-NOVFP-NEXT: uxth r0, r42424; CHECK-NOVFP-NEXT: bl __aeabi_h2f2425; CHECK-NOVFP-NEXT: mov r4, r02426; CHECK-NOVFP-NEXT: uxth r0, r52427; CHECK-NOVFP-NEXT: bl __aeabi_h2f2428; CHECK-NOVFP-NEXT: mov r1, r02429; CHECK-NOVFP-NEXT: mov r0, r42430; CHECK-NOVFP-NEXT: bl __aeabi_fadd2431; CHECK-NOVFP-NEXT: bl __aeabi_f2h2432; CHECK-NOVFP-NEXT: pop {r4, r5, r11, pc}2433 2434 2435 2436 %c = sitofp i32 %a to half2437 %r = fadd half %b, %c2438 ret half %r2439}2440 2441define void @test_fneg(ptr %p1, ptr %p2) #0 {2442; CHECK-ALL-LABEL: test_fneg:2443; CHECK-ALL: ldrh r0, [r0]2444; CHECK-ALL-NEXT: eor r0, r0, #327682445; CHECK-ALL-NEXT: strh r0, [r1]2446; CHECK-ALL-NEXT: bx lr2447 %v = load half, ptr %p1, align 22448 %res = fneg half %v2449 store half %res, ptr %p2, align 22450 ret void2451}2452 2453attributes #0 = { nounwind }2454