https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82445
Richard Biener <rguenth at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2017-10-06 Ever confirmed|0 |1 --- Comment #3 from Richard Biener <rguenth at gcc dot gnu.org> --- To answer myself, yes, -fno-store-merging fixes it. RTL expansion is ok: ;; MEM[(void *)unknown_glyph.0_1 + 4B] = 1048584; (insn 7 6 8 (set (reg:SI 112) (const_int 1048584 [0x100008])) "strd.c":50 -1 (nil)) (insn 8 7 0 (set (mem:SI (plus:SI (reg/f:SI 110 [ unknown_glyph.0_1 ]) (const_int 4 [0x4])) [0 MEM[(void *)unknown_glyph.0_1 + 4B]+0 S4 A32]) (reg:SI 112)) "strd.c":50 -1 (nil)) ;; MEM[(void *)unknown_glyph.0_1 + 8B] = 4294770688; (insn 9 8 10 (set (reg:SI 113) (const_int -196608 [0xfffffffffffd0000])) "strd.c":51 -1 (nil)) (insn 10 9 0 (set (mem:SI (plus:SI (reg/f:SI 110 [ unknown_glyph.0_1 ]) (const_int 8 [0x8])) [0 MEM[(void *)unknown_glyph.0_1 + 8B]+0 S4 A32]) (reg:SI 113)) "strd.c":51 -1 (nil)) ;; MEM[(void *)unknown_glyph.0_1 + 12B] = 8; (insn 11 10 12 (set (reg:SI 115) (const_int 8 [0x8])) "strd.c":53 -1 (nil)) (insn 12 11 13 (set (reg:HI 114) (subreg:HI (reg:SI 115) 0)) "strd.c":53 -1 (expr_list:REG_EQUAL (const_int 8 [0x8]) (nil))) (insn 13 12 0 (set (mem:HI (plus:SI (reg/f:SI 110 [ unknown_glyph.0_1 ]) (const_int 12 [0xc])) [0 MEM[(void *)unknown_glyph.0_1 + 12B]+0 S2 A32]) (reg:HI 114)) "strd.c":53 -1 (nil)) The DI move is introduced by peephole2: Splitting with gen_peephole2_12 which is ldrdstrd.md: (define_peephole2 ; strd [(set (match_operand:SI 2 "memory_operand" "") (match_operand:SI 0 "arm_general_register_operand" "")) (set (match_operand:SI 3 "memory_operand" "") (match_operand:SI 1 "arm_general_register_operand" ""))] "TARGET_LDRD" [(const_int 0)] { if (!gen_operands_ldrd_strd (operands, false, false, false)) FAIL; else if (TARGET_ARM) { /* In ARM state, the destination registers of LDRD/STRD must be consecutive. We emit DImode access. */ operands[0] = gen_rtx_REG (DImode, REGNO (operands[0])); operands[2] = adjust_address (operands[2], DImode, 0); /* Emit [(set (match_dup 2) (match_dup 0))] */ emit_insn (gen_rtx_SET (operands[2], operands[0])); DONE; } else if (TARGET_THUMB2) { /* Emit the pattern: [(parallel [(set (match_dup 2) (match_dup 0)) (set (match_dup 3) (match_dup 1))])] */ rtx t1 = gen_rtx_SET (operands[2], operands[0]); rtx t2 = gen_rtx_SET (operands[3], operands[1]); emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, t1, t2))); DONE; } }) but this doesn't at all consider alignment of the MEMs it merges.