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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |ASSIGNED
             Target|ppc64-linux-gnu             |ppc64-linux-gnu,
                   |                            |powerpc64le-linux-gnu
           Assignee|unassigned at gcc dot gnu.org      |rguenth at gcc dot 
gnu.org
                 CC|                            |rsandifo at gcc dot gnu.org

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
Also on LE, even without -mmodulo.  Richard inserted the assert with the last
refactoring of split_constant_offset.

We are splitting the initial value of the IV tmp.9_69 here which is

niters_vector_mult_vf.8_68 = bnd.7_67 << 3;
_70 = (long int) niters_vector_mult_vf.8_68;
_71 = _70 * 2;
tmp.9_69 = buf_12(D) + _71;

and the operation we're asserting on is _70 * 2.

Note the IV is

(short int *) buf_53

with

# buf_53 = PHI <..., tmp9_69>

so the trigger for the ICE is the added

1373          STRIP_NOPS (access_fn);

in dr_analyze_indices.  That was necessary to avoid regressions when IVs
are demoted to uintptr_t by if-conversion.

split_constant_offset makes sure to not look through conversions to
trapping types - maybe that check should also be on the individual operations
in case we start analyzing with an expression in trapping types (as done
here)?  Immediate mitigation would of course be to restrict the STRIP_NOPS
to not expose an IV that evolves in a trapping type.

For example the following would fix it:

diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 57bac06242f..2cae2528e41 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -775,6 +775,9 @@ split_constant_offset_1 (tree type, tree op0, enum
tree_code code, tree op1,

     case PLUS_EXPR:
     case MINUS_EXPR:
+      if (TYPE_OVERFLOW_TRAPS (type))
+       return false;
+
       split_constant_offset (op0, &var0, &off0, &op0_range, cache, limit);
       split_constant_offset (op1, &var1, &off1, &op1_range, cache, limit);
       *off = size_binop (code, off0, off1);
@@ -785,7 +788,7 @@ split_constant_offset_1 (tree type, tree op0, enum
tree_code code, tree op1,
       return true;

     case MULT_EXPR:
-      if (TREE_CODE (op1) != INTEGER_CST)
+      if (TREE_CODE (op1) != INTEGER_CST || TYPE_OVERFLOW_TRAPS (type))
        return false;

       split_constant_offset (op0, &var0, &off0, &op0_range, cache, limit);

of course (after more work already done), compute_distributive_range could
return false itself.

Richard?

Reply via email to