@@ -511,15 +511,15 @@ 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+ static bool isCommutative(Instruction *I, Instruction *InstWithUses ) {
515515 if (auto *Cmp = dyn_cast<CmpInst>(I))
516516 return Cmp->isCommutative();
517517 if (auto *BO = dyn_cast<BinaryOperator>(I))
518518 return BO->isCommutative() ||
519519 (BO->getOpcode() == Instruction::Sub &&
520- !BO ->hasNUsesOrMore(UsesLimit) &&
520+ !InstWithUses ->hasNUsesOrMore(UsesLimit) &&
521521 all_of(
522- BO ->uses(),
522+ InstWithUses ->uses(),
523523 [](const Use &U) {
524524 // Commutative, if icmp eq/ne sub, 0
525525 CmpPredicate Pred;
@@ -536,14 +536,16 @@ static bool isCommutative(Instruction *I) {
536536 Flag->isOne());
537537 })) ||
538538 (BO->getOpcode() == Instruction::FSub &&
539- !BO ->hasNUsesOrMore(UsesLimit) &&
540- all_of(BO ->uses(), [](const Use &U) {
539+ !InstWithUses ->hasNUsesOrMore(UsesLimit) &&
540+ all_of(InstWithUses ->uses(), [](const Use &U) {
541541 return match(U.getUser(),
542542 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
543543 }));
544544 return I->isCommutative();
545545}
546546
547+ static bool isCommutative(Instruction *I) { return isCommutative(I, I); }
548+
547549template <typename T>
548550static std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
549551 unsigned Offset) {
@@ -2898,7 +2900,11 @@ class BoUpSLP {
28982900 continue;
28992901 }
29002902 auto [SelectedOp, Ops] = convertTo(cast<Instruction>(V), S);
2901- bool IsInverseOperation = !isCommutative(SelectedOp);
2903+ // We cannot check commutativity by the converted instruction
2904+ // (SelectedOp) because isCommutative also examines def-use
2905+ // relationships.
2906+ bool IsInverseOperation =
2907+ !isCommutative(SelectedOp, cast<Instruction>(V));
29022908 for (unsigned OpIdx : seq<unsigned>(ArgSize)) {
29032909 bool APO = (OpIdx == 0) ? false : IsInverseOperation;
29042910 OpsVec[OpIdx][Lane] = {Operands[OpIdx][Lane], APO, false};
0 commit comments