@@ -5168,26 +5168,41 @@ bool AArch64TTIImpl::isProfitableToSinkOperands(
51685168 return false ;
51695169 }
51705170 case Instruction::Mul: {
5171+ auto ShouldSinkSplatForIndexedVariant = [](Value *V) {
5172+ auto VT = MVT::getVT (V->getType (), /* HandleUnknown=*/ true );
5173+ return (VT == MVT::v4i16 || VT == MVT::v8i16 || VT == MVT::v2i32 ||
5174+ VT == MVT::v4i32);
5175+ };
5176+
51715177 int NumZExts = 0 , NumSExts = 0 ;
51725178 for (auto &Op : I->operands ()) {
51735179 // Make sure we are not already sinking this operand
51745180 if (any_of (Ops, [&](Use *U) { return U->get () == Op; }))
51755181 continue ;
51765182
5177- if (match (&Op, m_SExt (m_Value ()))) {
5178- NumSExts++;
5179- continue ;
5180- } else if (match (&Op, m_ZExt (m_Value ()))) {
5181- NumZExts++;
5183+ if (match (&Op, m_ZExtOrSExt (m_Value ()))) {
5184+ auto *Ext = cast<Instruction>(Op);
5185+ auto *ExtOp = Ext->getOperand (0 );
5186+ if (isSplatShuffle (ExtOp) && ShouldSinkSplatForIndexedVariant (ExtOp))
5187+ Ops.push_back (&Ext->getOperandUse (0 ));
5188+ Ops.push_back (&Op);
5189+
5190+ if (isa<SExtInst>(Ext))
5191+ NumSExts++;
5192+ else
5193+ NumZExts++;
5194+
51825195 continue ;
51835196 }
51845197
51855198 ShuffleVectorInst *Shuffle = dyn_cast<ShuffleVectorInst>(Op);
5199+ if (!Shuffle)
5200+ continue ;
51865201
51875202 // If the Shuffle is a splat and the operand is a zext/sext, sinking the
51885203 // operand and the s/zext can help create indexed s/umull. This is
51895204 // especially useful to prevent i64 mul being scalarized.
5190- if (Shuffle && isSplatShuffle (Shuffle) &&
5205+ if (isSplatShuffle (Shuffle) &&
51915206 match (Shuffle->getOperand (0 ), m_ZExtOrSExt (m_Value ()))) {
51925207 Ops.push_back (&Shuffle->getOperandUse (0 ));
51935208 Ops.push_back (&Op);
@@ -5198,9 +5213,6 @@ bool AArch64TTIImpl::isProfitableToSinkOperands(
51985213 continue ;
51995214 }
52005215
5201- if (!Shuffle)
5202- continue ;
5203-
52045216 Value *ShuffleOperand = Shuffle->getOperand (0 );
52055217 InsertElementInst *Insert = dyn_cast<InsertElementInst>(ShuffleOperand);
52065218 if (!Insert)
@@ -5232,12 +5244,26 @@ bool AArch64TTIImpl::isProfitableToSinkOperands(
52325244 NumZExts++;
52335245 }
52345246
5247+ Ops.push_back (&Insert->getOperandUse (1 ));
52355248 Ops.push_back (&Shuffle->getOperandUse (0 ));
52365249 Ops.push_back (&Op);
52375250 }
52385251
5239- // Is it profitable to sink if we found two of the same type of extends.
5240- return !Ops.empty () && (NumSExts == 2 || NumZExts == 2 );
5252+ // It is profitable to sink if we found two of the same type of extends.
5253+ if (!Ops.empty () && (NumSExts == 2 || NumZExts == 2 ))
5254+ return true ;
5255+
5256+ // Otherwise, see if we should sink splats for indexed variants.
5257+ if (!ShouldSinkSplatForIndexedVariant (I))
5258+ return false ;
5259+
5260+ Ops.clear ();
5261+ if (isSplatShuffle (I->getOperand (0 )))
5262+ Ops.push_back (&I->getOperandUse (0 ));
5263+ if (isSplatShuffle (I->getOperand (1 )))
5264+ Ops.push_back (&I->getOperandUse (1 ));
5265+
5266+ return !Ops.empty ();
52415267 }
52425268 default :
52435269 return false ;
0 commit comments