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.

Reply via email to