llvm.org GIT mirror llvm / 0552d51
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 Eric Christopher 4 years ago
28 changed file(s) with 99 addition(s) and 78 deletion(s). Raw diff Collapse all Expand all
125125 cl::desc("Force codegen to assume rounding mode can change dynamically"),
126126 cl::init(false));
127127
128 cl::opt
129 GenerateSoftFloatCalls("soft-float",
130 cl::desc("Generate software floating point library calls"),
131 cl::init(false));
132
133128 cl::opt
134129 FloatABIForCalls("float-abi",
135130 cl::desc("Choose float ABI type"),
240235 Options.NoNaNsFPMath = EnableNoNaNsFPMath;
241236 Options.HonorSignDependentRoundingFPMathOption =
242237 EnableHonorSignDependentRoundingFPMath;
243 Options.UseSoftFloat = GenerateSoftFloatCalls;
244238 if (FloatABIForCalls != FloatABI::Default)
245239 Options.FloatABIType = FloatABIForCalls;
246240 Options.NoZerosInBSS = DontPlaceZerosInBSS;
164164
165165 bool isBigEndian() const { return !IsLittleEndian; }
166166 bool isLittleEndian() const { return IsLittleEndian; }
167 virtual bool useSoftFloat() const { return false; }
167168
168169 /// Return the pointer type for the given address space, defaults to
169170 /// the pointer type from the data layout.
6262 : PrintMachineCode(false), NoFramePointerElim(false),
6363 LessPreciseFPMADOption(false), UnsafeFPMath(false),
6464 NoInfsFPMath(false), NoNaNsFPMath(false),
65 HonorSignDependentRoundingFPMathOption(false), UseSoftFloat(false),
65 HonorSignDependentRoundingFPMathOption(false),
6666 NoZerosInBSS(false),
6767 GuaranteedTailCallOpt(false),
6868 DisableTailCalls(false), StackAlignmentOverride(0),
125125 /// assume that the rounding mode may dynamically change.
126126 unsigned HonorSignDependentRoundingFPMathOption : 1;
127127 bool HonorSignDependentRoundingFPMath() const;
128
129 /// UseSoftFloat - This flag is enabled when the -soft-float flag is
130 /// specified on the command line. When this flag is on, the code generator
131 /// will generate libcalls to the software floating point library instead of
132 /// target FP instructions.
133 unsigned UseSoftFloat : 1;
134128
135129 /// NoZerosInBSS - By default some codegens place zero-initialized data to
136130 /// .bss section. This flag disables such behaviour (necessary, e.g. for
239233 ARE_EQUAL(NoInfsFPMath) &&
240234 ARE_EQUAL(NoNaNsFPMath) &&
241235 ARE_EQUAL(HonorSignDependentRoundingFPMathOption) &&
242 ARE_EQUAL(UseSoftFloat) &&
243236 ARE_EQUAL(NoZerosInBSS) &&
244237 ARE_EQUAL(GuaranteedTailCallOpt) &&
245238 ARE_EQUAL(DisableTailCalls) &&
34553455 break;
34563456 }
34573457 case ISD::FP_TO_FP16: {
3458 if (!TM.Options.UseSoftFloat && TM.Options.UnsafeFPMath) {
3458 if (!TLI.useSoftFloat() && TM.Options.UnsafeFPMath) {
34593459 SDValue Op = Node->getOperand(0);
34603460 MVT SVT = Op.getSimpleValueType();
34613461 if ((SVT == MVT::f64 || SVT == MVT::f80) &&
2121
2222 def ModeThumb : SubtargetFeature<"thumb-mode", "InThumbMode", "true",
2323 "Thumb mode">;
24
25 def ModeSoftFloat : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
26 "Use software floating point features.">;
2427
2528 //===----------------------------------------------------------------------===//
2629 // ARM Subtarget features.
169169 if (Subtarget->isTargetMachO()) {
170170 // Uses VFP for Thumb libfuncs if available.
171171 if (Subtarget->isThumb() && Subtarget->hasVFP2() &&
172 Subtarget->hasARMOps() && !TM.Options.UseSoftFloat) {
172 Subtarget->hasARMOps() && !Subtarget->useSoftFloat()) {
173173 // Single-precision floating-point arithmetic.
174174 setLibcallName(RTLIB::ADD_F32, "__addsf3vfp");
175175 setLibcallName(RTLIB::SUB_F32, "__subsf3vfp");
400400 addRegisterClass(MVT::i32, &ARM::tGPRRegClass);
401401 else
402402 addRegisterClass(MVT::i32, &ARM::GPRRegClass);
403 if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
403 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
404404 !Subtarget->isThumb1Only()) {
405405 addRegisterClass(MVT::f32, &ARM::SPRRegClass);
406406 addRegisterClass(MVT::f64, &ARM::DPRRegClass);
819819 }
820820 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
821821
822 if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
822 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
823823 !Subtarget->isThumb1Only()) {
824824 // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR
825825 // iff target supports vfp2.
860860 setOperationAction(ISD::FSINCOS, MVT::f32, Expand);
861861 setOperationAction(ISD::FREM, MVT::f64, Expand);
862862 setOperationAction(ISD::FREM, MVT::f32, Expand);
863 if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() &&
863 if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2() &&
864864 !Subtarget->isThumb1Only()) {
865865 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Custom);
866866 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Custom);
874874 }
875875
876876 // Various VFP goodness
877 if (!TM.Options.UseSoftFloat && !Subtarget->isThumb1Only()) {
877 if (!Subtarget->useSoftFloat() && !Subtarget->isThumb1Only()) {
878878 // FP-ARMv8 adds f64 <-> f16 conversion. Before that it should be expanded.
879879 if (!Subtarget->hasFPARMv8() || Subtarget->isFPOnlySP()) {
880880 setOperationAction(ISD::FP16_TO_FP, MVT::f64, Expand);
931931
932932 setStackPointerRegisterToSaveRestore(ARM::SP);
933933
934 if (TM.Options.UseSoftFloat || Subtarget->isThumb1Only() ||
934 if (Subtarget->useSoftFloat() || Subtarget->isThumb1Only() ||
935935 !Subtarget->hasVFP2())
936936 setSchedulingPreference(Sched::RegPressure);
937937 else
953953 PredictableSelectIsExpensive = Subtarget->isLikeA9();
954954
955955 setMinFunctionAlignment(Subtarget->isThumb() ? 1 : 2);
956 }
957
958 bool ARMTargetLowering::useSoftFloat() const {
959 return Subtarget->useSoftFloat();
956960 }
957961
958962 // FIXME: It might make sense to define the representative register class as the
230230 const ARMSubtarget &STI);
231231
232232 unsigned getJumpTableEncoding() const override;
233 bool useSoftFloat() const override;
233234
234235 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
235236
144144 HasVMLxForwarding = false;
145145 SlowFPBrcc = false;
146146 InThumbMode = false;
147 UseSoftFloat = false;
147148 HasThumb2 = false;
148149 NoARM = false;
149150 IsR9Reserved = ReserveR9;
9898
9999 /// InThumbMode - True if compiling for Thumb, false for ARM.
100100 bool InThumbMode;
101
102 /// UseSoftFloat - True if we're using software floating point features.
103 bool UseSoftFloat;
101104
102105 /// HasThumb2 - True if Thumb2 instructions are supported.
103106 bool HasThumb2;
392395 bool isAPCS_ABI() const;
393396 bool isAAPCS_ABI() const;
394397
398 bool useSoftFloat() const { return UseSoftFloat; }
395399 bool isThumb() const { return InThumbMode; }
396400 bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
397401 bool isThumb2() const { return InThumbMode && HasThumb2; }
206206 // function before we can generate a subtarget. We also need to use
207207 // it as a key for the subtarget since that can be the only difference
208208 // between two functions.
209 Attribute SFAttr = F.getFnAttribute("use-soft-float");
210 bool SoftFloat = !SFAttr.hasAttribute(Attribute::None)
211 ? SFAttr.getValueAsString() == "true"
212 : Options.UseSoftFloat;
213
214 auto &I = SubtargetMap[CPU + FS + (SoftFloat ? "use-soft-float=true"
215 : "use-soft-float=false")];
209 bool SoftFloat =
210 F.hasFnAttribute("use-soft-float") &&
211 F.getFnAttribute("use-soft-float").getValueAsString() == "true";
212 // If the soft float attribute is set on the function turn on the soft float
213 // subtarget feature.
214 if (SoftFloat)
215 FS += FS.empty() ? "+soft-float" : ",+soft-float";
216
217 auto &I = SubtargetMap[CPU + FS];
216218 if (!I) {
217219 // This needs to be done before we create a new subtarget since any
218220 // creation will depend on the TM and the code generation flags on the
35973597 return TargetLowering::getJumpTableEncoding();
35983598 }
35993599
3600 bool MipsTargetLowering::useSoftFloat() const {
3601 return Subtarget.useSoftFloat();
3602 }
3603
36003604 void MipsTargetLowering::copyByValRegs(
36013605 SDValue Chain, SDLoc DL, std::vector &OutChains, SelectionDAG &DAG,
36023606 const ISD::ArgFlagsTy &Flags, SmallVectorImpl &InVals,
529529 bool isFPImmLegal(const APFloat &Imm, EVT VT) const override;
530530
531531 unsigned getJumpTableEncoding() const override;
532 bool useSoftFloat() const override;
532533
533534 /// Emit a sign-extension using sll/sra, seb, or seh appropriately.
534535 MachineBasicBlock *emitSignExtendToI32InReg(MachineInstr *MI,
139139 // FIXME: This is related to the code below to reset the target options,
140140 // we need to know whether or not the soft float flag is set on the
141141 // function, so we can enable it as a subtarget feature.
142 Attribute SFAttr = F.getFnAttribute("use-soft-float");
143 bool softFloat = !SFAttr.hasAttribute(Attribute::None)
144 ? SFAttr.getValueAsString() == "true"
145 : Options.UseSoftFloat;
142 bool softFloat =
143 F.hasFnAttribute("use-soft-float") &&
144 F.getFnAttribute("use-soft-float").getValueAsString() == "true";
146145
147146 if (hasMips16Attr)
148147 FS += FS.empty() ? "+mips16" : ",+mips16";
7070 RESET_OPTION(UnsafeFPMath, "unsafe-fp-math");
7171 RESET_OPTION(NoInfsFPMath, "no-infs-fp-math");
7272 RESET_OPTION(NoNaNsFPMath, "no-nans-fp-math");
73 RESET_OPTION(UseSoftFloat, "use-soft-float");
7473 RESET_OPTION(DisableTailCalls, "disable-tail-calls");
7574
7675 Options.MCOptions.SanitizeAddress = F.hasFnAttribute(Attribute::SanitizeAddress);
191191 "Use RSQRT* to optimize square root calculations">;
192192 def FeatureUseRecipEst : SubtargetFeature<"use-recip-est", "UseReciprocalEst",
193193 "true", "Use RCP* to optimize division calculations">;
194 def FeatureSoftFloat
195 : SubtargetFeature<"soft-float", "UseSoftFloat", "true",
196 "Use software floating point features.">;
194197
195198 //===----------------------------------------------------------------------===//
196199 // X86 processors supported.
22532253 default: return false;
22542254 case Intrinsic::convert_from_fp16:
22552255 case Intrinsic::convert_to_fp16: {
2256 if (TM.Options.UseSoftFloat || !Subtarget->hasF16C())
2256 if (Subtarget->useSoftFloat() || !Subtarget->hasF16C())
22572257 return false;
22582258
22592259 const Value *Op = II->getArgOperand(0);
182182 if (Subtarget->is64Bit()) {
183183 setOperationAction(ISD::UINT_TO_FP , MVT::i32 , Promote);
184184 setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
185 } else if (!TM.Options.UseSoftFloat) {
185 } else if (!Subtarget->useSoftFloat()) {
186186 // We have an algorithm for SSE2->double, and we turn this into a
187187 // 64-bit FILD followed by conditional FADD for other targets.
188188 setOperationAction(ISD::UINT_TO_FP , MVT::i64 , Custom);
196196 setOperationAction(ISD::SINT_TO_FP , MVT::i1 , Promote);
197197 setOperationAction(ISD::SINT_TO_FP , MVT::i8 , Promote);
198198
199 if (!TM.Options.UseSoftFloat) {
199 if (!Subtarget->useSoftFloat()) {
200200 // SSE has no i16 to fp conversion, only i32
201201 if (X86ScalarSSEf32) {
202202 setOperationAction(ISD::SINT_TO_FP , MVT::i16 , Promote);
239239 if (Subtarget->is64Bit()) {
240240 setOperationAction(ISD::FP_TO_UINT , MVT::i64 , Expand);
241241 setOperationAction(ISD::FP_TO_UINT , MVT::i32 , Promote);
242 } else if (!TM.Options.UseSoftFloat) {
242 } else if (!Subtarget->useSoftFloat()) {
243243 // Since AVX is a superset of SSE3, only check for SSE here.
244244 if (Subtarget->hasSSE1() && !Subtarget->hasSSE3())
245245 // Expand FP_TO_UINT into a select.
367367 // Special handling for half-precision floating point conversions.
368368 // If we don't have F16C support, then lower half float conversions
369369 // into library calls.
370 if (TM.Options.UseSoftFloat || !Subtarget->hasF16C()) {
370 if (Subtarget->useSoftFloat() || !Subtarget->hasF16C()) {
371371 setOperationAction(ISD::FP16_TO_FP, MVT::f32, Expand);
372372 setOperationAction(ISD::FP_TO_FP16, MVT::f32, Expand);
373373 }
516516 setOperationAction(ISD::GC_TRANSITION_START, MVT::Other, Custom);
517517 setOperationAction(ISD::GC_TRANSITION_END, MVT::Other, Custom);
518518
519 if (!TM.Options.UseSoftFloat && X86ScalarSSEf64) {
519 if (!Subtarget->useSoftFloat() && X86ScalarSSEf64) {
520520 // f32 and f64 use SSE.
521521 // Set up the FP register classes.
522522 addRegisterClass(MVT::f32, &X86::FR32RegClass);
550550 // cases we handle.
551551 addLegalFPImmediate(APFloat(+0.0)); // xorpd
552552 addLegalFPImmediate(APFloat(+0.0f)); // xorps
553 } else if (!TM.Options.UseSoftFloat && X86ScalarSSEf32) {
553 } else if (!Subtarget->useSoftFloat() && X86ScalarSSEf32) {
554554 // Use SSE for f32, x87 for f64.
555555 // Set up the FP register classes.
556556 addRegisterClass(MVT::f32, &X86::FR32RegClass);
585585 setOperationAction(ISD::FCOS , MVT::f64, Expand);
586586 setOperationAction(ISD::FSINCOS, MVT::f64, Expand);
587587 }
588 } else if (!TM.Options.UseSoftFloat) {
588 } else if (!Subtarget->useSoftFloat()) {
589589 // f32 and f64 in x87.
590590 // Set up the FP register classes.
591591 addRegisterClass(MVT::f64, &X86::RFP64RegClass);
619619 setOperationAction(ISD::FMA, MVT::f32, Expand);
620620
621621 // Long double always uses X87.
622 if (!TM.Options.UseSoftFloat) {
622 if (!Subtarget->useSoftFloat()) {
623623 addRegisterClass(MVT::f80, &X86::RFP80RegClass);
624624 setOperationAction(ISD::UNDEF, MVT::f80, Expand);
625625 setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
759759
760760 // FIXME: In order to prevent SSE instructions being expanded to MMX ones
761761 // with -msoft-float, disable use of MMX as well.
762 if (!TM.Options.UseSoftFloat && Subtarget->hasMMX()) {
762 if (!Subtarget->useSoftFloat() && Subtarget->hasMMX()) {
763763 addRegisterClass(MVT::x86mmx, &X86::VR64RegClass);
764764 // No operations on x86mmx supported, everything uses intrinsics.
765765 }
777777 }
778778 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v1i64, Expand);
779779
780 if (!TM.Options.UseSoftFloat && Subtarget->hasSSE1()) {
780 if (!Subtarget->useSoftFloat() && Subtarget->hasSSE1()) {
781781 addRegisterClass(MVT::v4f32, &X86::VR128RegClass);
782782
783783 setOperationAction(ISD::FADD, MVT::v4f32, Legal);
796796 setOperationAction(ISD::UINT_TO_FP, MVT::v4i32, Custom);
797797 }
798798
799 if (!TM.Options.UseSoftFloat && Subtarget->hasSSE2()) {
799 if (!Subtarget->useSoftFloat() && Subtarget->hasSSE2()) {
800800 addRegisterClass(MVT::v2f64, &X86::VR128RegClass);
801801
802802 // FIXME: Unfortunately, -soft-float and -no-implicit-float mean XMM
941941 setOperationAction(ISD::BITCAST, MVT::v8i8, Custom);
942942 }
943943
944 if (!TM.Options.UseSoftFloat && Subtarget->hasSSE41()) {
944 if (!Subtarget->useSoftFloat() && Subtarget->hasSSE41()) {
945945 for (MVT RoundedTy : {MVT::f32, MVT::f64, MVT::v4f32, MVT::v2f64}) {
946946 setOperationAction(ISD::FFLOOR, RoundedTy, Legal);
947947 setOperationAction(ISD::FCEIL, RoundedTy, Legal);
10231023 setOperationAction(ISD::SRA, MVT::v4i32, Custom);
10241024 }
10251025
1026 if (!TM.Options.UseSoftFloat && Subtarget->hasFp256()) {
1026 if (!Subtarget->useSoftFloat() && Subtarget->hasFp256()) {
10271027 addRegisterClass(MVT::v32i8, &X86::VR256RegClass);
10281028 addRegisterClass(MVT::v16i16, &X86::VR256RegClass);
10291029 addRegisterClass(MVT::v8i32, &X86::VR256RegClass);
12431243 }
12441244 }
12451245
1246 if (!TM.Options.UseSoftFloat && Subtarget->hasAVX512()) {
1246 if (!Subtarget->useSoftFloat() && Subtarget->hasAVX512()) {
12471247 addRegisterClass(MVT::v16i32, &X86::VR512RegClass);
12481248 addRegisterClass(MVT::v16f32, &X86::VR512RegClass);
12491249 addRegisterClass(MVT::v8i64, &X86::VR512RegClass);
14461446 }
14471447 }// has AVX-512
14481448
1449 if (!TM.Options.UseSoftFloat && Subtarget->hasBWI()) {
1449 if (!Subtarget->useSoftFloat() && Subtarget->hasBWI()) {
14501450 addRegisterClass(MVT::v32i16, &X86::VR512RegClass);
14511451 addRegisterClass(MVT::v64i8, &X86::VR512RegClass);
14521452
14831483 }
14841484 }
14851485
1486 if (!TM.Options.UseSoftFloat && Subtarget->hasVLX()) {
1486 if (!Subtarget->useSoftFloat() && Subtarget->hasVLX()) {
14871487 addRegisterClass(MVT::v4i1, &X86::VK4RegClass);
14881488 addRegisterClass(MVT::v2i1, &X86::VK2RegClass);
14891489
17881788 return TargetLowering::getJumpTableEncoding();
17891789 }
17901790
1791 bool X86TargetLowering::useSoftFloat() const {
1792 return Subtarget->useSoftFloat();
1793 }
1794
17911795 const MCExpr *
17921796 X86TargetLowering::LowerCustomJumpTableEntry(const MachineJumpTableInfo *MJTI,
17931797 const MachineBasicBlock *MBB,
22932297
22942298 const Function *Fn = MF.getFunction();
22952299 bool NoImplicitFloatOps = Fn->hasFnAttribute(Attribute::NoImplicitFloat);
2296 bool isSoftFloat = MF.getTarget().Options.UseSoftFloat;
2300 bool isSoftFloat = Subtarget->useSoftFloat();
22972301 assert(!(isSoftFloat && NoImplicitFloatOps) &&
22982302 "SSE register cannot be used when SSE is disabled!");
22992303 if (isSoftFloat || NoImplicitFloatOps || !Subtarget->hasSSE1())
24672471 bool IsWinEHParent = WinEHParent && WinEHParent == Fn;
24682472
24692473 // Figure out if XMM registers are in use.
2470 assert(!(MF.getTarget().Options.UseSoftFloat &&
2474 assert(!(Subtarget->useSoftFloat() &&
24712475 Fn->hasFnAttribute(Attribute::NoImplicitFloat)) &&
24722476 "SSE register cannot be used when SSE is disabled!");
24732477
1459914603
1460014604 if (ArgMode == 2) {
1460114605 // Sanity Check: Make sure using fp_offset makes sense.
14602 assert(!DAG.getTarget().Options.UseSoftFloat &&
14606 assert(!Subtarget->useSoftFloat() &&
1460314607 !(DAG.getMachineFunction().getFunction()->hasFnAttribute(
1460414608 Attribute::NoImplicitFloat)) &&
1460514609 Subtarget->hasSSE1());
2320223206
2320323207 const Function *F = DAG.getMachineFunction().getFunction();
2320423208 bool NoImplicitFloatOps = F->hasFnAttribute(Attribute::NoImplicitFloat);
23205 bool F64IsLegal = !DAG.getTarget().Options.UseSoftFloat && !NoImplicitFloatOps
23206 && Subtarget->hasSSE2();
23209 bool F64IsLegal =
23210 !Subtarget->useSoftFloat() && !NoImplicitFloatOps && Subtarget->hasSSE2();
2320723211 if ((VT.isVector() ||
2320823212 (VT == MVT::i64 && F64IsLegal && !Subtarget->is64Bit())) &&
2320923213 isa(St->getValue()) &&
571571 const X86Subtarget &STI);
572572
573573 unsigned getJumpTableEncoding() const override;
574 bool useSoftFloat() const override;
574575
575576 MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i8; }
576577
277277 stackAlignment = 4;
278278 // FIXME: this is a known good value for Yonah. How about others?
279279 MaxInlineSizeThreshold = 128;
280 UseSoftFloat = false;
280281 }
281282
282283 X86Subtarget &X86Subtarget::initializeSubtargetDependencies(StringRef CPU,
216216
217217 /// Processor has AVX-512 Vector Length eXtenstions
218218 bool HasVLX;
219
220 /// Use software floating point for code generation.
221 bool UseSoftFloat;
219222
220223 /// The minimum alignment known to hold of the stack frame on
221224 /// entry to the function and which must be maintained by every function.
384387
385388 bool isAtom() const { return X86ProcFamily == IntelAtom; }
386389 bool isSLM() const { return X86ProcFamily == IntelSLM; }
390 bool useSoftFloat() const { return UseSoftFloat; }
387391
388392 const Triple &getTargetTriple() const { return TargetTriple; }
389393
130130 // function before we can generate a subtarget. We also need to use
131131 // it as a key for the subtarget since that can be the only difference
132132 // between two functions.
133 Attribute SFAttr = F.getFnAttribute("use-soft-float");
134 bool SoftFloat = !SFAttr.hasAttribute(Attribute::None)
135 ? SFAttr.getValueAsString() == "true"
136 : Options.UseSoftFloat;
137
138 auto &I = SubtargetMap[CPU + FS + (SoftFloat ? "use-soft-float=true"
139 : "use-soft-float=false")];
133 bool SoftFloat =
134 F.hasFnAttribute("use-soft-float") &&
135 F.getFnAttribute("use-soft-float").getValueAsString() == "true";
136 // If the soft float attribute is set on the function turn on the soft float
137 // subtarget feature.
138 if (SoftFloat)
139 FS += FS.empty() ? "+soft-float" : ",+soft-float";
140
141 auto &I = SubtargetMap[CPU + FS];
140142 if (!I) {
141143 // This needs to be done before we create a new subtarget since any
142144 // creation will depend on the TM and the code generation flags on the
0 ; RUN: llc -mtriple=armv6-apple-ios -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-HARD
11 ; RUN: llc -mtriple=thumbv6-apple-ios -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-SOFTISH
2 ; RUN: llc -mtriple=armv7s-apple-ios -soft-float -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-SOFT
2 ; RUN: llc -mtriple=armv7s-apple-ios -mattr=+soft-float -mcpu=arm1136jf-s -o - %s | FileCheck %s --check-prefix=CHECK-SOFT
33
44 define float @test_call(float %a, float %b) {
55 ; CHECK-HARD: vadd.f32 {{s[0-9]+}}, {{s[0-9]+}}, {{s[0-9]+}}
77 ; CHECK-SOFT: bl ___addsf3{{$}}
88 %sum = fadd float %a, %b
99 ret float %sum
10 }
10 }
None ; RUN: llc < %s -soft-float
0 ; RUN: llc < %s
11 ; PR3899
22
33 @m = external global <2 x double>
44
5 define double @vector_ex() nounwind {
5 define double @vector_ex() nounwind #0 {
66 %v = load <2 x double>, <2 x double>* @m
77 %x = extractelement <2 x double> %v, i32 1
88 ret double %x
99 }
10
11 ; Soft-float attribute so that targets that pay attention to soft float will
12 ; make floating point types illegal and we'll exercise the legalizer code.
13 attributes #0 = { "use-soft-float" = "true" }
0 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=-f16c | FileCheck %s -check-prefix=CHECK -check-prefix=LIBCALL
11 ; RUN: llc < %s -march=x86-64 -mtriple=x86_64-unknown-linux-gnu -mcpu=corei7 -mattr=+f16c | FileCheck %s -check-prefix=CHECK -check-prefix=F16C
2 ; 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
3 ; 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
2 ; 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
3 ; 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
44
55 ; This is a test for float to half float conversions on x86-64.
66 ;
None ; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx -soft-float=0 | FileCheck %s --check-prefix=CHECK-HARD-FLOAT
1 ; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx -soft-float=1 | FileCheck %s --check-prefix=CHECK-SOFT-FLOAT
0 ; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx | FileCheck %s --check-prefix=CHECK-HARD-FLOAT
1 ; RUN: llc < %s -march=x86-64 -mattr=+sse4.1,-avx,+soft-float | FileCheck %s --check-prefix=CHECK-SOFT-FLOAT
22
33 target triple = "x86_64-unknown-linux-gnu"
44
None ; RUN: llc < %s -march=x86 -mattr=+sse2 -soft-float | FileCheck %s
1 ; RUN: llc < %s -march=x86-64 -mattr=+sse2 -soft-float | FileCheck %s
0 ; RUN: llc < %s -march=x86 -mattr=+sse2,+soft-float | FileCheck %s
1 ; RUN: llc < %s -march=x86-64 -mattr=+sse2,+soft-float | FileCheck %s
22
33 ; CHECK-NOT: xmm{[0-9]+}
44
280280 return 0;
281281
282282 assert(M && "Should have exited if we didn't have a module!");
283
284 if (GenerateSoftFloatCalls)
285 FloatABIForCalls = FloatABI::Soft;
283 if (FloatABIForCalls != FloatABI::Default)
284 Options.FloatABIType = FloatABIForCalls;
286285
287286 // Figure out where we are going to send the output.
288287 std::unique_ptr Out =
464464 builder.setOptLevel(OLvl);
465465
466466 TargetOptions Options;
467 Options.UseSoftFloat = GenerateSoftFloatCalls;
468467 if (FloatABIForCalls != FloatABI::Default)
469468 Options.FloatABIType = FloatABIForCalls;
470 if (GenerateSoftFloatCalls)
471 FloatABIForCalls = FloatABI::Soft;
472469
473470 builder.setTargetOptions(Options);
474471