https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127216

            Bug ID: 127216
           Summary: [17 Regression] Vector averaging code gen regression
                    after recent change
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: tree-optimization
          Assignee: unassigned at gcc dot gnu.org
          Reporter: law at gcc dot gnu.org
  Target Milestone: ---

This change:

commit 765ef64246da4b65ca394b29095cbf891006977d
Author: liuhongt <[email protected]>
Date:   Tue Sep 1 01:48:29 2026 -0700

    vect: Allow signed types in average fallback [PR89007]

    The average fallback is restricted to unsigned types, but it also works for
    signed types.  Arithmetic right shifts round down, and the low-bit carry
    adjusts the result in the same way.

    Remove the unsigned restriction.  Use target_supports_op_p rather than
    optab_for_tree_code to check whether the fallback operations are available.

    gcc/ChangeLog:

            PR tree-optimization/89007
            * tree-vect-patterns.cc (vect_recog_average_pattern): Allow signed
            types in the fallback.  Check whether the fallback operations are
            supported.

    gcc/testsuite/ChangeLog:

            PR tree-optimization/89007
            * gcc.target/i386/pr89007.c: New test.


Is causing code generation quality regressions on risc-v.  Example regressions
from the overnight run:

unix/-march=rv64gc_zba_zbb_zbs_zicond: gcc:
gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c -ftree-vectorize -O3
-mrvv-vector-bits=scalable -mrvv-max-lmul=dynamic -ffast-math 
scan-assembler-times vaadd.vx 2
unix/-march=rv64gc_zba_zbb_zbs_zicond: gcc:
gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i16.c -ftree-vectorize -O3
-mrvv-vector-bits=zvl -mrvv-max-lmul=dynamic -ffast-math  scan-assembler-times
vaadd.vx 2
unix/-march=rv64gc_zba_zbb_zbs_zicond: gcc:
gcc.target/riscv/rvv/autovec/vx_vf/vx-1-i32.c -ftree-vectorize -O3
-mrvv-vector-bits=scalable -mrvv-max-lmul=dynamic -ffast-math 
scan-assembler-times vaadd.vx 2



Looking at the first test in the function
test_vx_binary_avg_floor_test_it16_t_avg_floor_int16_t_case_2 (good grief!)
comparing good to bad:

  test_vx_binary_avg_floor_test_int16_t_avg_floor_int16_t_case_2:
-       csrwi   vxrm,2
        beq     a3,zero,.L201
        slli    a3,a3,32
!       srli    t0,a3,32
  .L196:
!       vsetvli a5,t0,e16,m4,ta,ma
!       vle16.v v4,0(a1)
!       slli    a4,a5,1
!       sub     t0,t0,a5
        add     a1,a1,a4
!       vaadd.vx        v8,v4,a2
!       vse16.v v8,0(a0)
        add     a0,a0,a4
!       bne     t0,zero,.L196
  .L201:
        ret
        .size   test_vx_binary_avg_floor_test_int16_t_avg_floor_int16_t_case_2,
.-test_vx_binary_avg_floor_tes
t_int16_t_avg_floor_int16_t_case_2
--- 882,907 ----
        .globl  test_vx_binary_avg_floor_test_int16_t_avg_floor_int16_t_case_2
        .type   test_vx_binary_avg_floor_test_int16_t_avg_floor_int16_t_case_2,
@function
  test_vx_binary_avg_floor_test_int16_t_avg_floor_int16_t_case_2:
        beq     a3,zero,.L201
+       vsetvli a5,zero,e16,m8,ta,ma
+       vmv.v.x v16,a2
        slli    a3,a3,32
!       srli    t1,a3,32
!       vsra.vi v24,v16,1
!       vand.vi v16,v16,1
  .L196:
!       vsetvli t0,t1,e16,m8,ta,ma
!       vle16.v v0,0(a1)
!       slli    a4,t0,1
!       sub     t1,t1,t0
        add     a1,a1,a4
!       vsra.vi v8,v0,1
!       vand.vv v0,v16,v0
!       vadd.vv v8,v8,v24
!       vadd.vv v0,v8,v0
!       vse16.v v0,0(a0)
        add     a0,a0,a4
!       bne     t1,zero,.L196


In the good code we generate the vaadd.vx instruction which is a vector average
of v4 and the value in a2 (broadcasted to the current vector type/len) storing
the result in v8.

You can see similar cases in the other tests.

Reply via email to