Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 39 additions & 10 deletions llvm/lib/Target/X86/X86ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19897,21 +19897,50 @@ static SDValue lowerFPToIntToFP(SDValue CastToFP, const SDLoc &DL,
// See if we have 128-bit vector cast instructions for this type of cast.
// We need cvttps2dq/cvttpd2dq and cvtdq2ps/cvtdq2pd.
if (!Subtarget.hasSSE2() || (VT != MVT::f32 && VT != MVT::f64) ||
IntVT != MVT::i32)
!(IntVT == MVT::i32 || (IntVT == MVT::i64 && Subtarget.hasDQI())))
return SDValue();

unsigned SrcSize = SrcVT.getSizeInBits();
unsigned IntSize = IntVT.getSizeInBits();
unsigned VTSize = VT.getSizeInBits();
MVT VecSrcVT = MVT::getVectorVT(SrcVT, 128 / SrcSize);
MVT VecIntVT = MVT::getVectorVT(IntVT, 128 / IntSize);
MVT VecVT = MVT::getVectorVT(VT, 128 / VTSize);

// We need target-specific opcodes if this is v2f64 -> v4i32 -> v2f64.
unsigned ToIntOpcode =
SrcSize != IntSize ? X86ISD::CVTTP2SI : (unsigned)ISD::FP_TO_SINT;
unsigned ToFPOpcode =
IntSize != VTSize ? X86ISD::CVTSI2P : (unsigned)ISD::SINT_TO_FP;
unsigned ToIntOpcode, ToFPOpcode;
unsigned Width = 128;
bool IsUnsigned = CastToInt.getOpcode() == ISD::FP_TO_UINT;

if (Subtarget.hasAVX512()) {
if (Subtarget.hasVLX()) {
// AVX512VL could handle for FP_TO_UINT/UINT_TO_FP (f64/32 <-> i32)
// AVX512F as well but Width = 512
if (IntVT == MVT::i32) {
ToIntOpcode = IsUnsigned ? X86ISD::CVTTP2UI : X86ISD::CVTTP2SI;
ToFPOpcode = IsUnsigned ? X86ISD::CVTUI2P : X86ISD::CVTSI2P;
} else {
ToIntOpcode = CastToInt.getOpcode();
ToFPOpcode = IsUnsigned ? ISD::UINT_TO_FP : ISD::SINT_TO_FP;
}
} else if (IntVT == MVT::i64) {
// AVX512DQ + AVX512VL could handle f64/32 <-> i64 SINT & UINT
ToIntOpcode = CastToInt.getOpcode();
ToFPOpcode = IsUnsigned ? ISD::UINT_TO_FP : ISD::SINT_TO_FP;
} else {
// AVX512F
Width = 512;
ToIntOpcode = CastToInt.getOpcode();
ToFPOpcode = IsUnsigned ? ISD::UINT_TO_FP : ISD::SINT_TO_FP;
}
} else {
if (IntVT != MVT::i32 || IsUnsigned)
return SDValue();
// We need target-specific opcodes if this is v2f64 -> v4i32 -> v2f64.
ToIntOpcode =
SrcSize != IntSize ? X86ISD::CVTTP2SI : (unsigned)ISD::FP_TO_SINT;
ToFPOpcode =
IntSize != VTSize ? X86ISD::CVTSI2P : (unsigned)ISD::SINT_TO_FP;
}

MVT VecSrcVT = MVT::getVectorVT(SrcVT, Width / SrcSize);
MVT VecIntVT = MVT::getVectorVT(IntVT, Width / IntSize);
MVT VecVT = MVT::getVectorVT(VT, Width / VTSize);

// sint_to_fp (fp_to_sint X) --> extelt (sint_to_fp (fp_to_sint (s2v X))), 0
//
Expand Down
Loading