https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127838
Richard Biener <rguenth at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |rsandifo at gcc dot gnu.org
--- Comment #4 from Richard Biener <rguenth at gcc dot gnu.org> ---
(In reply to Richard Biener from comment #3)
> Confirmed on x86-64. W/o versioning for aliasing (make res __restrict) it
> also segfaults.
But w/ __restrict it's invalid. Without:
1. Without __restrict, vect_prune_runtime_alias_test_list creates runtime
alias checks via create_intersect_range_checks in gcc/tree-data-ref.cc.
2. Because DR_STEP(s) = 4 and DR_STEP(res) = 1 differ, vect_vfa_segment_size
in gcc/tree-vect-data-refs.cc calculates the segment length using
scalar_loop_iters ((long unsigned int) length_10(D)):
1 length_factor = size_binop (MINUS_EXPR,
2 fold_convert (sizetype, length_factor),
3 size_one_node);
4 return size_binop (MULT_EXPR, fold_convert (sizetype, DR_STEP
(dr_info->dr)),
5 length_factor);
3. When length is passed as signed -16 (0xfffffff0), fold_convert (sizetype,
length_factor) sign-extends to 0xfffffffffffffff0. Multiplying by 4
overflows sizetype (modulo 2⁶⁴) to -64 (0xffffffffffffffc0).
4. In get_segment_min_max:
- min_reach = 0
- max_reach = seg_len = -64
This computes inverted segment endpoints [s, s - 64) where seg_max <
seg_min.
5. The runtime alias condition:
1 res >= s - 64 || s >= res - 16
evaluates to true at runtime because res = s + 5 >= s - 64.
6. GCC concludes at runtime that s and res do not alias, enters the vector
loop, and segfaults.
we have to guard against such overflow for non-equal DR_STEP so the wrapping
segment lengths do not invert the range check inadvertedly.