[PATCH] wide-int division fix (PR tree-optimization/64807)
Jakub Jelinek
jakub@redhat.com
Mon Jan 26 22:12:00 GMT 2015
Hi!
On the following testcase we generate wrong code, because
apparently divmod_internal_2 relies on 0 being the topmost
element (at b_dividend[m]):
algorithm. M is the number of significant elements of U however
there needs to be at least one extra element of B_DIVIDEND
allocated, N is the number of elements of B_DIVISOR. */
The comment talks just about allocation, but from the code
it seems it really relies on it being 0.
There is space for it:
unsigned HOST_HALF_WIDE_INT
b_dividend[(4 * MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_HALF_WIDE_INT) + 1];
unsigned HOST_HALF_WIDE_INT
b_divisor[4 * MAX_BITSIZE_MODE_ANY_INT / HOST_BITS_PER_HALF_WIDE_INT];
(the + 1), and usually there already is a zero in there:
m = dividend_blocks_needed;
while (m > 1 && b_dividend[m - 1] == 0)
m--;
so the only problematic case is if m isn't decreased.
Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux,
ok for trunk?
2015-01-26 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/64807
* wide-int.cc (wi::divmod_internal): Clear
b_dividend[dividend_blocks_needed].
* gcc.dg/pr64807.c: New test.
--- gcc/wide-int.cc.jj 2015-01-09 21:59:38.000000000 +0100
+++ gcc/wide-int.cc 2015-01-26 19:21:56.114316481 +0100
@@ -1819,6 +1819,7 @@ wi::divmod_internal (HOST_WIDE_INT *quot
divisor_blocks_needed, divisor_prec, sgn);
m = dividend_blocks_needed;
+ b_dividend[m] = 0;
while (m > 1 && b_dividend[m - 1] == 0)
m--;
--- gcc/testsuite/gcc.dg/pr64807.c.jj 2015-01-26 19:24:13.612943033 +0100
+++ gcc/testsuite/gcc.dg/pr64807.c 2015-01-26 19:32:34.502237566 +0100
@@ -0,0 +1,19 @@
+/* PR tree-optimization/64807 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2" } */
+
+__uint128_t
+foo (void)
+{
+ __uint128_t a = -1;
+ __uint128_t b = -1;
+ return a / b;
+}
+
+int
+main ()
+{
+ if (foo () != 1)
+ __builtin_abort ();
+ return 0;
+}
Jakub
More information about the Gcc-patches
mailing list