312 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 32; RUN: llc -o - %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v4 | FileCheck %s --check-prefixes=CHECK-NO_FP163; RUN: llc -o - %s -mtriple=x86_64-unknown-unknown -mcpu=x86-64-v4 -mattr=+avx512fp16 | FileCheck %s --check-prefixes=CHECK-WITH_FP164 5; Note: We could check more configurations, but anything with software6; emulation of fp16 generates a ton of assembly code and is not particularly7; interesting.8 9;----------------------------------------10; i8 input11;----------------------------------------12 13; uint8_t to float.14; - Go from i8 to i32: zext15; - Convert i32 to float16define float @uint8ToFloat(i8 %int8) {17; CHECK-NO_FP16-LABEL: uint8ToFloat:18; CHECK-NO_FP16: # %bb.0:19; CHECK-NO_FP16-NEXT: movzbl %dil, %eax20; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm021; CHECK-NO_FP16-NEXT: retq22;23; CHECK-WITH_FP16-LABEL: uint8ToFloat:24; CHECK-WITH_FP16: # %bb.0:25; CHECK-WITH_FP16-NEXT: movzbl %dil, %eax26; CHECK-WITH_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm027; CHECK-WITH_FP16-NEXT: retq28 %fp32 = uitofp i8 %int8 to float29 ret float %fp3230}31 32; vector uint8_t to float.33; Same as @uint8ToFloat but with vector types.34define <16 x float> @vector_uint8ToFloat(<16 x i8> %int8) {35; CHECK-NO_FP16-LABEL: vector_uint8ToFloat:36; CHECK-NO_FP16: # %bb.0:37; CHECK-NO_FP16-NEXT: vpmovzxbd {{.*#+}} zmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero,xmm0[8],zero,zero,zero,xmm0[9],zero,zero,zero,xmm0[10],zero,zero,zero,xmm0[11],zero,zero,zero,xmm0[12],zero,zero,zero,xmm0[13],zero,zero,zero,xmm0[14],zero,zero,zero,xmm0[15],zero,zero,zero38; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm039; CHECK-NO_FP16-NEXT: retq40;41; CHECK-WITH_FP16-LABEL: vector_uint8ToFloat:42; CHECK-WITH_FP16: # %bb.0:43; CHECK-WITH_FP16-NEXT: vpmovzxbd {{.*#+}} zmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero,xmm0[8],zero,zero,zero,xmm0[9],zero,zero,zero,xmm0[10],zero,zero,zero,xmm0[11],zero,zero,zero,xmm0[12],zero,zero,zero,xmm0[13],zero,zero,zero,xmm0[14],zero,zero,zero,xmm0[15],zero,zero,zero44; CHECK-WITH_FP16-NEXT: vcvtdq2ps %zmm0, %zmm045; CHECK-WITH_FP16-NEXT: retq46 %fp32 = uitofp <16 x i8> %int8 to <16 x float>47 ret <16 x float> %fp3248}49 50 51; uint8_t to half.52;53; If no half support:54; - Go from i8 to i32: zext55; - Convert i32 to float56; - Trunc from float to half57;58; Else if half support:59; - Go from i8 to i32: zext60; - Convert i32 to half61define half @uint8ToHalf(i8 %int8) {62; CHECK-NO_FP16-LABEL: uint8ToHalf:63; CHECK-NO_FP16: # %bb.0:64; CHECK-NO_FP16-NEXT: movzbl %dil, %eax65; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm066; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %xmm0, %xmm067; CHECK-NO_FP16-NEXT: retq68;69; CHECK-WITH_FP16-LABEL: uint8ToHalf:70; CHECK-WITH_FP16: # %bb.0:71; CHECK-WITH_FP16-NEXT: movzbl %dil, %eax72; CHECK-WITH_FP16-NEXT: vcvtsi2sh %eax, %xmm31, %xmm073; CHECK-WITH_FP16-NEXT: retq74 %fp32 = uitofp i8 %int8 to half75 ret half %fp3276}77 78; vector uint8_t to half.79;80; If no half support:81; - Go from i8 to i32: zext82; - Convert i32 to float83; - Trunc from float to half84;85; Else if half support:86; - Go from i8 to i16: zext87; - Convert i16 to half88;89; The difference with the scalar version (uint8ToHalf) is that we use i1690; for the intermediate type when we have half support.91define <16 x half> @vector_uint8ToHalf(<16 x i8> %int8) {92; CHECK-NO_FP16-LABEL: vector_uint8ToHalf:93; CHECK-NO_FP16: # %bb.0:94; CHECK-NO_FP16-NEXT: vpmovzxbd {{.*#+}} zmm0 = xmm0[0],zero,zero,zero,xmm0[1],zero,zero,zero,xmm0[2],zero,zero,zero,xmm0[3],zero,zero,zero,xmm0[4],zero,zero,zero,xmm0[5],zero,zero,zero,xmm0[6],zero,zero,zero,xmm0[7],zero,zero,zero,xmm0[8],zero,zero,zero,xmm0[9],zero,zero,zero,xmm0[10],zero,zero,zero,xmm0[11],zero,zero,zero,xmm0[12],zero,zero,zero,xmm0[13],zero,zero,zero,xmm0[14],zero,zero,zero,xmm0[15],zero,zero,zero95; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm096; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %zmm0, %ymm097; CHECK-NO_FP16-NEXT: retq98;99; CHECK-WITH_FP16-LABEL: vector_uint8ToHalf:100; CHECK-WITH_FP16: # %bb.0:101; CHECK-WITH_FP16-NEXT: vpmovzxbw {{.*#+}} ymm0 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero,xmm0[8],zero,xmm0[9],zero,xmm0[10],zero,xmm0[11],zero,xmm0[12],zero,xmm0[13],zero,xmm0[14],zero,xmm0[15],zero102; CHECK-WITH_FP16-NEXT: vcvtw2ph %ymm0, %ymm0103; CHECK-WITH_FP16-NEXT: retq104 %fp32 = uitofp <16 x i8> %int8 to <16 x half>105 ret <16 x half> %fp32106}107 108; Same as uint8_t but with the signed variant.109; I.e., use sext instead of zext.110define float @sint8ToFloat(i8 %int8) {111; CHECK-NO_FP16-LABEL: sint8ToFloat:112; CHECK-NO_FP16: # %bb.0:113; CHECK-NO_FP16-NEXT: movsbl %dil, %eax114; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0115; CHECK-NO_FP16-NEXT: retq116;117; CHECK-WITH_FP16-LABEL: sint8ToFloat:118; CHECK-WITH_FP16: # %bb.0:119; CHECK-WITH_FP16-NEXT: movsbl %dil, %eax120; CHECK-WITH_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0121; CHECK-WITH_FP16-NEXT: retq122 %fp32 = sitofp i8 %int8 to float123 ret float %fp32124}125 126define <16 x float> @vector_sint8ToFloat(<16 x i8> %int8) {127; CHECK-NO_FP16-LABEL: vector_sint8ToFloat:128; CHECK-NO_FP16: # %bb.0:129; CHECK-NO_FP16-NEXT: vpmovsxbd %xmm0, %zmm0130; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0131; CHECK-NO_FP16-NEXT: retq132;133; CHECK-WITH_FP16-LABEL: vector_sint8ToFloat:134; CHECK-WITH_FP16: # %bb.0:135; CHECK-WITH_FP16-NEXT: vpmovsxbd %xmm0, %zmm0136; CHECK-WITH_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0137; CHECK-WITH_FP16-NEXT: retq138 %fp32 = sitofp <16 x i8> %int8 to <16 x float>139 ret <16 x float> %fp32140}141 142define half @sint8ToHalf(i8 %int8) {143; CHECK-NO_FP16-LABEL: sint8ToHalf:144; CHECK-NO_FP16: # %bb.0:145; CHECK-NO_FP16-NEXT: movsbl %dil, %eax146; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0147; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %xmm0, %xmm0148; CHECK-NO_FP16-NEXT: retq149;150; CHECK-WITH_FP16-LABEL: sint8ToHalf:151; CHECK-WITH_FP16: # %bb.0:152; CHECK-WITH_FP16-NEXT: movsbl %dil, %eax153; CHECK-WITH_FP16-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0154; CHECK-WITH_FP16-NEXT: retq155 %fp32 = sitofp i8 %int8 to half156 ret half %fp32157}158 159define <16 x half> @vector_sint8ToHalf(<16 x i8> %int8) {160; CHECK-NO_FP16-LABEL: vector_sint8ToHalf:161; CHECK-NO_FP16: # %bb.0:162; CHECK-NO_FP16-NEXT: vpmovsxbd %xmm0, %zmm0163; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0164; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %zmm0, %ymm0165; CHECK-NO_FP16-NEXT: retq166;167; CHECK-WITH_FP16-LABEL: vector_sint8ToHalf:168; CHECK-WITH_FP16: # %bb.0:169; CHECK-WITH_FP16-NEXT: vpmovsxbw %xmm0, %ymm0170; CHECK-WITH_FP16-NEXT: vcvtw2ph %ymm0, %ymm0171; CHECK-WITH_FP16-NEXT: retq172 %fp32 = sitofp <16 x i8> %int8 to <16 x half>173 ret <16 x half> %fp32174}175 176 177;----------------------------------------178; i16 input179;----------------------------------------180 181; Similar lowering as i8, but with i16 as the input type.182 183define float @uint16ToFloat(i16 %int16) {184; CHECK-NO_FP16-LABEL: uint16ToFloat:185; CHECK-NO_FP16: # %bb.0:186; CHECK-NO_FP16-NEXT: movzwl %di, %eax187; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0188; CHECK-NO_FP16-NEXT: retq189;190; CHECK-WITH_FP16-LABEL: uint16ToFloat:191; CHECK-WITH_FP16: # %bb.0:192; CHECK-WITH_FP16-NEXT: movzwl %di, %eax193; CHECK-WITH_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0194; CHECK-WITH_FP16-NEXT: retq195 %fp32 = uitofp i16 %int16 to float196 ret float %fp32197}198 199define <16 x float> @vector_uint16ToFloat(<16 x i16> %int16) {200; CHECK-NO_FP16-LABEL: vector_uint16ToFloat:201; CHECK-NO_FP16: # %bb.0:202; CHECK-NO_FP16-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero203; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0204; CHECK-NO_FP16-NEXT: retq205;206; CHECK-WITH_FP16-LABEL: vector_uint16ToFloat:207; CHECK-WITH_FP16: # %bb.0:208; CHECK-WITH_FP16-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero209; CHECK-WITH_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0210; CHECK-WITH_FP16-NEXT: retq211 %fp32 = uitofp <16 x i16> %int16 to <16 x float>212 ret <16 x float> %fp32213}214 215define half @uint16ToHalf(i16 %int16) {216; CHECK-NO_FP16-LABEL: uint16ToHalf:217; CHECK-NO_FP16: # %bb.0:218; CHECK-NO_FP16-NEXT: movzwl %di, %eax219; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0220; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %xmm0, %xmm0221; CHECK-NO_FP16-NEXT: retq222;223; CHECK-WITH_FP16-LABEL: uint16ToHalf:224; CHECK-WITH_FP16: # %bb.0:225; CHECK-WITH_FP16-NEXT: movzwl %di, %eax226; CHECK-WITH_FP16-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0227; CHECK-WITH_FP16-NEXT: retq228 %fp32 = uitofp i16 %int16 to half229 ret half %fp32230}231 232define <16 x half> @vector_uint16ToHalf(<16 x i16> %int16) {233; CHECK-NO_FP16-LABEL: vector_uint16ToHalf:234; CHECK-NO_FP16: # %bb.0:235; CHECK-NO_FP16-NEXT: vpmovzxwd {{.*#+}} zmm0 = ymm0[0],zero,ymm0[1],zero,ymm0[2],zero,ymm0[3],zero,ymm0[4],zero,ymm0[5],zero,ymm0[6],zero,ymm0[7],zero,ymm0[8],zero,ymm0[9],zero,ymm0[10],zero,ymm0[11],zero,ymm0[12],zero,ymm0[13],zero,ymm0[14],zero,ymm0[15],zero236; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0237; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %zmm0, %ymm0238; CHECK-NO_FP16-NEXT: retq239;240; CHECK-WITH_FP16-LABEL: vector_uint16ToHalf:241; CHECK-WITH_FP16: # %bb.0:242; CHECK-WITH_FP16-NEXT: vcvtuw2ph %ymm0, %ymm0243; CHECK-WITH_FP16-NEXT: retq244 %fp32 = uitofp <16 x i16> %int16 to <16 x half>245 ret <16 x half> %fp32246}247 248define float @sint16ToFloat(i16 %int16) {249; CHECK-NO_FP16-LABEL: sint16ToFloat:250; CHECK-NO_FP16: # %bb.0:251; CHECK-NO_FP16-NEXT: movswl %di, %eax252; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0253; CHECK-NO_FP16-NEXT: retq254;255; CHECK-WITH_FP16-LABEL: sint16ToFloat:256; CHECK-WITH_FP16: # %bb.0:257; CHECK-WITH_FP16-NEXT: movswl %di, %eax258; CHECK-WITH_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0259; CHECK-WITH_FP16-NEXT: retq260 %fp32 = sitofp i16 %int16 to float261 ret float %fp32262}263 264define <16 x float> @vector_sint16ToFloat(<16 x i16> %int16) {265; CHECK-NO_FP16-LABEL: vector_sint16ToFloat:266; CHECK-NO_FP16: # %bb.0:267; CHECK-NO_FP16-NEXT: vpmovsxwd %ymm0, %zmm0268; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0269; CHECK-NO_FP16-NEXT: retq270;271; CHECK-WITH_FP16-LABEL: vector_sint16ToFloat:272; CHECK-WITH_FP16: # %bb.0:273; CHECK-WITH_FP16-NEXT: vpmovsxwd %ymm0, %zmm0274; CHECK-WITH_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0275; CHECK-WITH_FP16-NEXT: retq276 %fp32 = sitofp <16 x i16> %int16 to <16 x float>277 ret <16 x float> %fp32278}279 280define half @sint16ToHalf(i16 %int16) {281; CHECK-NO_FP16-LABEL: sint16ToHalf:282; CHECK-NO_FP16: # %bb.0:283; CHECK-NO_FP16-NEXT: movswl %di, %eax284; CHECK-NO_FP16-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0285; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %xmm0, %xmm0286; CHECK-NO_FP16-NEXT: retq287;288; CHECK-WITH_FP16-LABEL: sint16ToHalf:289; CHECK-WITH_FP16: # %bb.0:290; CHECK-WITH_FP16-NEXT: movswl %di, %eax291; CHECK-WITH_FP16-NEXT: vcvtsi2sh %eax, %xmm31, %xmm0292; CHECK-WITH_FP16-NEXT: retq293 %fp32 = sitofp i16 %int16 to half294 ret half %fp32295}296 297define <16 x half> @vector_sint16ToHalf(<16 x i16> %int16) {298; CHECK-NO_FP16-LABEL: vector_sint16ToHalf:299; CHECK-NO_FP16: # %bb.0:300; CHECK-NO_FP16-NEXT: vpmovsxwd %ymm0, %zmm0301; CHECK-NO_FP16-NEXT: vcvtdq2ps %zmm0, %zmm0302; CHECK-NO_FP16-NEXT: vcvtps2ph $4, %zmm0, %ymm0303; CHECK-NO_FP16-NEXT: retq304;305; CHECK-WITH_FP16-LABEL: vector_sint16ToHalf:306; CHECK-WITH_FP16: # %bb.0:307; CHECK-WITH_FP16-NEXT: vcvtw2ph %ymm0, %ymm0308; CHECK-WITH_FP16-NEXT: retq309 %fp32 = sitofp <16 x i16> %int16 to <16 x half>310 ret <16 x half> %fp32311}312