LegalizeTypes support for EXTRACT_VECTOR_ELT. The

approach taken is different to that in LegalizeDAG
when it is a question of expanding or promoting the
result type: for example, if extracting an i64 from
a <2 x i64>, when i64 needs expanding, it bitcasts
the vector to <4 x i32>, extracts the appropriate
two i32's, and uses those for the Lo and Hi parts.
Likewise, when extracting an i16 from a <4 x i16>,
and i16 needs promoting, it bitcasts the vector to
<2 x i32>, extracts the appropriate i32, twiddles
the bits if necessary, and uses that as the promoted
value.  This puts more pressure on bitcast legalization,
and I've added the appropriate cases.  They needed to
be added anyway since users can generate such bitcasts
too if they want to.  Also, when considering various
cases (Legal, Promote, Expand, Scalarize, Split) it is
a pain that expand can correspond to Expand, Scalarize
or Split, so I've changed the LegalizeTypes enum so it
lists those different cases - now Expand only means
splitting a scalar in two.
The code produced is the same as by LegalizeDAG for
all relevant testcases, except for
2007-10-31-extractelement-i64.ll, where the code seems
to have improved (see below; can an expert please tell
me if it is better or not).
Before < vs after >.

<       subl    $92, %esp
<       movaps  %xmm0, 64(%esp)
<       movaps  %xmm0, (%esp)
<       movl    4(%esp), %eax
<       movl    %eax, 28(%esp)
<       movl    (%esp), %eax
<       movl    %eax, 24(%esp)
<       movq    24(%esp), %mm0
<       movq    %mm0, 56(%esp)
---
>       subl    $44, %esp
>       movaps  %xmm0, 16(%esp)
>       pshufd  $1, %xmm0, %xmm1
>       movd    %xmm1, 4(%esp)
>       movd    %xmm0, (%esp)
>       movq    (%esp), %mm0
>       movq    %mm0, 8(%esp)

<       subl    $92, %esp
<       movaps  %xmm0, 64(%esp)
<       movaps  %xmm0, (%esp)
<       movl    12(%esp), %eax
<       movl    %eax, 28(%esp)
<       movl    8(%esp), %eax
<       movl    %eax, 24(%esp)
<       movq    24(%esp), %mm0
<       movq    %mm0, 56(%esp)
---
>       subl    $44, %esp
>       movaps  %xmm0, 16(%esp)
>       pshufd  $3, %xmm0, %xmm1
>       movd    %xmm1, 4(%esp)
>       movhlps %xmm0, %xmm0
>       movd    %xmm0, (%esp)
>       movq    (%esp), %mm0
>       movq    %mm0, 8(%esp)

<       subl    $92, %esp
<       movaps  %xmm0, 64(%esp)
---
>       subl    $44, %esp

<       movl    16(%esp), %eax
<       movl    %eax, 48(%esp)
<       movl    20(%esp), %eax
<       movl    %eax, 52(%esp)
<       movaps  %xmm0, (%esp)
<       movl    4(%esp), %eax
<       movl    %eax, 60(%esp)
<       movl    (%esp), %eax
<       movl    %eax, 56(%esp)
---
>       pshufd  $1, %xmm0, %xmm1
>       movd    %xmm1, 4(%esp)
>       movd    %xmm0, (%esp)
>       movd    %xmm1, 12(%esp)
>       movd    %xmm0, 8(%esp)

<       subl    $92, %esp
<       movaps  %xmm0, 64(%esp)
---
>       subl    $44, %esp

<       movl    24(%esp), %eax
<       movl    %eax, 48(%esp)
<       movl    28(%esp), %eax
<       movl    %eax, 52(%esp)
<       movaps  %xmm0, (%esp)
<       movl    12(%esp), %eax
<       movl    %eax, 60(%esp)
<       movl    8(%esp), %eax
<       movl    %eax, 56(%esp)
---
>       pshufd  $3, %xmm0, %xmm1
>       movd    %xmm1, 4(%esp)
>       movhlps %xmm0, %xmm0
>       movd    %xmm0, (%esp)
>       movd    %xmm1, 12(%esp)
>       movd    %xmm0, 8(%esp)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47672 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Duncan Sands
2008-02-27 13:34:40 +00:00
parent 0a4c3782c8
commit 077f9b20d0
6 changed files with 364 additions and 60 deletions

View File

@@ -68,25 +68,26 @@ void DAGTypeLegalizer::run() {
unsigned NumResults = N->getNumValues();
do {
MVT::ValueType ResultVT = N->getValueType(i);
LegalizeAction Action = getTypeAction(ResultVT);
if (Action == Promote) {
switch (getTypeAction(ResultVT)) {
default:
assert(false && "Unknown action!");
case Legal:
break;
case Promote:
PromoteResult(N, i);
goto NodeDone;
} else if (Action == Expand) {
// Expand can mean 1) split integer in half 2) scalarize single-element
// vector 3) split vector in half.
if (!MVT::isVector(ResultVT))
ExpandResult(N, i);
else if (MVT::getVectorNumElements(ResultVT) == 1)
ScalarizeResult(N, i); // Scalarize the single-element vector.
else
SplitResult(N, i); // Split the vector in half.
case Expand:
ExpandResult(N, i);
goto NodeDone;
case Scalarize:
ScalarizeResult(N, i);
goto NodeDone;
case Split:
SplitResult(N, i);
goto NodeDone;
} else {
assert(Action == Legal && "Unknown action!");
}
} while (++i < NumResults);
// Scan the operand list for the node, handling any nodes with operands that
// are illegal.
{
@@ -94,25 +95,25 @@ void DAGTypeLegalizer::run() {
bool NeedsRevisit = false;
for (i = 0; i != NumOperands; ++i) {
MVT::ValueType OpVT = N->getOperand(i).getValueType();
LegalizeAction Action = getTypeAction(OpVT);
if (Action == Promote) {
switch (getTypeAction(OpVT)) {
default:
assert(false && "Unknown action!");
case Legal:
continue;
case Promote:
NeedsRevisit = PromoteOperand(N, i);
break;
} else if (Action == Expand) {
// Expand can mean 1) split integer in half 2) scalarize single-element
// vector 3) split vector in half.
if (!MVT::isVector(OpVT)) {
NeedsRevisit = ExpandOperand(N, i);
} else if (MVT::getVectorNumElements(OpVT) == 1) {
// Scalarize the single-element vector.
NeedsRevisit = ScalarizeOperand(N, i);
} else {
NeedsRevisit = SplitOperand(N, i); // Split the vector in half.
}
case Expand:
NeedsRevisit = ExpandOperand(N, i);
break;
case Scalarize:
NeedsRevisit = ScalarizeOperand(N, i);
break;
case Split:
NeedsRevisit = SplitOperand(N, i);
break;
} else {
assert(Action == Legal && "Unknown action!");
}
break;
}
// If the node needs revisiting, don't add all users to the worklist etc.
@@ -432,7 +433,7 @@ SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) {
case Legal: break;
case Promote: Op2 = GetPromotedOp(Op2); break;
}
// The length could have any action required.
SDOperand Length = N->getOperand(3);
switch (getTypeAction(Length.getValueType())) {
@@ -444,21 +445,21 @@ SDOperand DAGTypeLegalizer::HandleMemIntrinsic(SDNode *N) {
GetExpandedOp(Length, Length, Dummy);
break;
}
SDOperand Align = N->getOperand(4);
switch (getTypeAction(Align.getValueType())) {
default: assert(0 && "Unknown action for memop operand");
case Legal: break;
case Promote: Align = GetPromotedZExtOp(Align); break;
}
SDOperand AlwaysInline = N->getOperand(5);
switch (getTypeAction(AlwaysInline.getValueType())) {
default: assert(0 && "Unknown action for memop operand");
case Legal: break;
case Promote: AlwaysInline = GetPromotedZExtOp(AlwaysInline); break;
}
SDOperand Ops[] = { Chain, Ptr, Op2, Length, Align, AlwaysInline };
return DAG.UpdateNodeOperands(SDOperand(N, 0), Ops, 6);
}