[llvm] [ValueTracking] Enhance overflow computation for unsigned mul (PR #171568)

Adar Dagan via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 10 20:47:34 PST 2025


https://github.com/Adar-Dagan updated https://github.com/llvm/llvm-project/pull/171568

>From b9fc661c6cfe9b2cb344c6fda603b0b44800e0ba Mon Sep 17 00:00:00 2001
From: Adar Dagan <adar.dagan at mobileye.com>
Date: Wed, 10 Dec 2025 08:10:10 +0200
Subject: [PATCH 1/2] Enhance overflow computation for unsigned mul

---
 llvm/lib/Analysis/ValueTracking.cpp     | 10 ++++-----
 llvm/test/Transforms/InstCombine/mul.ll | 28 +++++++++++++++++++++++++
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9cb6f19b9340c..f8609ec4ccf67 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7286,15 +7286,15 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
                                                    const Value *RHS,
                                                    const SimplifyQuery &SQ,
                                                    bool IsNSW) {
-  KnownBits LHSKnown = computeKnownBits(LHS, SQ);
-  KnownBits RHSKnown = computeKnownBits(RHS, SQ);
+  ConstantRange LHSRange =
+      computeConstantRangeIncludingKnownBits(LHS, false, SQ);
+  ConstantRange RHSRange =
+      computeConstantRangeIncludingKnownBits(RHS, false, SQ);
 
   // mul nsw of two non-negative numbers is also nuw.
-  if (IsNSW && LHSKnown.isNonNegative() && RHSKnown.isNonNegative())
+  if (IsNSW && LHSRange.isAllNonNegative() && RHSRange.isAllNonNegative())
     return OverflowResult::NeverOverflows;
 
-  ConstantRange LHSRange = ConstantRange::fromKnownBits(LHSKnown, false);
-  ConstantRange RHSRange = ConstantRange::fromKnownBits(RHSKnown, false);
   return mapOverflowResult(LHSRange.unsignedMulMayOverflow(RHSRange));
 }
 
diff --git a/llvm/test/Transforms/InstCombine/mul.ll b/llvm/test/Transforms/InstCombine/mul.ll
index 0f3137cdd0be3..615f905b7e58a 100644
--- a/llvm/test/Transforms/InstCombine/mul.ll
+++ b/llvm/test/Transforms/InstCombine/mul.ll
@@ -2202,3 +2202,31 @@ define i8 @mul_not_nsw_nonneg(i8 %x, i8 %y) {
   %mul = mul i8 %x, %y
   ret i8 %mul
 }
+
+define i16 @mul_udiv_zext(i8 %x) {
+; CHECK-LABEL: @mul_udiv_zext(
+; CHECK-NEXT:    [[X_FR:%.*]] = freeze i8 [[X:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = urem i8 [[X_FR]], 15
+; CHECK-NEXT:    [[NARROW:%.*]] = sub nuw i8 [[X_FR]], [[TMP1]]
+; CHECK-NEXT:    [[ZEXT:%.*]] = zext i8 [[NARROW]] to i16
+; CHECK-NEXT:    ret i16 [[ZEXT]]
+;
+  %div = udiv i8 %x, 15
+  %zext = zext i8 %div to i16
+  %mul = mul i16 %zext, 15
+  ret i16 %mul
+}
+
+define i16 @mul_udiv_zext_uneq(i8 %x) {
+; CHECK-LABEL: @mul_udiv_zext_uneq(
+; CHECK-NEXT:    [[DIV:%.*]] = udiv i8 [[X:%.*]], 20
+; CHECK-NEXT:    [[NARROW:%.*]] = mul nuw i8 [[DIV]], 15
+; CHECK-NEXT:    [[MUL:%.*]] = zext i8 [[NARROW]] to i16
+; CHECK-NEXT:    ret i16 [[MUL]]
+;
+  %div = udiv i8 %x, 20
+  %zext = zext i8 %div to i16
+  %mul = mul i16 %zext, 15
+  ret i16 %mul
+}
+

>From 71a5f29b904c19778999de27a0dc0c7311cb0381 Mon Sep 17 00:00:00 2001
From: Adar Dagan <adar.dagan at mobileye.com>
Date: Thu, 11 Dec 2025 06:38:34 +0200
Subject: [PATCH 2/2] Fix comments

---
 llvm/lib/Analysis/ValueTracking.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index f8609ec4ccf67..92577cd7517e6 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -7287,9 +7287,9 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
                                                    const SimplifyQuery &SQ,
                                                    bool IsNSW) {
   ConstantRange LHSRange =
-      computeConstantRangeIncludingKnownBits(LHS, false, SQ);
+      computeConstantRangeIncludingKnownBits(LHS, /*ForSigned=*/false, SQ);
   ConstantRange RHSRange =
-      computeConstantRangeIncludingKnownBits(RHS, false, SQ);
+      computeConstantRangeIncludingKnownBits(RHS, /*ForSigned=*/false, SQ);
 
   // mul nsw of two non-negative numbers is also nuw.
   if (IsNSW && LHSRange.isAllNonNegative() && RHSRange.isAllNonNegative())



More information about the llvm-commits mailing list