On Mon, Feb 21, 2022 at 9:31 AM Roger Sayle <ro...@nextmovesoftware.com> wrote:
>
>
> Hi Marc,
> I'm assuming that the use (semantics) of a REDUC_PLUS expr allow the
> reduction to be done in any order, for example the testcase requires
> -ffast-math to allow the REDUC_PLUS to be introduced in the first place.
> This also applies explains why the patch doesn't need to distinguish
> negative zeros from positive zeros in ctor_single_nonzero_element
> (but it's perhaps something to beware of in uses of VECTOR_CST's
> single_nonzero_element).

.IFN_REDUC_PLUS directly maps to the reduc_plus_scal optab
which does not specify an operation order.  There's also
fold_left_plus which does (left-to-right).

An argument could be made that constant folding should do what
the CPU will end up doing but we're already not doing that for
double arithmetic and flush-to-zero enabled with -ffast-math and
denormals I think.

+/* Return the single non-zero element of a CONSTRUCTOR or NULL_TREE.  */
+tree
+ctor_single_nonzero_element (const_tree t)
+{
+  unsigned HOST_WIDE_INT idx;
+  constructor_elt *ce;
+  tree elt = NULL_TREE;
+
+  if (TREE_CODE (t) == SSA_NAME)
+    {
+      gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (t));

I think this function should expect a CONSTRUCTOR 'T' and the use in
match.pd be adjusted similar to other CONSTRUCTOR users like

(simplify
 (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)
...
  (with
   {
     tree ctor = (TREE_CODE (@0) == SSA_NAME
                  ? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0);


+/* Fold reduction of a single nonzero element constructor.  */
+(for reduc (IFN_REDUC_PLUS IFN_REDUC_IOR IFN_REDUC_XOR)
+  (simplify (reduc (CONSTRUCTOR@0))
+    (with { tree elt = ctor_single_nonzero_element (@0); }
+      (if (elt)
+        (non_lvalue { elt; })))))

is (non_value... ) really necessary?  I highly doubt so.

I wonder if there's a case like { _1, 0., 0., -0. } where independent on
the order of the operations this transform relies on !HONOR_SIGNED_ZEROS?
It likely also should demote _1 from sNaN to qNaN and thus relies on
-fno-signalling-nans?

Otherwise OK.

Thanks,
Richard.

> Cheers,
> Roger
> --
>
> > -----Original Message-----
> > From: Marc Glisse <marc.gli...@inria.fr>
> > Sent: 21 February 2022 08:21
> > To: Roger Sayle <ro...@nextmovesoftware.com>
> > Cc: gcc-patches@gcc.gnu.org
> > Subject: Re: [PATCH] Implement constant-folding simplifications of
> reductions.
> >
> > On Mon, 21 Feb 2022, Roger Sayle wrote:
> >
> > > +/* Fold REDUC (@0 op VECTOR_CST) as REDUC (@0) op REDUC
> > (VECTOR_CST).
> > > +*/ (for reduc (IFN_REDUC_PLUS IFN_REDUC_MAX IFN_REDUC_MIN
> > IFN_REDUC_FMAX
> > > +            IFN_REDUC_FMIN IFN_REDUC_AND IFN_REDUC_IOR
> > IFN_REDUC_XOR)
> > > +     op (plus max min IFN_FMAX IFN_FMIN bit_and bit_ior bit_xor)
> > > +  (simplify (reduc (op @0 VECTOR_CST@1))
> > > +    (op (reduc:type @0) (reduc:type @1))))
> >
> > I wonder if we need to test flag_associative_math for the 'plus' case, or
> if the
> > presence of IFN_REDUC_PLUS is enough to justify the possible loss of
> precision.
> >
> > --
> > Marc Glisse
>

Reply via email to