https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91386

--- Comment #15 from Richard Earnshaw <rearnsha at gcc dot gnu.org> ---
From looking at the dumps it would appear that one of the STP generating
peepholes might have bailed out, but that some of the changes have not been
undone.

From the pass before, we have:

(insn/f:TI 8028 8027 8029 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 672 [0x2a0])) [17  S8 A8])
        (reg:DI 25 x25)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 25 x25)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 672 [0x2a0])) [17  S8 A8])
                (reg:DI 25 x25))
            (nil))))
(insn/f 8029 8028 8030 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 680 [0x2a8])) [17  S8 A8])
        (reg:DI 26 x26)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 26 x26)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 680 [0x2a8])) [17  S8 A8])
                (reg:DI 26 x26))
            (nil))))
(insn/f:TI 8030 8029 8031 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 688 [0x2b0])) [17  S8 A8])
        (reg:DI 27 x27)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 27 x27)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 688 [0x2b0])) [17  S8 A8])
                (reg:DI 27 x27))
            (nil))))
(insn/f 8031 8030 8303 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 696 [0x2b8])) [17  S8 A8])
        (reg:DI 28 x28)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 28 x28)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 696 [0x2b8])) [17  S8 A8])
                (reg:DI 28 x28))

Which looks like a perfect candidate for replacing with two STP instructions.

After peepholing, we have:

(insn/f:TI 8028 8027 8029 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 672 [0x2a0])) [17  S8 A8])
        (reg:DI 25 x25)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 25 x25)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 672 [0x2a0])) [17  S8 A8])
                (reg:DI 25 x25))
            (nil))))
(insn/f 8029 8028 8030 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 680 [0x2a8])) [17  S8 A8])
        (reg:DI 26 x26)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 26 x26)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 680 [0x2a8])) [17  S8 A8])
                (reg:DI 26 x26))
            (nil))))
(insn/f:TI 8030 8029 8031 4 (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                (const_int 688 [0x2b0])) [17  S8 A8])
        (reg:DI 27 x27)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 27 x27)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 688 [0x2b0])) [17  S8 A8])
                (reg:DI 27 x27))
            (nil))))
(insn/f 8031 8030 8303 4 (set (mem/c:DI (reg:DI 7 x7) [17  S8 A8])
        (reg:DI 28 x28)) 47 {*movdi_aarch64}
     (expr_list:REG_DEAD (reg:DI 28 x28)
        (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 31 sp)
                        (const_int 696 [0x2b8])) [17  S8 A8])
                (reg:DI 28 x28))
            (nil))))

And we can see that the last insn has been modified.  There's nothing earlier
in the log to suggest that there was any substitution here.

My suspicion is this hunk:

  replace_equiv_address_nv (mem_1, plus_constant (Pmode, operands[8],
                                                  new_off_1), true);
  replace_equiv_address_nv (mem_2, plus_constant (Pmode, operands[8],
                                                  new_off_1 + msize), true);
  replace_equiv_address_nv (mem_3, plus_constant (Pmode, operands[8],
                                                  new_off_3), true);
  replace_equiv_address_nv (mem_4, plus_constant (Pmode, operands[8],
                                                  new_off_3 + msize), true);

  if (!aarch64_mem_pair_operand (mem_1, mode)
      || !aarch64_mem_pair_operand (mem_3, mode))
    return false;

Is somehow modifying the insn in-place, but then the test is failing somehow.

Reply via email to