llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Rohit Aggarwal (rohitaggarwal007)

<details>
<summary>Changes</summary>

aocl-libm-ose  link : [Click here](https://github.com/amd/aocl-libm-ose)
Support scalar call to fast variant using -fsclrlib=AMDLIBM for X86 
architecture.

    Under fast-math at -O3, scalar math library calls (e.g. tan, exp)
    are rewritten to their AMD AOCL fast-call equivalents (e.g. amd_fasttan,
    amd_fastexp) on X86 targets.

    LLVM:
    - New X86 MachineFunctionPass X86GenScalarAmdFastCalls, run in 
addMachineSSAOptimization at CodeGenOptLevel::Aggressive.
    - TargetLibraryInfo gains a scalar-math-library selection (ScalarLibrary 
enum, addScalarFunctionsFromMathLib / getScalarFunctionFromMathLib / 
getScalarMathLib / setScalarMathLib), populated from the new 
ScalarAOCLFuncs.def mapping and driven by the -scalar-library=AMDLIBM cl::opt 
(usable with llc and the LTO plugin).
    - The rewrite is gated on -scalar-library=AMDLIBM plus a function-level 
fast-math signal (per-operation fast-math flags are no longer available at this 
late machine pass in upstream codegen).

    Clang:
    - New -fsclrlib= driver/CC1 flag with a CodeGenOptions ScalarLib enum, 
applied in BackendUtil and forwarded to LTO as -plugin-opt=-scalar-library=.

    Tests:
    - llvm/test/CodeGen/X86/aocl-fast-scalar-calls.ll (llc path, incl. a 
negative no-fast-math case).
    - clang/test/CodeGen/X86/aocl-fast-scalar-calls.c (driver path).
    - aocl-fast-scalar-calls-mappings.ll: float variants (tanf, powf), a 
*_finite alias (__exp_finite), inverse-trig (acos, atan), and negative cases 
for math calls with no AOCL mapping (pow(double), cbrt).
    - aocl-fast-scalar-calls-i686.ll: 32-bit X86 coverage (tan, expf).
    - aocl-fast-scalar-calls.c: add a single-precision case (tanf) and an 
unmapped negative case (cbrt) to the clang driver test.

---

Patch is 40.67 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/213676.diff


18 Files Affected:

- (modified) clang/include/clang/Basic/CodeGenOptions.def (+3) 
- (modified) clang/include/clang/Basic/CodeGenOptions.h (+6) 
- (modified) clang/include/clang/Options/Options.td (+7) 
- (modified) clang/lib/CodeGen/BackendUtil.cpp (+15) 
- (modified) clang/lib/Driver/ToolChains/Clang.cpp (+11) 
- (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+8) 
- (added) clang/test/CodeGen/X86/aocl-fast-scalar-calls.c (+40) 
- (added) llvm/include/llvm/Analysis/ScalarAOCLFuncs.def (+80) 
- (modified) llvm/include/llvm/Analysis/TargetLibraryInfo.h (+33) 
- (modified) llvm/lib/Analysis/TargetLibraryInfo.cpp (+52) 
- (modified) llvm/lib/Target/X86/CMakeLists.txt (+1) 
- (modified) llvm/lib/Target/X86/X86.h (+6) 
- (added) llvm/lib/Target/X86/X86GenScalarAmdFastCalls.cpp (+176) 
- (modified) llvm/lib/Target/X86/X86TargetMachine.cpp (+5) 
- (added) llvm/test/CodeGen/X86/aocl-fast-scalar-calls-i686.ll (+31) 
- (added) llvm/test/CodeGen/X86/aocl-fast-scalar-calls-mappings.ll (+124) 
- (added) llvm/test/CodeGen/X86/aocl-fast-scalar-calls.ll (+63) 
- (added) llvm/test/CodeGen/X86/veclib-llvm.sincos.s (+258) 


``````````diff
diff --git a/clang/include/clang/Basic/CodeGenOptions.def 
b/clang/include/clang/Basic/CodeGenOptions.def
index 7e54e75752f39..16e353ae76f20 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -420,6 +420,9 @@ VALUE_CODEGENOPT(InlineMaxStackSize, 32, UINT_MAX, Benign)
 // Vector functions library to use.
 ENUM_CODEGENOPT(VecLib, VectorLibrary, 4, VectorLibrary::NoLibrary, Benign)
 
+// Scalar math functions library to use.
+ENUM_CODEGENOPT(ScalarLib, ScalarLibrary, 1, Default_Scalar_Library, Benign)
+
 /// The default TLS model to use.
 ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel, Benign)
 
diff --git a/clang/include/clang/Basic/CodeGenOptions.h 
b/clang/include/clang/Basic/CodeGenOptions.h
index c12434135a198..06cca30d9c5aa 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -110,6 +110,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
     OnlyAlwaysInlining  // Only run the always inlining pass.
   };
 
+  /// Scalar math functions library to use with -fsclrlib=.
+  enum ScalarLibrary {
+    Default_Scalar_Library, // Use default library.
+    SCALAR_AMDLIBM          // AMD scalar math library.
+  };
+
   enum ObjCDispatchMethodKind {
     Legacy = 0,
     NonLegacy = 1,
diff --git a/clang/include/clang/Options/Options.td 
b/clang/include/clang/Options/Options.td
index 2467ebd0abe19..8eadef417fa35 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -3965,6 +3965,13 @@ def fveclib : Joined<["-"], "fveclib=">, Group<f_Group>,
     NormalizedValues<["Accelerate", "LIBMVEC", "MASSV", "SVML", "SLEEF",
                       "Darwin_libsystem_m", "ArmPL", "AMDLIBM", "NoLibrary"]>,
     MarshallingInfoEnum<CodeGenOpts<"VecLib">, "NoLibrary">;
+def fsclrlib : Joined<["-"], "fsclrlib=">, Group<f_Group>,
+    Visibility<[ClangOption, CC1Option]>,
+    HelpText<"Use the given scalar math functions library.">,
+    Values<"AMDLIBM,none">,
+    NormalizedValuesScope<"CodeGenOptions">,
+    NormalizedValues<["SCALAR_AMDLIBM", "Default_Scalar_Library"]>,
+    MarshallingInfoEnum<CodeGenOpts<"ScalarLib">, "Default_Scalar_Library">;
 def fno_lax_vector_conversions : Flag<["-"], "fno-lax-vector-conversions">, 
Group<f_Group>,
   Alias<flax_vector_conversions_EQ>, AliasArgs<["none"]>;
 def fno_implicit_module_maps : Flag <["-"], "fno-implicit-module-maps">, 
Group<f_Group>;
diff --git a/clang/lib/CodeGen/BackendUtil.cpp 
b/clang/lib/CodeGen/BackendUtil.cpp
index 068b1b4c262c8..aa0797adddfc3 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -142,6 +142,19 @@ static std::string getProfileGenName(const CodeGenOptions 
&CodeGenOpts) {
   return FileName;
 }
 
+/// Populate the scalar math library mappings on \p TLII according to the
+/// -fsclrlib= selection.
+static void addScalarMathLibrary(TargetLibraryInfoImpl &TLII,
+                                 const CodeGenOptions &CodeGenOpts) {
+  switch (CodeGenOpts.getScalarLib()) {
+  case CodeGenOptions::SCALAR_AMDLIBM:
+    TLII.addScalarFunctionsFromMathLib(TargetLibraryInfoImpl::SCALAR_AMDLIBM);
+    break;
+  case CodeGenOptions::Default_Scalar_Library:
+    break;
+  }
+}
+
 namespace {
 
 class EmitAssemblyHelper {
@@ -1002,6 +1015,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
   // preset TLI.
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
       llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
+  addScalarMathLibrary(*TLII, CodeGenOpts);
   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
 
   // Register all the basic analyses with the managers.
@@ -1271,6 +1285,7 @@ void EmitAssemblyHelper::RunCodegenPipelineLegacy(
   // Add LibraryInfo.
   std::unique_ptr<TargetLibraryInfoImpl> TLII(
       llvm::driver::createTLII(TargetTriple, CodeGenOpts.getVecLib()));
+  addScalarMathLibrary(*TLII, CodeGenOpts);
   CodeGenPasses.add(new TargetLibraryInfoWrapperPass(*TLII));
 
   const llvm::TargetOptions &Options = TM->Options;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp 
b/clang/lib/Driver/ToolChains/Clang.cpp
index 9e90994c178dd..934b504478a8c 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5982,6 +5982,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction 
&JA,
     A->render(Args, CmdArgs);
   }
 
+  if (Arg *A = Args.getLastArg(options::OPT_fsclrlib)) {
+    StringRef Name = A->getValue();
+    if (Name == "AMDLIBM") {
+      if (Triple.getArch() != llvm::Triple::x86 &&
+          Triple.getArch() != llvm::Triple::x86_64)
+        D.Diag(diag::err_drv_unsupported_opt_for_target)
+            << Name << Triple.getArchName();
+    }
+    A->render(Args, CmdArgs);
+  }
+
   if (Args.hasFlag(options::OPT_fmerge_all_constants,
                    options::OPT_fno_merge_all_constants, false))
     CmdArgs.push_back("-fmerge-all-constants");
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp 
b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 883296e43111b..2ca621ad1123a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -1145,6 +1145,14 @@ void tools::addLTOOptions(const ToolChain &ToolChain, 
const ArgList &Args,
           Twine(PluginOptPrefix) + "-vector-library=" + OptVal.value()));
   }
 
+  // Pass scalar math library arguments to LTO.
+  if (Arg *ArgScalarLib = Args.getLastArg(options::OPT_fsclrlib)) {
+    StringRef Name = ArgScalarLib->getValue();
+    if (Name == "AMDLIBM")
+      CmdArgs.push_back(Args.MakeArgString(Twine(PluginOptPrefix) +
+                                           "-scalar-library=" + Name));
+  }
+
   // Try to pass driver level flags relevant to LTO code generation down to
   // the plugin.
 
diff --git a/clang/test/CodeGen/X86/aocl-fast-scalar-calls.c 
b/clang/test/CodeGen/X86/aocl-fast-scalar-calls.c
new file mode 100644
index 0000000000000..50a512ebc2a5e
--- /dev/null
+++ b/clang/test/CodeGen/X86/aocl-fast-scalar-calls.c
@@ -0,0 +1,40 @@
+// Verify that the -fsclrlib=AMDLIBM driver flag, together with fast-math at 
-O3,
+// rewrites scalar math library calls into their AMD AOCL fast-call equivalents
+// for X86, and leaves them untouched without the flag.
+
+// REQUIRES: x86-registered-target
+
+// RUN: %clang --target=x86_64-unknown-linux-gnu -O3 -ffast-math \
+// RUN:   -fsclrlib=AMDLIBM -S %s -o - | FileCheck %s --check-prefix=AMD
+// RUN: %clang --target=x86_64-unknown-linux-gnu -O3 -ffast-math \
+// RUN:   -S %s -o - | FileCheck %s --check-prefix=STD
+
+double tan(double);
+double exp(double);
+float tanf(float);
+double cbrt(double);
+
+double call_tan(double x) { return tan(x) + x; }
+// AMD-LABEL: call_tan:
+// AMD: callq{{.*}}amd_fasttan
+// STD-LABEL: call_tan:
+// STD: callq{{.*}}tan
+
+double call_exp(double x) { return exp(x) + x; }
+// AMD-LABEL: call_exp:
+// AMD: callq{{.*}}amd_fastexp
+// STD-LABEL: call_exp:
+// STD: callq{{.*}}exp
+
+// Single-precision variant is rewritten too.
+float call_tanf(float x) { return tanf(x) + x; }
+// AMD-LABEL: call_tanf:
+// AMD: callq{{.*}}amd_fasttanf
+// STD-LABEL: call_tanf:
+// STD: callq{{.*}}tanf
+
+// cbrt has no AOCL mapping and must stay even with the option enabled.
+double call_cbrt(double x) { return cbrt(x) + x; }
+// AMD-LABEL: call_cbrt:
+// AMD-NOT: amd_fast
+// AMD: callq{{.*}}cbrt
diff --git a/llvm/include/llvm/Analysis/ScalarAOCLFuncs.def 
b/llvm/include/llvm/Analysis/ScalarAOCLFuncs.def
new file mode 100644
index 0000000000000..906b1612afa5c
--- /dev/null
+++ b/llvm/include/llvm/Analysis/ScalarAOCLFuncs.def
@@ -0,0 +1,80 @@
+//===-- ScalarAOCLFuncs.def - AMD scalar math library mappings --*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This .def file creates a mapping from standard scalar math functions to
+// their corresponding fast entry points in the AMD AOCL scalar math library.
+// The lowering is only legal under fast-math semantics.
+//
+//===----------------------------------------------------------------------===//
+
+#if defined(TLI_DEFINE_SCALAR_AOCL_FUNCS)
+#define TLI_DEFINE_SCALAR_AOCL_FUNC(SCAL, AOCLENTRY) {SCAL, AOCLENTRY},
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("acosf", "amd_fastacosf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__acosf_finite", "amd_fastacosf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("acos", "amd_fastacos")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__acos_finite", "amd_fastacos")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("asinf", "amd_fastasinf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__asinf_finite", "amd_fastasinf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("asin", "amd_fastasin")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__asin_finite", "amd_fastasin")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("atanf", "amd_fastatanf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__atanf_finite", "amd_fastatanf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("atan", "amd_fastatan")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__atan_finite", "amd_fastatan")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("cosf", "amd_fastcosf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__cosf_finite", "amd_fastcosf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.cos.f32", "amd_fastcosf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("cos", "amd_fastcos")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__cos_finite", "amd_fastcos")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.cos.f64", "amd_fastcos")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("erff", "amd_fasterff")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__erff_finite", "amd_fasterff")
+TLI_DEFINE_SCALAR_AOCL_FUNC("erf", "amd_fasterf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__erf_finite", "amd_fasterf")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("expf", "amd_fastexpf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__expf_finite", "amd_fastexpf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.exp.f32", "amd_fastexpf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("exp", "amd_fastexp")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__exp_finite", "amd_fastexp")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.exp.f64", "amd_fastexp")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("logf", "amd_fastlogf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__logf_finite", "amd_fastlogf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.log.f32", "amd_fastlogf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("log", "amd_fastlog")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__log_finite", "amd_fastlog")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.log.f64", "amd_fastlog")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("powf", "amd_fastpowf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__powf_finite", "amd_fastpowf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.pow.f32", "amd_fastpowf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("pow", "amd_fastpow")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__pow_finite", "amd_fastpow")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.pow.f64", "amd_fastpow")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("sinf", "amd_fastsinf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__sinf_finite", "amd_fastsinf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.sin.f32", "amd_fastsinf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("sin", "amd_fastsin")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__sin_finite", "amd_fastsin")
+TLI_DEFINE_SCALAR_AOCL_FUNC("llvm.sin.f64", "amd_fastsin")
+
+TLI_DEFINE_SCALAR_AOCL_FUNC("tanf", "amd_fasttanf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__tanf_finite", "amd_fasttanf")
+TLI_DEFINE_SCALAR_AOCL_FUNC("tan", "amd_fasttan")
+TLI_DEFINE_SCALAR_AOCL_FUNC("__tan_finite", "amd_fasttan")
+#endif
+
+#undef TLI_DEFINE_SCALAR_AOCL_FUNCS
+#undef TLI_DEFINE_SCALAR_AOCL_FUNC
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h 
b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index cd61b925ee5d7..4df61a4ec0791 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -109,12 +109,25 @@ class TargetLibraryInfoImpl {
   /// on VectorFnName rather than ScalarFnName.
   std::vector<VecDesc> ScalarDescs;
 
+  /// Mapping from a standard scalar math function name to its AMD scalar math
+  /// library fast-call equivalent (e.g. "tan" -> "amd_fasttan"). Populated 
when
+  /// an AMD scalar math library is selected.
+  DenseMap<StringRef, StringRef> LibScalarFunctions;
+
   /// Return true if the function type FTy is valid for the library function
   /// F, regardless of whether the function is available.
   LLVM_ABI bool isValidProtoForLibFunc(const FunctionType &FTy, LibFunc F,
                                        const Module &M) const;
 
 public:
+  /// Scalar math library selection used for lowering standard scalar math
+  /// calls to faster, library-specific entry points.
+  enum ScalarLibrary {
+    Default_Scalar_Library, // Use default library.
+    SCALAR_AMDLIBM          // AMD scalar math library.
+  };
+  ScalarLibrary ScalarMathLib = Default_Scalar_Library;
+
   TargetLibraryInfoImpl() = delete;
   LLVM_ABI explicit TargetLibraryInfoImpl(
       const Triple &T, VectorLibrary VecLib = VectorLibrary::NoLibrary);
@@ -182,6 +195,20 @@ class TargetLibraryInfoImpl {
   addVectorizableFunctionsFromVecLib(enum VectorLibrary VecLib,
                                      const llvm::Triple &TargetTriple);
 
+  /// Populate the scalar math function mappings for the given scalar library
+  /// and record it as the selected scalar math library.
+  LLVM_ABI void addScalarFunctionsFromMathLib(enum ScalarLibrary ScalarLib);
+
+  /// Return the library-specific scalar function name for \p F, or an empty
+  /// StringRef if no mapping exists.
+  LLVM_ABI StringRef getScalarFunctionFromMathLib(StringRef F) const;
+
+  /// Return the currently selected scalar math library.
+  LLVM_ABI ScalarLibrary getScalarMathLib() const;
+
+  /// Set the selected scalar math library.
+  LLVM_ABI void setScalarMathLib(enum ScalarLibrary ScalarLib);
+
   /// Return true if the function F has a vector equivalent with vectorization
   /// factor VF.
   bool isFunctionVectorizable(StringRef F, const ElementCount &VF) const {
@@ -387,6 +414,12 @@ class TargetLibraryInfo {
                                       bool Masked) const {
     return Impl->getVectorMappingInfo(F, VF, Masked);
   }
+  StringRef getScalarFunctionFromMathLib(StringRef F) const {
+    return Impl->getScalarFunctionFromMathLib(F);
+  }
+  TargetLibraryInfoImpl::ScalarLibrary getScalarMathLib() const {
+    return Impl->getScalarMathLib();
+  }
 
   /// Tests if the function is both available and a candidate for optimized 
code
   /// generation.
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp 
b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 763c04b9b06f7..45a20b8398b4e 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -18,9 +18,18 @@
 #include "llvm/IR/Module.h"
 #include "llvm/IR/SystemLibraries.h"
 #include "llvm/InitializePasses.h"
+#include "llvm/Support/CommandLine.h"
 #include "llvm/TargetParser/Triple.h"
 using namespace llvm;
 
+static cl::opt<TargetLibraryInfoImpl::ScalarLibrary> ClScalarLibrary(
+    "scalar-library", cl::Hidden, cl::desc("Scalar functions library"),
+    cl::init(TargetLibraryInfoImpl::Default_Scalar_Library),
+    cl::values(clEnumValN(TargetLibraryInfoImpl::Default_Scalar_Library, 
"none",
+                          "Use default library"),
+               clEnumValN(TargetLibraryInfoImpl::SCALAR_AMDLIBM, "AMDLIBM",
+                          "AMD scalar math library")));
+
 #define GET_TARGET_LIBRARY_INFO_STRING_TABLE
 #include "llvm/Analysis/TargetLibraryInfo.inc"
 
@@ -902,6 +911,7 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const Triple 
&T,
   memset(AvailableArray, -1, sizeof(AvailableArray));
 
   initialize(*this, T, StandardNamesStrTable, VecLib);
+  addScalarFunctionsFromMathLib(ClScalarLibrary);
 }
 
 TargetLibraryInfoImpl::TargetLibraryInfoImpl(const TargetLibraryInfoImpl &TLI)
@@ -913,6 +923,8 @@ TargetLibraryInfoImpl::TargetLibraryInfoImpl(const 
TargetLibraryInfoImpl &TLI)
   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
   VectorDescs = TLI.VectorDescs;
   ScalarDescs = TLI.ScalarDescs;
+  LibScalarFunctions = TLI.LibScalarFunctions;
+  ScalarMathLib = TLI.ScalarMathLib;
 }
 
 TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
@@ -926,6 +938,8 @@ 
TargetLibraryInfoImpl::TargetLibraryInfoImpl(TargetLibraryInfoImpl &&TLI)
             AvailableArray);
   VectorDescs = TLI.VectorDescs;
   ScalarDescs = TLI.ScalarDescs;
+  LibScalarFunctions = TLI.LibScalarFunctions;
+  ScalarMathLib = TLI.ScalarMathLib;
 }
 
 TargetLibraryInfoImpl &TargetLibraryInfoImpl::operator=(const 
TargetLibraryInfoImpl &TLI) {
@@ -936,6 +950,8 @@ TargetLibraryInfoImpl 
&TargetLibraryInfoImpl::operator=(const TargetLibraryInfoI
   ShouldSignExtI32Return = TLI.ShouldSignExtI32Return;
   SizeOfInt = TLI.SizeOfInt;
   memcpy(AvailableArray, TLI.AvailableArray, sizeof(AvailableArray));
+  LibScalarFunctions = TLI.LibScalarFunctions;
+  ScalarMathLib = TLI.ScalarMathLib;
   return *this;
 }
 
@@ -948,6 +964,8 @@ TargetLibraryInfoImpl 
&TargetLibraryInfoImpl::operator=(TargetLibraryInfoImpl &&
   SizeOfInt = TLI.SizeOfInt;
   std::move(std::begin(TLI.AvailableArray), std::end(TLI.AvailableArray),
             AvailableArray);
+  LibScalarFunctions = TLI.LibScalarFunctions;
+  ScalarMathLib = TLI.ScalarMathLib;
   return *this;
 }
 
@@ -1397,6 +1415,40 @@ void 
TargetLibraryInfoImpl::addVectorizableFunctionsFromVecLib(
   }
 }
 
+void TargetLibraryInfoImpl::addScalarFunctionsFromMathLib(
+    enum ScalarLibrary ScalarLib) {
+  setScalarMathLib(ScalarLib);
+  switch (ScalarLib) {
+  case ScalarLibrary::SCALAR_AMDLIBM: {
+    const DenseMap<StringRef, StringRef> ScalarAOCLFuncs = {
+#define TLI_DEFINE_SCALAR_AOCL_FUNCS
+#include "llvm/Analysis/ScalarAOCLFuncs.def"
+    };
+    LibScalarFunctions.insert(ScalarAOCLFuncs.begin(), ScalarAOCLFuncs.end());
+    break;
+  }
+  case ScalarLibrary::Default_Scalar_Library:
+    break;
+  }
+}
+
+void TargetLibraryInfoImpl::setScalarMathLib(enum ScalarLibrary ScalarLib) {
+  ScalarMathLib = ScalarLib;
+}
+
+StringRef TargetLibraryInfoImpl::getScalarFunctionFromMathLib(
+    StringRef ScalarFnName) const {
+  auto Iter = LibScalarFunctions.find(ScalarFnName);
+  if (Iter == LibScalarFunctions.end())
+    return StringRef();
+  return Iter->second;
+}
+
+TargetLibraryInfoImpl::ScalarLibrary
+TargetLibraryInfoImpl::getScalarMathLib() const {
+  return ScalarMathLib;
+}
+
 bool TargetLibraryInfoImpl::isFunctionVectorizable(StringRef funcName) const {
   funcName = sanitizeFunctionName(funcName);
   if (funcName.empty())
diff --git a/llvm/lib/Target/X86/CMakeLists.txt 
b/llvm/lib/Target/X86/CMakeLists.txt
index 62987bdbd1c2b..0c07e7c0c4b7f 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -56,6 +56,7 @@ set(sources
   X86FlagsCopyLowering.cpp
   X86FloatingPoint.cpp
   X86FrameLowering.cpp
+  X86GenScalarAmdFastCalls.cpp
   X86ISelDAGToDAG.cpp
   X86ISelLowering.cpp
   X86ISelLoweringCall.cpp
diff --git a/llvm/lib/Target/X86/X86.h b/llvm/lib/Target/X86/X86.h
index eef4de389a7de..e790a602e0f08 100644
--- a/llvm/lib/Target/X86/X86.h
+++ b/llvm/lib/Target/X86/X86.h
@@ -483,6 +483,12 @@ class X86ArgumentStackSlotPass
 
 FunctionPass *createX86ArgumentStackSlotLegacyPass();
 
+/// This pass rewrites scalar math library calls (e.g. tan) to their AMD AOCL
+/// fast-call equivalents (e.g. amd_fasttan) under fast-math semantics.
+FunctionPass *createX86GenScalarAmdFastCallsPass();
+void initializeX86GenScalarAmdFastCallsPass(PassRegistry &);
+extern char &X86GenScalarAmdFastCallsID;
+
 void initializeCompressEVEXLegacyPass(PassRegistry &);
 void initializeX86FixupBWInstLegacyPass(PassRegistry &);
 void initializeFixupLEAsLegacyPass(PassRegistry &);
diff --git a/llvm/lib/Target/X86/X86GenScalarAmdFastCalls.cpp 
b/llvm/lib/Target/X86/X86GenScalarAmdFastCalls.cpp
new file mode 100644
index 0000000000000..85544a2436c73
--- /dev/null
+++ b/llvm/lib/Target/X86/X86GenScalarAmdFastCalls.cpp
@@ -0,0 +1,176 @@
+//===-- X86GenScalarAmdFastCalls.cpp 
--------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This transformation converts standard scalar math function calls into their
+// corresponding AMD AOCL scalar library entries for X86 targets, e.g.:
+//     ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/213676
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to