diff options
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp | 20 | ||||
| -rw-r--r-- | llvm/test/CodeGen/Hexagon/autohvx/vmux-order.ll | 10 | 
2 files changed, 21 insertions, 9 deletions
| diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp index 4e5359582fc..537f97c9a98 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp @@ -884,8 +884,12 @@ static bool isUndef(ArrayRef<int> Mask) {  }  static bool isIdentity(ArrayRef<int> Mask) { -  unsigned Size = Mask.size(); -  return findStrip(Mask, 1, Size) == std::make_pair(0, Size); +  for (int I = 0, E = Mask.size(); I != E; ++I) { +    int M = Mask[I]; +    if (M >= 0 && M != I) +      return false; +  } +  return true;  }  static bool isPermutation(ArrayRef<int> Mask) { @@ -1181,6 +1185,9 @@ OpRef HvxSelector::shuffs1(ShuffleMask SM, OpRef Va, ResultStack &Results) {  OpRef HvxSelector::shuffs2(ShuffleMask SM, OpRef Va, OpRef Vb,                             ResultStack &Results) {    DEBUG_WITH_TYPE("isel", {dbgs() << __func__ << '\n';}); +  if (isUndef(SM.Mask)) +    return OpRef::undef(getSingleVT(MVT::i8)); +    OpRef C = contracting(SM, Va, Vb, Results);    if (C.isValid())      return C; @@ -1211,6 +1218,11 @@ OpRef HvxSelector::shuffp1(ShuffleMask SM, OpRef Va, ResultStack &Results) {    DEBUG_WITH_TYPE("isel", {dbgs() << __func__ << '\n';});    int VecLen = SM.Mask.size(); +  if (isIdentity(SM.Mask)) +    return Va; +  if (isUndef(SM.Mask)) +    return OpRef::undef(getPairVT(MVT::i8)); +    SmallVector<int,128> PackedMask(VecLen);    OpRef P = packs(SM, OpRef::lo(Va), OpRef::hi(Va), Results, PackedMask);    if (P.isValid()) { @@ -1241,8 +1253,10 @@ OpRef HvxSelector::shuffp1(ShuffleMask SM, OpRef Va, ResultStack &Results) {  OpRef HvxSelector::shuffp2(ShuffleMask SM, OpRef Va, OpRef Vb,                             ResultStack &Results) {    DEBUG_WITH_TYPE("isel", {dbgs() << __func__ << '\n';}); -  int VecLen = SM.Mask.size(); +  if (isUndef(SM.Mask)) +    return OpRef::undef(getPairVT(MVT::i8)); +  int VecLen = SM.Mask.size();    SmallVector<int,256> PackedMask(VecLen);    OpRef P = packp(SM, Va, Vb, Results, PackedMask);    if (P.isValid()) diff --git a/llvm/test/CodeGen/Hexagon/autohvx/vmux-order.ll b/llvm/test/CodeGen/Hexagon/autohvx/vmux-order.ll index f289f603ad8..b08542da0e3 100644 --- a/llvm/test/CodeGen/Hexagon/autohvx/vmux-order.ll +++ b/llvm/test/CodeGen/Hexagon/autohvx/vmux-order.ll @@ -1,12 +1,10 @@  ; RUN: llc -march=hexagon < %s | FileCheck %s -; The generated code isn't great, the vdeltas are no-ops (controls are all 0). -; Check for the correct order of vmux operands as is, when the code improves -; fix the checking as well. +; Check for the correct order of vmux operands: the vcmp.eq sets predicate +; bits for 0s in the mask. +;  +; CHECK: vmux(q{{[0-3]+}},v1,v0) -; CHECK-DAG: v[[V0:[0-9]+]] = vdelta(v0,v{{[0-9]+}}) -; CHECK-DAG: v[[V1:[0-9]+]] = vdelta(v1,v{{[0-9]+}}) -; CHECK: vmux(q{{[0-3]+}},v[[V1]],v[[V0]])  define <16 x i32> @fred(<16 x i32> %v0, <16 x i32> %v1) #0 {    %p = shufflevector <16 x i32> %v0, <16 x i32> %v1, <16 x i32> <i32 0,i32 17,i32 2,i32 19,i32 4,i32 21,i32 6,i32 23,i32 8,i32 25,i32 10,i32 27,i32 12,i32 29,i32 14,i32 31>    ret <16 x i32> %p | 

