@@ -537,7 +537,8 @@ static bool isSplat(ArrayRef<Value *> VL) {
537537/// \param I The instruction to check for commutativity
538538/// \param ValWithUses The value whose uses are analyzed for special
539539/// patterns
540- static bool isCommutative(Instruction *I, Value *ValWithUses) {
540+ static bool isCommutative(Instruction *I, Value *ValWithUses,
541+ bool IsCopyable = false) {
541542 if (auto *Cmp = dyn_cast<CmpInst>(I))
542543 return Cmp->isCommutative();
543544 if (auto *BO = dyn_cast<BinaryOperator>(I))
@@ -546,7 +547,7 @@ static bool isCommutative(Instruction *I, Value *ValWithUses) {
546547 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
547548 all_of(
548549 ValWithUses->uses(),
549- [](const Use &U) {
550+ [& ](const Use &U) {
550551 // Commutative, if icmp eq/ne sub, 0
551552 CmpPredicate Pred;
552553 if (match(U.getUser(),
@@ -555,10 +556,11 @@ static bool isCommutative(Instruction *I, Value *ValWithUses) {
555556 return true;
556557 // Commutative, if abs(sub nsw, true) or abs(sub, false).
557558 ConstantInt *Flag;
559+ auto *I = dyn_cast<BinaryOperator>(U.get());
558560 return match(U.getUser(),
559561 m_Intrinsic<Intrinsic::abs>(
560562 m_Specific(U.get()), m_ConstantInt(Flag))) &&
561- (!cast<Instruction>(U.get()) ->hasNoSignedWrap() ||
563+ ((!IsCopyable && I && !I ->hasNoSignedWrap() ) ||
562564 Flag->isOne());
563565 })) ||
564566 (BO->getOpcode() == Instruction::FSub &&
@@ -3164,7 +3166,8 @@ class BoUpSLP {
31643166 bool IsInverseOperation = false;
31653167 if (S.isCopyableElement(VL[Lane])) {
31663168 // The value is a copyable element.
3167- IsInverseOperation = !isCommutative(MainOp, VL[Lane]);
3169+ IsInverseOperation =
3170+ !isCommutative(MainOp, VL[Lane], /*IsCopyable=*/true);
31683171 } else {
31693172 assert(I && "Expected instruction");
31703173 auto [SelectedOp, Ops] = convertTo(I, S);
0 commit comments