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