This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Change replace_rtx if from is a REG (PR target/70245, take 2)


On Thu, Mar 17, 2016 at 01:32:15PM +0000, Joern Rennecke wrote:
> > Note that during register allocation / reload, REGNO equivalence is generally wrong,
> as it fails to distinguish between the frame pointer and a hard register that has the
> same regno as the frame pointer which has been created as a register allocation for
> a pseudo register when the frame pointer is being eliminated.
> lra_get_elimination_hard_regno actually gets this wrong (as well as the interfaces -
> there is no rtx value available, so it'd be very hard to fix), which means that targets
> can't use safely lra with frame pointer elimination and matching constraints, unless
> they use a separate soft frame pointer.
> If you want to decide automagically if you'd run into an ambiguity with register
> elimination, you have to check if either side of the comparison appears in
> regs_eliminate_1[i].from for 0 <= i < ARRAY_SIZE(regs_eliminate_1) .
> Unfortunately, although rarely encountered, it is possible to use the frame pointer
> in a mode other than Pmode, and once cleanup_subreg_operands is done with such
> a reference, an equality check with frame_pointer_rtx will fail.

Sure.  Which is why the trunk now uses the old behavior of replace_rtx
unless you ask for different one through extra argument.

In epiphany.md, I see
(define_peephole2
  [(parallel [(set (match_operand:WMODE 0 "gpr_operand" "")
                   (match_operand:WMODE 1 "" ""))
              (clobber (match_operand 8 "cc_operand"))])
   (match_operand 2 "" "")
   (set (match_operand:WMODE2 3 "gpr_operand" "")
        (match_operand:WMODE2 9 "gpr_operand" ""))
   (set (match_dup 3)
        (if_then_else:WMODE2 (match_operator 5 "proper_comparison_operator"
                               [(match_operand 6 "cc_operand")
                                (match_operand 7 "const0_operand")])
                             (match_operand:WMODE2 4 "nonmemory_operand" "")
                             (match_dup 3)))]
  "REGNO (operands[0]) == REGNO (operands[9])
   && peep2_reg_dead_p (3, operands[0])
   && !reg_set_p (operands[0], operands[2])
   && !reg_set_p (operands[3], operands[2])
   && !reg_overlap_mentioned_p (operands[3], operands[2])"
  [(parallel [(set (match_dup 10) (match_dup 1))
              (clobber (match_dup 8))])
   (match_dup 2)
   (set (match_dup 3)
        (if_then_else:WMODE2 (match_dup 5) (match_dup 4) (match_dup 3)))]
{
  operands[10] = simplify_gen_subreg (<WMODE:MODE>mode, operands[3],
                                      <WMODE2:MODE>mode, 0);
  replace_rtx (operands[2], operands[9], operands[3]);
  replace_rtx (operands[2], operands[0], operands[10]);
  gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[2]));
})
and peephole2s are after RA, and I bet you rely on the replacements to be done no matter
if there is pointer equality or just REGNO equality (and, can there be different modes
or just one?).  sh.md has something similar.

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]