optimization/9240: wierd scheduling on v850 unless -fno-sched-spec specified

miles@gnu.org miles@gnu.org
Mon Jan 13 05:17:00 GMT 2003


>Number:         9240
>Category:       optimization
>Synopsis:       wierd scheduling on v850 unless -fno-sched-spec specified
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          pessimizes-code
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 09 01:06:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Miles Bader
>Release:        gcc (GCC) 3.4 20030108 (experimental)
>Organization:
>Environment:
gcc compiled on debian unstable i686
cross-compiling for v850e-elf

configure args are: 

configure --prefix=... --target=v850e-elf --host=i386-pc-linux-gnu --with-newlib --enable-languages=c --configure-cache=../config.cache
>Description:
When given the source file below (`gcc-3.x-sched-bug.c'), gcc cross-compiling for the v850 generates very oddly scheduled assembly.

Old versions of gcc (e.g., 2.9x) or using the `-fno-sched-spec' option both cause much better code to be generated.

Here's the (slightly edited) assembly output generated from
`v850e-elf-gcc -S -O5 gcc-3.x-sched-bug.c':

   _bogus:
	   /* compute r10 */
	   mov r10,r12
	   subr r0,r12
	   movea lo(-125),r0,r5
	   cmp r5,r10
	   bge .L3
   .L2:
	   jmp [r31]
   .L3:
	   mov hilo(_errno),r5
	   st.w r12,0[r5]
	   mov -1,r10
	   br .L2

Note that:

 (1) It's moved much of the calculation for the 
     error case before the test, which I can see
     no reason for (especially since the v850 is
     such a simple processor -- no confusing
     speculative scheduling here!), and which
     pessimizes the normal path.

 (2) Even if there were a good reason for such
     scheduling for the error branch, use of
     __builtin_expect as shown arguably should
     have suppressed it, since it adversely
     effects the normal path.

Here's the output when using the -fno-sched-spec option (other args the same), which is much, much, better:

   _bogus:
	   /* compute r10 */
	   movea lo(-125),r0,r5
	   cmp r5,r10
	   bge .L3
   .L2:
	   jmp [r31]
   .L3:
	   subr r0,r10
	   mov hilo(_errno),r5
	   st.w r10,0[r5]
	   mov -1,r10
	   br .L2
>How-To-Repeat:
Here's the source (`gcc-3.x-sched-bug.c'):

   extern int errno;
   int bogus ()
   {
     register int val asm ("r10");

     asm volatile ("/* compute r10 */" : "=r" (val));

     if (__builtin_expect (val >= -125, 0))
       {
	 errno = -val;
	 val = -1;
       }

     return val;
   }

Compile it with:  v850e-elf-gcc -S -O5 gcc-3.x-sched-bug.c
>Fix:
This particular problem can be avoided by using the -fno-sched-spec option; however I do no know if doing so adversely affects other code.
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the Gcc-bugs mailing list