Value *llvm::emitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc_strncmp)) return nullptr; Module *M = B.GetInsertBlock()->getModule(); StringRef StrNCmpName = TLI->getName(LibFunc_strncmp); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *StrNCmp = M->getOrInsertFunction(StrNCmpName, B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context)); inferLibFuncAttributes(M, StrNCmpName, *TLI); CallInst *CI = B.CreateCall( StrNCmp, {castToCStr(Ptr1, B), castToCStr(Ptr2, B), Len}, StrNCmpName); if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *llvm::EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc::memchr)) return nullptr; Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeSet AS; Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *MemChr = M->getOrInsertFunction( "memchr", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), DL.getIntPtrType(Context), nullptr); CallInst *CI = B.CreateCall(MemChr, {CastToCStr(Ptr, B), Val, Len}, "memchr"); if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the /// specified pointer arguments. Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, const TargetLibraryInfo *TLI, StringRef Name) { if (!TLI->has(LibFunc::strcpy)) return nullptr; Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeSet AS[2]; AS[0] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, Attribute::NoUnwind); Type *I8Ptr = B.getInt8PtrTy(); Value *StrCpy = M->getOrInsertFunction(Name, AttributeSet::get(M->getContext(), AS), I8Ptr, I8Ptr, I8Ptr, nullptr); CallInst *CI = B.CreateCall(StrCpy, {CastToCStr(Dst, B), CastToCStr(Src, B)}, Name); if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitStrCpy - Emit a call to the strcpy function to the builder, for the /// specified pointer arguments. Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI, StringRef Name) { if (!TLI->has(LibFunc::strcpy)) return 0; Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeWithIndex AWI[2]; AWI[0] = AttributeWithIndex::get(M->getContext(), 2, Attributes::NoCapture); AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); Type *I8Ptr = B.getInt8PtrTy(); Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(M->getContext(), AWI), I8Ptr, I8Ptr, I8Ptr, NULL); CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Name); if (const Function *F = dyn_cast<Function>(StrCpy->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
Value *llvm::emitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, const AttributeList &Attrs) { SmallString<20> NameBuffer; appendTypeSuffix(Op, Name, NameBuffer); Module *M = B.GetInsertBlock()->getModule(); Value *Callee = M->getOrInsertFunction(Name, Op->getType(), Op->getType()); CallInst *CI = B.CreateCall(Callee, Op, Name); // The incoming attribute set may have come from a speculatable intrinsic, but // is being replaced with a library call which is not allowed to be // speculatable. CI->setAttributes(Attrs.removeAttribute(B.getContext(), AttributeList::FunctionIndex, Attribute::Speculatable)); if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitPutS - Emit a call to the puts function. This assumes that Str is /// some pointer. Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc::puts)) return 0; Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeSet AS[2]; AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); AS[1] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, Attribute::NoUnwind); Value *PutS = M->getOrInsertFunction("puts", AttributeSet::get(M->getContext(), AS), B.getInt32Ty(), B.getInt8PtrTy(), NULL); CallInst *CI = B.CreateCall(PutS, CastToCStr(Str, B), "puts"); if (const Function *F = dyn_cast<Function>(PutS->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
Value *llvm::emitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc_memcpy_chk)) return nullptr; Module *M = B.GetInsertBlock()->getModule(); AttributeSet AS; AS = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, Attribute::NoUnwind); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *MemCpy = M->getOrInsertFunction( "__memcpy_chk", AttributeSet::get(M->getContext(), AS), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), DL.getIntPtrType(Context), nullptr); Dst = castToCStr(Dst, B); Src = castToCStr(Src, B); CallInst *CI = B.CreateCall(MemCpy, {Dst, Src, Len, ObjSize}); if (const Function *F = dyn_cast<Function>(MemCpy->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitUnaryFloatFnCall - Emit a call to the unary function named 'Name' (e.g. /// 'floor'). This function is known to take a single of type matching 'Op' and /// returns one value with the same type. If 'Op' is a long double, 'l' is /// added as the suffix of name, if 'Op' is a float, we add a 'f' suffix. Value *llvm::EmitUnaryFloatFnCall(Value *Op, StringRef Name, IRBuilder<> &B, const AttrListPtr &Attrs) { SmallString<20> NameBuffer; if (!Op->getType()->isDoubleTy()) { // If we need to add a suffix, copy into NameBuffer. NameBuffer += Name; if (Op->getType()->isFloatTy()) NameBuffer += 'f'; // floorf else NameBuffer += 'l'; // floorl Name = NameBuffer; } Module *M = B.GetInsertBlock()->getParent()->getParent(); Value *Callee = M->getOrInsertFunction(Name, Op->getType(), Op->getType(), NULL); CallInst *CI = B.CreateCall(Callee, Op, Name); CI->setAttributes(Attrs); if (const Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitMemCmp - Emit a call to the memcmp function. Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, const TargetData *TD) { Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeWithIndex AWI[3]; AWI[0] = AttributeWithIndex::get(1, Attribute::NoCapture); AWI[1] = AttributeWithIndex::get(2, Attribute::NoCapture); AWI[2] = AttributeWithIndex::get(~0u, Attribute::ReadOnly | Attribute::NoUnwind); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI, 3), B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), TD->getIntPtrType(Context), NULL); CallInst *CI = B.CreateCall3(MemCmp, CastToCStr(Ptr1, B), CastToCStr(Ptr2, B), Len, "memcmp"); if (const Function *F = dyn_cast<Function>(MemCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
// // Method: visitCallSite() // // Description: // Examine the specified call site. If it is an indirect call, mark it for // transformation into a direct call. // void Devirtualize::visitCallSite (CallSite &CS) { // // First, determine if this is a direct call. If so, then just ignore it. // Value * CalledValue = CS.getCalledValue(); if (isa<Function>(CalledValue->stripPointerCasts())) return; // // Second, we will only transform those call sites which are complete (i.e., // for which we know all of the call targets). // if (!(CTF->isComplete(CS))) return; // // This is an indirect call site. Put it in the worklist of call sites to // transforms. // Worklist.push_back (CS.getInstruction()); return; }
Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, IRBuilder<> &B, const DataLayout &DL, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc::strncmp)) return nullptr; Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeSet AS[3]; AS[0] = AttributeSet::get(M->getContext(), 1, Attribute::NoCapture); AS[1] = AttributeSet::get(M->getContext(), 2, Attribute::NoCapture); Attribute::AttrKind AVs[2] = { Attribute::ReadOnly, Attribute::NoUnwind }; AS[2] = AttributeSet::get(M->getContext(), AttributeSet::FunctionIndex, AVs); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *StrNCmp = M->getOrInsertFunction( "strncmp", AttributeSet::get(M->getContext(), AS), B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), DL.getIntPtrType(Context), nullptr); CallInst *CI = B.CreateCall( StrNCmp, {CastToCStr(Ptr1, B), CastToCStr(Ptr2, B), Len}, "strncmp"); if (const Function *F = dyn_cast<Function>(StrNCmp->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
/// EmitMemChr - Emit a call to the memchr function. This assumes that Ptr is /// a pointer, Val is an i32 value, and Len is an 'intptr_t' value. Value *llvm::EmitMemChr(Value *Ptr, Value *Val, Value *Len, IRBuilder<> &B, const DataLayout *TD, const TargetLibraryInfo *TLI) { if (!TLI->has(LibFunc::memchr)) return 0; Module *M = B.GetInsertBlock()->getParent()->getParent(); AttributeWithIndex AWI; Attributes::AttrVal AVs[2] = { Attributes::ReadOnly, Attributes::NoUnwind }; AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, ArrayRef<Attributes::AttrVal>(AVs, 2)); Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), TD->getIntPtrType(Ptr->getType()), NULL); CallInst *CI = B.CreateCall3(MemChr, CastToCStr(Ptr, B), Val, Len, "memchr"); if (const Function *F = dyn_cast<Function>(MemChr->stripPointerCasts())) CI->setCallingConv(F->getCallingConv()); return CI; }
// // Method: addGetActualValue() // // Description: // Insert a call to the getactualvalue() run-time function to convert the // potentially Out of Bound pointer back into its original value. // // Inputs: // SCI - The instruction that has arguments requiring conversion. // operand - The index of the operand to the instruction that requires // conversion. // void RewriteOOB::addGetActualValue (Instruction *SCI, unsigned operand) { // // Get a reference to the getactualvalue() function. // Module * M = SCI->getParent()->getParent()->getParent(); Type * VoidPtrTy = getVoidPtrType (M->getContext()); Constant * GAVConst = M->getOrInsertFunction ("pchk_getActualValue", VoidPtrTy, VoidPtrTy, VoidPtrTy, NULL); Function * GetActualValue = cast<Function>(GAVConst); // // Get the operand that needs to be replaced. // Value * Operand = SCI->getOperand(operand); // // // Rewrite pointers are generated from calls to the SAFECode run-time // checks. Therefore, constants and return values from allocation // functions are known to be the original value and do not need to be // rewritten back into their orignal values. // // FIXME: // Add a case for calls to heap allocation functions. // Value * PeeledOperand = Operand->stripPointerCasts(); if (isa<Constant>(PeeledOperand) || isa<AllocaInst>(PeeledOperand)) { return; } // // Get the pool handle associated with the pointer. // Value *PH = ConstantPointerNull::get (getVoidPtrType(Operand->getContext())); // // Create a call to getActualValue() to convert the pointer back to its // original value. // // // Update the number of calls to getActualValue() that we inserted. // ++GetActuals; // // Insert the call to getActualValue() // Type * VoidPtrType = getVoidPtrType(Operand->getContext()); Value * OpVptr = castTo (Operand, VoidPtrType, Operand->getName() + ".casted", SCI); std::vector<Value *> args; args.push_back (PH); args.push_back (OpVptr); CallInst *CI = CallInst::Create (GetActualValue, args, "getval", SCI); Instruction *CastBack = castTo (CI, Operand->getType(), Operand->getName()+".castback", SCI); SCI->setOperand (operand, CastBack); return; }
void PoolRegisterElimination::removeSingletonRegistrations (const char * name) { // // Scan through all uses of the registration function and see if it can be // safely removed. If so, schedule it for removal. // std::vector<CallInst*> toBeRemoved; Function * F = intrinsic->getIntrinsic(name).F; // // Look for and record all registrations that can be deleted. // for (Value::use_iterator UI=F->use_begin(), UE=F->use_end(); UI != UE; ++UI) { // // Get the pointer to the registered object. // CallInst * CI = cast<CallInst>(*UI); Value * Ptr = intrinsic->getValuePointer(CI); // // Lookup the DSNode for the value in the function's DSGraph. // DSGraph * TDG = dsaPass->getDSGraph(*(CI->getParent()->getParent())); DSNodeHandle DSH = TDG->getNodeForValue(Ptr); assert ((!(DSH.isNull())) && "No DSNode for Value!\n"); // // If the object being registered is the same size as that found in the // DSNode, then we know it's a singleton object. The run-time doesn't need // such objects registered in the splay trees, so we can remove the // registration function. // DSNode * N = DSH.getNode(); Value * Size = intrinsic->getObjectSize (Ptr->stripPointerCasts()); if (Size) { if (ConstantInt * C = dyn_cast<ConstantInt>(Size)) { unsigned long size = C->getZExtValue(); if (size == N->getSize()) { toBeRemoved.push_back(CI); continue; } } } } // // Update the statistics. // if (toBeRemoved.size()) { RemovedRegistration += toBeRemoved.size(); SingletonRegistrations += toBeRemoved.size(); } // // Remove the unnecesary registrations. // std::vector<CallInst*>::iterator it, end; for (it = toBeRemoved.begin(), end = toBeRemoved.end(); it != end; ++it) { (*it)->eraseFromParent(); } }
// // Method: runOnModule() // // Description: // Entry point for this LLVM pass. // Find all GEPs, and simplify them. // // 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 SimplifyGEP::runOnModule(Module& M) { TD = &getAnalysis<TargetData>(); preprocess(M); for (Module::iterator F = M.begin(); F != M.end(); ++F){ for (Function::iterator B = F->begin(), FE = F->end(); B != FE; ++B) { for (BasicBlock::iterator I = B->begin(), BE = B->end(); I != BE; I++) { if(!(isa<GetElementPtrInst>(I))) continue; GetElementPtrInst *GEP = cast<GetElementPtrInst>(I); Value *PtrOp = GEP->getOperand(0); Value *StrippedPtr = PtrOp->stripPointerCasts(); // Check if the GEP base pointer is enclosed in a cast if (StrippedPtr != PtrOp) { const PointerType *StrippedPtrTy =cast<PointerType>(StrippedPtr->getType()); bool HasZeroPointerIndex = false; if (ConstantInt *C = dyn_cast<ConstantInt>(GEP->getOperand(1))) HasZeroPointerIndex = C->isZero(); // Transform: GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... // into : GEP [10 x i8]* X, i32 0, ... // // Likewise, transform: GEP (bitcast i8* X to [0 x i8]*), i32 0, ... // into : GEP i8* X, ... // // This occurs when the program declares an array extern like "int X[];" if (HasZeroPointerIndex) { const PointerType *CPTy = cast<PointerType>(PtrOp->getType()); if (const ArrayType *CATy = dyn_cast<ArrayType>(CPTy->getElementType())) { // GEP (bitcast i8* X to [0 x i8]*), i32 0, ... ? if (CATy->getElementType() == StrippedPtrTy->getElementType()) { // -> GEP i8* X, ... SmallVector<Value*, 8> Idx(GEP->idx_begin()+1, GEP->idx_end()); GetElementPtrInst *Res = GetElementPtrInst::Create(StrippedPtr, Idx, GEP->getName(), GEP); Res->setIsInBounds(GEP->isInBounds()); GEP->replaceAllUsesWith(Res); continue; } if (const ArrayType *XATy = dyn_cast<ArrayType>(StrippedPtrTy->getElementType())){ // GEP (bitcast [10 x i8]* X to [0 x i8]*), i32 0, ... ? if (CATy->getElementType() == XATy->getElementType()) { // -> GEP [10 x i8]* X, i32 0, ... // At this point, we know that the cast source type is a pointer // to an array of the same type as the destination pointer // array. Because the array type is never stepped over (there // is a leading zero) we can fold the cast into this GEP. GEP->setOperand(0, StrippedPtr); continue; } } } } else if (GEP->getNumOperands() == 2) { // Transform things like: // %t = getelementptr i32* bitcast ([2 x i32]* %str to i32*), i32 %V // into: %t1 = getelementptr [2 x i32]* %str, i32 0, i32 %V; bitcast Type *SrcElTy = StrippedPtrTy->getElementType(); Type *ResElTy=cast<PointerType>(PtrOp->getType())->getElementType(); if (TD && SrcElTy->isArrayTy() && TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()) == TD->getTypeAllocSize(ResElTy)) { Value *Idx[2]; Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext())); Idx[1] = GEP->getOperand(1); Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx, GEP->getName(), GEP); // V and GEP are both pointer types --> BitCast GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP)); continue; } // Transform things like: // getelementptr i8* bitcast ([100 x double]* X to i8*), i32 %tmp // (where tmp = 8*tmp2) into: // getelementptr [100 x double]* %arr, i32 0, i32 %tmp2; bitcast if (TD && SrcElTy->isArrayTy() && ResElTy->isIntegerTy(8)) { uint64_t ArrayEltSize = TD->getTypeAllocSize(cast<ArrayType>(SrcElTy)->getElementType()); // Check to see if "tmp" is a scale by a multiple of ArrayEltSize. We // allow either a mul, shift, or constant here. Value *NewIdx = 0; ConstantInt *Scale = 0; if (ArrayEltSize == 1) { NewIdx = GEP->getOperand(1); Scale = ConstantInt::get(cast<IntegerType>(NewIdx->getType()), 1); } else if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(1))) { NewIdx = ConstantInt::get(CI->getType(), 1); Scale = CI; } else if (Instruction *Inst =dyn_cast<Instruction>(GEP->getOperand(1))){ if (Inst->getOpcode() == Instruction::Shl && isa<ConstantInt>(Inst->getOperand(1))) { ConstantInt *ShAmt = cast<ConstantInt>(Inst->getOperand(1)); uint32_t ShAmtVal = ShAmt->getLimitedValue(64); Scale = ConstantInt::get(cast<IntegerType>(Inst->getType()), 1ULL << ShAmtVal); NewIdx = Inst->getOperand(0); } else if (Inst->getOpcode() == Instruction::Mul && isa<ConstantInt>(Inst->getOperand(1))) { Scale = cast<ConstantInt>(Inst->getOperand(1)); NewIdx = Inst->getOperand(0); } } // If the index will be to exactly the right offset with the scale taken // out, perform the transformation. Note, we don't know whether Scale is // signed or not. We'll use unsigned version of division/modulo // operation after making sure Scale doesn't have the sign bit set. if (ArrayEltSize && Scale && Scale->getSExtValue() >= 0LL && Scale->getZExtValue() % ArrayEltSize == 0) { Scale = ConstantInt::get(Scale->getType(), Scale->getZExtValue() / ArrayEltSize); if (Scale->getZExtValue() != 1) { Constant *C = ConstantExpr::getIntegerCast(Scale, NewIdx->getType(), false /*ZExt*/); NewIdx = BinaryOperator::Create(BinaryOperator::Mul, NewIdx, C, "idxscale"); } // Insert the new GEP instruction. Value *Idx[2]; Idx[0] = Constant::getNullValue(Type::getInt32Ty(GEP->getContext())); Idx[1] = NewIdx; Value *NewGEP = GetElementPtrInst::Create(StrippedPtr, Idx, GEP->getName(), GEP); GEP->replaceAllUsesWith(new BitCastInst(NewGEP, GEP->getType(), GEP->getName(), GEP)); continue; } } } } } } } return true; }
// If we can determine that all possible objects pointed to by the provided // pointer value are, not only dereferenceable, but also definitively less than // or equal to the provided maximum size, then return true. Otherwise, return // false (constant global values and allocas fall into this category). // // FIXME: This should probably live in ValueTracking (or similar). static bool isObjectSizeLessThanOrEq(Value *V, uint64_t MaxSize, const DataLayout &DL) { SmallPtrSet<Value *, 4> Visited; SmallVector<Value *, 4> Worklist(1, V); do { Value *P = Worklist.pop_back_val(); P = P->stripPointerCasts(); if (!Visited.insert(P).second) continue; if (SelectInst *SI = dyn_cast<SelectInst>(P)) { Worklist.push_back(SI->getTrueValue()); Worklist.push_back(SI->getFalseValue()); continue; } if (PHINode *PN = dyn_cast<PHINode>(P)) { for (Value *IncValue : PN->incoming_values()) Worklist.push_back(IncValue); continue; } if (GlobalAlias *GA = dyn_cast<GlobalAlias>(P)) { if (GA->mayBeOverridden()) return false; Worklist.push_back(GA->getAliasee()); continue; } // If we know how big this object is, and it is less than MaxSize, continue // searching. Otherwise, return false. if (AllocaInst *AI = dyn_cast<AllocaInst>(P)) { if (!AI->getAllocatedType()->isSized()) return false; ConstantInt *CS = dyn_cast<ConstantInt>(AI->getArraySize()); if (!CS) return false; uint64_t TypeSize = DL.getTypeAllocSize(AI->getAllocatedType()); // Make sure that, even if the multiplication below would wrap as an // uint64_t, we still do the right thing. if ((CS->getValue().zextOrSelf(128)*APInt(128, TypeSize)).ugt(MaxSize)) return false; continue; } if (GlobalVariable *GV = dyn_cast<GlobalVariable>(P)) { if (!GV->hasDefinitiveInitializer() || !GV->isConstant()) return false; uint64_t InitSize = DL.getTypeAllocSize(GV->getValueType()); if (InitSize > MaxSize) return false; continue; } return false; } while (!Worklist.empty()); return true; }
void Lint::visitCallSite(CallSite CS) { Instruction &I = *CS.getInstruction(); Value *Callee = CS.getCalledValue(); // TODO: Check function alignment? visitMemoryReference(I, Callee, 0, 0); if (Function *F = dyn_cast<Function>(Callee->stripPointerCasts())) { Assert1(CS.getCallingConv() == F->getCallingConv(), "Undefined behavior: Caller and callee calling convention differ", &I); const FunctionType *FT = F->getFunctionType(); unsigned NumActualArgs = unsigned(CS.arg_end()-CS.arg_begin()); Assert1(FT->isVarArg() ? FT->getNumParams() <= NumActualArgs : FT->getNumParams() == NumActualArgs, "Undefined behavior: Call argument count mismatches callee " "argument count", &I); // TODO: Check argument types (in case the callee was casted) // TODO: Check ABI-significant attributes. // TODO: Check noalias attribute. // TODO: Check sret attribute. } // TODO: Check the "tail" keyword constraints. if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I)) switch (II->getIntrinsicID()) { default: break; // TODO: Check more intrinsics case Intrinsic::memcpy: { MemCpyInst *MCI = cast<MemCpyInst>(&I); visitMemoryReference(I, MCI->getSource(), MCI->getAlignment(), 0); visitMemoryReference(I, MCI->getDest(), MCI->getAlignment(), 0); // Check that the memcpy arguments don't overlap. The AliasAnalysis API // isn't expressive enough for what we really want to do. Known partial // overlap is not distinguished from the case where nothing is known. unsigned Size = 0; if (const ConstantInt *Len = dyn_cast<ConstantInt>(MCI->getLength()->stripPointerCasts())) if (Len->getValue().isIntN(32)) Size = Len->getValue().getZExtValue(); Assert1(AA->alias(MCI->getSource(), Size, MCI->getDest(), Size) != AliasAnalysis::MustAlias, "Undefined behavior: memcpy source and destination overlap", &I); break; } case Intrinsic::memmove: { MemMoveInst *MMI = cast<MemMoveInst>(&I); visitMemoryReference(I, MMI->getSource(), MMI->getAlignment(), 0); visitMemoryReference(I, MMI->getDest(), MMI->getAlignment(), 0); break; } case Intrinsic::memset: { MemSetInst *MSI = cast<MemSetInst>(&I); visitMemoryReference(I, MSI->getDest(), MSI->getAlignment(), 0); break; } case Intrinsic::vastart: Assert1(I.getParent()->getParent()->isVarArg(), "Undefined behavior: va_start called in a non-varargs function", &I); visitMemoryReference(I, CS.getArgument(0), 0, 0); break; case Intrinsic::vacopy: visitMemoryReference(I, CS.getArgument(0), 0, 0); visitMemoryReference(I, CS.getArgument(1), 0, 0); break; case Intrinsic::vaend: visitMemoryReference(I, CS.getArgument(0), 0, 0); break; case Intrinsic::stackrestore: visitMemoryReference(I, CS.getArgument(0), 0, 0); break; } }
/// \brief Check if executing a load of this pointer value cannot trap. /// /// If DT is specified this method performs context-sensitive analysis. /// /// If it is not obviously safe to load from the specified pointer, we do /// a quick local scan of the basic block containing \c ScanFrom, to determine /// if the address is already accessed. /// /// This uses the pointee type to determine how many bytes need to be safe to /// load from the pointer. bool llvm::isSafeToLoadUnconditionally(Value *V, unsigned Align, Instruction *ScanFrom, const DominatorTree *DT, const TargetLibraryInfo *TLI) { const DataLayout &DL = ScanFrom->getModule()->getDataLayout(); // Zero alignment means that the load has the ABI alignment for the target if (Align == 0) Align = DL.getABITypeAlignment(V->getType()->getPointerElementType()); assert(isPowerOf2_32(Align)); // If DT is not specified we can't make context-sensitive query const Instruction* CtxI = DT ? ScanFrom : nullptr; if (isDereferenceableAndAlignedPointer(V, Align, DL, CtxI, DT, TLI)) return true; int64_t ByteOffset = 0; Value *Base = V; Base = GetPointerBaseWithConstantOffset(V, ByteOffset, DL); if (ByteOffset < 0) // out of bounds return false; Type *BaseType = nullptr; unsigned BaseAlign = 0; if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) { // An alloca is safe to load from as load as it is suitably aligned. BaseType = AI->getAllocatedType(); BaseAlign = AI->getAlignment(); } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { // Global variables are not necessarily safe to load from if they are // interposed arbitrarily. Their size may change or they may be weak and // require a test to determine if they were in fact provided. if (!GV->isInterposable()) { BaseType = GV->getType()->getElementType(); BaseAlign = GV->getAlignment(); } } PointerType *AddrTy = cast<PointerType>(V->getType()); uint64_t LoadSize = DL.getTypeStoreSize(AddrTy->getElementType()); // If we found a base allocated type from either an alloca or global variable, // try to see if we are definitively within the allocated region. We need to // know the size of the base type and the loaded type to do anything in this // case. if (BaseType && BaseType->isSized()) { if (BaseAlign == 0) BaseAlign = DL.getPrefTypeAlignment(BaseType); if (Align <= BaseAlign) { // Check if the load is within the bounds of the underlying object. if (ByteOffset + LoadSize <= DL.getTypeAllocSize(BaseType) && ((ByteOffset % Align) == 0)) return true; } } // Otherwise, be a little bit aggressive by scanning the local block where we // want to check to see if the pointer is already being loaded or stored // from/to. If so, the previous load or store would have already trapped, // so there is no harm doing an extra load (also, CSE will later eliminate // the load entirely). BasicBlock::iterator BBI = ScanFrom->getIterator(), E = ScanFrom->getParent()->begin(); // We can at least always strip pointer casts even though we can't use the // base here. V = V->stripPointerCasts(); while (BBI != E) { --BBI; // If we see a free or a call which may write to memory (i.e. which might do // a free) the pointer could be marked invalid. if (isa<CallInst>(BBI) && BBI->mayWriteToMemory() && !isa<DbgInfoIntrinsic>(BBI)) return false; Value *AccessedPtr; unsigned AccessedAlign; if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) { AccessedPtr = LI->getPointerOperand(); AccessedAlign = LI->getAlignment(); } else if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) { AccessedPtr = SI->getPointerOperand(); AccessedAlign = SI->getAlignment(); } else continue; Type *AccessedTy = AccessedPtr->getType()->getPointerElementType(); if (AccessedAlign == 0) AccessedAlign = DL.getABITypeAlignment(AccessedTy); if (AccessedAlign < Align) continue; // Handle trivial cases. if (AccessedPtr == V) return true; if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) && LoadSize <= DL.getTypeStoreSize(AccessedTy)) return true; } return false; }
/// \brief Check if executing a load of this pointer value cannot trap. /// /// If it is not obviously safe to load from the specified pointer, we do /// a quick local scan of the basic block containing \c ScanFrom, to determine /// if the address is already accessed. /// /// This uses the pointee type to determine how many bytes need to be safe to /// load from the pointer. bool llvm::isSafeToLoadUnconditionally(Value *V, Instruction *ScanFrom, unsigned Align, const DataLayout *DL) { int64_t ByteOffset = 0; Value *Base = V; Base = GetPointerBaseWithConstantOffset(V, ByteOffset, DL); if (ByteOffset < 0) // out of bounds return false; Type *BaseType = nullptr; unsigned BaseAlign = 0; if (const AllocaInst *AI = dyn_cast<AllocaInst>(Base)) { // An alloca is safe to load from as load as it is suitably aligned. BaseType = AI->getAllocatedType(); BaseAlign = AI->getAlignment(); } else if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) { // Global variables are not necessarily safe to load from if they are // overridden. Their size may change or they may be weak and require a test // to determine if they were in fact provided. if (!GV->mayBeOverridden()) { BaseType = GV->getType()->getElementType(); BaseAlign = GV->getAlignment(); } } PointerType *AddrTy = cast<PointerType>(V->getType()); uint64_t LoadSize = DL ? DL->getTypeStoreSize(AddrTy->getElementType()) : 0; // If we found a base allocated type from either an alloca or global variable, // try to see if we are definitively within the allocated region. We need to // know the size of the base type and the loaded type to do anything in this // case, so only try this when we have the DataLayout available. if (BaseType && BaseType->isSized() && DL) { if (BaseAlign == 0) BaseAlign = DL->getPrefTypeAlignment(BaseType); if (Align <= BaseAlign) { // Check if the load is within the bounds of the underlying object. if (ByteOffset + LoadSize <= DL->getTypeAllocSize(BaseType) && (Align == 0 || (ByteOffset % Align) == 0)) return true; } } // Otherwise, be a little bit aggressive by scanning the local block where we // want to check to see if the pointer is already being loaded or stored // from/to. If so, the previous load or store would have already trapped, // so there is no harm doing an extra load (also, CSE will later eliminate // the load entirely). BasicBlock::iterator BBI = ScanFrom, E = ScanFrom->getParent()->begin(); // We can at least always strip pointer casts even though we can't use the // base here. V = V->stripPointerCasts(); while (BBI != E) { --BBI; // If we see a free or a call which may write to memory (i.e. which might do // a free) the pointer could be marked invalid. if (isa<CallInst>(BBI) && BBI->mayWriteToMemory() && !isa<DbgInfoIntrinsic>(BBI)) return false; Value *AccessedPtr; if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) AccessedPtr = LI->getPointerOperand(); else if (StoreInst *SI = dyn_cast<StoreInst>(BBI)) AccessedPtr = SI->getPointerOperand(); else continue; // Handle trivial cases even w/o DataLayout or other work. if (AccessedPtr == V) return true; if (!DL) continue; auto *AccessedTy = cast<PointerType>(AccessedPtr->getType()); if (AreEquivalentAddressValues(AccessedPtr->stripPointerCasts(), V) && LoadSize <= DL->getTypeStoreSize(AccessedTy->getElementType())) return true; } return false; }
/// Evaluate all instructions in block BB, returning true if successful, false /// if we can't evaluate it. NewBB returns the next BB that control flows into, /// or null upon return. bool Evaluator::EvaluateBlock(BasicBlock::iterator CurInst, BasicBlock *&NextBB) { // This is the main evaluation loop. while (1) { Constant *InstResult = nullptr; DEBUG(dbgs() << "Evaluating Instruction: " << *CurInst << "\n"); if (StoreInst *SI = dyn_cast<StoreInst>(CurInst)) { if (!SI->isSimple()) { DEBUG(dbgs() << "Store is not simple! Can not evaluate.\n"); return false; // no volatile/atomic accesses. } Constant *Ptr = getVal(SI->getOperand(1)); if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) { DEBUG(dbgs() << "Folding constant ptr expression: " << *Ptr); Ptr = FoldedPtr; DEBUG(dbgs() << "; To: " << *Ptr << "\n"); } if (!isSimpleEnoughPointerToCommit(Ptr)) { // If this is too complex for us to commit, reject it. DEBUG(dbgs() << "Pointer is too complex for us to evaluate store."); return false; } Constant *Val = getVal(SI->getOperand(0)); // If this might be too difficult for the backend to handle (e.g. the addr // of one global variable divided by another) then we can't commit it. if (!isSimpleEnoughValueToCommit(Val, SimpleConstants, DL)) { DEBUG(dbgs() << "Store value is too complex to evaluate store. " << *Val << "\n"); return false; } if (ConstantExpr *CE = dyn_cast<ConstantExpr>(Ptr)) { if (CE->getOpcode() == Instruction::BitCast) { DEBUG(dbgs() << "Attempting to resolve bitcast on constant ptr.\n"); // If we're evaluating a store through a bitcast, then we need // to pull the bitcast off the pointer type and push it onto the // stored value. Ptr = CE->getOperand(0); Type *NewTy = cast<PointerType>(Ptr->getType())->getElementType(); // In order to push the bitcast onto the stored value, a bitcast // from NewTy to Val's type must be legal. If it's not, we can try // introspecting NewTy to find a legal conversion. while (!Val->getType()->canLosslesslyBitCastTo(NewTy)) { // If NewTy is a struct, we can convert the pointer to the struct // into a pointer to its first member. // FIXME: This could be extended to support arrays as well. if (StructType *STy = dyn_cast<StructType>(NewTy)) { NewTy = STy->getTypeAtIndex(0U); IntegerType *IdxTy = IntegerType::get(NewTy->getContext(), 32); Constant *IdxZero = ConstantInt::get(IdxTy, 0, false); Constant * const IdxList[] = {IdxZero, IdxZero}; Ptr = ConstantExpr::getGetElementPtr(nullptr, Ptr, IdxList); if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) Ptr = FoldedPtr; // If we can't improve the situation by introspecting NewTy, // we have to give up. } else { DEBUG(dbgs() << "Failed to bitcast constant ptr, can not " "evaluate.\n"); return false; } } // If we found compatible types, go ahead and push the bitcast // onto the stored value. Val = ConstantExpr::getBitCast(Val, NewTy); DEBUG(dbgs() << "Evaluated bitcast: " << *Val << "\n"); } } MutatedMemory[Ptr] = Val; } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) { InstResult = ConstantExpr::get(BO->getOpcode(), getVal(BO->getOperand(0)), getVal(BO->getOperand(1))); DEBUG(dbgs() << "Found a BinaryOperator! Simplifying: " << *InstResult << "\n"); } else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) { InstResult = ConstantExpr::getCompare(CI->getPredicate(), getVal(CI->getOperand(0)), getVal(CI->getOperand(1))); DEBUG(dbgs() << "Found a CmpInst! Simplifying: " << *InstResult << "\n"); } else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) { InstResult = ConstantExpr::getCast(CI->getOpcode(), getVal(CI->getOperand(0)), CI->getType()); DEBUG(dbgs() << "Found a Cast! Simplifying: " << *InstResult << "\n"); } else if (SelectInst *SI = dyn_cast<SelectInst>(CurInst)) { InstResult = ConstantExpr::getSelect(getVal(SI->getOperand(0)), getVal(SI->getOperand(1)), getVal(SI->getOperand(2))); DEBUG(dbgs() << "Found a Select! Simplifying: " << *InstResult << "\n"); } else if (auto *EVI = dyn_cast<ExtractValueInst>(CurInst)) { InstResult = ConstantExpr::getExtractValue( getVal(EVI->getAggregateOperand()), EVI->getIndices()); DEBUG(dbgs() << "Found an ExtractValueInst! Simplifying: " << *InstResult << "\n"); } else if (auto *IVI = dyn_cast<InsertValueInst>(CurInst)) { InstResult = ConstantExpr::getInsertValue( getVal(IVI->getAggregateOperand()), getVal(IVI->getInsertedValueOperand()), IVI->getIndices()); DEBUG(dbgs() << "Found an InsertValueInst! Simplifying: " << *InstResult << "\n"); } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurInst)) { Constant *P = getVal(GEP->getOperand(0)); SmallVector<Constant*, 8> GEPOps; for (User::op_iterator i = GEP->op_begin() + 1, e = GEP->op_end(); i != e; ++i) GEPOps.push_back(getVal(*i)); InstResult = ConstantExpr::getGetElementPtr(GEP->getSourceElementType(), P, GEPOps, cast<GEPOperator>(GEP)->isInBounds()); DEBUG(dbgs() << "Found a GEP! Simplifying: " << *InstResult << "\n"); } else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) { if (!LI->isSimple()) { DEBUG(dbgs() << "Found a Load! Not a simple load, can not evaluate.\n"); return false; // no volatile/atomic accesses. } Constant *Ptr = getVal(LI->getOperand(0)); if (auto *FoldedPtr = ConstantFoldConstant(Ptr, DL, TLI)) { Ptr = FoldedPtr; DEBUG(dbgs() << "Found a constant pointer expression, constant " "folding: " << *Ptr << "\n"); } InstResult = ComputeLoadResult(Ptr); if (!InstResult) { DEBUG(dbgs() << "Failed to compute load result. Can not evaluate load." "\n"); return false; // Could not evaluate load. } DEBUG(dbgs() << "Evaluated load: " << *InstResult << "\n"); } else if (AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) { if (AI->isArrayAllocation()) { DEBUG(dbgs() << "Found an array alloca. Can not evaluate.\n"); return false; // Cannot handle array allocs. } Type *Ty = AI->getAllocatedType(); AllocaTmps.push_back( make_unique<GlobalVariable>(Ty, false, GlobalValue::InternalLinkage, UndefValue::get(Ty), AI->getName())); InstResult = AllocaTmps.back().get(); DEBUG(dbgs() << "Found an alloca. Result: " << *InstResult << "\n"); } else if (isa<CallInst>(CurInst) || isa<InvokeInst>(CurInst)) { CallSite CS(&*CurInst); // Debug info can safely be ignored here. if (isa<DbgInfoIntrinsic>(CS.getInstruction())) { DEBUG(dbgs() << "Ignoring debug info.\n"); ++CurInst; continue; } // Cannot handle inline asm. if (isa<InlineAsm>(CS.getCalledValue())) { DEBUG(dbgs() << "Found inline asm, can not evaluate.\n"); return false; } if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(CS.getInstruction())) { if (MemSetInst *MSI = dyn_cast<MemSetInst>(II)) { if (MSI->isVolatile()) { DEBUG(dbgs() << "Can not optimize a volatile memset " << "intrinsic.\n"); return false; } Constant *Ptr = getVal(MSI->getDest()); Constant *Val = getVal(MSI->getValue()); Constant *DestVal = ComputeLoadResult(getVal(Ptr)); if (Val->isNullValue() && DestVal && DestVal->isNullValue()) { // This memset is a no-op. DEBUG(dbgs() << "Ignoring no-op memset.\n"); ++CurInst; continue; } } if (II->getIntrinsicID() == Intrinsic::lifetime_start || II->getIntrinsicID() == Intrinsic::lifetime_end) { DEBUG(dbgs() << "Ignoring lifetime intrinsic.\n"); ++CurInst; continue; } if (II->getIntrinsicID() == Intrinsic::invariant_start) { // We don't insert an entry into Values, as it doesn't have a // meaningful return value. if (!II->use_empty()) { DEBUG(dbgs() << "Found unused invariant_start. Can't evaluate.\n"); return false; } ConstantInt *Size = cast<ConstantInt>(II->getArgOperand(0)); Value *PtrArg = getVal(II->getArgOperand(1)); Value *Ptr = PtrArg->stripPointerCasts(); if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Ptr)) { Type *ElemTy = GV->getValueType(); if (!Size->isMinusOne() && Size->getValue().getLimitedValue() >= DL.getTypeStoreSize(ElemTy)) { Invariants.insert(GV); DEBUG(dbgs() << "Found a global var that is an invariant: " << *GV << "\n"); } else { DEBUG(dbgs() << "Found a global var, but can not treat it as an " "invariant.\n"); } } // Continue even if we do nothing. ++CurInst; continue; } else if (II->getIntrinsicID() == Intrinsic::assume) { DEBUG(dbgs() << "Skipping assume intrinsic.\n"); ++CurInst; continue; } DEBUG(dbgs() << "Unknown intrinsic. Can not evaluate.\n"); return false; } // Resolve function pointers. Function *Callee = dyn_cast<Function>(getVal(CS.getCalledValue())); if (!Callee || Callee->isInterposable()) { DEBUG(dbgs() << "Can not resolve function pointer.\n"); return false; // Cannot resolve. } SmallVector<Constant*, 8> Formals; for (User::op_iterator i = CS.arg_begin(), e = CS.arg_end(); i != e; ++i) Formals.push_back(getVal(*i)); if (Callee->isDeclaration()) { // If this is a function we can constant fold, do it. if (Constant *C = ConstantFoldCall(CS, Callee, Formals, TLI)) { InstResult = C; DEBUG(dbgs() << "Constant folded function call. Result: " << *InstResult << "\n"); } else { DEBUG(dbgs() << "Can not constant fold function call.\n"); return false; } } else { if (Callee->getFunctionType()->isVarArg()) { DEBUG(dbgs() << "Can not constant fold vararg function call.\n"); return false; } Constant *RetVal = nullptr; // Execute the call, if successful, use the return value. ValueStack.emplace_back(); if (!EvaluateFunction(Callee, RetVal, Formals)) { DEBUG(dbgs() << "Failed to evaluate function.\n"); return false; } ValueStack.pop_back(); InstResult = RetVal; if (InstResult) { DEBUG(dbgs() << "Successfully evaluated function. Result: " << *InstResult << "\n\n"); } else { DEBUG(dbgs() << "Successfully evaluated function. Result: 0\n\n"); } } } else if (isa<TerminatorInst>(CurInst)) { DEBUG(dbgs() << "Found a terminator instruction.\n"); if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) { if (BI->isUnconditional()) { NextBB = BI->getSuccessor(0); } else { ConstantInt *Cond = dyn_cast<ConstantInt>(getVal(BI->getCondition())); if (!Cond) return false; // Cannot determine. NextBB = BI->getSuccessor(!Cond->getZExtValue()); } } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurInst)) { ConstantInt *Val = dyn_cast<ConstantInt>(getVal(SI->getCondition())); if (!Val) return false; // Cannot determine. NextBB = SI->findCaseValue(Val)->getCaseSuccessor(); } else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(CurInst)) { Value *Val = getVal(IBI->getAddress())->stripPointerCasts(); if (BlockAddress *BA = dyn_cast<BlockAddress>(Val)) NextBB = BA->getBasicBlock(); else return false; // Cannot determine. } else if (isa<ReturnInst>(CurInst)) { NextBB = nullptr; } else { // invoke, unwind, resume, unreachable. DEBUG(dbgs() << "Can not handle terminator."); return false; // Cannot handle this terminator. } // We succeeded at evaluating this block! DEBUG(dbgs() << "Successfully evaluated block.\n"); return true; } else { // Did not know how to evaluate this! DEBUG(dbgs() << "Failed to evaluate block due to unhandled instruction." "\n"); return false; } if (!CurInst->use_empty()) { if (auto *FoldedInstResult = ConstantFoldConstant(InstResult, DL, TLI)) InstResult = FoldedInstResult; setVal(&*CurInst, InstResult); } // If we just processed an invoke, we finished evaluating the block. if (InvokeInst *II = dyn_cast<InvokeInst>(CurInst)) { NextBB = II->getNormalDest(); DEBUG(dbgs() << "Found an invoke instruction. Finished Block.\n\n"); return true; } // Advance program counter. ++CurInst; } }
// // Method: processFunction() // // Description: // This method searches for calls to a specified run-time check. For every // such call, it replaces the pointer that the call checks with the return // value of the call. // // This allows functions like boundscheck() to return a rewrite pointer; // this code changes the program to use the returned rewrite pointer instead // of the original pointer which was passed into boundscheck(). // // Inputs: // M - The module to modify. // Check - A reference to a structure describing the checking function to // process. // // Return value: // false - No modifications were made to the Module. // true - One or more modifications were made to the module. // bool RewriteOOB::processFunction (Module & M, const CheckInfo & Check) { // // Get a pointer to the checking function. If the checking function does // not exist within the program, then do nothing. // Function * F = M.getFunction (Check.name); if (!F) return false; // // Ensure the function has the right number of arguments and that its // result is a pointer type. // assert (isa<PointerType>(F->getReturnType())); // // To avoid recalculating the dominator information each time we process a // use of the specified function F, we will record the function containing // the call instruction to F and the corresponding dominator information; we // will then update this information only when the next use is a call // instruction belonging to a different function. We are helped by the fact // that iterating through uses often groups uses within the same function. // Function * CurrentFunction = 0; DominatorTree * domTree = 0; // // Iterate though all calls to the function and modify the use of the // operand to be the result of the function. // bool modified = false; for (Value::use_iterator FU = F->use_begin(); FU != F->use_end(); ++FU) { // // We are only concerned about call instructions; any other use is of // no interest to the organization. // if (CallInst * CI = dyn_cast<CallInst>(*FU)) { // // We're going to make a change. Mark that we will have done so. // modified = true; // // Get the operand that needs to be replaced as well as the operand // with all of the casts peeled away. Increment the operand index by // one because a call instruction's first operand is the function to // call. // Value * RealOperand = Check.getCheckedPointer (CI); Value * PeeledOperand = RealOperand->stripPointerCasts(); // // Cast the result of the call instruction to match that of the original // value. // BasicBlock::iterator i(CI); Instruction * CastCI = castTo (CI, PeeledOperand->getType(), PeeledOperand->getName(), ++i); // // Get dominator information for the function. // if ((CI->getParent()->getParent()) != CurrentFunction) { CurrentFunction = CI->getParent()->getParent(); domTree = &getAnalysis<DominatorTree>(*CurrentFunction); } // // For every use that the call instruction dominates, change the use to // use the result of the call instruction. We first collect the uses // that need to be modified before doing the modifications to avoid any // iterator invalidation errors. // std::vector<User *> Uses; Value::use_iterator UI = PeeledOperand->use_begin(); for (; UI != PeeledOperand->use_end(); ++UI) { if (Instruction * Use = dyn_cast<Instruction>(*UI)) if ((CI != Use) && (domTree->dominates (CI, Use))) { Uses.push_back (*UI); ++Changes; } } while (Uses.size()) { User * Use = Uses.back(); Uses.pop_back(); Use->replaceUsesOfWith (PeeledOperand, CastCI); } } } return modified; }
/// analyzeDestructor - Given the heap.metadata argument to swift_allocObject, /// take a look a the destructor and try to decide if it has side effects or any /// other bad effects that can prevent it from being optimized. static DtorKind analyzeDestructor(Value *P) { // If we have a null pointer for the metadata info, the dtor has no side // effects. Actually, the final release would crash. This is really only // useful for writing testcases. if (isa<ConstantPointerNull>(P->stripPointerCasts())) return DtorKind::NoSideEffects; // We have to have a known heap metadata value, reject dynamically computed // ones, or places GlobalVariable *GV = dyn_cast<GlobalVariable>(P->stripPointerCasts()); if (GV == 0 || GV->mayBeOverridden()) return DtorKind::Unknown; ConstantStruct *CS = dyn_cast_or_null<ConstantStruct>(GV->getInitializer()); if (CS == 0 || CS->getNumOperands() == 0) return DtorKind::Unknown; // FIXME: Would like to abstract the dtor slot (#0) out from this to somewhere // unified. enum { DTorSlotOfHeapMetadata = 0 }; Function *DtorFn =dyn_cast<Function>(CS->getOperand(DTorSlotOfHeapMetadata)); if (DtorFn == 0 || DtorFn->mayBeOverridden() || DtorFn->hasExternalLinkage()) return DtorKind::Unknown; // Okay, we have a body, and we can trust it. If the function is marked // readonly, then we know it can't have any interesting side effects, so we // don't need to analyze it at all. if (DtorFn->onlyReadsMemory()) return DtorKind::NoSideEffects; // The first argument is the object being destroyed. assert(DtorFn->arg_size() == 1 && !DtorFn->isVarArg() && "expected a single object argument to destructors"); Value *ThisObject = &*DtorFn->arg_begin(); // Scan the body of the function, looking for anything scary. for (BasicBlock &BB : *DtorFn) { for (Instruction &I : BB) { // Note that the destructor may not be in any particular canonical form. switch (classifyInstruction(I)) { // These instructions should not reach here based on the pass ordering. // i.e. LLVMARCOpt -> LLVMContractOpt. case RT_RetainN: case RT_UnknownRetainN: case RT_BridgeRetainN: case RT_ReleaseN: case RT_UnknownReleaseN: case RT_BridgeReleaseN: llvm_unreachable("These are only created by LLVMARCContract !"); case RT_NoMemoryAccessed: case RT_AllocObject: case RT_FixLifetime: case RT_CheckUnowned: // Skip over random instructions that don't touch memory in the caller. continue; case RT_RetainUnowned: case RT_BridgeRetain: // x = swift_bridgeRetain(y) case RT_Retain: { // swift_retain(obj) // Ignore retains of the "self" object, no resurrection is possible. Value *ThisRetainedObject = cast<CallInst>(I).getArgOperand(0); if (ThisRetainedObject->stripPointerCasts() == ThisObject->stripPointerCasts()) continue; // Otherwise, we may be retaining something scary. break; } case RT_Release: { // If we get to a release that is provably to this object, then we can // ignore it. Value *ThisReleasedObject = cast<CallInst>(I).getArgOperand(0); if (ThisReleasedObject->stripPointerCasts() == ThisObject->stripPointerCasts()) continue; // Otherwise, we may be retaining something scary. break; } case RT_ObjCRelease: case RT_ObjCRetain: case RT_UnknownRetain: case RT_UnknownRelease: case RT_BridgeRelease: // Objective-C retain and release can have arbitrary side effects. break; case RT_Unknown: // Ignore all instructions with no side effects. if (!I.mayHaveSideEffects()) continue; // store, memcpy, memmove *to* the object can be dropped. if (StoreInst *SI = dyn_cast<StoreInst>(&I)) { if (SI->getPointerOperand()->stripInBoundsOffsets() == ThisObject) continue; } if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&I)) { if (MI->getDest()->stripInBoundsOffsets() == ThisObject) continue; } // Otherwise, we can't remove the deallocation completely. break; } // Okay, the function has some side effects, if it doesn't capture the // object argument, at least that is something. return DtorFn->doesNotCapture(0) ? DtorKind::NoEscape : DtorKind::Unknown; } } // If we didn't find any side effects, we win. return DtorKind::NoSideEffects; }
/// processByValArgument - This is called on every byval argument in call sites. bool MemCpyOpt::processByValArgument(CallSite CS, unsigned ArgNo) { if (TD == 0) return false; // Find out what feeds this byval argument. Value *ByValArg = CS.getArgument(ArgNo); Type *ByValTy = cast<PointerType>(ByValArg->getType())->getElementType(); uint64_t ByValSize = TD->getTypeAllocSize(ByValTy); MemDepResult DepInfo = MD->getPointerDependencyFrom(AliasAnalysis::Location(ByValArg, ByValSize), true, CS.getInstruction(), CS.getInstruction()->getParent()); if (!DepInfo.isClobber()) return false; // If the byval argument isn't fed by a memcpy, ignore it. If it is fed by // a memcpy, see if we can byval from the source of the memcpy instead of the // result. MemCpyInst *MDep = dyn_cast<MemCpyInst>(DepInfo.getInst()); if (MDep == 0 || MDep->isVolatile() || ByValArg->stripPointerCasts() != MDep->getDest()) return false; // The length of the memcpy must be larger or equal to the size of the byval. ConstantInt *C1 = dyn_cast<ConstantInt>(MDep->getLength()); if (C1 == 0 || C1->getValue().getZExtValue() < ByValSize) return false; // Get the alignment of the byval. If the call doesn't specify the alignment, // then it is some target specific value that we can't know. unsigned ByValAlign = CS.getParamAlignment(ArgNo+1); if (ByValAlign == 0) return false; // If it is greater than the memcpy, then we check to see if we can force the // source of the memcpy to the alignment we need. If we fail, we bail out. if (MDep->getAlignment() < ByValAlign && getOrEnforceKnownAlignment(MDep->getSource(),ByValAlign, TD) < ByValAlign) return false; // Verify that the copied-from memory doesn't change in between the memcpy and // the byval call. // memcpy(a <- b) // *b = 42; // foo(*a) // It would be invalid to transform the second memcpy into foo(*b). // // NOTE: This is conservative, it will stop on any read from the source loc, // not just the defining memcpy. MemDepResult SourceDep = MD->getPointerDependencyFrom(AliasAnalysis::getLocationForSource(MDep), false, CS.getInstruction(), MDep->getParent()); if (!SourceDep.isClobber() || SourceDep.getInst() != MDep) return false; Value *TmpCast = MDep->getSource(); if (MDep->getSource()->getType() != ByValArg->getType()) TmpCast = new BitCastInst(MDep->getSource(), ByValArg->getType(), "tmpcast", CS.getInstruction()); DEBUG(dbgs() << "MemCpyOpt: Forwarding memcpy to byval:\n" << " " << *MDep << "\n" << " " << *CS.getInstruction() << "\n"); // Otherwise we're good! Update the byval argument. CS.setArgument(ArgNo, TmpCast); ++NumMemCpyInstr; return true; }
// // Method: insertEasyDanglingPointers() // // Description: // Insert dangling pointer dereferences into the code. This is done by // finding load/store instructions and inserting a free on the pointer to // ensure the dereference (and all future dereferences) are illegal. // // Return value: // true - The module was modified. // false - The module was left unmodified. // // Notes: // This code utilizes DSA to ensure that the pointer can pointer to heap // memory (although the pointer is allowed to alias global and stack memory). // bool FaultInjector::insertEasyDanglingPointers (Function & F) { // // Ensure that we can get analysis information for this function. // if (!(TDPass->hasDSGraph(F))) return false; // // Scan through each instruction of the function looking for load and store // instructions. Free the pointer right before. // DSGraph * DSG = TDPass->getDSGraph(F); for (Function::iterator fI = F.begin(), fE = F.end(); fI != fE; ++fI) { BasicBlock & BB = *fI; for (BasicBlock::iterator bI = BB.begin(), bE = BB.end(); bI != bE; ++bI) { Instruction * I = bI; // // Look to see if there is an instruction that uses a pointer. If so, // then free the pointer before the use. // Value * Pointer = 0; if (LoadInst * LI = dyn_cast<LoadInst>(I)) Pointer = LI->getPointerOperand(); else if (StoreInst * SI = dyn_cast<StoreInst>(I)) Pointer = SI->getPointerOperand(); else continue; // // Check to ensure that this pointer aliases with the heap. If so, go // ahead and add the free. Note that we may introduce an invalid free, // but we're injecting errors, so I think that's okay. // DSNode * Node = DSG->getNodeForValue(Pointer).getNode(); if (Node && (Node->isHeapNode())) { // // Avoid free'ing pointers that are trivially stack objects or global // variables. // if (isa<GlobalValue>(Pointer->stripPointerCasts()) || isa<AllocaInst>(Pointer->stripPointerCasts())) { continue; } // Skip if we should not insert a fault. if (!doFault()) continue; // // Print information about where the fault is being inserted. // printSourceInfo ("Easy dangling pointer", I); CallInst::Create (Free, Pointer, "", I); ++DPFaults; } } } return (DPFaults > 0); }
/// \brief Scan the ScanBB block backwards to see if we have the value at the /// memory address *Ptr locally available within a small number of instructions. /// /// The scan starts from \c ScanFrom. \c MaxInstsToScan specifies the maximum /// instructions to scan in the block. If it is set to \c 0, it will scan the whole /// block. /// /// If the value is available, this function returns it. If not, it returns the /// iterator for the last validated instruction that the value would be live /// through. If we scanned the entire block and didn't find something that /// invalidates \c *Ptr or provides it, \c ScanFrom is left at the last /// instruction processed and this returns null. /// /// You can also optionally specify an alias analysis implementation, which /// makes this more precise. /// /// If \c AATags is non-null and a load or store is found, the AA tags from the /// load or store are recorded there. If there are no AA tags or if no access is /// found, it is left unmodified. Value *llvm::FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan, AliasAnalysis *AA, AAMDNodes *AATags) { if (MaxInstsToScan == 0) MaxInstsToScan = ~0U; Value *Ptr = Load->getPointerOperand(); Type *AccessTy = Load->getType(); const DataLayout &DL = ScanBB->getModule()->getDataLayout(); // Try to get the store size for the type. uint64_t AccessSize = DL.getTypeStoreSize(AccessTy); Value *StrippedPtr = Ptr->stripPointerCasts(); while (ScanFrom != ScanBB->begin()) { // We must ignore debug info directives when counting (otherwise they // would affect codegen). Instruction *Inst = &*--ScanFrom; if (isa<DbgInfoIntrinsic>(Inst)) continue; // Restore ScanFrom to expected value in case next test succeeds ScanFrom++; // Don't scan huge blocks. if (MaxInstsToScan-- == 0) return nullptr; --ScanFrom; // If this is a load of Ptr, the loaded value is available. // (This is true even if the load is volatile or atomic, although // those cases are unlikely.) if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) if (AreEquivalentAddressValues( LI->getPointerOperand()->stripPointerCasts(), StrippedPtr) && CastInst::isBitOrNoopPointerCastable(LI->getType(), AccessTy, DL)) { if (AATags) LI->getAAMetadata(*AATags); return LI; } if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { Value *StorePtr = SI->getPointerOperand()->stripPointerCasts(); // If this is a store through Ptr, the value is available! // (This is true even if the store is volatile or atomic, although // those cases are unlikely.) if (AreEquivalentAddressValues(StorePtr, StrippedPtr) && CastInst::isBitOrNoopPointerCastable(SI->getValueOperand()->getType(), AccessTy, DL)) { if (AATags) SI->getAAMetadata(*AATags); return SI->getOperand(0); } // If both StrippedPtr and StorePtr reach all the way to an alloca or // global and they are different, ignore the store. This is a trivial form // of alias analysis that is important for reg2mem'd code. if ((isa<AllocaInst>(StrippedPtr) || isa<GlobalVariable>(StrippedPtr)) && (isa<AllocaInst>(StorePtr) || isa<GlobalVariable>(StorePtr)) && StrippedPtr != StorePtr) continue; // If we have alias analysis and it says the store won't modify the loaded // value, ignore the store. if (AA && (AA->getModRefInfo(SI, StrippedPtr, AccessSize) & MRI_Mod) == 0) continue; // Otherwise the store that may or may not alias the pointer, bail out. ++ScanFrom; return nullptr; } // If this is some other instruction that may clobber Ptr, bail out. if (Inst->mayWriteToMemory()) { // If alias analysis claims that it really won't modify the load, // ignore it. if (AA && (AA->getModRefInfo(Inst, StrippedPtr, AccessSize) & MRI_Mod) == 0) continue; // May modify the pointer, bail out. ++ScanFrom; return nullptr; } } // Got to the start of the block, we didn't find it, but are done for this // block. return nullptr; }