[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