[llvm] [AggressiveInstCombine] Extend MulHigh fold for `or disjoint` (PR #228897)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Oct 4 07:52:10 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-transforms
Author: 伍浩宇 (suogesi)
<details>
<summary>Changes</summary>
`foldMulHigh` is excecuted after another fold, which folds `add` into `or disjoint`. This can make `foldMulHigh` miss chances to fold.
Replacing `m_Add` into `m_AddLike` extends `foldMulHigh` so it can fold more cases in `-O3` mode.
Notice that there are more cases in `foldMulHigh`. They may need to replace `m_Add` too.
Fixes #<!-- -->221257.
---
Full diff: https://github.com/llvm/llvm-project/pull/228897.diff
2 Files Affected:
- (modified) llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp (+2-2)
- (added) llvm/test/Transforms/AggressiveInstCombine/umulh_carry_o3.ll (+33)
``````````diff
diff --git a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
index c5548eb107a11..7b90bc76626d0 100644
--- a/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
+++ b/llvm/lib/Transforms/AggressiveInstCombine/AggressiveInstCombine.cpp
@@ -2524,8 +2524,8 @@ static bool foldMulHigh(Instruction &I) {
Instruction *A, *B, *C;
auto HiHi = m_OneUse(m_Mul(m_LShr(m_Value(X), m_SpecificInt(BitWidth / 2)),
m_LShr(m_Value(Y), m_SpecificInt(BitWidth / 2))));
- if ((match(&I, m_c_Add(HiHi, m_OneUse(m_Add(m_Instruction(A),
- m_Instruction(B))))) ||
+ if ((match(&I, m_c_Add(HiHi, m_OneUse(m_AddLike(m_Instruction(A),
+ m_Instruction(B))))) ||
match(&I, m_c_Add(m_Instruction(A),
m_OneUse(m_c_Add(HiHi, m_Instruction(B)))))) &&
A->hasOneUse() && B->hasOneUse())
diff --git a/llvm/test/Transforms/AggressiveInstCombine/umulh_carry_o3.ll b/llvm/test/Transforms/AggressiveInstCombine/umulh_carry_o3.ll
new file mode 100644
index 0000000000000..7c6562959f09c
--- /dev/null
+++ b/llvm/test/Transforms/AggressiveInstCombine/umulh_carry_o3.ll
@@ -0,0 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -O3 -S | FileCheck %s
+
+define i32 @mul_carry_add_carry_to_crosssum(i32 %x, i32 %y) {
+; CHECK-LABEL: define range(i32 0, -1) i32 @mul_carry_add_carry_to_crosssum(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[X]] to i64
+; CHECK-NEXT: [[TMP1:%.*]] = zext i32 [[Y]] to i64
+; CHECK-NEXT: [[TMP2:%.*]] = mul nuw i64 [[TMP1]], [[TMP0]]
+; CHECK-NEXT: [[TMP3:%.*]] = lshr i64 [[TMP2]], 32
+; CHECK-NEXT: [[ADD11:%.*]] = trunc nuw i64 [[TMP3]] to i32
+; CHECK-NEXT: ret i32 [[ADD11]]
+;
+entry:
+ %shr = lshr i32 %x, 16
+ %and = and i32 %x, 65535
+ %shr1 = lshr i32 %y, 16
+ %and2 = and i32 %y, 65535
+ %mul = mul nuw i32 %and2, %shr
+ %mul3 = mul nuw i32 %shr1, %and
+ %add = add i32 %mul3, %mul
+ %mul4 = mul nuw i32 %and, %and2
+ %shr5 = lshr i32 %mul4, 16
+ %add6 = add i32 %shr5, %add
+ %cmp = icmp ult i32 %add6, %mul
+ %cond = select i1 %cmp, i32 65536, i32 0
+ %mul8 = mul nuw i32 %shr, %shr1
+ %shr10 = lshr i32 %add6, 16
+ %add9 = add nuw i32 %cond, %shr10
+ %add11 = add i32 %add9, %mul8
+ ret i32 %add11
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/228897
More information about the llvm-commits
mailing list