[ARM] MVE i1 splat

We needn't BFI each lane individually into a predicate register when each lane
in the same. A simple sign extend and a vmsr will do.

Differential Revision: https://reviews.llvm.org/D67653

llvm-svn: 372313
This commit is contained in:
David Green 2019-09-19 12:17:41 +00:00
parent ec841cf36c
commit 0cfb78e52a
2 changed files with 16 additions and 35 deletions

View File

@ -6945,6 +6945,19 @@ static SDValue LowerBUILD_VECTOR_i1(SDValue Op, SelectionDAG &DAG,
} else
return SDValue();
// If this is a single value copied into all lanes (a splat), we can just sign
// extend that single value
SDValue FirstOp = Op.getOperand(0);
if (!isa<ConstantSDNode>(FirstOp) &&
std::all_of(std::next(Op->op_begin()), Op->op_end(),
[&FirstOp](SDUse &U) {
return U.get().isUndef() || U.get() == FirstOp;
})) {
SDValue Ext = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, MVT::i32, FirstOp,
DAG.getValueType(MVT::i1));
return DAG.getNode(ARMISD::PREDICATE_CAST, dl, Op.getValueType(), Ext);
}
// First create base with bits set where known
unsigned Bits32 = 0;
for (unsigned i = 0; i < NumElts; ++i) {
@ -6957,7 +6970,6 @@ static SDValue LowerBUILD_VECTOR_i1(SDValue Op, SelectionDAG &DAG,
}
// Add in unknown nodes
// FIXME: Handle splats of the same value better.
SDValue Base = DAG.getNode(ARMISD::PREDICATE_CAST, dl, VT,
DAG.getConstant(Bits32, dl, MVT::i32));
for (unsigned i = 0; i < NumElts; ++i) {

View File

@ -44,15 +44,10 @@ define arm_aapcs_vfpcc <4 x i32> @build_varN_v4i1(i32 %s, i32 %t, <4 x i32> %a,
; CHECK-LABEL: build_varN_v4i1:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: cmp r0, r1
; CHECK-NEXT: mov.w r1, #0
; CHECK-NEXT: cset r0, lo
; CHECK-NEXT: and r0, r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #0, #4
; CHECK-NEXT: bfi r1, r0, #4, #4
; CHECK-NEXT: bfi r1, r0, #8, #4
; CHECK-NEXT: bfi r1, r0, #12, #4
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmsr p0, r0
; CHECK-NEXT: vpsel q0, q0, q1
; CHECK-NEXT: bx lr
entry:
@ -106,19 +101,10 @@ define arm_aapcs_vfpcc <8 x i16> @build_varN_v8i1(i32 %s, i32 %t, <8 x i16> %a,
; CHECK-LABEL: build_varN_v8i1:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: cmp r0, r1
; CHECK-NEXT: mov.w r1, #0
; CHECK-NEXT: cset r0, lo
; CHECK-NEXT: and r0, r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #0, #2
; CHECK-NEXT: bfi r1, r0, #2, #2
; CHECK-NEXT: bfi r1, r0, #4, #2
; CHECK-NEXT: bfi r1, r0, #6, #2
; CHECK-NEXT: bfi r1, r0, #8, #2
; CHECK-NEXT: bfi r1, r0, #10, #2
; CHECK-NEXT: bfi r1, r0, #12, #2
; CHECK-NEXT: bfi r1, r0, #14, #2
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmsr p0, r0
; CHECK-NEXT: vpsel q0, q0, q1
; CHECK-NEXT: bx lr
entry:
@ -172,27 +158,10 @@ define arm_aapcs_vfpcc <16 x i8> @build_varN_v16i1(i32 %s, i32 %t, <16 x i8> %a,
; CHECK-LABEL: build_varN_v16i1:
; CHECK: @ %bb.0: @ %entry
; CHECK-NEXT: cmp r0, r1
; CHECK-NEXT: mov.w r1, #0
; CHECK-NEXT: cset r0, lo
; CHECK-NEXT: and r0, r0, #1
; CHECK-NEXT: rsbs r0, r0, #0
; CHECK-NEXT: bfi r1, r0, #0, #1
; CHECK-NEXT: bfi r1, r0, #1, #1
; CHECK-NEXT: bfi r1, r0, #2, #1
; CHECK-NEXT: bfi r1, r0, #3, #1
; CHECK-NEXT: bfi r1, r0, #4, #1
; CHECK-NEXT: bfi r1, r0, #5, #1
; CHECK-NEXT: bfi r1, r0, #6, #1
; CHECK-NEXT: bfi r1, r0, #7, #1
; CHECK-NEXT: bfi r1, r0, #8, #1
; CHECK-NEXT: bfi r1, r0, #9, #1
; CHECK-NEXT: bfi r1, r0, #10, #1
; CHECK-NEXT: bfi r1, r0, #11, #1
; CHECK-NEXT: bfi r1, r0, #12, #1
; CHECK-NEXT: bfi r1, r0, #13, #1
; CHECK-NEXT: bfi r1, r0, #14, #1
; CHECK-NEXT: bfi r1, r0, #15, #1
; CHECK-NEXT: vmsr p0, r1
; CHECK-NEXT: vmsr p0, r0
; CHECK-NEXT: vpsel q0, q0, q1
; CHECK-NEXT: bx lr
entry: