13c66a510Svporpo //===- IntervalTest.cpp ---------------------------------------------------===// 23c66a510Svporpo // 33c66a510Svporpo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43c66a510Svporpo // See https://llvm.org/LICENSE.txt for license information. 53c66a510Svporpo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63c66a510Svporpo // 73c66a510Svporpo //===----------------------------------------------------------------------===// 83c66a510Svporpo 93c66a510Svporpo #include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h" 103c66a510Svporpo #include "llvm/AsmParser/Parser.h" 112018f4ccSVasileios Porpodas #include "llvm/SandboxIR/Context.h" 12e22b07e7Svporpo #include "llvm/SandboxIR/Function.h" 13eba106d4Svporpo #include "llvm/SandboxIR/Instruction.h" 143c66a510Svporpo #include "llvm/Support/SourceMgr.h" 15c214af84Svporpo #include "gmock/gmock-matchers.h" 163c66a510Svporpo #include "gtest/gtest.h" 173c66a510Svporpo 183c66a510Svporpo using namespace llvm; 193c66a510Svporpo 203c66a510Svporpo struct IntervalTest : public testing::Test { 213c66a510Svporpo LLVMContext C; 223c66a510Svporpo std::unique_ptr<Module> M; 233c66a510Svporpo 243c66a510Svporpo void parseIR(LLVMContext &C, const char *IR) { 253c66a510Svporpo SMDiagnostic Err; 263c66a510Svporpo M = parseAssemblyString(IR, Err, C); 273c66a510Svporpo if (!M) 283c66a510Svporpo Err.print("InstrIntervalTest", errs()); 293c66a510Svporpo } 303c66a510Svporpo }; 313c66a510Svporpo 323c66a510Svporpo TEST_F(IntervalTest, Basic) { 333c66a510Svporpo parseIR(C, R"IR( 343c66a510Svporpo define void @foo(i8 %v0) { 353c66a510Svporpo %add0 = add i8 %v0, %v0 363c66a510Svporpo %add1 = add i8 %v0, %v0 373c66a510Svporpo %add2 = add i8 %v0, %v0 383c66a510Svporpo ret void 393c66a510Svporpo } 403c66a510Svporpo )IR"); 413c66a510Svporpo Function &LLVMF = *M->getFunction("foo"); 423c66a510Svporpo sandboxir::Context Ctx(C); 433c66a510Svporpo auto &F = *Ctx.createFunction(&LLVMF); 443c66a510Svporpo auto *BB = &*F.begin(); 453c66a510Svporpo auto It = BB->begin(); 463c66a510Svporpo auto *I0 = &*It++; 473c66a510Svporpo auto *I1 = &*It++; 483c66a510Svporpo auto *I2 = &*It++; 493c66a510Svporpo auto *Ret = &*It++; 503c66a510Svporpo 513c66a510Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl(I0, Ret); 523c66a510Svporpo #ifndef NDEBUG 533c66a510Svporpo EXPECT_DEATH(sandboxir::Interval<sandboxir::Instruction>(I1, I0), 543c66a510Svporpo ".*before.*"); 553c66a510Svporpo #endif // NDEBUG 563c66a510Svporpo // Check Interval<sandboxir::Instruction>(ArrayRef), from(), to(). 573c66a510Svporpo { 583c66a510Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl( 593c66a510Svporpo SmallVector<sandboxir::Instruction *>({I0, Ret})); 603c66a510Svporpo EXPECT_EQ(Intvl.top(), I0); 613c66a510Svporpo EXPECT_EQ(Intvl.bottom(), Ret); 623c66a510Svporpo } 633c66a510Svporpo { 643c66a510Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl( 653c66a510Svporpo SmallVector<sandboxir::Instruction *>({Ret, I0})); 663c66a510Svporpo EXPECT_EQ(Intvl.top(), I0); 673c66a510Svporpo EXPECT_EQ(Intvl.bottom(), Ret); 683c66a510Svporpo } 693c66a510Svporpo { 703c66a510Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl( 713c66a510Svporpo SmallVector<sandboxir::Instruction *>({I0, I0})); 723c66a510Svporpo EXPECT_EQ(Intvl.top(), I0); 733c66a510Svporpo EXPECT_EQ(Intvl.bottom(), I0); 743c66a510Svporpo } 753c66a510Svporpo 763c66a510Svporpo // Check empty(). 773c66a510Svporpo EXPECT_FALSE(Intvl.empty()); 783c66a510Svporpo sandboxir::Interval<sandboxir::Instruction> Empty; 793c66a510Svporpo EXPECT_TRUE(Empty.empty()); 803c66a510Svporpo sandboxir::Interval<sandboxir::Instruction> One(I0, I0); 813c66a510Svporpo EXPECT_FALSE(One.empty()); 823c66a510Svporpo // Check contains(). 833c66a510Svporpo for (auto &I : *BB) { 843c66a510Svporpo EXPECT_TRUE(Intvl.contains(&I)); 853c66a510Svporpo EXPECT_FALSE(Empty.contains(&I)); 863c66a510Svporpo } 873c66a510Svporpo EXPECT_FALSE(One.contains(I1)); 883c66a510Svporpo EXPECT_FALSE(One.contains(I2)); 893c66a510Svporpo EXPECT_FALSE(One.contains(Ret)); 903c66a510Svporpo // Check iterator. 913c66a510Svporpo auto BBIt = BB->begin(); 923c66a510Svporpo for (auto &I : Intvl) 933c66a510Svporpo EXPECT_EQ(&I, &*BBIt++); 94c214af84Svporpo { 95c214af84Svporpo // Check equality. 96c214af84Svporpo EXPECT_TRUE(Empty == Empty); 97c214af84Svporpo EXPECT_FALSE(Empty == One); 98c214af84Svporpo EXPECT_TRUE(One == One); 99c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2); 100c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl2(I0, I2); 101c214af84Svporpo EXPECT_TRUE(Intvl1 == Intvl1); 102c214af84Svporpo EXPECT_TRUE(Intvl1 == Intvl2); 103c214af84Svporpo } 104c214af84Svporpo { 105c214af84Svporpo // Check inequality. 106c214af84Svporpo EXPECT_FALSE(Empty != Empty); 107c214af84Svporpo EXPECT_TRUE(Empty != One); 108c214af84Svporpo EXPECT_FALSE(One != One); 109c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2); 110c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl2(I0, I2); 111c214af84Svporpo EXPECT_FALSE(Intvl1 != Intvl1); 112c214af84Svporpo EXPECT_FALSE(Intvl1 != Intvl2); 113c214af84Svporpo } 114c214af84Svporpo { 115c214af84Svporpo // Check disjoint(). 116c214af84Svporpo EXPECT_TRUE(Empty.disjoint(Empty)); 117c214af84Svporpo EXPECT_TRUE(One.disjoint(Empty)); 118c214af84Svporpo EXPECT_TRUE(Empty.disjoint(One)); 119c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2); 120c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl2(I1, Ret); 121c214af84Svporpo EXPECT_FALSE(Intvl1.disjoint(Intvl2)); 122c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Intvl3(I2, I2); 123c214af84Svporpo EXPECT_FALSE(Intvl1.disjoint(Intvl3)); 124c214af84Svporpo EXPECT_TRUE(Intvl1.disjoint(Empty)); 125c214af84Svporpo } 12631b85c6eSvporpo { 12731b85c6eSvporpo // Check comesBefore(). 12831b85c6eSvporpo sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I0); 12931b85c6eSvporpo sandboxir::Interval<sandboxir::Instruction> Intvl2(I2, I2); 13031b85c6eSvporpo EXPECT_TRUE(Intvl1.comesBefore(Intvl2)); 13131b85c6eSvporpo EXPECT_FALSE(Intvl2.comesBefore(Intvl1)); 13231b85c6eSvporpo 13331b85c6eSvporpo sandboxir::Interval<sandboxir::Instruction> Intvl12(I1, I2); 13431b85c6eSvporpo EXPECT_TRUE(Intvl1.comesBefore(Intvl12)); 13531b85c6eSvporpo EXPECT_FALSE(Intvl12.comesBefore(Intvl1)); 13631b85c6eSvporpo { 13731b85c6eSvporpo #ifndef NDEBUG 13831b85c6eSvporpo // Check comesBefore() with non-disjoint intervals. 13931b85c6eSvporpo sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2); 14031b85c6eSvporpo sandboxir::Interval<sandboxir::Instruction> Intvl2(I2, I2); 14131b85c6eSvporpo EXPECT_DEATH(Intvl1.comesBefore(Intvl2), ".*disjoint.*"); 14231b85c6eSvporpo #endif // NDEBUG 14331b85c6eSvporpo } 14431b85c6eSvporpo } 145c214af84Svporpo } 146c214af84Svporpo 147c214af84Svporpo // Helper function for returning a vector of instruction pointers from a range 148c214af84Svporpo // of references. 149c214af84Svporpo template <typename RangeT> 150c214af84Svporpo static SmallVector<sandboxir::Instruction *> getPtrVec(RangeT Range) { 151c214af84Svporpo SmallVector<sandboxir::Instruction *> PtrVec; 152c214af84Svporpo for (sandboxir::Instruction &I : Range) 153c214af84Svporpo PtrVec.push_back(&I); 154c214af84Svporpo return PtrVec; 155c214af84Svporpo } 156c214af84Svporpo 157c214af84Svporpo TEST_F(IntervalTest, Difference) { 158c214af84Svporpo parseIR(C, R"IR( 159c214af84Svporpo define void @foo(i8 %v0) { 160c214af84Svporpo %I0 = add i8 %v0, %v0 161c214af84Svporpo %I1 = add i8 %v0, %v0 162c214af84Svporpo %I2 = add i8 %v0, %v0 163c214af84Svporpo ret void 164c214af84Svporpo } 165c214af84Svporpo )IR"); 166c214af84Svporpo Function &LLVMF = *M->getFunction("foo"); 167c214af84Svporpo sandboxir::Context Ctx(C); 168c214af84Svporpo auto &F = *Ctx.createFunction(&LLVMF); 169c214af84Svporpo auto *BB = &*F.begin(); 170c214af84Svporpo auto It = BB->begin(); 171c214af84Svporpo auto *I0 = &*It++; 172c214af84Svporpo auto *I1 = &*It++; 173c214af84Svporpo auto *I2 = &*It++; 174c214af84Svporpo auto *Ret = &*It++; 175c214af84Svporpo 176c214af84Svporpo { 177c214af84Svporpo // Check [I0,Ret] - [] 178c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 179c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Empty; 180c214af84Svporpo auto Diffs = I0Ret - Empty; 181c214af84Svporpo EXPECT_EQ(Diffs.size(), 1u); 182c214af84Svporpo const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0]; 183c214af84Svporpo EXPECT_THAT(getPtrVec(Diff), testing::ElementsAre(I0, I1, I2, Ret)); 1843c6041d2Svporpo 1853c6041d2Svporpo // Check getSingleDiff(). 1863c6041d2Svporpo EXPECT_EQ(I0Ret.getSingleDiff(Empty), Diff); 187c214af84Svporpo } 188c214af84Svporpo { 189c214af84Svporpo // Check [] - [I0,Ret] 190c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Empty; 191c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 192c214af84Svporpo auto Diffs = Empty - I0Ret; 193c214af84Svporpo EXPECT_EQ(Diffs.size(), 1u); 194c214af84Svporpo const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0]; 195c214af84Svporpo EXPECT_TRUE(Diff.empty()); 1963c6041d2Svporpo 1973c6041d2Svporpo // Check getSingleDiff(). 1983c6041d2Svporpo EXPECT_EQ(Empty.getSingleDiff(I0Ret), Diff); 199c214af84Svporpo } 200c214af84Svporpo { 201c214af84Svporpo // Check [I0,Ret] - [I0]. 202c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 203c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0); 204c214af84Svporpo auto Diffs = I0Ret - I0I0; 205c214af84Svporpo EXPECT_EQ(Diffs.size(), 1u); 206c214af84Svporpo const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0]; 207c214af84Svporpo EXPECT_THAT(getPtrVec(Diff), testing::ElementsAre(I1, I2, Ret)); 2083c6041d2Svporpo 2093c6041d2Svporpo // Check getSingleDiff(). 2103c6041d2Svporpo EXPECT_EQ(I0Ret.getSingleDiff(I0I0), Diff); 211c214af84Svporpo } 212c214af84Svporpo { 213c214af84Svporpo // Check [I0,Ret] - [I1]. 214c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 215c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1); 216c214af84Svporpo auto Diffs = I0Ret - I1I1; 217c214af84Svporpo EXPECT_EQ(Diffs.size(), 2u); 218c214af84Svporpo const sandboxir::Interval<sandboxir::Instruction> &Diff0 = Diffs[0]; 219c214af84Svporpo EXPECT_THAT(getPtrVec(Diff0), testing::ElementsAre(I0)); 220c214af84Svporpo const sandboxir::Interval<sandboxir::Instruction> &Diff1 = Diffs[1]; 221c214af84Svporpo EXPECT_THAT(getPtrVec(Diff1), testing::ElementsAre(I2, Ret)); 2223c6041d2Svporpo 2233c6041d2Svporpo #ifndef NDEBUG 2243c6041d2Svporpo // Check getSingleDiff(). 2253c6041d2Svporpo EXPECT_DEATH(I0Ret.getSingleDiff(I1I1), ".*single.*"); 2263c6041d2Svporpo #endif // NDEBUG 227c214af84Svporpo } 228c214af84Svporpo } 229c214af84Svporpo 230c214af84Svporpo TEST_F(IntervalTest, Intersection) { 231c214af84Svporpo parseIR(C, R"IR( 232c214af84Svporpo define void @foo(i8 %v0) { 233c214af84Svporpo %I0 = add i8 %v0, %v0 234c214af84Svporpo %I1 = add i8 %v0, %v0 235c214af84Svporpo %I2 = add i8 %v0, %v0 236c214af84Svporpo ret void 237c214af84Svporpo } 238c214af84Svporpo )IR"); 239c214af84Svporpo Function &LLVMF = *M->getFunction("foo"); 240c214af84Svporpo sandboxir::Context Ctx(C); 241c214af84Svporpo auto &F = *Ctx.createFunction(&LLVMF); 242c214af84Svporpo auto *BB = &*F.begin(); 243c214af84Svporpo auto It = BB->begin(); 244c214af84Svporpo auto *I0 = &*It++; 245c214af84Svporpo auto *I1 = &*It++; 246c214af84Svporpo [[maybe_unused]] auto *I2 = &*It++; 247c214af84Svporpo auto *Ret = &*It++; 248c214af84Svporpo 249c214af84Svporpo { 250c214af84Svporpo // Check [I0,Ret] ^ [] 251c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 252c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Empty; 253c214af84Svporpo auto Intersection = I0Ret.intersection(Empty); 254c214af84Svporpo EXPECT_TRUE(Intersection.empty()); 255c214af84Svporpo } 256c214af84Svporpo { 257c214af84Svporpo // Check [] ^ [I0,Ret] 258c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> Empty; 259c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 260c214af84Svporpo auto Intersection = Empty.intersection(I0Ret); 261c214af84Svporpo EXPECT_TRUE(Intersection.empty()); 262c214af84Svporpo } 263c214af84Svporpo { 264c214af84Svporpo // Check [I0,Ret] ^ [I0] 265c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 266c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0); 267c214af84Svporpo auto Intersection = I0Ret.intersection(I0I0); 268c214af84Svporpo EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I0)); 269c214af84Svporpo } 270c214af84Svporpo { 271c214af84Svporpo // Check [I0] ^ [I0,Ret] 272c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0); 273c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 274c214af84Svporpo auto Intersection = I0I0.intersection(I0Ret); 275c214af84Svporpo EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I0)); 276c214af84Svporpo } 277c214af84Svporpo { 278c214af84Svporpo // Check [I0,Ret] ^ [I1]. 279c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 280c214af84Svporpo sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1); 281c214af84Svporpo auto Intersection = I0Ret.intersection(I1I1); 282c214af84Svporpo EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I1)); 283c214af84Svporpo } 2843c66a510Svporpo } 2853c6041d2Svporpo 2863c6041d2Svporpo TEST_F(IntervalTest, UnionInterval) { 2873c6041d2Svporpo parseIR(C, R"IR( 2883c6041d2Svporpo define void @foo(i8 %v0) { 2893c6041d2Svporpo %I0 = add i8 %v0, %v0 2903c6041d2Svporpo %I1 = add i8 %v0, %v0 2913c6041d2Svporpo %I2 = add i8 %v0, %v0 2923c6041d2Svporpo ret void 2933c6041d2Svporpo } 2943c6041d2Svporpo )IR"); 2953c6041d2Svporpo Function &LLVMF = *M->getFunction("foo"); 2963c6041d2Svporpo sandboxir::Context Ctx(C); 2973c6041d2Svporpo auto &F = *Ctx.createFunction(&LLVMF); 2983c6041d2Svporpo auto *BB = &*F.begin(); 2993c6041d2Svporpo auto It = BB->begin(); 3003c6041d2Svporpo auto *I0 = &*It++; 3013c6041d2Svporpo auto *I1 = &*It++; 3023c6041d2Svporpo [[maybe_unused]] auto *I2 = &*It++; 3033c6041d2Svporpo auto *Ret = &*It++; 3043c6041d2Svporpo 3053c6041d2Svporpo { 3063c6041d2Svporpo // Check [I0] unionInterval [I2]. 3073c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0); 3083c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I2I2(I2, I2); 3093c6041d2Svporpo auto SingleUnion = I0I0.getUnionInterval(I2I2); 3103c6041d2Svporpo EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1, I2)); 3113c6041d2Svporpo } 3123c6041d2Svporpo { 3133c6041d2Svporpo // Check [I0] unionInterval Empty. 3143c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0); 3153c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> Empty; 3163c6041d2Svporpo auto SingleUnion = I0I0.getUnionInterval(Empty); 3173c6041d2Svporpo EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0)); 3183c6041d2Svporpo } 3193c6041d2Svporpo { 3203c6041d2Svporpo // Check [I0,I1] unionInterval [I1]. 3213c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I0I1(I0, I1); 3223c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1); 3233c6041d2Svporpo auto SingleUnion = I0I1.getUnionInterval(I1I1); 3243c6041d2Svporpo EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1)); 3253c6041d2Svporpo } 3263c6041d2Svporpo { 3273c6041d2Svporpo // Check [I2,Ret] unionInterval [I0]. 3283c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret); 3293c6041d2Svporpo sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0); 3303c6041d2Svporpo auto SingleUnion = I2Ret.getUnionInterval(I0I0); 3313c6041d2Svporpo EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1, I2, Ret)); 3323c6041d2Svporpo } 3333c6041d2Svporpo } 334*3769fcb3Svporpo 335*3769fcb3Svporpo TEST_F(IntervalTest, NotifyMoveInstr) { 336*3769fcb3Svporpo parseIR(C, R"IR( 337*3769fcb3Svporpo define void @foo(i8 %v0) { 338*3769fcb3Svporpo %I0 = add i8 %v0, %v0 339*3769fcb3Svporpo %I1 = add i8 %v0, %v0 340*3769fcb3Svporpo %I2 = add i8 %v0, %v0 341*3769fcb3Svporpo ret void 342*3769fcb3Svporpo } 343*3769fcb3Svporpo )IR"); 344*3769fcb3Svporpo Function &LLVMF = *M->getFunction("foo"); 345*3769fcb3Svporpo sandboxir::Context Ctx(C); 346*3769fcb3Svporpo auto &F = *Ctx.createFunction(&LLVMF); 347*3769fcb3Svporpo auto *BB = &*F.begin(); 348*3769fcb3Svporpo auto It = BB->begin(); 349*3769fcb3Svporpo auto *I0 = &*It++; 350*3769fcb3Svporpo auto *I1 = &*It++; 351*3769fcb3Svporpo auto *I2 = &*It++; 352*3769fcb3Svporpo auto *Ret = &*It++; 353*3769fcb3Svporpo { 354*3769fcb3Svporpo // Assert that we don't try to move external instr to the interval. 355*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret); 356*3769fcb3Svporpo #ifndef NDEBUG 357*3769fcb3Svporpo EXPECT_DEATH(I2Ret.notifyMoveInstr(I0, Ret->getIterator()), ".*interval.*"); 358*3769fcb3Svporpo #endif // NDEBUG 359*3769fcb3Svporpo } 360*3769fcb3Svporpo { 361*3769fcb3Svporpo // Assert that we don't move before self. 362*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret); 363*3769fcb3Svporpo #ifndef NDEBUG 364*3769fcb3Svporpo EXPECT_DEATH(I2Ret.notifyMoveInstr(Ret, Ret->getIterator()), ".*self.*"); 365*3769fcb3Svporpo #endif // NDEBUG 366*3769fcb3Svporpo } 367*3769fcb3Svporpo { 368*3769fcb3Svporpo // Single-element interval. 369*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I2I2(I2, I2); 370*3769fcb3Svporpo I2I2.notifyMoveInstr(I2, Ret->getIterator()); 371*3769fcb3Svporpo EXPECT_EQ(I2I2.top(), I2); 372*3769fcb3Svporpo EXPECT_EQ(I2I2.bottom(), I2); 373*3769fcb3Svporpo } 374*3769fcb3Svporpo { 375*3769fcb3Svporpo // Two-element interval swap. 376*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I1I2(I1, I2); 377*3769fcb3Svporpo I1I2.notifyMoveInstr(I2, I1->getIterator()); 378*3769fcb3Svporpo I2->moveBefore(I1); 379*3769fcb3Svporpo EXPECT_EQ(I1I2.top(), I2); 380*3769fcb3Svporpo EXPECT_EQ(I1I2.bottom(), I1); 381*3769fcb3Svporpo 382*3769fcb3Svporpo I2->moveAfter(I1); 383*3769fcb3Svporpo } 384*3769fcb3Svporpo { 385*3769fcb3Svporpo // Move to same position. 386*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 387*3769fcb3Svporpo I0Ret.notifyMoveInstr(I0, I1->getIterator()); 388*3769fcb3Svporpo I0->moveBefore(I1); 389*3769fcb3Svporpo EXPECT_EQ(I0Ret.top(), I0); 390*3769fcb3Svporpo EXPECT_EQ(I0Ret.bottom(), Ret); 391*3769fcb3Svporpo } 392*3769fcb3Svporpo { 393*3769fcb3Svporpo // Move internal to internal. 394*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 395*3769fcb3Svporpo I0Ret.notifyMoveInstr(I2, I1->getIterator()); 396*3769fcb3Svporpo I2->moveBefore(I1); 397*3769fcb3Svporpo EXPECT_EQ(I0Ret.top(), I0); 398*3769fcb3Svporpo EXPECT_EQ(I0Ret.bottom(), Ret); 399*3769fcb3Svporpo 400*3769fcb3Svporpo I2->moveAfter(I1); 401*3769fcb3Svporpo } 402*3769fcb3Svporpo { 403*3769fcb3Svporpo // Move internal before top. 404*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 405*3769fcb3Svporpo I0Ret.notifyMoveInstr(I2, I0->getIterator()); 406*3769fcb3Svporpo I2->moveBefore(I0); 407*3769fcb3Svporpo EXPECT_EQ(I0Ret.top(), I2); 408*3769fcb3Svporpo EXPECT_EQ(I0Ret.bottom(), Ret); 409*3769fcb3Svporpo 410*3769fcb3Svporpo I2->moveAfter(I1); 411*3769fcb3Svporpo } 412*3769fcb3Svporpo { 413*3769fcb3Svporpo // Move internal to bottom. 414*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 415*3769fcb3Svporpo I0Ret.notifyMoveInstr(I2, BB->end()); 416*3769fcb3Svporpo I2->moveAfter(Ret); 417*3769fcb3Svporpo EXPECT_EQ(I0Ret.top(), I0); 418*3769fcb3Svporpo EXPECT_EQ(I0Ret.bottom(), I2); 419*3769fcb3Svporpo 420*3769fcb3Svporpo I2->moveAfter(I1); 421*3769fcb3Svporpo } 422*3769fcb3Svporpo { 423*3769fcb3Svporpo // Move bottom before internal. 424*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 425*3769fcb3Svporpo I0Ret.notifyMoveInstr(Ret, I2->getIterator()); 426*3769fcb3Svporpo Ret->moveBefore(I2); 427*3769fcb3Svporpo EXPECT_EQ(I0Ret.top(), I0); 428*3769fcb3Svporpo EXPECT_EQ(I0Ret.bottom(), I2); 429*3769fcb3Svporpo 430*3769fcb3Svporpo Ret->moveAfter(I2); 431*3769fcb3Svporpo } 432*3769fcb3Svporpo { 433*3769fcb3Svporpo // Move bottom before top. 434*3769fcb3Svporpo sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret); 435*3769fcb3Svporpo I0Ret.notifyMoveInstr(Ret, I0->getIterator()); 436*3769fcb3Svporpo Ret->moveBefore(I0); 437*3769fcb3Svporpo EXPECT_EQ(I0Ret.top(), Ret); 438*3769fcb3Svporpo EXPECT_EQ(I0Ret.bottom(), I2); 439*3769fcb3Svporpo 440*3769fcb3Svporpo Ret->moveAfter(I2); 441*3769fcb3Svporpo } 442*3769fcb3Svporpo } 443