aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp')
-rw-r--r--llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp102
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;