[llvm] [ConstantRange] Bail out early in unsignedMulMayOverflow for wide integer types (PR #192275)
Max Graey via llvm-commits
llvm-commits at lists.llvm.org
Fri Apr 17 09:25:05 PDT 2026
================
@@ -2009,11 +2009,40 @@ APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) const {
}
APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const {
- if (countl_zero() + RHS.countl_zero() + 2 <= BitWidth) {
+ if (BitWidth == 0) {
+ Overflow = false;
+ return APInt(BitWidth, 0);
+ }
+ unsigned LZ = countl_zero() + RHS.countl_zero();
+
+ // No-overflow: product fits in BitWidth bits (bitlen(a)+bitlen(b) <=
+ // BitWidth).
+ if (LZ >= BitWidth) {
+ Overflow = false;
+ return *this * RHS;
+ }
+
+ // Guaranteed overflow: product needs more than BitWidth bits.
+ if (LZ < BitWidth - 1) {
Overflow = true;
return *this * RHS;
}
+ // Borderline (LZ == BitWidth-1): skip the slow path for trivial multipliers.
+ // *this==1: 1*x=x always fits, and avoids a wasteful lshr(1)==0 multiply.
+ // RHS==1: x*1=x always fits.
+ if (isOne()) {
+ Overflow = false;
+ return RHS;
+ }
+ if (RHS.isOne()) {
+ Overflow = false;
+ return *this;
+ }
----------------
MaxGraey wrote:
How about merge these two blocks into one more compact?
```suggestion
if (isOne() || RHS.isOne()) {
Overflow = false;
return isOne() ? RHS : *this;;
}
```
https://github.com/llvm/llvm-project/pull/192275
More information about the llvm-commits
mailing list