xref: /llvm-project/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp (revision 3769fcb3e78eba5f3e34d1c2dfa994625edb005a)
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