[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