Hi!

I admit I don't have testcases, but I'm afraid very bad things will happen
if either the offset2i - offseti or pd.offset + pd.size computations
overflow.  All are computed in (signed) HOST_WIDE_INT, and at least for the
memset or CONSTRUCTOR cases I'd fear the stores could be extremely large.

Or shall we introduce some system.h macros for this, say
HWI_SADD_OVERFLOW_P and HWI_SSUB_OVERFLOW_P that could use
__builtin_{add,sub}_overflow_p when available or do those
comparison checks and use those here?

Bootstrapped/regtested on x86_64-linux and i686-linux.

2020-02-27  Jakub Jelinek  <ja...@redhat.com>

        * tree-ssa-sccvn.c (vn_walk_cb_data::push_partial_def): Punt if
        pd.offset + pd.size would overflow.
        (vn_reference_lookup_3): Punt if offset2i - offseti would overflow.

--- gcc/tree-ssa-sccvn.c.jj     2020-02-26 13:38:01.899937521 +0100
+++ gcc/tree-ssa-sccvn.c        2020-02-26 14:39:26.472695329 +0100
@@ -1778,7 +1778,9 @@ vn_walk_cb_data::push_partial_def (const
       || CHAR_BIT != 8
       || BITS_PER_UNIT != 8
       /* Not prepared to handle PDP endian.  */
-      || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+      || BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN
+      /* Punt on overflows during pd.offset + pd.size computation.  */
+      || pd.offset > INTTYPE_MAXIMUM (HOST_WIDE_INT) - pd.size)
     return (void *)-1;
 
   bool pd_constant_p = (TREE_CODE (pd.rhs) == CONSTRUCTOR
@@ -2680,7 +2682,13 @@ vn_reference_lookup_3 (ao_ref *ref, tree
               && offset2.is_constant (&offset2i)
               && maxsize.is_constant (&maxsizei)
               && ranges_known_overlap_p (offseti, maxsizei, offset2i,
-                                         leni << LOG2_BITS_PER_UNIT))
+                                         leni << LOG2_BITS_PER_UNIT)
+              /* Punt on overflows.  */
+              && !((offseti > 0
+                    && offset2i < INTTYPE_MINIMUM (HOST_WIDE_INT) + offseti)
+                   || (offseti < 0
+                       && offset2i > (INTTYPE_MAXIMUM (HOST_WIDE_INT)
+                                      + offseti))))
        {
          pd_data pd;
          pd.rhs = build_constructor (NULL_TREE, NULL);
@@ -2733,7 +2741,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree
                   && offset2.is_constant (&offset2i)
                   && size2.is_constant (&size2i)
                   && ranges_known_overlap_p (offseti, maxsizei,
-                                             offset2i, size2i))
+                                             offset2i, size2i)
+                  /* Punt on overflows.  */
+                  && !((offseti > 0
+                        && offset2i < (INTTYPE_MINIMUM (HOST_WIDE_INT)
+                                       + offseti))
+                       || (offseti < 0
+                           && offset2i > (INTTYPE_MAXIMUM (HOST_WIDE_INT)
+                                          + offseti))))
            {
              /* Let clobbers be consumed by the partial-def tracker
                 which can choose to ignore them if they are shadowed
@@ -2886,7 +2901,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree
                }
            }
          else if (ranges_known_overlap_p (offseti, maxsizei, offset2i,
-                                          size2i))
+                                          size2i)
+                  /* Punt on overflows.  */
+                  && !((offseti > 0
+                        && offset2i < (INTTYPE_MINIMUM (HOST_WIDE_INT)
+                                       + offseti))
+                       || (offseti < 0
+                           && offset2i > (INTTYPE_MAXIMUM (HOST_WIDE_INT)
+                                          + offseti))))
            {
              pd_data pd;
              tree rhs = gimple_assign_rhs1 (def_stmt);
@@ -2969,7 +2991,14 @@ vn_reference_lookup_3 (ao_ref *ref, tree
                   && offset.is_constant (&offseti)
                   && offset2.is_constant (&offset2i)
                   && size2.is_constant (&size2i)
-                  && ranges_known_overlap_p (offset, maxsize, offset2, size2))
+                  && ranges_known_overlap_p (offset, maxsize, offset2, size2)
+                  /* Punt on overflows.  */
+                  && !((offseti > 0
+                        && offset2i < (INTTYPE_MINIMUM (HOST_WIDE_INT)
+                                       + offseti))
+                       || (offseti < 0
+                           && offset2i > (INTTYPE_MAXIMUM (HOST_WIDE_INT)
+                                          + offseti))))
            {
              pd_data pd;
              pd.rhs = SSA_VAL (def_rhs);

        Jakub

Reply via email to