[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
Wed Dec 3 08:46:50 PST 2025
================
@@ -2960,6 +2961,93 @@ 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;
+ }
+
+ Intrinsic::ID IID = II0->getIntrinsicID();
+ if (!isTriviallyVectorizable(IID))
+ return false;
+
+ // Cost analysis
+ InstructionCost OldCost =
+ TTI.getIntrinsicInstrCost(IntrinsicCostAttributes(IID, *II0), CostKind) +
+ TTI.getShuffleCost(TargetTransformInfo::SK_PermuteSingleSrc, ShuffleDstTy,
+ IntrinsicSrcTy, Mask, CostKind);
----------------
kuroyukiasuna wrote:
Thanks for capturing! Added in the new commit.
https://github.com/llvm/llvm-project/pull/170052
More information about the llvm-commits
mailing list