On Wed, Feb 12, 2025 at 11:06 AM H.J. Lu <hjl.to...@gmail.com> wrote:
>
> On Wed, Feb 12, 2025 at 5:28 PM Uros Bizjak <ubiz...@gmail.com> wrote:
> >
> > On Wed, Feb 12, 2025 at 6:25 AM H.J. Lu <hjl.to...@gmail.com> wrote:
> > >
> > > Don't assume that stack slots can only be accessed by stack or frame
> > > registers.  We first find all registers defined by stack or frame
> > > registers.  Then check memory accesses by such registers, including
> > > stack and frame registers.
> > >
> > > gcc/
> > >
> > > PR target/109780
> > > PR target/109093
> > > * config/i386/i386.cc (ix86_update_stack_alignment): New.
> > > (ix86_find_all_reg_use): Likewise.
> > > (ix86_find_max_used_stack_alignment): Also check memory accesses
> > > from registers defined by stack or frame registers.
> > >
> > > gcc/testsuite/
> > >
> > > PR target/109780
> > > PR target/109093
> > > * g++.target/i386/pr109780-1.C: New test.
> > > * gcc.target/i386/pr109093-1.c: Likewise.
> > > * gcc.target/i386/pr109780-1.c: Likewise.
> > > * gcc.target/i386/pr109780-2.c: Likewise.
> >
> > > +/* Find all registers defined with REG.  */
> > > +
> > > +static void
> > > +ix86_find_all_reg_use (HARD_REG_SET &stack_slot_access,
> > > +               unsigned int reg, auto_bitmap &worklist)
> > > +{
> > > +  for (df_ref ref = DF_REG_USE_CHAIN (reg);
> > > +       ref != NULL;
> > > +       ref = DF_REF_NEXT_REG (ref))
> > > +    {
> > > +      if (DF_REF_IS_ARTIFICIAL (ref))
> > > +    continue;
> > > +
> > > +      rtx_insn *insn = DF_REF_INSN (ref);
> > > +      if (!NONDEBUG_INSN_P (insn))
> > > +    continue;
> > > +
> > > +      rtx set = single_set (insn);
> > > +      if (!set)
> > > +    continue;
> > > +
> >
> > Isn't the above condition a bit too limiting? We can have insn with
> > multiple sets in the chain.
> >
> > The issue at hand is the correctness issue (the program will segfault
> > if registers are not tracked correctly), not some missing
> > optimization. I'd suggest to stay on the safe side and also process
> > PARALLELs. Something similar to e.g. store_data_bypass_p from
> > recog.cc:
> >
> > --cut here--
> >   rtx set = single_set (insn);
> >   if (set)
> >     ix86_find_all_reg_use_1(...);
> >
> >   rtx pat = PATTERN (insn);
> >   if (GET_CODE (pat) != PARALLEL)
> >     return false;
> >
> >   for (int i = 0; i < XVECLEN (pat, 0); i++)
> >     {
> >       rtx exp = XVECEXP (pat, 0, i);
> >
> >       if (GET_CODE (exp) == CLOBBER || GET_CODE (exp) == USE)
> >     continue;
> >
> >       gcc_assert (GET_CODE (exp) == SET);
> >
> >       ix86_find_all_reg_use_1(...);
> >     }
> > --cut here--
> >
> > The above will make ix86_find_all_reg_use significantly more robust.
> >
> > Uros.
>
> Like this?
Yes.

Thanks,
Uros.

>
> /* Helper function for ix86_find_all_reg_use.  */
>
> static void
> ix86_find_all_reg_use_1 (rtx set, HARD_REG_SET &stack_slot_access,
>                          auto_bitmap &worklist)
> {
>   rtx src = SET_SRC (set);
>   if (MEM_P (src))
>     return;
>
>   rtx dest = SET_DEST (set);
>   if (!REG_P (dest))
>     return;
>
>   if (TEST_HARD_REG_BIT (stack_slot_access, REGNO (dest)))
>     return;
>
>   /* Add this register to stack_slot_access.  */
>   add_to_hard_reg_set (&stack_slot_access, Pmode, REGNO (dest));
>   bitmap_set_bit (worklist, REGNO (dest));
> }
>
> /* Find all registers defined with REG.  */
>
> static void
> ix86_find_all_reg_use (HARD_REG_SET &stack_slot_access,
>                        unsigned int reg, auto_bitmap &worklist)
> {
>   for (df_ref ref = DF_REG_USE_CHAIN (reg);
>        ref != NULL;
>        ref = DF_REF_NEXT_REG (ref))
>     {
>       if (DF_REF_IS_ARTIFICIAL (ref))
>         continue;
>
>       rtx_insn *insn = DF_REF_INSN (ref);
>       if (!NONDEBUG_INSN_P (insn))
>         continue;
>
>       rtx set = single_set (insn);
>       if (set)
>         ix86_find_all_reg_use_1 (set, stack_slot_access, worklist);
>
>       rtx pat = PATTERN (insn);
>       if (GET_CODE (pat) != PARALLEL)
>         continue;
>
>       for (int i = 0; i < XVECLEN (pat, 0); i++)
>         {
>           rtx exp = XVECEXP (pat, 0, i);
>
>           if (GET_CODE (exp) == CLOBBER || GET_CODE (exp) == USE)
>             continue;
>
>           gcc_assert (GET_CODE (exp) == SET);
>
>           ix86_find_all_reg_use_1 (exp, stack_slot_access, worklist);
>         }
>     }
> }
>
>
> --
> H.J.

Reply via email to