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

--- Comment #31 from Matthew Malcomson <matmal01 at gcc dot gnu.org> ---
(In reply to Jakub Jelinek from comment #30)
> (In reply to Matthew Malcomson from comment #29)
> > I've been working on a patch that does very similar to the draft patch 
> > posted
> > above, and I notice a few things I've tried to avoid in it.
> > I doubt there are any actual bugs, since I don't know if the patterns that
> > trigger actual faults can occur at the moment.
> > 
> > --------
> > 
> > Using the `address_operand` predicate and 'p' constraint to ensure the
> > address
> > is a valid address would use the mode SImode of the operand rather than
> > checking
> > it's valid for the DImode of the emitted ldrd.
> 
> Sure, but does it really matter?
> This is a post reload pattern created by the peephole2s, so nothing that can
> be matched out of the blue sky like combiner normally matches.
> So, if it didn't pass the conditions in the peephole2s, the patterns
> wouldn't be created.

True -- as I mentioned I don't know if a problematic pattern could actually
occur, so I doubt this is actually a problem.

> Are there any addresses that pass arm_legitimate_address_p (DImode, x, true)
> and fail address_operand (x, SImode)?  From brief skimming I couldn't find
> anything.
> So, would you be happy if the && arm_legitimate_address_p (DImode, XEXP
> (operands[n], 0), true)
> condition is added to the insn conditions (after the rtx_equal_p check)?

That sounds good to me.

> 
> > There's a similar problem to the `address_operand` one above with using the
> > `arm_count_output_move_double_insns` function.
> > 
> > It's called on the original operands, which means it eventually calls
> > `output_move_double` with the first two operands (which are in SImode).
> > 
> > This function has some calls to `reg_overlap_mentioned_p`, which depends on
> > the
> > number of hard registers for a given registers mode.
> > 
> > I've only found cases where the `arm_count_output_move_double_insns` 
> > function
> > returns something other than what it should in cases that only match because
> > of
> > the `address_operand` problem above.
> > 
> > This could be replaced by a wrapper that generates DImode registers
> > specifically
> > for checking this.
> 
> For non-vfp or iwmmxt, the length is always 8, are there cases in the vfp
> insn that the length is not 8?

I believe the length *can* be 4 non-vfp, vfp, or iwmmxt (the case below
produces a single ldrd when compiled with each of them).

int __RTL (startwith ("peephole2")) foo_x4 (int *a)
{
(function "foo_x4"
  (insn-chain
    (cnote 1 NOTE_INSN_DELETED)
    (block 2
      (edge-from entry (flags "FALLTHRU"))
      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
      (cinsn 101 (set (reg:SI r2)
                      (mem/c:SI (plus:SI (reg:SI r0) (const_int 8)) [0 S4
A64])) "/home/matmal01/test.c":18)
      (cinsn 102 (set (reg:SI r3)
                      (mem/c:SI (plus:SI (reg:SI r0) (const_int 12)) [0 S4
A32])) "/home/matmal01/test.c":18)
      (cinsn 103 (set (reg:SI r0)
                      (plus:SI (reg:SI r2) (reg:SI r3)))
"/home/matmal01/test.c":18)
      (edge-to exit (flags "FALLTHRU"))
    ) ;; block 2
  ) ;; insn-chain
  (crtl
    (return_rtx 
      (reg/i:SI r0)
    ) ;; return_rtx
  ) ;; crtl
) ;; function "main"
}




Something else I've just noticed:
When compiling for vfp or iwmmxt, the ldm2_ define_insn matches the simpler
case below as it comes first in the md order.
That means we get a ldm instruction instead of the ldrd.

int __RTL (startwith ("peephole2")) foo_x5 (int *a)
{
(function "foo_x5"
  (insn-chain
    (cnote 1 NOTE_INSN_DELETED)
    (block 2
      (edge-from entry (flags "FALLTHRU"))
      (cnote 3 [bb 2] NOTE_INSN_BASIC_BLOCK)
      (cinsn 101 (set (reg:SI r2)
                      (mem/c:SI (reg:SI r0) [0 S4 A64]))
"/home/matmal01/test.c":18)
      (cinsn 102 (set (reg:SI r3)
                      (mem/c:SI (plus:SI (reg:SI r0) (const_int 4)) [0 S4
A32])) "/home/matmal01/test.c":18)
      (cinsn 103 (set (reg:SI r0)
                      (plus:SI (reg:SI r2) (reg:SI r3)))
"/home/matmal01/test.c":18)
      (edge-to exit (flags "FALLTHRU"))
    ) ;; block 2
  ) ;; insn-chain
  (crtl
    (return_rtx 
      (reg/i:SI r0)
    ) ;; return_rtx
  ) ;; crtl
) ;; function "main"
}

Reply via email to