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.

Reply via email to