aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
authorZahira Ammarguellat <Zahira.Ammarguellat@intel.com>2023-05-31 15:38:20 -0400
committerZahira Ammarguellat <Zahira.Ammarguellat@intel.com>2023-09-08 09:48:53 -0400
commit2c93e3c1c8ba70694bc0d3fd71ac90836a147f2d (patch)
treeb421a22c87343efdb3979efedb83e22f7b26fd27 /clang/lib
parent77054f3946161ea43b67a623f33d4647e5c850fc (diff)
downloadllvm-2c93e3c1c8ba70694bc0d3fd71ac90836a147f2d.zip
llvm-2c93e3c1c8ba70694bc0d3fd71ac90836a147f2d.tar.gz
llvm-2c93e3c1c8ba70694bc0d3fd71ac90836a147f2d.tar.bz2
Take math-errno into account with '#pragma float_control(precise,on)' and
'attribute__((optnone)). Differential Revision: https://reviews.llvm.org/D151834
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGBuiltin.cpp55
-rw-r--r--clang/lib/CodeGen/CGCall.cpp20
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h6
3 files changed, 77 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index a513eae..5f9199d 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -2312,6 +2312,26 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
const unsigned BuiltinIDIfNoAsmLabel =
FD->hasAttr<AsmLabelAttr>() ? 0 : BuiltinID;
+ bool ErrnoOverriden = false;
+ // True if math-errno is overriden via the
+ // '#pragma float_control(precise, on)'. This pragma disables fast-math,
+ // which implies math-errno.
+ if (E->hasStoredFPFeatures()) {
+ FPOptionsOverride OP = E->getFPFeatures();
+ if (OP.hasMathErrnoOverride())
+ ErrnoOverriden = OP.getMathErrnoOverride();
+ }
+ // True if 'atttibute__((optnone)) is used. This attibute overrides
+ // fast-math which implies math-errno.
+ bool OptNone = CurFuncDecl && CurFuncDecl->hasAttr<OptimizeNoneAttr>();
+
+ // True if we are compiling at -O2 and errno has been disabled
+ // using the '#pragma float_control(precise, off)', and
+ // attribute opt-none hasn't been seen.
+ bool ErrnoOverridenToFalseWithOpt =
+ !ErrnoOverriden && !OptNone &&
+ CGM.getCodeGenOpts().OptimizationLevel != 0;
+
// There are LLVM math intrinsics/instructions corresponding to math library
// functions except the LLVM op will never set errno while the math library
// might. Also, math builtins have the same semantics as their math library
@@ -2323,9 +2343,38 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
getContext().BuiltinInfo.isConstWithoutErrnoAndExceptions(BuiltinID);
bool ConstWithoutExceptions =
getContext().BuiltinInfo.isConstWithoutExceptions(BuiltinID);
- if (FD->hasAttr<ConstAttr>() ||
- ((ConstWithoutErrnoAndExceptions || ConstWithoutExceptions) &&
- (!ConstWithoutErrnoAndExceptions || (!getLangOpts().MathErrno)))) {
+
+ // ConstAttr is enabled in fast-math mode. In fast-math mode, math-errno is
+ // disabled.
+ // Math intrinsics are generated only when math-errno is disabled. Any pragmas
+ // or attributes that affect math-errno should prevent or allow math
+ // intrincs to be generated. Intrinsics are generated:
+ // 1- In fast math mode, unless math-errno is overriden
+ // via '#pragma float_control(precise, on)', or via an
+ // 'attribute__((optnone))'.
+ // 2- If math-errno was enabled on command line but overriden
+ // to false via '#pragma float_control(precise, off))' and
+ // 'attribute__((optnone))' hasn't been used.
+ // 3- If we are compiling with optimization and errno has been disabled
+ // via '#pragma float_control(precise, off)', and
+ // 'attribute__((optnone))' hasn't been used.
+
+ bool ConstWithoutErrnoOrExceptions =
+ ConstWithoutErrnoAndExceptions || ConstWithoutExceptions;
+ bool GenerateIntrinsics =
+ FD->hasAttr<ConstAttr>() && !ErrnoOverriden && !OptNone;
+ if (!GenerateIntrinsics) {
+ GenerateIntrinsics =
+ ConstWithoutErrnoOrExceptions && !ConstWithoutErrnoAndExceptions;
+ if (!GenerateIntrinsics)
+ GenerateIntrinsics =
+ ConstWithoutErrnoOrExceptions &&
+ (!getLangOpts().MathErrno && !ErrnoOverriden && !OptNone);
+ if (!GenerateIntrinsics)
+ GenerateIntrinsics =
+ ConstWithoutErrnoOrExceptions && ErrnoOverridenToFalseWithOpt;
+ }
+ if (GenerateIntrinsics) {
switch (BuiltinIDIfNoAsmLabel) {
case Builtin::BIceil:
case Builtin::BIceilf:
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 37de280..e15a463 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -2279,6 +2279,17 @@ static llvm::FPClassTest getNoFPClassTestMask(const LangOptions &LangOpts) {
return Mask;
}
+void CodeGenModule::AdjustMemoryAttribute(StringRef Name,
+ CGCalleeInfo CalleeInfo,
+ llvm::AttributeList &Attrs) {
+ if (Attrs.getMemoryEffects().getModRef() == llvm::ModRefInfo::NoModRef) {
+ Attrs = Attrs.removeFnAttribute(getLLVMContext(), llvm::Attribute::Memory);
+ llvm::Attribute MemoryAttr = llvm::Attribute::getWithMemoryEffects(
+ getLLVMContext(), llvm::MemoryEffects::writeOnly());
+ Attrs = Attrs.addFnAttribute(getLLVMContext(), MemoryAttr);
+ }
+}
+
/// Construct the IR attribute list of a function or call.
///
/// When adding an attribute, please consider where it should be handled:
@@ -5501,11 +5512,18 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
/*AttrOnCallSite=*/true,
/*IsThunk=*/false);
- if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl))
+ if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(CurFuncDecl)) {
if (FD->hasAttr<StrictFPAttr>())
// All calls within a strictfp function are marked strictfp
Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::StrictFP);
+ // If -ffast-math is enabled and the function is guarded by an
+ // '__attribute__((optnone)) adjust the memory attribute so the BE emits the
+ // library call instead of the intrinsic.
+ if (FD->hasAttr<OptimizeNoneAttr>() && getLangOpts().FastMath)
+ CGM.AdjustMemoryAttribute(CalleePtr->getName(), Callee.getAbstractInfo(),
+ Attrs);
+ }
// Add call-site nomerge attribute if exists.
if (InNoMergeAttributedStmt)
Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoMerge);
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index 79f48b6..073b471 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -1260,6 +1260,12 @@ public:
llvm::AttributeList &Attrs, unsigned &CallingConv,
bool AttrOnCallSite, bool IsThunk);
+ /// Adjust Memory attribute to ensure that the BE gets the right attribute
+ // in order to generate the library call or the intrinsic for the function
+ // name 'Name'.
+ void AdjustMemoryAttribute(StringRef Name, CGCalleeInfo CalleeInfo,
+ llvm::AttributeList &Attrs);
+
/// Like the overload taking a `Function &`, but intended specifically
/// for frontends that want to build on Clang's target-configuration logic.
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs);