This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Patch for incorrect execute/divconst-2.c


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);
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]