[llvm] [TLI] Add getLibFunc that accepts an Opcode and scalar Type. (PR #75919)
Paschalis Mpeis via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 20 06:17:19 PST 2023
https://github.com/paschalis-mpeis updated https://github.com/llvm/llvm-project/pull/75919
>From d7262239928eb1c7e7de8b6fa8e420d51da9a15c 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 1/4] [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
>From 1c605cab2a161eee0e56c0d82480d18fcfbb2ed4 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Tue, 19 Dec 2023 11:51:13 +0000
Subject: [PATCH 2/4] Dropping FP128 as they are target specific.
---
llvm/lib/Analysis/TargetLibraryInfo.cpp | 2 --
llvm/unittests/Analysis/TargetLibraryInfoTest.cpp | 1 -
2 files changed, 3 deletions(-)
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index 4bc9db2db54258..bd238d29b689c4 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1158,8 +1158,6 @@ bool TargetLibraryInfoImpl::getLibFunc(const Instruction &I, LibFunc &F) const {
F = LibFunc_fmod;
else if (ScalarTy->isFloatTy())
F = LibFunc_fmodf;
- else if (ScalarTy->isFP128Ty())
- F = LibFunc_fmodl;
else
return false;
return true;
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index d4285092a58d3c..993556420e41ff 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -680,5 +680,4 @@ class TLITestAarch64ArmPl : public ::testing::Test {
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
>From e239e37772a12c9417e2140280f5550c3aec78e3 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Tue, 19 Dec 2023 17:52:22 +0000
Subject: [PATCH 3/4] Simplified code.
Test class:
- no longer using IRBuilder to create FRem instructions
- no need to use ArmPL vector library
---
llvm/lib/Analysis/TargetLibraryInfo.cpp | 8 ++--
.../Analysis/TargetLibraryInfoTest.cpp | 43 ++++++-------------
2 files changed, 15 insertions(+), 36 deletions(-)
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index bd238d29b689c4..b4e7a7e00be80c 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1154,12 +1154,10 @@ bool TargetLibraryInfoImpl::getLibFunc(const Instruction &I, LibFunc &F) const {
return false;
Type *ScalarTy = I.getType()->getScalarType();
- if (ScalarTy->isDoubleTy())
- F = LibFunc_fmod;
- else if (ScalarTy->isFloatTy())
- F = LibFunc_fmodf;
- else
+ if (!ScalarTy->isDoubleTy() && !ScalarTy->isFloatTy())
return false;
+
+ F = ScalarTy->isDoubleTy() ? LibFunc_fmod : LibFunc_fmodf;
return true;
}
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 993556420e41ff..2e33ce0c1123c8 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -8,7 +8,6 @@
#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"
@@ -625,59 +624,41 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
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 {
+/// Creates TLI for AArch64 and uses it to get the LibFunc names for the FRem
+/// Instruction.
+class TLITestAarch64 : 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) {
+ /// Create TLI for AArch64
+ TLITestAarch64() : TargetTriple(Triple("aarch64-unknown-linux-gnu")) {
TLII = std::make_unique<TargetLibraryInfoImpl>(
TargetLibraryInfoImpl(TargetTriple));
- TLII->addVectorizableFunctionsFromVecLib(VecLib, TargetTriple);
+ TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::NoLibrary,
+ 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.
+ Value *V = Constant::getNullValue(Ty);
+ Instruction *FRem = BinaryOperator::Create(Instruction::FRem, V, V);
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;
+ FRem->deleteValue();
+ return TLI->getName(Func);
}
};
} // end anonymous namespace
-TEST_F(TLITestAarch64ArmPl, TestFrem) {
+TEST_F(TLITestAarch64, TestFrem) {
EXPECT_EQ(getFremScalarName(Type::getDoubleTy(Ctx)), "fmod");
EXPECT_EQ(getFremScalarName(Type::getFloatTy(Ctx)), "fmodf");
}
\ No newline at end of file
>From 24617b5a3e99f563b38127e235f7bc66d6015e04 Mon Sep 17 00:00:00 2001
From: Paschalis Mpeis <Paschalis.Mpeis at arm.com>
Date: Wed, 20 Dec 2023 12:16:17 +0000
Subject: [PATCH 4/4] getLibFunc accepts an Opcode and a ScalarFTy.
---
llvm/include/llvm/Analysis/TargetLibraryInfo.h | 14 +++++++-------
llvm/lib/Analysis/TargetLibraryInfo.cpp | 11 +++++------
llvm/unittests/Analysis/TargetLibraryInfoTest.cpp | 4 +---
3 files changed, 13 insertions(+), 16 deletions(-)
diff --git a/llvm/include/llvm/Analysis/TargetLibraryInfo.h b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
index bd77d1e8285626..f3bb2526fafd18 100644
--- a/llvm/include/llvm/Analysis/TargetLibraryInfo.h
+++ b/llvm/include/llvm/Analysis/TargetLibraryInfo.h
@@ -156,9 +156,9 @@ 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;
+ /// Searches for a function name using an Instruction \p Opcode.
+ /// Currently, only the frem instruction is supported.
+ bool getLibFunc(unsigned int Opcode, Type *ScalarTy, LibFunc &F) const;
/// Forces a function to be marked as unavailable.
void setUnavailable(LibFunc F) {
@@ -364,10 +364,10 @@ 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);
+ /// Searches for a function name using an Instruction \p Opcode.
+ /// Currently, only the frem instruction is supported.
+ bool getLibFunc(unsigned int Opcode, Type *ScalarTy, LibFunc &F) const {
+ return Impl->getLibFunc(Opcode, ScalarTy, F);
}
/// Disables all builtins.
diff --git a/llvm/lib/Analysis/TargetLibraryInfo.cpp b/llvm/lib/Analysis/TargetLibraryInfo.cpp
index b4e7a7e00be80c..018d16347a7bfd 100644
--- a/llvm/lib/Analysis/TargetLibraryInfo.cpp
+++ b/llvm/lib/Analysis/TargetLibraryInfo.cpp
@@ -1149,12 +1149,11 @@ 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() && !ScalarTy->isFloatTy())
+bool TargetLibraryInfoImpl::getLibFunc(unsigned int Opcode, Type *ScalarTy,
+ LibFunc &F) const {
+ // Must be a double or a float frem instruction.
+ if (Opcode != Instruction::FRem ||
+ (!ScalarTy->isDoubleTy() && !ScalarTy->isFloatTy()))
return false;
F = ScalarTy->isDoubleTy() ? LibFunc_fmod : LibFunc_fmodf;
diff --git a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
index 2e33ce0c1123c8..18686846236449 100644
--- a/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
+++ b/llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
@@ -639,8 +639,6 @@ class TLITestAarch64 : public ::testing::Test {
TLITestAarch64() : TargetTriple(Triple("aarch64-unknown-linux-gnu")) {
TLII = std::make_unique<TargetLibraryInfoImpl>(
TargetLibraryInfoImpl(TargetTriple));
- TLII->addVectorizableFunctionsFromVecLib(TargetLibraryInfoImpl::NoLibrary,
- TargetTriple);
TLI = std::make_unique<TargetLibraryInfo>(TargetLibraryInfo(*TLII));
}
@@ -650,7 +648,7 @@ class TLITestAarch64 : public ::testing::Test {
Value *V = Constant::getNullValue(Ty);
Instruction *FRem = BinaryOperator::Create(Instruction::FRem, V, V);
LibFunc Func;
- if (!TLI->getLibFunc(*FRem, Func))
+ if (!TLI->getLibFunc(FRem->getOpcode(), FRem->getType(), Func))
return "";
FRem->deleteValue();
return TLI->getName(Func);
More information about the llvm-commits
mailing list