diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index e55d242cde68a..f311c91895d53 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -394,17 +394,6 @@ static bool initTargetOptions(const CompilerInstance &CI, break; } - // Set float ABI type. - assert((CodeGenOpts.FloatABI == "soft" || CodeGenOpts.FloatABI == "softfp" || - CodeGenOpts.FloatABI == "hard" || CodeGenOpts.FloatABI.empty()) && - "Invalid Floating Point ABI!"); - Options.FloatABIType = - llvm::StringSwitch(CodeGenOpts.FloatABI) - .Case("soft", llvm::FloatABI::Soft) - .Case("softfp", llvm::FloatABI::Soft) - .Case("hard", llvm::FloatABI::Hard) - .Default(llvm::FloatABI::Default); - // Set FP fusion mode. switch (LangOpts.getDefaultFPContractMode()) { case LangOptions::FPM_Off: @@ -1281,9 +1270,9 @@ void EmitAssemblyHelper::RunCodegenPipelineLegacy( CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII)); const llvm::TargetOptions &Options = TM->Options; - CodeGenPasses.add(new RuntimeLibraryInfoWrapper( - TargetTriple, Options.ExceptionModel, Options.FloatABIType, - Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib)); + CodeGenPasses.add( + new RuntimeLibraryInfoWrapper(Options.ExceptionModel, Options.EABIVersion, + Options.MCOptions.ABIName, Options.VecLib)); if (TM->addPassesToEmitFile(CodeGenPasses, *OS, DwoOS ? &DwoOS->os() : nullptr, CGFT, diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index e21590cc9fa7f..7ecda651027e2 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -920,8 +920,8 @@ static void generateMachineCodeOrAssemblyImpl( llvm::driver::createTLII(triple, codeGenOpts.getVecLib()); codeGenPasses.add(new llvm::TargetLibraryInfoWrapperPass(*tlii)); codeGenPasses.add(new llvm::RuntimeLibraryInfoWrapper( - triple, tm.Options.ExceptionModel, tm.Options.FloatABIType, - tm.Options.EABIVersion, tm.Options.MCOptions.ABIName, tm.Options.VecLib)); + tm.Options.ExceptionModel, tm.Options.EABIVersion, + tm.Options.MCOptions.ABIName, tm.Options.VecLib)); std::unique_ptr dwoOS; if (!codeGenOpts.SplitDwarfOutput.empty()) { @@ -1040,8 +1040,8 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) { fam.registerPass([&] { return llvm::TargetLibraryAnalysis(*tlii); }); mam.registerPass([&] { return llvm::RuntimeLibraryAnalysis( - triple, targetMachine->Options.ExceptionModel, - targetMachine->Options.FloatABIType, targetMachine->Options.EABIVersion, + targetMachine->Options.ExceptionModel, + targetMachine->Options.EABIVersion, targetMachine->Options.MCOptions.ABIName, targetMachine->Options.VecLib); }); diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md index f87f791a49e6f..f79bc8c3c7b1b 100644 --- a/llvm/docs/ReleaseNotes.md +++ b/llvm/docs/ReleaseNotes.md @@ -54,6 +54,9 @@ Makes programs 10x faster by doing Special New Thing. ### Changes to LLVM infrastructure +* Removed `TargetOptions::FloatABIType`. The soft float ABI should be + controlled by setting the `"float-abi"` module flag. + ### Changes to building LLVM ### Changes to TableGen diff --git a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h index 3054177bc6cce..f4d81b2f1e057 100644 --- a/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h +++ b/llvm/include/llvm/Analysis/RuntimeLibcallInfo.h @@ -11,6 +11,8 @@ #include "llvm/IR/RuntimeLibcalls.h" #include "llvm/Pass.h" +#include +#include namespace llvm { @@ -20,24 +22,26 @@ class LLVM_ABI RuntimeLibraryAnalysis using Result = RTLIB::RuntimeLibcallsInfo; RuntimeLibraryAnalysis() = default; - RuntimeLibraryAnalysis(RTLIB::RuntimeLibcallsInfo &&BaselineInfoImpl) - : LibcallsInfo(std::move(BaselineInfoImpl)) {} - RuntimeLibraryAnalysis( - const Triple &TT, - ExceptionHandling ExceptionModel = ExceptionHandling::None, - FloatABI::ABIType FloatABI = FloatABI::Default, - EABI EABIVersion = EABI::Default, StringRef ABIName = "", - VectorLibrary VecLib = VectorLibrary::NoLibrary); + RuntimeLibraryAnalysis(ExceptionHandling ExceptionModel, + EABI EABIVersion = EABI::Default, + StringRef ABIName = "", + VectorLibrary VecLib = VectorLibrary::NoLibrary) + : ExceptionModel(ExceptionModel), EABIVersion(EABIVersion), + ABIName(ABIName.str()), VecLib(VecLib) {} RTLIB::RuntimeLibcallsInfo run(const Module &M, ModuleAnalysisManager &); - operator bool() const { return LibcallsInfo.has_value(); } - private: friend AnalysisInfoMixin; static AnalysisKey Key; - std::optional LibcallsInfo; + // FIXME: These are TargetOptions values that are not yet represented in the + // IR, copied here so run() can forward them to the RuntimeLibcallsInfo Module + // constructor. Delete each one as they are migrated to module flags. + ExceptionHandling ExceptionModel = ExceptionHandling::None; + EABI EABIVersion = EABI::Default; + std::string ABIName; + VectorLibrary VecLib = VectorLibrary::NoLibrary; }; class LLVM_ABI RuntimeLibraryInfoWrapper : public ImmutablePass { @@ -47,12 +51,10 @@ class LLVM_ABI RuntimeLibraryInfoWrapper : public ImmutablePass { public: static char ID; RuntimeLibraryInfoWrapper(); - RuntimeLibraryInfoWrapper( - const Triple &TT, - ExceptionHandling ExceptionModel = ExceptionHandling::None, - FloatABI::ABIType FloatABI = FloatABI::Default, - EABI EABIVersion = EABI::Default, StringRef ABIName = "", - VectorLibrary VecLib = VectorLibrary::NoLibrary); + RuntimeLibraryInfoWrapper(ExceptionHandling ExceptionModel, + EABI EABIVersion = EABI::Default, + StringRef ABIName = "", + VectorLibrary VecLib = VectorLibrary::NoLibrary); const RTLIB::RuntimeLibcallsInfo &getRTLCI(const Module &M) { if (!RTLCI) { diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 53927e96a232e..6090644f7a12f 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -1066,7 +1066,7 @@ class LLVM_ABI Module { /// @{ /// Returns the floating-point ABI recorded by the "float-abi" module flag, or - /// FloatABI::Default when the flag is absent (meaning the target default). + /// the ABI implied by the target triple when the flag is absent. FloatABI::ABIType getFloatABI() const; /// @} diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index a1f03393d1b23..4def7c6db3d50 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -92,7 +92,16 @@ struct RuntimeLibcallsInfo { EABI EABIVersion = EABI::Default, StringRef ABIName = "", VectorLibrary VecLib = VectorLibrary::NoLibrary); - LLVM_ABI explicit RuntimeLibcallsInfo(const Module &M); + // FIXME: The floating-point ABI is read from the "float-abi" module flag, but + // the ExceptionModel/EABIVersion/ABIName/VecLib parameters are still + // TargetOptions values that are not yet represented in the IR. Delete these + // parameters (and build everything from the Module) once those fields are + // migrated to module flags. + LLVM_ABI explicit RuntimeLibcallsInfo( + const Module &M, + ExceptionHandling ExceptionModel = ExceptionHandling::None, + EABI EABIVersion = EABI::Default, StringRef ABIName = "", + VectorLibrary VecLib = VectorLibrary::NoLibrary); LLVM_ABI bool invalidate(Module &M, const PreservedAnalyses &PA, ModuleAnalysisManager::Invalidator &); diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index dc8b2ebceee46..f6c862e99b98f 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -358,14 +358,6 @@ class TargetOptions { /// If greater than 0, override TargetLoweringBase::PrefLoopAlignment. unsigned LoopAlignment = 0; - /// FloatABIType - This setting is set by -float-abi=xxx option is specfied - /// on the command line. This setting may either be Default, Soft, or Hard. - /// Default selects the target's default behavior. Soft selects the ABI for - /// software floating point, but does not indicate that FP hardware may not - /// be used. Such a combination is unfortunately popular (e.g. - /// arm-apple-darwin). Hard presumes that the normal FP ABI is used. - FloatABI::ABIType FloatABIType = FloatABI::Default; - /// AllowFPOpFusion - This flag is set by the -fp-contract=xxx option. /// This controls the creation of fused FP ops that store intermediate /// results in higher precision than IEEE allows (E.g. FMAs). diff --git a/llvm/lib/Analysis/RuntimeLibcallInfo.cpp b/llvm/lib/Analysis/RuntimeLibcallInfo.cpp index 1c5a1cc75b7bd..23dca93c4d884 100644 --- a/llvm/lib/Analysis/RuntimeLibcallInfo.cpp +++ b/llvm/lib/Analysis/RuntimeLibcallInfo.cpp @@ -13,34 +13,21 @@ using namespace llvm; AnalysisKey RuntimeLibraryAnalysis::Key; -RuntimeLibraryAnalysis::RuntimeLibraryAnalysis(const Triple &TT, - ExceptionHandling ExceptionModel, - FloatABI::ABIType FloatABI, - EABI EABIVersion, - StringRef ABIName, - VectorLibrary VecLib) - : LibcallsInfo(std::in_place, TT, ExceptionModel, FloatABI, EABIVersion, - ABIName, VecLib) {} - RTLIB::RuntimeLibcallsInfo RuntimeLibraryAnalysis::run(const Module &M, ModuleAnalysisManager &) { - if (!LibcallsInfo) - LibcallsInfo = RTLIB::RuntimeLibcallsInfo(M); - return *LibcallsInfo; + return RTLIB::RuntimeLibcallsInfo(M, ExceptionModel, EABIVersion, ABIName, + VecLib); } INITIALIZE_PASS(RuntimeLibraryInfoWrapper, "runtime-library-info", "Runtime Library Function Analysis", false, true) -RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper() - : ImmutablePass(ID), RTLA(RTLIB::RuntimeLibcallsInfo(Triple())) {} +RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper() : ImmutablePass(ID) {} RuntimeLibraryInfoWrapper::RuntimeLibraryInfoWrapper( - const Triple &TT, ExceptionHandling ExceptionModel, - FloatABI::ABIType FloatABI, EABI EABIVersion, StringRef ABIName, + ExceptionHandling ExceptionModel, EABI EABIVersion, StringRef ABIName, VectorLibrary VecLib) - : ImmutablePass(ID), RTLCI(std::in_place, TT, ExceptionModel, FloatABI, - EABIVersion, ABIName, VecLib) {} + : ImmutablePass(ID), RTLA(ExceptionModel, EABIVersion, ABIName, VecLib) {} char RuntimeLibraryInfoWrapper::ID = 0; diff --git a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp index b66e1027e64c2..d869c123c2046 100644 --- a/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp +++ b/llvm/lib/CodeGen/CodeGenTargetMachineImpl.cpp @@ -129,9 +129,9 @@ addPassesToGenerateCode(CodeGenTargetMachineImpl &TM, PassManagerBase &PM, const TargetOptions &Options = TM.Options; TargetLibraryInfoImpl TLII(TM.getTargetTriple(), Options.VecLib); PM.add(new TargetLibraryInfoWrapperPass(TLII)); - PM.add(new RuntimeLibraryInfoWrapper( - TM.getTargetTriple(), Options.ExceptionModel, Options.FloatABIType, - Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib)); + PM.add( + new RuntimeLibraryInfoWrapper(Options.ExceptionModel, Options.EABIVersion, + Options.MCOptions.ABIName, Options.VecLib)); invokeGlobalTargetPassConfigCallbacks(TM, PM, PassConfig); diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp index 306c0ff7c704b..db149dd938203 100644 --- a/llvm/lib/CodeGen/CommandFlags.cpp +++ b/llvm/lib/CodeGen/CommandFlags.cpp @@ -23,6 +23,7 @@ #include "llvm/MC/MCTargetOptionsCommandFlags.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" @@ -588,8 +589,6 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) { Options.HonorSignDependentRoundingFPMathOption = getEnableHonorSignDependentRoundingFPMath(); - if (getFloatABIForCalls() != FloatABI::Default) - Options.FloatABIType = getFloatABIForCalls(); Options.EnableAIXExtendedAltivecABI = getEnableAIXExtendedAltivecABI(); Options.NoZerosInBSS = getDontPlaceZerosInBSS(); Options.GuaranteedTailCallOpt = getEnableGuaranteedTailCallOpt(); @@ -774,6 +773,25 @@ void codegen::setFunctionAttributes(Function &F, StringRef CPU, void codegen::setFunctionAttributes(Module &M, StringRef CPU, StringRef Features, StringRef TuneCPU) { + // Synthesize the "float-abi" module flag from the -float-abi option. + FloatABI::ABIType ABI = getFloatABIForCalls(); + if (ABI != FloatABI::Default) { + if (auto *Existing = + dyn_cast_or_null(M.getModuleFlag("float-abi"))) { + // The module already records a float ABI; -float-abi must not contradict + // it. + if (Existing->getString() != FloatABI::getABITypeName(ABI)) + reportFatalUsageError( + "-float-abi=" + FloatABI::getABITypeName(ABI) + + " conflicts with the \"float-abi\" module flag \"" + + Existing->getString() + "\""); + } else { + M.addModuleFlag( + Module::Error, "float-abi", + MDString::get(M.getContext(), FloatABI::getABITypeName(ABI))); + } + } + for (Function &F : M) setFunctionAttributes(F, CPU, Features, TuneCPU); } diff --git a/llvm/lib/CodeGen/TargetLoweringBase.cpp b/llvm/lib/CodeGen/TargetLoweringBase.cpp index 534bdc4bbc84b..b3c396af129fa 100644 --- a/llvm/lib/CodeGen/TargetLoweringBase.cpp +++ b/llvm/lib/CodeGen/TargetLoweringBase.cpp @@ -719,7 +719,8 @@ TargetLoweringBase::TargetLoweringBase(const TargetMachine &tm, const TargetSubtargetInfo &STI) : TM(tm), RuntimeLibcallInfo(TM.getTargetTriple(), TM.Options.ExceptionModel, - TM.Options.FloatABIType, TM.Options.EABIVersion, + TM.getTargetTriple().getDefaultFloatABI(), + TM.Options.EABIVersion, TM.Options.MCOptions.getABIName(), TM.Options.VecLib), Libcalls(RuntimeLibcallInfo, STI) { initActions(); diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 2ae76b80ccd57..510d33c0ad295 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -700,8 +700,10 @@ void Module::setLongDoubleFormat(LongDoubleFormat Format) { FloatABI::ABIType Module::getFloatABI() const { if (auto *Val = dyn_cast_or_null(getModuleFlag("float-abi"))) - return FloatABI::parseABIType(Val->getString()).value_or(FloatABI::Default); - return FloatABI::Default; + return *FloatABI::parseABIType(Val->getString()); + // Without an explicit flag, fall back to the ABI implied by the target + // triple. + return getTargetTriple().getDefaultFloatABI(); } std::optional Module::getLargeDataThreshold() const { diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index e1148891af69a..1befff9d5f00e 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -105,12 +105,13 @@ RuntimeLibcallsInfo::RuntimeLibcallsInfo(const Triple &TT, } } -RuntimeLibcallsInfo::RuntimeLibcallsInfo(const Module &M) { - // TODO: Consider the remaining module flags. - const Triple &TT = M.getTargetTriple(); - initLibcalls(TT, TT.getDefaultExceptionHandling(), FloatABI::Default, - EABI::Default, /*ABIName=*/"", M.getLongDoubleFormat()); -} +// TODO: Consider the remaining module flags. +RuntimeLibcallsInfo::RuntimeLibcallsInfo(const Module &M, + ExceptionHandling ExceptionModel, + EABI EABIVersion, StringRef ABIName, + VectorLibrary VecLib) + : RuntimeLibcallsInfo(M.getTargetTriple(), ExceptionModel, M.getFloatABI(), + EABIVersion, ABIName, VecLib) {} /// Set default libcall names. If a target wants to opt-out of a libcall it /// should be placed here. diff --git a/llvm/lib/LTO/LTOBackend.cpp b/llvm/lib/LTO/LTOBackend.cpp index 73697a9d0d446..69bc3fdae6c57 100644 --- a/llvm/lib/LTO/LTOBackend.cpp +++ b/llvm/lib/LTO/LTOBackend.cpp @@ -485,8 +485,7 @@ static void codegen(const Config &Conf, TargetMachine *TM, TargetLibraryInfoImpl TLII(Mod.getTargetTriple(), TM->Options.VecLib); CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII)); CodeGenPasses.add(new RuntimeLibraryInfoWrapper( - Mod.getTargetTriple(), TM->Options.ExceptionModel, - TM->Options.FloatABIType, TM->Options.EABIVersion, + TM->Options.ExceptionModel, TM->Options.EABIVersion, TM->Options.MCOptions.ABIName, TM->Options.VecLib)); // No need to make index available if the module is empty. diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 59ad547dc26d7..11f7929cb6dbe 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -698,11 +698,7 @@ void ARMAsmPrinter::emitAttributes() { } const ARMBaseTargetMachine &ATM = static_cast(TM); - // The float ABI comes from the "float-abi" module flag if present, otherwise - // from the legacy -float-abi target option. - FloatABI::ABIType FloatABI = MMI->getModule()->getFloatABI(); - if (FloatABI == FloatABI::Default) - FloatABI = ATM.Options.FloatABIType; + FloatABI::ABIType FloatABI = ATM.getFloatABI(*MMI->getModule()); const ARMSubtarget STI(TT, std::string(CPU), ArchFS, ATM, ATM.isLittleEndian(), FloatABI); diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.cpp b/llvm/lib/Target/ARM/ARMTargetMachine.cpp index 3d388a7db6687..a1ced45a83e63 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.cpp +++ b/llvm/lib/Target/ARM/ARMTargetMachine.cpp @@ -156,16 +156,6 @@ ARMBaseTargetMachine::ARMBaseTargetMachine(const Target &T, const Triple &TT, TargetABI(ARM::computeTargetABI(TT, Options.MCOptions.ABIName)), TLOF(createTLOF(getTargetTriple())), isLittle(TT.isLittleEndian()) { - // Default to triple-appropriate float ABI. -target-abi=aapcs16 forces hard - // float regardless of the triple default. - if (Options.FloatABIType == FloatABI::Default) { - if (TargetABI == ARM::ARM_ABI_AAPCS16 || - TT.getDefaultFloatABI() == FloatABI::Hard) - this->Options.FloatABIType = FloatABI::Hard; - else - this->Options.FloatABIType = FloatABI::Soft; - } - // Default to triple-appropriate EABI if (Options.EABIVersion == EABI::Default || Options.EABIVersion == EABI::Unknown) { @@ -207,6 +197,20 @@ MachineFunctionInfo *ARMBaseTargetMachine::createMachineFunctionInfo( Allocator, F, static_cast(STI)); } +FloatABI::ABIType ARMBaseTargetMachine::getFloatABI(const Module &M) const { + // An explicit "float-abi" module flag always wins, even for AAPCS16. + if (auto *Val = dyn_cast_or_null(M.getModuleFlag("float-abi"))) + return *FloatABI::parseABIType(Val->getString()); + + // With no explicit ABI, an explicit -target-abi=aapcs16 forces hard float + // even on triples whose default float ABI is soft (the triple default only + // detects AAPCS16 when it is the triple's own default ABI). + if (TargetABI == ARM::ARM_ABI_AAPCS16) + return FloatABI::Hard; + // Otherwise fall back to the ABI implied by the target triple. + return M.getTargetTriple().getDefaultFloatABI(); +} + const ARMSubtarget * ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const { Attribute CPUAttr = F.getFnAttribute("target-cpu"); @@ -238,16 +242,7 @@ ARMBaseTargetMachine::getSubtargetImpl(const Function &F) const { if (DM != DenormalMode::getIEEE()) Key += "denormal-fp-math=" + DM.str(); - // The float ABI comes from the "float-abi" module flag if present, otherwise - // from the legacy -float-abi target option (which the constructor seeded from - // the target triple). - FloatABI::ABIType FloatABI = F.getParent()->getFloatABI(); - if (FloatABI == FloatABI::Default) { - FloatABI = Options.FloatABIType; - assert(FloatABI != FloatABI::Default && - "expected TargetMachine constructor to overwrite default float abi"); - } - + FloatABI::ABIType FloatABI = getFloatABI(*F.getParent()); // It is legal to have FloatABI::Hard with +soft-float for targets with SIMD // registers, but no floating-point hardware (mve+nofp) Key += FloatABI == FloatABI::Hard ? "+hard-float-abi" : "+soft-float-abi"; diff --git a/llvm/lib/Target/ARM/ARMTargetMachine.h b/llvm/lib/Target/ARM/ARMTargetMachine.h index 1d373e65978f9..81dc7a5965f6f 100644 --- a/llvm/lib/Target/ARM/ARMTargetMachine.h +++ b/llvm/lib/Target/ARM/ARMTargetMachine.h @@ -52,6 +52,11 @@ class ARMBaseTargetMachine : public CodeGenTargetMachineImpl { const ARMSubtarget *getSubtargetImpl() const = delete; bool isLittleEndian() const { return isLittle; } + /// Returns the floating-point ABI in effect for \p M: the "float-abi" module + /// flag if present, otherwise the ABI implied by the target triple. An + /// explicit -target-abi=aapcs16 forces the hard-float ABI. + FloatABI::ABIType getFloatABI(const Module &M) const; + TargetTransformInfo getTargetTransformInfo(const Function &F) const override; // Pass Pipeline Configuration diff --git a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp index 2e1309391c338..454cf1885dc37 100644 --- a/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp +++ b/llvm/lib/Target/CSKY/CSKYTargetMachine.cpp @@ -61,8 +61,6 @@ CSKYTargetMachine::getSubtargetImpl(const Function &F) const { FSAttr.isValid() ? FSAttr.getValueAsString().str() : TargetFS; FloatABI::ABIType FloatABI = F.getParent()->getFloatABI(); - if (FloatABI == FloatABI::Default) - FloatABI = Options.FloatABIType; std::string Key = CPU + TuneCPU + FS; Key += FloatABI == FloatABI::Hard ? "+hard-float-abi" : "+soft-float-abi"; diff --git a/llvm/test/CodeGen/ARM/float-abi-module-flag.ll b/llvm/test/CodeGen/ARM/float-abi-module-flag.ll index ea57078c619bd..79e4d73cf7b1a 100644 --- a/llvm/test/CodeGen/ARM/float-abi-module-flag.ll +++ b/llvm/test/CodeGen/ARM/float-abi-module-flag.ll @@ -14,9 +14,9 @@ ; The triple default applies with no module flag. ; RUN: llc -mtriple=armv7-none-eabi -mattr=+vfp3 < %t/none.ll | FileCheck %s --check-prefix=SOFT -; An explicit module flag takes precedence over a conflicting -float-abi option. -; RUN: llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=soft < %t/hard.ll | FileCheck %s --check-prefix=HARD -; RUN: llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=hard < %t/soft.ll | FileCheck %s --check-prefix=SOFT +; A -float-abi option conflicting with the module flag is an error. +; RUN: not llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=soft < %t/hard.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT-SOFT +; RUN: not llc -mtriple=armv7-none-eabi -mattr=+vfp3 -float-abi=hard < %t/soft.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT-HARD ;--- hard.ll define float @f(float %x) { @@ -26,6 +26,7 @@ define float @f(float %x) { !llvm.module.flags = !{!0} !0 = !{i32 1, !"float-abi", !"hard"} ; HARD: vadd.f32 s0, +; CONFLICT-SOFT: -float-abi=soft conflicts with the "float-abi" module flag "hard" ;--- soft.ll define float @f(float %x) { @@ -35,6 +36,7 @@ define float @f(float %x) { !llvm.module.flags = !{!0} !0 = !{i32 1, !"float-abi", !"soft"} ; SOFT: vmov {{s[0-9]+}}, r0 +; CONFLICT-HARD: -float-abi=hard conflicts with the "float-abi" module flag "soft" ;--- none.ll define float @f(float %x) { diff --git a/llvm/test/CodeGen/ARM/float-abi-synthesize-flag.ll b/llvm/test/CodeGen/ARM/float-abi-synthesize-flag.ll new file mode 100644 index 0000000000000..147a13b3211c5 --- /dev/null +++ b/llvm/test/CodeGen/ARM/float-abi-synthesize-flag.ll @@ -0,0 +1,36 @@ +; Check behavior of the -float-abi command-line option; it should +; synthesize the "float-abi" module flag, unless one is already +; present + +; RUN: split-file %s %t + +; -float-abi=hard writes the module flag. +; RUN: llc -mtriple=armv7-none-eabi -float-abi=hard -stop-after=finalize-isel %t/none.ll -o - | FileCheck %s --check-prefix=HARD + +; -float-abi=soft writes the module flag. +; RUN: llc -mtriple=armv7-none-eabi -float-abi=soft -stop-after=finalize-isel %t/none.ll -o - | FileCheck %s --check-prefix=SOFT + +; Without -float-abi, no flag is synthesized. +; RUN: llc -mtriple=armv7-none-eabi -stop-after=finalize-isel %t/none.ll -o - | FileCheck %s --check-prefix=NONE + +; -float-abi matching an existing in-IR flag is accepted. +; RUN: llc -mtriple=armv7-none-eabi -float-abi=hard -stop-after=finalize-isel %t/hard.ll -o - | FileCheck %s --check-prefix=HARD + +; -float-abi conflicting with an existing in-IR flag is an error. +; RUN: not llc -mtriple=armv7-none-eabi -float-abi=soft -stop-after=finalize-isel %t/hard.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT + +;--- none.ll +define void @f() { + ret void +} +; HARD: !{i32 1, !"float-abi", !"hard"} +; SOFT: !{i32 1, !"float-abi", !"soft"} +; NONE-NOT: !"float-abi" + +;--- hard.ll +define void @f() { + ret void +} +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"float-abi", !"hard"} +; CONFLICT: -float-abi=soft conflicts with the "float-abi" module flag "hard" diff --git a/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll b/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll index 78cffe05ade2f..84461789dcfa8 100644 --- a/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll +++ b/llvm/test/CodeGen/CSKY/float-abi-module-flag.ll @@ -16,8 +16,8 @@ ; no "float-abi" flag. ; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/none.ll | FileCheck %s --check-prefix=HARD -; An explicit module flag takes precedence over the legacy -float-abi option. -; RUN: llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/soft.ll | FileCheck %s --check-prefix=SOFT +; A -float-abi option conflicting with the module flag is an error. +; RUN: not llc -csky-no-aliases -mtriple=csky -mattr=+2e3,+fpuv2_sf,+fpuv2_df,+hard-float -float-abi=hard < %t/soft.ll -filetype=null 2>&1 | FileCheck %s --check-prefix=CONFLICT ;--- none.ll define float @f(float %x, float %y) { @@ -43,3 +43,4 @@ define float @f(float %x, float %y) { ; SOFT: fmtvrl ; HARD-NOT: fmtvrl +; CONFLICT: -float-abi=hard conflicts with the "float-abi" module flag "soft" diff --git a/llvm/test/CodeGen/Hexagon/autohvx/xqf-assertion1.ll b/llvm/test/CodeGen/Hexagon/autohvx/xqf-assertion1.ll index 90d0790989388..81db9ba2e6ec9 100644 --- a/llvm/test/CodeGen/Hexagon/autohvx/xqf-assertion1.ll +++ b/llvm/test/CodeGen/Hexagon/autohvx/xqf-assertion1.ll @@ -1,8 +1,8 @@ ; On v79 and above, checks for Assertion `isImm() && "Wrong MachineOperand accessor"' failed -; RUN: llc -march=hexagon -enable-xqf-gen=true -enable-rem-conv=true \ +; RUN: llc -mtriple=hexagon -enable-xqf-gen=true -enable-rem-conv=true \ ; RUN: -mattr=+hvx-ieee-fp,+hvx-length128b,+hvxv79 -o /dev/null < %s -; RUN: llc -march=hexagon -enable-xqf-gen=true -enable-rem-conv=true \ +; RUN: llc -mtriple=hexagon -enable-xqf-gen=true -enable-rem-conv=true \ ; RUN: -mattr=+hvx-ieee-fp,+hvx-length128b,+hvxv81 -o /dev/null < %s diff --git a/llvm/test/CodeGen/Hexagon/autohvx/xqf-handle-conv.ll b/llvm/test/CodeGen/Hexagon/autohvx/xqf-handle-conv.ll index 21fbad7498081..023df7cfa6a50 100644 --- a/llvm/test/CodeGen/Hexagon/autohvx/xqf-handle-conv.ll +++ b/llvm/test/CodeGen/Hexagon/autohvx/xqf-handle-conv.ll @@ -3,9 +3,9 @@ ; by a qf instruction. ; REQUIRES: asserts -; RUN: llc -O2 -march=hexagon -mcpu=hexagonv79 -mattr=+hvx-ieee-fp,+hvx-length128b,+hvxv79 \ +; RUN: llc -O2 -mtriple=hexagon -mcpu=hexagonv79 -mattr=+hvx-ieee-fp,+hvx-length128b,+hvxv79 \ ; RUN: -debug-only=handle-qfp < %s 2>&1 -o /dev/null | FileCheck %s --check-prefix=V79 -; RUN: llc -O2 -march=hexagon -mcpu=hexagonv81 -mattr=+hvx-ieee-fp,+hvx-length128b,+hvxv81 \ +; RUN: llc -O2 -mtriple=hexagon -mcpu=hexagonv81 -mattr=+hvx-ieee-fp,+hvx-length128b,+hvxv81 \ ; RUN: -debug-only=handle-qfp < %s 2>&1 -o /dev/null | FileCheck %s --check-prefix=V81 ; V79: Analyzing convert instruction: renamable [[VREG1:\$v[0-9]+]] = V6_vconv_hf_qf16 renamable [[VREG2:\$v[0-9]+]] diff --git a/llvm/test/CodeGen/Hexagon/fmaximum.ll b/llvm/test/CodeGen/Hexagon/fmaximum.ll index 6a7c6a91946c5..7c1903ef44351 100644 --- a/llvm/test/CodeGen/Hexagon/fmaximum.ll +++ b/llvm/test/CodeGen/Hexagon/fmaximum.ll @@ -1,4 +1,4 @@ -; RUN: llc -O0 -march=hexagon < %s | FileCheck %s +; RUN: llc -O0 -mtriple=hexagon < %s | FileCheck %s ; CHECK-LABEL: fmaximum_vec32f32 define float @fmaximum_vec32f32(<32 x float> %vec) { diff --git a/llvm/test/CodeGen/Hexagon/fminimum.ll b/llvm/test/CodeGen/Hexagon/fminimum.ll index 5b5ad5ffb9552..238411ab49e8a 100644 --- a/llvm/test/CodeGen/Hexagon/fminimum.ll +++ b/llvm/test/CodeGen/Hexagon/fminimum.ll @@ -1,4 +1,4 @@ -; RUN: llc -O0 -march=hexagon < %s | FileCheck %s +; RUN: llc -O0 -mtriple=hexagon < %s | FileCheck %s ; CHECK-LABEL: fminimum_vec32f32 define float @fminimum_vec32f32(<32 x float> %vec) { diff --git a/llvm/test/LTO/ARM/float-abi-module-flag.ll b/llvm/test/LTO/ARM/float-abi-module-flag.ll new file mode 100644 index 0000000000000..41ee67cb27f4f --- /dev/null +++ b/llvm/test/LTO/ARM/float-abi-module-flag.ll @@ -0,0 +1,45 @@ +; The "float-abi" module flag selects the floating-point calling convention +; used during LTO codegen, the same way the -float-abi codegen option does. + +; REQUIRES: arm-registered-target + +; RUN: split-file %s %t + +; Hard float ABI: the argument and result stay in a VFP register (s0). +; RUN: llvm-as %t/hard.ll -o %t/hard.o +; RUN: llvm-lto2 run -r %t/hard.o,f,px %t/hard.o -filetype=asm -o %t/hard.s +; RUN: FileCheck %s --check-prefix=HARD < %t/hard.s.0 + +; Soft float ABI: the argument and result are passed in a GPR, so the value is +; moved between r0 and s0. +; RUN: llvm-as %t/soft.ll -o %t/soft.o +; RUN: llvm-lto2 run -r %t/soft.o,f,px %t/soft.o -filetype=asm -o %t/soft.s +; RUN: FileCheck %s --check-prefix=SOFT < %t/soft.s.0 + +;--- hard.ll +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7-none-eabi" + +; HARD-LABEL: f: +; HARD-NEXT: .fnstart +; HARD-NEXT: vadd.f32 s0, s0, s0 +define float @f(float %x) { + %r = fadd float %x, %x + ret float %r +} +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"float-abi", !"hard"} + +;--- soft.ll +target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" +target triple = "armv7-none-eabi" + +; SOFT-LABEL: f: +; SOFT-NEXT: .fnstart +; SOFT-NEXT: vmov s0, r0 +define float @f(float %x) { + %r = fadd float %x, %x + ret float %r +} +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"float-abi", !"soft"} diff --git a/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/float-abi-module-flag.ll b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/float-abi-module-flag.ll new file mode 100644 index 0000000000000..742122095a8b6 --- /dev/null +++ b/llvm/test/Transforms/Util/DeclareRuntimeLibcalls/float-abi-module-flag.ll @@ -0,0 +1,28 @@ +; REQUIRES: arm-registered-target + +; The "float-abi" module flag selects the calling convention of the +; runtime library calls. + +; RUN: split-file %s %t + +; Hard float ABI module flag: libcalls use the AAPCS-VFP calling convention. +; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=arm-none-linux-gnueabi < %t/hard.ll | FileCheck %s --check-prefix=HARD + +; Soft float ABI module flag: libcalls use the plain AAPCS calling convention. +; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=arm-none-linux-gnueabi < %t/soft.ll | FileCheck %s --check-prefix=SOFT + +; No module flag: the ABI defaults to the one implied by the target triple. +; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=arm-none-linux-gnueabihf < %t/none.ll | FileCheck %s --check-prefix=HARD +; RUN: opt -S -passes=declare-runtime-libcalls -mtriple=arm-none-linux-gnueabi < %t/none.ll | FileCheck %s --check-prefix=SOFT + +;--- hard.ll +; HARD: declare arm_aapcs_vfpcc void @__addtf3(...) +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"float-abi", !"hard"} + +;--- soft.ll +; SOFT: declare arm_aapcscc void @__addtf3(...) +!llvm.module.flags = !{!0} +!0 = !{i32 1, !"float-abi", !"soft"} + +;--- none.ll diff --git a/llvm/tools/llc/NewPMDriver.cpp b/llvm/tools/llc/NewPMDriver.cpp index 97a7a8a2a6ba8..cc13f2f545549 100644 --- a/llvm/tools/llc/NewPMDriver.cpp +++ b/llvm/tools/llc/NewPMDriver.cpp @@ -133,10 +133,8 @@ int llvm::compileModuleWithNewPM( MAM.registerPass([&] { const TargetOptions &Options = Target->Options; - return RuntimeLibraryAnalysis( - M->getTargetTriple(), Target->Options.ExceptionModel, - Target->Options.FloatABIType, Target->Options.EABIVersion, - Options.MCOptions.ABIName, Target->Options.VecLib); + return RuntimeLibraryAnalysis(Options.ExceptionModel, Options.EABIVersion, + Options.MCOptions.ABIName, Options.VecLib); }); MAM.registerPass([&] { return MachineModuleAnalysis(MMI); }); diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index 55f91a375fc8a..4d00e0fcb048a 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -684,9 +684,6 @@ static int compileModule(char **argv, SmallVectorImpl &PluginList, if (std::optional LDT = codegen::getExplicitLargeDataThreshold()) Target->setLargeDataThreshold(*LDT); - if (codegen::getFloatABIForCalls() != FloatABI::Default) - Target->Options.FloatABIType = codegen::getFloatABIForCalls(); - // Figure out where we are going to send the output. std::unique_ptr Out = GetOutputStream(TheTriple.getOS()); if (!Out) @@ -768,9 +765,8 @@ static int compileModule(char **argv, SmallVectorImpl &PluginList, legacy::PassManager PM; PM.add(new TargetLibraryInfoWrapperPass(TLII)); PM.add(new RuntimeLibraryInfoWrapper( - TheTriple, Target->Options.ExceptionModel, Target->Options.FloatABIType, - Target->Options.EABIVersion, Options.MCOptions.ABIName, - Target->Options.VecLib)); + Target->Options.ExceptionModel, Target->Options.EABIVersion, + Options.MCOptions.ABIName, Target->Options.VecLib)); { raw_pwrite_stream *OS = &Out->os(); diff --git a/llvm/tools/lli/lli.cpp b/llvm/tools/lli/lli.cpp index 97d2e7191e9b0..0fcad0a09591a 100644 --- a/llvm/tools/lli/lli.cpp +++ b/llvm/tools/lli/lli.cpp @@ -511,8 +511,12 @@ int main(int argc, char **argv, char * const *envp) { TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple(TargetTriple)); - if (codegen::getFloatABIForCalls() != FloatABI::Default) - Options.FloatABIType = codegen::getFloatABIForCalls(); + + if (FloatABI::ABIType ABI = codegen::getFloatABIForCalls(); + ABI != FloatABI::Default && !Mod->getModuleFlag("float-abi")) { + Mod->addModuleFlag(Module::Error, "float-abi", + MDString::get(Context, FloatABI::getABITypeName(ABI))); + } builder.setTargetOptions(Options); diff --git a/llvm/tools/opt/NewPMDriver.cpp b/llvm/tools/opt/NewPMDriver.cpp index 5a3e35f6f494d..04c7b99e08cbc 100644 --- a/llvm/tools/opt/NewPMDriver.cpp +++ b/llvm/tools/opt/NewPMDriver.cpp @@ -423,8 +423,7 @@ bool llvm::runPassPipeline( MAM.registerPass([&] { const TargetOptions &Options = TM->Options; - return RuntimeLibraryAnalysis(M.getTargetTriple(), Options.ExceptionModel, - Options.FloatABIType, Options.EABIVersion, + return RuntimeLibraryAnalysis(Options.ExceptionModel, Options.EABIVersion, Options.MCOptions.ABIName, Options.VecLib); }); } diff --git a/llvm/tools/opt/optdriver.cpp b/llvm/tools/opt/optdriver.cpp index e8c50110acc82..b499d74893937 100644 --- a/llvm/tools/opt/optdriver.cpp +++ b/llvm/tools/opt/optdriver.cpp @@ -852,8 +852,8 @@ optMain(int argc, char **argv, Passes.add(new TargetLibraryInfoWrapperPass(TLII)); Passes.add(new RuntimeLibraryInfoWrapper( - ModuleTriple, Options->ExceptionModel, Options->FloatABIType, - Options->EABIVersion, Options->MCOptions.ABIName, Options->VecLib)); + Options->ExceptionModel, Options->EABIVersion, Options->MCOptions.ABIName, + Options->VecLib)); // Add internal analysis passes from the target machine. Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis()