Hi Wilco,

> On 12 Aug 2026, at 18:59, Wilco Dijkstra <[email protected]> wrote:
> 
> Hi Kyrill,
> 
>> SVE2 does the whole thing in far fewer instructions and, being
>> vector-length agnostic, keeps scaling on implementations wider than
>> 128 bits.  Every 128-bit segment of the needle vector holds the four
>> characters, so a single MATCH reports set membership for the whole
>> vector, and MATCH sets the condition flags directly, so the loop branch
>> needs no reduction.  BRKB and INCP then convert the result predicate
>> straight into a pointer increment.
> 
> Looks great now - just 2 minor things below (but it's fine for commit either 
> way).
> 
> You might also want to try out my optimized AdvSIMD version at
> https://gcc.gnu.org/pipermail/gcc-patches/2026-August/727347.html :-)

Great! I’ll have a look.

> 
> Cheers,
> Wilco
> 
> +static const uchar * __attribute__ ((target ("+sve2")))
> +search_line_sve2 (const uchar *s, const uchar *end)
> +{
> +  /* Order within a segment is irrelevant to MATCH, which tests set
> +     membership, so this needs no adjustment for big-endian.  */
> +  const uint32_t chars = ((uint32_t) '\n' | ((uint32_t) '\r' << 8)
> +                         | ((uint32_t) '\\' << 16) | ((uint32_t) '?' << 24));
> +  const svuint8_t needles = svreinterpret_u8_u32 (svdup_n_u32 (chars));
> +  const svbool_t all = svptrue_b8 ();
> +  const uint64_t vl = svcntb ();
> +  svuint8_t data;
> +  svbool_t match;
> +  uintptr_t limit;
> +
> +  /* The last address from which a whole vector still lies below END.
> +     Computed on integers so that a buffer shorter than a vector simply
> +     skips the loop.  */
> +  limit = (uintptr_t) end;
> +  limit = limit >= vl ? limit - vl : 0;
> 
> Why not: limit = (uintptr_t) end & -vl; ?
> 
> That's simpler and allows the loop to process 0.5VL more data near the end.
> 
> +  while ((uintptr_t) s <= limit)
> +    {
> +      data = svld1_u8 (all, s);
> +      match = svmatch_u8 (all, data, needles);
> +      if (svptest_any (all, match))
> +       return s + svcntp_b8 (all, svbrkb_b_z (all, match));
> +      s += vl;
> +    }
> +
> +  /* What is left, up to and including *END, which _cpp_convert_input
> +     forces to a newline.  That guarantees a match, so no further test is
> +     needed.  */
> +  svbool_t pg = svwhilele_b8_u64 ((uint64_t) (uintptr_t) s,
> +                                 (uint64_t) (uintptr_t) end);
> 
> Why the double casting? It could just be svwhilele_b8_u64 ((uintptr_t) s, 
> (uintptr_t) end);

Thanks, I’ve adjusted both and pushed as 
ad3f5b0855ef5f3efd6b0a13c29f98cdbf598eb7
Kyrill

> 
> +  data = svld1_u8 (pg, s);
> +  match = svmatch_u8 (pg, data, needles);
> +  return s + svcntp_b8 (pg, svbrkb_b_z (pg, match));
> +}

Reply via email to