aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-02-27 13:34:40 +0000
committerDuncan Sands <baldrick@free.fr>2008-02-27 13:34:40 +0000
commit077f9b20d0e8659d00a09046a63e28edf0665ffe (patch)
tree19536af56a9bc4a2f026f4b006c016d51fbff242 /lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
parent0a4c3782c8d558a9859a90ae8e2d5d0efa057e41 (diff)
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
Diffstat (limited to 'lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
index 72c1f484db..6610693dd7 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
@@ -176,6 +176,9 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
assert(0 && "Do not know how to scalarize this operator's operand!");
abort();
+ case ISD::BIT_CONVERT:
+ Res = ScalarizeOp_BIT_CONVERT(N); break;
+
case ISD::EXTRACT_VECTOR_ELT:
Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
@@ -204,6 +207,13 @@ bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
return false;
}
+/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs
+/// to be scalarized, it must be <1 x ty>. Convert the element instead.
+SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
+ SDOperand Elt = GetScalarizedOp(N->getOperand(0));
+ return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
+}
+
/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
/// index.