diff mbox

[i386] : Fix PR55597, ICE in plus_constant, at explow.c:88

Message ID CAFULd4Z4Yv_Gq5mLHWiEv9qADhs29ooR2qXcC0uL6VBWxUnTxw@mail.gmail.com
State New
Headers show

Commit Message

Uros Bizjak Dec. 6, 2012, 10:01 p.m. UTC
Hello!

On x32, SImode and DImode symbols are accepted as valid. When SImode
symbol is legitimized through legitimize_tls_address, we use Pmode
operations and temporaries (in case of -maddress-mode=long, Pmode
equals to DImode). In case of Pmode == DImode, we forgot to extend the
mode of a sybmol from SImode to DImode, and we set REG_EQUAL to a
symbol in wrong mode.

The patch extends SImode symbols to DImode using ZERO_EXTEND RTX.

2012-12-06  Uros Bizjak  <ubizjak@gmail.com>
	    H.J. Lu  <hongjiu.lu@intel.com>

	PR target/55597
	* config/i386/i386.c (legitimize_tls_address): Zero-extend x to Pmode,
	before using it as insn or call equivalent.

testsuite/ChangeLog:

2012-12-06  Uros Bizjak  <ubizjak@gmail.com>

	PR target/55597
	* gcc.target/i386/pr55597.c: New test.

Patch was bootstrapped and regression tested on x86_64-pc-linux-gnu
{,-m32} and by H.J. on x32. Patch was committed to mainline SVN, and
will be committed to 4.7.

Uros.
diff mbox

Patch

Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 194263)
+++ config/i386/i386.c	(working copy)
@@ -12785,6 +12785,9 @@  legitimize_tls_address (rtx x, enum tls_model mode
 	  tp = get_thread_pointer (Pmode, true);
 	  dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, tp, dest));
 
+	  if (GET_MODE (x) != Pmode)
+	    x = gen_rtx_ZERO_EXTEND (Pmode, x);
+
 	  set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
 	}
       else
@@ -12793,15 +12796,20 @@  legitimize_tls_address (rtx x, enum tls_model mode
 
 	  if (TARGET_64BIT)
 	    {
-	      rtx rax = gen_rtx_REG (Pmode, AX_REG), insns;
+	      rtx rax = gen_rtx_REG (Pmode, AX_REG);
+	      rtx insns;
 
 	      start_sequence ();
-	      emit_call_insn (ix86_gen_tls_global_dynamic_64 (rax, x,
-							      caddr));
+	      emit_call_insn
+		(ix86_gen_tls_global_dynamic_64 (rax, x, caddr));
 	      insns = get_insns ();
 	      end_sequence ();
 
 	      RTL_CONST_CALL_P (insns) = 1;
+
+	      if (GET_MODE (x) != Pmode)
+		x = gen_rtx_ZERO_EXTEND (Pmode, x);
+
 	      emit_libcall_block (insns, dest, rax, x);
 	    }
 	  else
@@ -12842,11 +12850,12 @@  legitimize_tls_address (rtx x, enum tls_model mode
 
 	  if (TARGET_64BIT)
 	    {
-	      rtx rax = gen_rtx_REG (Pmode, AX_REG), insns, eqv;
+	      rtx rax = gen_rtx_REG (Pmode, AX_REG);
+	      rtx insns, eqv;
 
 	      start_sequence ();
-	      emit_call_insn (ix86_gen_tls_local_dynamic_base_64 (rax,
-								  caddr));
+	      emit_call_insn
+		(ix86_gen_tls_local_dynamic_base_64 (rax, caddr));
 	      insns = get_insns ();
 	      end_sequence ();
 
@@ -12871,6 +12880,9 @@  legitimize_tls_address (rtx x, enum tls_model mode
 	{
 	  dest = force_reg (Pmode, gen_rtx_PLUS (Pmode, dest, tp));
 
+	  if (GET_MODE (x) != Pmode)
+	    x = gen_rtx_ZERO_EXTEND (Pmode, x);
+
 	  set_unique_reg_note (get_last_insn (), REG_EQUAL, x);
 	}
       break;
Index: testsuite/gcc.target/i386/pr55597.c
===================================================================
--- testsuite/gcc.target/i386/pr55597.c	(revision 0)
+++ testsuite/gcc.target/i386/pr55597.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-O2 -fPIC -mx32 -maddress-mode=long" } */
+
+struct initial_sp
+{
+  void *sp;
+  int mask;
+};
+
+__thread struct initial_sp __morestack_initial_sp;
+
+void foo (int *);
+
+void __morestack_release_segments (void)
+{
+  foo (&__morestack_initial_sp.mask);
+}