Skip to content
5 changes: 4 additions & 1 deletion llvm/lib/CodeGen/ReplaceWithVeclib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ static bool replaceWithCallToVeclib(const TargetLibraryInfo &TLI,
Type *OrigTy = CI->getArgOperand(VFParam.ParamPos)->getType();
if (OrigTy->isVectorTy() != (VFParam.ParamKind == VFParamKind::Vector)) {
LLVM_DEBUG(dbgs() << DEBUG_TYPE
<< ": Will not replace: wrong type at index: "
<< ": Will not replace. Wrong type at index "
<< VFParam.ParamPos << ": " << *OrigTy << "\n");
return false;
}
Expand Down Expand Up @@ -245,6 +245,9 @@ PreservedAnalyses ReplaceWithVeclib::run(Function &F,
const TargetLibraryInfo &TLI = AM.getResult<TargetLibraryAnalysis>(F);
auto Changed = runImpl(TLI, F);
if (Changed) {
LLVM_DEBUG(dbgs() << "Instructions replaced with vector libraries: "
<< NumCallsReplaced << "\n");

PreservedAnalyses PA;
PA.preserveSet<CFGAnalyses>();
PA.preserve<TargetLibraryAnalysis>();
Expand Down
29 changes: 24 additions & 5 deletions llvm/unittests/Analysis/ReplaceWithVecLibTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,27 @@ static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
/// the input IR) does not match the replacement function (derived from the
/// VecDesc mapping).
class ReplaceWithVecLibTest : public ::testing::Test {

std::string getLastLine(std::string Out) {
// remove ending '\n' if it exists
if (!Out.empty() && *(Out.cend() - 1) == '\n')
Out.pop_back();

size_t LastNL = Out.find_last_of('\n');
return (LastNL == std::string::npos) ? Out : Out.substr(LastNL + 1);
}

protected:
LLVMContext Ctx;

/// Creates TLII using the given \p VD, and then runs the ReplaceWithVeclib
/// pass. The pass should not crash even when the replacement function
/// (derived from the \p VD mapping) does not match the function to be
/// replaced (from the input \p IR).
bool run(const VecDesc &VD, const char *IR) {
///
/// \returns the last line of the standard error to be compared for
/// correctness.
std::string run(const VecDesc &VD, const char *IR) {
// Create TLII and register it with FAM so it's preserved when
// ReplaceWithVeclib pass runs.
TargetLibraryInfoImpl TLII = TargetLibraryInfoImpl(Triple());
Expand All @@ -53,9 +66,12 @@ class ReplaceWithVecLibTest : public ::testing::Test {
std::unique_ptr<Module> M = parseIR(Ctx, IR);
PassBuilder PB;
PB.registerFunctionAnalyses(FAM);
FPM.run(*M->getFunction("foo"), FAM);

return true;
// Enable debugging and capture std error
llvm::DebugFlag = true;
testing::internal::CaptureStderr();
FPM.run(*M->getFunction("foo"), FAM);
return getLastLine(testing::internal::GetCapturedStderr());
}
};

Expand All @@ -76,7 +92,8 @@ TEST_F(ReplaceWithVecLibTest, TestValidMapping) {
VecDesc CorrectVD = {"llvm.powi.f32.i32", "_ZGVsMxvu_powi",
ElementCount::getScalable(4), /*Masked*/ true,
"_ZGVsMxvu"};
EXPECT_TRUE(run(CorrectVD, IR));
EXPECT_EQ(run(CorrectVD, IR),
"Instructions replaced with vector libraries: 1");
}

// The VFABI prefix in TLI describes signature which is not matching the powi
Expand All @@ -85,5 +102,7 @@ TEST_F(ReplaceWithVecLibTest, TestInvalidMapping) {
VecDesc IncorrectVD = {"llvm.powi.f32.i32", "_ZGVsMxvv_powi",
ElementCount::getScalable(4), /*Masked*/ true,
"_ZGVsMxvv"};
EXPECT_TRUE(run(IncorrectVD, IR));
EXPECT_EQ(
run(IncorrectVD, IR),
"replace-with-veclib: Will not replace. Wrong type at index 1: i32");
}