Skip to content

[TLI] Add getLibFunc that accepts an Opcode and scalar Type. #75919

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions llvm/include/llvm/Analysis/TargetLibraryInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 an Instruction \p Opcode.
/// Currently, only the frem instruction is supported.
bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const;

/// Forces a function to be marked as unavailable.
void setUnavailable(LibFunc F) {
setState(F, Unavailable);
Expand Down Expand Up @@ -360,6 +364,12 @@ class TargetLibraryInfo {
getLibFunc(*(CB.getCalledFunction()), F);
}

/// Searches for a function name using an Instruction \p Opcode.
/// Currently, only the frem instruction is supported.
bool getLibFunc(unsigned int Opcode, Type *Ty, LibFunc &F) const {
return Impl->getLibFunc(Opcode, Ty, F);
}

/// Disables all builtins.
///
/// This can be used for options like -fno-builtin.
Expand Down
10 changes: 10 additions & 0 deletions llvm/lib/Analysis/TargetLibraryInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,16 @@ bool TargetLibraryInfoImpl::getLibFunc(const Function &FDecl,
return isValidProtoForLibFunc(*FDecl.getFunctionType(), F, *M);
}

bool TargetLibraryInfoImpl::getLibFunc(unsigned int Opcode, Type *Ty,
LibFunc &F) const {
// Must be a frem instruction with float or double arguments.
if (Opcode != Instruction::FRem || (!Ty->isDoubleTy() && !Ty->isFloatTy()))
return false;

F = Ty->isDoubleTy() ? LibFunc_fmod : LibFunc_fmodf;
return true;
}

void TargetLibraryInfoImpl::disableAllFunctions() {
memset(AvailableArray, 0, sizeof(AvailableArray));
}
Expand Down
35 changes: 35 additions & 0 deletions llvm/unittests/Analysis/TargetLibraryInfoTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,38 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
EXPECT_TRUE(isLibFunc(F, LF));
}
}

namespace {

/// Creates TLI for AArch64 and uses it to get the LibFunc names for the given
/// Instruction opcode and Type.
class TLITestAarch64 : public ::testing::Test {
private:
const Triple TargetTriple;

protected:
LLVMContext Ctx;
std::unique_ptr<TargetLibraryInfoImpl> TLII;
std::unique_ptr<TargetLibraryInfo> TLI;

/// Create TLI for AArch64
TLITestAarch64() : TargetTriple(Triple("aarch64-unknown-linux-gnu")) {
TLII = std::make_unique<TargetLibraryInfoImpl>(
TargetLibraryInfoImpl(TargetTriple));
TLI = std::make_unique<TargetLibraryInfo>(TargetLibraryInfo(*TLII));
}

/// Returns the TLI function name for the given \p Opcode and type \p Ty.
StringRef getScalarName(unsigned int Opcode, Type *Ty) {
LibFunc Func;
if (!TLI->getLibFunc(Opcode, Ty, Func))
return "";
return TLI->getName(Func);
}
};
} // end anonymous namespace

TEST_F(TLITestAarch64, TestFrem) {
EXPECT_EQ(getScalarName(Instruction::FRem, Type::getDoubleTy(Ctx)), "fmod");
EXPECT_EQ(getScalarName(Instruction::FRem, Type::getFloatTy(Ctx)), "fmodf");
}