diff options
author | Melanie Blower <melanie.blower@intel.com> | 2019-12-02 11:22:52 -0800 |
---|---|---|
committer | Melanie Blower <melanie.blower@intel.com> | 2019-12-04 11:32:33 -0800 |
commit | cdbed2dd856c14687efd741c2d8321686102acb8 (patch) | |
tree | a51de1b31c871c79e7d2486466463562cdaa9a7d /clang/lib/CodeGen | |
parent | 75bbbeec74bbac327768a636d025f292a955c672 (diff) | |
download | bcm5719-llvm-cdbed2dd856c14687efd741c2d8321686102acb8.tar.gz bcm5719-llvm-cdbed2dd856c14687efd741c2d8321686102acb8.zip |
Reapply af57dbf12e54 "Add support for options -frounding-math, ftrapping-math, -ffp-model=, and -ffp-exception-behavior="
Patch was reverted because https://bugs.llvm.org/show_bug.cgi?id=44048
The original patch is modified to set the strictfp IR attribute
explicitly in CodeGen instead of as a side effect of IRBuilder
Differential Revision: https://reviews.llvm.org/D62731
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 52 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 3 |
3 files changed, 69 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index ca6b1d409c2..657c9260e6e 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4336,6 +4336,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, Callee.getAbstractInfo(), Attrs, CallingConv, /*AttrOnCallSite=*/true); + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) + if (FD->usesFPIntrin()) + // All calls within a strictfp function are marked strictfp + Attrs = + Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, + llvm::Attribute::StrictFP); + // Apply some call-site-specific attributes. // TODO: work this into building the attribute set. @@ -4385,6 +4392,13 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, SmallVector<llvm::OperandBundleDef, 1> BundleList = getBundlesForFunclet(CalleePtr); + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) + if (FD->usesFPIntrin()) + // All calls within a strictfp function are marked strictfp + Attrs = + Attrs.addAttribute(getLLVMContext(), llvm::AttributeList::FunctionIndex, + llvm::Attribute::StrictFP); + // Emit the actual call/invoke instruction. llvm::CallBase *CI; if (!InvokeDest) { diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 7f3be896a7b..fd3020835a4 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -33,6 +33,8 @@ #include "clang/Frontend/FrontendDiagnostic.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/FPEnv.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Operator.h" @@ -87,6 +89,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) FMF.setAllowReassoc(); } Builder.setFastMathFlags(FMF); + SetFPModel(); } CodeGenFunction::~CodeGenFunction() { @@ -102,6 +105,51 @@ CodeGenFunction::~CodeGenFunction() { CGM.getOpenMPRuntime().functionFinished(*this); } +// Map the LangOption for rounding mode into +// the corresponding enum in the IR. +static llvm::fp::RoundingMode ToConstrainedRoundingMD( + LangOptions::FPRoundingModeKind Kind) { + + switch (Kind) { + case LangOptions::FPR_ToNearest: return llvm::fp::rmToNearest; + case LangOptions::FPR_Downward: return llvm::fp::rmDownward; + case LangOptions::FPR_Upward: return llvm::fp::rmUpward; + case LangOptions::FPR_TowardZero: return llvm::fp::rmTowardZero; + case LangOptions::FPR_Dynamic: return llvm::fp::rmDynamic; + } + llvm_unreachable("Unsupported FP RoundingMode"); +} + +// Map the LangOption for exception behavior into +// the corresponding enum in the IR. +static llvm::fp::ExceptionBehavior ToConstrainedExceptMD( + LangOptions::FPExceptionModeKind Kind) { + + switch (Kind) { + case LangOptions::FPE_Ignore: return llvm::fp::ebIgnore; + case LangOptions::FPE_MayTrap: return llvm::fp::ebMayTrap; + case LangOptions::FPE_Strict: return llvm::fp::ebStrict; + } + llvm_unreachable("Unsupported FP Exception Behavior"); +} + +void CodeGenFunction::SetFPModel() { + auto fpRoundingMode = ToConstrainedRoundingMD( + getLangOpts().getFPRoundingMode()); + auto fpExceptionBehavior = ToConstrainedExceptMD( + getLangOpts().getFPExceptionMode()); + + if (fpExceptionBehavior == llvm::fp::ebIgnore && + fpRoundingMode == llvm::fp::rmToNearest) + // Constrained intrinsics are not used. + ; + else { + Builder.setIsFPConstrained(true); + Builder.setDefaultConstrainedRounding(fpRoundingMode); + Builder.setDefaultConstrainedExcept(fpExceptionBehavior); + } +} + CharUnits CodeGenFunction::getNaturalPointeeTypeAlignment(QualType T, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo) { @@ -823,6 +871,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, if (FD->isMain()) Fn->addFnAttr(llvm::Attribute::NoRecurse); + if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) + if (FD->usesFPIntrin()) + Fn->addFnAttr(llvm::Attribute::StrictFP); + // If a custom alignment is used, force realigning to this alignment on // any main function which certainly will need it. if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 7a2627ccf58..8f99b090b81 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4169,6 +4169,9 @@ public: /// point operation, expressed as the maximum relative error in ulp. void SetFPAccuracy(llvm::Value *Val, float Accuracy); + /// SetFPModel - Control floating point behavior via fp-model settings. + void SetFPModel(); + private: llvm::MDNode *getRangeForLoadFromType(QualType Ty); void EmitReturnOfRValue(RValue RV, QualType Ty); |