Index: include/llvm/CodeGen/CommandFlags.h =================================================================== --- include/llvm/CodeGen/CommandFlags.h +++ include/llvm/CodeGen/CommandFlags.h @@ -266,6 +266,14 @@ Options.ThreadModel = TMModel; + if (getenv("STRIP_FAST_MATH_FLAGS")) { + Options.UnsafeFPMath = false; + Options.NoInfsFPMath = false; + Options.NoNaNsFPMath = false; + Options.LessPreciseFPMADOption = false; + Options.AllowFPOpFusion = FPOpFusion::Strict; + } + return Options; } Index: include/llvm/InitializePasses.h =================================================================== --- include/llvm/InitializePasses.h +++ include/llvm/InitializePasses.h @@ -267,6 +267,7 @@ void initializeStripDeadDebugInfoPass(PassRegistry&); void initializeStripDeadPrototypesPassPass(PassRegistry&); void initializeStripDebugDeclarePass(PassRegistry&); +void initializeStripFastMathPass(PassRegistry&); void initializeStripNonDebugSymbolsPass(PassRegistry&); void initializeStripSymbolsPass(PassRegistry&); void initializeTailCallElimPass(PassRegistry&); Index: include/llvm/LinkAllPasses.h =================================================================== --- include/llvm/LinkAllPasses.h +++ include/llvm/LinkAllPasses.h @@ -138,6 +138,7 @@ (void) llvm::createStripNonDebugSymbolsPass(); (void) llvm::createStripDeadDebugInfoPass(); (void) llvm::createStripDeadPrototypesPass(); + (void) llvm::createStripFastMathPass(); (void) llvm::createTailCallEliminationPass(); (void) llvm::createJumpThreadingPass(); (void) llvm::createUnifyFunctionExitNodesPass(); Index: include/llvm/Transforms/Scalar.h =================================================================== --- include/llvm/Transforms/Scalar.h +++ include/llvm/Transforms/Scalar.h @@ -486,6 +486,9 @@ // FunctionPass *createLoopDistributePass(); +/// \brief This pass strip fast-math flags. +FunctionPass *createStripFastMathPass(); + } // End llvm namespace #endif Index: lib/Transforms/IPO/PassManagerBuilder.cpp =================================================================== --- lib/Transforms/IPO/PassManagerBuilder.cpp +++ lib/Transforms/IPO/PassManagerBuilder.cpp @@ -422,6 +422,9 @@ MPM.add(createMergeFunctionsPass()); addExtensionsToPM(EP_OptimizerLast, MPM); + + if (getenv("STRIP_FAST_MATH_FLAGS")) + MPM.add(createStripFastMathPass()); } void PassManagerBuilder::addLTOOptimizationPasses(legacy::PassManagerBase &PM) { @@ -517,6 +520,9 @@ addExtensionsToPM(EP_Peephole, PM); PM.add(createJumpThreadingPass()); + + if (getenv("STRIP_FAST_MATH_FLAGS")) + PM.add(createStripFastMathPass()); } void PassManagerBuilder::addLateLTOOptimizationPasses( Index: lib/Transforms/Scalar/CMakeLists.txt =================================================================== --- lib/Transforms/Scalar/CMakeLists.txt +++ lib/Transforms/Scalar/CMakeLists.txt @@ -49,6 +49,7 @@ StraightLineStrengthReduce.cpp StructurizeCFG.cpp TailRecursionElimination.cpp + StripFastMath.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms Index: lib/Transforms/Scalar/Scalar.cpp =================================================================== --- lib/Transforms/Scalar/Scalar.cpp +++ lib/Transforms/Scalar/Scalar.cpp @@ -81,6 +81,7 @@ initializePlaceSafepointsPass(Registry); initializeFloat2IntPass(Registry); initializeLoopDistributePass(Registry); + initializeStripFastMathPass(Registry); } void LLVMInitializeScalarOpts(LLVMPassRegistryRef R) { @@ -239,3 +240,7 @@ void LLVMAddLowerExpectIntrinsicPass(LLVMPassManagerRef PM) { unwrap(PM)->add(createLowerExpectIntrinsicPass()); } + +void LLVMAddStripFastMathPass(LLVMPassManagerRef PM) { + unwrap(PM)->add(createStripFastMathPass()); +} Index: lib/Transforms/Scalar/StripFastMath.cpp =================================================================== --- lib/Transforms/Scalar/StripFastMath.cpp +++ lib/Transforms/Scalar/StripFastMath.cpp @@ -0,0 +1,77 @@ +//===- StripFastMath.cpp - Strip fast-math flags from a module ------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The StripFastMath transformation implements code stripping. Specifically, it +// can delete: +// +// * 'fast' and other instruction flags +// * fast-math function attributes +// * fast-math TargetOptions +// +//===----------------------------------------------------------------------===// + +#include "llvm/Transforms/Scalar.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/TypeFinder.h" +#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/Utils/Local.h" +using namespace llvm; + +namespace { + class StripFastMath : public FunctionPass { + public: + static char ID; // Pass identification, replacement for typeid + explicit StripFastMath() + : FunctionPass(ID) { + initializeStripFastMathPass(*PassRegistry::getPassRegistry()); + } + + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { + AU.setPreservesAll(); + } + }; +} + +char StripFastMath::ID = 0; +INITIALIZE_PASS(StripFastMath, "strip-fast-math", + "Strip fast-math flags from a module", false, false) + +FunctionPass *llvm::createStripFastMathPass() { + return new StripFastMath(); +} + +bool StripFastMath::runOnFunction(Function &F) { + F.addFnAttr("less-precise-fpmad", "false"); + F.addFnAttr("no-infs-fp-math", "false"); + F.addFnAttr("no-nans-fp-math", "false"); + F.addFnAttr("unsafe-fp-math", "false"); + + for (auto &B : F) { + for (auto &I : B) { + if (isa(I)) { + I.setHasUnsafeAlgebra(false); + I.setHasNoNaNs(false); + I.setHasNoInfs(false); + I.setHasNoSignedZeros(false); + I.setHasAllowReciprocal(false); + } + } + } + + return true; +} Index: tools/clang/lib/CodeGen/BackendUtil.cpp =================================================================== --- tools/clang/lib/CodeGen/BackendUtil.cpp +++ tools/clang/lib/CodeGen/BackendUtil.cpp @@ -550,6 +550,14 @@ Options.MCOptions.AsmVerbose = CodeGenOpts.AsmVerbose; Options.MCOptions.ABIName = TargetOpts.ABI; + if (getenv("STRIP_FAST_MATH_FLAGS")) { + Options.UnsafeFPMath = false; + Options.NoInfsFPMath = false; + Options.NoNaNsFPMath = false; + Options.LessPreciseFPMADOption = false; + Options.AllowFPOpFusion = llvm::FPOpFusion::Strict; + } + TargetMachine *TM = TheTarget->createTargetMachine(Triple, TargetOpts.CPU, FeaturesStr, Options, RM, CM, OptLevel);