Changes in directory llvm/lib/Transforms/Scalar:
InstructionCombining.cpp updated: 1.486 -> 1.487 --- Log message: Transform things like (splat(splat)) -> splat --- Diffs of the changes: (+50 -4) InstructionCombining.cpp | 54 +++++++++++++++++++++++++++++++++++++++++++---- 1 files changed, 50 insertions(+), 4 deletions(-) Index: llvm/lib/Transforms/Scalar/InstructionCombining.cpp diff -u llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.486 llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.487 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp:1.486 Thu May 25 18:48:38 2006 +++ llvm/lib/Transforms/Scalar/InstructionCombining.cpp Thu May 25 19:29:06 2006 @@ -7398,18 +7398,26 @@ // Remap any references to RHS to use LHS. std::vector<Constant*> Elts; for (unsigned i = 0, e = Mask.size(); i != e; ++i) { - if (Mask[i] > 2*e) + if (Mask[i] >= 2*e) Elts.push_back(UndefValue::get(Type::UIntTy)); - else - Elts.push_back(ConstantUInt::get(Type::UIntTy, Mask[i] & (e-1))); + else { + if ((Mask[i] >= e && isa<UndefValue>(RHS)) || + (Mask[i] < e && isa<UndefValue>(LHS))) + Mask[i] = 2*e; // Turn into undef. + else + Mask[i] &= (e-1); // Force to LHS. + Elts.push_back(ConstantUInt::get(Type::UIntTy, Mask[i])); + } } SVI.setOperand(0, SVI.getOperand(1)); SVI.setOperand(1, UndefValue::get(RHS->getType())); SVI.setOperand(2, ConstantPacked::get(Elts)); + LHS = SVI.getOperand(0); + RHS = SVI.getOperand(1); MadeChange = true; } - // Analyze the shuffle, are the LHS or RHS and identity shuffle? + // Analyze the shuffle, are the LHS or RHS and identity shuffles? bool isLHSID = true, isRHSID = true; for (unsigned i = 0, e = Mask.size(); i != e; ++i) { @@ -7425,6 +7433,44 @@ if (isLHSID) return ReplaceInstUsesWith(SVI, LHS); if (isRHSID) return ReplaceInstUsesWith(SVI, RHS); + // If the LHS is a shufflevector itself, see if we can combine it with this + // one without producing an unusual shuffle. Here we are really conservative: + // we are absolutely afraid of producing a shuffle mask not in the input + // program, because the code gen may not be smart enough to turn a merged + // shuffle into two specific shuffles: it may produce worse code. As such, + // we only merge two shuffles if the result is one of the two input shuffle + // masks. In this case, merging the shuffles just removes one instruction, + // which we know is safe. This is good for things like turning: + // (splat(splat)) -> splat. + if (ShuffleVectorInst *LHSSVI = dyn_cast<ShuffleVectorInst>(LHS)) { + if (isa<UndefValue>(RHS)) { + std::vector<unsigned> LHSMask = getShuffleMask(LHSSVI); + + std::vector<unsigned> NewMask; + for (unsigned i = 0, e = Mask.size(); i != e; ++i) + if (Mask[i] >= 2*e) + NewMask.push_back(2*e); + else + NewMask.push_back(LHSMask[Mask[i]]); + + // If the result mask is equal to the src shuffle or this shuffle mask, do + // the replacement. + if (NewMask == LHSMask || NewMask == Mask) { + std::vector<Constant*> Elts; + for (unsigned i = 0, e = NewMask.size(); i != e; ++i) { + if (NewMask[i] >= e*2) { + Elts.push_back(UndefValue::get(Type::UIntTy)); + } else { + Elts.push_back(ConstantUInt::get(Type::UIntTy, NewMask[i])); + } + } + return new ShuffleVectorInst(LHSSVI->getOperand(0), + LHSSVI->getOperand(1), + ConstantPacked::get(Elts)); + } + } + } + return MadeChange ? &SVI : 0; } _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits