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

via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 4 00:36:07 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

this is the example i did in unit test:


TEST(KnownBitsTest, NonZeroDenomSDiv) {
  KnownBits Num = KnownBits::makeConstant(APInt(4, -8, true));
  KnownBits Denom(4);

  // Denom = 0b0?00.
  Denom.Zero.setBit(3);
  //Denom.Zero.setBit(2);
  Denom.Zero.setBit(1);
  Denom.Zero.setBit(0);

  KnownBits Result = KnownBits::sdiv(Num, Denom);
  KnownBits Answer = KnownBits::makeConstant(APInt(4, -2, true));

  EXPECT_EQ(Result, Answer);
}

and this was the output of the test:

/home/user/Documents/anand/llvm23/llvm-project/llvm/unittests/Support/KnownBitsTest.cpp:710: Failure
Expected equality of these values:
  Result
    Which is: 111?
  Answer
    Which is: 1110

[  FAILED  ] KnownBitsTest.NonZeroDenomSDiv (0 ms)
[----------] 1 test from KnownBitsTest (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] KnownBitsTest.NonZeroDenomSDiv

 1 FAILED TEST

as you can see here the value stored in result is 111? and not 1110 . if i test it with  the Answer.One.setHighBits(3);
instead of Answer = KnownBits::makeConstant(APInt(4, -2, true));
the test passes!! its checking the setbits.

is this what you meant by "where you would check that the known bits of the return value are `0b111???` or etc for example"???
let me know? thanks.

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


More information about the llvm-commits mailing list