https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83758
--- Comment #26 from acsawdey at gcc dot gnu.org --- A little bit more info: It appears the parameter asmhdr in this function is at the center of this: func (tools gccgoToolchain) gc(b *Builder, a *Action, archive string, importcfg []byte, asmhdr bool, gofiles []string) (ofile string, output []byte, err error) { vt_add_function_parameter first sees this as (reg/v:DI 194 [ asmhdrD_4038 ]) but then near the top of the function is uses replace_equiv_address_nv to rewrite it as: (mem/c:QI (plus:DI (plus:DI (reg/f:DI 187) (const_int 32 [0x20])) (const_int 72 [0x48])) [8 asmhdrD_4038+0 S1 A64]) Then this piece of code in the same function gets ahold of it: lowpart = var_lowpart (mode, incoming); if (!lowpart) return; val = cselib_lookup_from_insn (lowpart, mode, true, VOIDmode, get_insns ()); /* ??? Float-typed values in memory are not handled by cselib. */ if (val) { preserve_value (val); set_variable_part (out, val->val_rtx, dv, const_offset, VAR_INIT_STATUS_INITIALIZED, NULL, INSERT); dv = dv_from_value (val->val_rtx); } if (MEM_P (incoming)) { val = cselib_lookup_from_insn (XEXP (incoming, 0), mode, true, VOIDmode, get_insns ()); if (val) { preserve_value (val); incoming = replace_equiv_address_nv (incoming, val->val_rtx); } } This preserves the whole thing at the first preserve call: (mem/c:QI (plus:DI (plus:DI (reg/f:DI 187) (const_int 32 [0x20])) (const_int 72 [0x48])) [8 asmhdrD_4038+0 S1 A64]) and this piece at the second call inside the MEM_P condition: (plus:DI (plus:DI (reg/f:DI 187) (const_int 32 [0x20])) (const_int 72 [0x48])) The expression that later causes the problem is the (reg/f:DI 187) in the center of that which is not preserved. Later when cselib_expand_value expands asmhdr, vt_expand_var_loc_chain gets called on all 3 pieces of this and throws the assert on the innermost one (reg/f:DI 187) when it sees it is not marked preserve.