On Thu, 2015-01-08 at 14:18 -0700, Jeff Law wrote:
> On 01/08/15 05:23, Oleg Endo wrote:
> > Hi,
> >
> > Currently reg_set_p doesn't handle sequence rtx, which I've identified
> > as the root cause of PR 64479. There is another alternative fix for the
> > PR, but I'd like to get some comments regarding letting reg_set_p also
> > handle sequence rtx:
> >
> > Index: gcc/rtlanal.c
> > ===================================================================
> > --- gcc/rtlanal.c (revision 218544)
> > +++ gcc/rtlanal.c (working copy)
> > @@ -875,17 +875,24 @@
> > {
> > /* We can be passed an insn or part of one. If we are passed an insn,
> > check if a side-effect of the insn clobbers REG. */
> > - if (INSN_P (insn)
> > - && (FIND_REG_INC_NOTE (insn, reg)
> > - || (CALL_P (insn)
> > - && ((REG_P (reg)
> > - && REGNO (reg) < FIRST_PSEUDO_REGISTER
> > - && overlaps_hard_reg_set_p (regs_invalidated_by_call,
> > - GET_MODE (reg), REGNO (reg)))
> > - || MEM_P (reg)
> > - || find_reg_fusage (insn, CLOBBER, reg)))))
> > - return 1;
> > + if (INSN_P (insn) && FIND_REG_INC_NOTE (insn, reg))
> > + return true;
> >
> > + /* After delay slot handling, call and branch insns might be in a
> > + sequence. Check all the elements there. */
> > + if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
> > + for (int i = 0; i < XVECLEN (PATTERN (insn), 0); ++i)
> > + if (reg_set_p (reg, XVECEXP (PATTERN (insn), 0, i)))
> > + return true;
> > +
> > + if (CALL_P (insn)
> > + && ((REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER
> > + && overlaps_hard_reg_set_p (regs_invalidated_by_call,
> > + GET_MODE (reg), REGNO (reg)))
> > + || MEM_P (reg)
> > + || find_reg_fusage (insn, CLOBBER, reg)))
> > + return true;
> > +
> > return set_of (reg, insn) != NULL_RTX;
> > }
> >
> >
> > Would that be OK to do if it passes testing, or is there something that
> > could potentially/obviously blow up?
> It looks reasonable to me.
>
> Any particular reason why the SEQUENCE handling isn't done first, then
> the REG_INC and CALL insn handling? I'd probably explicitly return
> false if we had a sequence and none of its elements returned true.
> There's no need to check anything on the toplevel SEQUENCE to the best
> of my knowledge.
No meaningful reason. Attached is an updated patch that applies on 4.8
and trunk. Bootstrapped on trunk i686-pc-linux-gnu. Tested with make
-k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}" on trunk
sh-elf. In the PR it has been reported, that the patch fixes the
problems when building a native SH GCC.
Although the related SH problem occurs only on 4.8, I'd like to install
this on trunk and 4.9, too, to avoid future surprises. OK?
Cheers,
Oleg
gcc/ChangeLog:
PR target/64479
* rtlanal.c (set_reg_p): Handle SEQUENCE constructs.
Index: gcc/rtlanal.c
===================================================================
--- gcc/rtlanal.c (revision 218544)
+++ gcc/rtlanal.c (working copy)
@@ -873,6 +873,17 @@
int
reg_set_p (const_rtx reg, const_rtx insn)
{
+ /* After delay slot handling, call and branch insns might be in a
+ sequence. Check all the elements there. */
+ if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
+ {
+ for (int i = 0; i < XVECLEN (PATTERN (insn), 0); ++i)
+ if (reg_set_p (reg, XVECEXP (PATTERN (insn), 0, i)))
+ return true;
+
+ return false;
+ }
+
/* We can be passed an insn or part of one. If we are passed an insn,
check if a side-effect of the insn clobbers REG. */
if (INSN_P (insn)
@@ -884,7 +895,7 @@
GET_MODE (reg), REGNO (reg)))
|| MEM_P (reg)
|| find_reg_fusage (insn, CLOBBER, reg)))))
- return 1;
+ return true;
return set_of (reg, insn) != NULL_RTX;
}