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