Cleanup. Document. Make sure that this build_vector optimization only runs before the op legalizer and that the used type is legal.

llvm-svn: 143358
This commit is contained in:
Nadav Rotem 2011-10-31 20:08:25 +00:00
parent e4c8e692f2
commit f310361a7d
1 changed files with 29 additions and 16 deletions

View File

@ -6941,9 +6941,9 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
// Check to see if this is a BUILD_VECTOR of a bunch of values // Check to see if this is a BUILD_VECTOR of a bunch of values
// which come from any_extend or zero_extend nodes. If so, we can create // which come from any_extend or zero_extend nodes. If so, we can create
// a new BUILD_VECTOR using bit-casts which may enable other BUILD_VECTOR // a new BUILD_VECTOR using bit-casts which may enable other BUILD_VECTOR
// optimizations. // optimizations. We do not handle sign-extend because we can't fill the sign
// using shuffles.
EVT SourceType = MVT::Other; EVT SourceType = MVT::Other;
bool allExtend = true;
bool allAnyExt = true; bool allAnyExt = true;
for (unsigned i = 0; i < NumInScalars; ++i) { for (unsigned i = 0; i < NumInScalars; ++i) {
SDValue In = N->getOperand(i); SDValue In = N->getOperand(i);
@ -6953,9 +6953,9 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
bool AnyExt = In.getOpcode() == ISD::ANY_EXTEND; bool AnyExt = In.getOpcode() == ISD::ANY_EXTEND;
bool ZeroExt = In.getOpcode() == ISD::ZERO_EXTEND; bool ZeroExt = In.getOpcode() == ISD::ZERO_EXTEND;
// Abort non-extend incoming values. // Abort if the element is not an extension.
if (!ZeroExt && !AnyExt) { if (!ZeroExt && !AnyExt) {
allExtend = false; SourceType = MVT::Other;
break; break;
} }
@ -6964,10 +6964,11 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
// Check that all of the widened source types are the same. // Check that all of the widened source types are the same.
if (SourceType == MVT::Other) if (SourceType == MVT::Other)
// First time.
SourceType = InTy; SourceType = InTy;
else if (InTy != SourceType) { else if (InTy != SourceType) {
// Multiple income types. Abort. // Multiple income types. Abort.
allExtend = false; SourceType = MVT::Other;
break; break;
} }
@ -6975,17 +6976,27 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
allAnyExt &= AnyExt; allAnyExt &= AnyExt;
} }
// And we are post type-legalization,
// If all of the values are Ext or undef, // In order to have valid types, all of the inputs must be extended from the
// We have a non undef entry. // same source type and all of the inputs must be any or zero extend.
if (LegalTypes && allExtend && SourceType != MVT::Other) { // Scalar sizes must be a power of two.
EVT OutScalarTy = N->getValueType(0).getScalarType();
bool validTypes = SourceType != MVT::Other &&
isPowerOf2_32(OutScalarTy.getSizeInBits()) &&
isPowerOf2_32(SourceType.getSizeInBits());
// We perform this optimization post type-legalization because
// the type-legalizer often scalarizes integer-promoted vectors.
// Performing this optimization before may create bit-casts which
// will be type-legalized to complex code sequences.
// We perform this optimization only before the operation legalizer because we
// may introduce illegal operations.
if (LegalTypes && !LegalOperations && validTypes) {
bool isLE = TLI.isLittleEndian(); bool isLE = TLI.isLittleEndian();
EVT InScalarTy = SourceType.getScalarType(); unsigned ElemRatio = OutScalarTy.getSizeInBits()/SourceType.getSizeInBits();
EVT OutScalarTy = N->getValueType(0).getScalarType();
unsigned ElemRatio = OutScalarTy.getSizeInBits()/InScalarTy.getSizeInBits();
assert(ElemRatio > 1 && "Invalid element size ratio"); assert(ElemRatio > 1 && "Invalid element size ratio");
SDValue Filler = allAnyExt ? DAG.getUNDEF(InScalarTy): SDValue Filler = allAnyExt ? DAG.getUNDEF(SourceType):
DAG.getConstant(0, InScalarTy); DAG.getConstant(0, SourceType);
unsigned NewBVElems = ElemRatio * N->getValueType(0).getVectorNumElements(); unsigned NewBVElems = ElemRatio * N->getValueType(0).getVectorNumElements();
SmallVector<SDValue, 8> Ops(NewBVElems, Filler); SmallVector<SDValue, 8> Ops(NewBVElems, Filler);
@ -6998,7 +7009,7 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
Cast.getOpcode() == ISD::UNDEF) && "Invalid cast opcode"); Cast.getOpcode() == ISD::UNDEF) && "Invalid cast opcode");
SDValue In; SDValue In;
if (Cast.getOpcode() == ISD::UNDEF) if (Cast.getOpcode() == ISD::UNDEF)
In = DAG.getUNDEF(InScalarTy); In = DAG.getUNDEF(SourceType);
else else
In = Cast->getOperand(0); In = Cast->getOperand(0);
unsigned Index = isLE ? (i * ElemRatio) : unsigned Index = isLE ? (i * ElemRatio) :
@ -7009,9 +7020,11 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) {
} }
// The type of the new BUILD_VECTOR node. // The type of the new BUILD_VECTOR node.
EVT VecVT = EVT::getVectorVT(*DAG.getContext(), InScalarTy, NewBVElems); EVT VecVT = EVT::getVectorVT(*DAG.getContext(), SourceType, NewBVElems);
assert(VecVT.getSizeInBits() == N->getValueType(0).getSizeInBits() && assert(VecVT.getSizeInBits() == N->getValueType(0).getSizeInBits() &&
"Invalid vector size"); "Invalid vector size");
// Check if the new vector type is legal.
if (!isTypeLegal(VecVT)) return SDValue();
// Make the new BUILD_VECTOR. // Make the new BUILD_VECTOR.
SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), SDValue BV = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(),