[llvm] [TLI] Add getLibFunc in TLI API that accepts an Instruction. (PR #75919)

Paschalis Mpeis via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 02:25:32 PST 2023


https://github.com/paschalis-mpeis created https://github.com/llvm/llvm-project/pull/75919

It sets a LibFunc similarly with the other two getLibFunc methods. Currently, it supports only the FRem Instruction.

Add tests for FRem.

>From f00bc4e59dd4ec90b9eff78b9e4eecdc30b3dd92 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Tue, 19 Dec 2023 09:58:57 +0000
Subject: [PATCH] [TLI] Add getLibFunc in API that accepts an Instruction.

It sets a LibFunc similarly with the other two getLibFunc methods.
Currently, it supports only the FRem Instruction.

Add tests for FRem.
---
 .../include/llvm/Analysis/TargetLibraryInfo.h | 10 +++
 llvm/lib/Analysis/TargetLibraryInfo.cpp       | 16 +++++
 .../Analysis/TargetLibraryInfoTest.cpp        | 61 +++++++++++++++++++
 3 files changed, 87 insertions(+)

diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index 2ffd4d4b714394..bd77d1e8285626 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -156,6 +156,10 @@ class TargetLibraryInfoImpl {
   /// FDecl is assumed to have a parent Module when using this function.
   bool getLibFunc(const Function &FDecl, LibFunc &F) const;
 
+  /// Searches for a function name using the opcode of \p I. Currently, only the
+  /// frem instruction is supported.
+  bool getLibFunc(const Instruction &I, LibFunc &F) const;
+
   /// Forces a function to be marked as unavailable.
   void setUnavailable(LibFunc F) {
     setState(F, Unavailable);
@@ -360,6 +364,12 @@ class TargetLibraryInfo {
            getLibFunc(*(CB.getCalledFunction()), F);
   }
 
+  /// Searches for a function name using the opcode of \p I. Currently, only the
+  /// frem instruction is supported.
+  bool getLibFunc(const Instruction &I, LibFunc &F) const {
+    return Impl->getLibFunc(I, F);
+  }
+
   /// Disables all builtins.
   ///
   /// This can be used for options like -fno-builtin.
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 20959cf6948f65..4bc9db2db54258 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1149,6 +1149,22 @@ bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl,
   return isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M);
 }
 
+bool TargetLibraryInfoImpl::getLibFunc(const Instruction &I, LibFunc &F) const {
+  if (I.getOpcode() != Instruction::FRem)
+    return false;
+
+  Type *ScalarTy = I.getType()->getScalarType();
+  if (ScalarTy->isDoubleTy())
+    F = LibFunc_fmod;
+  else if (ScalarTy->isFloatTy())
+    F = LibFunc_fmodf;
+  else if (ScalarTy->isFP128Ty())
+    F = LibFunc_fmodl;
+  else
+    return false;
+  return true;
+}
+
 void TargetLibraryInfoImpl::disableAllFunctions() {
   memset(AvailableArray, 0, sizeof(AvailableArray));
 }
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 292b5cade9509b..d4285092a58d3c 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -8,6 +8,7 @@
 
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/AsmParser/Parser.h"
+#include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/LLVMContext.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/SourceMgr.h"
@@ -621,3 +622,63 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
     EXPECT_TRUE(isLibFunc(F, LF));
   }
 }
+
+namespace {
+
+// Creates TLI for AArch64 and VecLibrary ARmPL, and uses it to get the TLI
+// names for different FRem Instructions.
+class TLITestAarch64ArmPl : public ::testing::Test {
+private:
+  SMDiagnostic Err;
+  const Triple TargetTriple;
+  const TargetLibraryInfoImpl::VectorLibrary VecLib;
+
+protected:
+  LLVMContext Ctx;
+  std::unique_ptr<Module> M;
+  std::unique_ptr<TargetLibraryInfoImpl> TLII;
+  std::unique_ptr<TargetLibraryInfo> TLI;
+
+  /// Create TLI for AArch64 with VecLib ArmPL.
+  TLITestAarch64ArmPl()
+      : TargetTriple(Triple("aarch64-unknown-linux-gnu")),
+        VecLib(TargetLibraryInfoImpl::ArmPL) {
+    TLII = std::make_unique<TargetLibraryInfoImpl>(
+        TargetLibraryInfoImpl(TargetTriple));
+    TLII->addVectorizableFunctionsFromVecLib(VecLib, TargetTriple);
+    TLI = std::make_unique<TargetLibraryInfo>(TargetLibraryInfo(*TLII));
+    // Create a dummy module needed for tests.
+    M = parseAssemblyString("declare void @dummy()", Err, Ctx);
+    EXPECT_NE(M.get(), nullptr)
+        << "Loading an invalid module.\n " << Err.getMessage() << "\n";
+  }
+
+  /// Creates an FRem Instruction of Type \p Ty, and uses it to get the TLI
+  /// function name.
+  StringRef getFremScalarName(Type *Ty) {
+    // Use a dummy function and a BB to create an FRem Instruction.
+    FunctionType *FTy = FunctionType::get(Ty, {Ty, Ty}, false);
+    Function *F = Function::Create(FTy, Function::ExternalLinkage, "foo", *M);
+    BasicBlock *BB = BasicBlock::Create(Ctx, "entry", F);
+    IRBuilder<> Builder(BB);
+    Builder.SetInsertPoint(BB);
+    auto *FRem =
+        dyn_cast<Instruction>(Builder.CreateFRem(F->getArg(0), F->getArg(1)));
+
+    // Use TLI to get LibFunc and then the TLI name.
+    LibFunc Func;
+    if (!TLI->getLibFunc(*FRem, Func))
+      return "";
+    auto FuncName = TLI->getName(Func);
+    // Erase tmp function to prepare for the next test.
+    F->eraseFromParent();
+    return FuncName;
+  }
+};
+} // end anonymous namespace
+
+TEST_F(TLITestAarch64ArmPl, TestFrem) {
+  EXPECT_EQ(getFremScalarName(Type::getDoubleTy(Ctx)), "fmod");
+  EXPECT_EQ(getFremScalarName(Type::getFloatTy(Ctx)), "fmodf");
+  EXPECT_EQ(getFremScalarName(Type::getFP128Ty(Ctx)), "fmodl");
+}
\ No newline at end of file



More information about the llvm-commits mailing list