mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-18 13:34:04 +00:00
Migrate existing backends that care about software floating point
to use the information in the module rather than TargetOptions. We've had and clang has used the use-soft-float attribute for some time now so have the backends set a subtarget feature based on a particular function now that subtargets are created based on functions and function attributes. For the one middle end soft float check go ahead and create an overloadable TargetLowering::useSoftFloat function that just checks the TargetSubtargetInfo in all cases. Also remove the command line option that hard codes whether or not soft-float is set by using the attribute for all of the target specific test cases - for the generic just go ahead and add the attribute in the one case that showed up. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237079 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d1074b0e7f
commit
0552d51c45
@ -126,11 +126,6 @@ EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
|
||||
cl::desc("Force codegen to assume rounding mode can change dynamically"),
|
||||
cl::init(false));
|
||||
|
||||
cl::opt<bool>
|
||||
GenerateSoftFloatCalls("soft-float",
|
||||
cl::desc("Generate software floating point library calls"),
|
||||
cl::init(false));
|
||||
|
||||
cl::opt<llvm::FloatABI::ABIType>
|
||||
FloatABIForCalls("float-abi",
|
||||
cl::desc("Choose float ABI type"),
|
||||
@ -241,7 +236,6 @@ static inline TargetOptions InitTargetOptionsFromCodeGenFlags() {
|
||||
Options.NoNaNsFPMath = EnableNoNaNsFPMath;
|
||||
Options.HonorSignDependentRoundingFPMathOption =
|
||||
EnableHonorSignDependentRoundingFPMath;
|
||||
Options.UseSoftFloat = GenerateSoftFloatCalls;
|
||||
if (FloatABIForCalls != FloatABI::Default)
|
||||
Options.FloatABIType = FloatABIForCalls;
|
||||
Options.NoZerosInBSS = DontPlaceZerosInBSS;
|
||||
|
@ -165,6 +165,7 @@ public:
|
||||
|
||||
bool isBigEndian() const { return !IsLittleEndian; }
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
virtual bool useSoftFloat() const { return false; }
|
||||
|
||||
/// Return the pointer type for the given address space, defaults to
|
||||
/// the pointer type from the data layout.
|
||||
|
@ -63,7 +63,7 @@ namespace llvm {
|
||||
: PrintMachineCode(false), NoFramePointerElim(false),
|
||||
LessPreciseFPMADOption(false), UnsafeFPMath(false),
|
||||
NoInfsFPMath(false), NoNaNsFPMath(false),
|
||||
HonorSignDependentRoundingFPMathOption(false), UseSoftFloat(false),
|
||||
HonorSignDependentRoundingFPMathOption(false),
|
||||
NoZerosInBSS(false),
|
||||
GuaranteedTailCallOpt(false),
|
||||
DisableTailCalls(false), StackAlignmentOverride(0),
|
||||
@ -127,12 +127,6 @@ namespace llvm {
|
||||
unsigned HonorSignDependentRoundingFPMathOption : 1;
|
||||
bool HonorSignDependentRoundingFPMath() const;
|
||||
|
||||
/// UseSoftFloat - This flag is enabled when the -soft-float flag is
|
||||
/// specified on the command line. When this flag is on, the code generator
|
||||
/// will generate libcalls to the software floating point library instead of
|
||||
/// target FP instructions.
|
||||
unsigned UseSoftFloat : 1;
|
||||
|
||||
/// NoZerosInBSS - By default some codegens place zero-initialized data to
|
||||
/// .bss section. This flag disables such behaviour (necessary, e.g. for
|
||||
/// crt*.o compiling).
|
||||
@ -240,7 +234,6 @@ inline bool operator==(const TargetOptions &LHS,
|
||||
ARE_EQUAL(NoInfsFPMath) &&
|
||||
ARE_EQUAL(NoNaNsFPMath) &&
|
||||
ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
|
||||
ARE_EQUAL(UseSoftFloat) &&
|
||||
ARE_EQUAL(NoZerosInBSS) &&
|
||||
ARE_EQUAL(GuaranteedTailCallOpt) &&
|
||||
ARE_EQUAL(DisableTailCalls) &&
|
||||
|
@ -3456,7 +3456,7 @@ void SelectionDAGLegalize::ExpandNode(SDNode *Node) {
|
||||
break;
|
||||
}
|
||||
case ISD::FP_TO_FP16: {
|
||||
if (!TM.Options.UseSoftFloat && TM.Options.UnsafeFPMath) {
|
||||
if (!TLI.useSoftFloat() && TM.Options.UnsafeFPMath) {
|
||||
SDValue Op = Node->getOperand(0);
|
||||
MVT SVT = Op.getSimpleValueType();
|
||||
if ((SVT == MVT::f64 || SVT == MVT::f80) &&
|
||||
|
@ -23,6 +23,9 @@ include "llvm/Target/Target.td"
|
||||
def ModeThumb : SubtargetFeature<"thumb-mode", "InThumbMode", "true",
|
||||
"Thumb mode">;
|
||||
|
||||
def ModeSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
|
||||
"Use software floating point features.">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ARM Subtarget features.
|
||||
//
|
||||
|
@ -170,7 +170,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
if (Subtarget->isTargetMachO()) {
|
||||
// Uses VFP for Thumb libfuncs if available.
|
||||
if (Subtarget->isThumb() && Subtarget->hasVFP2() &&
|
||||
Subtarget->hasARMOps() && !TM.Options.UseSoftFloat) {
|
||||
Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) {
|
||||
// Single-precision floating-point arithmetic.
|
||||
setLibcallName(RTLIB::ADD_F32, "__addsf3vfp");
|
||||
setLibcallName(RTLIB::SUB_F32, "__subsf3vfp");
|
||||
@ -401,7 +401,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
|
||||
else
|
||||
addRegisterClass(MVT::i32, &ARM::GPRRegClass);
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
|
||||
!Subtarget->isThumb1Only()) {
|
||||
addRegisterClass(MVT::f32, &ARM::SPRRegClass);
|
||||
addRegisterClass(MVT::f64, &ARM::DPRRegClass);
|
||||
@ -820,7 +820,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
}
|
||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
|
||||
!Subtarget->isThumb1Only()) {
|
||||
// Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
|
||||
// iff target supports vfp2.
|
||||
@ -861,7 +861,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FREM, MVT::f64, Expand);
|
||||
setOperationAction(ISD::FREM, MVT::f32, Expand);
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
|
||||
!Subtarget->isThumb1Only()) {
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
|
||||
@ -875,7 +875,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
}
|
||||
|
||||
// Various VFP goodness
|
||||
if (!TM.Options.UseSoftFloat && !Subtarget->isThumb1Only()) {
|
||||
if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
|
||||
// FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
|
||||
if (!Subtarget->hasFPARMv8() || Subtarget->isFPOnlySP()) {
|
||||
setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
|
||||
@ -932,7 +932,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
|
||||
setStackPointerRegisterToSaveRestore(ARM::SP);
|
||||
|
||||
if (TM.Options.UseSoftFloat || Subtarget->isThumb1Only() ||
|
||||
if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
|
||||
!Subtarget->hasVFP2())
|
||||
setSchedulingPreference(Sched::RegPressure);
|
||||
else
|
||||
@ -956,6 +956,10 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM,
|
||||
setMinFunctionAlignment(Subtarget->isThumb() ? 1 : 2);
|
||||
}
|
||||
|
||||
bool ARMTargetLowering::useSoftFloat() const {
|
||||
return Subtarget->useSoftFloat();
|
||||
}
|
||||
|
||||
// FIXME: It might make sense to define the representative register class as the
|
||||
// nearest super-register that has a non-null superset. For example, DPR_VFP2 is
|
||||
// a super-register of SPR, and DPR is a superset if DPR_VFP2. Consequently,
|
||||
|
@ -231,6 +231,7 @@ namespace llvm {
|
||||
const ARMSubtarget &STI);
|
||||
|
||||
unsigned getJumpTableEncoding() const override;
|
||||
bool useSoftFloat() const override;
|
||||
|
||||
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
|
||||
|
||||
|
@ -145,6 +145,7 @@ void ARMSubtarget::initializeEnvironment() {
|
||||
HasVMLxForwarding = false;
|
||||
SlowFPBrcc = false;
|
||||
InThumbMode = false;
|
||||
UseSoftFloat = false;
|
||||
HasThumb2 = false;
|
||||
NoARM = false;
|
||||
IsR9Reserved = ReserveR9;
|
||||
|
@ -100,6 +100,9 @@ protected:
|
||||
/// InThumbMode - True if compiling for Thumb, false for ARM.
|
||||
bool InThumbMode;
|
||||
|
||||
/// UseSoftFloat - True if we're using software floating point features.
|
||||
bool UseSoftFloat;
|
||||
|
||||
/// HasThumb2 - True if Thumb2 instructions are supported.
|
||||
bool HasThumb2;
|
||||
|
||||
@ -393,6 +396,7 @@ public:
|
||||
bool isAPCS_ABI() const;
|
||||
bool isAAPCS_ABI() const;
|
||||
|
||||
bool useSoftFloat() const { return UseSoftFloat; }
|
||||
bool isThumb() const { return InThumbMode; }
|
||||
bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
|
||||
bool isThumb2() const { return InThumbMode && HasThumb2; }
|
||||
|
@ -207,13 +207,15 @@ ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const {
|
||||
// function before we can generate a subtarget. We also need to use
|
||||
// it as a key for the subtarget since that can be the only difference
|
||||
// between two functions.
|
||||
Attribute SFAttr = F.getFnAttribute("use-soft-float");
|
||||
bool SoftFloat = !SFAttr.hasAttribute(Attribute::None)
|
||||
? SFAttr.getValueAsString() == "true"
|
||||
: Options.UseSoftFloat;
|
||||
bool SoftFloat =
|
||||
F.hasFnAttribute("use-soft-float") &&
|
||||
F.getFnAttribute("use-soft-float").getValueAsString() == "true";
|
||||
// If the soft float attribute is set on the function turn on the soft float
|
||||
// subtarget feature.
|
||||
if (SoftFloat)
|
||||
FS += FS.empty() ? "+soft-float" : ",+soft-float";
|
||||
|
||||
auto &I = SubtargetMap[CPU + FS + (SoftFloat ? "use-soft-float=true"
|
||||
: "use-soft-float=false")];
|
||||
auto &I = SubtargetMap[CPU + FS];
|
||||
if (!I) {
|
||||
// This needs to be done before we create a new subtarget since any
|
||||
// creation will depend on the TM and the code generation flags on the
|
||||
|
@ -3598,6 +3598,10 @@ unsigned MipsTargetLowering::getJumpTableEncoding() const {
|
||||
return TargetLowering::getJumpTableEncoding();
|
||||
}
|
||||
|
||||
bool MipsTargetLowering::useSoftFloat() const {
|
||||
return Subtarget.useSoftFloat();
|
||||
}
|
||||
|
||||
void MipsTargetLowering::copyByValRegs(
|
||||
SDValue Chain, SDLoc DL, std::vector<SDValue> &OutChains, SelectionDAG &DAG,
|
||||
const ISD::ArgFlagsTy &Flags, SmallVectorImpl<SDValue> &InVals,
|
||||
|
@ -530,6 +530,7 @@ namespace llvm {
|
||||
bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
|
||||
|
||||
unsigned getJumpTableEncoding() const override;
|
||||
bool useSoftFloat() const override;
|
||||
|
||||
/// Emit a sign-extension using sll/sra, seb, or seh appropriately.
|
||||
MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr *MI,
|
||||
|
@ -140,10 +140,9 @@ MipsTargetMachine::getSubtargetImpl(const Function &F) const {
|
||||
// FIXME: This is related to the code below to reset the target options,
|
||||
// we need to know whether or not the soft float flag is set on the
|
||||
// function, so we can enable it as a subtarget feature.
|
||||
Attribute SFAttr = F.getFnAttribute("use-soft-float");
|
||||
bool softFloat = !SFAttr.hasAttribute(Attribute::None)
|
||||
? SFAttr.getValueAsString() == "true"
|
||||
: Options.UseSoftFloat;
|
||||
bool softFloat =
|
||||
F.hasFnAttribute("use-soft-float") &&
|
||||
F.getFnAttribute("use-soft-float").getValueAsString() == "true";
|
||||
|
||||
if (hasMips16Attr)
|
||||
FS += FS.empty() ? "+mips16" : ",+mips16";
|
||||
|
@ -71,7 +71,6 @@ void TargetMachine::resetTargetOptions(const Function &F) const {
|
||||
RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
|
||||
RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
|
||||
RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
|
||||
RESET_OPTION(UseSoftFloat, "use-soft-float");
|
||||
RESET_OPTION(DisableTailCalls, "disable-tail-calls");
|
||||
|
||||
Options.MCOptions.SanitizeAddress = F.hasFnAttribute(Attribute::SanitizeAddress);
|
||||
|
@ -192,6 +192,9 @@ def FeatureUseSqrtEst : SubtargetFeature<"use-sqrt-est", "UseSqrtEst", "true",
|
||||
"Use RSQRT* to optimize square root calculations">;
|
||||
def FeatureUseRecipEst : SubtargetFeature<"use-recip-est", "UseReciprocalEst",
|
||||
"true", "Use RCP* to optimize division calculations">;
|
||||
def FeatureSoftFloat
|
||||
: SubtargetFeature<"soft-float", "UseSoftFloat", "true",
|
||||
"Use software floating point features.">;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// X86 processors supported.
|
||||
|
@ -2254,7 +2254,7 @@ bool X86FastISel::fastLowerIntrinsicCall(const IntrinsicInst *II) {
|
||||
default: return false;
|
||||
case Intrinsic::convert_from_fp16:
|
||||
case Intrinsic::convert_to_fp16: {
|
||||
if (TM.Options.UseSoftFloat || !Subtarget->hasF16C())
|
||||
if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
|
||||
return false;
|
||||
|
||||
const Value *Op = II->getArgOperand(0);
|
||||
|
@ -183,7 +183,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
|
||||
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
|
||||
} else if (!TM.Options.UseSoftFloat) {
|
||||
} else if (!Subtarget->useSoftFloat()) {
|
||||
// We have an algorithm for SSE2->double, and we turn this into a
|
||||
// 64-bit FILD followed by conditional FADD for other targets.
|
||||
setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
|
||||
@ -197,7 +197,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
|
||||
setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
|
||||
|
||||
if (!TM.Options.UseSoftFloat) {
|
||||
if (!Subtarget->useSoftFloat()) {
|
||||
// SSE has no i16 to fp conversion, only i32
|
||||
if (X86ScalarSSEf32) {
|
||||
setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote);
|
||||
@ -240,7 +240,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
if (Subtarget->is64Bit()) {
|
||||
setOperationAction(ISD::FP_TO_UINT , MVT::i64 , Expand);
|
||||
setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
|
||||
} else if (!TM.Options.UseSoftFloat) {
|
||||
} else if (!Subtarget->useSoftFloat()) {
|
||||
// Since AVX is a superset of SSE3, only check for SSE here.
|
||||
if (Subtarget->hasSSE1() && !Subtarget->hasSSE3())
|
||||
// Expand FP_TO_UINT into a select.
|
||||
@ -368,7 +368,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
// Special handling for half-precision floating point conversions.
|
||||
// If we don't have F16C support, then lower half float conversions
|
||||
// into library calls.
|
||||
if (TM.Options.UseSoftFloat || !Subtarget->hasF16C()) {
|
||||
if (Subtarget->useSoftFloat() || !Subtarget->hasF16C()) {
|
||||
setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
|
||||
setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
|
||||
}
|
||||
@ -517,7 +517,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::GC_TRANSITION_START, MVT::Other, Custom);
|
||||
setOperationAction(ISD::GC_TRANSITION_END, MVT::Other, Custom);
|
||||
|
||||
if (!TM.Options.UseSoftFloat && X86ScalarSSEf64) {
|
||||
if (!Subtarget->useSoftFloat() && X86ScalarSSEf64) {
|
||||
// f32 and f64 use SSE.
|
||||
// Set up the FP register classes.
|
||||
addRegisterClass(MVT::f32, &X86::FR32RegClass);
|
||||
@ -551,7 +551,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
// cases we handle.
|
||||
addLegalFPImmediate(APFloat(+0.0)); // xorpd
|
||||
addLegalFPImmediate(APFloat(+0.0f)); // xorps
|
||||
} else if (!TM.Options.UseSoftFloat && X86ScalarSSEf32) {
|
||||
} else if (!Subtarget->useSoftFloat() && X86ScalarSSEf32) {
|
||||
// Use SSE for f32, x87 for f64.
|
||||
// Set up the FP register classes.
|
||||
addRegisterClass(MVT::f32, &X86::FR32RegClass);
|
||||
@ -586,7 +586,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::FCOS , MVT::f64, Expand);
|
||||
setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
|
||||
}
|
||||
} else if (!TM.Options.UseSoftFloat) {
|
||||
} else if (!Subtarget->useSoftFloat()) {
|
||||
// f32 and f64 in x87.
|
||||
// Set up the FP register classes.
|
||||
addRegisterClass(MVT::f64, &X86::RFP64RegClass);
|
||||
@ -620,7 +620,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::FMA, MVT::f32, Expand);
|
||||
|
||||
// Long double always uses X87.
|
||||
if (!TM.Options.UseSoftFloat) {
|
||||
if (!Subtarget->useSoftFloat()) {
|
||||
addRegisterClass(MVT::f80, &X86::RFP80RegClass);
|
||||
setOperationAction(ISD::UNDEF, MVT::f80, Expand);
|
||||
setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
|
||||
@ -760,7 +760,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
|
||||
// FIXME: In order to prevent SSE instructions being expanded to MMX ones
|
||||
// with -msoft-float, disable use of MMX as well.
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasMMX()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasMMX()) {
|
||||
addRegisterClass(MVT::x86mmx, &X86::VR64RegClass);
|
||||
// No operations on x86mmx supported, everything uses intrinsics.
|
||||
}
|
||||
@ -778,7 +778,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
}
|
||||
setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v1i64, Expand);
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasSSE1()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasSSE1()) {
|
||||
addRegisterClass(MVT::v4f32, &X86::VR128RegClass);
|
||||
|
||||
setOperationAction(ISD::FADD, MVT::v4f32, Legal);
|
||||
@ -797,7 +797,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::UINT_TO_FP, MVT::v4i32, Custom);
|
||||
}
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasSSE2()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasSSE2()) {
|
||||
addRegisterClass(MVT::v2f64, &X86::VR128RegClass);
|
||||
|
||||
// FIXME: Unfortunately, -soft-float and -no-implicit-float mean XMM
|
||||
@ -942,7 +942,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::BITCAST, MVT::v8i8, Custom);
|
||||
}
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasSSE41()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasSSE41()) {
|
||||
for (MVT RoundedTy : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
|
||||
setOperationAction(ISD::FFLOOR, RoundedTy, Legal);
|
||||
setOperationAction(ISD::FCEIL, RoundedTy, Legal);
|
||||
@ -1024,7 +1024,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
setOperationAction(ISD::SRA, MVT::v4i32, Custom);
|
||||
}
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasFp256()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasFp256()) {
|
||||
addRegisterClass(MVT::v32i8, &X86::VR256RegClass);
|
||||
addRegisterClass(MVT::v16i16, &X86::VR256RegClass);
|
||||
addRegisterClass(MVT::v8i32, &X86::VR256RegClass);
|
||||
@ -1244,7 +1244,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
}
|
||||
}
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasAVX512()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasAVX512()) {
|
||||
addRegisterClass(MVT::v16i32, &X86::VR512RegClass);
|
||||
addRegisterClass(MVT::v16f32, &X86::VR512RegClass);
|
||||
addRegisterClass(MVT::v8i64, &X86::VR512RegClass);
|
||||
@ -1447,7 +1447,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
}
|
||||
}// has AVX-512
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasBWI()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasBWI()) {
|
||||
addRegisterClass(MVT::v32i16, &X86::VR512RegClass);
|
||||
addRegisterClass(MVT::v64i8, &X86::VR512RegClass);
|
||||
|
||||
@ -1484,7 +1484,7 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
}
|
||||
}
|
||||
|
||||
if (!TM.Options.UseSoftFloat && Subtarget->hasVLX()) {
|
||||
if (!Subtarget->useSoftFloat() && Subtarget->hasVLX()) {
|
||||
addRegisterClass(MVT::v4i1, &X86::VK4RegClass);
|
||||
addRegisterClass(MVT::v2i1, &X86::VK2RegClass);
|
||||
|
||||
@ -1789,6 +1789,10 @@ unsigned X86TargetLowering::getJumpTableEncoding() const {
|
||||
return TargetLowering::getJumpTableEncoding();
|
||||
}
|
||||
|
||||
bool X86TargetLowering::useSoftFloat() const {
|
||||
return Subtarget->useSoftFloat();
|
||||
}
|
||||
|
||||
const MCExpr *
|
||||
X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
|
||||
const MachineBasicBlock *MBB,
|
||||
@ -2294,7 +2298,7 @@ static ArrayRef<MCPhysReg> get64BitArgumentXMMs(MachineFunction &MF,
|
||||
|
||||
const Function *Fn = MF.getFunction();
|
||||
bool NoImplicitFloatOps = Fn->hasFnAttribute(Attribute::NoImplicitFloat);
|
||||
bool isSoftFloat = MF.getTarget().Options.UseSoftFloat;
|
||||
bool isSoftFloat = Subtarget->useSoftFloat();
|
||||
assert(!(isSoftFloat && NoImplicitFloatOps) &&
|
||||
"SSE register cannot be used when SSE is disabled!");
|
||||
if (isSoftFloat || NoImplicitFloatOps || !Subtarget->hasSSE1())
|
||||
@ -2468,7 +2472,7 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
|
||||
bool IsWinEHParent = WinEHParent && WinEHParent == Fn;
|
||||
|
||||
// Figure out if XMM registers are in use.
|
||||
assert(!(MF.getTarget().Options.UseSoftFloat &&
|
||||
assert(!(Subtarget->useSoftFloat() &&
|
||||
Fn->hasFnAttribute(Attribute::NoImplicitFloat)) &&
|
||||
"SSE register cannot be used when SSE is disabled!");
|
||||
|
||||
@ -14600,7 +14604,7 @@ SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
|
||||
|
||||
if (ArgMode == 2) {
|
||||
// Sanity Check: Make sure using fp_offset makes sense.
|
||||
assert(!DAG.getTarget().Options.UseSoftFloat &&
|
||||
assert(!Subtarget->useSoftFloat() &&
|
||||
!(DAG.getMachineFunction().getFunction()->hasFnAttribute(
|
||||
Attribute::NoImplicitFloat)) &&
|
||||
Subtarget->hasSSE1());
|
||||
@ -23203,8 +23207,8 @@ static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
|
||||
|
||||
const Function *F = DAG.getMachineFunction().getFunction();
|
||||
bool NoImplicitFloatOps = F->hasFnAttribute(Attribute::NoImplicitFloat);
|
||||
bool F64IsLegal = !DAG.getTarget().Options.UseSoftFloat && !NoImplicitFloatOps
|
||||
&& Subtarget->hasSSE2();
|
||||
bool F64IsLegal =
|
||||
!Subtarget->useSoftFloat() && !NoImplicitFloatOps && Subtarget->hasSSE2();
|
||||
if ((VT.isVector() ||
|
||||
(VT == MVT::i64 && F64IsLegal && !Subtarget->is64Bit())) &&
|
||||
isa<LoadSDNode>(St->getValue()) &&
|
||||
|
@ -572,6 +572,7 @@ namespace llvm {
|
||||
const X86Subtarget &STI);
|
||||
|
||||
unsigned getJumpTableEncoding() const override;
|
||||
bool useSoftFloat() const override;
|
||||
|
||||
MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i8; }
|
||||
|
||||
|
@ -278,6 +278,7 @@ void X86Subtarget::initializeEnvironment() {
|
||||
stackAlignment = 4;
|
||||
// FIXME: this is a known good value for Yonah. How about others?
|
||||
MaxInlineSizeThreshold = 128;
|
||||
UseSoftFloat = false;
|
||||
}
|
||||
|
||||
X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,
|
||||
|
@ -218,6 +218,9 @@ protected:
|
||||
/// Processor has AVX-512 Vector Length eXtenstions
|
||||
bool HasVLX;
|
||||
|
||||
/// Use software floating point for code generation.
|
||||
bool UseSoftFloat;
|
||||
|
||||
/// The minimum alignment known to hold of the stack frame on
|
||||
/// entry to the function and which must be maintained by every function.
|
||||
unsigned stackAlignment;
|
||||
@ -385,6 +388,7 @@ public:
|
||||
|
||||
bool isAtom() const { return X86ProcFamily == IntelAtom; }
|
||||
bool isSLM() const { return X86ProcFamily == IntelSLM; }
|
||||
bool useSoftFloat() const { return UseSoftFloat; }
|
||||
|
||||
const Triple &getTargetTriple() const { return TargetTriple; }
|
||||
|
||||
|
@ -131,13 +131,15 @@ X86TargetMachine::getSubtargetImpl(const Function &F) const {
|
||||
// function before we can generate a subtarget. We also need to use
|
||||
// it as a key for the subtarget since that can be the only difference
|
||||
// between two functions.
|
||||
Attribute SFAttr = F.getFnAttribute("use-soft-float");
|
||||
bool SoftFloat = !SFAttr.hasAttribute(Attribute::None)
|
||||
? SFAttr.getValueAsString() == "true"
|
||||
: Options.UseSoftFloat;
|
||||
bool SoftFloat =
|
||||
F.hasFnAttribute("use-soft-float") &&
|
||||
F.getFnAttribute("use-soft-float").getValueAsString() == "true";
|
||||
// If the soft float attribute is set on the function turn on the soft float
|
||||
// subtarget feature.
|
||||
if (SoftFloat)
|
||||
FS += FS.empty() ? "+soft-float" : ",+soft-float";
|
||||
|
||||
auto &I = SubtargetMap[CPU + FS + (SoftFloat ? "use-soft-float=true"
|
||||
: "use-soft-float=false")];
|
||||
auto &I = SubtargetMap[CPU + FS];
|
||||
if (!I) {
|
||||
// This needs to be done before we create a new subtarget since any
|
||||
// creation will depend on the TM and the code generation flags on the
|
||||
|
@ -1,6 +1,6 @@
|
||||
; RUN: llc -mtriple=armv6-apple-ios -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-HARD
|
||||
; RUN: llc -mtriple=thumbv6-apple-ios -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-SOFTISH
|
||||
; RUN: llc -mtriple=armv7s-apple-ios -soft-float -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-SOFT
|
||||
; RUN: llc -mtriple=armv7s-apple-ios -mattr=+soft-float -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-SOFT
|
||||
|
||||
define float @test_call(float %a, float %b) {
|
||||
; CHECK-HARD: vadd.f32 {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
|
||||
@ -8,4 +8,4 @@ define float @test_call(float %a, float %b) {
|
||||
; CHECK-SOFT: bl ___addsf3{{$}}
|
||||
%sum = fadd float %a, %b
|
||||
ret float %sum
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,14 @@
|
||||
; RUN: llc < %s -soft-float
|
||||
; RUN: llc < %s
|
||||
; PR3899
|
||||
|
||||
@m = external global <2 x double>
|
||||
|
||||
define double @vector_ex() nounwind {
|
||||
define double @vector_ex() nounwind #0 {
|
||||
%v = load <2 x double>, <2 x double>* @m
|
||||
%x = extractelement <2 x double> %v, i32 1
|
||||
ret double %x
|
||||
}
|
||||
|
||||
; Soft-float attribute so that targets that pay attention to soft float will
|
||||
; make floating point types illegal and we'll exercise the legalizer code.
|
||||
attributes #0 = { "use-soft-float" = "true" }
|
||||
|
@ -1,7 +1,7 @@
|
||||
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=-f16c | FileCheck %s -check-prefix=CHECK -check-prefix=LIBCALL
|
||||
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+f16c | FileCheck %s -check-prefix=CHECK -check-prefix=F16C
|
||||
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -soft-float=1 -mattr=-f16c | FileCheck %s -check-prefix=CHECK -check-prefix=SOFTFLOAT
|
||||
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -soft-float=1 -mattr=+f16c | FileCheck %s -check-prefix=CHECK -check-prefix=SOFTFLOAT
|
||||
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=-f16c,+soft-float | FileCheck %s -check-prefix=CHECK -check-prefix=SOFTFLOAT
|
||||
; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+f16c,+soft-float | FileCheck %s -check-prefix=CHECK -check-prefix=SOFTFLOAT
|
||||
|
||||
; This is a test for float to half float conversions on x86-64.
|
||||
;
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx -soft-float=0 | FileCheck %s --check-prefix=CHECK-HARD-FLOAT
|
||||
; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx -soft-float=1 | FileCheck %s --check-prefix=CHECK-SOFT-FLOAT
|
||||
; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx | FileCheck %s --check-prefix=CHECK-HARD-FLOAT
|
||||
; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx,+soft-float | FileCheck %s --check-prefix=CHECK-SOFT-FLOAT
|
||||
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
; RUN: llc < %s -march=x86 -mattr=+sse2 -soft-float | FileCheck %s
|
||||
; RUN: llc < %s -march=x86-64 -mattr=+sse2 -soft-float | FileCheck %s
|
||||
; RUN: llc < %s -march=x86 -mattr=+sse2,+soft-float | FileCheck %s
|
||||
; RUN: llc < %s -march=x86-64 -mattr=+sse2,+soft-float | FileCheck %s
|
||||
|
||||
; CHECK-NOT: xmm{[0-9]+}
|
||||
|
||||
|
@ -281,9 +281,8 @@ static int compileModule(char **argv, LLVMContext &Context) {
|
||||
return 0;
|
||||
|
||||
assert(M && "Should have exited if we didn't have a module!");
|
||||
|
||||
if (GenerateSoftFloatCalls)
|
||||
FloatABIForCalls = FloatABI::Soft;
|
||||
if (FloatABIForCalls != FloatABI::Default)
|
||||
Options.FloatABIType = FloatABIForCalls;
|
||||
|
||||
// Figure out where we are going to send the output.
|
||||
std::unique_ptr<tool_output_file> Out =
|
||||
|
@ -465,11 +465,8 @@ int main(int argc, char **argv, char * const *envp) {
|
||||
builder.setOptLevel(OLvl);
|
||||
|
||||
TargetOptions Options;
|
||||
Options.UseSoftFloat = GenerateSoftFloatCalls;
|
||||
if (FloatABIForCalls != FloatABI::Default)
|
||||
Options.FloatABIType = FloatABIForCalls;
|
||||
if (GenerateSoftFloatCalls)
|
||||
FloatABIForCalls = FloatABI::Soft;
|
||||
|
||||
builder.setTargetOptions(Options);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user