Bug 31701 - [4.1/4.2/4.3 Regression] SH: wrong epilogue for sibling calls
Summary: [4.1/4.2/4.3 Regression] SH: wrong epilogue for sibling calls
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.2.0
: P3 normal
Target Milestone: 4.1.3
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2007-04-25 14:15 UTC by Ashay Jaiswal
Modified: 2007-05-26 03:15 UTC (History)
4 users (show)

See Also:
Host: sh4-unknown-linux
Target: sh4-unknown-linux
Build: i686-pc-linux
Known to work: 4.0.0 4.2.1
Known to fail: 4.1.0 4.2.0 4.3.0
Last reconfirmed: 2007-04-26 08:17:49


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ashay Jaiswal 2007-04-25 14:15:12 UTC
Hello all,
              
I have successfully built SH4-Linux toolchain based on
(binutils-2.17, gcc-4.2-20061205, glibc-2.5) for Renesas SH target.

I am facing problem while executing the following program.

 ------------------------------------------------------------------
 #include <stdio.h>        
 extern void func();          
 typedef struct abc {       
 char name[16]; 
 }ABC;  
 main()  
 {          
     int i; 
     ABC buffer[20];         
     for (i=0; i<20; i++)                 
         buffer[i].name[0] = 't';         
   if (buffer[10].name[0] == 't')       
   printf("OK\n"); 
   else   
   printf("NOT OK\n");      
}           
-------------------------------------------------------------------------           

The above program when compiled with '-O0' optimization executes successfully,
but I am getting segmentation fault error while executing the program compiled 
with '-O2' optimization.

Observations:
           
1. I found differences in the assembly output of the program when compiled
   with '-O0' and '-O2' optimization.
   It seems stack register get corrupted with '-O2' optimization.
   
   Following code corrupts the stack register
   L10:
            mov.w   .L18,r14
            mov.l     .L19,r1
            add       r14,r14
            mov      r14,r15        <<here it is corrupting the stack register
            mov.l     @r15+,r14
            jmp       @r1
            nop
            .align 1
   
2. Program executes successfully when compiled with '-O2' and
   '-fno-optimize-sibling-calls' options.

3. Same problem is encountered with gcc-4.0.1 and after reverting the
   patch PR21265(http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21265) the program
   executes successfully with '-O2' optimization. But this solution doesn't work with gcc-4.2-20061205 based toolchain.

Any help on this will be appreciated.

Regards,
Ashay Jaiswal
KPIT Cummins Infosystems Ltd,
Pune (INDIA)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Free download of GNU based SH-Linux toolchains for Renesas' SH Series.                
The following site also offers free technical support to its users.              
Visit http://www.kpitgnutools.com for details.           
Latest versions of KPIT GNU SH-Linux tools were released on April 5, 2007.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Comment 1 Kazumoto Kojima 2007-04-26 08:17:49 UTC
I've confirmed that the test case fails also on trunk.
sh.c:output_stack_adjust tries to find a register for a constant
to unwind the frame and wrongly finds a frame register itself
in the problematic case.  I'm testing the attached patch.

diff -uprN ORIG/trunk/gcc/config/sh/sh.c LOCAL/trunk/gcc/config/sh/sh.c
--- ORIG/trunk/gcc/config/sh/sh.c	2007-03-22 09:50:40.000000000 +0900
+++ LOCAL/trunk/gcc/config/sh/sh.c	2007-04-26 08:06:16.000000000 +0900
@@ -5619,7 +5619,13 @@ output_stack_adjust (int size, rtx reg, 
 	      temp = scavenge_reg (&temps);
 	    }
 	  if (temp < 0 && live_regs_mask)
-	    temp = scavenge_reg (live_regs_mask);
+	    {
+	      HARD_REG_SET temps;
+
+	      COPY_HARD_REG_SET (temps, *live_regs_mask);
+	      CLEAR_HARD_REG_BIT (temps, REGNO (reg));
+	      temp = scavenge_reg (&temps);
+	    }
 	  if (temp < 0)
 	    {
 	      rtx adj_reg, tmp_reg, mem;
@@ -5668,6 +5674,9 @@ output_stack_adjust (int size, rtx reg, 
 	      emit_move_insn (adj_reg, mem);
 	      mem = gen_tmp_stack_mem (Pmode, gen_rtx_POST_INC (Pmode, reg));
 	      emit_move_insn (tmp_reg, mem);
+	      /* Tell flow the insns that pop r4/r5 aren't dead.  */
+	      emit_insn (gen_rtx_USE (VOIDmode, tmp_reg));
+	      emit_insn (gen_rtx_USE (VOIDmode, adj_reg));
 	      return;
 	    }
 	  const_reg = gen_rtx_REG (GET_MODE (reg), temp);
Comment 2 Kazumoto Kojima 2007-04-28 01:07:51 UTC
Subject: Bug 31701

Author: kkojima
Date: Sat Apr 28 01:07:40 2007
New Revision: 124248

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124248
Log:
	PR target/31701
	* config/sh/sh.c (output_stack_adjust): Avoid using the frame
	register itself to hold the offset constant.  Tell flow the use
	of r4 and r5 when they are used.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/sh/sh.c

Comment 3 Kazumoto Kojima 2007-05-21 00:27:36 UTC
Subject: Bug 31701

Author: kkojima
Date: Sun May 20 23:27:22 2007
New Revision: 124882

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124882
Log:
	PR target/31701
	Backport from mainline.
	* config/sh/sh.c (output_stack_adjust): Avoid using the frame
	register itself to hold the offset constant.  Tell flow the use
	of r4 and r5 when they are used.


Modified:
    branches/gcc-4_2-branch/gcc/ChangeLog
    branches/gcc-4_2-branch/gcc/config/sh/sh.c

Comment 4 Kazumoto Kojima 2007-05-21 00:57:54 UTC
Subject: Bug 31701

Author: kkojima
Date: Sun May 20 23:57:32 2007
New Revision: 124885

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=124885
Log:
	PR target/31701
	Backport from mainline.
	* config/sh/sh.c (output_stack_adjust): Avoid using the frame
	register itself to hold the offset constant.  Tell flow the use
	of r4 and r5 when they are used.


Modified:
    branches/gcc-4_1-branch/gcc/ChangeLog
    branches/gcc-4_1-branch/gcc/config/sh/sh.c

Comment 5 Kazumoto Kojima 2007-05-21 01:02:58 UTC
Fixed.