[Bug libgcc/114762] wrong code with _BitInt() division by "BITINT_NN_MIN"

2024-04-19 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114762

Jakub Jelinek  changed:

   What|Removed |Added

 Resolution|--- |FIXED
 Status|ASSIGNED|RESOLVED

--- Comment #4 from Jakub Jelinek  ---
Fixed.

[Bug libgcc/114762] wrong code with _BitInt() division by "BITINT_NN_MIN"

2024-04-19 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114762

--- Comment #3 from GCC Commits  ---
The master branch has been updated by Jakub Jelinek :

https://gcc.gnu.org/g:36f4c8a9ac8f71fc21fcb169c7913e8fef30d15c

commit r14-10034-g36f4c8a9ac8f71fc21fcb169c7913e8fef30d15c
Author: Jakub Jelinek 
Date:   Fri Apr 19 08:44:54 2024 +0200

libgcc: Another __divmodbitint4 bug fix [PR114762]

The following testcase is miscompiled because the code to decrement
vn on negative value with all ones in most significant limb (even partial)
and 0 in most significant bit of the second most significant limb doesn't
take into account the case where all bits below the most significant limb
are zero.  This has been a problem both in the version before yesterday's
commit where it has been done only if un was one shorter than vn before
this
decrement, and is now problem even more often when it is done earlier.
When we decrement vn in such case and negate it, we end up with all 0s in
the v2 value, so have both the problems with UB on __builtin_clz* and the
expectations of the algorithm that the divisor has most significant bit set
after shifting, plus when the decremented vn is 1 it can SIGFPE on division
by zero even when it is not division by zero etc.  Other values shouldn't
get 0 in the new most significant limb after negation, because the
bitint_reduce_prec canonicalization should reduce prec if the second most
significant limb is all ones and if that limb is all zeros, if at least
one limb below it is non-zero, carry in will make it non-zero.

The following patch fixes it by checking if at least one bit below the
most significant limb is non-zero, in that case it decrements, otherwise
it will do nothing (but e.g. for the un < vn case that also means the
divisor is large enough that the result should be q 0 r u).

2024-04-18  Jakub Jelinek  

PR libgcc/114762
* libgcc2.c (__divmodbitint4): Perform the decrement on negative
v with most significant limb all ones and the second least
significant limb with most significant bit clear always, regardless
of
un < vn.

* gcc.dg/torture/bitint-70.c: New test.

[Bug libgcc/114762] wrong code with _BitInt() division by "BITINT_NN_MIN"

2024-04-18 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114762

Jakub Jelinek  changed:

   What|Removed |Added

 Ever confirmed|0   |1
   Last reconfirmed||2024-04-18
 Status|UNCONFIRMED |ASSIGNED
   Assignee|unassigned at gcc dot gnu.org  |jakub at gcc dot gnu.org

--- Comment #2 from Jakub Jelinek  ---
Created attachment 57982
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57982=edit
gcc14-pr114762.patch

Untested fix.
Note, -0x1wb is not _BitInt(65) minimum, but _BitInt(66) with
value equal to _BitInt(65) minimum.

[Bug libgcc/114762] wrong code with _BitInt() division by "BITINT_NN_MIN"

2024-04-18 Thread zsojka at seznam dot cz via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114762

--- Comment #1 from Zdenek Sojka  ---
Created attachment 57981
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=57981=edit
testcase trying reasonable input for division (and multiplication)

This can be used to test various input combinations. It might be reasonable to
try both -O0 and -O3.

$ x86_64-pc-linux-gnu-gcc tg.c -O0 -fsanitize=undefined -g3 -static && ./a.out 
1 0
Floating point exception

$ aarch64-unknown-linux-gnu-gcc tg.c -O3 -static && qemu-aarch64 -- ./a.out 
1 0
2 0
2 1
3 0
...
62 57
62 58
62 59
62 60
62 61
63 0
a.out: tg.c:35: divmod: Assertion `q * sb + r == sa' failed.
qemu: uncaught target signal 6 (Aborted) - core dumped
Aborted

No warranty for code correctness.