bool X86RaisedValueTracker::testAndSetEflagSSAValue()

in X86/X86RaisedValueTracker.cpp [508:1054]


bool X86RaisedValueTracker::testAndSetEflagSSAValue(unsigned int FlagBit,
                                                    const MachineInstr &MI,
                                                    Value *TestResultVal) {
  assert((FlagBit >= X86RegisterUtils::EFLAGS::CF) &&
         (FlagBit < X86RegisterUtils::EFLAGS::UNDEFINED) &&
         "Unknown EFLAGS bit specified");

  int MBBNo = MI.getParent()->getNumber();
  MachineFunction &MF = x86MIRaiser->getMF();
  LLVMContext &Ctx = MF.getFunction().getContext();

  BasicBlock *RaisedBB =
      x86MIRaiser->getRaisedBasicBlock(MF.getBlockNumbered(MBBNo));

  unsigned int ResTyNumBits =
      TestResultVal->getType()->getPrimitiveSizeInBits();
  switch (FlagBit) {
  case X86RegisterUtils::EFLAGS::ZF: {
    Value *ZeroVal = ConstantInt::get(Ctx, APInt(ResTyNumBits, 0));
    // Set ZF - test if TestVal is 0
    Instruction *ZFTest =
        new ICmpInst(CmpInst::Predicate::ICMP_EQ, TestResultVal, ZeroVal,
                     X86RegisterUtils::getEflagName(FlagBit));

    RaisedBB->getInstList().push_back(ZFTest);
    physRegDefsInMBB[FlagBit][MBBNo].second = ZFTest;
  } break;
  case X86RegisterUtils::EFLAGS::SF: {
    Value *ZeroVal = ConstantInt::get(Ctx, APInt(ResTyNumBits, 0));
    // Set SF - test if TestVal is signed
    auto ShiftVal = ConstantInt::get(Ctx, APInt(ResTyNumBits, 1));
    auto HighBitSetVal =
        ConstantInt::get(Ctx, APInt(ResTyNumBits, ResTyNumBits - 1));
    // Compute 1 << (ResTyNumBits - 1)
    auto ShiftLeft = ConstantExpr::getShl(ShiftVal, HighBitSetVal, true, true);

    // Create the instruction
    //      and SubInst, ShiftLeft
    Instruction *AndInst =
        BinaryOperator::CreateAnd(ShiftLeft, TestResultVal, "highbit");
    RaisedBB->getInstList().push_back(AndInst);
    // Compare result of logical and operation to find if bit 31 is set SF
    // accordingly
    Instruction *SFTest =
        new ICmpInst(CmpInst::Predicate::ICMP_NE, AndInst, ZeroVal,
                     X86RegisterUtils::getEflagName(FlagBit));
    RaisedBB->getInstList().push_back(SFTest);
    physRegDefsInMBB[FlagBit][MBBNo].second = SFTest;
  } break;
  case X86RegisterUtils::EFLAGS::OF: {
    auto IntrinsicOF = Intrinsic::not_intrinsic;
    Value *TestArg[2];
    Module *M = x86MIRaiser->getModuleRaiser()->getModule();

    // If TestVal is a cast value, it is most likely cast to match the
    // source of the compare instruction. Get to the value prior to casting.
    CastInst *castInst = dyn_cast<CastInst>(TestResultVal);
    while (castInst) {
      TestResultVal = castInst->getOperand(0);
      castInst = dyn_cast<CastInst>(TestResultVal);
    }

    Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
    assert((TestInst != nullptr) && "Expect test producing instruction while "
                                    "testing and setting of EFLAGS");

    if ((x86MIRaiser->instrNameStartsWith(MI, "SUB")) ||
        (x86MIRaiser->instrNameStartsWith(MI, "CMP")) ||
        (x86MIRaiser->instrNameStartsWith(MI, "SBB"))) {
      IntrinsicOF = Intrinsic::ssub_with_overflow;
      TestArg[0] = TestInst->getOperand(0);
      TestArg[1] = TestInst->getOperand(1);
      assert((TestArg[0]->getType() == TestArg[1]->getType()) &&
             "Differing types of test values unexpected");

      // Construct a call to get overflow value upon comparison of test arg
      // values
      Function *ValueOF =
          Intrinsic::getDeclaration(M, IntrinsicOF, TestArg[0]->getType());
      CallInst *GetOF = CallInst::Create(
          cast<FunctionType>(
              cast<PointerType>(ValueOF->getType())->getElementType()),
          ValueOF, ArrayRef<Value *>(TestArg));
      RaisedBB->getInstList().push_back(GetOF);
      // Extract OF and set it
      physRegDefsInMBB[FlagBit][MBBNo].second =
          ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
    } else if (x86MIRaiser->instrNameStartsWith(MI, "ADD")) {
      IntrinsicOF = Intrinsic::sadd_with_overflow;
      TestArg[0] = TestInst->getOperand(0);
      TestArg[1] = TestInst->getOperand(1);
      assert((TestArg[0]->getType() == TestArg[1]->getType()) &&
             "Differing types of test values unexpected");

      // Construct a call to get overflow value upon comparison of test arg
      // values
      Function *ValueOF =
          Intrinsic::getDeclaration(M, IntrinsicOF, TestArg[0]->getType());
      CallInst *GetOF = CallInst::Create(
          cast<FunctionType>(
              cast<PointerType>(ValueOF->getType())->getElementType()),
          ValueOF, ArrayRef<Value *>(TestArg));
      RaisedBB->getInstList().push_back(GetOF);
      // Extract OF and set it
      physRegDefsInMBB[FlagBit][MBBNo].second =
          ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
    } else if (x86MIRaiser->instrNameStartsWith(MI, "ROL")) {
      // OF flag is defined only for 1-bit rotates i.e., ROLr*1).
      // It is undefined in all other cases. OF flag is set to the exclusive OR
      // of CF after rotate and the most-significant bit of the result.
      if ((MI.getNumExplicitOperands() == 2) &&
          (MI.findTiedOperandIdx(1) == 0)) {
        // CF flag receives a copy of the bit that was shifted from one end to
        // the other. Find the least-significant bit, which is the bit shifted
        // from the most-significant location.
        // NOTE: CF computation is repeated here, just to be sure.
        // Construct constant 1 of TestResultVal type
        Value *OneValue = ConstantInt::get(TestResultVal->getType(), 1);
        // Get LSB of TestResultVal using the instruction and TestResultVal, 1
        Instruction *ResultLSB = BinaryOperator::CreateAnd(
            TestResultVal, OneValue, "lsb-result", RaisedBB);
        // Set ResultCF to 1 if LSB is 1, else to 0
        Instruction *ResultCF = new ICmpInst(CmpInst::Predicate::ICMP_EQ,
                                             ResultLSB, OneValue, "CF-RES");
        // Insert compare instruction
        RaisedBB->getInstList().push_back(ResultCF);

        // Get most-significant bit of the result (i.e., TestResultVal)
        auto ResultNumBits = TestResultVal->getType()->getPrimitiveSizeInBits();
        // Construct a constant with only the most significant bit set
        Value *LeftShift =
            ConstantInt::get(TestResultVal->getType(), (ResultNumBits - 1));
        // Get (1 << LeftShift)
        Value *MSBSetConst = BinaryOperator::CreateShl(OneValue, LeftShift,
                                                       "MSB-CONST", RaisedBB);
        // Get (TestResultVal & MSBSetConst) to get the most significant bit of
        // TestResultVal
        Instruction *ResultMSB = BinaryOperator::CreateAnd(
            TestResultVal, MSBSetConst, "MSB-RES", RaisedBB);
        // Check if MSB is non-zero
        Value *ZeroValue = ConstantInt::get(ResultMSB->getType(), 0);
        // Generate (ResultMSB != 0) to indicate MSB
        Instruction *MSBIsSet = new ICmpInst(CmpInst::Predicate::ICMP_NE,
                                             ResultMSB, ZeroValue, "MSB-SET");
        RaisedBB->getInstList().push_back(dyn_cast<Instruction>(MSBIsSet));
        // Generate XOR ResultCF, MSBIsSet to compute OF
        Instruction *ResultOF =
            BinaryOperator::CreateXor(ResultCF, MSBIsSet, "OF", RaisedBB);
        physRegDefsInMBB[FlagBit][MBBNo].second = ResultOF;
      }
    } else if (x86MIRaiser->instrNameStartsWith(MI, "ROR")) {
      // OF flag is defined only for 1-bit rotates i.e., RORr*1).
      // It is undefined in all other cases. OF flag is set to the exclusive OR
      // of the two most-significant bits of the result.
      if ((MI.getNumExplicitOperands() == 2) &&
          (MI.findTiedOperandIdx(1) == 0)) {
        // Find most-significant bit of result.
        Value *OneValue = ConstantInt::get(TestResultVal->getType(), 1);

        // Get most-significant bit of the result (i.e., TestResultVal)
        auto ResultNumBits = TestResultVal->getType()->getPrimitiveSizeInBits();
        // Construct a constant with only the most significant bit set
        Value *LeftShift =
            ConstantInt::get(TestResultVal->getType(), (ResultNumBits - 1));
        // Get (1 << LeftShift)
        Value *BitSetConst = BinaryOperator::CreateShl(OneValue, LeftShift,
                                                       "MSB-CONST", RaisedBB);
        // Get (TestResultVal & MSBSetConst) to get the most significant bit of
        // TestResultVal
        Instruction *BitSetResult = BinaryOperator::CreateAnd(
            TestResultVal, BitSetConst, "MSB-RES", RaisedBB);
        // Check if MSB is non-zero
        Value *ZeroValue = ConstantInt::get(BitSetResult->getType(), 0);
        // Generate (BitSetResult != 0) to indicate MSB
        Instruction *MSBIsSet = new ICmpInst(
            CmpInst::Predicate::ICMP_NE, BitSetResult, ZeroValue, "MSB-SET");
        RaisedBB->getInstList().push_back(dyn_cast<Instruction>(MSBIsSet));

        // Construct a constant with only the pre-MSB location set
        LeftShift =
            ConstantInt::get(TestResultVal->getType(), (ResultNumBits - 2));
        // Get (1 << LeftShift)
        BitSetConst = BinaryOperator::CreateShl(OneValue, LeftShift,
                                                "Pre-MSB-CONST", RaisedBB);
        // Get (TestResultVal & BitSetConst) to get the pre-most significant bit
        // of TestResultVal
        BitSetResult = BinaryOperator::CreateAnd(TestResultVal, BitSetConst,
                                                 "Pre-MSB-RES", RaisedBB);
        // Check if pre-MSB is non-zero
        // Generate (BitSetResult != 0) to indicate pre-MSB
        Instruction *PreMSBIsSet =
            new ICmpInst(CmpInst::Predicate::ICMP_NE, BitSetResult, ZeroValue,
                         "Pre-MSB-SET");
        RaisedBB->getInstList().push_back(dyn_cast<Instruction>(PreMSBIsSet));

        // Generate XOR MSBIsSet, PreMSBIsSet to compute OF
        Instruction *ResultOF =
            BinaryOperator::CreateXor(MSBIsSet, PreMSBIsSet, "OF", RaisedBB);
        physRegDefsInMBB[FlagBit][MBBNo].second = ResultOF;
      }
    } else if (x86MIRaiser->instrNameStartsWith(MI, "TEST")) {
      // Set CF to 0 and make type to i1
      physRegDefsInMBB[FlagBit][MBBNo].second =
          ConstantInt::get(Type::getInt1Ty(Ctx), 0);
    } else {
      LLVM_DEBUG(MI.dump());
      assert(false && "*** EFLAGS update abstraction not handled yet");
    }
  } break;
  case X86RegisterUtils::EFLAGS::PF: {
    // PF is set if least-significant byte of the result contains an even number
    // of 1 bits; else the flag is cleared.
    Module *M = x86MIRaiser->getModuleRaiser()->getModule();

    Value *SrcVal = TestResultVal;

    if (SrcVal->getType()->isIntegerTy() &&
        SrcVal->getType()->getIntegerBitWidth() > 8) {
      // Get least-significant byte
      Instruction *LSB = BinaryOperator::CreateAnd(
          SrcVal, ConstantInt::get(SrcVal->getType(), 0xff));
      RaisedBB->getInstList().push_back(LSB);
      SrcVal = LSB;
    }

    Function *IntrinsicFunc =
        Intrinsic::getDeclaration(M, Intrinsic::ctpop, SrcVal->getType());
    Value *IntrinsicCallArgs[] = {SrcVal};
    Instruction *ParityValue =
        CallInst::Create(IntrinsicFunc, ArrayRef<Value *>(IntrinsicCallArgs));

    // Add the intrinsic call instruction
    RaisedBB->getInstList().push_back(ParityValue);

    Instruction *ParityEvenBit = BinaryOperator::CreateAnd(
        ParityValue, ConstantInt::get(ParityValue->getType(), 1));
    RaisedBB->getInstList().push_back(ParityEvenBit);

    // Test if ParityEvenBit is Zero
    Value *ZeroValue =
        ConstantInt::get(ParityEvenBit->getType(), 0, false /* isSigned */);
    Instruction *PFTest = new ICmpInst(CmpInst::Predicate::ICMP_EQ,
                                       ParityEvenBit, ZeroValue, "PF");
    RaisedBB->getInstList().push_back(PFTest);
    physRegDefsInMBB[FlagBit][MBBNo].second = PFTest;
  } break;
  case X86RegisterUtils::EFLAGS::CF: {
    Module *M = x86MIRaiser->getModuleRaiser()->getModule();
    Value *NewCF = nullptr;

    // If TestVal is a cast value, it is most likely cast to match the
    // source of the compare instruction. Get to the value prior to casting.
    CastInst *castInst = dyn_cast<CastInst>(TestResultVal);
    while (castInst) {
      TestResultVal = castInst->getOperand(0);
      castInst = dyn_cast<CastInst>(TestResultVal);
    }

    if (x86MIRaiser->instrNameStartsWith(MI, "NEG")) {
      // Set CF to 0 if source operand is 0 else to 1
      Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
      assert((TestInst != nullptr) && "Expect test producing instruction while "
                                      "testing and setting of EFLAGS");
      // TestInst should be a sub 0, val instruction
      assert((TestInst->getOpcode() == Instruction::Sub) &&
             "Expect NEG to be raised as SUB");
      // Get the arguments of the sub instruction that computes the neg
      Value *TestArg[2];
      TestArg[0] = TestInst->getOperand(0);
      TestArg[1] = TestInst->getOperand(1);
      assert((TestArg[0]->getType() == TestArg[1]->getType()) &&
             "Differing types of test values not expected");
      // A zero value of appropriate type
      Value *ZeroVal =
          ConstantFP::getZeroValueForNegation(TestArg[1]->getType());
      assert(((TestArg[0] == ZeroVal)) &&
             "Expected zero value of sub instruction while updating CF for NEG "
             "instruction");
      // Set ZF - test if TestVal is not equal to 0 - to get the CF bit value.
      Instruction *CmpInst =
          new ICmpInst(CmpInst::Predicate::ICMP_NE, TestArg[0], ZeroVal,
                       X86RegisterUtils::getEflagName(FlagBit));
      RaisedBB->getInstList().push_back(CmpInst);
      NewCF = CmpInst;
    } else if ((x86MIRaiser->instrNameStartsWith(MI, "SUB")) ||
               (x86MIRaiser->instrNameStartsWith(MI, "CMP")) ||
               (x86MIRaiser->instrNameStartsWith(MI, "SBB"))) {
      Value *TestArg[2];
      Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
      assert((TestInst != nullptr) && "Expect test producing instruction while "
                                      "testing and setting of EFLAGS");
      TestArg[0] = TestInst->getOperand(0);
      TestArg[1] = TestInst->getOperand(1);
      assert((TestArg[0]->getType() == TestArg[1]->getType()) &&
             "Differing types of test values not expected");
      // Construct a call to get carry flag value upon comparison of test arg
      // values
      Function *ValueCF = Intrinsic::getDeclaration(
          M, Intrinsic::usub_with_overflow, TestArg[0]->getType());
      CallInst *GetCF = CallInst::Create(
          cast<FunctionType>(
              cast<PointerType>(ValueCF->getType())->getElementType()),
          ValueCF, ArrayRef<Value *>(TestArg));
      RaisedBB->getInstList().push_back(GetCF);
      // Extract flag-bit
      NewCF = ExtractValueInst::Create(GetCF, 1, "CF", RaisedBB);
    } else if (x86MIRaiser->instrNameStartsWith(MI, "ADD")) {
      Value *TestArg[2];
      Instruction *TestInst = dyn_cast<Instruction>(TestResultVal);
      assert((TestInst != nullptr) && "Expect test producing instruction while "
                                      "testing and setting of EFLAGS");
      TestArg[0] = TestInst->getOperand(0);
      TestArg[1] = TestInst->getOperand(1);
      assert((TestArg[0]->getType() == TestArg[1]->getType()) &&
             "Differing types of test values not expected");
      // Construct a call to get carry flag value upon comparison of test arg
      // values
      Function *ValueCF = Intrinsic::getDeclaration(
          M, Intrinsic::uadd_with_overflow, TestArg[0]->getType());
      CallInst *GetCF = CallInst::Create(
          cast<FunctionType>(
              cast<PointerType>(ValueCF->getType())->getElementType()),
          ValueCF, ArrayRef<Value *>(TestArg));
      RaisedBB->getInstList().push_back(GetCF);
      // Extract flag-bit
      NewCF = ExtractValueInst::Create(GetCF, 1, "CF", RaisedBB);
    } else if (x86MIRaiser->instrNameStartsWith(MI, "SHRD")) {
      // TestInst should have been a call to intrinsic llvm.fshr.*
      CallInst *IntrinsicCall = dyn_cast<CallInst>(TestResultVal);
      assert((IntrinsicCall != nullptr) &&
             (IntrinsicCall->getFunctionType()->getNumParams() == 3) &&
             "Expected call instruction with three arguments not found");
      Value *DstArgVal = IntrinsicCall->getArgOperand(1);
      Value *CountArgVal = IntrinsicCall->getArgOperand(2);
      // If count is 1 or greater, CF is filled with the last bit shifted out
      // of destination operand.
      Value *ZeroVal = ConstantInt::get(
          Ctx, APInt(CountArgVal->getType()->getPrimitiveSizeInBits(), 0));
      Instruction *CountValTest =
          new ICmpInst(CmpInst::Predicate::ICMP_SGT, CountArgVal, ZeroVal,
                       "shrd_cf_count_cmp");
      RaisedBB->getInstList().push_back(CountValTest);

      // The last bit shifted out of destination operand is the
      // least-significant N'th bit where N == CountVal. So get that value as
      // follows:
      // if (DestVal & (1 << N))
      //   CF = 1
      // else
      //   CF = 0
      Instruction *ShlInst =
          BinaryOperator::CreateShl(ConstantInt::get(CountArgVal->getType(), 1),
                                    CountArgVal, "shrd_cf_count_shift");
      RaisedBB->getInstList().push_back(ShlInst);
      Instruction *AndInst =
          BinaryOperator::CreateAnd(DstArgVal, ShlInst, "shrd_cf_count_and");

      RaisedBB->getInstList().push_back(AndInst);

      // Is it Zero
      Instruction *NewCFInst =
          new ICmpInst(CmpInst::Predicate::ICMP_SGT, AndInst, ZeroVal,
                       "shrd_cf_count_shft_out");

      RaisedBB->getInstList().push_back(NewCFInst);

      Value *OldCF = physRegDefsInMBB[FlagBit][MBBNo].second;
      if (OldCF == nullptr) {
        // if CF is undefined, assume CF = 0
        LLVMContext &Ctx(MF.getFunction().getContext());
        OldCF = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
      }

      // Select the value of CF based on Count value being > 0
      Instruction *SelectCF =
          SelectInst::Create(CountValTest, NewCFInst, OldCF, "shrd_cf_update");
      RaisedBB->getInstList().push_back(SelectCF);

      NewCF = SelectCF;
    } else if (x86MIRaiser->instrNameStartsWith(MI, "SHL") ||
               x86MIRaiser->instrNameStartsWith(MI, "SHR") ||
               x86MIRaiser->instrNameStartsWith(MI, "SAR")) {
      Value *DstArgVal = nullptr;
      Value *CountArgVal = nullptr;
      // If this is a funnel shift
      if (x86MIRaiser->instrNameStartsWith(MI, "SHLD")) {
        // TestInst should have been a call to intrinsic llvm.fshl.*
        CallInst *IntrinsicCall = dyn_cast<CallInst>(TestResultVal);
        assert((IntrinsicCall != nullptr) &&
               (IntrinsicCall->getFunctionType()->getNumParams() == 3) &&
               "Expected call instruction with three arguments not found");
        DstArgVal = IntrinsicCall->getArgOperand(0);
        CountArgVal = IntrinsicCall->getArgOperand(2);
      } else {
        // TestInst should have been shl/shr/sar instruction
        BinaryOperator *BinOp = dyn_cast<BinaryOperator>(TestResultVal);
        assert((BinOp != nullptr) && (BinOp->getNumOperands() == 2) &&
               "Expected a shl binary operator with 2 operands");
        DstArgVal = BinOp->getOperand(0);
        CountArgVal = BinOp->getOperand(1);
      }
      // If count is 1 or greater, CF is filled with the last bit shifted out
      // of destination operand.
      Value *ZeroVal = ConstantInt::get(
          Ctx, APInt(CountArgVal->getType()->getPrimitiveSizeInBits(), 0));
      Instruction *CountValTest =
          new ICmpInst(CmpInst::Predicate::ICMP_SGT, CountArgVal, ZeroVal,
                       "shrd_cf_count_cmp");
      RaisedBB->getInstList().push_back(CountValTest);

      // The last bit shifted out of destination operand is the
      // least-significant N'th bit where TypeSize =
      // DstArgVal->getType()->getPrimitiveSizeInBits()) and
      // N == (TypeSize - CountVal).
      // So get that value as follows:
      // if (DestVal & (1 << N))
      //   CF = 1
      // else
      //   CF = 0
      Value *TypeSizeVal =
          ConstantInt::get(CountArgVal->getType(),
                           DstArgVal->getType()->getPrimitiveSizeInBits());

      Instruction *ShiftAmt =
          BinaryOperator::CreateSub(TypeSizeVal, CountArgVal);

      RaisedBB->getInstList().push_back(ShiftAmt);

      // Shift 1 by ShiftAmt
      Instruction *ShlInst =
          BinaryOperator::CreateShl(ConstantInt::get(CountArgVal->getType(), 1),
                                    ShiftAmt, "shld_cf_count_shift");
      RaisedBB->getInstList().push_back(ShlInst);

      Instruction *AndInst =
          BinaryOperator::CreateAnd(DstArgVal, ShlInst, "shld_cf_count_and");

      RaisedBB->getInstList().push_back(AndInst);

      // Is it Zero
      Instruction *NewCFInst =
          new ICmpInst(CmpInst::Predicate::ICMP_SGT, AndInst, ZeroVal,
                       "shld_cf_count_shft_out");

      RaisedBB->getInstList().push_back(NewCFInst);

      Value *OldCF = physRegDefsInMBB[FlagBit][MBBNo].second;
      if (OldCF == nullptr) {
        // if CF is undefined, assume CF = 0
        LLVMContext &Ctx(MF.getFunction().getContext());
        OldCF = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
      }
      // Select the value of CF based on Count value being > 0
      Instruction *SelectCF =
          SelectInst::Create(CountValTest, NewCFInst, OldCF, "shld_cf_update");
      RaisedBB->getInstList().push_back(SelectCF);

      NewCF = SelectCF;
    } else if (x86MIRaiser->instrNameStartsWith(MI, "ROL")) {
      // CF flag receives a copy of the bit that was shifted from one end to
      // the other. Find the least-significant bit, which is the bit shifted
      // from the most-significant location.
      // NOTE: CF computation is repeated here, just to be sure.
      // Construct constant 1 of TestResultVal type
      Value *OneValue = ConstantInt::get(TestResultVal->getType(), 1);
      // Get LSB of TestResultVal using the instruction and TestResultVal, 1
      Instruction *ResultLSB = BinaryOperator::CreateAnd(
          TestResultVal, OneValue, "lsb-result", RaisedBB);
      // Set ResultCF to 1 if LSB is 1, else to 0
      Instruction *ResultCF = new ICmpInst(CmpInst::Predicate::ICMP_EQ,
                                           ResultLSB, OneValue, "CF-RES");
      // Insert compare instruction
      RaisedBB->getInstList().push_back(ResultCF);
      NewCF = ResultCF;
    } else if (x86MIRaiser->instrNameStartsWith(MI, "ROR")) {
      // CF flag receives a copy of the bit that was shifted from one end to
      // the other. Find the most-significant bit, which is the bit shifted
      // from the least-significant location.
      // Find most-significant bit of result.
      Value *OneValue = ConstantInt::get(TestResultVal->getType(), 1);

      // Get most-significant bit of the result (i.e., TestResultVal)
      auto ResultNumBits = TestResultVal->getType()->getPrimitiveSizeInBits();
      // Construct a constant with only the most significant bit set
      Value *LeftShift =
          ConstantInt::get(TestResultVal->getType(), (ResultNumBits - 1));
      // Get (1 << LeftShift)
      Value *BitSetConst =
          BinaryOperator::CreateShl(OneValue, LeftShift, "MSB-CONST", RaisedBB);
      // Get (TestResultVal & MSBSetConst) to get the most significant bit of
      // TestResultVal
      Instruction *BitSetResult = BinaryOperator::CreateAnd(
          TestResultVal, BitSetConst, "MSB-RES", RaisedBB);
      // Check if MSB is non-zero
      Value *ZeroValue = ConstantInt::get(BitSetResult->getType(), 0);
      // Generate (BitSetResult != 0) to indicate MSB
      Instruction *MSBIsSet = new ICmpInst(CmpInst::Predicate::ICMP_NE,
                                           BitSetResult, ZeroValue, "MSB-SET");
      RaisedBB->getInstList().push_back(dyn_cast<Instruction>(MSBIsSet));
      NewCF = MSBIsSet;
    } else if (x86MIRaiser->instrNameStartsWith(MI, "IMUL")) {
      // TestInst should have been mul instruction
      BinaryOperator *TestInst = dyn_cast<BinaryOperator>(TestResultVal);
      assert((TestInst != nullptr) && (TestInst->getNumOperands() == 2) &&
             "Expected a mul binary operator with 2 operands");
      Value *TestArg[2];
      TestArg[0] = TestInst->getOperand(0);
      TestArg[1] = TestInst->getOperand(1);
      assert((TestArg[0]->getType() == TestArg[1]->getType()) &&
             "Differing types of test values unexpected");

      // Construct a call to get overflow value upon comparison of test arg
      // values.
      Function *ValueOF = Intrinsic::getDeclaration(
          M, Intrinsic::smul_with_overflow, TestArg[0]->getType());
      CallInst *GetOF = CallInst::Create(
          cast<FunctionType>(
              cast<PointerType>(ValueOF->getType())->getElementType()),
          ValueOF, ArrayRef<Value *>(TestArg));
      RaisedBB->getInstList().push_back(GetOF);
      // Extract OF and set both OF and CF to the same value
      auto NewOF = ExtractValueInst::Create(GetOF, 1, "OF", RaisedBB);
      physRegDefsInMBB[EFLAGS::OF][MBBNo].second = NewOF;
      NewCF = NewOF;
      // Set OF to the same value of CF
      physRegDefsInMBB[EFLAGS::OF][MBBNo].second = NewCF;
    } else if (x86MIRaiser->instrNameStartsWith(MI, "TEST")) {
      // Set CF to 0 and make type to i1
      NewCF = ConstantInt::get(Type::getInt1Ty(Ctx), 0);
    } else {
      LLVM_DEBUG(MI.dump());
      assert(false &&
             "*** Abstraction of CF for the instruction not handled yet");
    }
    // Update CF.
    assert((NewCF != nullptr) && "Value to update CF not found");
    physRegDefsInMBB[FlagBit][MBBNo].second = NewCF;
  } break;

  // TODO: Add code to test for other flags
  default:
    assert(false && "Unhandled EFLAGS bit specified");
  }
  // EFLAGS bit size is 1
  physRegDefsInMBB[FlagBit][MBBNo].first = 1;
  return true;
}