summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp52
1 files changed, 52 insertions, 0 deletions
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))
OpenPOWER on IntegriCloud