@@ -331,3 +331,112 @@ define void @foo(i8 %v0) {
331
331
EXPECT_THAT (getPtrVec (SingleUnion), testing::ElementsAre (I0, I1, I2, Ret));
332
332
}
333
333
}
334
+
335
+ TEST_F (IntervalTest, NotifyMoveInstr) {
336
+ parseIR (C, R"IR(
337
+ define void @foo(i8 %v0) {
338
+ %I0 = add i8 %v0, %v0
339
+ %I1 = add i8 %v0, %v0
340
+ %I2 = add i8 %v0, %v0
341
+ ret void
342
+ }
343
+ )IR" );
344
+ Function &LLVMF = *M->getFunction (" foo" );
345
+ sandboxir::Context Ctx (C);
346
+ auto &F = *Ctx.createFunction (&LLVMF);
347
+ auto *BB = &*F.begin ();
348
+ auto It = BB->begin ();
349
+ auto *I0 = &*It++;
350
+ auto *I1 = &*It++;
351
+ auto *I2 = &*It++;
352
+ auto *Ret = &*It++;
353
+ {
354
+ // Assert that we don't try to move external instr to the interval.
355
+ sandboxir::Interval<sandboxir::Instruction> I2Ret (I2, Ret);
356
+ #ifndef NDEBUG
357
+ EXPECT_DEATH (I2Ret.notifyMoveInstr (I0, Ret->getIterator ()), " .*interval.*" );
358
+ #endif // NDEBUG
359
+ }
360
+ {
361
+ // Assert that we don't move before self.
362
+ sandboxir::Interval<sandboxir::Instruction> I2Ret (I2, Ret);
363
+ #ifndef NDEBUG
364
+ EXPECT_DEATH (I2Ret.notifyMoveInstr (Ret, Ret->getIterator ()), " .*self.*" );
365
+ #endif // NDEBUG
366
+ }
367
+ {
368
+ // Single-element interval.
369
+ sandboxir::Interval<sandboxir::Instruction> I2I2 (I2, I2);
370
+ I2I2.notifyMoveInstr (I2, Ret->getIterator ());
371
+ EXPECT_EQ (I2I2.top (), I2);
372
+ EXPECT_EQ (I2I2.bottom (), I2);
373
+ }
374
+ {
375
+ // Two-element interval swap.
376
+ sandboxir::Interval<sandboxir::Instruction> I1I2 (I1, I2);
377
+ I1I2.notifyMoveInstr (I2, I1->getIterator ());
378
+ I2->moveBefore (I1);
379
+ EXPECT_EQ (I1I2.top (), I2);
380
+ EXPECT_EQ (I1I2.bottom (), I1);
381
+
382
+ I2->moveAfter (I1);
383
+ }
384
+ {
385
+ // Move to same position.
386
+ sandboxir::Interval<sandboxir::Instruction> I0Ret (I0, Ret);
387
+ I0Ret.notifyMoveInstr (I0, I1->getIterator ());
388
+ I0->moveBefore (I1);
389
+ EXPECT_EQ (I0Ret.top (), I0);
390
+ EXPECT_EQ (I0Ret.bottom (), Ret);
391
+ }
392
+ {
393
+ // Move internal to internal.
394
+ sandboxir::Interval<sandboxir::Instruction> I0Ret (I0, Ret);
395
+ I0Ret.notifyMoveInstr (I2, I1->getIterator ());
396
+ I2->moveBefore (I1);
397
+ EXPECT_EQ (I0Ret.top (), I0);
398
+ EXPECT_EQ (I0Ret.bottom (), Ret);
399
+
400
+ I2->moveAfter (I1);
401
+ }
402
+ {
403
+ // Move internal before top.
404
+ sandboxir::Interval<sandboxir::Instruction> I0Ret (I0, Ret);
405
+ I0Ret.notifyMoveInstr (I2, I0->getIterator ());
406
+ I2->moveBefore (I0);
407
+ EXPECT_EQ (I0Ret.top (), I2);
408
+ EXPECT_EQ (I0Ret.bottom (), Ret);
409
+
410
+ I2->moveAfter (I1);
411
+ }
412
+ {
413
+ // Move internal to bottom.
414
+ sandboxir::Interval<sandboxir::Instruction> I0Ret (I0, Ret);
415
+ I0Ret.notifyMoveInstr (I2, BB->end ());
416
+ I2->moveAfter (Ret);
417
+ EXPECT_EQ (I0Ret.top (), I0);
418
+ EXPECT_EQ (I0Ret.bottom (), I2);
419
+
420
+ I2->moveAfter (I1);
421
+ }
422
+ {
423
+ // Move bottom before internal.
424
+ sandboxir::Interval<sandboxir::Instruction> I0Ret (I0, Ret);
425
+ I0Ret.notifyMoveInstr (Ret, I2->getIterator ());
426
+ Ret->moveBefore (I2);
427
+ EXPECT_EQ (I0Ret.top (), I0);
428
+ EXPECT_EQ (I0Ret.bottom (), I2);
429
+
430
+ Ret->moveAfter (I2);
431
+ }
432
+ {
433
+ // Move bottom before top.
434
+ sandboxir::Interval<sandboxir::Instruction> I0Ret (I0, Ret);
435
+ I0Ret.notifyMoveInstr (Ret, I0->getIterator ());
436
+ Ret->moveBefore (I0);
437
+ EXPECT_EQ (I0Ret.top (), Ret);
438
+ EXPECT_EQ (I0Ret.bottom (), I2);
439
+
440
+ Ret->moveAfter (I2);
441
+ }
442
+ }
0 commit comments