[patch RFA] SH: Fix miscompile for pr24428.c

Kaz Kojima kkojima@rr.iij4u.or.jp
Fri Oct 21 13:06:00 GMT 2005


Hi,

gcc.dg/tls/pr24428.c fails on sh4-unknown-linux-gnu.  It's
miscompiled at -O2:

main:
	mov.l	.L8,r1
	stc	gbr,r2
	mova	.L9,r0
	fmov.s	@r0+,fr3
	fmov.s	@r0+,fr2
	mov.l	.L10,r3
	add	r1,r2
	mov.l	r14,@-r15
	mov	r15,r14
	add	#4,r2
.L12:
	fmov.s	fr2,@r2
	fmov.s	fr3,@-r2
	add	#8,r2
	cmp/eq	r3,r2
	bf/s	.L12
	add	#4,r2
	add	#-4,r2
	mov	#0,r0
	mov	r14,r15
	mov.l	@r15+,r14
	rts	
	nop
.L11:
	.align 2
.L8:
	.long	thrtest@TPOFF
.L9:
	.long	0
	.long	1072693248
.L10:
	.long	thrtest+648

where thrtest+648 isn't a correct address for TLS.  I've confirmed
that pr24428.c doesn't fail with 3.4.4 and 4.0.2 on sh4-linux.  So
this is a 4.1 regression.  The attached patch is to handle the address
constant of the form (const (plus (symbol_ref tls_address) (const_int n))).
It's tested with bootstrap and the toplevel "make -k check" with
no new failures on sh4-unknown-linux-gnu.

Regards,
	kaz
--
:ADDPATCH target:

2005-10-21  Kaz Kojima  <kkojima@gcc.gnu.org>

	* config/sh/sh.c (prepare_move_operands): Handle the address
	constant which is a tls symbolic address plus a constant.

diff -uprN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
--- ORIG/gcc/gcc/config/sh/sh.c	2005-10-20 06:07:36.000000000 +0900
+++ LOCAL/gcc/gcc/config/sh/sh.c	2005-10-20 12:11:04.000000000 +0900
@@ -1238,11 +1238,21 @@ prepare_move_operands (rtx operands[], e
 
   if (mode == Pmode || mode == ptr_mode)
     {
-      rtx op0, op1;
+      rtx op0, op1, opc;
       enum tls_model tls_kind;
 
       op0 = operands[0];
       op1 = operands[1];
+      if (GET_CODE (op1) == CONST
+	  && GET_CODE (XEXP (op1, 0)) == PLUS
+	  && tls_symbolic_operand (XEXP (XEXP (op1, 0), 0), Pmode))
+	{
+	  opc = XEXP (XEXP (op1, 0), 1);
+	  op1 = XEXP (XEXP (op1, 0), 0);
+	}
+      else
+	opc = NULL_RTX;
+
       if ((tls_kind = tls_symbolic_operand (op1, Pmode)))
 	{
 	  rtx tga_op1, tga_ret, tmp, tmp2;
@@ -1308,6 +1318,8 @@ prepare_move_operands (rtx operands[], e
 	    default:
 	      gcc_unreachable ();
 	    }
+	  if (opc)
+	    emit_insn (gen_addsi3 (op1, op1, force_reg (SImode, opc)));
 	  operands[1] = op1;
 	}
     }



More information about the Gcc-patches mailing list