summaryrefslogtreecommitdiff
path: root/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2013-07-08 18:18:52 +0000
committerJim Grosbach <grosbach@apple.com>2013-07-08 18:18:52 +0000
commitdc2d418dd29ad9396aea06f2b72c9a7d29b30940 (patch)
treefee86f8ce5d436cac3a36e32d6fa71637efb781c /lib/Target/ARM/ARMISelLowering.cpp
parent66f464ee266b31bb02058c49a5abe3a6b77f080b (diff)
downloadllvm-dc2d418dd29ad9396aea06f2b72c9a7d29b30940.tar.gz
llvm-dc2d418dd29ad9396aea06f2b72c9a7d29b30940.tar.bz2
llvm-dc2d418dd29ad9396aea06f2b72c9a7d29b30940.tar.xz
ARM: Improve codegen for generic vselect.
Fall back to by-element insert rather than building it up on the stack. rdar://14351991 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@185846 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 991a703f81..8c4a3f13d1 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -4734,6 +4734,24 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
return DAG.getNode(ISD::BITCAST, dl, VT, Val);
}
+ // If all else fails, just use a sequence of INSERT_VECTOR_ELT when we
+ // know the default expansion would otherwise fall back on something even
+ // worse. For a vector with one or two non-undef values, that's
+ // scalar_to_vector for the elements followed by a shuffle (provided the
+ // shuffle is valid for the target) and materialization element by element
+ // on the stack followed by a load for everything else.
+ if (!isConstant && !usesOnlyOneValue) {
+ SDValue Vec = DAG.getUNDEF(VT);
+ for (unsigned i = 0 ; i < NumElts; ++i) {
+ SDValue V = Op.getOperand(i);
+ if (V.getOpcode() == ISD::UNDEF)
+ continue;
+ SDValue LaneIdx = DAG.getConstant(i, MVT::i32);
+ Vec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VT, Vec, V, LaneIdx);
+ }
+ return Vec;
+ }
+
return SDValue();
}