diff options
-rw-r--r-- | gcc/testsuite/gcc.dg/torture/bitint-70.c | 22 | ||||
-rw-r--r-- | libgcc/libgcc2.c | 13 |
2 files changed, 32 insertions, 3 deletions
diff --git a/gcc/testsuite/gcc.dg/torture/bitint-70.c b/gcc/testsuite/gcc.dg/torture/bitint-70.c new file mode 100644 index 0000000..2d693bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/bitint-70.c @@ -0,0 +1,22 @@ +/* PR libgcc/114762 */ +/* { dg-do run { target bitint } } */ +/* { dg-options "-std=c23" } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */ +/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */ + +#if __BITINT_MAXWIDTH__ >= 255 +__attribute__((__noipa__)) signed _BitInt(255) +foo (signed _BitInt(255) a, signed _BitInt(65) b) +{ + return a / b; +} +#endif + +int +main () +{ +#if __BITINT_MAXWIDTH__ >= 255 + if (foo (1, -0xffffffffffffffffwb - 1wb)) + __builtin_abort (); +#endif +} diff --git a/libgcc/libgcc2.c b/libgcc/libgcc2.c index 120d071..3fcb85c 100644 --- a/libgcc/libgcc2.c +++ b/libgcc/libgcc2.c @@ -1715,11 +1715,18 @@ __divmodbitint4 (UBILtype *q, SItype qprec, && vn > 1 && (Wtype) v[BITINT_END (1, vn - 2)] >= 0) { - vp = 0; - --vn; + /* Unless all bits below the most significant limb are zero. */ + SItype vn2; + for (vn2 = vn - 2; vn2 >= 0; --vn2) + if (v[BITINT_END (vn - 1 - vn2, vn2)]) + { + vp = 0; + --vn; #if __LIBGCC_BITINT_ORDER__ == __ORDER_BIG_ENDIAN__ - ++v; + ++v; #endif + break; + } } if (__builtin_expect (un < vn, 0)) { |