[llvm] [AggressiveInstCombine] Fold i64 x i64 -> i128 multiply-by-parts (PR #156879)
David Green via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 28 07:09:19 PDT 2025
================
@@ -1457,6 +1457,268 @@ static bool foldLibCalls(Instruction &I, TargetTransformInfo &TTI,
return false;
}
+/// Match low part of 128-bit multiplication.
+///
+/// Use counts are checked to prevent total instruction count increase as per
+/// contributors guide:
+/// https://llvm.org/docs/InstCombineContributorGuide.html#multi-use-handling
+static bool foldMul128Low(Instruction &I) {
+ auto *Ty = I.getType();
+ if (!Ty->isIntegerTy(64))
+ return false;
+
+ // (low_accum << 32) | lo(lo(y) * lo(x))
+ Value *LowAccum = nullptr, *YLowXLow = nullptr;
+ if (!match(&I, m_c_DisjointOr(
+ m_OneUse(m_Shl(m_Value(LowAccum), m_SpecificInt(32))),
+ m_OneUse(
+ m_And(m_Value(YLowXLow), m_SpecificInt(0xffffffff))))))
+ return false;
+
+ // lo(cross_sum) + hi(lo(y) * lo(x))
+ Value *CrossSum = nullptr;
+ if (!match(
+ LowAccum,
+ m_c_Add(m_OneUse(m_And(m_Value(CrossSum), m_SpecificInt(0xffffffff))),
+ m_OneUse(m_LShr(m_Specific(YLowXLow), m_SpecificInt(32))))) ||
+ LowAccum->hasNUsesOrMore(3))
+ return false;
+
+ // (hi(y) * lo(x)) + (lo(y) * hi(x))
+ Value *YHigh = nullptr, *XLow = nullptr, *YLowXHigh = nullptr;
+ if (!match(CrossSum, m_c_Add(m_OneUse(m_c_Mul(m_Value(YHigh), m_Value(XLow))),
----------------
davemgreen wrote:
m_c_Mul can be m_Mul as both the operands are m_Value.
https://github.com/llvm/llvm-project/pull/156879
More information about the llvm-commits
mailing list