On Thu, Jan 27, 2022 at 2:59 PM Maciej W. Rozycki <ma...@embecosm.com> wrote:
>
> On Thu, 27 Jan 2022, Richard Biener wrote:
>
> > > Index: gcc/gcc/c/c-typeck.cc
> > > ===================================================================
> > > --- gcc.orig/gcc/c/c-typeck.cc
> > > +++ gcc/gcc/c/c-typeck.cc
> > > @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.
> > >  #include "gomp-constants.h"
> > >  #include "spellcheck-tree.h"
> > >  #include "gcc-rich-location.h"
> > > +#include "optabs-query.h"
> > >  #include "stringpool.h"
> > >  #include "attribs.h"
> > >  #include "asan.h"
> > > @@ -11923,7 +11924,9 @@ build_binary_op (location_t location, en
> > >                bool maybe_const = true;
> > >                tree sc;
> > >                sc = c_fully_fold (op0, false, &maybe_const);
> > > -              sc = save_expr (sc);
> > > +             if (optab_handler (vec_duplicate_optab,
> > > +                                TYPE_MODE (type1)) == CODE_FOR_nothing)
> > > +               sc = save_expr (sc);
> >
> > This doesn't make much sense - I suppose the CONSTRUCTOR retains
> > TREE_SIDE_EFFECTS but such flag has no meaning on GIMPLE
> > and thus should have been cleared during gimplification or in the end
> > ignored by RTL expansion.
>
>  This is how the expression built here eventually looks in
> `store_constructor':
>
> (gdb) print exp
> $41 = <constructor 0x7ffff5c06ba0>
> (gdb) pt
>  <constructor 0x7ffff5c06ba0
>     type <vector_type 0x7ffff5e7ea48 v4sf
>         type <real_type 0x7ffff5cf1260 float sizes-gimplified SF
>             size <integer_cst 0x7ffff5c00f78 constant 32>
>             unit-size <integer_cst 0x7ffff5c00f90 constant 4>
>             align:32 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
> 0x7ffff5cf1260 precision:32
>             pointer_to_this <pointer_type 0x7ffff5cf1848>>
>         sizes-gimplified V4SF
>         size <integer_cst 0x7ffff5c00d80 constant 128>
>         unit-size <integer_cst 0x7ffff5c00d98 constant 16>
>         align:128 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 
> 0x7ffff5d19648 nunits:4 context <translation_unit_decl 0x7ffff5ec0bb8 
> v4sf-dup.c>>
>     side-effects length:4
>     val <ssa_name 0x7ffff5cb0dc8 type <real_type 0x7ffff5cf1260 float>
>         visited var <parm_decl 0x7ffff5f00080 y>
>         def_stmt GIMPLE_NOP
>         version:2>
>     val <ssa_name 0x7ffff5cb0dc8 type <real_type 0x7ffff5cf1260 float>
>         visited var <parm_decl 0x7ffff5f00080 y>
>         def_stmt GIMPLE_NOP
>         version:2>
>     val <ssa_name 0x7ffff5cb0dc8 type <real_type 0x7ffff5cf1260 float>
>         visited var <parm_decl 0x7ffff5f00080 y>
>         def_stmt GIMPLE_NOP
>         version:2>
>     val <ssa_name 0x7ffff5cb0dc8 type <real_type 0x7ffff5cf1260 float>
>         visited var <parm_decl 0x7ffff5f00080 y>
>         def_stmt GIMPLE_NOP
>         version:2>>
> (gdb)
>
> The `side-effects' flag prevents this conditional from executing:
>
>         /* Try using vec_duplicate_optab for uniform vectors.  */
>         if (!TREE_SIDE_EFFECTS (exp)
>             && VECTOR_MODE_P (mode)
>             && eltmode == GET_MODE_INNER (mode)
>             && ((icode = optab_handler (vec_duplicate_optab, mode))
>                 != CODE_FOR_nothing)
>             && (elt = uniform_vector_p (exp))
>             && !VECTOR_TYPE_P (TREE_TYPE (elt)))
>           {
>             class expand_operand ops[2];
>             create_output_operand (&ops[0], target, mode);
>             create_input_operand (&ops[1], expand_normal (elt), eltmode);
>             expand_insn (icode, 2, ops);
>             if (!rtx_equal_p (target, ops[0].value))
>               emit_move_insn (target, ops[0].value);
>             break;
>           }
>
> I don't know what's supposed to clear the flag (and what the purpose of
> setting it in the first place would be then).

It's probably safe to remove the !TREE_SIDE_EFFECTS check above
but already gimplification should have made sure all side-effects are
pushed to separate stmts.  gimplifiation usually calls recompute_side_effects
but that doesn't seem to touch CONSTRUCTORs.  But I do remember fixing
some spurious TREE_SIDE_EFFECTS on CTORs before.

Might be worth verifying in verify_gimple_assign_single that CTORs
do not have TREE_SIDE_EFFECTS set (unless this is a clobber).

>
> > You do not add a testcase so it's hard to see what goes wrong where exactly.
>
>  This only happens with an out-of-tree microarchitecture and I was unable
> to find an in-tree target that ever uses the `vec_duplicateM' standard RTL
> pattern, so I wasn't able to produce a test case that would trigger with
> upstream code.  Code is essentially like:
>
> typedef float v4sf __attribute__ ((vector_size (16)));
>
> v4sf
> odd_even (v4sf x, float y)
> {
>   return x + f;
> }
>
>  I considered the Aarch64 one the most likely candidate as it is the one
> commit be4c1d4a42c5 has been for, but as I noted in the description it
> does not appear to use it either.  It uses `vec_initMN' instead and does
> the broadcast by hand in the backend.
>
>  Maybe I'm missing something.
>
>   Maciej

Reply via email to