This is the mail archive of the gcc@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]

GCC 2.7.2.3 good, EGCS 1.0.3 bad for x86 subtract then test


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


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