Ping.

Also CC'ing Andrea, could you please take a look if possible? 

Thanks,
Soumya

On on Tue, 16 Jun 2026 10:54:37 +0000, Soumya AR <[email protected]> wrote:
> Ping.
> 
> Thanks,
> Soumya
> 
>> On 8 Jun 2026, at 11:23 PM, Soumya AR <[email protected]> wrote:
>> 
>> Ping.
>> 
>> Thanks,
>> Soumya
>> 
>>> On 26 May 2026, at 2:24 PM, Soumya AR <[email protected]> wrote:
>>> 
>>> Hi,
>>> 
>>> Reviving this patch because it completely slipped my mind and has been 
>>> sitting
>>> in limbo ever since.
>>> 
>>> I'll try to summarize the discussion for some context:
>>> 
>>> This patch teaches expand_divmod to dispatch through the sdiv_pow2 optab for
>>> vector pow2 divisions, so that
>>> 
>>> svint32_t bar (svint32_t x) { return x / 4; }
>>> 
>>> emits a single ASRD instead of a vector SDIV. ASRD on SVE performs signed
>>> division by an arithmetic shift right that rounds toward zero.
>>> 
>>> The autovectorizer already uses this optab via vect_recog_divmod_pattern; 
>>> this
>>> extends the same mechanism to the non-vectorizer path.
>>> 
>>> There are a couple of backend approaches we could've taken: 
>>> 
>>> - make expand_divmod emit the shift sequence for vector pow2 divisions 
>>> (similar
>>> to how it handles scalars) and and rely on combine to recognize it back into
>>> ASRD.
>>> 
>>> - extend the SVE SDIV pattern to accept immediates and emit ASRD for pow2.
>>> 
>>> But those feel less clean given we have a dedicated optab (and that it 
>>> would be
>>> neater to be consistent with the autovectorizer approach).
>>> 
>>> Note that this also applies to Adv. SIMD vectors on SVE targets, since the
>>> AArch64 backend exposes sdiv_pow2 for Adv. SIMD modes.
>>> 
>>> For example, both:
>>> 
>>> int32x4_t
>>> foo (int32x4_t x)
>>> {
>>> return x / 4;
>>> }
>>> 
>>> and 
>>> 
>>> svint32_t
>>> bar (svint32_t x)
>>> {
>>> return x / 4;
>>> }
>>> 
>>> currently generate DIV, but can be done using ASRD.
>>> 
>>> The patch was bootstrapped and regtested on aarch64-linux-gnu, no 
>>> regression.
>>> OK for trunk?
>>> 
>>> Signed-off-by: Soumya AR <[email protected]>
>>> 
>>> gcc/ChangeLog:
>>> 
>>> * expmed.cc (expand_divmod): Expand to sdiv_pow2 optab for vectors.
>>> 
>>> gcc/testsuite/ChangeLog:
>>> 
>>> * gcc.target/aarch64/sve/sve-asrd-2.c: New test.
>>> ---
>>> gcc/expmed.cc                                 | 21 ++++++
>>> .../gcc.target/aarch64/sve/sve-asrd-2.c       | 74 +++++++++++++++++++
>>> 2 files changed, 95 insertions(+)
>>> create mode 100644 gcc/testsuite/gcc.target/aarch64/sve/sve-asrd-2.c
>>> 
>>> diff --git a/gcc/expmed.cc b/gcc/expmed.cc
>>> index fe39506b6bd..ef12420689f 100644
>>> --- a/gcc/expmed.cc
>>> +++ b/gcc/expmed.cc
>>> @@ -4487,6 +4487,27 @@ expand_divmod (int rem_flag, enum tree_code code, 
>>> machine_mode mode,
>>>      {
>>>      case TRUNC_MOD_EXPR:
>>>      case TRUNC_DIV_EXPR:
>>> + if (CONST_VECTOR_P (op1)
>>> +    && optab_handler (sdiv_pow2_optab, mode) != CODE_FOR_nothing)
>>> +  {
>>> +    rtx scalar_op1;
>>> +    if (const_vec_duplicate_p (op1, &scalar_op1)
>>> + && CONST_INT_P (scalar_op1))
>>> +      {
>>> + HOST_WIDE_INT d = INTVAL (scalar_op1);
>>> + if (d > 0 && pow2p_hwi (d))
>>> +  {
>>> +    rtx shift_amount
>>> +      = gen_const_vec_duplicate (mode,
>>> + GEN_INT (floor_log2 (d)));
>>> +    rtx result
>>> +      = expand_binop (mode, sdiv_pow2_optab, op0, shift_amount,
>>> +      target, unsignedp, methods);
>>> +    if (result)
>>> +      return result;
>>> +  }
>>> +      }
>>> +  }
>>> if (op1_is_constant)
>>> {
>>>   scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);
>>> diff --git a/gcc/testsuite/gcc.target/aarch64/sve/sve-asrd-2.c 
>>> b/gcc/testsuite/gcc.target/aarch64/sve/sve-asrd-2.c
>>> new file mode 100644
>>> index 00000000000..a5163421a69
>>> --- /dev/null
>>> +++ b/gcc/testsuite/gcc.target/aarch64/sve/sve-asrd-2.c
>>> @@ -0,0 +1,74 @@
>>> +/* { dg-do compile } */
>>> +/* { dg-additional-options "-O3" } */
>>> +/* { dg-final { check-function-bodies "**" "" "" } } */
>>> +
>>> +#include <arm_sve.h>
>>> +
>>> +#define FOO(type) \
>>> +type foo_##type(type x) { \
>>> +  return x / 8; \
>>> +}
>>> +
>>> +/*
>>> +** foo_int32x4_t:
>>> +**     ptrue (p[0-7]).b, vl16
>>> +**     asrd z[0-9]+\.s, \1/m, z[0-9]+\.s, #3
>>> +**     ret
>>> +*/
>>> +FOO(int32x4_t)
>>> +
>>> +/*
>>> +** foo_int64x2_t:
>>> +**     ptrue (p[0-7]).b, vl16
>>> +**     asrd z[0-9]+\.d, \1/m, z[0-9]+\.d, #3
>>> +**     ret
>>> +*/
>>> +FOO(int64x2_t)
>>> +
>>> +/*
>>> +** foo_svint32_t:
>>> +**     ptrue (p[0-7]).b, all
>>> +**     asrd z[0-9]+\.s, \1/m, z[0-9]+\.s, #3
>>> +**     ret
>>> +*/
>>> +FOO(svint32_t)
>>> +
>>> +/*
>>> +** foo_svint64_t:
>>> +**     ptrue (p[0-7]).b, all
>>> +**     asrd z[0-9]+\.d, \1/m, z[0-9]+\.d, #3
>>> +**     ret
>>> +*/
>>> +FOO(svint64_t)
>>> +
>>> +/*
>>> +** foo_uint32x4_t:
>>> +**     ptrue (p[0-7]).b, vl16
>>> +**     asrd z[0-9]+\.s, \1/m, z[0-9]+\.s, #3
>>> +**     ret
>>> +*/
>>> +FOO(uint32x4_t)
>>> +
>>> +/*
>>> +** foo_uint64x2_t:
>>> +**     ptrue (p[0-7]).b, vl16
>>> +**     asrd z[0-9]+\.d, \1/m, z[0-9]+\.d, #3
>>> +**     ret
>>> +*/
>>> +FOO(uint64x2_t)
>>> +
>>> +/*
>>> +** foo_svuint32_t:
>>> +**     ptrue (p[0-7]).b, all
>>> +**     asrd z[0-9]+\.s, \1/m, z[0-9]+\.s, #3
>>> +**     ret
>>> +*/
>>> +FOO(svuint32_t)
>>> +
>>> +/*
>>> +** foo_svuint64_t:
>>> +**     ptrue (p[0-7]).b, all
>>> +**     asrd z[0-9]+\.d, \1/m, z[0-9]+\.d, #3
>>> +**     ret
>>> +*/
>>> +FOO(svuint64_t)
>>> -- 
>>> 2.43.0
>>> 
>>> 
>>>> On 22 Oct 2025, at 7:21 PM, Tamar Christina <[email protected]> 
>>>> wrote:
>>>> 
>>>> External email: Use caution opening links or attachments
>>>> 
>>>> 
>>>>> -----Original Message-----
>>>>> From: Richard Biener <[email protected]>
>>>>> Sent: 22 October 2025 14:30
>>>>> To: Tamar Christina <[email protected]>
>>>>> Cc: Soumya AR <[email protected]>; [email protected]; Kyrylo
>>>>> Tkachov <[email protected]>
>>>>> Subject: RE: [PATCH] aarch64: Use SVE ASRD with vector division using
>>>>> division operator
>>>>> 
>>>>> On Wed, 22 Oct 2025, Tamar Christina wrote:
>>>>> 
>>>>>>> -----Original Message-----
>>>>>>> From: Richard Biener <[email protected]>
>>>>>>> Sent: 22 October 2025 14:05
>>>>>>> To: Tamar Christina <[email protected]>
>>>>>>> Cc: Soumya AR <[email protected]>; [email protected]; Kyrylo
>>>>>>> Tkachov <[email protected]>
>>>>>>> Subject: RE: [PATCH] aarch64: Use SVE ASRD with vector division using
>>>>>>> division operator
>>>>>>> 
>>>>>>> On Wed, 22 Oct 2025, Tamar Christina wrote:
>>>>>>> 
>>>>>>>> Hi Soumya,
>>>>>>>> 
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: Soumya AR <[email protected]>
>>>>>>>>> Sent: 13 October 2025 13:42
>>>>>>>>> To: Tamar Christina <[email protected]>
>>>>>>>>> Cc: [email protected]; Kyrylo Tkachov <[email protected]>;
>>>>>>>>> Richard Biener <[email protected]>
>>>>>>>>> Subject: Re: [PATCH] aarch64: Use SVE ASRD with vector division using
>>>>>>>>> division operator
>>>>>>>>> Importance: High
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>>> On 13 Oct 2025, at 1:48 PM, Tamar Christina
>>>>>>> <[email protected]>
>>>>>>>>> wrote:
>>>>>>>>>> 
>>>>>>>>>> External email: Use caution opening links or attachments
>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>>> Hi Soumya,
>>>>>>>>>> 
>>>>>>>>>> The 10/13/2025 07:05, Soumya AR wrote:
>>>>>>>>>>> The ASRD instruction on SVE performs an arithmetic shift right by an
>>>>>>>>> immediate
>>>>>>>>>>> for divide. This patch enables ASRD when dividing vectors using the
>>>>> GNU
>>>>>>> C
>>>>>>>>>>> division operator.
>>>>>>>>>>> 
>>>>>>>>>>> For example:
>>>>>>>>>>> 
>>>>>>>>>>> int32x4_t
>>>>>>>>>>> foo (int32x4_t x)
>>>>>>>>>>> {
>>>>>>>>>>>   return x / 4;
>>>>>>>>>>> }
>>>>>>>>>>> 
>>>>>>>>>>> svint32_t
>>>>>>>>>>> bar (svint32_t x)
>>>>>>>>>>> {
>>>>>>>>>>>   return x / 4;
>>>>>>>>>>> }
>>>>>>>>>>> 
>>>>>>>>>>> currently generates a DIV, but can be done using ASRD.
>>>>>>>>>>> 
>>>>>>>>>>> The patch was bootstrapped and regtested on aarch64-linux-gnu, no
>>>>>>>>> regression.
>>>>>>>>>>> OK for GCC16?
>>>>>>>>>>> 
>>>>>>>>>>> Signed-off-by: Soumya AR <[email protected]>
>>>>>>>>>>> 
>>>>>>>>>>> gcc/ChangeLog:
>>>>>>>>>>> 
>>>>>>>>>>>   * expmed.cc (expand_divmod): Expand to sdiv_pow2 optab for
>>>>>>> vectors.
>>>>>>>>>>> 
>>>>>>>>>>> gcc/testsuite/ChangeLog:
>>>>>>>>>>> 
>>>>>>>>>>>   * gcc.target/aarch64/sve/sve-asrd-2.c: New test.
>>>>>>>>>>> 
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Hi Tamar,
>>>>>>>>> 
>>>>>>>>> Thanks for the quick review!
>>>>>>>>> 
>>>>>>>>>> The test is OK, but you'll need a middle-end maintainer for the
>>>>> expmed.cc
>>>>>>>>> changes.
>>>>>>>>> 
>>>>>>>>> My bad, CC'ing Richi here as well.
>>>>>>>>> 
>>>>>>>>>> But that said...
>>>>>>>>>> 
>>>>>>>>>> diff --git a/gcc/expmed.cc b/gcc/expmed.cc
>>>>>>>>>> index df09cbccd08..a35aa229d44 100644
>>>>>>>>>> --- a/gcc/expmed.cc
>>>>>>>>>> +++ b/gcc/expmed.cc
>>>>>>>>>> @@ -4465,6 +4465,24 @@ expand_divmod (int rem_flag, enum
>>>>>>> tree_code
>>>>>>>>> code, machine_mode mode,
>>>>>>>>>>    {
>>>>>>>>>>    case TRUNC_MOD_EXPR:
>>>>>>>>>>    case TRUNC_DIV_EXPR:
>>>>>>>>>> +       if (CONST_VECTOR_P (op1)
>>>>>>>>>> +           && optab_handler (sdiv_pow2_optab, mode) !=
>>>>>>> CODE_FOR_nothing)
>>>>>>>>>> +         {
>>>>>>>>>> +           rtx scalar_op1 = unwrap_const_vec_duplicate (op1);
>>>>>>>>>> +           if (scalar_op1 != NULL_RTX && CONST_INT_P (scalar_op1))
>>>>>>>>>> 
>>>>>>>>>> You can simplify this using const_vec_duplicate_p.
>>>>>>>>>> 
>>>>>>>>>> +             {
>>>>>>>>>> +               HOST_WIDE_INT d = INTVAL (scalar_op1);
>>>>>>>>>> +               if (d > 0 && pow2p_hwi (d))
>>>>>>>>>> +                 {
>>>>>>>>>> +                   rtx shift_amount
>>>>>>>>>> +                     = gen_const_vec_duplicate (mode,
>>>>>>>>>> +                                                GEN_INT (floor_log2 
>>>>>>>>>> (d)));
>>>>>>>>>> +                   return expand_binop (mode, sdiv_pow2_optab, op0,
>>>>>>>>>> +                                        shift_amount, target, 
>>>>>>>>>> unsignedp,
>>>>>>>>>> +                                        methods);
>>>>>>>>>> 
>>>>>>>>>> This expansion can fail, when e.g. the shift amount is larger than 
>>>>>>>>>> the
>>>>>>> bitsize
>>>>>>>>> of the element,
>>>>>>>>>> so you should check the result of it before exiting from
>>>>> expand_divmod.
>>>>>>>>>> 
>>>>>>>>> 
>>>>>>>>> Makes sense, attaching an updated patch with both changes.
>>>>>>>>> 
>>>>>>>> 
>>>>>>>> The new patch looks OK to me (it uses the old interface but that's what
>>>>> most
>>>>>>> of
>>>>>>>> expmed uses).
>>>>>>>> 
>>>>>>>> I think your cover letter needs to mention that we can't do this in the
>>>>>>> backend because
>>>>>>>> Adv. SIMD lacks a division instruction and that the decomposition is
>>>>> harder
>>>>>>> to match
>>>>>>>> correctly in all cases.
>>>>>>>> 
>>>>>>>> That said you still need a middle-end maintainer approval.
>>>>>>> 
>>>>>>> So the backend advertises a vector division?  Othewise I would have
>>>>>>> expected vector lowering to lower this (if it does that at all, for
>>>>>>> VLA vectors?!).
>>>>>>> 
>>>>>>> So this is an alternative better expansion - but there should already
>>>>>>> be generic code to deal with divisions by a power of two, why does
>>>>>>> that not trigger?  And what's this sdiv_pow2 thing again?
>>>>>> 
>>>>>> Yes, expand intercepts in expand_divmod division by a power of 2 and
>>>>> decomposes
>>>>>> It to shifts.   We could re-recognize the instruction in combine of 
>>>>>> course, but
>>>>> we already
>>>>>> have an optab the vectorizer would have used in this case [us]div_pow2, 
>>>>>> see
>>>>>> vect_recog_divmod_pattern.  So this is just teaching expand about the
>>>>> special division of
>>>>>> a power of 2 optab that the vectorizer uses for normal vector operations.
>>>>> 
>>>>> I can't remember the difference of div_pow2 and shifts, but it feels like
>>>>> this expand-time improvement should be done by expand_divmod then?
>>>> 
>>>> The patch does extend expand_divmod though, but does through an existing
>>>> optab.
>>>> 
>>>> The issue is that signedness matters,
>>>> this rewrite to asrd is only possible for signed values as it's an 
>>>> arithmetic shift.
>>>> 
>>>> For unsigned values we want ushr.
>>>> 
>>>>> 'asrd' is described as arithmetic shift right for divide by immediate
>>>>> whatever the exact difference from 'asr' is ... the docs say sth
>>>>> about round towards zero, but then we're using arithmetic right shifts
>>>>> for signed division already ...
>>>> 
>>>> SVE doesn't support division by immediates, so SDIV only takes a register.
>>>> we could always extend the sdiv pattern to support immediates, but it
>>>> does feel odd given we have a different optab for this.
>>>> 
>>>> Thanks,
>>>> Tamar
>>>> 
>>>>> 
>>>>> Richard.
>>>>> 
>>>>>> Thanks,
>>>>>> Tamar
>>>>>> 
>>>>>>> 
>>>>>>> Richard.
>>>>>>> 
>>>>>>>> Thanks,
>>>>>>>> Tamar
>>>>>>>> 
>>>>>>>>> Thanks,
>>>>>>>>> Soumya
>>>>>>>>> 
>>>>>>>>>> Thanks,
>>>>>>>>>> Tamar
>>>>>>>>>> 
>>>>>>>>>> +                 }
>>>>>>>>>> +             }
>>>>>>>>>> +         }
>>>>>>>>>>     if (op1_is_constant)
>>>>>>>>>>       {
>>>>>>>>>>         scalar_int_mode int_mode = as_a <scalar_int_mode>
>>>>>>>>> (compute_mode);
>>>>>>>>> 
>>>>>>>> 
>>>>>>>> 
>>>>>>> 
>>>>>>> --
>>>>>>> Richard Biener <[email protected]>
>>>>>>> SUSE Software Solutions Germany GmbH,
>>>>>>> Frankenstrasse 146, 90461 Nuernberg, Germany;
>>>>>>> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
>>>>>>> Nuernberg)
>>>>>> 
>>>>> 
>>>>> --
>>>>> Richard Biener <[email protected]>
>>>>> SUSE Software Solutions Germany GmbH,
>>>>> Frankenstrasse 146, 90461 Nuernberg, Germany;
>>>>> GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG
>>>>> Nuernberg)
>>> 
>>> 
>>

Reply via email to