Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -4583,6 +4583,8 @@ def m80387 : Flag<["-"], "m80387">, Alias; def mno_80387 : Flag<["-"], "mno-80387">, Alias; def mno_fp_ret_in_387 : Flag<["-"], "mno-fp-ret-in-387">, Alias; +def mpc80 : Flag<["-"], "mpc80">, Group; +def mno_pc80 : Flag<["-"], "mno-pc80">, Group; def mmmx : Flag<["-"], "mmmx">, Group; def mno_mmx : Flag<["-"], "mno-mmx">, Group; def m3dnow : Flag<["-"], "m3dnow">, Group; Index: clang/lib/Basic/Targets/X86.h =================================================================== --- clang/lib/Basic/Targets/X86.h +++ clang/lib/Basic/Targets/X86.h @@ -155,6 +155,7 @@ bool HasUINTR = false; bool HasCRC32 = false; bool HasX87 = false; + bool HasPC80 = false; protected: llvm::X86::CPUKind CPU = llvm::X86::CK_None; Index: clang/lib/Basic/Targets/X86.cpp =================================================================== --- clang/lib/Basic/Targets/X86.cpp +++ clang/lib/Basic/Targets/X86.cpp @@ -356,6 +356,8 @@ HasCRC32 = true; } else if (Feature == "+x87") { HasX87 = true; + } else if (Feature == "+pc80") { + HasPC80 = true; } X86SSEEnum Level = llvm::StringSwitch(Feature) @@ -1070,6 +1072,7 @@ .Case("movdiri", HasMOVDIRI) .Case("movdir64b", HasMOVDIR64B) .Case("mwaitx", HasMWAITX) + .Case("pc80", HasPC80) .Case("pclmul", HasPCLMUL) .Case("pconfig", HasPCONFIG) .Case("pku", HasPKU) Index: llvm/include/llvm/TargetParser/X86TargetParser.def =================================================================== --- llvm/include/llvm/TargetParser/X86TargetParser.def +++ llvm/include/llvm/TargetParser/X86TargetParser.def @@ -189,6 +189,7 @@ X86_FEATURE (MOVDIR64B, "movdir64b") X86_FEATURE (MOVDIRI, "movdiri") X86_FEATURE (MWAITX, "mwaitx") +X86_FEATURE (PC80, "pc80") X86_FEATURE (PCONFIG, "pconfig") X86_FEATURE (PKU, "pku") X86_FEATURE (PREFETCHI, "prefetchi") Index: llvm/lib/Target/X86/X86.td =================================================================== --- llvm/lib/Target/X86/X86.td +++ llvm/lib/Target/X86/X86.td @@ -33,6 +33,10 @@ def FeatureX87 : SubtargetFeature<"x87","HasX87", "true", "Enable X87 float instructions">; +def FeaturePC80 : SubtargetFeature<"pc80", "HasPC80", "true", + "Enable X87 float instructions with 80-bit FP", + [FeatureX87]>; + def FeatureNOPL : SubtargetFeature<"nopl", "HasNOPL", "true", "Enable NOPL instruction (generally pentium pro+)">; Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -21368,6 +21368,10 @@ if (VT == MVT::f128 || !Subtarget.hasX87()) return SDValue(); + if (SrcVT == MVT::i64 && UseSSEReg && Subtarget.isOSWindows() && + !Subtarget.hasPC80()) + return SDValue(); + SDValue ValueToStore = Src; if (SrcVT == MVT::i64 && Subtarget.hasSSE2() && !Subtarget.is64Bit()) // Bitcasting to f64 here allows us to do a single 64-bit store from @@ -21824,7 +21828,9 @@ if (SDValue Extract = vectorizeExtractedCast(Op, DAG, Subtarget)) return Extract; - if (Subtarget.hasAVX512() && isScalarFPTypeInSSEReg(DstVT) && + bool UseSSEReg = isScalarFPTypeInSSEReg(DstVT); + + if (Subtarget.hasAVX512() && UseSSEReg && (SrcVT == MVT::i32 || (SrcVT == MVT::i64 && Subtarget.is64Bit()))) { // Conversions from unsigned i32 to f32/f64 are legal, // using VCVTUSI2SS/SD. Same for i64 in 64-bit mode. @@ -21859,6 +21865,9 @@ (DstVT == MVT::f32 || DstVT == MVT::f64)) return SDValue(); + if (!Subtarget.hasX87()) + return SDValue(); + // Make a 64-bit buffer, and use it to build an FILD. SDValue StackSlot = DAG.CreateStackTemporary(MVT::i64, 8); int SSFI = cast(StackSlot)->getIndex(); @@ -21880,6 +21889,10 @@ } assert(SrcVT == MVT::i64 && "Unexpected type in UINT_TO_FP"); + + if (UseSSEReg && Subtarget.isOSWindows() && !Subtarget.hasPC80()) + return SDValue(); + SDValue ValueToStore = Src; if (isScalarFPTypeInSSEReg(Op.getValueType()) && !Subtarget.is64Bit()) { // Bitcasting to f64 here allows us to do a single 64-bit store from Index: llvm/lib/TargetParser/X86TargetParser.cpp =================================================================== --- llvm/lib/TargetParser/X86TargetParser.cpp +++ llvm/lib/TargetParser/X86TargetParser.cpp @@ -510,6 +510,7 @@ constexpr FeatureBitset ImpliedFeaturesMOVBE = {}; constexpr FeatureBitset ImpliedFeaturesMOVDIR64B = {}; constexpr FeatureBitset ImpliedFeaturesMOVDIRI = {}; +constexpr FeatureBitset ImpliedFeaturesPC80 = {}; constexpr FeatureBitset ImpliedFeaturesPCONFIG = {}; constexpr FeatureBitset ImpliedFeaturesPOPCNT = {}; constexpr FeatureBitset ImpliedFeaturesPKU = {};