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.
> 

The test is OK, but you'll need a middle-end maintainer for the expmed.cc 
changes.
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.

Thanks,
Tamar

+                 }
+             }
+         }
        if (op1_is_constant)
          {
            scalar_int_mode int_mode = as_a <scalar_int_mode> (compute_mode);

Reply via email to