Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -151,6 +151,9 @@ // from TargetMachine. void resetTargetOptions(const Function &F) const; + bool haveAllFunctionsAttribute(const Module &M, StringRef Attr, + StringRef Value); + /// Return target specific asm information. const MCAsmInfo *getMCAsmInfo() const { return AsmInfo; } Index: lib/Target/ARM/ARMAsmPrinter.cpp =================================================================== --- lib/Target/ARM/ARMAsmPrinter.cpp +++ lib/Target/ARM/ARMAsmPrinter.cpp @@ -451,16 +451,8 @@ OutStreamer->EmitAssemblerFlag(MCAF_SyntaxUnified); // Emit ARM Build Attributes - if (TT.isOSBinFormatELF()) { - if (!M.empty()) { - // FIXME: this is a hack, but it is not more broken than - // resetTargetOptions already was. The purpose of reading the target - // options here is to read function attributes denormal and trapping-math - // that we want to map onto build attributes. - TM.resetTargetOptions(*M.begin()); - } + if (TT.isOSBinFormatELF()) emitAttributes(); - } // Use the triple's architecture and subarchitecture to determine // if we're thumb for the purposes of the top level code16 assembler @@ -759,12 +751,16 @@ } // Set FP Denormals. - if (TM.Options.FPDenormalType == FPDenormal::PreserveSign) - ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, - ARMBuildAttrs::PreserveFPSign); - else if (TM.Options.FPDenormalType == FPDenormal::PositiveZero) - ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, - ARMBuildAttrs::PositiveZero); + if (TM.haveAllFunctionsAttribute(*MMI->getModule(), "denormal-fp-math", + "preserve-sign") || + TM.Options.FPDenormalType == FPDenormal::PreserveSign) + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, + ARMBuildAttrs::PreserveFPSign); + else if (TM.haveAllFunctionsAttribute(*MMI->getModule(), "denormal-fp-math", + "positive-zero") || + TM.Options.FPDenormalType == FPDenormal::PositiveZero) + ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, + ARMBuildAttrs::PositiveZero); else if (!TM.Options.UnsafeFPMath) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_denormal, ARMBuildAttrs::IEEEDenormals); @@ -795,7 +791,9 @@ } // Set FP exceptions and rounding - if (TM.Options.NoTrappingFPMath) + if (TM.haveAllFunctionsAttribute(*MMI->getModule(), "no-trapping-math", + "true") || + TM.Options.NoTrappingFPMath) ATS.emitAttribute(ARMBuildAttrs::ABI_FP_exceptions, ARMBuildAttrs::Not_Allowed); else if (!TM.Options.UnsafeFPMath) { Index: lib/Target/TargetMachine.cpp =================================================================== --- lib/Target/TargetMachine.cpp +++ lib/Target/TargetMachine.cpp @@ -89,6 +89,17 @@ Options.FPDenormalType = FPDenormal::PositiveZero; } +/// \brief Returns true if all functions have the same function attribute value +/// and false otherwise. +bool TargetMachine::haveAllFunctionsAttribute(const Module &M, StringRef Attr, + StringRef Value) { + for (auto &F : M) + if (F.getFnAttribute(Attr).getValueAsString() != Value) + return false; + + return true; +} + /// Returns the code generation relocation model. The choices are static, PIC, /// and dynamic-no-pic. Reloc::Model TargetMachine::getRelocationModel() const { return RM; }