Example #1
0
/// \brief Emit materialization code for all rebased constants and update their
/// users.
void ConstantHoisting::EmitBaseConstants(Function &F, User *U,
                                         Instruction *Base, Constant *Offset,
                                         ConstantInt *OriginalConstant) {
  if (Instruction *I = dyn_cast<Instruction>(U)) {
    Instruction *Mat = Base;
    if (!Offset->isNullValue()) {
      Mat = BinaryOperator::Create(Instruction::Add, Base, Offset,
                                   "const_mat", getMatInsertPt(I, DT));

      // Use the same debug location as the instruction we are about to update.
      Mat->setDebugLoc(I->getDebugLoc());

      DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0)
                   << " + " << *Offset << ") in BB "
                   << I->getParent()->getName() << '\n' << *Mat << '\n');
    }
    DEBUG(dbgs() << "Update: " << *I << '\n');
    I->replaceUsesOfWith(OriginalConstant, Mat);
    DEBUG(dbgs() << "To: " << *I << '\n');
    return;
  }
  assert(isa<ConstantExpr>(U) && "Expected a ConstantExpr.");
  ConstantExpr *CE = cast<ConstantExpr>(U);
  for (Value::use_iterator UU = CE->use_begin(), E = CE->use_end();
       UU != E; ++UU) {
    // We only handel instructions here and won't walk down a ConstantExpr chain
    // to replace all ConstExpr with instructions.
    if (Instruction *I = dyn_cast<Instruction>(*UU)) {
      // Only update constant expressions in the current function.
      if (I->getParent()->getParent() != &F)
        continue;

      Instruction *Mat = Base;
      Instruction *InsertBefore = getMatInsertPt(I, DT);
      if (!Offset->isNullValue()) {
        Mat = BinaryOperator::Create(Instruction::Add, Base, Offset,
                                     "const_mat", InsertBefore);

        // Use the same debug location as the instruction we are about to
        // update.
        Mat->setDebugLoc(I->getDebugLoc());

        DEBUG(dbgs() << "Materialize constant (" << *Base->getOperand(0)
                     << " + " << *Offset << ") in BB "
                     << I->getParent()->getName() << '\n' << *Mat << '\n');
      }
      Instruction *ICE = CE->getAsInstruction();
      ICE->replaceUsesOfWith(OriginalConstant, Mat);
      ICE->insertBefore(InsertBefore);

      // Use the same debug location as the instruction we are about to update.
      ICE->setDebugLoc(I->getDebugLoc());

      DEBUG(dbgs() << "Create instruction: " << *ICE << '\n');
      DEBUG(dbgs() << "Update: " << *I << '\n');
      I->replaceUsesOfWith(CE, ICE);
      DEBUG(dbgs() << "To: " << *I << '\n');
    }
  }
}
Example #2
0
// Breaks down a constraint into all of it's individual pieces, returning a
// list of IndependentElementSets or the independent factors.
//
// Caller takes ownership of returned std::list.
static std::list<IndependentElementSet>*
getAllIndependentConstraintsSets(const Query &query) {
  std::list<IndependentElementSet> *factors = new std::list<IndependentElementSet>();
  ConstantExpr *CE = dyn_cast<ConstantExpr>(query.expr);
  if (CE) {
    assert(CE && CE->isFalse() && "the expr should always be false and "
                                  "therefore not included in factors");
  } else {
    ref<Expr> neg = Expr::createIsZero(query.expr);
    factors->push_back(IndependentElementSet(neg));
  }

  for (ConstraintManager::const_iterator it = query.constraints.begin(),
                                         ie = query.constraints.end();
       it != ie; ++it) {
    // iterate through all the previously separated constraints.  Until we
    // actually return, factors is treated as a queue of expressions to be
    // evaluated.  If the queue property isn't maintained, then the exprs
    // could be returned in an order different from how they came it, negatively
    // affecting later stages.
    factors->push_back(IndependentElementSet(*it));
  }

  bool doneLoop = false;
  do {
    doneLoop = true;
    std::list<IndependentElementSet> *done =
        new std::list<IndependentElementSet>;
    while (factors->size() > 0) {
      IndependentElementSet current = factors->front();
      factors->pop_front();
      // This list represents the set of factors that are separate from current.
      // Those that are not inserted into this list (queue) intersect with
      // current.
      std::list<IndependentElementSet> *keep =
          new std::list<IndependentElementSet>;
      while (factors->size() > 0) {
        IndependentElementSet compare = factors->front();
        factors->pop_front();
        if (current.intersects(compare)) {
          if (current.add(compare)) {
            // Means that we have added (z=y)added to (x=y)
            // Now need to see if there are any (z=?)'s
            doneLoop = false;
          }
        } else {
          keep->push_back(compare);
        }
      }
      done->push_back(current);
      delete factors;
      factors = keep;
    }
    delete factors;
    factors = done;
  } while (!doneLoop);

  return factors;
}
Example #3
0
void ControlFlowIntegrity::PatchDtorFunctions(void) {
  GlobalVariable *global_dtors = _M.getNamedGlobal("llvm.global_dtors");

  // check for dtor section
  if (!global_dtors || !global_dtors->getOperand(0)) {
    return;
  }

  Constant *c = global_dtors->getInitializer();
  if (!c)
    report_fatal_error("llvm.global_dtors without initializer!", false);

  ConstantArray *CA = dyn_cast<ConstantArray>(c);
  if (!CA)
    report_fatal_error("Cast to ConstantArray failed", true);

  for (Value *Op : ValueOpRange(*CA)) {
    ConstantStruct *CS = dyn_cast<ConstantStruct>(Op);
    if (!CS)
      report_fatal_error("Cast to ConstantStruct failed", true);

    Constant *FP = CS->getOperand(1);
    if (FP->isNullValue())
      break; // found a NULL termintator, stop here

    Function *F = dyn_cast_or_null<Function>(FP);
    if (F == NULL) {
      // Strip off constant expression cast
      ConstantExpr *CE = dyn_cast<ConstantExpr>(FP);
      if (!CE)
        report_fatal_error("Cast to ConstantExpr failed", true);
      if (CE->isCast()) {
        FP = CE->getOperand(0);
      }
      F = dyn_cast_or_null<Function>(FP);
    }

    if (!F)
      report_fatal_error("Cast to Function failed", true);

    // set visibility to hidden (do not export), unless it is already
    // local (for ex. static), in which case we have to make it non-static
    if (F->hasLocalLinkage()) {
      F->setLinkage(llvm::GlobalValue::ExternalLinkage);
    }
    F->setVisibility(GlobalValue::HiddenVisibility);

    _FiniFunctions.insert(F->getName());
  }

  if (global_dtors->getNumUses() > 0)
    report_fatal_error("llvm.global_dtors uses count is > 0!", false);

  global_dtors->removeFromParent();

}
Example #4
0
void ClassHierarchyUtils::findClassHierarchy(Module& M) {
  // extract call hierarchy using std::type_info structures rather
  // than debug info. The former works even for when there are anonymous
  // namespaces. type_info structs can be obtained from vtable globals.
  // (for more info, see http://mentorembedded.github.io/cxx-abi/abi.html)
  for (Module::global_iterator I=M.global_begin(), E=M.global_end(); I != E; I++) {
    GlobalVariable* G = &*I;
    if (G->getName().startswith("_ZTV")) {
      if (G->hasInitializer()) {
        SDEBUG("soaap.util.classhierarchy", 3, G->dump());
        ConstantArray* Ginit = cast<ConstantArray>(G->getInitializer());
        // Ginit[1] is the type_info global for this vtable's type
        bool typeInfoFound = false;
        bool primaryVTable = true;
        for (int i=0; i<Ginit->getNumOperands(); i++) {
          // typeinfo will be the first global variable in the array.
          // It's not always at a fixed index so we have to search for it...
          if (GlobalVariable* TI = dyn_cast<GlobalVariable>(Ginit->getOperand(i)->stripPointerCasts())) {
            //TI->dump();
            typeInfoToVTable[TI] = G;
            vTableToTypeInfo[G] = TI;
            processTypeInfo(TI); // process TI recursively (it contains refs to super-class TIs)
            typeInfoFound = true;
            if (primaryVTable) {
              primaryVTable = false;
              vTableToSecondaryVTableMaps[G][0] = i+1;  // i+1 is also the size of the vtable header            
            }
            else {
              // offset_to_top is at the previous index 
              ConstantExpr* offsetValCast = cast<ConstantExpr>(Ginit->getOperand(i-1)->stripPointerCasts());
              ConstantInt* offsetVal = cast<ConstantInt>(offsetValCast->getOperand(0)); 
              int offsetToTop = offsetVal->getSExtValue();
              if (offsetToTop > 0) {
                dbgs() << "ERROR: offsetToTop is positive!\n";
                G->dump();
              }
              else {
                offsetToTop *= -1;
              }
              
              SDEBUG("soaap.util.classhierarchy", 3, dbgs() << "offsetToTop: " << offsetToTop << "\n");
              vTableToSecondaryVTableMaps[G][offsetToTop] = i+1;
            }
          }
        }

        if (!typeInfoFound) {
          dbgs() << "ERROR: vtable initializer is not a global variable...\n";
          dbgs() << *G << " = " << *Ginit << "\n";
        }
      }
    }
  }
  
  SDEBUG("soaap.util.classhierarchy", 3, ppClassHierarchy(classToSubclasses));
}
/// AddCatchInfo - Extract the personality and type infos from an eh.selector
/// call, and add them to the specified machine basic block.
void llvm::AddCatchInfo(CallInst &I, MachineModuleInfo *MMI,
                        MachineBasicBlock *MBB) {
  // Inform the MachineModuleInfo of the personality for this landing pad.
  ConstantExpr *CE = cast<ConstantExpr>(I.getOperand(2));
  assert(CE->getOpcode() == Instruction::BitCast &&
         isa<Function>(CE->getOperand(0)) &&
         "Personality should be a function");
  MMI->addPersonality(MBB, cast<Function>(CE->getOperand(0)));

  // Gather all the type infos for this landing pad and pass them along to
  // MachineModuleInfo.
  std::vector<GlobalVariable *> TyInfo;
  unsigned N = I.getNumOperands();

  for (unsigned i = N - 1; i > 2; --i) {
    if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i))) {
      unsigned FilterLength = CI->getZExtValue();
      unsigned FirstCatch = i + FilterLength + !FilterLength;
      assert (FirstCatch <= N && "Invalid filter length");

      if (FirstCatch < N) {
        TyInfo.reserve(N - FirstCatch);
        for (unsigned j = FirstCatch; j < N; ++j)
          TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
        MMI->addCatchTypeInfo(MBB, TyInfo);
        TyInfo.clear();
      }

      if (!FilterLength) {
        // Cleanup.
        MMI->addCleanup(MBB);
      } else {
        // Filter.
        TyInfo.reserve(FilterLength - 1);
        for (unsigned j = i + 1; j < FirstCatch; ++j)
          TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
        MMI->addFilterTypeInfo(MBB, TyInfo);
        TyInfo.clear();
      }

      N = i;
    }
  }

  if (N > 3) {
    TyInfo.reserve(N - 3);
    for (unsigned j = 3; j < N; ++j)
      TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
    MMI->addCatchTypeInfo(MBB, TyInfo);
  }
}
Example #6
0
GlobalValue *GlobalAlias::getAliasedGlobal() {
  Constant *C = getAliasee();
  if (C == 0) return 0;
  
  if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
    return GV;

  ConstantExpr *CE = cast<ConstantExpr>(C);
  assert((CE->getOpcode() == Instruction::BitCast ||
          CE->getOpcode() == Instruction::AddrSpaceCast ||
          CE->getOpcode() == Instruction::GetElementPtr) &&
         "Unsupported aliasee");
  
  return cast<GlobalValue>(CE->getOperand(0));
}
static GlobalValue *getAliaseeGV(GlobalAlias *GA) {
  Constant *C = GA->getAliasee();
  assert(C && "Must alias something");

  if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
    return GV;

  ConstantExpr *CE = cast<ConstantExpr>(C);
  assert((CE->getOpcode() == Instruction::BitCast ||
          CE->getOpcode() == Instruction::AddrSpaceCast ||
          CE->getOpcode() == Instruction::GetElementPtr) &&
         "Unsupported aliasee");

  return cast<GlobalValue>(CE->getOperand(0));
}
Example #8
0
void DebugDatabase::getGEPBaseAndOffset(ConstantExpr *GEP, Value **getBase,
                                        int *getOffset) {
    int offset = 0;
    Value *base = NULL;

    User *baseAddress = GEP->getOperand(0);
    ConstantExpr *CE = dyn_cast<ConstantExpr>(baseAddress);

    if (CE && CE->getOpcode() == Instruction::GetElementPtr) {
        // Nested GEP
        getGEPBaseAndOffset(CE, &base, &offset);
    } else if (isa<GlobalVariable>(baseAddress) ||
               isa<AllocaInst>(baseAddress)) {
        base = baseAddress;
    } else {
        assert(false);
    }

    assert(base);

    gep_type_iterator GTI = gep_type_begin(GEP);
    for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e;
         ++i, ++GTI) {
        Value *Op = *i;

        // Build a mask for high order bits.
        const DataLayout *TD = dbgInfo->getAlloc()->getDataLayout();
        unsigned IntPtrWidth = TD->getPointerSizeInBits();
        uint64_t PtrSizeMask = ~0ULL >> (64 - IntPtrWidth);

        // apply mask
        uint64_t Size =
            TD->getTypeAllocSize(GTI.getIndexedType()) & PtrSizeMask;

        assert(isa<ConstantInt>(Op));
        if (ConstantInt *OpC = dyn_cast<ConstantInt>(Op)) {
            // Handle a struct index, which adds its field offset.
            if (StructType *STy = dyn_cast<StructType>(*GTI)) {
                offset += TD->getStructLayout(STy)
                              ->getElementOffset(OpC->getZExtValue());
            } else {
                offset += Size * OpC->getValue().getSExtValue();
            }
        }
    }
    *getBase = base;
    *getOffset = offset;
}
Example #9
0
static Constant*
sd_getDestructorFunction(Constant* vtblElement) {
  ConstantExpr* bcExpr = NULL;

  // if this a constant bitcast expression, this might be a vthunk
  if ((bcExpr = dyn_cast<ConstantExpr>(vtblElement)) && bcExpr->getOpcode() == BITCAST_OPCODE) {
    Constant* operand = bcExpr->getOperand(0);

    // this is a vthunk
    if (sd_isDestructorName(operand->getName())) {
      return operand;
    }
  }

  return NULL;
}
ref<Expr> BitfieldSimplifier::replaceWithConstant(ref<Expr> e, uint64_t value)
{
    ConstantExpr *ce = dyn_cast<ConstantExpr>(e);
    if(ce && ce->getZExtValue() == value)
        return e;

    // Remove kids from cache
    unsigned numKids = e->getNumKids();
    for(unsigned i = 0; i < numKids; ++i)
        m_bitsInfoCache.erase(e->getKid(i));

    // Remove e from cache
    m_bitsInfoCache.erase(e);

    return ConstantExpr::create(value & ~zeroMask(e->getWidth()), e->getWidth());
}
Example #11
0
static Constant*
sd_isRTTI(Constant* vtblElement) {
  ConstantExpr* bcExpr = NULL;

  // if this a constant bitcast expression, this might be a vthunk
  if ((bcExpr = dyn_cast<ConstantExpr>(vtblElement)) &&
      bcExpr->getOpcode() == Instruction::BitCast) {
    Constant* operand = bcExpr->getOperand(0);

    // this is a vthunk
    if (operand->getName().startswith("_ZTI")) {
      return operand;
    }
  }

  return NULL;
}
Example #12
0
std::string readAnnotate(Function *f) {
  std::string annotation = "";

  // Get annotation variable
  GlobalVariable *glob =
      f->getParent()->getGlobalVariable("llvm.global.annotations");

  if (glob != NULL) {
    // Get the array
    if (ConstantArray *ca = dyn_cast<ConstantArray>(glob->getInitializer())) {
      for (unsigned i = 0; i < ca->getNumOperands(); ++i) {
        // Get the struct
        if (ConstantStruct *structAn =
                dyn_cast<ConstantStruct>(ca->getOperand(i))) {
          if (ConstantExpr *expr =
                  dyn_cast<ConstantExpr>(structAn->getOperand(0))) {
            // If it's a bitcast we can check if the annotation is concerning
            // the current function
            if (expr->getOpcode() == Instruction::BitCast &&
                expr->getOperand(0) == f) {
              ConstantExpr *note = cast<ConstantExpr>(structAn->getOperand(1));
              // If it's a GetElementPtr, that means we found the variable
              // containing the annotations
              if (note->getOpcode() == Instruction::GetElementPtr) {
                if (GlobalVariable *annoteStr =
                        dyn_cast<GlobalVariable>(note->getOperand(0))) {
                  if (ConstantDataSequential *data =
                          dyn_cast<ConstantDataSequential>(
                              annoteStr->getInitializer())) {
                    if (data->isString()) {
                      annotation += data->getAsString().lower() + " ";
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return annotation;
}
/// IsConstantOffsetFromGlobal - If this constant is actually a constant offset
/// from a global, return the global and the constant.  Because of
/// constantexprs, this function is recursive.
static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
                                       int64_t &Offset, const TargetData &TD) {
  // Trivial case, constant is the global.
  if ((GV = dyn_cast<GlobalValue>(C))) {
    Offset = 0;
    return true;
  }
  
  // Otherwise, if this isn't a constant expr, bail out.
  ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
  if (!CE) return false;
  
  // Look through ptr->int and ptr->ptr casts.
  if (CE->getOpcode() == Instruction::PtrToInt ||
      CE->getOpcode() == Instruction::BitCast)
    return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, TD);
  
  // i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)    
  if (CE->getOpcode() == Instruction::GetElementPtr) {
    // Cannot compute this if the element type of the pointer is missing size
    // info.
    if (!cast<PointerType>(CE->getOperand(0)->getType())->getElementType()->isSized())
      return false;
    
    // If the base isn't a global+constant, we aren't either.
    if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, TD))
      return false;
    
    // Otherwise, add any offset that our operands provide.
    gep_type_iterator GTI = gep_type_begin(CE);
    for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i, ++GTI) {
      ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(i));
      if (!CI) return false;  // Index isn't a simple constant?
      if (CI->getZExtValue() == 0) continue;  // Not adding anything.
      
      if (const StructType *ST = dyn_cast<StructType>(*GTI)) {
        // N = N + Offset
        Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue());
      } else {
        const SequentialType *SQT = cast<SequentialType>(*GTI);
        Offset += TD.getTypeSize(SQT->getElementType())*CI->getSExtValue();
      }
    }
    return true;
  }
  
  return false;
}
Example #14
0
/**
 * 将ConstantExpr转换为对应的Constant类型
 */
Constant* Transfer::expr2Constant(Expr* expr, Type* type) {
	Constant* param = NULL;
	if (type->isIntegerTy()) {
		ConstantExpr* constantExpr = dyn_cast<ConstantExpr>(expr);
		param = ConstantInt::get(type, constantExpr->getAPValue());
	} else if (type->isFloatTy()) {
		ConstantExpr* constantExpr = dyn_cast<ConstantExpr>(expr);
		APFloat apValue(APFloat::IEEEsingle, constantExpr->getAPValue());
		param = ConstantFP::get(type->getContext(), apValue);
	} else if (type->isDoubleTy()) {
		ConstantExpr* constantExpr = dyn_cast<ConstantExpr>(expr);
		APFloat apValue(APFloat::IEEEdouble, constantExpr->getAPValue());
		param = ConstantFP::get(type->getContext(), apValue);
	} else if (type->isPointerTy()) {
		ConstantExpr* constantExpr = dyn_cast<ConstantExpr>(expr);
		param = ConstantInt::get(
				Type::getIntNTy(type->getContext(),
						Context::get().getPointerWidth()),
				constantExpr->getAPValue());
	} else {
		assert(0 && "not support type");
	}
	return param;
}
Example #15
0
z3::expr KQuery2Z3::eachExprToZ3(ref<Expr> &ele) {
	z3::expr res = z3_ctx.bool_val(true);

	switch (ele->getKind()) {

	case Expr::Constant: {
		ConstantExpr *ce = cast<ConstantExpr>(ele);
		Expr::Width width = ce->getWidth();

		if (ele.get()->isFloat) {
			//float point number
			//in z3 there is no difference between float and double
			//they are all real value.
			double temp = 1.0;
			if (width == 32) {
				llvm::APFloat resValue(llvm::APFloat::IEEEsingle,
						ce->getAPValue());
				temp = resValue.convertToFloat(); //the real float number,how to establish expr of z3
			} else if (width == 64) {
				llvm::APFloat resValue(llvm::APFloat::IEEEdouble,
						ce->getAPValue());
				temp = resValue.convertToDouble(); // the real double number.
			}
			Fraction frac;
			getFraction(temp, frac);
//			std::stringstream ss;
//			ss << temp;
//				std::cerr << "frac.num = " << frac.num << " "
//						<< "frac.den = " << frac.den << std::endl;
//			res = z3_ctx.real_val(ss.str().c_str());
			res = z3_ctx.real_val(frac.num, frac.den);
//				std::cerr << "float point value = " << res << std::endl;
		} else {
			if (width == Expr::Bool) {
				if (ce->isTrue()) {
					//that is true
					res = z3_ctx.bool_val(true);
				} else {
					//that is false
					res = z3_ctx.bool_val(false);
				}
			} else if (width != Expr::Fl80) {
				int temp = ce->getZExtValue();
//					std::cerr << "temp = " << temp << std::endl;
#if INT_ARITHMETIC
				res = z3_ctx.int_val(temp);
#else
				res = z3_ctx.bv_val(temp, BIT_WIDTH);
#endif

//	     			std::cerr << res;
			} else {
				assert(0 && "The Fl80 out, value bit number extends 64");
			}
		}
		return res;
	}

	case Expr::NotOptimized: {
		assert(0 && "don't handle NotOptimized expression");
		return res;
	}

	case Expr::Read: {
		//type char
		ReadExpr *re = cast<ReadExpr>(ele);
		assert(re && re->updates.root);
		const std::string varName = re->updates.root->name;
		if (re->getWidth() == Expr::Bool) {
			res = z3_ctx.bool_const(varName.c_str());
		} else {
#if INT_ARITHMETIC
				res = z3_ctx.constant(varName.c_str(), z3_ctx.int_sort());
#else
				res = z3_ctx.constant(varName.c_str(), z3_ctx.bv_sort(BIT_WIDTH));
#endif

		}
		return res;
	}

	case Expr::Select: {
		SelectExpr *se = cast<SelectExpr>(ele);

		z3::expr cond = eachExprToZ3(se->cond);
		z3::expr tExpr = eachExprToZ3(se->trueExpr);
		z3::expr fExpr = eachExprToZ3(se->falseExpr);

		res = z3::ite(cond, tExpr, fExpr);
		return res;
	}

	case Expr::Concat: {
		ConcatExpr *ce = cast<ConcatExpr>(ele);
		ReadExpr *re = NULL;
		if (ce->getKid(0)->getKind() == Expr::Read)
			re = cast<ReadExpr>(ce->getKid(0));
		else if (ce->getKid(1)->getKind() == Expr::Read)
			re = cast<ReadExpr>(ce->getKid(1));
		else if (ce->getKid(1)->getKind() == Expr::Concat){
			while (ce->getKid(1)->getKind() == Expr::Concat) {
				ce = cast<ConcatExpr>(ce->getKid(1));
			}
			re = cast<ReadExpr>(ce->getKid(1));
		} else {
			assert("file: kQuery2z3, Expr::Concat" && false);
		}
		const std::string varName = re->updates.root->name;
		if (re->updates.root->isFloat) {  //float point symbolics
//				std::cerr << "build float " << varName << std::endl;
			res = z3_ctx.constant(varName.c_str(), z3_ctx.real_sort());
		} else {

//			std::cerr << "build bitvector" << varName << std::endl;
			if (ele.get()->isFloat)
				res = z3_ctx.constant(varName.c_str(), z3_ctx.real_sort());
			else
#if INT_ARITHMETIC
				res = z3_ctx.constant(varName.c_str(), z3_ctx.int_sort());
#else
				res = z3_ctx.constant(varName.c_str(), z3_ctx.bv_sort(BIT_WIDTH));
#endif

		}
//			else {
//				assert("real concat operation happened in Expr::Concat\n"
//						"need to be handle in minutes");
//			}
		return res;
	}

		//Trunc and FPTrunc and FPtoSI and FPtoUI
	case Expr::Extract: {
		ExtractExpr * ee = cast<ExtractExpr>(ele);
		z3::expr src = eachExprToZ3(ee->expr);

//			std::cerr << "print in the Extract in kquery2z3\n";
//			ele->dump();
//			ee->expr.get()->dump();

		//convert to boolean value, that means the result
		//depends on the ExtractExpr's least significant
		//bytes.
		if (ee->expr.get()->isFloat && !ee->isFloat) {
			//handle fptosi and fptoui
//			std::cerr << "handle fptosi \n";
//			ele.get()->dump();
			try {
#if INT_ARITHMETIC
			z3::expr temp = z3::to_expr(z3_ctx, Z3_mk_real2int(z3_ctx, src));
#else
			z3::expr temp = z3::to_expr(z3_ctx, Z3_mk_real2int(z3_ctx, src));
			z3::expr vecTemp = z3::to_expr(z3_ctx,
					Z3_mk_int2bv(z3_ctx, BIT_WIDTH, temp));
#endif
			if (ee->width == Expr::Bool) {
				//handle double->bool the special
#if INT_ARITHMETIC
				res = z3::ite(temp, z3_ctx.bool_val(1), z3_ctx.bool_val(0));
#else
				res = z3::ite(
						z3::to_expr(z3_ctx,
								Z3_mk_extract(z3_ctx, 0, 0, vecTemp)),
								z3_ctx.bv_val(1, BIT_WIDTH), z3_ctx.bv_val(0, BIT_WIDTH));
#endif
			} else {
#if INT_ARITHMETIC
				res = temp;
#else
				res = vecTemp;
#endif
			}
			} catch (z3::exception &ex) {
				std::cerr << "exception = " << ex << std::endl;
			}
		} else if (!ee->expr.get()->isFloat && !ee->isFloat) {
			//handle trunc and fptrunc, both these instructions
			//have same type before or after convert.
			if (ee->width == Expr::Bool) {
				//handle int->bool the special
#if INT_ARITHMETIC
				res = z3::ite(src, z3_ctx.int_val(1), z3_ctx.int_val(0));
#else
				res = z3::ite(
						z3::to_expr(z3_ctx, Z3_mk_extract(z3_ctx, 0, 0, src)),
						z3_ctx.bv_val(1, BIT_WIDTH), z3_ctx.bv_val(0, BIT_WIDTH));
#endif

			} else {
				res = src;
			}
		} else {
			//float->float;
			res = src;
		}
		return res;
	}

		//ZExt SExt handle methods from encode.cpp
	case Expr::ZExt: {
		CastExpr * ce = cast<CastExpr>(ele);
		z3::expr src = eachExprToZ3(ce->src);

		if (ce->src.get()->getWidth() == Expr::Bool) {
#if INT_ARITHMETIC
				res = z3::ite(src, z3_ctx.int_val(1), z3_ctx.int_val(0));
#else
				res = z3::ite(src, z3_ctx.bv_val(1, BIT_WIDTH), z3_ctx.bv_val(0, BIT_WIDTH));
//				res = z3::ite(
//					z3::to_expr(z3_ctx, Z3_mk_extract(z3_ctx, 0, 0, src)),
//					z3_ctx.bool_val(true), z3_ctx.bool_val(false));
#endif
//			if (Z3_TRUE == Z3_algebraic_is_zero(z3_ctx, src)) {
//				res = z3_ctx.bool_val(false);
//			} else {
//				res = z3_ctx.bool_val(true);
//			}
		} else {
			res = src;
		}
		return res;
	}

	case Expr::SExt: {
		CastExpr * ce = cast<CastExpr>(ele);

		//convert int or unsigned int to float point
		//need to handle alone.
//			if (ce->isFloat) {
//				res = eachExprToZ3(ce->src, true);
//			} else {
		z3::expr src = eachExprToZ3(ce->src);
		if (ce->isFloat && !ce->src.get()->isFloat) {
			try {
#if INT_ARITHMETIC
			z3::expr realTemp = to_expr(z3_ctx, Z3_mk_int2real(z3_ctx, src));

#else
			z3::expr temp = to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, src, true));
			z3::expr realTemp = to_expr(z3_ctx, Z3_mk_int2real(z3_ctx, temp));
#endif
			res = realTemp;
			} catch (z3::exception &ex) {
				std::cerr << "exception = " << ex << std::endl;
			}
		} else if (!ce->isFloat && !ce->src.get()->isFloat) {
			if (ce->src.get()->getWidth() == Expr::Bool
					&& ce->width != Expr::Bool) {
#if INT_ARITHMETIC
				res = z3::ite(src, z3_ctx.int_val(1), z3_ctx.int_val(0));
#else
				res = z3::ite(src, z3_ctx.bv_val(1, BIT_WIDTH), z3_ctx.bv_val(0, BIT_WIDTH));
#endif
//				res = z3::ite(src, z3_ctx.bool_val(true), z3_ctx.bool_val(false));
//				res = z3::ite(
//						z3::to_expr(z3_ctx, Z3_mk_extract(z3_ctx, 0, 0, src)),
//						z3_ctx.bool_val(true), z3_ctx.bool_val(false));
			} else {
				res = src;
			}
		} else {
			res = src;
		}
//			}
		return res;
	}

	case Expr::Add: {
		AddExpr *ae = cast<AddExpr>(ele);
//			std::cerr << "Is this wrong?\n";
//			ae->left.get()->dump();
//			ae->right.get()->dump();
//			std::cerr << "Add expr show\n";
//			ele.get()->dump();


			// if one of the operand is a float point number
			// then the left and right are all float point number.
			if (ae->left.get()->isFloat || ae->right.get()->isFloat) {
				ae->left.get()->isFloat = true;
				ae->right.get()->isFloat = true;
			}
		z3::expr left = eachExprToZ3(ae->left);
		z3::expr right = eachExprToZ3(ae->right);

//		assert(
//				left.get_sort() == right.get_sort()
//						&& "sort between left and right are different in Expr::Add\n");

			res = left + right;
			return res;
		}

		case Expr::Sub: {
			SubExpr *se = cast<SubExpr>(ele);
			if (se->left.get()->isFloat || se->right.get()->isFloat) {
				se->left.get()->isFloat = true;
				se->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(se->left);
			z3::expr right = eachExprToZ3(se->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Sub\n");

		res = left - right;
		return res;
	}

		case Expr::Mul: {
			MulExpr *me = cast<MulExpr>(ele);
			if (me->left.get()->isFloat || me->right.get()->isFloat) {
				me->left.get()->isFloat = true;
				me->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(me->left);
			z3::expr right = eachExprToZ3(me->right);
//			std::cerr << left << "\n";
//			std::cerr << right << "\n";
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Mul\n");


		res = left * right;
		return res;
	}

	case Expr::UDiv: {
		//could handled with SDiv, but for test just do in here.
			UDivExpr *ue = cast<UDivExpr>(ele);
			if (ue->left.get()->isFloat || ue->right.get()->isFloat) {
				ue->left.get()->isFloat = true;
				ue->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(ue->left);
			z3::expr right = eachExprToZ3(ue->right);
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::UDiv\n");
		try {
			if (left.is_bv()) {
				res = z3::to_expr(z3_ctx, Z3_mk_bvudiv(z3_ctx, left, right));
			} else {
				res = z3::to_expr(z3_ctx, Z3_mk_div(z3_ctx, left, right));
			}
		} catch (z3::exception &ex) {
				std::cerr << "UDiv exception = " << ex << std::endl;
		}
		return res;
	}

		case Expr::SDiv: {
			SDivExpr *se = cast<SDivExpr>(ele);
			if (se->left.get()->isFloat || se->right.get()->isFloat) {
				se->left.get()->isFloat = true;
				se->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(se->left);
			z3::expr right = eachExprToZ3(se->right);
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::SDiv\n");
			try {
				if (left.is_bv()) {
					res = z3::to_expr(z3_ctx, Z3_mk_bvsdiv(z3_ctx, left, right));
				} else {
					res = z3::to_expr(z3_ctx, Z3_mk_div(z3_ctx, left, right));
				}
			} catch (z3::exception &ex) {
				std::cerr << "SDiv exception = " << ex << std::endl;
			}

		return res;
	}

		case Expr::URem: {
			URemExpr *ur = cast<URemExpr>(ele);
			if (ur->left.get()->isFloat || ur->right.get()->isFloat) {
				ur->left.get()->isFloat = true;
				ur->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(ur->left);
			z3::expr right = eachExprToZ3(ur->right);
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::URem\n");
			try {
				if (left.is_bv()) {
					//bitvecotor, all int are bitvector;
					res = z3::to_expr(z3_ctx, Z3_mk_bvurem(z3_ctx, left, right));
				} else {
				//float
					res = z3::to_expr(z3_ctx, Z3_mk_rem(z3_ctx, left, right));
				}
			} catch (z3::exception &ex) {
				std::cerr << "URem exception = " << ex << std::endl;
			}
			return res;
		}

		case Expr::SRem: {
			SRemExpr *sr = cast<SRemExpr>(ele);
			if (sr->left.get()->isFloat || sr->right.get()->isFloat) {
				sr->left.get()->isFloat = true;
				sr->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(sr->left);
			z3::expr right = eachExprToZ3(sr->right);
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::SRem\n");
			try {
				if (left.is_bv()) {
					//bitvecotor, all int are bitvector;
					res = z3::to_expr(z3_ctx, Z3_mk_bvsrem(z3_ctx, left, right));
				} else {
					//float
					res = z3::to_expr(z3_ctx, Z3_mk_rem(z3_ctx, left, right));
				}
			} catch (z3::exception &ex) {
				std::cerr << "SRem exception = " << ex << std::endl;
			}
			return res;
		}

	case Expr::Not: {
		NotExpr *ne = cast<NotExpr>(ele);
		res = eachExprToZ3(ne->expr);
		try {
			if (res.is_bv()) {
				res = z3::to_expr(z3_ctx, Z3_mk_bvnot(z3_ctx, res));
			} else {
				res = z3::to_expr(z3_ctx, Z3_mk_not(z3_ctx, res));
			}
		} catch (z3::exception &ex) {
			std::cerr << "Not exception = " << ex << std::endl;
		}
		return res;
	}

		case Expr::And: {
			AndExpr *ae = cast<AndExpr>(ele);
			if (ae->left.get()->isFloat || ae->right.get()->isFloat) {
				ae->left.get()->isFloat = true;
				ae->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(ae->left);
			z3::expr right = eachExprToZ3(ae->right);
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::And\n");
//			std::cerr << "And left = " << left << std::endl;
//			std::cerr << "And right = " << right << std::endl;
			if (left.is_bv()) {
				res = z3::to_expr(z3_ctx, Z3_mk_bvand(z3_ctx, left, right));
			} else {
//				std::cerr << "left = " << left << ", left sort = " << left.get_sort() << std::endl;
//				std::cerr << "right = " << right << ", right sort = " << right.get_sort() << std::endl;
#if INT_ARITHMETIC
				try {
					if (left.is_int()) {
						z3::expr tempLeft = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, left));
//						std::cerr << "tempLeft = " << tempLeft << std::endl;
						z3::expr tempRight = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, right));
//						std::cerr << "tempRight = " << tempRight << std::endl;

						z3::expr tempRes = z3::to_expr(z3_ctx, Z3_mk_bvand(z3_ctx, tempLeft, tempRight));
//						std::cerr << "tempRes = " << tempRes << std::endl;
						res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
//						std::cerr << "res = " << res << std::endl;
					} else {
						res = left && right;
					}
				} catch (z3::exception &ex) {
					std::cerr << "And exception = " << ex << std::endl;
				}
#else
				res = left && right;
#endif
			}
		return res;
	}


		case Expr::Or: {
			OrExpr *oe = cast<OrExpr>(ele);
			if (oe->left.get()->isFloat || oe->right.get()->isFloat) {
				oe->left.get()->isFloat = true;
				oe->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(oe->left);
			z3::expr right = eachExprToZ3(oe->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Or\n");

			if (left.is_bv()) {
				res = z3::to_expr(z3_ctx, Z3_mk_bvor(z3_ctx, left, right));
			} else {
#if INT_ARITHMETIC
				try {
					if (left.is_int()) {
						z3::expr tempLeft = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, left));
						z3::expr tempRight = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, right));
						z3::expr tempRes = z3::to_expr(z3_ctx, Z3_mk_bvor(z3_ctx, tempLeft, tempRight));
						res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
					} else {
						res = left || right;
					}
				} catch(z3::exception &ex) {
					std::cerr << "Or exception : " << ex << std::endl;
				}
#else
				res = left || right;
#endif
			}
		return res;
	}


		case Expr::Xor: {
			XorExpr *xe = cast<XorExpr>(ele);
			if (xe->left.get()->isFloat || xe->right.get()->isFloat) {
				xe->left.get()->isFloat = true;
				xe->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(xe->left);
			z3::expr right = eachExprToZ3(xe->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Xor\n");
			try {
				if (left.is_bv()) {
					res = z3::to_expr(z3_ctx, Z3_mk_bvxor(z3_ctx, left, right));
				} else {
					res = z3::to_expr(z3_ctx, Z3_mk_xor(z3_ctx, left, right));
				}
			} catch(z3::exception &ex) {
				std::cerr << "Xor exception : " << ex << std::endl;
			}
		return res;
	}

		//following shift operation must be bitvector operand.
	case Expr::Shl: {
		ShlExpr * se = cast<ShlExpr>(ele);
		z3::expr left = eachExprToZ3(se->left);
		z3::expr right = eachExprToZ3(se->right);
		//convert bit vector to int in order to binary operation.
//		assert(
//				left.get_sort() == right.get_sort()
//						&& "sort between left and right are different in Expr::Shl\n");
#if INT_ARITHMETIC
		try {
			z3::expr tempLeft = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, left));
			z3::expr tempRight = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, right));

			z3::expr tempRes = z3::to_expr(z3_ctx, Z3_mk_bvshl(z3_ctx, tempLeft, tempRight));
			res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
		} catch(z3::exception &ex) {
			std::cerr << "Shl exception : " << ex << std::endl;
		}
#else
		res = z3::to_expr(z3_ctx, Z3_mk_bvshl(z3_ctx, left, right));
//		res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
#endif


		return res;
	}

	case Expr::LShr: {
		LShrExpr * lse = cast<LShrExpr>(ele);
		z3::expr left = eachExprToZ3(lse->left);
		z3::expr right = eachExprToZ3(lse->right);
//		assert(
//				left.get_sort() == right.get_sort()
//						&& "sort between left and right are different in Expr::LShr\n");
#if INT_ARITHMETIC
		try {
			z3::expr tempLeft = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, left));
			z3::expr tempRight = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, right));
			z3::expr tempRes = z3::to_expr(z3_ctx, Z3_mk_bvlshr(z3_ctx, tempLeft, tempRight));
			res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
		} catch(z3::exception &ex) {
			std::cerr << "LShr exception : " << ex << std::endl;
		}
#else
		res = z3::to_expr(z3_ctx, Z3_mk_bvlshr(z3_ctx, left, right));
//		res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
#endif

		return res;
	}

	case Expr::AShr: {
		AShrExpr * ase = cast<AShrExpr>(ele);
		z3::expr left = eachExprToZ3(ase->left);
		z3::expr right = eachExprToZ3(ase->right);
//		assert(
//				left.get_sort() == right.get_sort()
//						&& "sort between left and right are different in Expr::AShr\n");
#if INT_ARITHMETIC
		try {
			z3::expr tempLeft = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, left));
			z3::expr tempRight = z3::to_expr(z3_ctx, Z3_mk_int2bv(z3_ctx, BIT_WIDTH, right));
			z3::expr tempRes = z3::to_expr(z3_ctx, Z3_mk_bvashr(z3_ctx, tempLeft, tempRight));
			res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
		} catch(z3::exception &ex) {
			std::cerr << "AShr exception : " << ex << std::endl;
		}
#else
		res = z3::to_expr(z3_ctx, Z3_mk_bvashr(z3_ctx, left, right));
//		res = z3::to_expr(z3_ctx, Z3_mk_bv2int(z3_ctx, tempRes, true));
#endif

		return res;
	}

		case Expr::Eq: {
			EqExpr *ee = cast<EqExpr>(ele);
			if (ee->left.get()->isFloat || ee->right.get()->isFloat) {
				ee->left.get()->isFloat = true;
				ee->right.get()->isFloat = true;
			}
//			std::cerr << "ele = " << ele << std::endl;
			z3::expr left = eachExprToZ3(ee->left);
//			std::cerr << "left = " << left << std::endl;
			z3::expr right = eachExprToZ3(ee->right);
//			assert(
//					Z3_get_sort_kind(z3_ctx, left)
//							&& "sort between left and right are different in Expr::Eq\n");
//			std::cerr << "right = " << right << std::endl;
//			std::cerr << "ee left = " << ee->left << std::endl;
//			std::cerr << "ee right = " << ee->right << std::endl;
//			std::cerr << "left = " << left << ", left sort = " << left.get_sort() << std::endl;
//			std::cerr << "right = " << right << ", right sort = " << right.get_sort() << std::endl;
			res = (left == right);

			return res;
		}

		case Expr::Ult: {
			//probably can float point value's comparison.
			UltExpr *ue = cast<UltExpr>(ele);
			if (ue->left.get()->isFloat || ue->right.get()->isFloat) {
				ue->left.get()->isFloat = true;
				ue->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(ue->left);
			z3::expr right = eachExprToZ3(ue->right);
//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Ult\n");
			try {
				if (left.is_bv()) {
					res = z3::to_expr(z3_ctx, Z3_mk_bvult(z3_ctx, left, right));
				} else {
					res = z3::to_expr(z3_ctx, Z3_mk_lt(z3_ctx, left, right));
				}
			} catch(z3::exception &ex) {
				std::cerr << "Ult exception : " << ex << std::endl;
			}
			return res;
		}


		case Expr::Ule: {
			UleExpr *ue = cast<UleExpr>(ele);
			if (ue->left.get()->isFloat || ue->right.get()->isFloat) {
							ue->left.get()->isFloat = true;
							ue->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(ue->left);
			z3::expr right = eachExprToZ3(ue->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Ule\n");
			try {
				if (left.is_bv()) {
					res = z3::to_expr(z3_ctx, Z3_mk_bvule(z3_ctx, left, right));
				} else {
					res = z3::to_expr(z3_ctx, Z3_mk_le(z3_ctx, left, right));
				}
			} catch(z3::exception &ex) {
				std::cerr << "Ule exception : " << ex << std::endl;
			}
		return res;
	}
		case Expr::Slt: {
			SltExpr *se = cast<SltExpr>(ele);
			if (se->left.get()->isFloat || se->right.get()->isFloat) {
				se->left.get()->isFloat = true;
				se->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(se->left);
			z3::expr right = eachExprToZ3(se->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Slt\n");
			try {
				if (left.is_bv()) {
					res = z3::to_expr(z3_ctx, Z3_mk_bvslt(z3_ctx, left, right));
				} else {
					res = z3::to_expr(z3_ctx, Z3_mk_lt(z3_ctx, left, right));
				}
			} catch(z3::exception &ex) {
				std::cerr << "Slt exception : " << ex << std::endl;
			}
		return res;
	}
		case Expr::Sle: {
			SleExpr *se = cast<SleExpr>(ele);
			if (se->left.get()->isFloat || se->right.get()->isFloat) {
							se->left.get()->isFloat = true;
							se->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(se->left);
			z3::expr right = eachExprToZ3(se->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Sle\n");
			try {
				if (left.is_bv()) {
					res = z3::to_expr(z3_ctx, Z3_mk_bvsle(z3_ctx, left, right));
				} else {
					res = z3::to_expr(z3_ctx, Z3_mk_le(z3_ctx, left, right));
				}
			} catch (z3::exception &ex) {
				std::cerr << "Sle exception : " << ex << std::endl;
			}
		return res;
	}

		case Expr::Ne: {
			NeExpr *ne = cast<NeExpr>(ele);
			if (ne->left.get()->isFloat || ne->right.get()->isFloat) {
				ne->left.get()->isFloat = true;
				ne->right.get()->isFloat = true;
			}
			z3::expr left = eachExprToZ3(ne->left);
			z3::expr right = eachExprToZ3(ne->right);

//			assert(
//					left.get_sort() == right.get_sort()
//							&& "sort between left and right are different in Expr::Ne\n");

			res = (left != right);
		return res;
	}

		//stp unhandled type
		/*	  case Expr::Ne:
		 case Expr::Ugt:
		 case Expr::Uge:
		 case Expr::Sgt:
		 case Expr::Sge:
		 */
	default:
		assert(0 && "unhandled Expr type in kueryExpr to Z3Expr");
		return res;

	}
	std::cerr << "end of switch\n";
	return res;
}
Example #16
0
/** if *width_out!=1 then result is a bitvector,
    otherwise it is a bool */
ExprHandle STPBuilder::constructActual(ref<Expr> e, int *width_out) {
    int width;
    if (!width_out) width_out = &width;

    ++stats::queryConstructs;

    switch (e->getKind()) {
    case Expr::Constant: {
        ConstantExpr *CE = cast<ConstantExpr>(e);
        *width_out = CE->getWidth();

        // Coerce to bool if necessary.
        if (*width_out == 1)
            return CE->isTrue() ? getTrue() : getFalse();

        // Fast path.
        if (*width_out <= 32)
            return bvConst32(*width_out, CE->getZExtValue(32));
        if (*width_out <= 64)
            return bvConst64(*width_out, CE->getZExtValue());

        ref<ConstantExpr> Tmp = CE;
        ExprHandle Res = bvConst64(64, Tmp->Extract(0, 64)->getZExtValue());
        while (Tmp->getWidth() > 64) {
            Tmp = Tmp->Extract(64, Tmp->getWidth()-64);
            unsigned Width = std::min(64U, Tmp->getWidth());
            Res = vc_bvConcatExpr(vc, bvConst64(Width,
                                                Tmp->Extract(0, Width)->getZExtValue()),
                                  Res);
        }
        return Res;
    }

    // Special
    case Expr::NotOptimized: {
        NotOptimizedExpr *noe = cast<NotOptimizedExpr>(e);
        return construct(noe->src, width_out);
    }

    case Expr::Read: {
        ReadExpr *re = cast<ReadExpr>(e);
        assert(re && re->updates.root);
        *width_out = re->updates.root->getRange();
        return vc_readExpr(vc,
                           getArrayForUpdate(re->updates.root, re->updates.head),
                           construct(re->index, 0));
    }

    case Expr::Select: {
        SelectExpr *se = cast<SelectExpr>(e);
        ExprHandle cond = construct(se->cond, 0);
        ExprHandle tExpr = construct(se->trueExpr, width_out);
        ExprHandle fExpr = construct(se->falseExpr, width_out);
        return vc_iteExpr(vc, cond, tExpr, fExpr);
    }

    case Expr::Concat: {
        ConcatExpr *ce = cast<ConcatExpr>(e);
        unsigned numKids = ce->getNumKids();
        ExprHandle res = construct(ce->getKid(numKids-1), 0);
        for (int i=numKids-2; i>=0; i--) {
            res = vc_bvConcatExpr(vc, construct(ce->getKid(i), 0), res);
        }
        *width_out = ce->getWidth();
        return res;
    }

    case Expr::Extract: {
        ExtractExpr *ee = cast<ExtractExpr>(e);
        ExprHandle src = construct(ee->expr, width_out);
        *width_out = ee->getWidth();
        if (*width_out==1) {
            return bvBoolExtract(src, ee->offset);
        } else {
            return vc_bvExtract(vc, src, ee->offset + *width_out - 1, ee->offset);
        }
    }

    // Casting

    case Expr::ZExt: {
        int srcWidth;
        CastExpr *ce = cast<CastExpr>(e);
        ExprHandle src = construct(ce->src, &srcWidth);
        *width_out = ce->getWidth();
        if (srcWidth==1) {
            return vc_iteExpr(vc, src, bvOne(*width_out), bvZero(*width_out));
        } else {
            return vc_bvConcatExpr(vc, bvZero(*width_out-srcWidth), src);
        }
    }

    case Expr::SExt: {
        int srcWidth;
        CastExpr *ce = cast<CastExpr>(e);
        ExprHandle src = construct(ce->src, &srcWidth);
        *width_out = ce->getWidth();
        if (srcWidth==1) {
            return vc_iteExpr(vc, src, bvMinusOne(*width_out), bvZero(*width_out));
        } else {
            return vc_bvSignExtend(vc, src, *width_out);
        }
    }

    // Arithmetic

    case Expr::Add: {
        AddExpr *ae = cast<AddExpr>(e);
        ExprHandle left = construct(ae->left, width_out);
        ExprHandle right = construct(ae->right, width_out);
        assert(*width_out!=1 && "uncanonicalized add");
        return vc_bvPlusExpr(vc, *width_out, left, right);
    }

    case Expr::Sub: {
        SubExpr *se = cast<SubExpr>(e);
        ExprHandle left = construct(se->left, width_out);
        ExprHandle right = construct(se->right, width_out);
        assert(*width_out!=1 && "uncanonicalized sub");
        return vc_bvMinusExpr(vc, *width_out, left, right);
    }

    case Expr::Mul: {
        MulExpr *me = cast<MulExpr>(e);
        ExprHandle right = construct(me->right, width_out);
        assert(*width_out!=1 && "uncanonicalized mul");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(me->left))
            if (CE->getWidth() <= 64)
                return constructMulByConstant(right, *width_out,
                                              CE->getZExtValue());

        ExprHandle left = construct(me->left, width_out);
        return vc_bvMultExpr(vc, *width_out, left, right);
    }

    case Expr::UDiv: {
        UDivExpr *de = cast<UDivExpr>(e);
        ExprHandle left = construct(de->left, width_out);
        assert(*width_out!=1 && "uncanonicalized udiv");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(de->right)) {
            if (CE->getWidth() <= 64) {
                uint64_t divisor = CE->getZExtValue();

                if (bits64::isPowerOfTwo(divisor)) {
                    return bvRightShift(left,
                                        bits64::indexOfSingleBit(divisor));
                } else if (optimizeDivides) {
                    if (*width_out == 32) //only works for 32-bit division
                        return constructUDivByConstant( left, *width_out,
                                                        (uint32_t) divisor);
                }
            }
        }

        ExprHandle right = construct(de->right, width_out);
        return vc_bvDivExpr(vc, *width_out, left, right);
    }

    case Expr::SDiv: {
        SDivExpr *de = cast<SDivExpr>(e);
        ExprHandle left = construct(de->left, width_out);
        assert(*width_out!=1 && "uncanonicalized sdiv");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(de->right))
            if (optimizeDivides)
                if (*width_out == 32) //only works for 32-bit division
                    return constructSDivByConstant( left, *width_out,
                                                    CE->getZExtValue(32));

        // XXX need to test for proper handling of sign, not sure I
        // trust STP
        ExprHandle right = construct(de->right, width_out);
        return vc_sbvDivExpr(vc, *width_out, left, right);
    }

    case Expr::URem: {
        URemExpr *de = cast<URemExpr>(e);
        ExprHandle left = construct(de->left, width_out);
        assert(*width_out!=1 && "uncanonicalized urem");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(de->right)) {
            if (CE->getWidth() <= 64) {
                uint64_t divisor = CE->getZExtValue();

                if (bits64::isPowerOfTwo(divisor)) {
                    unsigned bits = bits64::indexOfSingleBit(divisor);

                    // special case for modding by 1 or else we bvExtract -1:0
                    if (bits == 0) {
                        return bvZero(*width_out);
                    } else {
                        return vc_bvConcatExpr(vc,
                                               bvZero(*width_out - bits),
                                               bvExtract(left, bits - 1, 0));
                    }
                }

                // Use fast division to compute modulo without explicit division for
                // constant divisor.

                if (optimizeDivides) {
                    if (*width_out == 32) { //only works for 32-bit division
                        ExprHandle quotient = constructUDivByConstant( left, *width_out, (uint32_t)divisor );
                        ExprHandle quot_times_divisor = constructMulByConstant( quotient, *width_out, divisor );
                        ExprHandle rem = vc_bvMinusExpr( vc, *width_out, left, quot_times_divisor );
                        return rem;
                    }
                }
            }
        }

        ExprHandle right = construct(de->right, width_out);
        return vc_bvModExpr(vc, *width_out, left, right);
    }

    case Expr::SRem: {
        SRemExpr *de = cast<SRemExpr>(e);
        ExprHandle left = construct(de->left, width_out);
        ExprHandle right = construct(de->right, width_out);
        assert(*width_out!=1 && "uncanonicalized srem");

#if 0 //not faster per first benchmark
        if (optimizeDivides) {
            if (ConstantExpr *cre = de->right->asConstant()) {
                uint64_t divisor = cre->asUInt64;

                //use fast division to compute modulo without explicit division for constant divisor
                if( *width_out == 32 ) { //only works for 32-bit division
                    ExprHandle quotient = constructSDivByConstant( left, *width_out, divisor );
                    ExprHandle quot_times_divisor = constructMulByConstant( quotient, *width_out, divisor );
                    ExprHandle rem = vc_bvMinusExpr( vc, *width_out, left, quot_times_divisor );
                    return rem;
                }
            }
        }
#endif

        // XXX implement my fast path and test for proper handling of sign
        return vc_sbvModExpr(vc, *width_out, left, right);
    }

    // Bitwise

    case Expr::Not: {
        NotExpr *ne = cast<NotExpr>(e);
        ExprHandle expr = construct(ne->expr, width_out);
        if (*width_out==1) {
            return vc_notExpr(vc, expr);
        } else {
            return vc_bvNotExpr(vc, expr);
        }
    }

    case Expr::And: {
        AndExpr *ae = cast<AndExpr>(e);
        ExprHandle left = construct(ae->left, width_out);
        ExprHandle right = construct(ae->right, width_out);
        if (*width_out==1) {
            return vc_andExpr(vc, left, right);
        } else {
            return vc_bvAndExpr(vc, left, right);
        }
    }

    case Expr::Or: {
        OrExpr *oe = cast<OrExpr>(e);
        ExprHandle left = construct(oe->left, width_out);
        ExprHandle right = construct(oe->right, width_out);
        if (*width_out==1) {
            return vc_orExpr(vc, left, right);
        } else {
            return vc_bvOrExpr(vc, left, right);
        }
    }

    case Expr::Xor: {
        XorExpr *xe = cast<XorExpr>(e);
        ExprHandle left = construct(xe->left, width_out);
        ExprHandle right = construct(xe->right, width_out);

        if (*width_out==1) {
            // XXX check for most efficient?
            return vc_iteExpr(vc, left,
                              ExprHandle(vc_notExpr(vc, right)), right);
        } else {
            return vc_bvXorExpr(vc, left, right);
        }
    }

    case Expr::Shl: {
        ShlExpr *se = cast<ShlExpr>(e);
        ExprHandle left = construct(se->left, width_out);
        assert(*width_out!=1 && "uncanonicalized shl");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(se->right)) {
            return bvLeftShift(left, (unsigned) CE->getLimitedValue());
        } else {
            int shiftWidth;
            ExprHandle amount = construct(se->right, &shiftWidth);
            return bvVarLeftShift( left, amount);
        }
    }

    case Expr::LShr: {
        LShrExpr *lse = cast<LShrExpr>(e);
        ExprHandle left = construct(lse->left, width_out);
        assert(*width_out!=1 && "uncanonicalized lshr");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(lse->right)) {
            return bvRightShift(left, (unsigned) CE->getLimitedValue());
        } else {
            int shiftWidth;
            ExprHandle amount = construct(lse->right, &shiftWidth);
            return bvVarRightShift( left, amount);
        }
    }

    case Expr::AShr: {
        AShrExpr *ase = cast<AShrExpr>(e);
        ExprHandle left = construct(ase->left, width_out);
        assert(*width_out!=1 && "uncanonicalized ashr");

        if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ase->right)) {
            unsigned shift = (unsigned) CE->getLimitedValue();
            ExprHandle signedBool = bvBoolExtract(left, *width_out-1);
            return constructAShrByConstant(left, shift, signedBool);
        } else {
            int shiftWidth;
            ExprHandle amount = construct(ase->right, &shiftWidth);
            return bvVarArithRightShift( left, amount);
        }
    }

    // Comparison

    case Expr::Eq: {
        EqExpr *ee = cast<EqExpr>(e);
        ExprHandle left = construct(ee->left, width_out);
        ExprHandle right = construct(ee->right, width_out);
        if (*width_out==1) {
            if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ee->left)) {
                if (CE->isTrue())
                    return right;
                return vc_notExpr(vc, right);
            } else {
                return vc_iffExpr(vc, left, right);
            }
        } else {
            *width_out = 1;
            return vc_eqExpr(vc, left, right);
        }
    }

    case Expr::Ult: {
        UltExpr *ue = cast<UltExpr>(e);
        ExprHandle left = construct(ue->left, width_out);
        ExprHandle right = construct(ue->right, width_out);
        assert(*width_out!=1 && "uncanonicalized ult");
        *width_out = 1;
        return vc_bvLtExpr(vc, left, right);
    }

    case Expr::Ule: {
        UleExpr *ue = cast<UleExpr>(e);
        ExprHandle left = construct(ue->left, width_out);
        ExprHandle right = construct(ue->right, width_out);
        assert(*width_out!=1 && "uncanonicalized ule");
        *width_out = 1;
        return vc_bvLeExpr(vc, left, right);
    }

    case Expr::Slt: {
        SltExpr *se = cast<SltExpr>(e);
        ExprHandle left = construct(se->left, width_out);
        ExprHandle right = construct(se->right, width_out);
        assert(*width_out!=1 && "uncanonicalized slt");
        *width_out = 1;
        return vc_sbvLtExpr(vc, left, right);
    }

    case Expr::Sle: {
        SleExpr *se = cast<SleExpr>(e);
        ExprHandle left = construct(se->left, width_out);
        ExprHandle right = construct(se->right, width_out);
        assert(*width_out!=1 && "uncanonicalized sle");
        *width_out = 1;
        return vc_sbvLeExpr(vc, left, right);
    }

        // unused due to canonicalization
#if 0
    case Expr::Ne:
    case Expr::Ugt:
    case Expr::Uge:
    case Expr::Sgt:
    case Expr::Sge:
#endif

    default:
        assert(0 && "unhandled Expr type");
        return vc_trueExpr(vc);
    }
}
Example #17
0
/// Return true if the specified constant can be handled by the code generator.
/// We don't want to generate something like:
///   void *X = &X/42;
/// because the code generator doesn't have a relocation that can handle that.
///
/// This function should be called if C was not found (but just got inserted)
/// in SimpleConstants to avoid having to rescan the same constants all the
/// time.
static bool
isSimpleEnoughValueToCommitHelper(Constant *C,
                                  SmallPtrSetImpl<Constant *> &SimpleConstants,
                                  const DataLayout &DL) {
  // Simple global addresses are supported, do not allow dllimport or
  // thread-local globals.
  if (auto *GV = dyn_cast<GlobalValue>(C))
    return !GV->hasDLLImportStorageClass() && !GV->isThreadLocal();

  // Simple integer, undef, constant aggregate zero, etc are all supported.
  if (C->getNumOperands() == 0 || isa<BlockAddress>(C))
    return true;

  // Aggregate values are safe if all their elements are.
  if (isa<ConstantAggregate>(C)) {
    for (Value *Op : C->operands())
      if (!isSimpleEnoughValueToCommit(cast<Constant>(Op), SimpleConstants, DL))
        return false;
    return true;
  }

  // We don't know exactly what relocations are allowed in constant expressions,
  // so we allow &global+constantoffset, which is safe and uniformly supported
  // across targets.
  ConstantExpr *CE = cast<ConstantExpr>(C);
  switch (CE->getOpcode()) {
  case Instruction::BitCast:
    // Bitcast is fine if the casted value is fine.
    return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, DL);

  case Instruction::IntToPtr:
  case Instruction::PtrToInt:
    // int <=> ptr is fine if the int type is the same size as the
    // pointer type.
    if (DL.getTypeSizeInBits(CE->getType()) !=
        DL.getTypeSizeInBits(CE->getOperand(0)->getType()))
      return false;
    return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, DL);

  // GEP is fine if it is simple + constant offset.
  case Instruction::GetElementPtr:
    for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
      if (!isa<ConstantInt>(CE->getOperand(i)))
        return false;
    return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, DL);

  case Instruction::Add:
    // We allow simple+cst.
    if (!isa<ConstantInt>(CE->getOperand(1)))
      return false;
    return isSimpleEnoughValueToCommit(CE->getOperand(0), SimpleConstants, DL);
  }
  return false;
}
Example #18
0
uint64_t ExprFrame::SerializeExpr(const ref<Expr> e) {
  data::ExprNode *ser_expr_node = expr_data_->add_expr();
  ser_expr_node->set_id(s_.next_id_++);
  ser_expr_node->set_kind((data::ExprKind)e->getKind());

  switch (e->getKind()) {
  case Expr::Constant: {
    ConstantExpr *ce = cast<ConstantExpr>(e);

    assert(ce->getWidth() <= 64 && "FIXME");
    ser_expr_node->set_value(ce->getZExtValue());
    ser_expr_node->set_width(ce->getWidth());
    break;
  }

  case Expr::NotOptimized: {
    NotOptimizedExpr *noe = cast<NotOptimizedExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(noe->src));
    break;
  }

  case Expr::Read: {
    ReadExpr *re = cast<ReadExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(re->index));

    if (re->updates.head) {
      ExprSerializer::UpdateNodePosition un_pos = GetOrSerializeUpdateList(re->updates);
      ser_expr_node->set_update_list_id(un_pos.first);
      ser_expr_node->set_update_list_offset(un_pos.second);
    }
    ser_expr_node->set_array_id(GetOrSerializeArray(re->updates.root));
    break;
  }

  case Expr::Select: {
    SelectExpr *se = cast<SelectExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(se->cond));
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(se->trueExpr));
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(se->falseExpr));
    break;
  }

  case Expr::Concat: {
    ConcatExpr *ce = cast<ConcatExpr>(e);
    for (unsigned i = 0; i < ce->getNumKids(); ++i) {
      ser_expr_node->add_child_expr_id(GetOrSerializeExpr(ce->getKid(i)));
    }
    break;
  }

  case Expr::Extract: {
    ExtractExpr *ee = cast<ExtractExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(ee->expr));
    ser_expr_node->set_offset(ee->offset);
    ser_expr_node->set_width(ee->getWidth());
    break;
  }

    // Casting,
  case Expr::ZExt:
  case Expr::SExt: {
    CastExpr *ce = cast<CastExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(ce->src));
    ser_expr_node->set_width(ce->getWidth());
    break;
  }

    // All subsequent kinds are binary.

    // Arithmetic
  case Expr::Add:
  case Expr::Sub:
  case Expr::Mul:
  case Expr::UDiv:
  case Expr::SDiv:
  case Expr::URem:
  case Expr::SRem: {
    BinaryExpr *be = cast<BinaryExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(be->left));
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(be->right));
    break;
  }

    // Bit
  case Expr::Not: {
    NotExpr *ne = cast<NotExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(ne->expr));
    break;
  }

  case Expr::And:
  case Expr::Or:
  case Expr::Xor:
  case Expr::Shl:
  case Expr::LShr:
  case Expr::AShr: {
    BinaryExpr *be = cast<BinaryExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(be->left));
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(be->right));
    break;
  }

    // Compare
  case Expr::Eq:
  case Expr::Ne:  ///< Not used in canonical form
  case Expr::Ult:
  case Expr::Ule:
  case Expr::Ugt: ///< Not used in canonical form
  case Expr::Uge: ///< Not used in canonical form
  case Expr::Slt:
  case Expr::Sle:
  case Expr::Sgt: ///< Not used in canonical form
  case Expr::Sge: { ///< Not used in canonical form
    BinaryExpr *be = cast<BinaryExpr>(e);
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(be->left));
    ser_expr_node->add_child_expr_id(GetOrSerializeExpr(be->right));
    break;
  }

  default:
    assert(0 && "Unhandled Expr type");
  }

  return ser_expr_node->id();
}
Example #19
0
z3::expr Z3Builder::makeExpr(ref<Expr> e) {
    ++stats::queryConstructs;

    switch (e->getKind()) {
    case Expr::Constant: {
        ConstantExpr *CE = cast<ConstantExpr>(e);
        unsigned width = CE->getWidth();
        if (width == 1)
            return context_.bool_val(CE->isTrue());
        if (width <= 64)
            return context_.bv_val((__uint64)CE->getZExtValue(), width);

        // This is slower than concatenating 64-bit extractions, like STPBuilder
        // does, but the assumption is that it's quite infrequent.
        // TODO: Log these transformations.
        llvm::SmallString<32> const_repr;
        CE->getAPValue().toStringUnsigned(const_repr, 10);
        return context_.bv_val(const_repr.c_str(), width);
    }

    case Expr::NotOptimized: {
        NotOptimizedExpr *noe = cast<NotOptimizedExpr>(e);
        return getOrMakeExpr(noe->src);
    }

    case Expr::Read: {
        return makeReadExpr(cast<ReadExpr>(e));
    }

    case Expr::Select: {
        SelectExpr *se = cast<SelectExpr>(e);
        // XXX: A bug in Clang prevents us from using z3::ite
        return z3::to_expr(context_, Z3_mk_ite(context_,
                getOrMakeExpr(se->cond),
                getOrMakeExpr(se->trueExpr),
                getOrMakeExpr(se->falseExpr)));
    }

    case Expr::Concat: {
        ConcatExpr *ce = cast<ConcatExpr>(e);

        unsigned numKids = ce->getNumKids();
        z3::expr res = getOrMakeExpr(ce->getKid(numKids-1));
        for (int i = numKids - 2; i >= 0; --i) {
            res = z3::to_expr(context_,
                    Z3_mk_concat(context_, getOrMakeExpr(ce->getKid(i)), res));
        }
        return res;
    }

    case Expr::Extract: {
        ExtractExpr *ee = cast<ExtractExpr>(e);

        z3::expr src = getOrMakeExpr(ee->expr);
        if (ee->getWidth() == 1) {
            return z3::to_expr(context_, Z3_mk_extract(context_,
                    ee->offset, ee->offset, src)) == context_.bv_val(1, 1);
        } else {
            return z3::to_expr(context_, Z3_mk_extract(context_,
                    ee->offset + ee->getWidth() - 1, ee->offset, src));
        }
    }

    // Casting

    case Expr::ZExt: {
        CastExpr *ce = cast<CastExpr>(e);

        z3::expr src = getOrMakeExpr(ce->src);
        if (src.is_bool()) {
            // XXX: A bug in Clang prevents us from using z3::ite
            return z3::to_expr(context_, Z3_mk_ite(context_,
                    src,
                    context_.bv_val(1, ce->getWidth()),
                    context_.bv_val(0, ce->getWidth())));
        } else {
            return z3::to_expr(context_, Z3_mk_zero_ext(context_,
                    ce->getWidth() - src.get_sort().bv_size(), src));
        }
    }

    case Expr::SExt: {
        CastExpr *ce = cast<CastExpr>(e);

        z3::expr src = getOrMakeExpr(ce->src);
        if (src.is_bool()) {
            return z3::to_expr(context_, Z3_mk_ite(context_,
                    src,
                    context_.bv_val(1, ce->getWidth()),
                    context_.bv_val(0, ce->getWidth())));
        } else {
            return z3::to_expr(context_, Z3_mk_sign_ext(context_,
                    ce->getWidth() - src.get_sort().bv_size(), src));
        }
    }

    // Arithmetic

    case Expr::Add: {
        AddExpr *ae = cast<AddExpr>(e);
        return getOrMakeExpr(ae->left) + getOrMakeExpr(ae->right);
    }

    case Expr::Sub: {
        SubExpr *se = cast<SubExpr>(e);

        // STP here takes an extra width parameter, wondering why...
        return getOrMakeExpr(se->left) - getOrMakeExpr(se->right);
    }

    case Expr::Mul: {
        MulExpr *me = cast<MulExpr>(e);

        // Again, we skip some optimizations from STPBuilder; just let the solver
        // do its own set of simplifications.
        return getOrMakeExpr(me->left) * getOrMakeExpr(me->right);
    }

    case Expr::UDiv: {
        UDivExpr *de = cast<UDivExpr>(e);
        return z3::udiv(getOrMakeExpr(de->left), getOrMakeExpr(de->right));
    }

    case Expr::SDiv: {
        SDivExpr *de = cast<SDivExpr>(e);
        return getOrMakeExpr(de->left) / getOrMakeExpr(de->right);
    }

    case Expr::URem: {
        URemExpr *de = cast<URemExpr>(e);
        return z3::to_expr(context_, Z3_mk_bvurem(context_,
                getOrMakeExpr(de->left),
                getOrMakeExpr(de->right)));
    }

    case Expr::SRem: {
        SRemExpr *de = cast<SRemExpr>(e);

        // Assuming the sign follows dividend (otherwise we should have used
        // the Z3_mk_bvsmod() call)
        return z3::to_expr(context_, Z3_mk_bvsrem(context_,
                getOrMakeExpr(de->left),
                getOrMakeExpr(de->right)));
    }

    // Bitwise

    case Expr::Not: {
        NotExpr *ne = cast<NotExpr>(e);

        z3::expr expr = getOrMakeExpr(ne->expr);
        if (expr.is_bool()) {
            return !expr;
        } else {
            return ~expr;
        }
    }

    case Expr::And: {
        AndExpr *ae = cast<AndExpr>(e);

        z3::expr left = getOrMakeExpr(ae->left);
        z3::expr right = getOrMakeExpr(ae->right);

        if (left.is_bool()) {
            return left && right;
        } else {
            return left & right;
        }
    }

    case Expr::Or: {
        OrExpr *oe = cast<OrExpr>(e);

        z3::expr left = getOrMakeExpr(oe->left);
        z3::expr right = getOrMakeExpr(oe->right);

        if (left.is_bool()) {
            return left || right;
        } else {
            return left | right;
        }
    }

    case Expr::Xor: {
        XorExpr *xe = cast<XorExpr>(e);

        z3::expr left = getOrMakeExpr(xe->left);
        z3::expr right = getOrMakeExpr(xe->right);

        if (left.is_bool()) {
            return z3::to_expr(context_, Z3_mk_xor(context_, left, right));
        } else {
            return left ^ right;
        }
    }

    case Expr::Shl: {
        ShlExpr *se = cast<ShlExpr>(e);
        return z3::to_expr(context_, Z3_mk_bvshl(context_,
                getOrMakeExpr(se->left),
                getOrMakeExpr(se->right)));
    }

    case Expr::LShr: {
        LShrExpr *lse = cast<LShrExpr>(e);
        return z3::to_expr(context_, Z3_mk_bvlshr(context_,
                getOrMakeExpr(lse->left),
                getOrMakeExpr(lse->right)));
    }

    case Expr::AShr: {
        AShrExpr *ase = cast<AShrExpr>(e);
        return z3::to_expr(context_, Z3_mk_bvashr(context_,
                getOrMakeExpr(ase->left),
                getOrMakeExpr(ase->right)));
    }

    // Comparison

    case Expr::Eq: {
        EqExpr *ee = cast<EqExpr>(e);
        return getOrMakeExpr(ee->left) == getOrMakeExpr(ee->right);
    }

    case Expr::Ult: {
        UltExpr *ue = cast<UltExpr>(e);
        return z3::ult(getOrMakeExpr(ue->left), getOrMakeExpr(ue->right));
    }

    case Expr::Ule: {
        UleExpr *ue = cast<UleExpr>(e);
        return z3::ule(getOrMakeExpr(ue->left), getOrMakeExpr(ue->right));
    }

    case Expr::Slt: {
        SltExpr *se = cast<SltExpr>(e);
        return getOrMakeExpr(se->left) < getOrMakeExpr(se->right);
    }

    case Expr::Sle: {
        SleExpr *se = cast<SleExpr>(e);
        return getOrMakeExpr(se->left) <= getOrMakeExpr(se->right);
    }

    // unused due to canonicalization
#if 0
    case Expr::Ne:
    case Expr::Ugt:
    case Expr::Uge:
    case Expr::Sgt:
    case Expr::Sge:
#endif

    default:
        assert(0 && "unhandled Expr type");
    }
}
Example #20
0
//
// Method: runOnModule()
//
// Description:
//  Entry point for this LLVM pass.
//  Search for all call sites to casted functions.
//  Check if they only differ in an argument type
//  Cast the argument, and call the original function
//
// Inputs:
//  M - A reference to the LLVM module to transform
//
// Outputs:
//  M - The transformed LLVM module.
//
// Return value:
//  true  - The module was modified.
//  false - The module was not modified.
//
bool ArgCast::runOnModule(Module& M) {

  std::vector<CallInst*> worklist;
  for (Module::iterator I = M.begin(); I != M.end(); ++I) {
    if (I->mayBeOverridden())
      continue;
    // Find all uses of this function
    for(Value::user_iterator ui = I->user_begin(), ue = I->user_end(); ui != ue; ) {
      // check if is ever casted to a different function type
      ConstantExpr *CE = dyn_cast<ConstantExpr>(*ui++);
      if(!CE)
        continue;
      if (CE->getOpcode() != Instruction::BitCast)
        continue;
      if(CE->getOperand(0) != I)
        continue;
      const PointerType *PTy = dyn_cast<PointerType>(CE->getType());
      if (!PTy)
        continue;
      const Type *ETy = PTy->getElementType();
      const FunctionType *FTy  = dyn_cast<FunctionType>(ETy); 
      if(!FTy)
        continue;
      // casting to a varargs funtion
      // or function with same number of arguments
      // possibly varying types of arguments
      
      if(FTy->getNumParams() != I->arg_size() && !FTy->isVarArg())
        continue;
      for(Value::user_iterator uii = CE->user_begin(),
          uee = CE->user_end(); uii != uee; ++uii) {
        // Find all uses of the casted value, and check if it is 
        // used in a Call Instruction
        if (CallInst* CI = dyn_cast<CallInst>(*uii)) {
          // Check that it is the called value, and not an argument
          if(CI->getCalledValue() != CE) 
            continue;
          // Check that the number of arguments passed, and expected
          // by the function are the same.
          if(!I->isVarArg()) {
            if(CI->getNumOperands() != I->arg_size() + 1)
              continue;
          } else {
            if(CI->getNumOperands() < I->arg_size() + 1)
              continue;
          }
          // If so, add to worklist
          worklist.push_back(CI);
        }
      }
    }
  }

  // Proces the worklist of potential call sites to transform
  while(!worklist.empty()) {
    CallInst *CI = worklist.back();
    worklist.pop_back();
    // Get the called Function
    Function *F = cast<Function>(CI->getCalledValue()->stripPointerCasts());
    const FunctionType *FTy = F->getFunctionType();

    SmallVector<Value*, 8> Args;
    unsigned i =0;
    for(i =0; i< FTy->getNumParams(); ++i) {
      Type *ArgType = CI->getOperand(i+1)->getType();
      Type *FormalType = FTy->getParamType(i);
      // If the types for this argument match, just add it to the
      // parameter list. No cast needs to be inserted.
      if(ArgType == FormalType) {
        Args.push_back(CI->getOperand(i+1));
      }
      else if(ArgType->isPointerTy() && FormalType->isPointerTy()) {
        CastInst *CastI = CastInst::CreatePointerCast(CI->getOperand(i+1), 
                                                      FormalType, "", CI);
        Args.push_back(CastI);
      } else if (ArgType->isIntegerTy() && FormalType->isIntegerTy()) {
        unsigned SrcBits = ArgType->getScalarSizeInBits();
        unsigned DstBits = FormalType->getScalarSizeInBits();
        if(SrcBits > DstBits) {
          CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), 
                                                        FormalType, true, "", CI);
          Args.push_back(CastI);
        } else {
          if (F->getAttributes().hasAttribute(i+1, Attribute::SExt)) {
            CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), 
                                                          FormalType, true, "", CI);
            Args.push_back(CastI);
          } else if (F->getAttributes().hasAttribute(i+1, Attribute::ZExt)) {
            CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), 
                                                          FormalType, false, "", CI);
            Args.push_back(CastI);
          } else {
            // Use ZExt in default case.
            // Derived from InstCombine. Also, the only reason this should happen
            // is mismatched prototypes.
            // Seen in case of integer constants which get interpreted as i32, 
            // even if being used as i64.
            // TODO: is this correct?
            CastInst *CastI = CastInst::CreateIntegerCast(CI->getOperand(i+1), 
                                                          FormalType, false, "", CI);
            Args.push_back(CastI);
          } 
        } 
      } else {
        DEBUG(ArgType->dump());
        DEBUG(FormalType->dump());
        break;
      }
    }

    // If we found an argument we could not cast, try the next instruction
    if(i != FTy->getNumParams()) {
      continue;
    }

    if(FTy->isVarArg()) {
      for(; i< CI->getNumOperands() - 1 ;i++) {
        Args.push_back(CI->getOperand(i+1));
      }
    }

    // else replace the call instruction
    CallInst *CINew = CallInst::Create(F, Args, "", CI);
    CINew->setCallingConv(CI->getCallingConv());
    CINew->setAttributes(CI->getAttributes());
    if(!CI->use_empty()) {
      CastInst *RetCast;
      if(CI->getType() != CINew->getType()) {
        if(CI->getType()->isPointerTy() && CINew->getType()->isPointerTy())
          RetCast = CastInst::CreatePointerCast(CINew, CI->getType(), "", CI);
        else if(CI->getType()->isIntOrIntVectorTy() && CINew->getType()->isIntOrIntVectorTy())
          RetCast = CastInst::CreateIntegerCast(CINew, CI->getType(), false, "", CI);
        else if(CI->getType()->isIntOrIntVectorTy() && CINew->getType()->isPointerTy())
          RetCast = CastInst::CreatePointerCast(CINew, CI->getType(), "", CI);
        else if(CI->getType()->isPointerTy() && CINew->getType()->isIntOrIntVectorTy()) 
          RetCast = new IntToPtrInst(CINew, CI->getType(), "", CI);
        else {
          // TODO: I'm not sure what right behavior is here, but this case should be handled.
          llvm_unreachable("Unexpected type conversion in call!");
          abort();
        }
        CI->replaceAllUsesWith(RetCast);
      } else {
        CI->replaceAllUsesWith(CINew);
      }
    }

    // Debug printing
    DEBUG(errs() << "ARGCAST:");
    DEBUG(errs() << "ERASE:");
    DEBUG(CI->dump());
    DEBUG(errs() << "ARGCAST:");
    DEBUG(errs() << "ADDED:");
    DEBUG(CINew->dump());

    CI->eraseFromParent();
    numChanged++;
  }
  return true;
}
Example #21
0
/** if *et_out==etBV then result is a bitvector,
    otherwise it is a bool */
ExprHandle STPBuilder::constructActual(ref<Expr> e, int *width_out, STPExprType *et_out) {
  int width;
  if (!width_out) width_out = &width;

  ++stats::queryConstructs;

  switch (e->getKind()) {
  case Expr::Constant: {
    ConstantExpr *CE = cast<ConstantExpr>(e);
    *width_out = CE->getWidth();

    // Coerce to bool if necessary.
    if (*width_out == 1 && (*et_out == etBOOL || *et_out == etDontCare)) {
      *et_out = etBOOL;
      return CE->isTrue() ? getTrue() : getFalse();
    }

    *et_out = etBV;

    // Fast path.
    if (*width_out <= 32)
      return bvConst32(*width_out, CE->getZExtValue(32));
    if (*width_out <= 64)
      return bvConst64(*width_out, CE->getZExtValue());

    ref<ConstantExpr> Tmp = CE;
    ExprHandle Res = bvConst64(64, Tmp->Extract(0, 64)->getZExtValue());
    while (Tmp->getWidth() > 64) {
      Tmp = Tmp->Extract(64, Tmp->getWidth()-64);
      unsigned Width = std::min(64U, Tmp->getWidth());
      Res = vc_bvConcatExpr(vc, bvConst64(Width,
                                        Tmp->Extract(0, Width)->getZExtValue()),
                            Res);
    }
    return Res;
  }
    
  // Special
  case Expr::NotOptimized: {
    NotOptimizedExpr *noe = cast<NotOptimizedExpr>(e);
    return construct(noe->src, width_out, et_out);
  }

  case Expr::Read: {
    ReadExpr *re = cast<ReadExpr>(e);
    *width_out = 8;
    *et_out = etBV;
    return vc_readExpr(vc,
                       getArrayForUpdate(re->updates.root, re->updates.head),
                       construct(re->index, 0, etBV));
  }
    
  case Expr::Select: {
    SelectExpr *se = cast<SelectExpr>(e);
    ExprHandle cond = construct(se->cond, 0, etBOOL);
    ExprHandle tExpr = construct(se->trueExpr, width_out, etBV);
    ExprHandle fExpr = construct(se->falseExpr, width_out, etBV);
    *et_out = etBV;
    return vc_iteExpr(vc, cond, tExpr, fExpr);
  }

  case Expr::Concat: {
    ConcatExpr *ce = cast<ConcatExpr>(e);
    unsigned numKids = ce->getNumKids();
    ExprHandle res = construct(ce->getKid(numKids-1), 0, etBV);
    for (int i=numKids-2; i>=0; i--) {
      res = vc_bvConcatExpr(vc, construct(ce->getKid(i), 0, etBV), res);
    }
    *width_out = ce->getWidth();
    *et_out = etBV;
    return res;
  }

  case Expr::Extract: {
    ExtractExpr *ee = cast<ExtractExpr>(e);
    ExprHandle src = construct(ee->expr, width_out, etBV);    
    *width_out = ee->getWidth();
    *et_out = etBV;
    return vc_bvExtract(vc, src, ee->offset + *width_out - 1, ee->offset);
  }

    // Casting

  case Expr::ZExt: {
    int srcWidth;
    CastExpr *ce = cast<CastExpr>(e);
    STPExprType src_rt = etDontCare;
    ExprHandle src = construct(ce->src, &srcWidth, &src_rt);
    *width_out = ce->getWidth();
    *et_out = etBV;
    if (src_rt==etBOOL) {
      return vc_iteExpr(vc, src, bvOne(*width_out), bvZero(*width_out));
    } else {
      return vc_bvConcatExpr(vc, bvZero(*width_out-srcWidth), src);
    }
  }

  case Expr::SExt: {
    int srcWidth;
    CastExpr *ce = cast<CastExpr>(e);
    STPExprType src_rt = etDontCare;
    ExprHandle src = construct(ce->src, &srcWidth, &src_rt);
    *width_out = ce->getWidth();
    *et_out = etBV;
    if (src_rt==etBOOL) {
      return vc_iteExpr(vc, src, bvMinusOne(*width_out), bvZero(*width_out));
    } else {
      return vc_bvSignExtend(vc, src, *width_out);
    }
  }

    // Arithmetic

  case Expr::Add: {
    AddExpr *ae = cast<AddExpr>(e);
    ExprHandle left = construct(ae->left, width_out, etBV);
    ExprHandle right = construct(ae->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized add");
    *et_out = etBV;
    return vc_bvPlusExpr(vc, *width_out, left, right);
  }

  case Expr::Sub: {
    SubExpr *se = cast<SubExpr>(e);
    ExprHandle left = construct(se->left, width_out, etBV);
    ExprHandle right = construct(se->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized sub");
    *et_out = etBV;
    return vc_bvMinusExpr(vc, *width_out, left, right);
  } 

  case Expr::Mul: {
    MulExpr *me = cast<MulExpr>(e);
    ExprHandle right = construct(me->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized mul");
    *et_out = etBV;

    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(me->left))
      if (CE->getWidth() <= 64)
        return constructMulByConstant(right, *width_out, 
                                      CE->getZExtValue());

    ExprHandle left = construct(me->left, width_out, etBV);
    return vc_bvMultExpr(vc, *width_out, left, right);
  }

  case Expr::UDiv: {
    UDivExpr *de = cast<UDivExpr>(e);
    ExprHandle left = construct(de->left, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized udiv");
    *et_out = etBV;
    
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(de->right)) {
      if (CE->getWidth() <= 64) {
        uint64_t divisor = CE->getZExtValue();
      
        if (bits64::isPowerOfTwo(divisor)) {
          return bvRightShift(left,
                              bits64::indexOfSingleBit(divisor),
                              getShiftBits(*width_out));
        } else if (optimizeDivides) {
          if (*width_out == 32) //only works for 32-bit division
            return constructUDivByConstant( left, *width_out, 
                                            (uint32_t) divisor);
        }
      }
    } 

    ExprHandle right = construct(de->right, width_out, etBV);
    return vc_bvDivExpr(vc, *width_out, left, right);
  }

  case Expr::SDiv: {
    SDivExpr *de = cast<SDivExpr>(e);
    ExprHandle left = construct(de->left, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized sdiv");
    *et_out = etBV;

    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(de->right))
      if (optimizeDivides)
	if (*width_out == 32) //only works for 32-bit division
	  return constructSDivByConstant( left, *width_out, 
                                          CE->getZExtValue(32));

    // XXX need to test for proper handling of sign, not sure I
    // trust STP
    ExprHandle right = construct(de->right, width_out, etBV);
    return vc_sbvDivExpr(vc, *width_out, left, right);
  }

  case Expr::URem: {
    URemExpr *de = cast<URemExpr>(e);
    ExprHandle left = construct(de->left, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized urem");
    *et_out = etBV;
    
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(de->right)) {
      if (CE->getWidth() <= 64) {
        uint64_t divisor = CE->getZExtValue();

        if (bits64::isPowerOfTwo(divisor)) {
          unsigned bits = bits64::indexOfSingleBit(divisor);

          // special case for modding by 1 or else we bvExtract -1:0
          if (bits == 0) {
            return bvZero(*width_out);
          } else {
            return vc_bvConcatExpr(vc,
                                   bvZero(*width_out - bits),
                                   bvExtract(left, bits - 1, 0));
          }
        }

        // Use fast division to compute modulo without explicit division for
        // constant divisor.

        if (optimizeDivides) {
          if (*width_out == 32) { //only works for 32-bit division
            ExprHandle quotient = constructUDivByConstant( left, *width_out, (uint32_t)divisor );
            ExprHandle quot_times_divisor = constructMulByConstant( quotient, *width_out, divisor );
            ExprHandle rem = vc_bvMinusExpr( vc, *width_out, left, quot_times_divisor );
            return rem;
          }
        }
      }
    }
    
    ExprHandle right = construct(de->right, width_out, etBV);
    return vc_bvModExpr(vc, *width_out, left, right);
  }

  case Expr::SRem: {
    SRemExpr *de = cast<SRemExpr>(e);
    ExprHandle left = construct(de->left, width_out, etBV);
    ExprHandle right = construct(de->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized srem");
    *et_out = etBV;

#if 0 //not faster per first benchmark
    if (optimizeDivides) {
      if (ConstantExpr *cre = de->right->asConstant()) {
	uint64_t divisor = cre->asUInt64;

	//use fast division to compute modulo without explicit division for constant divisor
      	if( *width_out == 32 ) { //only works for 32-bit division
	  ExprHandle quotient = constructSDivByConstant( left, *width_out, divisor );
	  ExprHandle quot_times_divisor = constructMulByConstant( quotient, *width_out, divisor );
	  ExprHandle rem = vc_bvMinusExpr( vc, *width_out, left, quot_times_divisor );
	  return rem;
	}
      }
    }
#endif

    // XXX implement my fast path and test for proper handling of sign
    return vc_sbvModExpr(vc, *width_out, left, right);
  }

    // Bitwise

  case Expr::Not: {
    NotExpr *ne = cast<NotExpr>(e);
    ExprHandle expr = construct(ne->expr, width_out, et_out);
    if (*et_out == etBOOL) {
      return vc_notExpr(vc, expr);
    } else {
      return vc_bvNotExpr(vc, expr);
    }
  }    

  case Expr::And: {
    AndExpr *ae = cast<AndExpr>(e);
    ExprHandle left = construct(ae->left, width_out, et_out);
    ExprHandle right = construct(ae->right, width_out, *et_out);
    if (*et_out == etBOOL) {
      return vc_andExpr(vc, left, right);
    } else {
      return vc_bvAndExpr(vc, left, right);
    }
  }

  case Expr::Or: {
    OrExpr *oe = cast<OrExpr>(e);
    ExprHandle left = construct(oe->left, width_out, et_out);
    ExprHandle right = construct(oe->right, width_out, *et_out);
    if (*et_out == etBOOL) {
      return vc_orExpr(vc, left, right);
    } else {
      return vc_bvOrExpr(vc, left, right);
    }
  }

  case Expr::Xor: {
    XorExpr *xe = cast<XorExpr>(e);
    ExprHandle left = construct(xe->left, width_out, et_out);
    ExprHandle right = construct(xe->right, width_out, *et_out);
    
    if (*et_out == etBOOL) {
      // XXX check for most efficient?
      return vc_iteExpr(vc, left, 
                        ExprHandle(vc_notExpr(vc, right)), right);
    } else {
      return vc_bvXorExpr(vc, left, right);
    }
  }

  case Expr::Shl: {
    ShlExpr *se = cast<ShlExpr>(e);
    ExprHandle left = construct(se->left, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized shl");
    *et_out = etBV;

    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(se->right)) {
      return bvLeftShift(left, (unsigned) CE->getLimitedValue(), 
                         getShiftBits(*width_out));
    } else {
      int shiftWidth;
      ExprHandle amount = construct(se->right, &shiftWidth, etBV);
      return bvVarLeftShift( left, amount, *width_out );
    }
  }

  case Expr::LShr: {
    LShrExpr *lse = cast<LShrExpr>(e);
    ExprHandle left = construct(lse->left, width_out, etBV);
    unsigned shiftBits = getShiftBits(*width_out);
    assert(*width_out!=1 && "uncanonicalized lshr");
    *et_out = etBV;

    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(lse->right)) {
      return bvRightShift(left, (unsigned) CE->getLimitedValue(), 
                          shiftBits);
    } else {
      int shiftWidth;
      ExprHandle amount = construct(lse->right, &shiftWidth, etBV);
      return bvVarRightShift( left, amount, *width_out );
    }
  }

  case Expr::AShr: {
    AShrExpr *ase = cast<AShrExpr>(e);
    ExprHandle left = construct(ase->left, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized ashr");
    *et_out = etBV;
    
    if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ase->right)) {
      unsigned shift = (unsigned) CE->getLimitedValue();
      ExprHandle signedBool = bvBoolExtract(left, *width_out-1);
      return constructAShrByConstant(left, shift, signedBool, 
                                     getShiftBits(*width_out));
    } else {
      int shiftWidth;
      ExprHandle amount = construct(ase->right, &shiftWidth, etBV);
      return bvVarArithRightShift( left, amount, *width_out );
    }
  }

    // Comparison

  case Expr::Eq: {
    EqExpr *ee = cast<EqExpr>(e);
    STPExprType src_rt = etDontCare;
    ExprHandle left = construct(ee->left, width_out, &src_rt);
    ExprHandle right = construct(ee->right, width_out, src_rt);
    *et_out = etBOOL;
    *width_out = 1;
    if (src_rt == etBOOL) {
      if (ConstantExpr *CE = dyn_cast<ConstantExpr>(ee->left)) {
        if (CE->isTrue())
          return right;
        return vc_notExpr(vc, right);
      } else {
        return vc_iffExpr(vc, left, right);
      }
    } else {
      return vc_eqExpr(vc, left, right);
    }
  }

  case Expr::Ult: {
    UltExpr *ue = cast<UltExpr>(e);
    ExprHandle left = construct(ue->left, width_out, etBV);
    ExprHandle right = construct(ue->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized ult");
    *width_out = 1;
    *et_out = etBOOL;
    return vc_bvLtExpr(vc, left, right);
  }

  case Expr::Ule: {
    UleExpr *ue = cast<UleExpr>(e);
    ExprHandle left = construct(ue->left, width_out, etBV);
    ExprHandle right = construct(ue->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized ule");
    *width_out = 1;
    *et_out = etBOOL;
    return vc_bvLeExpr(vc, left, right);
  }

  case Expr::Slt: {
    SltExpr *se = cast<SltExpr>(e);
    ExprHandle left = construct(se->left, width_out, etBV);
    ExprHandle right = construct(se->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized slt");
    *width_out = 1;
    *et_out = etBOOL;
    return vc_sbvLtExpr(vc, left, right);
  }

  case Expr::Sle: {
    SleExpr *se = cast<SleExpr>(e);
    ExprHandle left = construct(se->left, width_out, etBV);
    ExprHandle right = construct(se->right, width_out, etBV);
    assert(*width_out!=1 && "uncanonicalized sle");
    *width_out = 1;
    *et_out = etBOOL;
    return vc_sbvLeExpr(vc, left, right);
  }

    // unused due to canonicalization
#if 0
  case Expr::Ne:
  case Expr::Ugt:
  case Expr::Uge:
  case Expr::Sgt:
  case Expr::Sge:
#endif

  case Expr::FPToSI:
  case Expr::FPToUI: {
    if (UseFPToIAbstraction) {
      std::ostringstream ss;
      ss << "FPtoI" << fpCount++;
      *width_out = e->getWidth();
      *et_out = etBV;
      return buildVar(ss.str().c_str(), e->getWidth());
    } else {
      F2IConvertExpr *ce = cast<F2IConvertExpr>(e);
      ref<Expr> res = floatUtils(ce->src,
          ce->roundNearest()
            ? ieee_floatt::ROUND_TO_EVEN
            : ieee_floatt::ROUND_TO_ZERO).to_integer(ce->src, ce->getWidth(),
                                                  e->getKind() == Expr::FPToSI);
      return constructActual(res, width_out, et_out);
    }
  }

  case Expr::UIToFP: {
    UIToFPExpr *ue = cast<UIToFPExpr>(e);
    ref<Expr> res = floatUtils(e).from_unsigned_integer(ue->src);
    return constructActual(res, width_out, et_out);
  }

  case Expr::SIToFP: {
    SIToFPExpr *se = cast<SIToFPExpr>(e);
    ref<Expr> res = floatUtils(e).from_signed_integer(se->src);
    return constructActual(res, width_out, et_out);
  }

  case Expr::FCmp: {
    FCmpExpr *ce = cast<FCmpExpr>(e);
    float_utilst &u = floatUtils(ce->left);
    ref<Expr> res;
    switch (ce->getPredicate()) {
    case FCmpExpr::OEQ:
      res = u.relation(ce->left, float_utilst::EQ, ce->right);
      break;
    case FCmpExpr::OGT:
      res = u.relation(ce->left, float_utilst::GT, ce->right);
      break;
    case FCmpExpr::OGE:
      res = u.relation(ce->left, float_utilst::GE, ce->right);
      break;
    case FCmpExpr::OLT:
      res = u.relation(ce->left, float_utilst::LT, ce->right);
      break;
    case FCmpExpr::OLE:
      res = u.relation(ce->left, float_utilst::LE, ce->right);
      break;
    case FCmpExpr::ONE:
      res = OrExpr::create(u.relation(ce->left, float_utilst::LT, ce->right),
                           u.relation(ce->left, float_utilst::GT, ce->right));
      break;
    case FCmpExpr::ORD:
      res = Expr::createIsZero(OrExpr::create(u.is_NaN(ce->left),
                                              u.is_NaN(ce->right)));
      break;
    case FCmpExpr::UNO:
      res = OrExpr::create(u.is_NaN(ce->left),
                           u.is_NaN(ce->right));
      break;
    case FCmpExpr::UEQ:
      res = Expr::createIsZero(
              OrExpr::create(u.relation(ce->left, float_utilst::LT, ce->right),
                            u.relation(ce->left, float_utilst::GT, ce->right)));
      break;
    case FCmpExpr::UGT:
      res = Expr::createIsZero(
              u.relation(ce->left, float_utilst::LE, ce->right));
      break;
    case FCmpExpr::UGE:
      res = Expr::createIsZero(
              u.relation(ce->left, float_utilst::LT, ce->right));
      break;
    case FCmpExpr::ULT:
      res = Expr::createIsZero(
              u.relation(ce->left, float_utilst::GE, ce->right));
      break;
    case FCmpExpr::ULE:
      res = Expr::createIsZero(
              u.relation(ce->left, float_utilst::GT, ce->right));
      break;
    case FCmpExpr::UNE:
      res = Expr::createIsZero(
              u.relation(ce->left, float_utilst::EQ, ce->right));
      break;
    default:
      assert(0 && "fp cmp not implemented yet");
    }
    return constructActual(res, width_out, et_out);
  }

  case Expr::FPExt:
  case Expr::FPTrunc: {
    F2FConvertExpr *ce = cast<F2FConvertExpr>(e);
    float_utilst &fromu = floatUtils(ce->src), &tou = floatUtils(ce);
    ref<Expr> res = fromu.conversion(ce->src, tou.spec);
    return constructActual(res, width_out, et_out);
  }

  case Expr::FAdd: {
    FAddExpr *ae = cast<FAddExpr>(e);
    ref<Expr> res = floatUtils(e).add(ae->left, ae->right);
    return constructActual(res, width_out, et_out);
  }

  case Expr::FSub: {
    FSubExpr *se = cast<FSubExpr>(e);
    ref<Expr> res = floatUtils(e).sub(se->left, se->right);
    return constructActual(res, width_out, et_out);
  }

  case Expr::FMul: {
    FMulExpr *me = cast<FMulExpr>(e);
    ref<Expr> res = floatUtils(e).mul(me->left, me->right);
    return constructActual(res, width_out, et_out);
  }

  case Expr::FDiv: {
    FDivExpr *de = cast<FDivExpr>(e);
    ref<Expr> res = floatUtils(e).div(de->left, de->right);
    return constructActual(res, width_out, et_out);
  }

  default: 
    assert(0 && "unhandled Expr type");
    *et_out = etBOOL;
    return vc_trueExpr(vc);
  }
}
Example #22
0
void ControlFlowIntegrity::ParseAnnotations(void) {
  GlobalVariable *global_ctors = _M.getNamedGlobal("llvm.global.annotations");

  // check for ctor section
  if (!global_ctors || !global_ctors->getOperand(0)) {
    return;
  }

  Constant *c = global_ctors->getInitializer();
  if (!c)
    report_fatal_error("llvm.global.annotations without initializer!", false);

  ConstantArray *CA = dyn_cast<ConstantArray>(c);
  if (!CA)
    report_fatal_error("Cast to ConstantArray failed", true);

  for (Value *Op : ValueOpRange(*CA)) {
    ConstantStruct *CS = dyn_cast<ConstantStruct>(Op);
    if (!CS)
      report_fatal_error("Cast to ConstantStruct failed", true);

    Constant *FP = CS->getOperand(0);
    if (FP->isNullValue())
      break; // found a NULL termintator, stop here

    ConstantExpr *CE;
    Function *F = dyn_cast_or_null<Function>(FP);

    if (F == NULL) {
      // Strip off constant expression cast
      CE = dyn_cast<ConstantExpr>(FP);
      if (!CE)
        report_fatal_error("Cast to ConstantExpr failed", true);
      if (CE->isCast()) {
        FP = CE->getOperand(0);
        F = dyn_cast_or_null<Function>(FP);
      }
    }

    if (!F)
      report_fatal_error("Cast to Function failed", true);

    Constant *SP = CS->getOperand(1);
    if (SP->isNullValue())
      break; // found a NULL termintator, stop here

    // Strip off constant expression cast
    CE = dyn_cast<ConstantExpr>(SP);
    if (!CE)
      report_fatal_error("Cast to ConstantExpr failed", true);
    if (CE->isCast()) {
      SP = CE->getOperand(0);
    }

    Value *V = SP->getOperand(0);
    GlobalVariable *GV = dyn_cast_or_null<GlobalVariable>(V);
    if (!GV)
      report_fatal_error("Cast to GlobalVariable failed", false);
    assert(GV && "cast to GlobalVariable failed");

    Constant *cval = GV->getInitializer();
    const StringRef s = (cast<ConstantDataArray>(cval))->getAsCString();
    if (s == ANNOTATION_IGNORE_BLOCK) {
      _IgnoredBlocksFunctions.insert(F->getName());
    }
  }

  if (global_ctors->getNumUses() > 0)
    report_fatal_error("llvm.global.annotations uses count is > 0", false);
}
Example #23
-1
        virtual bool runOnFunction(Function &F) {
            //F.dump();
            bool changed = false;
            for (inst_iterator inst_it = inst_begin(F), _inst_end = inst_end(F); inst_it != _inst_end; ++inst_it) {
                LoadInst *li = dyn_cast<LoadInst>(&*inst_it);
                if (!li) continue;

                ConstantExpr *ce = dyn_cast<ConstantExpr>(li->getOperand(0));
                // Not 100% sure what the isGEPWithNoNotionalOverIndexing() means, but
                // at least it checks if it's a gep:
                if (ce && ce->isGEPWithNoNotionalOverIndexing() && ce->getOperand(0)->getType() == g.llvm_flavor_type_ptr) {
                    changed = handleFlavor(li, ce);
                }

                GlobalVariable *gv = dyn_cast<GlobalVariable>(li->getOperand(0));
                if (!gv) continue;

                llvm::Type* gv_t = gv->getType();

                if (gv_t == g.llvm_bool_type_ptr->getPointerTo()) {
                    changed = handleBool(li, gv) || changed;
                    continue;
                }

                if (gv_t == g.llvm_class_type_ptr->getPointerTo()) {
                    changed = handleCls(li, gv) || changed;
                    continue;
                }
            }

            return changed;
        }