172 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=-f16c | FileCheck %s -check-prefix=LIBCALL3; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+f16c | FileCheck %s -check-prefix=F16C4; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=-f16c,+soft-float | FileCheck %s -check-prefix=SOFTFLOAT5; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+f16c,+soft-float | FileCheck %s -check-prefix=SOFTFLOAT6 7; This is a test for float to half float conversions on x86-64.8;9; If flag -soft-float is set, or if there is no F16C support, then:10; 1) half float to float conversions are11; translated into calls to __gnu_h2f_ieee defined12; by the compiler runtime library;13; 2) float to half float conversions are translated into calls14; to __gnu_f2h_ieee which expected to be defined by the15; compiler runtime library.16;17; Otherwise (we have F16C support):18; 1) half float to float conversion are translated using19; vcvtph2ps instructions;20; 2) float to half float conversions are translated using21; vcvtps2ph instructions22 23 24define void @test1(float %src, ptr %dest) nounwind {25; LIBCALL-LABEL: test1:26; LIBCALL: # %bb.0:27; LIBCALL-NEXT: pushq %rbx28; LIBCALL-NEXT: movq %rdi, %rbx29; LIBCALL-NEXT: callq __truncsfhf2@PLT30; LIBCALL-NEXT: pextrw $0, %xmm0, (%rbx)31; LIBCALL-NEXT: popq %rbx32; LIBCALL-NEXT: retq33;34; F16C-LABEL: test1:35; F16C: # %bb.0:36; F16C-NEXT: vcvtps2ph $4, %xmm0, %xmm037; F16C-NEXT: vpextrw $0, %xmm0, (%rdi)38; F16C-NEXT: retq39;40; SOFTFLOAT-LABEL: test1:41; SOFTFLOAT: # %bb.0:42; SOFTFLOAT-NEXT: pushq %rbx43; SOFTFLOAT-NEXT: movq %rsi, %rbx44; SOFTFLOAT-NEXT: callq __truncsfhf2@PLT45; SOFTFLOAT-NEXT: movw %ax, (%rbx)46; SOFTFLOAT-NEXT: popq %rbx47; SOFTFLOAT-NEXT: retq48 %1 = tail call i16 @llvm.convert.to.fp16.f32(float %src)49 store i16 %1, ptr %dest, align 250 ret void51}52 53define float @test2(ptr nocapture %src) nounwind {54; LIBCALL-LABEL: test2:55; LIBCALL: # %bb.0:56; LIBCALL-NEXT: pinsrw $0, (%rdi), %xmm057; LIBCALL-NEXT: jmp __extendhfsf2@PLT # TAILCALL58;59; F16C-LABEL: test2:60; F16C: # %bb.0:61; F16C-NEXT: vpinsrw $0, (%rdi), %xmm0, %xmm062; F16C-NEXT: vcvtph2ps %xmm0, %xmm063; F16C-NEXT: retq64;65; SOFTFLOAT-LABEL: test2:66; SOFTFLOAT: # %bb.0:67; SOFTFLOAT-NEXT: pushq %rax68; SOFTFLOAT-NEXT: movzwl (%rdi), %edi69; SOFTFLOAT-NEXT: callq __extendhfsf2@PLT70; SOFTFLOAT-NEXT: popq %rcx71; SOFTFLOAT-NEXT: retq72 %1 = load i16, ptr %src, align 273 %2 = tail call float @llvm.convert.from.fp16.f32(i16 %1)74 ret float %275}76 77define float @test3(float %src) nounwind uwtable readnone {78; LIBCALL-LABEL: test3:79; LIBCALL: # %bb.0:80; LIBCALL-NEXT: pushq %rax81; LIBCALL-NEXT: .cfi_def_cfa_offset 1682; LIBCALL-NEXT: callq __truncsfhf2@PLT83; LIBCALL-NEXT: popq %rax84; LIBCALL-NEXT: .cfi_def_cfa_offset 885; LIBCALL-NEXT: jmp __extendhfsf2@PLT # TAILCALL86;87; F16C-LABEL: test3:88; F16C: # %bb.0:89; F16C-NEXT: vcvtps2ph $4, %xmm0, %xmm090; F16C-NEXT: vcvtph2ps %xmm0, %xmm091; F16C-NEXT: retq92;93; SOFTFLOAT-LABEL: test3:94; SOFTFLOAT: # %bb.0:95; SOFTFLOAT-NEXT: pushq %rax96; SOFTFLOAT-NEXT: .cfi_def_cfa_offset 1697; SOFTFLOAT-NEXT: callq __truncsfhf2@PLT98; SOFTFLOAT-NEXT: movzwl %ax, %edi99; SOFTFLOAT-NEXT: callq __extendhfsf2@PLT100; SOFTFLOAT-NEXT: popq %rcx101; SOFTFLOAT-NEXT: .cfi_def_cfa_offset 8102; SOFTFLOAT-NEXT: retq103 %1 = tail call i16 @llvm.convert.to.fp16.f32(float %src)104 %2 = tail call float @llvm.convert.from.fp16.f32(i16 %1)105 ret float %2106}107 108define double @test4(ptr nocapture %src) nounwind {109; LIBCALL-LABEL: test4:110; LIBCALL: # %bb.0:111; LIBCALL-NEXT: pushq %rax112; LIBCALL-NEXT: pinsrw $0, (%rdi), %xmm0113; LIBCALL-NEXT: callq __extendhfsf2@PLT114; LIBCALL-NEXT: cvtss2sd %xmm0, %xmm0115; LIBCALL-NEXT: popq %rax116; LIBCALL-NEXT: retq117;118; F16C-LABEL: test4:119; F16C: # %bb.0:120; F16C-NEXT: vpinsrw $0, (%rdi), %xmm0, %xmm0121; F16C-NEXT: vcvtph2ps %xmm0, %xmm0122; F16C-NEXT: vcvtss2sd %xmm0, %xmm0, %xmm0123; F16C-NEXT: retq124;125; SOFTFLOAT-LABEL: test4:126; SOFTFLOAT: # %bb.0:127; SOFTFLOAT-NEXT: pushq %rax128; SOFTFLOAT-NEXT: movzwl (%rdi), %edi129; SOFTFLOAT-NEXT: callq __extendhfsf2@PLT130; SOFTFLOAT-NEXT: movl %eax, %edi131; SOFTFLOAT-NEXT: callq __extendsfdf2@PLT132; SOFTFLOAT-NEXT: popq %rcx133; SOFTFLOAT-NEXT: retq134 %1 = load i16, ptr %src, align 2135 %2 = tail call double @llvm.convert.from.fp16.f64(i16 %1)136 ret double %2137}138 139define i16 @test5(double %src) nounwind {140; LIBCALL-LABEL: test5:141; LIBCALL: # %bb.0:142; LIBCALL-NEXT: pushq %rax143; LIBCALL-NEXT: callq __truncdfhf2@PLT144; LIBCALL-NEXT: pextrw $0, %xmm0, %eax145; LIBCALL-NEXT: # kill: def $ax killed $ax killed $eax146; LIBCALL-NEXT: popq %rcx147; LIBCALL-NEXT: retq148;149; F16C-LABEL: test5:150; F16C: # %bb.0:151; F16C-NEXT: pushq %rax152; F16C-NEXT: callq __truncdfhf2@PLT153; F16C-NEXT: vpextrw $0, %xmm0, %eax154; F16C-NEXT: # kill: def $ax killed $ax killed $eax155; F16C-NEXT: popq %rcx156; F16C-NEXT: retq157;158; SOFTFLOAT-LABEL: test5:159; SOFTFLOAT: # %bb.0:160; SOFTFLOAT-NEXT: pushq %rax161; SOFTFLOAT-NEXT: callq __truncdfhf2@PLT162; SOFTFLOAT-NEXT: popq %rcx163; SOFTFLOAT-NEXT: retq164 %val = tail call i16 @llvm.convert.to.fp16.f64(double %src)165 ret i16 %val166}167 168declare float @llvm.convert.from.fp16.f32(i16) nounwind readnone169declare i16 @llvm.convert.to.fp16.f32(float) nounwind readnone170declare double @llvm.convert.from.fp16.f64(i16) nounwind readnone171declare i16 @llvm.convert.to.fp16.f64(double) nounwind readnone172