From: Chris Lattner Date: Mon, 31 Jan 2005 05:51:45 +0000 (+0000) Subject: Implement InstCombine/cast.ll:test25, a case that occurs many times X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=fcfe33acda7fdac53834db228e26c736c4107143;p=oota-llvm.git Implement InstCombine/cast.ll:test25, a case that occurs many times in spec git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19953 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 885355dc0b8..a90dde6c8aa 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -4622,6 +4622,7 @@ static Constant *GetGEPGlobalInitializer(Constant *C, ConstantExpr *CE) { return C; } +/// InstCombineLoadCast - Fold 'load (cast P)' -> cast (load P)' when possible. static Instruction *InstCombineLoadCast(InstCombiner &IC, LoadInst &LI) { User *CI = cast(LI.getOperand(0)); Value *CastOp = CI->getOperand(0); @@ -4805,6 +4806,51 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { return 0; } +/// InstCombineStoreToCast - Fold 'store V, (cast P)' -> store (cast V), P' +/// when possible. +static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { + User *CI = cast(SI.getOperand(1)); + Value *CastOp = CI->getOperand(0); + + const Type *DestPTy = cast(CI->getType())->getElementType(); + if (const PointerType *SrcTy = dyn_cast(CastOp->getType())) { + const Type *SrcPTy = SrcTy->getElementType(); + + if (DestPTy->isInteger() || isa(DestPTy)) { + // If the source is an array, the code below will not succeed. Check to + // see if a trivial 'gep P, 0, 0' will help matters. Only do this for + // constants. + if (const ArrayType *ASrcTy = dyn_cast(SrcPTy)) + if (Constant *CSrc = dyn_cast(CastOp)) + if (ASrcTy->getNumElements() != 0) { + std::vector Idxs(2, Constant::getNullValue(Type::IntTy)); + CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs); + SrcTy = cast(CastOp->getType()); + SrcPTy = SrcTy->getElementType(); + } + + if ((SrcPTy->isInteger() || isa(SrcPTy)) && + IC.getTargetData().getTypeSize(SrcPTy) == + IC.getTargetData().getTypeSize(DestPTy)) { + + // Okay, we are casting from one integer or pointer type to another of + // the same size. Instead of casting the pointer before the store, cast + // the value to be stored. + Value *NewCast; + if (Constant *C = dyn_cast(SI.getOperand(0))) + NewCast = ConstantExpr::getCast(C, SrcPTy); + else + NewCast = IC.InsertNewInstBefore(new CastInst(SI.getOperand(0), + SrcPTy, + SI.getOperand(0)->getName()+".c"), SI); + + return new StoreInst(NewCast, CastOp); + } + } + } + return 0; +} + Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { Value *Val = SI.getOperand(0); Value *Ptr = SI.getOperand(1); @@ -4837,6 +4883,16 @@ Instruction *InstCombiner::visitStoreInst(StoreInst &SI) { return 0; } + // If the pointer destination is a cast, see if we can fold the cast into the + // source instead. + if (CastInst *CI = dyn_cast(Ptr)) + if (Instruction *Res = InstCombineStoreToCast(*this, SI)) + return Res; + if (ConstantExpr *CE = dyn_cast(Ptr)) + if (CE->getOpcode() == Instruction::Cast) + if (Instruction *Res = InstCombineStoreToCast(*this, SI)) + return Res; + return 0; }