diff options
Diffstat (limited to 'llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp | 102 |
1 files changed, 101 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp index dd8ecf6ef7fc..bab7fe9d25e4 100644 --- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp +++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp @@ -315,7 +315,8 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, getActionDefinitionsBuilder(G_PHI) .legalIf([=](const LegalityQuery &Query) -> bool { return typeInSet(0, {s8, s16, s32, p0})(Query) || - (Is64Bit && typeInSet(0, {s64})(Query)) || + (UseX87 && typeIs(0, s80)(Query)) || + (Is64Bit && typeIs(0, s64)(Query)) || (HasSSE1 && typeInSet(0, {v16s8, v8s16, v4s32, v2s64})(Query)) || (HasAVX && typeInSet(0, {v32s8, v16s16, v8s32, v4s64})(Query)) || (HasAVX512 && @@ -497,6 +498,62 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI, .clampScalar(0, s32, sMaxScalar) .widenScalarToNextPow2(1); + // For G_UITOFP and G_FPTOUI without AVX512, we have to custom legalize types + // <= s32 manually. Otherwise, in custom handler there is no way to + // understand whether s32 is an original type and we need to promote it to + // s64 or s32 is obtained after widening and we shouldn't widen it to s64. + // + // For AVX512 we simply widen types as there is direct mapping from opcodes + // to asm instructions. + getActionDefinitionsBuilder(G_UITOFP) + .legalIf([=](const LegalityQuery &Query) { + return HasAVX512 && typeInSet(0, {s32, s64})(Query) && + typeInSet(1, {s32, s64})(Query); + }) + .customIf([=](const LegalityQuery &Query) { + return !HasAVX512 && + ((HasSSE1 && typeIs(0, s32)(Query)) || + (HasSSE2 && typeIs(0, s64)(Query))) && + scalarNarrowerThan(1, Is64Bit ? 64 : 32)(Query); + }) + .lowerIf([=](const LegalityQuery &Query) { + // Lower conversions from s64 + return !HasAVX512 && + ((HasSSE1 && typeIs(0, s32)(Query)) || + (HasSSE2 && typeIs(0, s64)(Query))) && + (Is64Bit && typeIs(1, s64)(Query)); + }) + .clampScalar(0, s32, HasSSE2 ? s64 : s32) + .widenScalarToNextPow2(0) + .clampScalar(1, s32, sMaxScalar) + .widenScalarToNextPow2(1); + + getActionDefinitionsBuilder(G_FPTOUI) + .legalIf([=](const LegalityQuery &Query) { + return HasAVX512 && typeInSet(0, {s32, s64})(Query) && + typeInSet(1, {s32, s64})(Query); + }) + .customIf([=](const LegalityQuery &Query) { + return !HasAVX512 && + ((HasSSE1 && typeIs(1, s32)(Query)) || + (HasSSE2 && typeIs(1, s64)(Query))) && + scalarNarrowerThan(0, Is64Bit ? 64 : 32)(Query); + }) + // TODO: replace with customized legalization using + // specifics of cvttsd2si. The selection of this node requires + // a vector type. Either G_SCALAR_TO_VECTOR is needed or more advanced + // support of G_BUILD_VECTOR/G_INSERT_VECTOR_ELT is required beforehand. + .lowerIf([=](const LegalityQuery &Query) { + return !HasAVX512 && + ((HasSSE1 && typeIs(1, s32)(Query)) || + (HasSSE2 && typeIs(1, s64)(Query))) && + (Is64Bit && typeIs(0, s64)(Query)); + }) + .clampScalar(0, s32, sMaxScalar) + .widenScalarToNextPow2(0) + .clampScalar(1, s32, HasSSE2 ? s64 : s32) + .widenScalarToNextPow2(1); + // vector ops getActionDefinitionsBuilder(G_BUILD_VECTOR) .customIf([=](const LegalityQuery &Query) { @@ -589,6 +646,10 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, return false; case TargetOpcode::G_BUILD_VECTOR: return legalizeBuildVector(MI, MRI, Helper); + case TargetOpcode::G_FPTOUI: + return legalizeFPTOUI(MI, MRI, Helper); + case TargetOpcode::G_UITOFP: + return legalizeUITOFP(MI, MRI, Helper); } llvm_unreachable("expected switch to return"); } @@ -644,6 +705,45 @@ bool X86LegalizerInfo::legalizeBuildVector(MachineInstr &MI, return true; } +bool X86LegalizerInfo::legalizeFPTOUI(MachineInstr &MI, + MachineRegisterInfo &MRI, + LegalizerHelper &Helper) const { + MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; + auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs(); + unsigned DstSizeInBits = DstTy.getScalarSizeInBits(); + const LLT s32 = LLT::scalar(32); + const LLT s64 = LLT::scalar(64); + + // Simply reuse FPTOSI when it is possible to widen the type + if (DstSizeInBits <= 32) { + auto Casted = MIRBuilder.buildFPTOSI(DstTy == s32 ? s64 : s32, Src); + MIRBuilder.buildTrunc(Dst, Casted); + MI.eraseFromParent(); + return true; + } + + return false; +} + +bool X86LegalizerInfo::legalizeUITOFP(MachineInstr &MI, + MachineRegisterInfo &MRI, + LegalizerHelper &Helper) const { + MachineIRBuilder &MIRBuilder = Helper.MIRBuilder; + auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs(); + const LLT s32 = LLT::scalar(32); + const LLT s64 = LLT::scalar(64); + + // Simply reuse SITOFP when it is possible to widen the type + if (SrcTy.getSizeInBits() <= 32) { + auto Ext = MIRBuilder.buildZExt(SrcTy == s32 ? s64 : s32, Src); + MIRBuilder.buildSITOFP(Dst, Ext); + MI.eraseFromParent(); + return true; + } + + return false; +} + bool X86LegalizerInfo::legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const { return true; |
