@@ -511,15 +511,25 @@ static bool isSplat(ArrayRef<Value *> VL) {
511
511
}
512
512
513
513
/// \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) {
515
525
if (auto *Cmp = dyn_cast<CmpInst>(I))
516
526
return Cmp->isCommutative();
517
527
if (auto *BO = dyn_cast<BinaryOperator>(I))
518
528
return BO->isCommutative() ||
519
529
(BO->getOpcode() == Instruction::Sub &&
520
- !BO ->hasNUsesOrMore(UsesLimit) &&
530
+ !InstWithUses ->hasNUsesOrMore(UsesLimit) &&
521
531
all_of(
522
- BO ->uses(),
532
+ InstWithUses ->uses(),
523
533
[](const Use &U) {
524
534
// Commutative, if icmp eq/ne sub, 0
525
535
CmpPredicate Pred;
@@ -536,14 +546,24 @@ static bool isCommutative(Instruction *I) {
536
546
Flag->isOne());
537
547
})) ||
538
548
(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) {
541
551
return match(U.getUser(),
542
552
m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
543
553
}));
544
554
return I->isCommutative();
545
555
}
546
556
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
+
547
567
template <typename T>
548
568
static std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
549
569
unsigned Offset) {
@@ -2898,7 +2918,11 @@ class BoUpSLP {
2898
2918
continue;
2899
2919
}
2900
2920
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));
2902
2926
for (unsigned OpIdx : seq<unsigned>(ArgSize)) {
2903
2927
bool APO = (OpIdx == 0) ? false : IsInverseOperation;
2904
2928
OpsVec[OpIdx][Lane] = {Operands[OpIdx][Lane], APO, false};
0 commit comments