@@ -511,15 +511,25 @@ static bool isSplat(ArrayRef<Value *> VL) {
511511}
512512
513513/// \returns True if \p I is commutative, handles CmpInst and BinaryOperator.
514- static bool isCommutative(Instruction *I) {
514+ /// For BinaryOperator, it also checks if \p InstWithUses is used in specific
515+ /// patterns that make it effectively commutative (like equality comparisons
516+ /// with zero).
517+ /// In most cases, users should not call this function directly (since \p I and
518+ /// \p InstWithUses are the same). However, when analyzing interchangeable
519+ /// instructions, we need to use the converted opcode along with the original
520+ /// uses.
521+ /// \param I The instruction to check for commutativity
522+ /// \param InstWithUses The instruction whose uses are analyzed for special
523+ /// patterns
524+ static bool isCommutative(Instruction *I, Instruction *InstWithUses) {
515525 if (auto *Cmp = dyn_cast<CmpInst>(I))
516526 return Cmp->isCommutative();
517527 if (auto *BO = dyn_cast<BinaryOperator>(I))
518528 return BO->isCommutative() ||
519529 (BO->getOpcode() == Instruction::Sub &&
520- !BO ->hasNUsesOrMore(UsesLimit) &&
530+ !InstWithUses ->hasNUsesOrMore(UsesLimit) &&
521531 all_of(
522- BO ->uses(),
532+ InstWithUses ->uses(),
523533 [](const Use &U) {
524534 // Commutative, if icmp eq/ne sub, 0
525535 CmpPredicate Pred;
@@ -536,14 +546,24 @@ static bool isCommutative(Instruction *I) {
536546 Flag->isOne());
537547 })) ||
538548 (BO->getOpcode() == Instruction::FSub &&
539- !BO ->hasNUsesOrMore(UsesLimit) &&
540- all_of(BO ->uses(), [](const Use &U) {
549+ !InstWithUses ->hasNUsesOrMore(UsesLimit) &&
550+ all_of(InstWithUses ->uses(), [](const Use &U) {
541551 return match(U.getUser(),
542552 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
543553 }));
544554 return I->isCommutative();
545555}
546556
557+ /// This is a helper function to check whether \p I is commutative.
558+ /// This is a convenience wrapper that calls the two-parameter version of
559+ /// isCommutative with the same instruction for both parameters. This is
560+ /// the common case where the instruction being checked for commutativity
561+ /// is the same as the instruction whose uses are analyzed for special
562+ /// patterns (see the two-parameter version above for details).
563+ /// \param I The instruction to check for commutativity
564+ /// \returns true if the instruction is commutative, false otherwise
565+ static bool isCommutative(Instruction *I) { return isCommutative(I, I); }
566+
547567template <typename T>
548568static std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
549569 unsigned Offset) {
@@ -2898,7 +2918,11 @@ class BoUpSLP {
28982918 continue;
28992919 }
29002920 auto [SelectedOp, Ops] = convertTo(cast<Instruction>(V), S);
2901- bool IsInverseOperation = !isCommutative(SelectedOp);
2921+ // We cannot check commutativity by the converted instruction
2922+ // (SelectedOp) because isCommutative also examines def-use
2923+ // relationships.
2924+ bool IsInverseOperation =
2925+ !isCommutative(SelectedOp, cast<Instruction>(V));
29022926 for (unsigned OpIdx : seq<unsigned>(ArgSize)) {
29032927 bool APO = (OpIdx == 0) ? false : IsInverseOperation;
29042928 OpsVec[OpIdx][Lane] = {Operands[OpIdx][Lane], APO, false};
0 commit comments