[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