diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp index 31515788d2b..8aef9b4560d 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp @@ -1054,7 +1054,7 @@ OpRef HvxSelector::packs(ShuffleMask SM, OpRef Va, OpRef Vb, int VecLen = SM.Mask.size(); MVT Ty = getSingleVT(MVT::i8); - auto IsSubvector = [] (ShuffleMask M) { + auto IsExtSubvector = [] (ShuffleMask M) { assert(M.MinSrc >= 0 && M.MaxSrc >= 0); for (int I = 0, E = M.Mask.size(); I != E; ++I) { if (M.Mask[I] >= 0 && M.Mask[I]-I != M.MinSrc) @@ -1064,11 +1064,11 @@ OpRef HvxSelector::packs(ShuffleMask SM, OpRef Va, OpRef Vb, }; if (SM.MaxSrc - SM.MinSrc < int(HwLen)) { - if (SM.MinSrc == 0 || SM.MinSrc == int(HwLen) || !IsSubvector(SM)) { + if (SM.MinSrc == 0 || SM.MinSrc == int(HwLen) || !IsExtSubvector(SM)) { // If the mask picks elements from only one of the operands, return // that operand, and update the mask to use index 0 to refer to the // first element of that operand. - // If the mask selects a subvector, it will be handled below, so + // If the mask extracts a subvector, it will be handled below, so // skip it here. if (SM.MaxSrc < int(HwLen)) { memcpy(NewMask.data(), SM.Mask.data(), sizeof(int)*VecLen); @@ -1092,10 +1092,15 @@ OpRef HvxSelector::packs(ShuffleMask SM, OpRef Va, OpRef Vb, MinSrc = SM.MinSrc - HwLen; } const SDLoc &dl(Results.InpNode); - SDValue S = DAG.getTargetConstant(MinSrc, dl, MVT::i32); - if (isUInt<3>(MinSrc)) { - Results.push(Hexagon::V6_valignbi, Ty, {Vb, Va, S}); + if (isUInt<3>(MinSrc) || isUInt<3>(HwLen-MinSrc)) { + bool IsRight = isUInt<3>(MinSrc); // Right align. + SDValue S = DAG.getTargetConstant(IsRight ? MinSrc : HwLen-MinSrc, + dl, MVT::i32); + unsigned Opc = IsRight ? Hexagon::V6_valignbi + : Hexagon::V6_vlalignbi; + Results.push(Opc, Ty, {Vb, Va, S}); } else { + SDValue S = DAG.getTargetConstant(MinSrc, dl, MVT::i32); Results.push(Hexagon::A2_tfrsi, MVT::i32, {S}); unsigned Top = Results.top(); Results.push(Hexagon::V6_valignb, Ty, {Vb, Va, OpRef::res(Top)}); |

