From: Chris Lattner Date: Thu, 25 May 2006 23:24:33 +0000 (+0000) Subject: Turn (cast (shuffle (cast)) -> shuffle (cast) if it reduces the # casts in X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=01575b73151e7df62075cc0e5eed656f5ca5c088;p=oota-llvm.git Turn (cast (shuffle (cast)) -> shuffle (cast) if it reduces the # casts in the program. This exposes more opportunities for the instcombiner, and implements vec_shuffle.ll:test6 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28487 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Scalar/InstructionCombining.cpp b/lib/Transforms/Scalar/InstructionCombining.cpp index 8bb23226e48..3d096eeecd2 100644 --- a/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/lib/Transforms/Scalar/InstructionCombining.cpp @@ -413,7 +413,7 @@ static bool ValueRequiresCast(const Value *V, const Type *Ty, TargetData *TD) { if (V->getType()->isLosslesslyConvertibleTo(Ty)) return false; - // If this is another cast that can be elimianted, it isn't codegen either. + // If this is another cast that can be eliminated, it isn't codegen either. if (const CastInst *CI = dyn_cast(V)) if (isEliminableCastOfCast(CI->getOperand(0)->getType(), CI->getType(), Ty, TD)) @@ -4970,7 +4970,7 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { // If the source value is an instruction with only this use, we can attempt to // propagate the cast into the instruction. Also, only handle integral types // for now. - if (Instruction *SrcI = dyn_cast(Src)) + if (Instruction *SrcI = dyn_cast(Src)) { if (SrcI->hasOneUse() && Src->getType()->isIntegral() && CI.getType()->isInteger()) { // Don't mess with casts to bool here @@ -5152,6 +5152,35 @@ Instruction *InstCombiner::visitCastInst(CastInst &CI) { break; } } + + if (SrcI->hasOneUse()) { + if (ShuffleVectorInst *SVI = dyn_cast(SrcI)) { + // Okay, we have (cast (shuffle ..)). We know this cast is a bitconvert + // because the inputs are known to be a vector. Check to see if this is + // a cast to a vector with the same # elts. + if (isa(CI.getType()) && + cast(CI.getType())->getNumElements() == + SVI->getType()->getNumElements()) { + CastInst *Tmp; + // If either of the operands is a cast from CI.getType(), then + // evaluating the shuffle in the casted destination's type will allow + // us to eliminate at least one cast. + if (((Tmp = dyn_cast(SVI->getOperand(0))) && + Tmp->getOperand(0)->getType() == CI.getType()) || + ((Tmp = dyn_cast(SVI->getOperand(1))) && + Tmp->getOperand(1)->getType() == CI.getType())) { + Value *LHS = InsertOperandCastBefore(SVI->getOperand(0), + CI.getType(), &CI); + Value *RHS = InsertOperandCastBefore(SVI->getOperand(1), + CI.getType(), &CI); + // Return a new shuffle vector. Use the same element ID's, as we + // know the vector types match #elts. + return new ShuffleVectorInst(LHS, RHS, SVI->getOperand(2)); + } + } + } + } + } return 0; }