[llvm] [TLI] Add getLibFunc in TLI API that accepts an Instruction. (PR #75919)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 19 02:26:02 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-analysis
Author: Paschalis Mpeis (paschalis-mpeis)
<details>
<summary>Changes</summary>
It sets a LibFunc similarly with the other two getLibFunc methods. Currently, it supports only the FRem Instruction.
Add tests for FRem.
---
Full diff: https://github.com/llvm/llvm-project/pull/75919.diff
3 Files Affected:
- (modified) llvm/include/llvm/Analysis/TargetLibraryInfo.h (+10)
- (modified) llvm/lib/Analysis/TargetLibraryInfo.cpp (+16)
- (modified) llvm/unittests/Analysis/TargetLibraryInfoTest.cpp (+61)
``````````diff
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
``````````
</details>
https://github.com/llvm/llvm-project/pull/75919
More information about the llvm-commits
mailing list