[llvm] [Reassociate] Distribute multiply over add to enable factorization (PR #178201)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Sat May 2 03:47:54 PDT 2026
================
@@ -963,6 +963,69 @@ static BinaryOperator *convertOrWithNoCommonBitsToAdd(Instruction *Or) {
return New;
}
+/// Return true if Mul is of the form (X+Y)*C or (X-Y)*C where C is a
+/// constant, and there exists a sibling instruction of the form X*C' or Y*C'
+/// in the same expression — indicating that distribution followed by
+/// factoring will reduce the instruction count.
+static bool ShouldBreakUpDistribution(Instruction *Mul) {
+ Value *A, *B;
+ if (!match(Mul, m_c_Mul(m_OneUse(m_CombineOr(m_Add(m_Value(A), m_Value(B)),
+ m_Sub(m_Value(A), m_Value(B)))),
+ m_ImmConstant())))
+ return false;
+
+ if (!Mul->hasOneUse())
+ return false;
+
+ auto *MulUser = dyn_cast<Instruction>(Mul->user_back());
+ // The parent MUST be an Add or Sub to ensure the tree is flattened
+ if (!MulUser || (MulUser->getOpcode() != Instruction::Add &&
+ MulUser->getOpcode() != Instruction::Sub))
+ return false;
+
+ for (Value *Sibling : MulUser->operands()) {
+ if (Sibling == Mul || !Sibling->hasOneUse())
+ continue;
+
+ // Sibling must be NonConst * C'.
+ Value *SibNC;
+ if (match(Sibling, m_Mul(m_Value(SibNC), m_Constant()))) {
+ if ((SibNC == A || SibNC == B) && !isa<Constant>(SibNC))
+ return true;
+ }
----------------
dtcxzyw wrote:
```suggestion
if (match(Sibling, m_Mul(m_Value(SibNC), m_Constant())) && (SibNC == A || SibNC == B) && !isa<Constant>(SibNC))
return true;
```
https://github.com/llvm/llvm-project/pull/178201
More information about the llvm-commits
mailing list