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

via llvm-commits llvm-commits at lists.llvm.org
Wed Dec 10 23:13:28 PST 2025


Author: Adar Dagan
Date: 2025-12-11T08:13:23+01:00
New Revision: 488202935ed9857ad2ad44cb25e99c4365eea2e0

URL: https://github.com/llvm/llvm-project/commit/488202935ed9857ad2ad44cb25e99c4365eea2e0
DIFF: https://github.com/llvm/llvm-project/commit/488202935ed9857ad2ad44cb25e99c4365eea2e0.diff

LOG: [ValueTracking] Enhance overflow computation for unsigned mul (#171568)

Changed the range computation in computeOverflowForUnsignedMul to use
computeConstantRange as well.

This expands the patterns that InstCombine manages to narrow a mul that
has values that come from zext, for example if a value comes from a div
operation then the known bits doesn't give the narrowest possible range
for that value.

---------

Co-authored-by: Adar Dagan <adar.dagan at mobileye.com>

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstCombine/mul.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 9cb6f19b9340c..92577cd7517e6 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, /*ForSigned=*/false, SQ);
+  ConstantRange RHSRange =
+      computeConstantRangeIncludingKnownBits(RHS, /*ForSigned=*/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
+}
+


        


More information about the llvm-commits mailing list