@@ -934,38 +934,90 @@ void SVFIRBuilder::visitBranchInst(BranchInst &inst)
934934 assert (inst.getNumSuccessors () <= 2 && " if/else has more than two branches?" );
935935
936936 BranchStmt::SuccAndCondPairVec successors;
937- for (u32_t i = 0 ; i < inst.getNumSuccessors (); ++i)
937+ std::vector<const Instruction*> nextInsts;
938+ LLVMUtil::getNextInsts (&inst, nextInsts);
939+ u32_t branchID = 0 ;
940+ for (const Instruction* succInst : nextInsts)
938941 {
939- const Instruction* succInst = &inst. getSuccessor (i)-> front ( );
942+ assert (branchID <= 2 && " if/else has more than two branches? " );
940943 const SVFInstruction* svfSuccInst = LLVMModuleSet::getLLVMModuleSet ()->getSVFInstruction (succInst);
941944 const ICFGNode* icfgNode = pag->getICFG ()->getICFGNode (svfSuccInst);
942- successors.push_back (std::make_pair (icfgNode, 1 -i));
945+ successors.push_back (std::make_pair (icfgNode, 1 -branchID));
946+ branchID++;
943947 }
944- addBranchStmt (brinst, cond,successors);
948+ addBranchStmt (brinst, cond, successors);
945949}
946950
951+
952+ /* *
953+ * See more: https://github.com/SVF-tools/SVF/pull/1191
954+ *
955+ * Given the code:
956+ *
957+ * switch (a) {
958+ * case 0: printf("0\n"); break;
959+ * case 1:
960+ * case 2:
961+ * case 3: printf("a >=1 && a <= 3\n"); break;
962+ * case 4:
963+ * case 6:
964+ * case 7: printf("a >= 4 && a <=7\n"); break;
965+ * default: printf("a < 0 || a > 7"); break;
966+ * }
967+ *
968+ * Generate the IR:
969+ *
970+ * switch i32 %0, label %sw.default [
971+ * i32 0, label %sw.bb
972+ * i32 1, label %sw.bb1
973+ * i32 2, label %sw.bb1
974+ * i32 3, label %sw.bb1
975+ * i32 4, label %sw.bb3
976+ * i32 6, label %sw.bb3
977+ * i32 7, label %sw.bb3
978+ * ]
979+ *
980+ * We can get every case basic block and related case value:
981+ * [
982+ * {%sw.default, -1},
983+ * {%sw.bb, 0},
984+ * {%sw.bb1, 1},
985+ * {%sw.bb1, 2},
986+ * {%sw.bb1, 3},
987+ * {%sw.bb3, 4},
988+ * {%sw.bb3, 6},
989+ * {%sw.bb3, 7},
990+ * ]
991+ * Note: default case value is nullptr
992+ */
993+ // / For larger number, we preserve case value just -1 now
994+ // / see more: https://github.com/SVF-tools/SVF/pull/992
995+
996+ // / The following implementation follows ICFGBuilder::processFunBody
947997void SVFIRBuilder::visitSwitchInst (SwitchInst &inst)
948998{
949999 NodeID brinst = getValueNode (&inst);
9501000 NodeID cond = getValueNode (inst.getCondition ());
9511001
9521002 BranchStmt::SuccAndCondPairVec successors;
953-
954- // get case successor basic block and related case value
955- SuccBBAndCondValPairVec succBB2CondValPairVec;
956- LLVMUtil::getSuccBBandCondValPairVec (inst, succBB2CondValPairVec);
957- for (auto &succBB2CaseValue : succBB2CondValPairVec)
1003+ std::vector<const Instruction*> nextInsts;
1004+ LLVMUtil::getNextInsts (&inst, nextInsts);
1005+ for (const Instruction* succInst : nextInsts)
9581006 {
959- s64_t val = LLVMUtil::getCaseValue (inst, succBB2CaseValue);
960- const BasicBlock *succBB = succBB2CaseValue.first ;
961- const Instruction* succInst = &succBB->front ();
1007+ // / branch condition value
1008+ const ConstantInt* condVal = inst.findCaseDest (const_cast <BasicBlock*>(succInst->getParent ()));
1009+ // / default case is set to -1;
1010+ s64_t val = -1 ;
1011+ if (condVal && condVal->getBitWidth () <= 64 )
1012+ val = condVal->getSExtValue ();
9621013 const SVFInstruction* svfSuccInst = LLVMModuleSet::getLLVMModuleSet ()->getSVFInstruction (succInst);
9631014 const ICFGNode* icfgNode = pag->getICFG ()->getICFGNode (svfSuccInst);
9641015 successors.push_back (std::make_pair (icfgNode, val));
9651016 }
9661017 addBranchStmt (brinst, cond, successors);
9671018}
9681019
1020+
9691021// / %ap = alloca %struct.va_list
9701022// / %ap2 = bitcast %struct.va_list* %ap to i8*
9711023// / ; Read a single integer argument from %ap2
0 commit comments