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.