xref: /llvm-project/llvm/unittests/SandboxIR/PassTest.cpp (revision 4b209c5d87c8b8eb4bbf2750ea9daa5927a13699)
1f12e10b5Svporpo //===- PassTest.cpp -------------------------------------------------------===//
2f12e10b5Svporpo //
3f12e10b5Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f12e10b5Svporpo // See https://llvm.org/LICENSE.txt for license information.
5f12e10b5Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f12e10b5Svporpo //
7f12e10b5Svporpo //===----------------------------------------------------------------------===//
8f12e10b5Svporpo 
9f12e10b5Svporpo #include "llvm/SandboxIR/Pass.h"
10*4b209c5dSvporpo #include "llvm/Analysis/TargetTransformInfo.h"
11f12e10b5Svporpo #include "llvm/AsmParser/Parser.h"
12f12e10b5Svporpo #include "llvm/IR/Module.h"
132018f4ccSVasileios Porpodas #include "llvm/SandboxIR/Constant.h"
142018f4ccSVasileios Porpodas #include "llvm/SandboxIR/Context.h"
15e22b07e7Svporpo #include "llvm/SandboxIR/Function.h"
163363760fSvporpo #include "llvm/SandboxIR/PassManager.h"
17f35c213cSJorge Gorbe Moya #include "llvm/SandboxIR/Region.h"
18f12e10b5Svporpo #include "llvm/Support/SourceMgr.h"
19f12e10b5Svporpo #include "gtest/gtest.h"
20f12e10b5Svporpo 
21f12e10b5Svporpo using namespace llvm::sandboxir;
22f12e10b5Svporpo 
23f12e10b5Svporpo struct PassTest : public testing::Test {
24f12e10b5Svporpo   llvm::LLVMContext LLVMCtx;
25f12e10b5Svporpo   std::unique_ptr<llvm::Module> LLVMM;
26f12e10b5Svporpo   std::unique_ptr<Context> Ctx;
27*4b209c5dSvporpo   std::unique_ptr<llvm::TargetTransformInfo> TTI;
28f12e10b5Svporpo 
29f12e10b5Svporpo   Function *parseFunction(const char *IR, const char *FuncName) {
30f12e10b5Svporpo     llvm::SMDiagnostic Err;
31f12e10b5Svporpo     LLVMM = parseAssemblyString(IR, Err, LLVMCtx);
32*4b209c5dSvporpo     TTI = std::make_unique<llvm::TargetTransformInfo>(LLVMM->getDataLayout());
33*4b209c5dSvporpo 
34f12e10b5Svporpo     if (!LLVMM)
35f12e10b5Svporpo       Err.print("PassTest", llvm::errs());
36f12e10b5Svporpo     Ctx = std::make_unique<Context>(LLVMCtx);
37f12e10b5Svporpo     return Ctx->createFunction(LLVMM->getFunction(FuncName));
38f12e10b5Svporpo   }
39f12e10b5Svporpo };
40f12e10b5Svporpo 
41f12e10b5Svporpo TEST_F(PassTest, FunctionPass) {
42f12e10b5Svporpo   auto *F = parseFunction(R"IR(
43f12e10b5Svporpo define void @foo() {
44f12e10b5Svporpo   ret void
45f12e10b5Svporpo }
46f12e10b5Svporpo )IR",
47f12e10b5Svporpo                           "foo");
48f12e10b5Svporpo   class TestPass final : public FunctionPass {
49f12e10b5Svporpo     unsigned &BBCnt;
50f12e10b5Svporpo 
51f12e10b5Svporpo   public:
52f12e10b5Svporpo     TestPass(unsigned &BBCnt) : FunctionPass("test-pass"), BBCnt(BBCnt) {}
53a461869dSvporpo     bool runOnFunction(Function &F, const Analyses &A) final {
54f12e10b5Svporpo       for ([[maybe_unused]] auto &BB : F)
55f12e10b5Svporpo         ++BBCnt;
56f12e10b5Svporpo       return false;
57f12e10b5Svporpo     }
58f12e10b5Svporpo   };
59f12e10b5Svporpo   unsigned BBCnt = 0;
60f12e10b5Svporpo   TestPass TPass(BBCnt);
61f12e10b5Svporpo   // Check getName(),
62f12e10b5Svporpo   EXPECT_EQ(TPass.getName(), "test-pass");
63f12e10b5Svporpo   // Check classof().
64f12e10b5Svporpo   EXPECT_TRUE(llvm::isa<FunctionPass>(TPass));
65f12e10b5Svporpo   // Check runOnFunction();
66a461869dSvporpo   TPass.runOnFunction(*F, Analyses::emptyForTesting());
67f12e10b5Svporpo   EXPECT_EQ(BBCnt, 1u);
68f12e10b5Svporpo #ifndef NDEBUG
69f12e10b5Svporpo   {
70f12e10b5Svporpo     // Check print().
71f12e10b5Svporpo     std::string Buff;
72f12e10b5Svporpo     llvm::raw_string_ostream SS(Buff);
73f12e10b5Svporpo     TPass.print(SS);
74f12e10b5Svporpo     EXPECT_EQ(Buff, "test-pass");
75f12e10b5Svporpo   }
76f12e10b5Svporpo   {
77f12e10b5Svporpo     // Check operator<<().
78f12e10b5Svporpo     std::string Buff;
79f12e10b5Svporpo     llvm::raw_string_ostream SS(Buff);
80f12e10b5Svporpo     SS << TPass;
81f12e10b5Svporpo     EXPECT_EQ(Buff, "test-pass");
82f12e10b5Svporpo   }
83f12e10b5Svporpo   // Check pass name assertions.
84f12e10b5Svporpo   class TestNamePass final : public FunctionPass {
85f12e10b5Svporpo   public:
86f12e10b5Svporpo     TestNamePass(llvm::StringRef Name) : FunctionPass(Name) {}
87a461869dSvporpo     bool runOnFunction(Function &F, const Analyses &A) { return false; }
88f12e10b5Svporpo   };
89f12e10b5Svporpo   EXPECT_DEATH(TestNamePass("white space"), ".*whitespace.*");
90f12e10b5Svporpo   EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
91f12e10b5Svporpo #endif
92f12e10b5Svporpo }
933363760fSvporpo 
94f35c213cSJorge Gorbe Moya TEST_F(PassTest, RegionPass) {
95f35c213cSJorge Gorbe Moya   auto *F = parseFunction(R"IR(
96f35c213cSJorge Gorbe Moya define i8 @foo(i8 %v0, i8 %v1) {
97f35c213cSJorge Gorbe Moya   %t0 = add i8 %v0, 1
98f35c213cSJorge Gorbe Moya   %t1 = add i8 %t0, %v1, !sandboxvec !0
99f35c213cSJorge Gorbe Moya   %t2 = add i8 %t1, %v1, !sandboxvec !0
100f35c213cSJorge Gorbe Moya   ret i8 %t1
101f35c213cSJorge Gorbe Moya }
102f35c213cSJorge Gorbe Moya 
103f35c213cSJorge Gorbe Moya !0 = distinct !{!"sandboxregion"}
104f35c213cSJorge Gorbe Moya )IR",
105f35c213cSJorge Gorbe Moya                           "foo");
106f35c213cSJorge Gorbe Moya 
107f35c213cSJorge Gorbe Moya   class TestPass final : public RegionPass {
108f35c213cSJorge Gorbe Moya     unsigned &InstCount;
109f35c213cSJorge Gorbe Moya 
110f35c213cSJorge Gorbe Moya   public:
111f35c213cSJorge Gorbe Moya     TestPass(unsigned &InstCount)
112f35c213cSJorge Gorbe Moya         : RegionPass("test-pass"), InstCount(InstCount) {}
113a461869dSvporpo     bool runOnRegion(Region &R, const Analyses &A) final {
114f35c213cSJorge Gorbe Moya       for ([[maybe_unused]] auto &Inst : R) {
115f35c213cSJorge Gorbe Moya         ++InstCount;
116f35c213cSJorge Gorbe Moya       }
117f35c213cSJorge Gorbe Moya       return false;
118f35c213cSJorge Gorbe Moya     }
119f35c213cSJorge Gorbe Moya   };
120f35c213cSJorge Gorbe Moya   unsigned InstCount = 0;
121f35c213cSJorge Gorbe Moya   TestPass TPass(InstCount);
122f35c213cSJorge Gorbe Moya   // Check getName(),
123f35c213cSJorge Gorbe Moya   EXPECT_EQ(TPass.getName(), "test-pass");
124f35c213cSJorge Gorbe Moya   // Check runOnRegion();
125f35c213cSJorge Gorbe Moya   llvm::SmallVector<std::unique_ptr<Region>> Regions =
126*4b209c5dSvporpo       Region::createRegionsFromMD(*F, *TTI);
127f35c213cSJorge Gorbe Moya   ASSERT_EQ(Regions.size(), 1u);
128a461869dSvporpo   TPass.runOnRegion(*Regions[0], Analyses::emptyForTesting());
129f35c213cSJorge Gorbe Moya   EXPECT_EQ(InstCount, 2u);
130f35c213cSJorge Gorbe Moya #ifndef NDEBUG
131f35c213cSJorge Gorbe Moya   {
132f35c213cSJorge Gorbe Moya     // Check print().
133f35c213cSJorge Gorbe Moya     std::string Buff;
134f35c213cSJorge Gorbe Moya     llvm::raw_string_ostream SS(Buff);
135f35c213cSJorge Gorbe Moya     TPass.print(SS);
136f35c213cSJorge Gorbe Moya     EXPECT_EQ(Buff, "test-pass");
137f35c213cSJorge Gorbe Moya   }
138f35c213cSJorge Gorbe Moya   {
139f35c213cSJorge Gorbe Moya     // Check operator<<().
140f35c213cSJorge Gorbe Moya     std::string Buff;
141f35c213cSJorge Gorbe Moya     llvm::raw_string_ostream SS(Buff);
142f35c213cSJorge Gorbe Moya     SS << TPass;
143f35c213cSJorge Gorbe Moya     EXPECT_EQ(Buff, "test-pass");
144f35c213cSJorge Gorbe Moya   }
145f35c213cSJorge Gorbe Moya   // Check pass name assertions.
146f35c213cSJorge Gorbe Moya   class TestNamePass final : public RegionPass {
147f35c213cSJorge Gorbe Moya   public:
148f35c213cSJorge Gorbe Moya     TestNamePass(llvm::StringRef Name) : RegionPass(Name) {}
149a461869dSvporpo     bool runOnRegion(Region &F, const Analyses &A) { return false; }
150f35c213cSJorge Gorbe Moya   };
151f35c213cSJorge Gorbe Moya   EXPECT_DEATH(TestNamePass("white space"), ".*whitespace.*");
152f35c213cSJorge Gorbe Moya   EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
153f35c213cSJorge Gorbe Moya #endif
154f35c213cSJorge Gorbe Moya }
155f35c213cSJorge Gorbe Moya 
1563363760fSvporpo TEST_F(PassTest, FunctionPassManager) {
1573363760fSvporpo   auto *F = parseFunction(R"IR(
1583363760fSvporpo define void @foo() {
1593363760fSvporpo   ret void
1603363760fSvporpo }
1613363760fSvporpo )IR",
1623363760fSvporpo                           "foo");
1633363760fSvporpo   class TestPass1 final : public FunctionPass {
1643363760fSvporpo     unsigned &BBCnt;
1653363760fSvporpo 
1663363760fSvporpo   public:
1673363760fSvporpo     TestPass1(unsigned &BBCnt) : FunctionPass("test-pass1"), BBCnt(BBCnt) {}
168a461869dSvporpo     bool runOnFunction(Function &F, const Analyses &A) final {
1693363760fSvporpo       for ([[maybe_unused]] auto &BB : F)
1703363760fSvporpo         ++BBCnt;
1713363760fSvporpo       return false;
1723363760fSvporpo     }
1733363760fSvporpo   };
1743363760fSvporpo   class TestPass2 final : public FunctionPass {
1753363760fSvporpo     unsigned &BBCnt;
1763363760fSvporpo 
1773363760fSvporpo   public:
1783363760fSvporpo     TestPass2(unsigned &BBCnt) : FunctionPass("test-pass2"), BBCnt(BBCnt) {}
179a461869dSvporpo     bool runOnFunction(Function &F, const Analyses &A) final {
1803363760fSvporpo       for ([[maybe_unused]] auto &BB : F)
1813363760fSvporpo         ++BBCnt;
1823363760fSvporpo       return false;
1833363760fSvporpo     }
1843363760fSvporpo   };
1853363760fSvporpo   unsigned BBCnt1 = 0;
1863363760fSvporpo   unsigned BBCnt2 = 0;
1873363760fSvporpo 
1883363760fSvporpo   FunctionPassManager FPM("test-fpm");
189756ec99cSJorge Gorbe Moya   FPM.addPass(std::make_unique<TestPass1>(BBCnt1));
190756ec99cSJorge Gorbe Moya   FPM.addPass(std::make_unique<TestPass2>(BBCnt2));
1913363760fSvporpo   // Check runOnFunction().
192a461869dSvporpo   FPM.runOnFunction(*F, Analyses::emptyForTesting());
1933363760fSvporpo   EXPECT_EQ(BBCnt1, 1u);
1943363760fSvporpo   EXPECT_EQ(BBCnt2, 1u);
1953363760fSvporpo #ifndef NDEBUG
1963363760fSvporpo   // Check dump().
1973363760fSvporpo   std::string Buff;
1983363760fSvporpo   llvm::raw_string_ostream SS(Buff);
1993363760fSvporpo   FPM.print(SS);
2003363760fSvporpo   EXPECT_EQ(Buff, "test-fpm(test-pass1,test-pass2)");
2013363760fSvporpo #endif // NDEBUG
2023363760fSvporpo }
2032ddf21bcSvporpo 
204f35c213cSJorge Gorbe Moya TEST_F(PassTest, RegionPassManager) {
205f35c213cSJorge Gorbe Moya   auto *F = parseFunction(R"IR(
206f35c213cSJorge Gorbe Moya define i8 @foo(i8 %v0, i8 %v1) {
207f35c213cSJorge Gorbe Moya   %t0 = add i8 %v0, 1
208f35c213cSJorge Gorbe Moya   %t1 = add i8 %t0, %v1, !sandboxvec !0
209f35c213cSJorge Gorbe Moya   %t2 = add i8 %t1, %v1, !sandboxvec !0
210f35c213cSJorge Gorbe Moya   ret i8 %t1
211f35c213cSJorge Gorbe Moya }
212f35c213cSJorge Gorbe Moya 
213f35c213cSJorge Gorbe Moya !0 = distinct !{!"sandboxregion"}
214f35c213cSJorge Gorbe Moya )IR",
215f35c213cSJorge Gorbe Moya                           "foo");
216f35c213cSJorge Gorbe Moya 
217f35c213cSJorge Gorbe Moya   class TestPass1 final : public RegionPass {
218f35c213cSJorge Gorbe Moya     unsigned &InstCount;
219f35c213cSJorge Gorbe Moya 
220f35c213cSJorge Gorbe Moya   public:
221f35c213cSJorge Gorbe Moya     TestPass1(unsigned &InstCount)
222f35c213cSJorge Gorbe Moya         : RegionPass("test-pass1"), InstCount(InstCount) {}
223a461869dSvporpo     bool runOnRegion(Region &R, const Analyses &A) final {
224f35c213cSJorge Gorbe Moya       for ([[maybe_unused]] auto &Inst : R)
225f35c213cSJorge Gorbe Moya         ++InstCount;
226f35c213cSJorge Gorbe Moya       return false;
227f35c213cSJorge Gorbe Moya     }
228f35c213cSJorge Gorbe Moya   };
229f35c213cSJorge Gorbe Moya   class TestPass2 final : public RegionPass {
230f35c213cSJorge Gorbe Moya     unsigned &InstCount;
231f35c213cSJorge Gorbe Moya 
232f35c213cSJorge Gorbe Moya   public:
233f35c213cSJorge Gorbe Moya     TestPass2(unsigned &InstCount)
234f35c213cSJorge Gorbe Moya         : RegionPass("test-pass2"), InstCount(InstCount) {}
235a461869dSvporpo     bool runOnRegion(Region &R, const Analyses &A) final {
236f35c213cSJorge Gorbe Moya       for ([[maybe_unused]] auto &Inst : R)
237f35c213cSJorge Gorbe Moya         ++InstCount;
238f35c213cSJorge Gorbe Moya       return false;
239f35c213cSJorge Gorbe Moya     }
240f35c213cSJorge Gorbe Moya   };
241f35c213cSJorge Gorbe Moya   unsigned InstCount1 = 0;
242f35c213cSJorge Gorbe Moya   unsigned InstCount2 = 0;
243f35c213cSJorge Gorbe Moya 
244f35c213cSJorge Gorbe Moya   RegionPassManager RPM("test-rpm");
245756ec99cSJorge Gorbe Moya   RPM.addPass(std::make_unique<TestPass1>(InstCount1));
246756ec99cSJorge Gorbe Moya   RPM.addPass(std::make_unique<TestPass2>(InstCount2));
247f35c213cSJorge Gorbe Moya   // Check runOnRegion().
248f35c213cSJorge Gorbe Moya   llvm::SmallVector<std::unique_ptr<Region>> Regions =
249*4b209c5dSvporpo       Region::createRegionsFromMD(*F, *TTI);
250f35c213cSJorge Gorbe Moya   ASSERT_EQ(Regions.size(), 1u);
251a461869dSvporpo   RPM.runOnRegion(*Regions[0], Analyses::emptyForTesting());
252f35c213cSJorge Gorbe Moya   EXPECT_EQ(InstCount1, 2u);
253f35c213cSJorge Gorbe Moya   EXPECT_EQ(InstCount2, 2u);
254f35c213cSJorge Gorbe Moya #ifndef NDEBUG
255f35c213cSJorge Gorbe Moya   // Check dump().
256f35c213cSJorge Gorbe Moya   std::string Buff;
257f35c213cSJorge Gorbe Moya   llvm::raw_string_ostream SS(Buff);
258f35c213cSJorge Gorbe Moya   RPM.print(SS);
259f35c213cSJorge Gorbe Moya   EXPECT_EQ(Buff, "test-rpm(test-pass1,test-pass2)");
260f35c213cSJorge Gorbe Moya #endif // NDEBUG
261f35c213cSJorge Gorbe Moya }
262f35c213cSJorge Gorbe Moya 
263756ec99cSJorge Gorbe Moya TEST_F(PassTest, SetPassPipeline) {
264756ec99cSJorge Gorbe Moya   auto *F = parseFunction(R"IR(
265756ec99cSJorge Gorbe Moya define void @f() {
266756ec99cSJorge Gorbe Moya   ret void
267102c384bSJorge Gorbe Moya }
268756ec99cSJorge Gorbe Moya )IR",
269756ec99cSJorge Gorbe Moya                           "f");
270756ec99cSJorge Gorbe Moya   class FooPass final : public FunctionPass {
271756ec99cSJorge Gorbe Moya     std::string &Str;
2722e8ad49eSJorge Gorbe Moya     std::string Args;
273f0f1b706Svporpo 
274102c384bSJorge Gorbe Moya   public:
2752e8ad49eSJorge Gorbe Moya     FooPass(std::string &Str, llvm::StringRef Args)
2762e8ad49eSJorge Gorbe Moya         : FunctionPass("foo-pass"), Str(Str), Args(Args.str()) {}
277a461869dSvporpo     bool runOnFunction(Function &F, const Analyses &A) final {
2782e8ad49eSJorge Gorbe Moya       Str += "foo<" + Args + ">";
279756ec99cSJorge Gorbe Moya       return false;
280756ec99cSJorge Gorbe Moya     }
281102c384bSJorge Gorbe Moya   };
282756ec99cSJorge Gorbe Moya   class BarPass final : public FunctionPass {
283756ec99cSJorge Gorbe Moya     std::string &Str;
2842e8ad49eSJorge Gorbe Moya     std::string Args;
285756ec99cSJorge Gorbe Moya 
286102c384bSJorge Gorbe Moya   public:
2872e8ad49eSJorge Gorbe Moya     BarPass(std::string &Str, llvm::StringRef Args)
2882e8ad49eSJorge Gorbe Moya         : FunctionPass("bar-pass"), Str(Str), Args(Args.str()) {}
289a461869dSvporpo     bool runOnFunction(Function &F, const Analyses &A) final {
2902e8ad49eSJorge Gorbe Moya       Str += "bar<" + Args + ">";
291756ec99cSJorge Gorbe Moya       return false;
292756ec99cSJorge Gorbe Moya     }
293102c384bSJorge Gorbe Moya   };
294102c384bSJorge Gorbe Moya 
295756ec99cSJorge Gorbe Moya   std::string Str;
296756ec99cSJorge Gorbe Moya   auto CreatePass =
2972e8ad49eSJorge Gorbe Moya       [&Str](llvm::StringRef Name,
2982e8ad49eSJorge Gorbe Moya              llvm::StringRef Args) -> std::unique_ptr<FunctionPass> {
299756ec99cSJorge Gorbe Moya     if (Name == "foo")
3002e8ad49eSJorge Gorbe Moya       return std::make_unique<FooPass>(Str, Args);
301756ec99cSJorge Gorbe Moya     if (Name == "bar")
3022e8ad49eSJorge Gorbe Moya       return std::make_unique<BarPass>(Str, Args);
303756ec99cSJorge Gorbe Moya     return nullptr;
304756ec99cSJorge Gorbe Moya   };
305102c384bSJorge Gorbe Moya 
306756ec99cSJorge Gorbe Moya   FunctionPassManager FPM("test-fpm");
3072e8ad49eSJorge Gorbe Moya   FPM.setPassPipeline("foo<abc>,bar<nested1<nested2<nested3>>>,foo",
3082e8ad49eSJorge Gorbe Moya                       CreatePass);
309a461869dSvporpo   FPM.runOnFunction(*F, Analyses::emptyForTesting());
3102e8ad49eSJorge Gorbe Moya   EXPECT_EQ(Str, "foo<abc>bar<nested1<nested2<nested3>>>foo<>");
311756ec99cSJorge Gorbe Moya 
312756ec99cSJorge Gorbe Moya   // A second call to setPassPipeline will trigger an assertion in debug mode.
313102c384bSJorge Gorbe Moya #ifndef NDEBUG
314756ec99cSJorge Gorbe Moya   EXPECT_DEATH(FPM.setPassPipeline("bar,bar,foo", CreatePass),
315756ec99cSJorge Gorbe Moya                "setPassPipeline called on a non-empty sandboxir::PassManager");
316756ec99cSJorge Gorbe Moya #endif
317102c384bSJorge Gorbe Moya 
318756ec99cSJorge Gorbe Moya   // Fresh PM for the death tests so they die from bad pipeline strings, rather
319756ec99cSJorge Gorbe Moya   // than from multiple setPassPipeline calls.
320756ec99cSJorge Gorbe Moya   FunctionPassManager FPM2("test-fpm");
3212e8ad49eSJorge Gorbe Moya   // Bad/empty pass names.
322756ec99cSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("bad-pass-name", CreatePass),
323f0f1b706Svporpo                ".*not registered.*");
3242e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline(",", CreatePass), ".*empty pass name.*");
3252e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("<>", CreatePass), ".*empty pass name.*");
3262e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("<>foo", CreatePass),
3272e8ad49eSJorge Gorbe Moya                ".*empty pass name.*");
3282e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo,<>", CreatePass),
3292e8ad49eSJorge Gorbe Moya                ".*empty pass name.*");
3302e8ad49eSJorge Gorbe Moya 
3312e8ad49eSJorge Gorbe Moya   // Mismatched argument brackets.
3322e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo<", CreatePass), ".*Missing '>'.*");
3332e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo<bar", CreatePass), ".*Missing '>'.*");
3342e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo<bar<>", CreatePass),
3352e8ad49eSJorge Gorbe Moya                ".*Missing '>'.*");
3362e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo>", CreatePass), ".*Unexpected '>'.*");
3372e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline(">foo", CreatePass), ".*Unexpected '>'.*");
3382e8ad49eSJorge Gorbe Moya   // Extra garbage between args and next delimiter/end-of-string.
3392e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo<bar<>>>", CreatePass),
3402e8ad49eSJorge Gorbe Moya                ".*Expected delimiter.*");
3412e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("bar<>foo", CreatePass),
3422e8ad49eSJorge Gorbe Moya                ".*Expected delimiter.*");
3432e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("bar<>foo,baz", CreatePass),
3442e8ad49eSJorge Gorbe Moya                ".*Expected delimiter.*");
3452e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo<args><more-args>", CreatePass),
3462e8ad49eSJorge Gorbe Moya                ".*Expected delimiter.*");
3472e8ad49eSJorge Gorbe Moya   EXPECT_DEATH(FPM2.setPassPipeline("foo<args>bar", CreatePass),
3482e8ad49eSJorge Gorbe Moya                ".*Expected delimiter.*");
349f0f1b706Svporpo }
350