X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FInstCombine%2FInstCombineCalls.cpp;h=c531fd32ac45c8f4cdab4e4a249204f95de63c45;hb=165dac08d1bb8428b32a5f39cdd3dbee2888987f;hp=b9445040c84d50aba9881f1899d122f30c0b6ea5;hpb=1df9859c40492511b8aa4321eb76496005d3b75b;p=oota-llvm.git diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index b9445040c84..c531fd32ac4 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -16,6 +16,7 @@ #include "llvm/Support/CallSite.h" #include "llvm/Target/TargetData.h" #include "llvm/Analysis/MemoryBuiltins.h" +#include "llvm/Transforms/Utils/BuildLibCalls.h" using namespace llvm; /// getPromotedType - Return the specified type promoted as it would be to pass @@ -108,8 +109,8 @@ unsigned InstCombiner::GetOrEnforceKnownAlignment(Value *V, } Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { - unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(1)); - unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(2)); + unsigned DstAlign = GetOrEnforceKnownAlignment(MI->getOperand(0)); + unsigned SrcAlign = GetOrEnforceKnownAlignment(MI->getOperand(1)); unsigned MinAlign = std::min(DstAlign, SrcAlign); unsigned CopyAlign = MI->getAlignment(); @@ -121,7 +122,7 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { // If MemCpyInst length is 1/2/4/8 bytes then replace memcpy with // load/store. - ConstantInt *MemOpLength = dyn_cast(MI->getOperand(3)); + ConstantInt *MemOpLength = dyn_cast(MI->getOperand(2)); if (MemOpLength == 0) return 0; // Source and destination pointer types are always "i8*" for intrinsic. See @@ -135,8 +136,14 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { return 0; // If not 1/2/4/8 bytes, exit. // Use an integer load+store unless we can find something better. - Type *NewPtrTy = - PointerType::getUnqual(IntegerType::get(MI->getContext(), Size<<3)); + unsigned SrcAddrSp = + cast(MI->getOperand(1)->getType())->getAddressSpace(); + unsigned DstAddrSp = + cast(MI->getOperand(0)->getType())->getAddressSpace(); + + const IntegerType* IntType = IntegerType::get(MI->getContext(), Size<<3); + Type *NewSrcPtrTy = PointerType::get(IntType, SrcAddrSp); + Type *NewDstPtrTy = PointerType::get(IntType, DstAddrSp); // Memcpy forces the use of i8* for the source and destination. That means // that if you're using memcpy to move one double around, you'll get a cast @@ -144,8 +151,8 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { // an i64 load+store, here because this improves the odds that the source or // dest address will be promotable. See if we can find a better type than the // integer datatype. - Value *StrippedDest = MI->getOperand(1)->stripPointerCasts(); - if (StrippedDest != MI->getOperand(1)) { + Value *StrippedDest = MI->getOperand(0)->stripPointerCasts(); + if (StrippedDest != MI->getOperand(0)) { const Type *SrcETy = cast(StrippedDest->getType()) ->getElementType(); if (TD && SrcETy->isSized() && TD->getTypeStoreSize(SrcETy) == Size) { @@ -166,8 +173,10 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { break; } - if (SrcETy->isSingleValueType()) - NewPtrTy = PointerType::getUnqual(SrcETy); + if (SrcETy->isSingleValueType()) { + NewSrcPtrTy = PointerType::get(SrcETy, SrcAddrSp); + NewDstPtrTy = PointerType::get(SrcETy, DstAddrSp); + } } } @@ -177,14 +186,15 @@ Instruction *InstCombiner::SimplifyMemTransfer(MemIntrinsic *MI) { SrcAlign = std::max(SrcAlign, CopyAlign); DstAlign = std::max(DstAlign, CopyAlign); - Value *Src = Builder->CreateBitCast(MI->getOperand(2), NewPtrTy); - Value *Dest = Builder->CreateBitCast(MI->getOperand(1), NewPtrTy); - Instruction *L = new LoadInst(Src, "tmp", false, SrcAlign); + Value *Src = Builder->CreateBitCast(MI->getOperand(1), NewSrcPtrTy); + Value *Dest = Builder->CreateBitCast(MI->getOperand(0), NewDstPtrTy); + Instruction *L = new LoadInst(Src, "tmp", MI->isVolatile(), SrcAlign); InsertNewInstBefore(L, *MI); - InsertNewInstBefore(new StoreInst(L, Dest, false, DstAlign), *MI); + InsertNewInstBefore(new StoreInst(L, Dest, MI->isVolatile(), DstAlign), + *MI); // Set the size of the copy to 0, it will be deleted on the next iteration. - MI->setOperand(3, Constant::getNullValue(MemOpLength->getType())); + MI->setOperand(2, Constant::getNullValue(MemOpLength->getType())); return MI; } @@ -248,7 +258,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { IntrinsicInst *II = dyn_cast(&CI); if (!II) return visitCallSite(&CI); - + // Intrinsics cannot occur in an invoke, so handle them here instead of in // visitCallSite. if (MemIntrinsic *MI = dyn_cast(II)) { @@ -272,12 +282,13 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { if (MemMoveInst *MMI = dyn_cast(MI)) { if (GlobalVariable *GVSrc = dyn_cast(MMI->getSource())) if (GVSrc->isConstant()) { - Module *M = CI.getParent()->getParent()->getParent(); + Module *M = MMI->getParent()->getParent()->getParent(); Intrinsic::ID MemCpyID = Intrinsic::memcpy; - const Type *Tys[1]; - Tys[0] = CI.getOperand(3)->getType(); - CI.setOperand(0, - Intrinsic::getDeclaration(M, MemCpyID, Tys, 1)); + const Type *Tys[3] = { CI.getOperand(0)->getType(), + CI.getOperand(1)->getType(), + CI.getOperand(2)->getType() }; + MMI->setCalledFunction( + Intrinsic::getDeclaration(M, MemCpyID, Tys, 3)); Changed = true; } } @@ -286,47 +297,65 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // memmove(x,x,size) -> noop. if (MTI->getSource() == MTI->getDest()) return EraseInstFromFunction(CI); - } - // If we can determine a pointer alignment that is bigger than currently - // set, update the alignment. - if (isa(MI)) { - if (Instruction *I = SimplifyMemTransfer(MI)) + // If we can determine a pointer alignment that is bigger than currently + // set, update the alignment. + if (Instruction *I = SimplifyMemTransfer(MTI)) return I; } else if (MemSetInst *MSI = dyn_cast(MI)) { if (Instruction *I = SimplifyMemSet(MSI)) return I; } - + if (Changed) return II; } - + switch (II->getIntrinsicID()) { default: break; case Intrinsic::objectsize: { - const Type *ReturnTy = CI.getType(); - Value *Op1 = II->getOperand(1); - bool Min = (cast(II->getOperand(2))->getZExtValue() == 1); - // We need target data for just about everything so depend on it. if (!TD) break; + const Type *ReturnTy = CI.getType(); + bool Min = (cast(II->getOperand(1))->getZExtValue() == 1); + // Get to the real allocated thing and offset as fast as possible. - Op1 = Op1->stripPointerCasts(); + Value *Op1 = II->getOperand(0)->stripPointerCasts(); // If we've stripped down to a single global variable that we // can know the size of then just return that. if (GlobalVariable *GV = dyn_cast(Op1)) { if (GV->hasDefinitiveInitializer()) { Constant *C = GV->getInitializer(); - size_t globalSize = TD->getTypeAllocSize(C->getType()); - return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, globalSize)); + uint64_t GlobalSize = TD->getTypeAllocSize(C->getType()); + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, GlobalSize)); } else { + // Can't determine size of the GV. Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); return ReplaceInstUsesWith(CI, RetVal); } - } else if (ConstantExpr *CE = dyn_cast(Op1)) { - + } else if (AllocaInst *AI = dyn_cast(Op1)) { + // Get alloca size. + if (AI->getAllocatedType()->isSized()) { + uint64_t AllocaSize = TD->getTypeAllocSize(AI->getAllocatedType()); + if (AI->isArrayAllocation()) { + const ConstantInt *C = dyn_cast(AI->getArraySize()); + if (!C) break; + AllocaSize *= C->getZExtValue(); + } + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, AllocaSize)); + } + } else if (CallInst *MI = extractMallocCall(Op1)) { + const Type* MallocType = getMallocAllocatedType(MI); + // Get alloca size. + if (MallocType && MallocType->isSized()) { + if (Value *NElems = getMallocArraySize(MI, TD, true)) { + if (ConstantInt *NElements = dyn_cast(NElems)) + return ReplaceInstUsesWith(CI, ConstantInt::get(ReturnTy, + (NElements->getZExtValue() * TD->getTypeAllocSize(MallocType)))); + } + } + } else if (ConstantExpr *CE = dyn_cast(Op1)) { // Only handle constant GEPs here. if (CE->getOpcode() != Instruction::GetElementPtr) break; GEPOperator *GEP = cast(CE); @@ -337,67 +366,75 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { Operand = Operand->stripPointerCasts(); if (GlobalVariable *GV = dyn_cast(Operand)) if (!GV->hasDefinitiveInitializer()) break; - + // Get what we're pointing to and its size. const PointerType *BaseType = cast(Operand->getType()); - size_t Size = TD->getTypeAllocSize(BaseType->getElementType()); + uint64_t Size = TD->getTypeAllocSize(BaseType->getElementType()); // Get the current byte offset into the thing. Use the original // operand in case we're looking through a bitcast. SmallVector Ops(CE->op_begin()+1, CE->op_end()); const PointerType *OffsetType = cast(GEP->getPointerOperand()->getType()); - size_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size()); + uint64_t Offset = TD->getIndexedOffset(OffsetType, &Ops[0], Ops.size()); - assert(Size >= Offset); + if (Size < Offset) { + // Out of bound reference? Negative index normalized to large + // index? Just return "I don't know". + Constant *RetVal = ConstantInt::get(ReturnTy, Min ? 0 : -1ULL); + return ReplaceInstUsesWith(CI, RetVal); + } Constant *RetVal = ConstantInt::get(ReturnTy, Size-Offset); return ReplaceInstUsesWith(CI, RetVal); - - } + } + + // Do not return "I don't know" here. Later optimization passes could + // make it possible to evaluate objectsize to a constant. + break; } case Intrinsic::bswap: // bswap(bswap(x)) -> x - if (IntrinsicInst *Operand = dyn_cast(II->getOperand(1))) + if (IntrinsicInst *Operand = dyn_cast(II->getOperand(0))) if (Operand->getIntrinsicID() == Intrinsic::bswap) - return ReplaceInstUsesWith(CI, Operand->getOperand(1)); + return ReplaceInstUsesWith(CI, Operand->getOperand(0)); // bswap(trunc(bswap(x))) -> trunc(lshr(x, c)) - if (TruncInst *TI = dyn_cast(II->getOperand(1))) { + if (TruncInst *TI = dyn_cast(II->getOperand(0))) { if (IntrinsicInst *Operand = dyn_cast(TI->getOperand(0))) if (Operand->getIntrinsicID() == Intrinsic::bswap) { unsigned C = Operand->getType()->getPrimitiveSizeInBits() - TI->getType()->getPrimitiveSizeInBits(); Value *CV = ConstantInt::get(Operand->getType(), C); - Value *V = Builder->CreateLShr(Operand->getOperand(1), CV); + Value *V = Builder->CreateLShr(Operand->getOperand(0), CV); return new TruncInst(V, TI->getType()); } } break; case Intrinsic::powi: - if (ConstantInt *Power = dyn_cast(II->getOperand(2))) { + if (ConstantInt *Power = dyn_cast(II->getOperand(1))) { // powi(x, 0) -> 1.0 if (Power->isZero()) return ReplaceInstUsesWith(CI, ConstantFP::get(CI.getType(), 1.0)); // powi(x, 1) -> x if (Power->isOne()) - return ReplaceInstUsesWith(CI, II->getOperand(1)); + return ReplaceInstUsesWith(CI, II->getOperand(0)); // powi(x, -1) -> 1/x if (Power->isAllOnesValue()) return BinaryOperator::CreateFDiv(ConstantFP::get(CI.getType(), 1.0), - II->getOperand(1)); + II->getOperand(0)); } break; case Intrinsic::cttz: { // If all bits below the first known one are known zero, // this value is constant. - const IntegerType *IT = cast(II->getOperand(1)->getType()); + const IntegerType *IT = cast(II->getOperand(0)->getType()); uint32_t BitWidth = IT->getBitWidth(); APInt KnownZero(BitWidth, 0); APInt KnownOne(BitWidth, 0); - ComputeMaskedBits(II->getOperand(1), APInt::getAllOnesValue(BitWidth), + ComputeMaskedBits(II->getOperand(0), APInt::getAllOnesValue(BitWidth), KnownZero, KnownOne); unsigned TrailingZeros = KnownOne.countTrailingZeros(); APInt Mask(APInt::getLowBitsSet(BitWidth, TrailingZeros)); @@ -410,11 +447,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::ctlz: { // If all bits above the first known one are known zero, // this value is constant. - const IntegerType *IT = cast(II->getOperand(1)->getType()); + const IntegerType *IT = cast(II->getOperand(0)->getType()); uint32_t BitWidth = IT->getBitWidth(); APInt KnownZero(BitWidth, 0); APInt KnownOne(BitWidth, 0); - ComputeMaskedBits(II->getOperand(1), APInt::getAllOnesValue(BitWidth), + ComputeMaskedBits(II->getOperand(0), APInt::getAllOnesValue(BitWidth), KnownZero, KnownOne); unsigned LeadingZeros = KnownOne.countLeadingZeros(); APInt Mask(APInt::getHighBitsSet(BitWidth, LeadingZeros)); @@ -425,8 +462,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { } break; case Intrinsic::uadd_with_overflow: { - Value *LHS = II->getOperand(1), *RHS = II->getOperand(2); - const IntegerType *IT = cast(II->getOperand(1)->getType()); + Value *LHS = II->getOperand(0), *RHS = II->getOperand(1); + const IntegerType *IT = cast(II->getOperand(0)->getType()); uint32_t BitWidth = IT->getBitWidth(); APInt Mask = APInt::getSignBit(BitWidth); APInt LHSKnownZero(BitWidth, 0); @@ -470,19 +507,19 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // FALL THROUGH uadd into sadd case Intrinsic::sadd_with_overflow: // Canonicalize constants into the RHS. - if (isa(II->getOperand(1)) && - !isa(II->getOperand(2))) { - Value *LHS = II->getOperand(1); - II->setOperand(1, II->getOperand(2)); - II->setOperand(2, LHS); + if (isa(II->getOperand(0)) && + !isa(II->getOperand(1))) { + Value *LHS = II->getOperand(0); + II->setOperand(0, II->getOperand(1)); + II->setOperand(1, LHS); return II; } // X + undef -> undef - if (isa(II->getOperand(2))) + if (isa(II->getOperand(1))) return ReplaceInstUsesWith(CI, UndefValue::get(II->getType())); - if (ConstantInt *RHS = dyn_cast(II->getOperand(2))) { + if (ConstantInt *RHS = dyn_cast(II->getOperand(1))) { // X + 0 -> {X, false} if (RHS->isZero()) { Constant *V[] = { @@ -490,7 +527,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { ConstantInt::getFalse(II->getContext()) }; Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); - return InsertValueInst::Create(Struct, II->getOperand(1), 0); + return InsertValueInst::Create(Struct, II->getOperand(0), 0); } } break; @@ -498,38 +535,38 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::ssub_with_overflow: // undef - X -> undef // X - undef -> undef - if (isa(II->getOperand(1)) || - isa(II->getOperand(2))) + if (isa(II->getOperand(0)) || + isa(II->getOperand(1))) return ReplaceInstUsesWith(CI, UndefValue::get(II->getType())); - if (ConstantInt *RHS = dyn_cast(II->getOperand(2))) { + if (ConstantInt *RHS = dyn_cast(II->getOperand(1))) { // X - 0 -> {X, false} if (RHS->isZero()) { Constant *V[] = { - UndefValue::get(II->getOperand(1)->getType()), + UndefValue::get(II->getOperand(0)->getType()), ConstantInt::getFalse(II->getContext()) }; Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); - return InsertValueInst::Create(Struct, II->getOperand(1), 0); + return InsertValueInst::Create(Struct, II->getOperand(0), 0); } } break; case Intrinsic::umul_with_overflow: case Intrinsic::smul_with_overflow: // Canonicalize constants into the RHS. - if (isa(II->getOperand(1)) && - !isa(II->getOperand(2))) { - Value *LHS = II->getOperand(1); - II->setOperand(1, II->getOperand(2)); - II->setOperand(2, LHS); + if (isa(II->getOperand(0)) && + !isa(II->getOperand(1))) { + Value *LHS = II->getOperand(0); + II->setOperand(0, II->getOperand(1)); + II->setOperand(1, LHS); return II; } // X * undef -> undef - if (isa(II->getOperand(2))) + if (isa(II->getOperand(1))) return ReplaceInstUsesWith(CI, UndefValue::get(II->getType())); - if (ConstantInt *RHSI = dyn_cast(II->getOperand(2))) { + if (ConstantInt *RHSI = dyn_cast(II->getOperand(1))) { // X*0 -> {0, false} if (RHSI->isZero()) return ReplaceInstUsesWith(CI, Constant::getNullValue(II->getType())); @@ -537,11 +574,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // X * 1 -> {X, false} if (RHSI->equalsInt(1)) { Constant *V[] = { - UndefValue::get(II->getOperand(1)->getType()), + UndefValue::get(II->getOperand(0)->getType()), ConstantInt::getFalse(II->getContext()) }; Constant *Struct = ConstantStruct::get(II->getContext(), V, 2, false); - return InsertValueInst::Create(Struct, II->getOperand(1), 0); + return InsertValueInst::Create(Struct, II->getOperand(0), 0); } } break; @@ -552,8 +589,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::x86_sse2_loadu_dq: // Turn PPC lvx -> load if the pointer is known aligned. // Turn X86 loadups -> load if the pointer is known aligned. - if (GetOrEnforceKnownAlignment(II->getOperand(1), 16) >= 16) { - Value *Ptr = Builder->CreateBitCast(II->getOperand(1), + if (GetOrEnforceKnownAlignment(II->getOperand(0), 16) >= 16) { + Value *Ptr = Builder->CreateBitCast(II->getOperand(0), PointerType::getUnqual(II->getType())); return new LoadInst(Ptr); } @@ -561,22 +598,22 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::ppc_altivec_stvx: case Intrinsic::ppc_altivec_stvxl: // Turn stvx -> store if the pointer is known aligned. - if (GetOrEnforceKnownAlignment(II->getOperand(2), 16) >= 16) { + if (GetOrEnforceKnownAlignment(II->getOperand(1), 16) >= 16) { const Type *OpPtrTy = - PointerType::getUnqual(II->getOperand(1)->getType()); - Value *Ptr = Builder->CreateBitCast(II->getOperand(2), OpPtrTy); - return new StoreInst(II->getOperand(1), Ptr); + PointerType::getUnqual(II->getOperand(0)->getType()); + Value *Ptr = Builder->CreateBitCast(II->getOperand(1), OpPtrTy); + return new StoreInst(II->getOperand(0), Ptr); } break; case Intrinsic::x86_sse_storeu_ps: case Intrinsic::x86_sse2_storeu_pd: case Intrinsic::x86_sse2_storeu_dq: // Turn X86 storeu -> store if the pointer is known aligned. - if (GetOrEnforceKnownAlignment(II->getOperand(1), 16) >= 16) { + if (GetOrEnforceKnownAlignment(II->getOperand(0), 16) >= 16) { const Type *OpPtrTy = - PointerType::getUnqual(II->getOperand(2)->getType()); - Value *Ptr = Builder->CreateBitCast(II->getOperand(1), OpPtrTy); - return new StoreInst(II->getOperand(2), Ptr); + PointerType::getUnqual(II->getOperand(1)->getType()); + Value *Ptr = Builder->CreateBitCast(II->getOperand(0), OpPtrTy); + return new StoreInst(II->getOperand(1), Ptr); } break; @@ -584,12 +621,12 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { // These intrinsics only demands the 0th element of its input vector. If // we can simplify the input based on that, do so now. unsigned VWidth = - cast(II->getOperand(1)->getType())->getNumElements(); + cast(II->getOperand(0)->getType())->getNumElements(); APInt DemandedElts(VWidth, 1); APInt UndefElts(VWidth, 0); - if (Value *V = SimplifyDemandedVectorElts(II->getOperand(1), DemandedElts, + if (Value *V = SimplifyDemandedVectorElts(II->getOperand(0), DemandedElts, UndefElts)) { - II->setOperand(1, V); + II->setOperand(0, V); return II; } break; @@ -597,7 +634,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::ppc_altivec_vperm: // Turn vperm(V1,V2,mask) -> shuffle(V1,V2,mask) if mask is a constant. - if (ConstantVector *Mask = dyn_cast(II->getOperand(3))) { + if (ConstantVector *Mask = dyn_cast(II->getOperand(2))) { assert(Mask->getNumOperands() == 16 && "Bad type for intrinsic!"); // Check that all of the elements are integer constants or undefs. @@ -612,8 +649,8 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { if (AllEltsOk) { // Cast the input vectors to byte vectors. - Value *Op0 = Builder->CreateBitCast(II->getOperand(1), Mask->getType()); - Value *Op1 = Builder->CreateBitCast(II->getOperand(2), Mask->getType()); + Value *Op0 = Builder->CreateBitCast(II->getOperand(0), Mask->getType()); + Value *Op1 = Builder->CreateBitCast(II->getOperand(1), Mask->getType()); Value *Result = UndefValue::get(Op0->getType()); // Only extract each element once. @@ -646,7 +683,7 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) { case Intrinsic::stackrestore: { // If the save is right next to the restore, remove the restore. This can // happen when variable allocas are DCE'd. - if (IntrinsicInst *SS = dyn_cast(II->getOperand(1))) { + if (IntrinsicInst *SS = dyn_cast(II->getOperand(0))) { if (SS->getIntrinsicID() == Intrinsic::stacksave) { BasicBlock::iterator BI = SS; if (&*++BI == II) @@ -721,6 +758,43 @@ static bool isSafeToEliminateVarargsCast(const CallSite CS, return true; } +namespace { +class InstCombineFortifiedLibCalls : public SimplifyFortifiedLibCalls { + InstCombiner *IC; +protected: + void replaceCall(Value *With) { + NewInstruction = IC->ReplaceInstUsesWith(*CI, With); + } + bool isFoldable(unsigned SizeCIOp, unsigned SizeArgOp, bool isString) const { + if (ConstantInt *SizeCI = dyn_cast(CI->getOperand(SizeCIOp))) { + if (SizeCI->isAllOnesValue()) + return true; + if (isString) + return SizeCI->getZExtValue() >= + GetStringLength(CI->getOperand(SizeArgOp)); + if (ConstantInt *Arg = dyn_cast(CI->getOperand(SizeArgOp))) + return SizeCI->getZExtValue() >= Arg->getZExtValue(); + } + return false; + } +public: + InstCombineFortifiedLibCalls(InstCombiner *IC) : IC(IC), NewInstruction(0) { } + Instruction *NewInstruction; +}; +} // end anonymous namespace + +// Try to fold some different type of calls here. +// Currently we're only working with the checking functions, memcpy_chk, +// mempcpy_chk, memmove_chk, memset_chk, strcpy_chk, stpcpy_chk, strncpy_chk, +// strcat_chk and strncat_chk. +Instruction *InstCombiner::tryOptimizeCall(CallInst *CI, const TargetData *TD) { + if (CI->getCalledFunction() == 0) return 0; + + InstCombineFortifiedLibCalls Simplifier(this); + Simplifier.fold(CI, TD); + return Simplifier.NewInstruction; +} + // visitCallSite - Improvements for call and invoke instructions. // Instruction *InstCombiner::visitCallSite(CallSite CS) { @@ -753,7 +827,7 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { // We cannot remove an invoke, because it would change the CFG, just // change the callee to a null pointer. - cast(OldCall)->setOperand(0, + cast(OldCall)->setCalledFunction( Constant::getNullValue(CalleeF->getType())); return 0; } @@ -766,7 +840,7 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { UndefValue::get(Type::getInt1PtrTy(Callee->getContext())), CS.getInstruction()); - // If CS dues not return void then replaceAllUsesWith undef. + // If CS does not return void then replaceAllUsesWith undef. // This allows ValueHandlers and custom metadata to adjust itself. if (!CS.getInstruction()->getType()->isVoidTy()) CS.getInstruction()-> @@ -807,6 +881,16 @@ Instruction *InstCombiner::visitCallSite(CallSite CS) { Changed = true; } + // Try to optimize the call if possible, we require TargetData for most of + // this. None of these calls are seen as possibly dead so go ahead and + // delete the instruction now. + if (CallInst *CI = dyn_cast(CS.getInstruction())) { + Instruction *I = tryOptimizeCall(CI, TD); + // If we changed something return the result, etc. Otherwise let + // the fallthrough check. + if (I) return EraseInstFromFunction(*I); + } + return Changed ? CS.getInstruction() : 0; } @@ -1050,7 +1134,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) { IntrinsicInst *Tramp = cast(cast(Callee)->getOperand(0)); - Function *NestF = cast(Tramp->getOperand(2)->stripPointerCasts()); + Function *NestF = cast(Tramp->getOperand(1)->stripPointerCasts()); const PointerType *NestFPTy = cast(NestF->getType()); const FunctionType *NestFTy = cast(NestFPTy->getElementType()); @@ -1091,7 +1175,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) { do { if (Idx == NestIdx) { // Add the chain argument and attributes. - Value *NestVal = Tramp->getOperand(3); + Value *NestVal = Tramp->getOperand(2); if (NestVal->getType() != NestTy) NestVal = new BitCastInst(NestVal, NestTy, "nest", Caller); NewArgs.push_back(NestVal);