-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[VectorUtils] Add llvm::scaleShuffleMaskElts wrapper for narrowShuffleMaskElts/widenShuffleMaskElts #96646
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…eMaskElts/widenShuffleMaskElts Using the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly. Working on llvm#58895 I didn't want to create yet another case where we have to handle both re-scaling cases.
@llvm/pr-subscribers-llvm-analysis Author: Simon Pilgrim (RKSimon) ChangesUsing the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly. Working on #58895 I didn't want to create yet another case where we have to handle both re-scaling cases. Full diff: https://github.com/llvm/llvm-project/pull/96646.diff 3 Files Affected:
diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index 7a740d1206f7c..db3b62807cc67 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -224,6 +224,13 @@ void narrowShuffleMaskElts(int Scale, ArrayRef<int> Mask,
bool widenShuffleMaskElts(int Scale, ArrayRef<int> Mask,
SmallVectorImpl<int> &ScaledMask);
+/// Attempt to narrow/widen the \p Mask shuffle mask to the \p NumDstElts target
+/// width. Internally this will call narrowShuffleMaskElts/widenShuffleMaskElts.
+/// This will fail unless NumDstElts is a multiple of Mask.size (or vice-versa).
+/// Returns false on failure, and ScaledMask will be in an undefined state.
+bool scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef<int> Mask,
+ SmallVectorImpl<int> &ScaledMask);
+
/// Repetitively apply `widenShuffleMaskElts()` for as long as it succeeds,
/// to get the shuffle mask with widest possible elements.
void getShuffleMaskWithWidestElts(ArrayRef<int> Mask,
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index 6e183bbe5bff1..856f34ee1d5da 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -418,6 +418,31 @@ bool llvm::widenShuffleMaskElts(int Scale, ArrayRef<int> Mask,
return true;
}
+bool llvm::scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef<int> Mask,
+ SmallVectorImpl<int> &ScaledMask) {
+ unsigned NumSrcElts = Mask.size();
+ assert(NumSrcElts > 0 && NumDstElts > 0 && "Unexpected scaling factor");
+
+ // Fast-path: if no scaling, then it is just a copy.
+ if (NumSrcElts == NumDstElts) {
+ ScaledMask.assign(Mask.begin(), Mask.end());
+ return true;
+ }
+
+ // We can't find a whole scale factor - bail out.
+ if ((NumSrcElts % NumDstElts) != 0 && (NumDstElts % NumSrcElts) != 0)
+ return false;
+
+ if (NumSrcElts > NumDstElts) {
+ int Scale = NumSrcElts / NumDstElts;
+ return widenShuffleMaskElts(Scale, Mask, ScaledMask);
+ }
+
+ int Scale = NumDstElts / NumSrcElts;
+ narrowShuffleMaskElts(Scale, Mask, ScaledMask);
+ return true;
+}
+
void llvm::getShuffleMaskWithWidestElts(ArrayRef<int> Mask,
SmallVectorImpl<int> &ScaledMask) {
std::array<SmallVector<int, 16>, 2> TmpMasks;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index ebc2930d33d26..3de56a4038039 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -2837,15 +2837,7 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
auto *XType = cast<FixedVectorType>(X->getType());
unsigned XNumElts = XType->getNumElements();
SmallVector<int, 16> ScaledMask;
- if (XNumElts >= VWidth) {
- assert(XNumElts % VWidth == 0 && "Unexpected vector bitcast");
- narrowShuffleMaskElts(XNumElts / VWidth, Mask, ScaledMask);
- } else {
- assert(VWidth % XNumElts == 0 && "Unexpected vector bitcast");
- if (!widenShuffleMaskElts(VWidth / XNumElts, Mask, ScaledMask))
- ScaledMask.clear();
- }
- if (!ScaledMask.empty()) {
+ if (scaleShuffleMaskElts(XNumElts, Mask, ScaledMask)) {
// If the shuffled source vector simplifies, cast that value to this
// shuffle's type.
if (auto *V = simplifyShuffleVectorInst(X, UndefValue::get(XType),
|
@llvm/pr-subscribers-llvm-transforms Author: Simon Pilgrim (RKSimon) ChangesUsing the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly. Working on #58895 I didn't want to create yet another case where we have to handle both re-scaling cases. Full diff: https://github.com/llvm/llvm-project/pull/96646.diff 3 Files Affected:
diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index 7a740d1206f7c..db3b62807cc67 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -224,6 +224,13 @@ void narrowShuffleMaskElts(int Scale, ArrayRef<int> Mask,
bool widenShuffleMaskElts(int Scale, ArrayRef<int> Mask,
SmallVectorImpl<int> &ScaledMask);
+/// Attempt to narrow/widen the \p Mask shuffle mask to the \p NumDstElts target
+/// width. Internally this will call narrowShuffleMaskElts/widenShuffleMaskElts.
+/// This will fail unless NumDstElts is a multiple of Mask.size (or vice-versa).
+/// Returns false on failure, and ScaledMask will be in an undefined state.
+bool scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef<int> Mask,
+ SmallVectorImpl<int> &ScaledMask);
+
/// Repetitively apply `widenShuffleMaskElts()` for as long as it succeeds,
/// to get the shuffle mask with widest possible elements.
void getShuffleMaskWithWidestElts(ArrayRef<int> Mask,
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index 6e183bbe5bff1..856f34ee1d5da 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -418,6 +418,31 @@ bool llvm::widenShuffleMaskElts(int Scale, ArrayRef<int> Mask,
return true;
}
+bool llvm::scaleShuffleMaskElts(unsigned NumDstElts, ArrayRef<int> Mask,
+ SmallVectorImpl<int> &ScaledMask) {
+ unsigned NumSrcElts = Mask.size();
+ assert(NumSrcElts > 0 && NumDstElts > 0 && "Unexpected scaling factor");
+
+ // Fast-path: if no scaling, then it is just a copy.
+ if (NumSrcElts == NumDstElts) {
+ ScaledMask.assign(Mask.begin(), Mask.end());
+ return true;
+ }
+
+ // We can't find a whole scale factor - bail out.
+ if ((NumSrcElts % NumDstElts) != 0 && (NumDstElts % NumSrcElts) != 0)
+ return false;
+
+ if (NumSrcElts > NumDstElts) {
+ int Scale = NumSrcElts / NumDstElts;
+ return widenShuffleMaskElts(Scale, Mask, ScaledMask);
+ }
+
+ int Scale = NumDstElts / NumSrcElts;
+ narrowShuffleMaskElts(Scale, Mask, ScaledMask);
+ return true;
+}
+
void llvm::getShuffleMaskWithWidestElts(ArrayRef<int> Mask,
SmallVectorImpl<int> &ScaledMask) {
std::array<SmallVector<int, 16>, 2> TmpMasks;
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
index ebc2930d33d26..3de56a4038039 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineVectorOps.cpp
@@ -2837,15 +2837,7 @@ Instruction *InstCombinerImpl::visitShuffleVectorInst(ShuffleVectorInst &SVI) {
auto *XType = cast<FixedVectorType>(X->getType());
unsigned XNumElts = XType->getNumElements();
SmallVector<int, 16> ScaledMask;
- if (XNumElts >= VWidth) {
- assert(XNumElts % VWidth == 0 && "Unexpected vector bitcast");
- narrowShuffleMaskElts(XNumElts / VWidth, Mask, ScaledMask);
- } else {
- assert(VWidth % XNumElts == 0 && "Unexpected vector bitcast");
- if (!widenShuffleMaskElts(VWidth / XNumElts, Mask, ScaledMask))
- ScaledMask.clear();
- }
- if (!ScaledMask.empty()) {
+ if (scaleShuffleMaskElts(XNumElts, Mask, ScaledMask)) {
// If the shuffled source vector simplifies, cast that value to this
// shuffle's type.
if (auto *V = simplifyShuffleVectorInst(X, UndefValue::get(XType),
|
llvm/lib/Analysis/VectorUtils.cpp
Outdated
} | ||
|
||
// We can't find a whole scale factor - bail out. | ||
if ((NumSrcElts % NumDstElts) != 0 && (NumDstElts % NumSrcElts) != 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be an assertion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd left this as a bail out in case future uses won't guarantee this, but I've updated it to an assertion for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. This patch should be marked as an NFC.
…eMaskElts/widenShuffleMaskElts, NFC. (llvm#96646) Using the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly. Working on llvm#58895 I didn't want to create yet another case where we have to handle both re-scaling cases.
…eMaskElts/widenShuffleMaskElts, NFC. (llvm#96646) Using the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly. Working on llvm#58895 I didn't want to create yet another case where we have to handle both re-scaling cases.
Using the target number of vector elements, scaleShuffleMaskElts will try to use narrowShuffleMaskElts/widenShuffleMaskElts to scale the shuffle mask accordingly.
Working on #58895 I didn't want to create yet another case where we have to handle both re-scaling cases.