diff options
author | Zahira Ammarguellat <Zahira.Ammarguellat@intel.com> | 2023-05-31 15:38:20 -0400 |
---|---|---|
committer | Zahira Ammarguellat <Zahira.Ammarguellat@intel.com> | 2023-09-08 09:48:53 -0400 |
commit | 2c93e3c1c8ba70694bc0d3fd71ac90836a147f2d (patch) | |
tree | b421a22c87343efdb3979efedb83e22f7b26fd27 /clang/lib | |
parent | 77054f3946161ea43b67a623f33d4647e5c850fc (diff) | |
download | llvm-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.cpp | 55 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 20 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 6 |
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); |