diff options
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a47a6669849..b6e310694ba 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -7010,7 +7010,7 @@ static bool getFauxShuffleMask(SDValue N, const APInt &DemandedElts, return false; } -/// Removes unused shuffle source inputs and adjusts the shuffle mask accordingly. +/// Removes unused/repeated shuffle source inputs and adjusts the shuffle mask. static void resolveTargetShuffleInputsAndMask(SmallVectorImpl<SDValue> &Inputs, SmallVectorImpl<int> &Mask) { int MaskWidth = Mask.size(); @@ -7026,13 +7026,28 @@ static void resolveTargetShuffleInputsAndMask(SmallVectorImpl<SDValue> &Inputs, M = SM_SentinelUndef; // Check for unused inputs. - if (any_of(Mask, [lo, hi](int i) { return (lo <= i) && (i < hi); })) { - UsedInputs.push_back(Inputs[i]); + if (none_of(Mask, [lo, hi](int i) { return (lo <= i) && (i < hi); })) { + for (int &M : Mask) + if (lo <= M) + M -= MaskWidth; continue; } - for (int &M : Mask) - if (lo <= M) - M -= MaskWidth; + + // Check for repeated inputs. + bool IsRepeat = false; + for (int j = 0, ue = UsedInputs.size(); j != ue; ++j) { + if (UsedInputs[j] != Inputs[i]) + continue; + for (int &M : Mask) + if (lo <= M) + M = (M < hi) ? ((M - lo) + (j * MaskWidth)) : (M - MaskWidth); + IsRepeat = true; + break; + } + if (IsRepeat) + continue; + + UsedInputs.push_back(Inputs[i]); } Inputs = UsedInputs; } @@ -32668,7 +32683,7 @@ static SDValue combineX86ShufflesRecursively( return getZeroVector(Root.getSimpleValueType(), Subtarget, DAG, SDLoc(Root)); - // Remove unused shuffle source ops. + // Remove unused/repeated shuffle source ops. resolveTargetShuffleInputsAndMask(Ops, Mask); assert(!Ops.empty() && "Shuffle with no inputs detected"); |

