Fix test failures introduced by PR #113697 (#116941)
[llvm-project.git] / llvm / unittests / Analysis / ReplaceWithVecLibTest.cpp
blobd97549cb69d556dd83c29ac945ca65eecbf49ba6
1 //===--- ReplaceWithVecLibTest.cpp - replace-with-veclib unit tests -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "llvm/CodeGen/ReplaceWithVeclib.h"
10 #include "llvm/Analysis/TargetLibraryInfo.h"
11 #include "llvm/AsmParser/Parser.h"
12 #include "llvm/IR/LLVMContext.h"
13 #include "llvm/IR/Module.h"
14 #include "llvm/Passes/PassBuilder.h"
15 #include "llvm/Support/SourceMgr.h"
16 #include "gtest/gtest.h"
18 using namespace llvm;
20 /// NOTE: Assertions must be enabled for these tests to run.
21 #ifndef NDEBUG
23 namespace {
25 static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
26 SMDiagnostic Err;
27 std::unique_ptr<Module> Mod = parseAssemblyString(IR, Err, C);
28 if (!Mod)
29 Err.print("ReplaceWithVecLibTest", errs());
30 return Mod;
33 /// Runs ReplaceWithVecLib with different TLIIs that have custom VecDescs. This
34 /// allows checking that the pass won't crash when the function to replace (from
35 /// the input IR) does not match the replacement function (derived from the
36 /// VecDesc mapping).
37 ///
38 class ReplaceWithVecLibTest : public ::testing::Test {
40 std::string getLastLine(std::string Out) {
41 // remove any trailing '\n'
42 if (!Out.empty() && *(Out.cend() - 1) == '\n')
43 Out.pop_back();
45 size_t LastNL = Out.find_last_of('\n');
46 return (LastNL == std::string::npos) ? Out : Out.substr(LastNL + 1);
49 protected:
50 LLVMContext Ctx;
52 /// Creates TLII using the given \p VD, and then runs the ReplaceWithVeclib
53 /// pass. The pass should not crash even when the replacement function
54 /// (derived from the \p VD mapping) does not match the function to be
55 /// replaced (from the input \p IR).
56 ///
57 /// \returns the last line of the standard error to be compared for
58 /// correctness.
59 std::string run(const VecDesc &VD, const char *IR) {
60 // Create TLII and register it with FAM so it's preserved when
61 // ReplaceWithVeclib pass runs.
62 TargetLibraryInfoImpl TLII = TargetLibraryInfoImpl(Triple());
63 TLII.addVectorizableFunctions({VD});
64 FunctionAnalysisManager FAM;
65 FAM.registerPass([&TLII]() { return TargetLibraryAnalysis(TLII); });
67 // Register and run the pass on the 'foo' function from the input IR.
68 FunctionPassManager FPM;
69 FPM.addPass(ReplaceWithVeclib());
70 std::unique_ptr<Module> M = parseIR(Ctx, IR);
71 PassBuilder PB;
72 PB.registerFunctionAnalyses(FAM);
74 // Enable debugging and capture std error
75 bool DebugFlagPrev = llvm::DebugFlag;
76 llvm::DebugFlag = true;
77 testing::internal::CaptureStderr();
78 FPM.run(*M->getFunction("foo"), FAM);
79 llvm::DebugFlag = DebugFlagPrev;
80 return getLastLine(testing::internal::GetCapturedStderr());
84 } // end anonymous namespace
86 static const char *IR = R"IR(
87 define <vscale x 4 x float> @foo(<vscale x 4 x float> %in){
88 %call = call <vscale x 4 x float> @llvm.powi.f32.i32(<vscale x 4 x float> %in, i32 3)
89 ret <vscale x 4 x float> %call
92 declare <vscale x 4 x float> @llvm.powi.f32.i32(<vscale x 4 x float>, i32) #0
93 )IR";
95 // The VFABI prefix in TLI describes signature which is matching the powi
96 // intrinsic declaration.
97 TEST_F(ReplaceWithVecLibTest, TestValidMapping) {
98 VecDesc CorrectVD = {"llvm.powi.f32.i32", "_ZGVsMxvu_powi",
99 ElementCount::getScalable(4), /*Masked*/ true,
100 "_ZGVsMxvu"};
101 EXPECT_EQ(run(CorrectVD, IR),
102 "Intrinsic calls replaced with vector libraries: 1");
105 // The VFABI prefix in TLI describes signature which is not matching the powi
106 // intrinsic declaration.
107 TEST_F(ReplaceWithVecLibTest, TestInvalidMapping) {
108 VecDesc IncorrectVD = {"llvm.powi.f32.i32", "_ZGVsMxvv_powi",
109 ElementCount::getScalable(4), /*Masked*/ true,
110 "_ZGVsMxvv"};
111 EXPECT_EQ(run(IncorrectVD, IR),
112 "replace-with-veclib: Will not replace: llvm.powi.f32.i32. Wrong "
113 "type at index 1: i32");
115 #endif