Change handling of illegal vector types to widen when possible instead of

expanding: e.g. <2 x float> -> <4 x float> instead of -> 2 floats.  This
affects two places in the code: handling cross block values and handling
function return and arguments.  Since vectors are already widened by 
legalizetypes, this gives us much better code and unblocks x86-64 abi
and SPU abi work.

For example, this (which is a silly example of a cross-block value):
define <4 x float> @test2(<4 x float> %A) nounwind {
 %B = shufflevector <4 x float> %A, <4 x float> undef, <2 x i32> <i32 0, i32 1>
 %C = fadd <2 x float> %B, %B
  br label %BB
BB:
 %D = fadd <2 x float> %C, %C
 %E = shufflevector <2 x float> %D, <2 x float> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
 ret <4 x float> %E
}

Now compiles into:

_test2:                                 ## @test2
## BB#0:
 addps %xmm0, %xmm0
 addps %xmm0, %xmm0
 ret

previously it compiled into:

_test2:                                 ## @test2
## BB#0:
 addps %xmm0, %xmm0
 pshufd $1, %xmm0, %xmm1
                                        ## kill: XMM0<def> XMM0<kill> XMM0<def>
 insertps $0, %xmm0, %xmm0
 insertps $16, %xmm1, %xmm0
 addps %xmm0, %xmm0
 ret

This implements rdar://8230384



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112101 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2010-08-25 22:49:25 +00:00
parent e6e0018d3e
commit e6f7c267df
5 changed files with 193 additions and 74 deletions

View File

@@ -214,24 +214,59 @@ public:
/// ValueTypeActions - For each value type, keep a LegalizeAction enum
/// that indicates how instruction selection should deal with the type.
uint8_t ValueTypeActions[MVT::LAST_VALUETYPE];
LegalizeAction getExtendedTypeAction(EVT VT) const {
// Handle non-vector integers.
if (!VT.isVector()) {
assert(VT.isInteger() && "Unsupported extended type!");
unsigned BitSize = VT.getSizeInBits();
// First promote to a power-of-two size, then expand if necessary.
if (BitSize < 8 || !isPowerOf2_32(BitSize))
return Promote;
return Expand;
}
// If this is a type smaller than a legal vector type, promote to that
// type, e.g. <2 x float> -> <4 x float>.
if (VT.getVectorElementType().isSimple() &&
VT.getVectorNumElements() != 1) {
MVT EltType = VT.getVectorElementType().getSimpleVT();
unsigned NumElts = VT.getVectorNumElements();
while (1) {
// Round up to the nearest power of 2.
NumElts = (unsigned)NextPowerOf2(NumElts);
MVT LargerVector = MVT::getVectorVT(EltType, NumElts);
if (LargerVector == MVT()) break;
// If this the larger type is legal, promote to it.
if (getTypeAction(LargerVector) == Legal) return Promote;
}
}
return VT.isPow2VectorType() ? Expand : Promote;
}
public:
ValueTypeActionImpl() {
std::fill(ValueTypeActions, array_endof(ValueTypeActions), 0);
}
/// FIXME: This Context argument is now dead, zap it.
LegalizeAction getTypeAction(LLVMContext &Context, EVT VT) const {
if (VT.isExtended()) {
if (VT.isVector()) {
return VT.isPow2VectorType() ? Expand : Promote;
}
if (VT.isInteger())
// First promote to a power-of-two size, then expand if necessary.
return VT == VT.getRoundIntegerType(Context) ? Expand : Promote;
assert(0 && "Unsupported extended type!");
return Legal;
}
unsigned I = VT.getSimpleVT().SimpleTy;
return (LegalizeAction)ValueTypeActions[I];
return getTypeAction(VT);
}
LegalizeAction getTypeAction(EVT VT) const {
if (!VT.isExtended())
return getTypeAction(VT.getSimpleVT());
return getExtendedTypeAction(VT);
}
LegalizeAction getTypeAction(MVT VT) const {
return (LegalizeAction)ValueTypeActions[VT.SimpleTy];
}
void setTypeAction(EVT VT, LegalizeAction Action) {
unsigned I = VT.getSimpleVT().SimpleTy;
ValueTypeActions[I] = Action;