Skip to content

Commit 4882029

Browse files
Adar-DaganAdar Dagan
andauthored
[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 <[email protected]>
1 parent cb4b6ad commit 4882029

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7286,15 +7286,15 @@ OverflowResult llvm::computeOverflowForUnsignedMul(const Value *LHS,
72867286
const Value *RHS,
72877287
const SimplifyQuery &SQ,
72887288
bool IsNSW) {
7289-
KnownBits LHSKnown = computeKnownBits(LHS, SQ);
7290-
KnownBits RHSKnown = computeKnownBits(RHS, SQ);
7289+
ConstantRange LHSRange =
7290+
computeConstantRangeIncludingKnownBits(LHS, /*ForSigned=*/false, SQ);
7291+
ConstantRange RHSRange =
7292+
computeConstantRangeIncludingKnownBits(RHS, /*ForSigned=*/false, SQ);
72917293

72927294
// mul nsw of two non-negative numbers is also nuw.
7293-
if (IsNSW && LHSKnown.isNonNegative() && RHSKnown.isNonNegative())
7295+
if (IsNSW && LHSRange.isAllNonNegative() && RHSRange.isAllNonNegative())
72947296
return OverflowResult::NeverOverflows;
72957297

7296-
ConstantRange LHSRange = ConstantRange::fromKnownBits(LHSKnown, false);
7297-
ConstantRange RHSRange = ConstantRange::fromKnownBits(RHSKnown, false);
72987298
return mapOverflowResult(LHSRange.unsignedMulMayOverflow(RHSRange));
72997299
}
73007300

llvm/test/Transforms/InstCombine/mul.ll

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2202,3 +2202,31 @@ define i8 @mul_not_nsw_nonneg(i8 %x, i8 %y) {
22022202
%mul = mul i8 %x, %y
22032203
ret i8 %mul
22042204
}
2205+
2206+
define i16 @mul_udiv_zext(i8 %x) {
2207+
; CHECK-LABEL: @mul_udiv_zext(
2208+
; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]
2209+
; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X_FR]], 15
2210+
; CHECK-NEXT: [[NARROW:%.*]] = sub nuw i8 [[X_FR]], [[TMP1]]
2211+
; CHECK-NEXT: [[ZEXT:%.*]] = zext i8 [[NARROW]] to i16
2212+
; CHECK-NEXT: ret i16 [[ZEXT]]
2213+
;
2214+
%div = udiv i8 %x, 15
2215+
%zext = zext i8 %div to i16
2216+
%mul = mul i16 %zext, 15
2217+
ret i16 %mul
2218+
}
2219+
2220+
define i16 @mul_udiv_zext_uneq(i8 %x) {
2221+
; CHECK-LABEL: @mul_udiv_zext_uneq(
2222+
; CHECK-NEXT: [[DIV:%.*]] = udiv i8 [[X:%.*]], 20
2223+
; CHECK-NEXT: [[NARROW:%.*]] = mul nuw i8 [[DIV]], 15
2224+
; CHECK-NEXT: [[MUL:%.*]] = zext i8 [[NARROW]] to i16
2225+
; CHECK-NEXT: ret i16 [[MUL]]
2226+
;
2227+
%div = udiv i8 %x, 20
2228+
%zext = zext i8 %div to i16
2229+
%mul = mul i16 %zext, 15
2230+
ret i16 %mul
2231+
}
2232+

0 commit comments

Comments
 (0)