@@ -964,18 +964,88 @@ define void @foo(i32 %cond0, i32 %cond1) {
964964 EXPECT_EQ (Switch->findCaseDest (BB0), Zero);
965965 EXPECT_EQ (Switch->findCaseDest (BB1), One);
966966
967- // Check order is preserved after reverting multiple removeCase invocations.
967+ }
968+
969+ TEST_F (TrackerTest, SwitchInstPreservesSuccesorOrder) {
970+ parseIR (C, R"IR(
971+ define void @foo(i32 %cond0) {
972+ entry:
973+ switch i32 %cond0, label %default [ i32 0, label %bb0
974+ i32 1, label %bb1
975+ i32 2, label %bb2 ]
976+ bb0:
977+ ret void
978+ bb1:
979+ ret void
980+ bb2:
981+ ret void
982+ default:
983+ ret void
984+ }
985+ )IR" );
986+ Function &LLVMF = *M->getFunction (" foo" );
987+ auto *LLVMEntry = getBasicBlockByName (LLVMF, " entry" );
988+
989+ sandboxir::Context Ctx (C);
990+ [[maybe_unused]] auto &F = *Ctx.createFunction (&LLVMF);
991+ auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue (LLVMEntry));
992+ auto *BB0 = cast<sandboxir::BasicBlock>(
993+ Ctx.getValue (getBasicBlockByName (LLVMF, " bb0" )));
994+ auto *BB1 = cast<sandboxir::BasicBlock>(
995+ Ctx.getValue (getBasicBlockByName (LLVMF, " bb1" )));
996+ auto *BB2 = cast<sandboxir::BasicBlock>(
997+ Ctx.getValue (getBasicBlockByName (LLVMF, " bb2" )));
998+ auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin ());
999+
1000+ auto *DefaultDest = Switch->getDefaultDest ();
1001+ auto *Zero = sandboxir::ConstantInt::get (sandboxir::Type::getInt32Ty (Ctx), 0 );
1002+ auto *One = sandboxir::ConstantInt::get (sandboxir::Type::getInt32Ty (Ctx), 1 );
1003+ auto *Two = sandboxir::ConstantInt::get (sandboxir::Type::getInt32Ty (Ctx), 2 );
1004+
1005+ // Check that we can properly revert a removeCase multiple positions apart
1006+ // from the end of the operand list.
9681007 Ctx.save ();
9691008 Switch->removeCase (Switch->findCaseValue (Zero));
1009+ EXPECT_EQ (Switch->getNumCases (), 2u );
1010+ Ctx.revert ();
1011+ EXPECT_EQ (Switch->getNumCases (), 3u );
1012+ EXPECT_EQ (Switch->findCaseDest (BB0), Zero);
1013+ EXPECT_EQ (Switch->findCaseDest (BB1), One);
1014+ EXPECT_EQ (Switch->findCaseDest (BB2), Two);
1015+ EXPECT_EQ (Switch->getSuccessor (0 ), DefaultDest);
1016+ EXPECT_EQ (Switch->getSuccessor (1 ), BB0);
1017+ EXPECT_EQ (Switch->getSuccessor (2 ), BB1);
1018+ EXPECT_EQ (Switch->getSuccessor (3 ), BB2);
1019+
1020+ // Check that we can properly revert a removeCase of the last case.
1021+ Ctx.save ();
1022+ Switch->removeCase (Switch->findCaseValue (Two));
1023+ EXPECT_EQ (Switch->getNumCases (), 2u );
1024+ Ctx.revert ();
1025+ EXPECT_EQ (Switch->getNumCases (), 3u );
1026+ EXPECT_EQ (Switch->findCaseDest (BB0), Zero);
1027+ EXPECT_EQ (Switch->findCaseDest (BB1), One);
1028+ EXPECT_EQ (Switch->findCaseDest (BB2), Two);
1029+ EXPECT_EQ (Switch->getSuccessor (0 ), DefaultDest);
1030+ EXPECT_EQ (Switch->getSuccessor (1 ), BB0);
1031+ EXPECT_EQ (Switch->getSuccessor (2 ), BB1);
1032+ EXPECT_EQ (Switch->getSuccessor (3 ), BB2);
1033+
1034+ // Check order is preserved after reverting multiple removeCase invocations.
1035+ Ctx.save ();
9701036 Switch->removeCase (Switch->findCaseValue (One));
1037+ Switch->removeCase (Switch->findCaseValue (Zero));
1038+ Switch->removeCase (Switch->findCaseValue (Two));
9711039 EXPECT_EQ (Switch->getNumCases (), 0u );
9721040 Ctx.revert ();
973- EXPECT_EQ (Switch->getNumCases (), 2u );
1041+ EXPECT_EQ (Switch->getNumCases (), 3u );
9741042 EXPECT_EQ (Switch->findCaseDest (BB0), Zero);
9751043 EXPECT_EQ (Switch->findCaseDest (BB1), One);
976- EXPECT_EQ (Switch->getSuccessor (0 ), OrigDefaultDest);
1044+ EXPECT_EQ (Switch->findCaseDest (BB2), Two);
1045+ EXPECT_EQ (Switch->getSuccessor (0 ), DefaultDest);
9771046 EXPECT_EQ (Switch->getSuccessor (1 ), BB0);
9781047 EXPECT_EQ (Switch->getSuccessor (2 ), BB1);
1048+ EXPECT_EQ (Switch->getSuccessor (3 ), BB2);
9791049}
9801050
9811051TEST_F (TrackerTest, SelectInst) {
0 commit comments