> -----Original Message-----
> From: Richard Sandiford <richard.sandif...@arm.com>
> Sent: Friday, September 20, 2024 2:10 PM
> To: Tamar Christina <tamar.christ...@arm.com>
> Cc: gcc-patches@gcc.gnu.org; nd <n...@arm.com>
> Subject: Re: [PATCH 3/4][rtl]: simplify boolean vector EQ and NE comparisons
> 
> Tamar Christina <tamar.christ...@arm.com> writes:
> >> For variable-sized vectors, I suppose the question is whether the
> >> first unequal element is found in the minimum vector length, or whether
> >> it only occurs for larger lengths.  In the former case we can fold at
> >> compile time, but in the latter case we can't.
> >>
> >> So we probably do want the loop for variable-length vectors, up to
> >> constant_lower_bound (CONST_VECTOR_NUNITS (...)).
> >>
> >
> > Doesn't operand_equal already do this? it looks like the VLA handling
> > In same_vector_encodings_p rejects vectors that are not the same size,
> > which is good enough for this no? since I'm after strict equality.
> 
> But what I meant is that for VLA vectors, compile-time equality is
> a tristate value: yes, no, or maybe.
> 
> E.g.:
> 
>    { 0, 0, 0, 0, 0, 0, 0, 0, ... }
> 
> is not equal to
> 
>    { 0, 0, 1, 1, 1, 1, 1, 1, ... }
> 
> if the runtime VL gives more than 2 elements, but they are equal if
> the runtime VL gives 2 elements.  In this case, we can't fold EQ to
> false at compile time if the minimum length is 2 elements, but we can
> if the minimum length is 4 elements.
> 
> Similarly:
> 
>    { 0, 0, 1, 1, 1, 1, 1, 1, ... }
> 
> is only conditionally not equal to:
> 
>    { 0, 0, 1, 1, 2, 2, 3, 3, ... }
> 
> It isn't the case that every encoded value has to be present in every
> runtime vector.  E.g. the series { 0, 1, 2, ... } exists for VNx2DI
> (for INDEX Z0.D, #0, #1), even though there is never a "2" element for
> the minimum vector length.

Ah ok... so if I understand correctly, VLA series aren't capped by the VL
(e.g. representable values) In RTL but represent the base + step only.
So the series for a VNx2DI and a VNx4SI are the same but what the
usable bits are is determined by the mode/VL?

That's really not how I thought they were represented but get why you
want a loop now...

Tamar.

> 
> Thanks,
> Richard
> 
> >
> >
> > Bootstrapped Regtested on aarch64-none-linux-gnu, arm-none-linux-gnueabihf,
> > x86_64-pc-linux-gnu -m32, -m64 and no issues.
> >
> > Ok for master?
> >
> > Thanks,
> > Tamar
> >
> > gcc/ChangeLog:
> >
> >     * simplify-rtx.cc (simplify_context::simplify_unary_operation): Try
> >     simplifying operand.
> >     (simplify_const_relational_operation): Simplify vector EQ and NE.
> >     (test_vector_int_const_compare): New.
> >     (test_vector_ops): Use it.
> >
> >
> > -- inline copy of patch --
> >
> > diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc
> > index
> a20a61c5dddbc80b23a9489d925a2c31b2163458..8ba5864efb33ffa5d1ced99f
> 6a7d0c73e12560d5 100644
> > --- a/gcc/simplify-rtx.cc
> > +++ b/gcc/simplify-rtx.cc
> > @@ -6354,6 +6354,19 @@ simplify_const_relational_operation (enum rtx_code
> code,
> >     return 0;
> >      }
> >
> > +  /* Check if the operands are a vector EQ or NE comparison.  */
> > +  if (VECTOR_MODE_P (mode)
> > +      && INTEGRAL_MODE_P (mode)
> > +      && GET_CODE (op0) == CONST_VECTOR
> > +      && GET_CODE (op1) == CONST_VECTOR
> > +      && (code == EQ || code == NE))
> > +    {
> > +      if (rtx_equal_p (op0, op1))
> > +   return code == EQ ? const_true_rtx : const0_rtx;
> > +      else
> > +   return code == NE ? const_true_rtx : const0_rtx;
> > +    }
> > +
> >    /* We can't simplify MODE_CC values since we don't know what the
> >       actual comparison is.  */
> >    if (GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC)
> > @@ -8797,6 +8810,34 @@ test_vector_subregs (machine_mode inner_mode)
> >    test_vector_subregs_stepped (inner_mode);
> >  }
> >
> > +/* Verify vector constant comparisons for EQ and NE.  */
> > +
> > +static void
> > +test_vector_int_const_compare (machine_mode mode)
> > +{
> > +  rtx zeros = CONST0_RTX (mode);
> > +  rtx minusone = CONSTM1_RTX (mode);
> > +  rtx series_0_1 = gen_const_vec_series (mode, const0_rtx, const1_rtx);
> > +  ASSERT_RTX_EQ (const0_rtx,
> > +            simplify_const_relational_operation (EQ, mode, zeros,
> > +                                                 CONST1_RTX (mode)));
> > +  ASSERT_RTX_EQ (const_true_rtx,
> > +            simplify_const_relational_operation (EQ, mode, zeros,
> > +                                                 CONST0_RTX (mode)));
> > +  ASSERT_RTX_EQ (const_true_rtx,
> > +            simplify_const_relational_operation (EQ, mode, minusone,
> > +                                                 CONSTM1_RTX (mode)));
> > +  ASSERT_RTX_EQ (const_true_rtx,
> > +            simplify_const_relational_operation (NE, mode, zeros,
> > +                                                 CONST1_RTX (mode)));
> > +  ASSERT_RTX_EQ (const_true_rtx,
> > +            simplify_const_relational_operation (NE, mode, zeros,
> > +                                                 series_0_1));
> > +  ASSERT_RTX_EQ (const0_rtx,
> > +            simplify_const_relational_operation (EQ, mode, zeros,
> > +                                                 series_0_1));
> > +}
> > +
> >  /* Verify some simplifications involving vectors.  */
> >
> >  static void
> > @@ -8814,6 +8855,7 @@ test_vector_ops ()
> >         {
> >           test_vector_ops_series (mode, scalar_reg);
> >           test_vector_subregs (mode);
> > +         test_vector_int_const_compare (mode);
> >         }
> >       test_vec_merge (mode);
> >     }

Reply via email to