1717#include " llvm/CodeGen/GlobalISel/LegalizerHelper.h"
1818#include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
1919#include " llvm/CodeGen/MachineConstantPool.h"
20+ #include " llvm/CodeGen/MachineFrameInfo.h"
2021#include " llvm/CodeGen/TargetOpcodes.h"
2122#include " llvm/CodeGen/ValueTypes.h"
2223#include " llvm/IR/DerivedTypes.h"
@@ -498,7 +499,16 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
498499 (typePairInSet (0 , 1 , {{s64, s32}})(Query) ||
499500 (Is64Bit && typePairInSet (0 , 1 , {{s64, s64}})(Query))));
500501 })
501- .clampScalar (1 , s32, sMaxScalar )
502+ .customIf ([=](const LegalityQuery &Query) -> bool {
503+ if (!UseX87)
504+ return false ;
505+ if ((typeIs (0 , s32)(Query) && HasSSE1) ||
506+ (typeIs (0 , s64)(Query) && HasSSE2))
507+ return false ;
508+ return typeInSet (0 , {s32, s64, s80})(Query) &&
509+ typeInSet (1 , {s16, s32, s64})(Query);
510+ })
511+ .clampScalar (1 , (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar )
502512 .widenScalarToNextPow2 (1 )
503513 .clampScalar (0 , s32, HasSSE2 ? s64 : s32)
504514 .widenScalarToNextPow2 (0 );
@@ -512,9 +522,18 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
512522 (typePairInSet (0 , 1 , {{s32, s64}})(Query) ||
513523 (Is64Bit && typePairInSet (0 , 1 , {{s64, s64}})(Query))));
514524 })
515- .clampScalar (1 , s32, HasSSE2 ? s64 : s32)
525+ .customIf ([=](const LegalityQuery &Query) -> bool {
526+ if (!UseX87)
527+ return false ;
528+ if ((typeIs (1 , s32)(Query) && HasSSE1) ||
529+ (typeIs (1 , s64)(Query) && HasSSE2))
530+ return false ;
531+ return typeInSet (0 , {s16, s32, s64})(Query) &&
532+ typeInSet (1 , {s32, s64, s80})(Query);
533+ })
534+ .clampScalar (0 , (UseX87 && !HasSSE1) ? s16 : s32, sMaxScalar )
516535 .widenScalarToNextPow2 (0 )
517- .clampScalar (0 , s32, sMaxScalar )
536+ .clampScalar (1 , s32, HasSSE2 ? s64 : s32 )
518537 .widenScalarToNextPow2 (1 );
519538
520539 // For G_UITOFP and G_FPTOUI without AVX512, we have to custom legalize types
@@ -671,10 +690,77 @@ bool X86LegalizerInfo::legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI,
671690 return legalizeUITOFP (MI, MRI, Helper);
672691 case TargetOpcode::G_STORE:
673692 return legalizeNarrowingStore (MI, MRI, Helper);
693+ case TargetOpcode::G_SITOFP:
694+ return legalizeSITOFP (MI, MRI, Helper);
695+ case TargetOpcode::G_FPTOSI:
696+ return legalizeFPTOSI (MI, MRI, Helper);
674697 }
675698 llvm_unreachable (" expected switch to return" );
676699}
677700
701+ bool X86LegalizerInfo::legalizeSITOFP (MachineInstr &MI,
702+ MachineRegisterInfo &MRI,
703+ LegalizerHelper &Helper) const {
704+ MachineIRBuilder &MIRBuilder = Helper.MIRBuilder ;
705+ MachineFunction &MF = *MI.getMF ();
706+ auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs ();
707+
708+ assert ((SrcTy.getSizeInBits () == 16 || SrcTy.getSizeInBits () == 32 ||
709+ SrcTy.getSizeInBits () == 64 ) &&
710+ " Unexpected source type for SITOFP in X87 mode." );
711+
712+ const LLT p0 = LLT::pointer (0 , MF.getTarget ().getPointerSizeInBits (0 ));
713+ int MemSize = SrcTy.getSizeInBytes ();
714+ int StackSlot =
715+ MF.getFrameInfo ().CreateStackObject (MemSize, Align (MemSize), false );
716+
717+ auto SlotPointer = MIRBuilder.buildFrameIndex (p0, StackSlot);
718+ MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack (MF, StackSlot);
719+ MachineMemOperand *StoreMMO = MF.getMachineMemOperand (
720+ PtrInfo, MachineMemOperand::MOStore, MemSize, Align (MemSize));
721+
722+ // Store the integer value on the FPU stack.
723+ MIRBuilder.buildStore (Src, SlotPointer, *StoreMMO);
724+
725+ MachineMemOperand *LoadMMO = MF.getMachineMemOperand (
726+ PtrInfo, MachineMemOperand::MOLoad, MemSize, Align (MemSize));
727+ MIRBuilder.buildInstr (X86::G_FILD)
728+ .addDef (Dst)
729+ .addUse (SlotPointer.getReg (0 ))
730+ .addMemOperand (LoadMMO);
731+
732+ MI.eraseFromParent ();
733+ return true ;
734+ }
735+
736+ bool X86LegalizerInfo::legalizeFPTOSI (MachineInstr &MI,
737+ MachineRegisterInfo &MRI,
738+ LegalizerHelper &Helper) const {
739+ MachineFunction &MF = *MI.getMF ();
740+ MachineIRBuilder &MIRBuilder = Helper.MIRBuilder ;
741+ const LLT p0 = LLT::pointer (0 , MF.getTarget ().getPointerSizeInBits (0 ));
742+ auto [Dst, DstTy, Src, SrcTy] = MI.getFirst2RegLLTs ();
743+
744+ unsigned MemSize = DstTy.getSizeInBytes ();
745+ int StackSlot =
746+ MF.getFrameInfo ().CreateStackObject (MemSize, Align (MemSize), false );
747+
748+ auto SlotPointer = MIRBuilder.buildFrameIndex (p0, StackSlot);
749+
750+ MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack (MF, StackSlot);
751+ MachineMemOperand *StoreMMO = MF.getMachineMemOperand (
752+ PtrInfo, MachineMemOperand::MOStore, MemSize, Align (MemSize));
753+
754+ MIRBuilder.buildInstr (X86::G_FIST)
755+ .addUse (Src)
756+ .addUse (SlotPointer.getReg (0 ))
757+ .addMemOperand (StoreMMO);
758+
759+ MIRBuilder.buildLoad (Dst, SlotPointer, PtrInfo, Align (MemSize));
760+ MI.eraseFromParent ();
761+ return true ;
762+ }
763+
678764bool X86LegalizerInfo::legalizeBuildVector (MachineInstr &MI,
679765 MachineRegisterInfo &MRI,
680766 LegalizerHelper &Helper) const {
0 commit comments