summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonISelDAGToDAGHVX.cpp17
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)});
OpenPOWER on IntegriCloud