http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42894

--- Comment #17 from Jakub Jelinek <jakub at gcc dot gnu.org> 2011-01-26 
13:21:46 UTC ---
Simplified testcase:

extern __thread int t;

void
foo (int a)
{
  t = a;
}

Looking at it in detail, not sure if the bug isn't earlier.
Seems the expander isn't extra careful about rtl sharing issues and relies on
subsequent unsharing of everything.  Except that unshare_all_rtl doesn't look
at constant pool expressions.

So, a fix could be something like:
--- expr.c.jj  2011-01-18 08:44:29.000000000 +0100
+++ expr.c      2011-01-26 13:29:34.644796679 +0100
@@ -3398,7 +3398,7 @@ emit_move_insn (rtx x, rtx y)
       && (set = single_set (last_insn)) != NULL_RTX
       && SET_DEST (set) == x
       && ! rtx_equal_p (y_cst, SET_SRC (set)))
-    set_unique_reg_note (last_insn, REG_EQUAL, y_cst);
+    set_unique_reg_note (last_insn, REG_EQUAL, copy_rtx (y_cst));

   return last_insn;
 }

or e.g.:
--- varasm.c.jj        2011-01-25 12:58:41.000000000 +0100
+++ varasm.c    2011-01-26 14:07:50.635389932 +0100
@@ -3518,7 +3518,7 @@ force_const_mem (enum machine_mode mode,
   pool->offset &= ~ ((align / BITS_PER_UNIT) - 1);

   desc->next = NULL;
-  desc->constant = tmp.constant;
+  desc->constant = copy_rtx (tmp.constant);
   desc->offset = pool->offset;
   desc->hash = hash;
   desc->mode = mode;

(the latter is IMHO better).  Both fix this ICE. Perhaps if
avoid_constant_pool_reference callers want to use the result in insn stream
they need to unshare it again (at least if they use it more than once), not
sure if avoid_constant_pool_reference itself shoudl do the copy_rtx or just if
callers should take care of it.  Jeff, what do you think about this?

I've tried if copy_rtx_if_shared couldn't be itself taught about unsharing the
constants, i.e. that we wouldn't unnecessarily unshare if it wasn't used
anywhere else, but it gets quite complicated because SYMBOL_REFs should be
shared, yet we want to recurse just once on their &SYMBOL_REF_CONSTANT
(x)->constant for CONSTANT_POOL_REFERENCE_P.  In copy_rtx_if_shared it can be
coded, but not sure what to do about mark_used_flags.  I think the varasm.c
patch above shouldn't be a big deal, most constants in the constant pool can be
actually shared and thus copy_rtx on them is a nop.

Reply via email to