diff --git a/llvm/lib/Support/KnownBits.cpp b/llvm/lib/Support/KnownBits.cpp --- a/llvm/lib/Support/KnownBits.cpp +++ b/llvm/lib/Support/KnownBits.cpp @@ -758,6 +758,13 @@ assert(!LHS.hasConflict() && !RHS.hasConflict() && "Bad inputs"); KnownBits Known(BitWidth); + if (LHS.isZero() || RHS.isZero()) { + // Result is either known Zero or UB. Return Zero either way. + // Checking this earlier saves us a lot of special cases later on. + Known.setAllZero(); + return Known; + } + std::optional Res; if (LHS.isNegative() && RHS.isNegative()) { // Result non-negative. @@ -819,6 +826,13 @@ assert(!LHS.hasConflict() && !RHS.hasConflict()); KnownBits Known(BitWidth); + if (LHS.isZero() || RHS.isZero()) { + // Result is either known Zero or UB. Return Zero either way. + // Checking this earlier saves us a lot of special cases later on. + Known.setAllZero(); + return Known; + } + // We can figure out the minimum number of upper zero bits by doing // MaxNumerator / MinDenominator. If the Numerator gets smaller or Denominator // gets larger, the number of upper zero bits increases. diff --git a/llvm/test/CodeGen/WebAssembly/pr59626.ll b/llvm/test/CodeGen/WebAssembly/pr59626.ll --- a/llvm/test/CodeGen/WebAssembly/pr59626.ll +++ b/llvm/test/CodeGen/WebAssembly/pr59626.ll @@ -13,6 +13,9 @@ ; CHECK-32-NEXT: i32.const 0 ; CHECK-32-NEXT: i32.store16 0 ; CHECK-32-NEXT: local.get 1 +; CHECK-32-NEXT: i32.const 0 +; CHECK-32-NEXT: i32.store8 2 +; CHECK-32-NEXT: local.get 1 ; CHECK-32-NEXT: local.get 0 ; CHECK-32-NEXT: i8x16.splat ; CHECK-32-NEXT: v128.store16_lane 0, 0