From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jamie Lokier To: Marc Lehmann , egcs@cygnus.com Subject: GCC 2.7.2.3 good, EGCS 1.0.3 bad for x86 subtract then test Date: Mon, 21 Dec 1998 02:53:00 -0000 Message-id: <19981221105213.A5825@tantalophile.demon.co.uk> References: <19981218003619.B28066@cerebro.laendle> <19981220010520.A4999@tantalophile.demon.co.uk> <19981220223834.D16580@cerebro.laendle> X-SW-Source: 1998-12/msg00804.html On Sun, Dec 20, 1998 at 10:38:34PM +0100, Marc Lehmann wrote: > That means that expressions like > > a-b>0 > > Almost always generate a seperate testl. > > Jamie Lokier write: > > I even modified the code (in a private GCC) to do this for DImode > > subtract/compare. So there ;-) > > Silly that it doesn't work (in gcc-2.7.2.3 ;) You should have tried a-b>=0 :-) ^^ The interesting thing is that the test is optimised away by GCC 2.7.3.2, but not EGCS 1.0.3. (Which I'd never have noticed if it weren't for this discussion). Here's the example program: extern void a (void); void f (int x, int y) { if ((x -= y) >= 0) a (); } With GCC 2.7.2.3, it optimises to: f: pushl %ebp movl %esp,%ebp movl 8(%ebp),%eax subl 12(%ebp),%eax js .L2 call a .L2: leave ret With EGCS 1.0.3, -O2 it optimises to this: f: pushl %ebp movl %esp,%ebp movl 12(%ebp),%eax movl 8(%ebp),%edx subl %eax,%edx movl %edx,%eax testl %eax,%eax jl .L2 call a .L2: leave ret -mpentium etc. don't make any difference to the test. As well is keeping the redundant test instruction, you can also see that EGCS' register allocation is sucking quite hard. In fact, perhaps the redundant spill is the reason for the redundant test. BTW, if anyone wants my ancient DImode patch for GCC 2.7.2, ask. Comments from the patch: "This patch is for the i386 machine descripton of GCC 2.7.2. It was tested with some other changes in place, so the patch offsets may be a little off but it should still work with an unchanged 2.7.2: 1. Different patterns for adddi3 and subdi3. These use fewer move instructions in some cases (let reload do the work instead. It might even be able to cope in 2.8.0). 2. Use smaller instructions when outputting small decrements. 3. Use the sign flag from adddi3, subdi3 and negdi2 insns, so they can be followed immediately by a branch. * i386.h (CC_NO_ZERO): New cc_status flag. * i386.c (notice_update_cc): Set flags for DImode ADD, SUB, NEG. * i386.md (adddi3, subdi3): Simplify constraints, use fewer explicit moves, and subtract if adding a negative constant. (addsi3): Subtract if adding a negative constant. (seq, sne, beq, bne): Take into account CC_NO_ZERO in the output routines for these insns." -- Jamie