http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60556
--- Comment #16 from Steve Ellcey <sje at gcc dot gnu.org> --- It looks like this is a bug in convert_move when POINTERS_EXTEND_UNSIGNED is false. If unsignedp is false we call emit_store_flag to get 'fill_value'. Arguments 3 and 4 (op0 and op1 in emit_store_flag) are: (symbol_ref:SI ("g") [flags 0x41] <function_decl 0x7f0208e65900 g>) (const_int 0 [0]) This causes emit_store_flag to return NULL_RTX which gets passed into emit_move which causes the abort. I am testing at this patch which fixes the test case. Technically we should only need to force from into a register if it is a symbol and if unsignedp is not set but it seems cleaner to do it for all symbols. diff --git a/gcc/expr.c b/gcc/expr.c index be62c53..d065588 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -533,7 +533,8 @@ convert_move (rtx to, rtx from, int unsignedp) conversion sequence might require several references to it and we must ensure we're getting the same value every time. */ - if (MEM_P (from) || reg_overlap_mentioned_p (to, from)) + if (MEM_P (from) || GET_CODE (from) == SYMBOL_REF + || reg_overlap_mentioned_p (to, from)) from = force_reg (from_mode, from); /* Get a copy of FROM widened to a word, if necessary. */