This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Patch for incorrect execute/divconst-2.c
- To: Jeffrey A Law <law at cygnus dot com>
- Subject: Re: Patch for incorrect execute/divconst-2.c
- From: Hans-Peter Nilsson <hp at bitrange dot com>
- Date: Sat, 11 Mar 2000 08:02:05 -0500 (EST)
- cc: gcc-patches at gcc dot gnu dot org
On Tue, 7 Mar 2000, Jeffrey A Law wrote:
> In message <Pine.BSF.4.10.10003062120400.13918-100000@dair.pair.com>you write
> > * execute/divconst-2.c (main): Allow for 0x7fffffffL /
> > -0x80000000L yielding a -1 quotient.
> Seems to me the best thing would be change the test so that it checks that
> (a/b)*b + a%b == a Instead of looking for specific constant values.
Thanks for looking at this.
I rewrote the test to check for standards-compliant results like
arith-rand.c, but kept what seemed the "point" of the test, the
divide-by-(-2147483648) constant stuff.
Unfortunately this uncovers other GCC problems: the "quot * -2147483648"
gets optimized into "quot << 31" on a host with 32-bit HOST_WIDE_INTs,
regardless of sizeof long on the actual target, and abs(-2147483648)
yields itself, which compares as negative on the i386.
The test now fails on, for example i686-pc-linux-gnulibc1 targeting mmix
(for the first reason) or self (for the second reason - a separate bug),
but succeeds on alpha-unknown-linux-gnu, targeting self or mmix.
Should I commit this, or break some more stuff? :-)
Perhaps I should remove the ABS check, so it doesn't break on ix86-* self?
Fri Mar 10 01:15:19 2000 Hans-Peter Nilsson <hp@bitrange.com>
* execute/divconst-2.c: Rewrite to check for standards-compliant
result rather than specific constants. Put test-values in array.
Index: divconst-2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/testsuite/gcc.c-torture/execute/divconst-2.c,v
retrieving revision 1.2
diff -p -c -r1.2 divconst-2.c
*** divconst-2.c 1998/12/16 22:15:36 1.2
--- divconst-2.c 2000/03/10 00:01:06
*************** f (long x)
*** 4,12 ****
return x / (-0x7fffffffL - 1L);
}
main ()
{
! if (f (-1L) != 0L || f (0x7fffffffL) != 0L || f (-0x7fffffffL - 1L) != 1l)
! abort ();
exit (0);
}
--- 4,40 ----
return x / (-0x7fffffffL - 1L);
}
+ long
+ r (long x)
+ {
+ return x % (-0x7fffffffL - 1L);
+ }
+
+ #define ABS(x) ((x) >= 0 ? (x) : -(x))
+
+ /* Since we have a negative divisor, this equation must hold for the
+ results of / and %; no specific results are guaranteed. */
+ long
+ std_eqn (long num, long denom, long quot, long rem)
+ {
+ return quot * (-0x7fffffffL - 1L) + rem == num
+ && ABS (rem) < ABS (denom);
+ }
+
+ long nums[] =
+ {
+ -1L, 0x7fffffffL, -0x7fffffffL - 1L
+ };
+
main ()
{
! int i;
!
! for (i = 0;
! i < sizeof (nums) / sizeof (nums[0]);
! i++)
! if (std_eqn (nums[i], -0x7fffffffL - 1L, f (nums[i]), r (nums[i])) == 0)
! abort ();
!
exit (0);
}