Ping. Thanks, Soumya
> On 30 Jun 2026, at 1:53 PM, Soumya AR <[email protected]> wrote: > > 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) >>>> >>>> >>>
