diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-03-02 22:22:19 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-03-02 22:22:19 +0000 |
commit | e3e963236a3461c977f3968326aff1ee6bb36287 (patch) | |
tree | a2bb1999da25b6069b582d3754bfc08187e2c83e /llvm/lib/Target | |
parent | 2646a41e54ba858fdcb0d52fb7286af5ecbc0d38 (diff) | |
download | bcm5719-llvm-e3e963236a3461c977f3968326aff1ee6bb36287.tar.gz bcm5719-llvm-e3e963236a3461c977f3968326aff1ee6bb36287.zip |
[Hexagon] Generate valignb for shifting shuffles (instead of vdelta)
llvm-svn: 326627
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp index 553263ee516..9b58e00cbe0 100644 --- a/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp +++ b/llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp @@ -776,6 +776,13 @@ struct ShuffleMask { size_t H = Mask.size()/2; return ShuffleMask(Mask.take_back(H)); } + + void print(raw_ostream &OS) const { + OS << "MinSrc:" << MinSrc << ", MaxSrc:" << MaxSrc << " {"; + for (int M : Mask) + OS << ' ' << M; + OS << " }"; + } }; } // namespace @@ -1042,19 +1049,36 @@ OpRef HvxSelector::packs(ShuffleMask SM, OpRef Va, OpRef Vb, int VecLen = SM.Mask.size(); MVT Ty = getSingleVT(MVT::i8); - if (SM.MaxSrc - SM.MinSrc < int(HwLen)) { - if (SM.MaxSrc < int(HwLen)) { - memcpy(NewMask.data(), SM.Mask.data(), sizeof(int)*VecLen); - return Va; + auto IsSubvector = [] (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) + return false; } - if (SM.MinSrc >= int(HwLen)) { - for (int I = 0; I != VecLen; ++I) { - int M = SM.Mask[I]; - if (M != -1) - M -= HwLen; - NewMask[I] = M; + return true; + }; + + if (SM.MaxSrc - SM.MinSrc < int(HwLen)) { + if (SM.MinSrc == 0 || SM.MinSrc == int(HwLen) || !IsSubvector(SM)) { + if (SM.MaxSrc < int(HwLen)) { + memcpy(NewMask.data(), SM.Mask.data(), sizeof(int)*VecLen); + return Va; + } + if (SM.MinSrc >= int(HwLen)) { + for (int I = 0; I != VecLen; ++I) { + int M = SM.Mask[I]; + if (M != -1) + M -= HwLen; + NewMask[I] = M; + } + return Vb; } - return Vb; + } + if (SM.MaxSrc < int(HwLen)) { + Vb = Va; + } else if (SM.MinSrc > int(HwLen)) { + Va = Vb; + SM.MinSrc -= HwLen; } const SDLoc &dl(Results.InpNode); SDValue S = DAG.getTargetConstant(SM.MinSrc, dl, MVT::i32); |