1092 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx512fp16 -mattr=+avx512vl | FileCheck %s --check-prefixes=CHECK,X643; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx512fp16 -mattr=+avx512vl | FileCheck %s --check-prefixes=CHECK,X864 5define half @f32tof16(float %b) nounwind {6; X64-LABEL: f32tof16:7; X64: # %bb.0:8; X64-NEXT: vcvtss2sh %xmm0, %xmm0, %xmm09; X64-NEXT: retq10;11; X86-LABEL: f32tof16:12; X86: # %bb.0:13; X86-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero14; X86-NEXT: vcvtss2sh %xmm0, %xmm0, %xmm015; X86-NEXT: retl16 %a = fptrunc float %b to half17 ret half %a18}19 20define half @f64tof16(double %b) nounwind {21; X64-LABEL: f64tof16:22; X64: # %bb.0:23; X64-NEXT: vcvtsd2sh %xmm0, %xmm0, %xmm024; X64-NEXT: retq25;26; X86-LABEL: f64tof16:27; X86: # %bb.0:28; X86-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero29; X86-NEXT: vcvtsd2sh %xmm0, %xmm0, %xmm030; X86-NEXT: retl31 %a = fptrunc double %b to half32 ret half %a33}34 35define <16 x half> @f32to16f16(<16 x float> %b) nounwind {36; CHECK-LABEL: f32to16f16:37; CHECK: # %bb.0:38; CHECK-NEXT: vcvtps2phx %zmm0, %ymm039; CHECK-NEXT: ret{{[l|q]}}40 %a = fptrunc <16 x float> %b to <16 x half>41 ret <16 x half> %a42}43 44define <8 x half> @f32to8f16(<8 x float> %b) {45; CHECK-LABEL: f32to8f16:46; CHECK: # %bb.0:47; CHECK-NEXT: vcvtps2phx %ymm0, %xmm048; CHECK-NEXT: vzeroupper49; CHECK-NEXT: ret{{[l|q]}}50 %a = fptrunc <8 x float> %b to <8 x half>51 ret <8 x half> %a52}53 54define <4 x half> @f32to4f16(<4 x float> %b) {55; CHECK-LABEL: f32to4f16:56; CHECK: # %bb.0:57; CHECK-NEXT: vcvtps2phx %xmm0, %xmm058; CHECK-NEXT: ret{{[l|q]}}59 %a = fptrunc <4 x float> %b to <4 x half>60 ret <4 x half> %a61}62 63define <2 x half> @f32to2f16(<2 x float> %b) {64; CHECK-LABEL: f32to2f16:65; CHECK: # %bb.0:66; CHECK-NEXT: vcvtps2phx %xmm0, %xmm067; CHECK-NEXT: ret{{[l|q]}}68 %a = fptrunc <2 x float> %b to <2 x half>69 ret <2 x half> %a70}71 72declare <8 x half> @llvm.x86.avx512fp16.mask.vcvtps2phx.128(<4 x float>, <8 x half>, i8)73declare <8 x half> @llvm.x86.avx512fp16.mask.vcvtps2phx.256(<8 x float>, <8 x half>, i8)74 75define <8 x half> @f32to4f16_mask(<4 x float> %a, <8 x half> %b, i8 %mask) {76; X64-LABEL: f32to4f16_mask:77; X64: # %bb.0:78; X64-NEXT: kmovd %edi, %k179; X64-NEXT: vcvtps2phx %xmm0, %xmm1 {%k1}80; X64-NEXT: vmovaps %xmm1, %xmm081; X64-NEXT: retq82;83; X86-LABEL: f32to4f16_mask:84; X86: # %bb.0:85; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax86; X86-NEXT: kmovd %eax, %k187; X86-NEXT: vcvtps2phx %xmm0, %xmm1 {%k1}88; X86-NEXT: vmovaps %xmm1, %xmm089; X86-NEXT: retl90 %res = call <8 x half> @llvm.x86.avx512fp16.mask.vcvtps2phx.128(<4 x float> %a, <8 x half> %b, i8 %mask)91 ret <8 x half> %res92}93 94define <8 x half> @f32to8f16_mask(<8 x float> %a, <8 x half> %b, i8 %mask) {95; X64-LABEL: f32to8f16_mask:96; X64: # %bb.0:97; X64-NEXT: kmovd %edi, %k198; X64-NEXT: vcvtps2phx %ymm0, %xmm1 {%k1}99; X64-NEXT: vmovaps %xmm1, %xmm0100; X64-NEXT: vzeroupper101; X64-NEXT: retq102;103; X86-LABEL: f32to8f16_mask:104; X86: # %bb.0:105; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax106; X86-NEXT: kmovd %eax, %k1107; X86-NEXT: vcvtps2phx %ymm0, %xmm1 {%k1}108; X86-NEXT: vmovaps %xmm1, %xmm0109; X86-NEXT: vzeroupper110; X86-NEXT: retl111 %res = call <8 x half> @llvm.x86.avx512fp16.mask.vcvtps2phx.256(<8 x float> %a, <8 x half> %b, i8 %mask)112 ret <8 x half> %res113}114 115define <8 x half> @f32to8f16_mask2(<8 x float> %b, <8 x i1> %mask) {116; CHECK-LABEL: f32to8f16_mask2:117; CHECK: # %bb.0:118; CHECK-NEXT: vpsllw $15, %xmm1, %xmm1119; CHECK-NEXT: vpmovw2m %xmm1, %k1120; CHECK-NEXT: vcvtps2phx %ymm0, %xmm0 {%k1} {z}121; CHECK-NEXT: vzeroupper122; CHECK-NEXT: ret{{[l|q]}}123 %a = fptrunc <8 x float> %b to <8 x half>124 %c = select <8 x i1>%mask, <8 x half>%a, <8 x half> zeroinitializer125 ret <8 x half> %c126}127 128define <16 x half> @f32to16f16_mask(<16 x float> %b, <16 x i1> %mask) {129; CHECK-LABEL: f32to16f16_mask:130; CHECK: # %bb.0:131; CHECK-NEXT: vpsllw $7, %xmm1, %xmm1132; CHECK-NEXT: vpmovb2m %xmm1, %k1133; CHECK-NEXT: vcvtps2phx %zmm0, %ymm0 {%k1} {z}134; CHECK-NEXT: ret{{[l|q]}}135 %a = fptrunc <16 x float> %b to <16 x half>136 %c = select <16 x i1>%mask, <16 x half>%a, <16 x half> zeroinitializer137 ret <16 x half> %c138}139 140define float @f16tof32(half %b) nounwind {141; X64-LABEL: f16tof32:142; X64: # %bb.0:143; X64-NEXT: vcvtsh2ss %xmm0, %xmm0, %xmm0144; X64-NEXT: retq145;146; X86-LABEL: f16tof32:147; X86: # %bb.0:148; X86-NEXT: pushl %eax149; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero150; X86-NEXT: vcvtsh2ss %xmm0, %xmm0, %xmm0151; X86-NEXT: vmovss %xmm0, (%esp)152; X86-NEXT: flds (%esp)153; X86-NEXT: popl %eax154; X86-NEXT: retl155 %a = fpext half %b to float156 ret float %a157}158 159define double @f16tof64(half %b) nounwind {160; X64-LABEL: f16tof64:161; X64: # %bb.0:162; X64-NEXT: vcvtsh2sd %xmm0, %xmm0, %xmm0163; X64-NEXT: retq164;165; X86-LABEL: f16tof64:166; X86: # %bb.0:167; X86-NEXT: pushl %ebp168; X86-NEXT: movl %esp, %ebp169; X86-NEXT: andl $-8, %esp170; X86-NEXT: subl $8, %esp171; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero172; X86-NEXT: vcvtsh2sd %xmm0, %xmm0, %xmm0173; X86-NEXT: vmovsd %xmm0, (%esp)174; X86-NEXT: fldl (%esp)175; X86-NEXT: movl %ebp, %esp176; X86-NEXT: popl %ebp177; X86-NEXT: retl178 %a = fpext half %b to double179 ret double %a180}181 182define <16 x float> @f16to16f32(<16 x half> %b) nounwind {183; CHECK-LABEL: f16to16f32:184; CHECK: # %bb.0:185; CHECK-NEXT: vcvtph2psx %ymm0, %zmm0186; CHECK-NEXT: ret{{[l|q]}}187 %a = fpext <16 x half> %b to <16 x float>188 ret <16 x float> %a189}190 191define <8 x float> @f16to8f32(<8 x half> %b) nounwind {192; CHECK-LABEL: f16to8f32:193; CHECK: # %bb.0:194; CHECK-NEXT: vcvtph2psx %xmm0, %ymm0195; CHECK-NEXT: ret{{[l|q]}}196 %a = fpext <8 x half> %b to <8 x float>197 ret <8 x float> %a198}199 200define <4 x float> @f16to4f32(<4 x half> %b) nounwind {201; CHECK-LABEL: f16to4f32:202; CHECK: # %bb.0:203; CHECK-NEXT: vcvtph2psx %xmm0, %xmm0204; CHECK-NEXT: ret{{[l|q]}}205 %a = fpext <4 x half> %b to <4 x float>206 ret <4 x float> %a207}208 209define <2 x float> @f16to2f32(<2 x half> %b) nounwind {210; CHECK-LABEL: f16to2f32:211; CHECK: # %bb.0:212; CHECK-NEXT: vcvtph2psx %xmm0, %xmm0213; CHECK-NEXT: ret{{[l|q]}}214 %a = fpext <2 x half> %b to <2 x float>215 ret <2 x float> %a216}217 218define <16 x float> @f16to16f32_mask(<16 x half> %b, <16 x float> %b1, <16 x float> %a1) {219; CHECK-LABEL: f16to16f32_mask:220; CHECK: # %bb.0:221; CHECK-NEXT: vcmpltps %zmm2, %zmm1, %k1222; CHECK-NEXT: vcvtph2psx %ymm0, %zmm0 {%k1} {z}223; CHECK-NEXT: ret{{[l|q]}}224 %a = fpext <16 x half> %b to <16 x float>225 %mask = fcmp ogt <16 x float> %a1, %b1226 %c = select <16 x i1> %mask, <16 x float> %a, <16 x float> zeroinitializer227 ret <16 x float> %c228}229 230define <8 x float> @f16to8f32_mask(<8 x half> %b, <8 x float> %b1, <8 x float> %a1) {231; CHECK-LABEL: f16to8f32_mask:232; CHECK: # %bb.0:233; CHECK-NEXT: vcmpltps %ymm2, %ymm1, %k1234; CHECK-NEXT: vcvtph2psx %xmm0, %ymm0 {%k1} {z}235; CHECK-NEXT: ret{{[l|q]}}236 %a = fpext <8 x half> %b to <8 x float>237 %mask = fcmp ogt <8 x float> %a1, %b1238 %c = select <8 x i1> %mask, <8 x float> %a, <8 x float> zeroinitializer239 ret <8 x float> %c240}241 242define <4 x float> @f16to4f32_mask(<4 x half> %b, <4 x float> %b1, <4 x float> %a1) {243; CHECK-LABEL: f16to4f32_mask:244; CHECK: # %bb.0:245; CHECK-NEXT: vcmpltps %xmm2, %xmm1, %k1246; CHECK-NEXT: vcvtph2psx %xmm0, %xmm0 {%k1} {z}247; CHECK-NEXT: ret{{[l|q]}}248 %a = fpext <4 x half> %b to <4 x float>249 %mask = fcmp ogt <4 x float> %a1, %b1250 %c = select <4 x i1> %mask, <4 x float> %a, <4 x float> zeroinitializer251 ret <4 x float> %c252}253 254define <2 x float> @f16to2f32_mask(<2 x half> %b, <2 x float> %b1, <2 x float> %a1) {255; CHECK-LABEL: f16to2f32_mask:256; CHECK: # %bb.0:257; CHECK-NEXT: vcmpltps %xmm2, %xmm1, %k1258; CHECK-NEXT: vcvtph2psx %xmm0, %xmm0 {%k1} {z}259; CHECK-NEXT: ret{{[l|q]}}260 %a = fpext <2 x half> %b to <2 x float>261 %mask = fcmp ogt <2 x float> %a1, %b1262 %c = select <2 x i1> %mask, <2 x float> %a, <2 x float> zeroinitializer263 ret <2 x float> %c264}265 266define <2 x double> @f16to2f64(<2 x half> %b) nounwind {267; CHECK-LABEL: f16to2f64:268; CHECK: # %bb.0:269; CHECK-NEXT: vcvtph2pd %xmm0, %xmm0270; CHECK-NEXT: ret{{[l|q]}}271 %a = fpext <2 x half> %b to <2 x double>272 ret <2 x double> %a273}274 275define <2 x double> @f16to2f64_mask(<2 x half> %b, <2 x double> %b1, <2 x double> %a1) {276; CHECK-LABEL: f16to2f64_mask:277; CHECK: # %bb.0:278; CHECK-NEXT: vcmpltpd %xmm2, %xmm1, %k1279; CHECK-NEXT: vcvtph2pd %xmm0, %xmm0 {%k1} {z}280; CHECK-NEXT: ret{{[l|q]}}281 %a = fpext <2 x half> %b to <2 x double>282 %mask = fcmp ogt <2 x double> %a1, %b1283 %c = select <2 x i1> %mask, <2 x double> %a, <2 x double> zeroinitializer284 ret <2 x double> %c285}286 287define <4 x double> @f16to4f64(<4 x half> %b) nounwind {288; CHECK-LABEL: f16to4f64:289; CHECK: # %bb.0:290; CHECK-NEXT: vcvtph2pd %xmm0, %ymm0291; CHECK-NEXT: ret{{[l|q]}}292 %a = fpext <4 x half> %b to <4 x double>293 ret <4 x double> %a294}295 296define <4 x double> @f16to4f64_mask(<4 x half> %b, <4 x double> %b1, <4 x double> %a1) {297; CHECK-LABEL: f16to4f64_mask:298; CHECK: # %bb.0:299; CHECK-NEXT: vcmpltpd %ymm2, %ymm1, %k1300; CHECK-NEXT: vcvtph2pd %xmm0, %ymm0 {%k1} {z}301; CHECK-NEXT: ret{{[l|q]}}302 %a = fpext <4 x half> %b to <4 x double>303 %mask = fcmp ogt <4 x double> %a1, %b1304 %c = select <4 x i1> %mask, <4 x double> %a, <4 x double> zeroinitializer305 ret <4 x double> %c306}307 308define <8 x double> @f16to8f64(<8 x half> %b) nounwind {309; CHECK-LABEL: f16to8f64:310; CHECK: # %bb.0:311; CHECK-NEXT: vcvtph2pd %xmm0, %zmm0312; CHECK-NEXT: ret{{[l|q]}}313 %a = fpext <8 x half> %b to <8 x double>314 ret <8 x double> %a315}316 317define <8 x double> @f16to8f64_mask(<8 x half> %b, <8 x double> %b1, <8 x double> %a1) {318; CHECK-LABEL: f16to8f64_mask:319; CHECK: # %bb.0:320; CHECK-NEXT: vcmpltpd %zmm2, %zmm1, %k1321; CHECK-NEXT: vcvtph2pd %xmm0, %zmm0 {%k1} {z}322; CHECK-NEXT: ret{{[l|q]}}323 %a = fpext <8 x half> %b to <8 x double>324 %mask = fcmp ogt <8 x double> %a1, %b1325 %c = select <8 x i1> %mask, <8 x double> %a, <8 x double> zeroinitializer326 ret <8 x double> %c327}328 329define <2 x half> @f64to2f16(<2 x double> %b) {330; CHECK-LABEL: f64to2f16:331; CHECK: # %bb.0:332; CHECK-NEXT: vcvtpd2ph %xmm0, %xmm0333; CHECK-NEXT: ret{{[l|q]}}334 %a = fptrunc <2 x double> %b to <2 x half>335 ret <2 x half> %a336}337 338define <4 x half> @f64to4f16(<4 x double> %b) {339; CHECK-LABEL: f64to4f16:340; CHECK: # %bb.0:341; CHECK-NEXT: vcvtpd2ph %ymm0, %xmm0342; CHECK-NEXT: vzeroupper343; CHECK-NEXT: ret{{[l|q]}}344 %a = fptrunc <4 x double> %b to <4 x half>345 ret <4 x half> %a346}347 348define <8 x half> @f64to8f16(<8 x double> %b) {349; CHECK-LABEL: f64to8f16:350; CHECK: # %bb.0:351; CHECK-NEXT: vcvtpd2ph %zmm0, %xmm0352; CHECK-NEXT: vzeroupper353; CHECK-NEXT: ret{{[l|q]}}354 %a = fptrunc <8 x double> %b to <8 x half>355 ret <8 x half> %a356}357 358define float @extload_f16_f32(ptr %x) {359; X64-LABEL: extload_f16_f32:360; X64: # %bb.0:361; X64-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero362; X64-NEXT: vcvtsh2ss %xmm0, %xmm0, %xmm0363; X64-NEXT: retq364;365; X86-LABEL: extload_f16_f32:366; X86: # %bb.0:367; X86-NEXT: pushl %eax368; X86-NEXT: .cfi_def_cfa_offset 8369; X86-NEXT: movl {{[0-9]+}}(%esp), %eax370; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero371; X86-NEXT: vcvtsh2ss %xmm0, %xmm0, %xmm0372; X86-NEXT: vmovss %xmm0, (%esp)373; X86-NEXT: flds (%esp)374; X86-NEXT: popl %eax375; X86-NEXT: .cfi_def_cfa_offset 4376; X86-NEXT: retl377 %a = load half, ptr %x378 %b = fpext half %a to float379 ret float %b380}381 382define double @extload_f16_f64(ptr %x) {383; X64-LABEL: extload_f16_f64:384; X64: # %bb.0:385; X64-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero386; X64-NEXT: vcvtsh2sd %xmm0, %xmm0, %xmm0387; X64-NEXT: retq388;389; X86-LABEL: extload_f16_f64:390; X86: # %bb.0:391; X86-NEXT: pushl %ebp392; X86-NEXT: .cfi_def_cfa_offset 8393; X86-NEXT: .cfi_offset %ebp, -8394; X86-NEXT: movl %esp, %ebp395; X86-NEXT: .cfi_def_cfa_register %ebp396; X86-NEXT: andl $-8, %esp397; X86-NEXT: subl $8, %esp398; X86-NEXT: movl 8(%ebp), %eax399; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero400; X86-NEXT: vcvtsh2sd %xmm0, %xmm0, %xmm0401; X86-NEXT: vmovsd %xmm0, (%esp)402; X86-NEXT: fldl (%esp)403; X86-NEXT: movl %ebp, %esp404; X86-NEXT: popl %ebp405; X86-NEXT: .cfi_def_cfa %esp, 4406; X86-NEXT: retl407 %a = load half, ptr %x408 %b = fpext half %a to double409 ret double %b410}411 412define float @extload_f16_f32_optsize(ptr %x) optsize {413; X64-LABEL: extload_f16_f32_optsize:414; X64: # %bb.0:415; X64-NEXT: vcvtsh2ss (%rdi), %xmm15, %xmm0416; X64-NEXT: retq417;418; X86-LABEL: extload_f16_f32_optsize:419; X86: # %bb.0:420; X86-NEXT: pushl %eax421; X86-NEXT: .cfi_def_cfa_offset 8422; X86-NEXT: movl {{[0-9]+}}(%esp), %eax423; X86-NEXT: vcvtsh2ss (%eax), %xmm7, %xmm0424; X86-NEXT: vmovss %xmm0, (%esp)425; X86-NEXT: flds (%esp)426; X86-NEXT: popl %eax427; X86-NEXT: .cfi_def_cfa_offset 4428; X86-NEXT: retl429 %a = load half, ptr %x430 %b = fpext half %a to float431 ret float %b432}433 434define double @extload_f16_f64_optsize(ptr %x) optsize {435; X64-LABEL: extload_f16_f64_optsize:436; X64: # %bb.0:437; X64-NEXT: vcvtsh2sd (%rdi), %xmm15, %xmm0438; X64-NEXT: retq439;440; X86-LABEL: extload_f16_f64_optsize:441; X86: # %bb.0:442; X86-NEXT: pushl %ebp443; X86-NEXT: .cfi_def_cfa_offset 8444; X86-NEXT: .cfi_offset %ebp, -8445; X86-NEXT: movl %esp, %ebp446; X86-NEXT: .cfi_def_cfa_register %ebp447; X86-NEXT: andl $-8, %esp448; X86-NEXT: subl $8, %esp449; X86-NEXT: movl 8(%ebp), %eax450; X86-NEXT: vcvtsh2sd (%eax), %xmm7, %xmm0451; X86-NEXT: vmovsd %xmm0, (%esp)452; X86-NEXT: fldl (%esp)453; X86-NEXT: movl %ebp, %esp454; X86-NEXT: popl %ebp455; X86-NEXT: .cfi_def_cfa %esp, 4456; X86-NEXT: retl457 %a = load half, ptr %x458 %b = fpext half %a to double459 ret double %b460}461 462define <16 x float> @extload_v16f16_v16f32(ptr %x) {463; X64-LABEL: extload_v16f16_v16f32:464; X64: # %bb.0:465; X64-NEXT: vcvtph2psx (%rdi), %zmm0466; X64-NEXT: retq467;468; X86-LABEL: extload_v16f16_v16f32:469; X86: # %bb.0:470; X86-NEXT: movl {{[0-9]+}}(%esp), %eax471; X86-NEXT: vcvtph2psx (%eax), %zmm0472; X86-NEXT: retl473 %a = load <16 x half>, ptr %x474 %b = fpext <16 x half> %a to <16 x float>475 ret <16 x float> %b476}477 478define <8 x float> @extload_v8f16_v8f32(ptr %x) {479; X64-LABEL: extload_v8f16_v8f32:480; X64: # %bb.0:481; X64-NEXT: vcvtph2psx (%rdi), %ymm0482; X64-NEXT: retq483;484; X86-LABEL: extload_v8f16_v8f32:485; X86: # %bb.0:486; X86-NEXT: movl {{[0-9]+}}(%esp), %eax487; X86-NEXT: vcvtph2psx (%eax), %ymm0488; X86-NEXT: retl489 %a = load <8 x half>, ptr %x490 %b = fpext <8 x half> %a to <8 x float>491 ret <8 x float> %b492}493 494define <4 x float> @extload_v4f16_v4f32(ptr %x) {495; X64-LABEL: extload_v4f16_v4f32:496; X64: # %bb.0:497; X64-NEXT: vcvtph2psx (%rdi), %xmm0498; X64-NEXT: retq499;500; X86-LABEL: extload_v4f16_v4f32:501; X86: # %bb.0:502; X86-NEXT: movl {{[0-9]+}}(%esp), %eax503; X86-NEXT: vcvtph2psx (%eax), %xmm0504; X86-NEXT: retl505 %a = load <4 x half>, ptr %x506 %b = fpext <4 x half> %a to <4 x float>507 ret <4 x float> %b508}509 510define <8 x double> @extload_v8f16_v8f64(ptr %x) {511; X64-LABEL: extload_v8f16_v8f64:512; X64: # %bb.0:513; X64-NEXT: vcvtph2pd (%rdi), %zmm0514; X64-NEXT: retq515;516; X86-LABEL: extload_v8f16_v8f64:517; X86: # %bb.0:518; X86-NEXT: movl {{[0-9]+}}(%esp), %eax519; X86-NEXT: vcvtph2pd (%eax), %zmm0520; X86-NEXT: retl521 %a = load <8 x half>, ptr %x522 %b = fpext <8 x half> %a to <8 x double>523 ret <8 x double> %b524}525 526define <4 x double> @extload_v4f16_v4f64(ptr %x) {527; X64-LABEL: extload_v4f16_v4f64:528; X64: # %bb.0:529; X64-NEXT: vcvtph2pd (%rdi), %ymm0530; X64-NEXT: retq531;532; X86-LABEL: extload_v4f16_v4f64:533; X86: # %bb.0:534; X86-NEXT: movl {{[0-9]+}}(%esp), %eax535; X86-NEXT: vcvtph2pd (%eax), %ymm0536; X86-NEXT: retl537 %a = load <4 x half>, ptr %x538 %b = fpext <4 x half> %a to <4 x double>539 ret <4 x double> %b540}541 542define <2 x double> @extload_v2f16_v2f64(ptr %x) {543; X64-LABEL: extload_v2f16_v2f64:544; X64: # %bb.0:545; X64-NEXT: vcvtph2pd (%rdi), %xmm0546; X64-NEXT: retq547;548; X86-LABEL: extload_v2f16_v2f64:549; X86: # %bb.0:550; X86-NEXT: movl {{[0-9]+}}(%esp), %eax551; X86-NEXT: vcvtph2pd (%eax), %xmm0552; X86-NEXT: retl553 %a = load <2 x half>, ptr %x554 %b = fpext <2 x half> %a to <2 x double>555 ret <2 x double> %b556}557 558define half @s8_to_half(i8 %x) {559; X64-LABEL: s8_to_half:560; X64: # %bb.0:561; X64-NEXT: movsbl %dil, %eax562; X64-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0563; X64-NEXT: retq564;565; X86-LABEL: s8_to_half:566; X86: # %bb.0:567; X86-NEXT: movsbl {{[0-9]+}}(%esp), %eax568; X86-NEXT: vcvtsi2sh %eax, %xmm7, %xmm0569; X86-NEXT: retl570 %a = sitofp i8 %x to half571 ret half %a572}573 574define half @s16_to_half(i16 %x) {575; X64-LABEL: s16_to_half:576; X64: # %bb.0:577; X64-NEXT: movswl %di, %eax578; X64-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0579; X64-NEXT: retq580;581; X86-LABEL: s16_to_half:582; X86: # %bb.0:583; X86-NEXT: movswl {{[0-9]+}}(%esp), %eax584; X86-NEXT: vcvtsi2sh %eax, %xmm7, %xmm0585; X86-NEXT: retl586 %a = sitofp i16 %x to half587 ret half %a588}589 590define half @s32_to_half(i32 %x) {591; X64-LABEL: s32_to_half:592; X64: # %bb.0:593; X64-NEXT: vcvtsi2sh %edi, %xmm31, %xmm0594; X64-NEXT: retq595;596; X86-LABEL: s32_to_half:597; X86: # %bb.0:598; X86-NEXT: vcvtsi2shl {{[0-9]+}}(%esp), %xmm7, %xmm0599; X86-NEXT: retl600 %a = sitofp i32 %x to half601 ret half %a602}603 604define half @s64_to_half(i64 %x) {605; X64-LABEL: s64_to_half:606; X64: # %bb.0:607; X64-NEXT: vcvtsi2sh %rdi, %xmm31, %xmm0608; X64-NEXT: retq609;610; X86-LABEL: s64_to_half:611; X86: # %bb.0:612; X86-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero613; X86-NEXT: vcvtqq2ph %xmm0, %xmm0614; X86-NEXT: retl615 %a = sitofp i64 %x to half616 ret half %a617}618 619define half @s128_to_half(i128 %x) {620; X64-LABEL: s128_to_half:621; X64: # %bb.0:622; X64-NEXT: pushq %rax623; X64-NEXT: .cfi_def_cfa_offset 16624; X64-NEXT: callq __floattihf@PLT625; X64-NEXT: popq %rax626; X64-NEXT: .cfi_def_cfa_offset 8627; X64-NEXT: retq628;629; X86-LABEL: s128_to_half:630; X86: # %bb.0:631; X86-NEXT: pushl %ebp632; X86-NEXT: .cfi_def_cfa_offset 8633; X86-NEXT: .cfi_offset %ebp, -8634; X86-NEXT: movl %esp, %ebp635; X86-NEXT: .cfi_def_cfa_register %ebp636; X86-NEXT: andl $-16, %esp637; X86-NEXT: subl $32, %esp638; X86-NEXT: vmovups 8(%ebp), %xmm0639; X86-NEXT: vmovups %xmm0, (%esp)640; X86-NEXT: calll __floattihf641; X86-NEXT: movl %ebp, %esp642; X86-NEXT: popl %ebp643; X86-NEXT: .cfi_def_cfa %esp, 4644; X86-NEXT: retl645 %a = sitofp i128 %x to half646 ret half %a647}648 649define half @u8_to_half(i8 %x) {650; X64-LABEL: u8_to_half:651; X64: # %bb.0:652; X64-NEXT: movzbl %dil, %eax653; X64-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0654; X64-NEXT: retq655;656; X86-LABEL: u8_to_half:657; X86: # %bb.0:658; X86-NEXT: movzbl {{[0-9]+}}(%esp), %eax659; X86-NEXT: vcvtsi2sh %eax, %xmm7, %xmm0660; X86-NEXT: retl661 %a = uitofp i8 %x to half662 ret half %a663}664 665define half @u16_to_half(i16 %x) {666; X64-LABEL: u16_to_half:667; X64: # %bb.0:668; X64-NEXT: movzwl %di, %eax669; X64-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0670; X64-NEXT: retq671;672; X86-LABEL: u16_to_half:673; X86: # %bb.0:674; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax675; X86-NEXT: vcvtsi2sh %eax, %xmm7, %xmm0676; X86-NEXT: retl677 %a = uitofp i16 %x to half678 ret half %a679}680 681define half @u32_to_half(i32 %x) {682; X64-LABEL: u32_to_half:683; X64: # %bb.0:684; X64-NEXT: vcvtusi2sh %edi, %xmm31, %xmm0685; X64-NEXT: retq686;687; X86-LABEL: u32_to_half:688; X86: # %bb.0:689; X86-NEXT: vcvtusi2shl {{[0-9]+}}(%esp), %xmm7, %xmm0690; X86-NEXT: retl691 %a = uitofp i32 %x to half692 ret half %a693}694 695define half @u64_to_half(i64 %x) {696; X64-LABEL: u64_to_half:697; X64: # %bb.0:698; X64-NEXT: vcvtusi2sh %rdi, %xmm31, %xmm0699; X64-NEXT: retq700;701; X86-LABEL: u64_to_half:702; X86: # %bb.0:703; X86-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero704; X86-NEXT: vcvtuqq2ph %xmm0, %xmm0705; X86-NEXT: retl706 %a = uitofp i64 %x to half707 ret half %a708}709 710define half @u128_to_half(i128 %x) {711; X64-LABEL: u128_to_half:712; X64: # %bb.0:713; X64-NEXT: pushq %rax714; X64-NEXT: .cfi_def_cfa_offset 16715; X64-NEXT: callq __floatuntihf@PLT716; X64-NEXT: popq %rax717; X64-NEXT: .cfi_def_cfa_offset 8718; X64-NEXT: retq719;720; X86-LABEL: u128_to_half:721; X86: # %bb.0:722; X86-NEXT: pushl %ebp723; X86-NEXT: .cfi_def_cfa_offset 8724; X86-NEXT: .cfi_offset %ebp, -8725; X86-NEXT: movl %esp, %ebp726; X86-NEXT: .cfi_def_cfa_register %ebp727; X86-NEXT: andl $-16, %esp728; X86-NEXT: subl $32, %esp729; X86-NEXT: vmovups 8(%ebp), %xmm0730; X86-NEXT: vmovups %xmm0, (%esp)731; X86-NEXT: calll __floatuntihf732; X86-NEXT: movl %ebp, %esp733; X86-NEXT: popl %ebp734; X86-NEXT: .cfi_def_cfa %esp, 4735; X86-NEXT: retl736 %a = uitofp i128 %x to half737 ret half %a738}739 740define i8 @half_to_s8(half %x) {741; X64-LABEL: half_to_s8:742; X64: # %bb.0:743; X64-NEXT: vcvttsh2si %xmm0, %eax744; X64-NEXT: # kill: def $al killed $al killed $eax745; X64-NEXT: retq746;747; X86-LABEL: half_to_s8:748; X86: # %bb.0:749; X86-NEXT: vcvttsh2si {{[0-9]+}}(%esp), %eax750; X86-NEXT: # kill: def $al killed $al killed $eax751; X86-NEXT: retl752 %a = fptosi half %x to i8753 ret i8 %a754}755 756define i16 @half_to_s16(half %x) {757; X64-LABEL: half_to_s16:758; X64: # %bb.0:759; X64-NEXT: vcvttsh2si %xmm0, %eax760; X64-NEXT: # kill: def $ax killed $ax killed $eax761; X64-NEXT: retq762;763; X86-LABEL: half_to_s16:764; X86: # %bb.0:765; X86-NEXT: vcvttsh2si {{[0-9]+}}(%esp), %eax766; X86-NEXT: # kill: def $ax killed $ax killed $eax767; X86-NEXT: retl768 %a = fptosi half %x to i16769 ret i16 %a770}771 772define i32 @half_to_s32(half %x) {773; X64-LABEL: half_to_s32:774; X64: # %bb.0:775; X64-NEXT: vcvttsh2si %xmm0, %eax776; X64-NEXT: retq777;778; X86-LABEL: half_to_s32:779; X86: # %bb.0:780; X86-NEXT: vcvttsh2si {{[0-9]+}}(%esp), %eax781; X86-NEXT: retl782 %a = fptosi half %x to i32783 ret i32 %a784}785 786define i64 @half_to_s64(half %x) {787; X64-LABEL: half_to_s64:788; X64: # %bb.0:789; X64-NEXT: vcvttsh2si %xmm0, %rax790; X64-NEXT: retq791;792; X86-LABEL: half_to_s64:793; X86: # %bb.0:794; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero795; X86-NEXT: vcvttph2qq %xmm0, %xmm0796; X86-NEXT: vmovd %xmm0, %eax797; X86-NEXT: vpextrd $1, %xmm0, %edx798; X86-NEXT: retl799 %a = fptosi half %x to i64800 ret i64 %a801}802 803define i128 @half_to_s128(half %x) {804; X64-LABEL: half_to_s128:805; X64: # %bb.0:806; X64-NEXT: pushq %rax807; X64-NEXT: .cfi_def_cfa_offset 16808; X64-NEXT: callq __fixhfti@PLT809; X64-NEXT: popq %rcx810; X64-NEXT: .cfi_def_cfa_offset 8811; X64-NEXT: retq812;813; X86-LABEL: half_to_s128:814; X86: # %bb.0:815; X86-NEXT: pushl %ebp816; X86-NEXT: .cfi_def_cfa_offset 8817; X86-NEXT: .cfi_offset %ebp, -8818; X86-NEXT: movl %esp, %ebp819; X86-NEXT: .cfi_def_cfa_register %ebp820; X86-NEXT: pushl %esi821; X86-NEXT: andl $-16, %esp822; X86-NEXT: subl $48, %esp823; X86-NEXT: .cfi_offset %esi, -12824; X86-NEXT: movl 8(%ebp), %esi825; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero826; X86-NEXT: vmovsh %xmm0, {{[0-9]+}}(%esp)827; X86-NEXT: leal {{[0-9]+}}(%esp), %eax828; X86-NEXT: movl %eax, (%esp)829; X86-NEXT: calll __fixhfti830; X86-NEXT: subl $4, %esp831; X86-NEXT: vmovaps {{[0-9]+}}(%esp), %xmm0832; X86-NEXT: vmovaps %xmm0, (%esi)833; X86-NEXT: movl %esi, %eax834; X86-NEXT: leal -4(%ebp), %esp835; X86-NEXT: popl %esi836; X86-NEXT: popl %ebp837; X86-NEXT: .cfi_def_cfa %esp, 4838; X86-NEXT: retl $4839 %a = fptosi half %x to i128840 ret i128 %a841}842 843define i8 @half_to_u8(half %x) {844; X64-LABEL: half_to_u8:845; X64: # %bb.0:846; X64-NEXT: vcvttsh2si %xmm0, %eax847; X64-NEXT: # kill: def $al killed $al killed $eax848; X64-NEXT: retq849;850; X86-LABEL: half_to_u8:851; X86: # %bb.0:852; X86-NEXT: vcvttsh2si {{[0-9]+}}(%esp), %eax853; X86-NEXT: # kill: def $al killed $al killed $eax854; X86-NEXT: retl855 %a = fptoui half %x to i8856 ret i8 %a857}858 859define i16 @half_to_u16(half %x) {860; X64-LABEL: half_to_u16:861; X64: # %bb.0:862; X64-NEXT: vcvttsh2si %xmm0, %eax863; X64-NEXT: # kill: def $ax killed $ax killed $eax864; X64-NEXT: retq865;866; X86-LABEL: half_to_u16:867; X86: # %bb.0:868; X86-NEXT: vcvttsh2si {{[0-9]+}}(%esp), %eax869; X86-NEXT: # kill: def $ax killed $ax killed $eax870; X86-NEXT: retl871 %a = fptoui half %x to i16872 ret i16 %a873}874 875define i32 @half_to_u32(half %x) {876; X64-LABEL: half_to_u32:877; X64: # %bb.0:878; X64-NEXT: vcvttsh2usi %xmm0, %eax879; X64-NEXT: retq880;881; X86-LABEL: half_to_u32:882; X86: # %bb.0:883; X86-NEXT: vcvttsh2usi {{[0-9]+}}(%esp), %eax884; X86-NEXT: retl885 %a = fptoui half %x to i32886 ret i32 %a887}888 889define i64 @half_to_u64(half %x) {890; X64-LABEL: half_to_u64:891; X64: # %bb.0:892; X64-NEXT: vcvttsh2usi %xmm0, %rax893; X64-NEXT: retq894;895; X86-LABEL: half_to_u64:896; X86: # %bb.0:897; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero898; X86-NEXT: vcvttph2uqq %xmm0, %xmm0899; X86-NEXT: vmovd %xmm0, %eax900; X86-NEXT: vpextrd $1, %xmm0, %edx901; X86-NEXT: retl902 %a = fptoui half %x to i64903 ret i64 %a904}905 906define i128 @half_to_u128(half %x) {907; X64-LABEL: half_to_u128:908; X64: # %bb.0:909; X64-NEXT: pushq %rax910; X64-NEXT: .cfi_def_cfa_offset 16911; X64-NEXT: callq __fixunshfti@PLT912; X64-NEXT: popq %rcx913; X64-NEXT: .cfi_def_cfa_offset 8914; X64-NEXT: retq915;916; X86-LABEL: half_to_u128:917; X86: # %bb.0:918; X86-NEXT: pushl %ebp919; X86-NEXT: .cfi_def_cfa_offset 8920; X86-NEXT: .cfi_offset %ebp, -8921; X86-NEXT: movl %esp, %ebp922; X86-NEXT: .cfi_def_cfa_register %ebp923; X86-NEXT: pushl %esi924; X86-NEXT: andl $-16, %esp925; X86-NEXT: subl $48, %esp926; X86-NEXT: .cfi_offset %esi, -12927; X86-NEXT: movl 8(%ebp), %esi928; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero929; X86-NEXT: vmovsh %xmm0, {{[0-9]+}}(%esp)930; X86-NEXT: leal {{[0-9]+}}(%esp), %eax931; X86-NEXT: movl %eax, (%esp)932; X86-NEXT: calll __fixunshfti933; X86-NEXT: subl $4, %esp934; X86-NEXT: vmovaps {{[0-9]+}}(%esp), %xmm0935; X86-NEXT: vmovaps %xmm0, (%esi)936; X86-NEXT: movl %esi, %eax937; X86-NEXT: leal -4(%ebp), %esp938; X86-NEXT: popl %esi939; X86-NEXT: popl %ebp940; X86-NEXT: .cfi_def_cfa %esp, 4941; X86-NEXT: retl $4942 %a = fptoui half %x to i128943 ret i128 %a944}945 946define x86_fp80 @half_to_f80(half %x) nounwind {947; X64-LABEL: half_to_f80:948; X64: # %bb.0:949; X64-NEXT: pushq %rax950; X64-NEXT: callq __extendhfxf2@PLT951; X64-NEXT: popq %rax952; X64-NEXT: retq953;954; X86-LABEL: half_to_f80:955; X86: # %bb.0:956; X86-NEXT: pushl %eax957; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero958; X86-NEXT: vmovsh %xmm0, (%esp)959; X86-NEXT: calll __extendhfxf2960; X86-NEXT: popl %eax961; X86-NEXT: retl962 %a = fpext half %x to x86_fp80963 ret x86_fp80 %a964}965 966define half @f80_to_half(x86_fp80 %x) nounwind {967; X64-LABEL: f80_to_half:968; X64: # %bb.0:969; X64-NEXT: subq $24, %rsp970; X64-NEXT: fldt {{[0-9]+}}(%rsp)971; X64-NEXT: fstpt (%rsp)972; X64-NEXT: callq __truncxfhf2@PLT973; X64-NEXT: addq $24, %rsp974; X64-NEXT: retq975;976; X86-LABEL: f80_to_half:977; X86: # %bb.0:978; X86-NEXT: subl $12, %esp979; X86-NEXT: fldt {{[0-9]+}}(%esp)980; X86-NEXT: fstpt (%esp)981; X86-NEXT: calll __truncxfhf2982; X86-NEXT: addl $12, %esp983; X86-NEXT: retl984 %a = fptrunc x86_fp80 %x to half985 ret half %a986}987 988; FIXME: We're doing a two step conversion here on 32-bit.989; First from f16->f32 then f32->f128. This is occuring990; due to common code in LegalizeFloatTypes that thinks991; there are no libcalls for f16 to any type but f32.992; Changing this may break other non-x86 targets. The code993; generated here should be functional.994define fp128 @half_to_f128(half %x) nounwind {995; X64-LABEL: half_to_f128:996; X64: # %bb.0:997; X64-NEXT: jmp __extendhftf2@PLT # TAILCALL998;999; X86-LABEL: half_to_f128:1000; X86: # %bb.0:1001; X86-NEXT: pushl %ebp1002; X86-NEXT: movl %esp, %ebp1003; X86-NEXT: pushl %esi1004; X86-NEXT: andl $-16, %esp1005; X86-NEXT: subl $48, %esp1006; X86-NEXT: movl 8(%ebp), %esi1007; X86-NEXT: vmovsh {{.*#+}} xmm0 = mem[0],zero,zero,zero,zero,zero,zero,zero1008; X86-NEXT: vcvtsh2ss %xmm0, %xmm0, %xmm01009; X86-NEXT: vmovss %xmm0, {{[0-9]+}}(%esp)1010; X86-NEXT: leal {{[0-9]+}}(%esp), %eax1011; X86-NEXT: movl %eax, (%esp)1012; X86-NEXT: calll __extendsftf21013; X86-NEXT: subl $4, %esp1014; X86-NEXT: vmovaps {{[0-9]+}}(%esp), %xmm01015; X86-NEXT: vmovaps %xmm0, (%esi)1016; X86-NEXT: movl %esi, %eax1017; X86-NEXT: leal -4(%ebp), %esp1018; X86-NEXT: popl %esi1019; X86-NEXT: popl %ebp1020; X86-NEXT: retl $41021 %a = fpext half %x to fp1281022 ret fp128 %a1023}1024 1025define half @f128_to_half(fp128 %x) nounwind {1026; X64-LABEL: f128_to_half:1027; X64: # %bb.0:1028; X64-NEXT: pushq %rax1029; X64-NEXT: callq __trunctfhf2@PLT1030; X64-NEXT: popq %rax1031; X64-NEXT: retq1032;1033; X86-LABEL: f128_to_half:1034; X86: # %bb.0:1035; X86-NEXT: pushl %ebp1036; X86-NEXT: movl %esp, %ebp1037; X86-NEXT: andl $-16, %esp1038; X86-NEXT: subl $32, %esp1039; X86-NEXT: vmovups 8(%ebp), %xmm01040; X86-NEXT: vmovups %xmm0, (%esp)1041; X86-NEXT: calll __trunctfhf21042; X86-NEXT: movl %ebp, %esp1043; X86-NEXT: popl %ebp1044; X86-NEXT: retl1045 %a = fptrunc fp128 %x to half1046 ret half %a1047}1048 1049define <8 x half> @s64tof16(<8 x i64> %a) #0 {1050; CHECK-LABEL: s64tof16:1051; CHECK: # %bb.0:1052; CHECK-NEXT: vcvtqq2ph %ymm1, %xmm11053; CHECK-NEXT: vcvtqq2ph %ymm0, %xmm01054; CHECK-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]1055; CHECK-NEXT: vzeroupper1056; CHECK-NEXT: ret{{[l|q]}}1057 %1 = sitofp <8 x i64> %a to <8 x half>1058 ret <8 x half> %11059}1060 1061define <8 x half> @u64tof16(<8 x i64> %a) #0 {1062; CHECK-LABEL: u64tof16:1063; CHECK: # %bb.0:1064; CHECK-NEXT: vcvtuqq2ph %ymm1, %xmm11065; CHECK-NEXT: vcvtuqq2ph %ymm0, %xmm01066; CHECK-NEXT: vmovlhps {{.*#+}} xmm0 = xmm0[0],xmm1[0]1067; CHECK-NEXT: vzeroupper1068; CHECK-NEXT: ret{{[l|q]}}1069 %1 = uitofp <8 x i64> %a to <8 x half>1070 ret <8 x half> %11071}1072 1073define void @f16tou32(ptr %ptr) {1074; X64-LABEL: f16tou32:1075; X64: # %bb.0:1076; X64-NEXT: vcvttph2udq {{\.?LCPI[0-9]+_[0-9]+}}(%rip){1to4}, %xmm01077; X64-NEXT: vmovlps %xmm0, (%rdi)1078; X64-NEXT: retq1079;1080; X86-LABEL: f16tou32:1081; X86: # %bb.0:1082; X86-NEXT: movl {{[0-9]+}}(%esp), %eax1083; X86-NEXT: vcvttph2udq {{\.?LCPI[0-9]+_[0-9]+}}{1to4}, %xmm01084; X86-NEXT: vmovlps %xmm0, (%eax)1085; X86-NEXT: retl1086 %1 = fptoui <2 x half> splat (half 0xH7E00) to <2 x i32>1087 store <2 x i32> %1, ptr %ptr, align 81088 ret void1089}1090 1091attributes #0 = { "min-legal-vector-width"="256" "prefer-vector-width"="256" }1092