[llvm] [KnownBits] Improve minimum denominator bounds for sdiv (PR #227264)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 02:29:50 PDT 2026


================
@@ -0,0 +1,157 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; Division by zero is UB, so sdiv uses the lowest unknown bit of the
+; denominator as the minimum non-zero denominator when it may be zero.
+; Each test masks the quotient with its known high bits, so it folds to a
+; constant only if the quotient range is tight enough.
+
+; i8, denominator 0b0???????, numerator in [-128, -16] (exact):
+; minimum denominator 1, quotient in [-128, -1].
+define i8 @sdiv_exact_denom_0b0_______(i8 %a, i8 %x) {
+; CHECK-LABEL: define i8 @sdiv_exact_denom_0b0_______(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[X:%.*]]) {
+; CHECK-NEXT:    ret i8 -128
+;
+  %n = and i8 %a, -16
+  %n.neg = or i8 %n, -128
+  %d = and i8 %x, 127
+  %r = sdiv exact i8 %n.neg, %d
+  %m = and i8 %r, -128
+  ret i8 %m
+}
+
+; i8, denominator 0b0??????0, numerator in [-128, -16] (exact):
+; minimum denominator 2, quotient in [-64, -1].
+define i8 @sdiv_exact_denom_0b0______0(i8 %a, i8 %x) {
+; CHECK-LABEL: define i8 @sdiv_exact_denom_0b0______0(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[X:%.*]]) {
+; CHECK-NEXT:    ret i8 -64
+;
+  %n = and i8 %a, -16
+  %n.neg = or i8 %n, -128
+  %d = and i8 %x, 126
+  %r = sdiv exact i8 %n.neg, %d
+  %m = and i8 %r, -64
+  ret i8 %m
+}
+
+; i8, denominator 0b0000000?, numerator in [-128, -16]:
+; minimum denominator 1, quotient in [-128, -1].
+define i8 @sdiv_denom_0b0000000_(i8 %a, i8 %x) {
+; CHECK-LABEL: define i8 @sdiv_denom_0b0000000_(
+; CHECK-SAME: i8 [[A:%.*]], i8 [[X:%.*]]) {
+; CHECK-NEXT:    ret i8 -128
+;
+  %n = and i8 %a, -16
+  %n.neg = or i8 %n, -128
+  %d = and i8 %x, 1
+  %r = sdiv i8 %n.neg, %d
+  %m = and i8 %r, -128
----------------
anandkvinu wrote:

> This tests just the signbit. I think there are ways to check against the KnownBits, where you would check that the known bits of the return value are `0b111???` or etc for example

%a =????????, %x = ????????
%n.neg = or i8 %a, -8 (11111000) so %n.neg becomes 11111???
%d = and i8 %x, 1 (%d becomes 0000000?){0,1}
%r = sdiv i8 %n.neg, %d (%n.neg / 1 = %n.neg) that tell %r can be in range [-8, -1]
%m = and i8 %r, -8 (%m = 11111??? & 11111000 = 11111000)

-8 & -8 = -8
-7 & -8 = -8
-6 & -8 = -8
.
.
-1 & -8 = -8
ret i8 %m

will this suffice? please let me know. thanks.

https://github.com/llvm/llvm-project/pull/227264


More information about the llvm-commits mailing list