With recent SLP vectorization patches I see RISC-V divison by zero
for gfortran.dg/matmul_10.f90 and others in get_group_load_store_type
which does
&& can_div_trunc_p (group_size
* LOOP_VINFO_VECT_FACTOR (loop_vinfo) - gap,
nunits, &tem, &remain)
&& (known_eq (remain, 0u)
|| (constant_multiple_p (nunits, remain, &num)
&& (vector_vector_composition_type (vectype, num,
&half_vtype)
!= NULL_TREE))))
overrun_p = false;
where for [2, 2] / [0, 2] the condition doesn't reflect what we
are trying to test - that, when remain is zero or, when non-zero,
nunits is a multiple of remain, we can avoid touching a gap via
loading smaller pieces and vector composition.
It isn't safe to change the known_eq to maybe_eq so instead
require known_ne (remain, 0u) before doing constant_multiple_p.
There's the corresponding code in vectorizable_load that's known
to have a latent similar issue, so sync that up as well.
* tree-vect-stmts.cc (get_group_load_store_type): Check
known_ne (remain, 0u) before doing constant_multiple_p.
(vectorizable_load): Likewise.
* LOOP_VINFO_VECT_FACTOR (loop_vinfo) - gap,
nunits, &tem, &remain)
&& (known_eq (remain, 0u)
- || (constant_multiple_p (nunits, remain, &num)
+ || (known_ne (remain, 0u)
+ && constant_multiple_p (nunits, remain, &num)
&& (vector_vector_composition_type (vectype, num,
&half_vtype)
!= NULL_TREE))))
{
/* remain should now be > 0 and < nunits. */
unsigned num;
- if (constant_multiple_p (nunits, remain, &num))
+ if (known_ne (remain, 0u)
+ && constant_multiple_p (nunits, remain, &num))
{
tree ptype;
new_vtype