[ARM][ISel] Improve the lowering of vector loads.

When vectors are built from a single value, the ARM lowering issues a
scalar_to_vector node.
This node is then always morphed into a move from the general purpose unit to
the vector unit.
When the value comes from a load, this can be simplified into a vector load to
the right lane.

This patch changes the lowering of insert_vector_elt to expose a vector
friendly pattern in this situation.

This is a step toward fixing <rdar://problem/14170854>.

llvm-svn: 186999
This commit is contained in:
Quentin Colombet 2013-07-23 22:34:47 +00:00
parent 402ccb5d66
commit 0f2fe74aaf
2 changed files with 17 additions and 1 deletions

View File

@ -4674,7 +4674,9 @@ SDValue ARMTargetLowering::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
if (ValueCounts.size() == 0) if (ValueCounts.size() == 0)
return DAG.getUNDEF(VT); return DAG.getUNDEF(VT);
if (isOnlyLowElement) // Loads are better lowered with insert_vector_elt/ARMISD::BUILD_VECTOR.
// Keep going if we are hitting this case.
if (isOnlyLowElement && !ISD::isNormalLoad(Value.getNode()))
return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value); return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value);
unsigned EltSize = VT.getVectorElementType().getSizeInBits(); unsigned EltSize = VT.getVectorElementType().getSizeInBits();

View File

@ -184,3 +184,17 @@ entry:
; Function Attrs: nounwind readnone ; Function Attrs: nounwind readnone
declare <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8>, <8 x i8>) declare <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8>, <8 x i8>)
; Check that (insert_vector_elt (load)) => (vector_load).
; Thus, check that scalar_to_vector do not interfer with that.
define <8 x i16> @t4(i8* nocapture %sp0) {
; CHECK: t4
; CHECK: vld1.32 {{{d[0-9]+}}[0]}, [r0]
entry:
%pix_sp0.0.cast = bitcast i8* %sp0 to i32*
%pix_sp0.0.copyload = load i32* %pix_sp0.0.cast, align 1
%vec = insertelement <2 x i32> undef, i32 %pix_sp0.0.copyload, i32 0
%0 = bitcast <2 x i32> %vec to <8 x i8>
%vmull.i = tail call <8 x i16> @llvm.arm.neon.vmullu.v8i16(<8 x i8> %0, <8 x i8> %0)
ret <8 x i16> %vmull.i
}