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.