[llvm] [VectorCombine] Fold permute of intrinsics into intrinsic of permutes: shuffle(intrinsic, poison/undef) -> intrinsic(shuffle) (PR #170052)
Jerry Dang via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 4 09:49:09 PST 2025
================
@@ -2961,6 +2962,94 @@ bool VectorCombine::foldShuffleOfIntrinsics(Instruction &I) {
return true;
}
+/// Try to convert
+/// "shuffle (intrinsic), (poison/undef)" into "intrinsic (shuffle)".
+bool VectorCombine::foldPermuteOfIntrinsic(Instruction &I) {
+ Value *V0, *V1;
+ ArrayRef<int> Mask;
+ if (!match(&I, m_Shuffle(m_OneUse(m_Value(V0)), m_Value(V1), m_Mask(Mask))))
+ return false;
+
+ // Check for permute
+ if (!match(V1, m_Poison()) && !match(V1, m_Undef())) {
+ LLVM_DEBUG(dbgs() << "not a permute\n");
+ return false;
+ }
+
+ auto *II0 = dyn_cast<IntrinsicInst>(V0);
+ if (!II0)
+ return false;
+
+ auto *ShuffleDstTy = dyn_cast<FixedVectorType>(I.getType());
+ auto *IntrinsicSrcTy = dyn_cast<FixedVectorType>(II0->getType());
+ if (!ShuffleDstTy || !IntrinsicSrcTy)
+ return false;
+
+ // Validate it's a pure permute, mask should only reference the first vector
+ unsigned NumSrcElts = IntrinsicSrcTy->getNumElements();
+ for (int Idx : Mask) {
+ if (Idx > 0 && Idx >= (int)NumSrcElts)
+ return false;
+ }
----------------
kuroyukiasuna wrote:
The `M < 0` condition would cause the optimization failing to trigger because poison values in the mask produces -1.
E.g.:
```
%1 = shufflevector <2 x i16> %l266, <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
```
that is `<0, 1, -1, -1>`, and we want the optimization to run in this case.
I ended up using:
```
if (any_of(Mask, [NumSrcElts](int M){ return M >= (int)NumSrcElts; }))
return false;
```
Let me know if you have other suggestions. Thanks!
https://github.com/llvm/llvm-project/pull/170052
More information about the llvm-commits
mailing list