brintos

brintos / llvm-project-archived public Read only

0
0
Text · 19.0 KiB · b013dda Raw
515 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2  -O3 | FileCheck %s --check-prefixes=SSE23; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+f16c  -O3 | FileCheck %s --check-prefixes=AVX,F16C4; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512f  -O3 | FileCheck %s --check-prefixes=AVX,AVX5125; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx512fp16 -mattr=+avx512vl -O3 | FileCheck %s --check-prefixes=X866; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512fp16 -mattr=+avx512vl -O3 | FileCheck %s --check-prefixes=X647 8declare half @llvm.experimental.constrained.fadd.f16(half, half, metadata, metadata)9declare half @llvm.experimental.constrained.fsub.f16(half, half, metadata, metadata)10declare half @llvm.experimental.constrained.fmul.f16(half, half, metadata, metadata)11declare half @llvm.experimental.constrained.fdiv.f16(half, half, metadata, metadata)12declare float @llvm.experimental.constrained.fpext.f32.f16(half, metadata)13declare double @llvm.experimental.constrained.fpext.f64.f16(half, metadata)14declare half @llvm.experimental.constrained.fptrunc.f16.f32(float, metadata, metadata)15declare half @llvm.experimental.constrained.fptrunc.f16.f64(double, metadata, metadata)16declare half @llvm.experimental.constrained.sqrt.f16(half, metadata, metadata)17declare half @llvm.experimental.constrained.fma.f16(half, half, half, metadata, metadata)18 19define half @fadd_f16(half %a, half %b) nounwind strictfp {20; SSE2-LABEL: fadd_f16:21; SSE2:       # %bb.0:22; SSE2-NEXT:    pushq %rax23; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill24; SSE2-NEXT:    movaps %xmm1, %xmm025; SSE2-NEXT:    callq __extendhfsf2@PLT26; SSE2-NEXT:    movss %xmm0, (%rsp) # 4-byte Spill27; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload28; SSE2-NEXT:    # xmm0 = mem[0],zero,zero,zero29; SSE2-NEXT:    callq __extendhfsf2@PLT30; SSE2-NEXT:    addss (%rsp), %xmm0 # 4-byte Folded Reload31; SSE2-NEXT:    callq __truncsfhf2@PLT32; SSE2-NEXT:    popq %rax33; SSE2-NEXT:    retq34;35; AVX-LABEL: fadd_f16:36; AVX:       # %bb.0:37; AVX-NEXT:    vpextrw $0, %xmm0, %eax38; AVX-NEXT:    vpextrw $0, %xmm1, %ecx39; AVX-NEXT:    movzwl %cx, %ecx40; AVX-NEXT:    vmovd %ecx, %xmm041; AVX-NEXT:    vcvtph2ps %xmm0, %xmm042; AVX-NEXT:    movzwl %ax, %eax43; AVX-NEXT:    vmovd %eax, %xmm144; AVX-NEXT:    vcvtph2ps %xmm1, %xmm145; AVX-NEXT:    vaddss %xmm0, %xmm1, %xmm046; AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm147; AVX-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]48; AVX-NEXT:    vcvtps2ph $4, %xmm0, %xmm049; AVX-NEXT:    retq50;51; X86-LABEL: fadd_f16:52; X86:       # %bb.0:53; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero54; X86-NEXT:    vaddsh {{[0-9]+}}(%esp), %xmm0, %xmm055; X86-NEXT:    retl56;57; X64-LABEL: fadd_f16:58; X64:       # %bb.0:59; X64-NEXT:    vaddsh %xmm1, %xmm0, %xmm060; X64-NEXT:    retq61  %ret = call half @llvm.experimental.constrained.fadd.f16(half %a, half %b,62                                                           metadata !"round.dynamic",63                                                           metadata !"fpexcept.strict") #064  ret half %ret65}66 67define half @fsub_f16(half %a, half %b) nounwind strictfp {68; SSE2-LABEL: fsub_f16:69; SSE2:       # %bb.0:70; SSE2-NEXT:    pushq %rax71; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill72; SSE2-NEXT:    movaps %xmm1, %xmm073; SSE2-NEXT:    callq __extendhfsf2@PLT74; SSE2-NEXT:    movss %xmm0, (%rsp) # 4-byte Spill75; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload76; SSE2-NEXT:    # xmm0 = mem[0],zero,zero,zero77; SSE2-NEXT:    callq __extendhfsf2@PLT78; SSE2-NEXT:    subss (%rsp), %xmm0 # 4-byte Folded Reload79; SSE2-NEXT:    callq __truncsfhf2@PLT80; SSE2-NEXT:    popq %rax81; SSE2-NEXT:    retq82;83; AVX-LABEL: fsub_f16:84; AVX:       # %bb.0:85; AVX-NEXT:    vpextrw $0, %xmm0, %eax86; AVX-NEXT:    vpextrw $0, %xmm1, %ecx87; AVX-NEXT:    movzwl %cx, %ecx88; AVX-NEXT:    vmovd %ecx, %xmm089; AVX-NEXT:    vcvtph2ps %xmm0, %xmm090; AVX-NEXT:    movzwl %ax, %eax91; AVX-NEXT:    vmovd %eax, %xmm192; AVX-NEXT:    vcvtph2ps %xmm1, %xmm193; AVX-NEXT:    vsubss %xmm0, %xmm1, %xmm094; AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm195; AVX-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]96; AVX-NEXT:    vcvtps2ph $4, %xmm0, %xmm097; AVX-NEXT:    retq98;99; X86-LABEL: fsub_f16:100; X86:       # %bb.0:101; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero102; X86-NEXT:    vsubsh {{[0-9]+}}(%esp), %xmm0, %xmm0103; X86-NEXT:    retl104;105; X64-LABEL: fsub_f16:106; X64:       # %bb.0:107; X64-NEXT:    vsubsh %xmm1, %xmm0, %xmm0108; X64-NEXT:    retq109  %ret = call half @llvm.experimental.constrained.fsub.f16(half %a, half %b,110                                                           metadata !"round.dynamic",111                                                           metadata !"fpexcept.strict") #0112  ret half %ret113}114 115define half @fmul_f16(half %a, half %b) nounwind strictfp {116; SSE2-LABEL: fmul_f16:117; SSE2:       # %bb.0:118; SSE2-NEXT:    pushq %rax119; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill120; SSE2-NEXT:    movaps %xmm1, %xmm0121; SSE2-NEXT:    callq __extendhfsf2@PLT122; SSE2-NEXT:    movss %xmm0, (%rsp) # 4-byte Spill123; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload124; SSE2-NEXT:    # xmm0 = mem[0],zero,zero,zero125; SSE2-NEXT:    callq __extendhfsf2@PLT126; SSE2-NEXT:    mulss (%rsp), %xmm0 # 4-byte Folded Reload127; SSE2-NEXT:    callq __truncsfhf2@PLT128; SSE2-NEXT:    popq %rax129; SSE2-NEXT:    retq130;131; AVX-LABEL: fmul_f16:132; AVX:       # %bb.0:133; AVX-NEXT:    vpextrw $0, %xmm0, %eax134; AVX-NEXT:    vpextrw $0, %xmm1, %ecx135; AVX-NEXT:    movzwl %cx, %ecx136; AVX-NEXT:    vmovd %ecx, %xmm0137; AVX-NEXT:    vcvtph2ps %xmm0, %xmm0138; AVX-NEXT:    movzwl %ax, %eax139; AVX-NEXT:    vmovd %eax, %xmm1140; AVX-NEXT:    vcvtph2ps %xmm1, %xmm1141; AVX-NEXT:    vmulss %xmm0, %xmm1, %xmm0142; AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm1143; AVX-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]144; AVX-NEXT:    vcvtps2ph $4, %xmm0, %xmm0145; AVX-NEXT:    retq146;147; X86-LABEL: fmul_f16:148; X86:       # %bb.0:149; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero150; X86-NEXT:    vmulsh {{[0-9]+}}(%esp), %xmm0, %xmm0151; X86-NEXT:    retl152;153; X64-LABEL: fmul_f16:154; X64:       # %bb.0:155; X64-NEXT:    vmulsh %xmm1, %xmm0, %xmm0156; X64-NEXT:    retq157  %ret = call half @llvm.experimental.constrained.fmul.f16(half %a, half %b,158                                                           metadata !"round.dynamic",159                                                           metadata !"fpexcept.strict") #0160  ret half %ret161}162 163define half @fdiv_f16(half %a, half %b) nounwind strictfp {164; SSE2-LABEL: fdiv_f16:165; SSE2:       # %bb.0:166; SSE2-NEXT:    pushq %rax167; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill168; SSE2-NEXT:    movaps %xmm1, %xmm0169; SSE2-NEXT:    callq __extendhfsf2@PLT170; SSE2-NEXT:    movss %xmm0, (%rsp) # 4-byte Spill171; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload172; SSE2-NEXT:    # xmm0 = mem[0],zero,zero,zero173; SSE2-NEXT:    callq __extendhfsf2@PLT174; SSE2-NEXT:    divss (%rsp), %xmm0 # 4-byte Folded Reload175; SSE2-NEXT:    callq __truncsfhf2@PLT176; SSE2-NEXT:    popq %rax177; SSE2-NEXT:    retq178;179; AVX-LABEL: fdiv_f16:180; AVX:       # %bb.0:181; AVX-NEXT:    vpextrw $0, %xmm0, %eax182; AVX-NEXT:    vpextrw $0, %xmm1, %ecx183; AVX-NEXT:    movzwl %cx, %ecx184; AVX-NEXT:    vmovd %ecx, %xmm0185; AVX-NEXT:    vcvtph2ps %xmm0, %xmm0186; AVX-NEXT:    movzwl %ax, %eax187; AVX-NEXT:    vmovd %eax, %xmm1188; AVX-NEXT:    vcvtph2ps %xmm1, %xmm1189; AVX-NEXT:    vdivss %xmm0, %xmm1, %xmm0190; AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm1191; AVX-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]192; AVX-NEXT:    vcvtps2ph $4, %xmm0, %xmm0193; AVX-NEXT:    retq194;195; X86-LABEL: fdiv_f16:196; X86:       # %bb.0:197; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero198; X86-NEXT:    vdivsh {{[0-9]+}}(%esp), %xmm0, %xmm0199; X86-NEXT:    retl200;201; X64-LABEL: fdiv_f16:202; X64:       # %bb.0:203; X64-NEXT:    vdivsh %xmm1, %xmm0, %xmm0204; X64-NEXT:    retq205  %ret = call half @llvm.experimental.constrained.fdiv.f16(half %a, half %b,206                                                           metadata !"round.dynamic",207                                                           metadata !"fpexcept.strict") #0208  ret half %ret209}210 211define void @fpext_f16_to_f32(ptr %val, ptr %ret) nounwind strictfp {212; SSE2-LABEL: fpext_f16_to_f32:213; SSE2:       # %bb.0:214; SSE2-NEXT:    pushq %rbx215; SSE2-NEXT:    movq %rsi, %rbx216; SSE2-NEXT:    pinsrw $0, (%rdi), %xmm0217; SSE2-NEXT:    callq __extendhfsf2@PLT218; SSE2-NEXT:    movd %xmm0, (%rbx)219; SSE2-NEXT:    popq %rbx220; SSE2-NEXT:    retq221;222; AVX-LABEL: fpext_f16_to_f32:223; AVX:       # %bb.0:224; AVX-NEXT:    movzwl (%rdi), %eax225; AVX-NEXT:    vmovd %eax, %xmm0226; AVX-NEXT:    vcvtph2ps %xmm0, %xmm0227; AVX-NEXT:    vmovss %xmm0, (%rsi)228; AVX-NEXT:    retq229;230; X86-LABEL: fpext_f16_to_f32:231; X86:       # %bb.0:232; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax233; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx234; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero235; X86-NEXT:    vcvtsh2ss %xmm0, %xmm0, %xmm0236; X86-NEXT:    vmovss %xmm0, (%eax)237; X86-NEXT:    retl238;239; X64-LABEL: fpext_f16_to_f32:240; X64:       # %bb.0:241; X64-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero242; X64-NEXT:    vcvtsh2ss %xmm0, %xmm0, %xmm0243; X64-NEXT:    vmovss %xmm0, (%rsi)244; X64-NEXT:    retq245  %1 = load half, ptr %val, align 4246  %res = call float @llvm.experimental.constrained.fpext.f32.f16(half %1,247                                                                 metadata !"fpexcept.strict") #0248  store float %res, ptr %ret, align 8249  ret void250}251 252define void @fpext_f16_to_f64(ptr %val, ptr %ret) nounwind strictfp {253; SSE2-LABEL: fpext_f16_to_f64:254; SSE2:       # %bb.0:255; SSE2-NEXT:    pushq %rbx256; SSE2-NEXT:    movq %rsi, %rbx257; SSE2-NEXT:    pinsrw $0, (%rdi), %xmm0258; SSE2-NEXT:    callq __extendhfsf2@PLT259; SSE2-NEXT:    cvtss2sd %xmm0, %xmm0260; SSE2-NEXT:    movsd %xmm0, (%rbx)261; SSE2-NEXT:    popq %rbx262; SSE2-NEXT:    retq263;264; AVX-LABEL: fpext_f16_to_f64:265; AVX:       # %bb.0:266; AVX-NEXT:    movzwl (%rdi), %eax267; AVX-NEXT:    vmovd %eax, %xmm0268; AVX-NEXT:    vcvtph2ps %xmm0, %xmm0269; AVX-NEXT:    vcvtss2sd %xmm0, %xmm0, %xmm0270; AVX-NEXT:    vmovsd %xmm0, (%rsi)271; AVX-NEXT:    retq272;273; X86-LABEL: fpext_f16_to_f64:274; X86:       # %bb.0:275; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax276; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx277; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero278; X86-NEXT:    vcvtsh2sd %xmm0, %xmm0, %xmm0279; X86-NEXT:    vmovsd %xmm0, (%eax)280; X86-NEXT:    retl281;282; X64-LABEL: fpext_f16_to_f64:283; X64:       # %bb.0:284; X64-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero285; X64-NEXT:    vcvtsh2sd %xmm0, %xmm0, %xmm0286; X64-NEXT:    vmovsd %xmm0, (%rsi)287; X64-NEXT:    retq288  %1 = load half, ptr %val, align 4289  %res = call double @llvm.experimental.constrained.fpext.f64.f16(half %1,290                                                                  metadata !"fpexcept.strict") #0291  store double %res, ptr %ret, align 8292  ret void293}294 295define void @fptrunc_float_to_f16(ptr %val, ptr%ret) nounwind strictfp {296; SSE2-LABEL: fptrunc_float_to_f16:297; SSE2:       # %bb.0:298; SSE2-NEXT:    pushq %rbx299; SSE2-NEXT:    movq %rsi, %rbx300; SSE2-NEXT:    movd {{.*#+}} xmm0 = mem[0],zero,zero,zero301; SSE2-NEXT:    callq __truncsfhf2@PLT302; SSE2-NEXT:    pextrw $0, %xmm0, %eax303; SSE2-NEXT:    movw %ax, (%rbx)304; SSE2-NEXT:    popq %rbx305; SSE2-NEXT:    retq306;307; AVX-LABEL: fptrunc_float_to_f16:308; AVX:       # %bb.0:309; AVX-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero310; AVX-NEXT:    vcvtps2ph $4, %xmm0, %xmm0311; AVX-NEXT:    vpextrw $0, %xmm0, (%rsi)312; AVX-NEXT:    retq313;314; X86-LABEL: fptrunc_float_to_f16:315; X86:       # %bb.0:316; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax317; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx318; X86-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero319; X86-NEXT:    vcvtss2sh %xmm0, %xmm0, %xmm0320; X86-NEXT:    vmovsh %xmm0, (%eax)321; X86-NEXT:    retl322;323; X64-LABEL: fptrunc_float_to_f16:324; X64:       # %bb.0:325; X64-NEXT:    vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero326; X64-NEXT:    vcvtss2sh %xmm0, %xmm0, %xmm0327; X64-NEXT:    vmovsh %xmm0, (%rsi)328; X64-NEXT:    retq329  %1 = load float, ptr %val, align 8330  %res = call half @llvm.experimental.constrained.fptrunc.f16.f32(float %1,331                                                                  metadata !"round.dynamic",332                                                                  metadata !"fpexcept.strict") #0333  store half %res, ptr %ret, align 4334  ret void335}336 337define void @fptrunc_double_to_f16(ptr %val, ptr%ret) nounwind strictfp {338; SSE2-LABEL: fptrunc_double_to_f16:339; SSE2:       # %bb.0:340; SSE2-NEXT:    pushq %rbx341; SSE2-NEXT:    movq %rsi, %rbx342; SSE2-NEXT:    movq {{.*#+}} xmm0 = mem[0],zero343; SSE2-NEXT:    callq __truncdfhf2@PLT344; SSE2-NEXT:    pextrw $0, %xmm0, %eax345; SSE2-NEXT:    movw %ax, (%rbx)346; SSE2-NEXT:    popq %rbx347; SSE2-NEXT:    retq348;349; AVX-LABEL: fptrunc_double_to_f16:350; AVX:       # %bb.0:351; AVX-NEXT:    pushq %rbx352; AVX-NEXT:    movq %rsi, %rbx353; AVX-NEXT:    vmovq {{.*#+}} xmm0 = mem[0],zero354; AVX-NEXT:    callq __truncdfhf2@PLT355; AVX-NEXT:    vpextrw $0, %xmm0, (%rbx)356; AVX-NEXT:    popq %rbx357; AVX-NEXT:    retq358;359; X86-LABEL: fptrunc_double_to_f16:360; X86:       # %bb.0:361; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax362; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx363; X86-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero364; X86-NEXT:    vcvtsd2sh %xmm0, %xmm0, %xmm0365; X86-NEXT:    vmovsh %xmm0, (%eax)366; X86-NEXT:    retl367;368; X64-LABEL: fptrunc_double_to_f16:369; X64:       # %bb.0:370; X64-NEXT:    vmovsd {{.*#+}} xmm0 = mem[0],zero371; X64-NEXT:    vcvtsd2sh %xmm0, %xmm0, %xmm0372; X64-NEXT:    vmovsh %xmm0, (%rsi)373; X64-NEXT:    retq374  %1 = load double, ptr %val, align 8375  %res = call half @llvm.experimental.constrained.fptrunc.f16.f64(double %1,376                                                                  metadata !"round.dynamic",377                                                                  metadata !"fpexcept.strict") #0378  store half %res, ptr %ret, align 4379  ret void380}381 382define void @fsqrt_f16(ptr %a) nounwind strictfp {383; SSE2-LABEL: fsqrt_f16:384; SSE2:       # %bb.0:385; SSE2-NEXT:    pushq %rbx386; SSE2-NEXT:    movq %rdi, %rbx387; SSE2-NEXT:    pinsrw $0, (%rdi), %xmm0388; SSE2-NEXT:    callq __extendhfsf2@PLT389; SSE2-NEXT:    sqrtss %xmm0, %xmm0390; SSE2-NEXT:    callq __truncsfhf2@PLT391; SSE2-NEXT:    pextrw $0, %xmm0, %eax392; SSE2-NEXT:    movw %ax, (%rbx)393; SSE2-NEXT:    popq %rbx394; SSE2-NEXT:    retq395;396; AVX-LABEL: fsqrt_f16:397; AVX:       # %bb.0:398; AVX-NEXT:    movzwl (%rdi), %eax399; AVX-NEXT:    vmovd %eax, %xmm0400; AVX-NEXT:    vcvtph2ps %xmm0, %xmm0401; AVX-NEXT:    vsqrtss %xmm0, %xmm0, %xmm0402; AVX-NEXT:    vxorps %xmm1, %xmm1, %xmm1403; AVX-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]404; AVX-NEXT:    vcvtps2ph $4, %xmm0, %xmm0405; AVX-NEXT:    vpextrw $0, %xmm0, (%rdi)406; AVX-NEXT:    retq407;408; X86-LABEL: fsqrt_f16:409; X86:       # %bb.0:410; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax411; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero412; X86-NEXT:    vsqrtsh %xmm0, %xmm0, %xmm0413; X86-NEXT:    vmovsh %xmm0, (%eax)414; X86-NEXT:    retl415;416; X64-LABEL: fsqrt_f16:417; X64:       # %bb.0:418; X64-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero419; X64-NEXT:    vsqrtsh %xmm0, %xmm0, %xmm0420; X64-NEXT:    vmovsh %xmm0, (%rdi)421; X64-NEXT:    retq422  %1 = load half, ptr %a, align 4423  %res = call half @llvm.experimental.constrained.sqrt.f16(half %1,424                                                           metadata !"round.dynamic",425                                                           metadata !"fpexcept.strict") #0426  store half %res, ptr %a, align 4427  ret void428}429 430define half @fma_f16(half %a, half %b, half %c) nounwind strictfp {431; SSE2-LABEL: fma_f16:432; SSE2:       # %bb.0:433; SSE2-NEXT:    subq $24, %rsp434; SSE2-NEXT:    movss %xmm2, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill435; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill436; SSE2-NEXT:    movaps %xmm1, %xmm0437; SSE2-NEXT:    callq __extendhfsf2@PLT438; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill439; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload440; SSE2-NEXT:    # xmm0 = mem[0],zero,zero,zero441; SSE2-NEXT:    callq __extendhfsf2@PLT442; SSE2-NEXT:    movss %xmm0, {{[-0-9]+}}(%r{{[sb]}}p) # 4-byte Spill443; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm0 # 4-byte Reload444; SSE2-NEXT:    # xmm0 = mem[0],zero,zero,zero445; SSE2-NEXT:    callq __extendhfsf2@PLT446; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm1 # 4-byte Reload447; SSE2-NEXT:    # xmm1 = mem[0],zero,zero,zero448; SSE2-NEXT:    movss {{[-0-9]+}}(%r{{[sb]}}p), %xmm2 # 4-byte Reload449; SSE2-NEXT:    # xmm2 = mem[0],zero,zero,zero450; SSE2-NEXT:    callq fmaf@PLT451; SSE2-NEXT:    callq __truncsfhf2@PLT452; SSE2-NEXT:    addq $24, %rsp453; SSE2-NEXT:    retq454;455; F16C-LABEL: fma_f16:456; F16C:       # %bb.0:457; F16C-NEXT:    pushq %rax458; F16C-NEXT:    vpextrw $0, %xmm0, %eax459; F16C-NEXT:    vpextrw $0, %xmm1, %ecx460; F16C-NEXT:    vpextrw $0, %xmm2, %edx461; F16C-NEXT:    movzwl %dx, %edx462; F16C-NEXT:    vmovd %edx, %xmm0463; F16C-NEXT:    vcvtph2ps %xmm0, %xmm2464; F16C-NEXT:    movzwl %cx, %ecx465; F16C-NEXT:    vmovd %ecx, %xmm0466; F16C-NEXT:    vcvtph2ps %xmm0, %xmm1467; F16C-NEXT:    movzwl %ax, %eax468; F16C-NEXT:    vmovd %eax, %xmm0469; F16C-NEXT:    vcvtph2ps %xmm0, %xmm0470; F16C-NEXT:    callq fmaf@PLT471; F16C-NEXT:    vxorps %xmm1, %xmm1, %xmm1472; F16C-NEXT:    vmovss {{.*#+}} xmm0 = xmm0[0],xmm1[1,2,3]473; F16C-NEXT:    vcvtps2ph $4, %xmm0, %xmm0474; F16C-NEXT:    popq %rax475; F16C-NEXT:    retq476;477; AVX512-LABEL: fma_f16:478; AVX512:       # %bb.0:479; AVX512-NEXT:    vpextrw $0, %xmm1, %eax480; AVX512-NEXT:    vpextrw $0, %xmm0, %ecx481; AVX512-NEXT:    vpextrw $0, %xmm2, %edx482; AVX512-NEXT:    movzwl %dx, %edx483; AVX512-NEXT:    vmovd %edx, %xmm0484; AVX512-NEXT:    vcvtph2ps %xmm0, %xmm0485; AVX512-NEXT:    movzwl %cx, %ecx486; AVX512-NEXT:    vmovd %ecx, %xmm1487; AVX512-NEXT:    vcvtph2ps %xmm1, %xmm1488; AVX512-NEXT:    movzwl %ax, %eax489; AVX512-NEXT:    vmovd %eax, %xmm2490; AVX512-NEXT:    vcvtph2ps %xmm2, %xmm2491; AVX512-NEXT:    vfmadd213ss {{.*#+}} xmm2 = (xmm1 * xmm2) + xmm0492; AVX512-NEXT:    vxorps %xmm0, %xmm0, %xmm0493; AVX512-NEXT:    vmovss {{.*#+}} xmm0 = xmm2[0],xmm0[1,2,3]494; AVX512-NEXT:    vcvtps2ph $4, %xmm0, %xmm0495; AVX512-NEXT:    retq496;497; X86-LABEL: fma_f16:498; X86:       # %bb.0:499; X86-NEXT:    vmovsh {{.*#+}} xmm1 = mem[0],zero,zero,zero,zero,zero,zero,zero500; X86-NEXT:    vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero501; X86-NEXT:    vfmadd213sh {{[0-9]+}}(%esp), %xmm1, %xmm0502; X86-NEXT:    retl503;504; X64-LABEL: fma_f16:505; X64:       # %bb.0:506; X64-NEXT:    vfmadd213sh %xmm2, %xmm1, %xmm0507; X64-NEXT:    retq508  %res = call half @llvm.experimental.constrained.fma.f16(half %a, half %b, half %c,509                                                          metadata !"round.dynamic",510                                                          metadata !"fpexcept.strict") #0511  ret half %res512}513 514attributes #0 = { strictfp }515