https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87376
Georg-Johann Lay <gjl at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2018-10-11 Ever confirmed|0 |1 Known to fail| |8.0.1 --- Comment #1 from Georg-Johann Lay <gjl at gcc dot gnu.org> --- Hi Senthil, confirmed with v8.0.1 and -O2 -mmcu=atmega128 and test case extern const __memx long long a asm ("a2"); const long long b = 0x1122334455667788; const __memx long long a2 = 0x123456789abcdef1; __attribute((noinline,noclone)) long long add (void) { return a + b; } int main() { if (add() != a2 + b) __builtin_abort(); return 0; } TER propagates parameter register DI:18 into QImode subregs of DI, and we get the following insn in expand: (insn ... (parallel [ (set (reg:QI 21 r21 [+3 ]) (mem/u/c:QI (reg/f:PSI 51) [1 a+3 S1 A8 AS7])) (clobber (reg:QI 22 r22)) (clobber (reg:QI 21 r21)) (clobber (reg:HI 30 r30))])) and a similar insn for R22. R21 and R22 correspond to a+3 and a+4, respectively. The insn is xloadqi_A and emit by movqi expander. An (untested) fix is to avoid overlaps of the destination register and a clobbered register, e.g. by means of loading the destination into a new pseudo: if (!avr_xload_libgcc_p (<MODE>mode)) ... else { if (REG_P (dest) && (reg_operlaps_mentioned_p (dest, all_regs_rtx[21]) || reg_operlaps_mentioned_p (dest, gen_rtx_REG (<MODE>mode, 22)) || reg_operlaps_mentioned_p (dest, reg_z))) { // PR87376: Avoid overlaps of hard reg destination and clobber(s). rtx reg = gen_reg_rtx (<MODE>mode); emit_insn (gen_xload<mode>_A (reg, src)); emit_move_insn (dest, reg); } else emit_insn (gen_xload<mode>_A (dest, src)); }