On Wed, 20 Jan 2021, Richard Sandiford wrote:

> Richard Biener <rguent...@suse.de> writes:
> > diff --git a/gcc/hwint.h b/gcc/hwint.h
> > index 127b0130c66..8812bc7150f 100644
> > --- a/gcc/hwint.h
> > +++ b/gcc/hwint.h
> > @@ -333,4 +333,46 @@ absu_hwi (HOST_WIDE_INT x)
> >    return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x;
> >  }
> >  
> > +/* Compute the sum of signed A and B and indicate in *OVERFLOW whether
> > +   that operation overflowed.  */
> > +
> > +inline HOST_WIDE_INT
> > +add_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow)
> > +{
> > +#if GCC_VERSION < 11000
> > +  unsigned HOST_WIDE_INT result = a + b;
> 
> Sorry for the late comment, but shouldn't this cast a or b to
> unsigned HOST_WIDE_INT?

Yes ...

> Thanks,
> Richard
> 
> > +  if ((((result ^ a) & (result ^ b))
> > +       >> (HOST_BITS_PER_WIDE_INT - 1)) & 1)
> > +    *overflow = true;
> > +  else
> > +    *overflow = false;
> > +  return result;
> > +#else
> > +  HOST_WIDE_INT result;
> > +  *overflow = __builtin_add_overflow (a, b, &result);
> > +  return result;
> > +#endif
> > +}
> > +
> > +/* Compute the product of signed A and B and indicate in *OVERFLOW whether
> > +   that operation overflowed.  */
> > +
> > +inline HOST_WIDE_INT
> > +mul_hwi (HOST_WIDE_INT a, HOST_WIDE_INT b, bool *overflow)
> > +{
> > +#if GCC_VERSION < 11000
> > +  unsigned HOST_WIDE_INT result = a * (unsigned HOST_WIDE_INT)b;
> > +  if ((a == -1 && b == HOST_WIDE_INT_MIN)
> > +      || (a != 0 && (HOST_WIDE_INT)result / a != b))
> > +    *overflow = true;
> > +  else
> > +    *overflow = false;
> > +  return result;
> > +#else
> > +  HOST_WIDE_INT result;
> > +  *overflow = __builtin_mul_overflow (a, b, &result);
> > +  return result;
> > +#endif
> > +}
> > +
> >  #endif /* ! GCC_HWINT_H */
> > diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
> > index 9d07b415e9d..d19c5eb51e4 100644
> > --- a/gcc/tree-data-ref.c
> > +++ b/gcc/tree-data-ref.c
> > @@ -3924,9 +3924,25 @@ initialize_matrix_A (lambda_matrix A, tree chrec, 
> > unsigned index, int mult)
> >    switch (TREE_CODE (chrec))
> >      {
> >      case POLYNOMIAL_CHREC:
> > -      if (!cst_and_fits_in_hwi (CHREC_RIGHT (chrec)))
> > +      /* CHREC_RIGHT and its negated value should fit in a lambda_int.
> > +    Pointer typed chrecs right are to be interpreted signed.  */
> > +      HOST_WIDE_INT chrec_right;
> > +      if (POINTER_TYPE_P (chrec_type (chrec)))
> > +   {
> > +     if (!cst_and_fits_in_hwi (CHREC_RIGHT (chrec)))
> > +       return chrec_dont_know;
> > +     chrec_right = int_cst_value (CHREC_RIGHT (chrec));
> > +   }
> > +      else
> > +   {
> > +     if (!tree_fits_shwi_p (CHREC_RIGHT (chrec)))
> > +       return chrec_dont_know;
> > +     chrec_right = tree_to_shwi (CHREC_RIGHT (chrec));
> > +   }
> > +      /* We want to be able to negate without overflow.  */
> > +      if (chrec_right == HOST_WIDE_INT_MIN)
> >     return chrec_dont_know;
> > -      A[index][0] = mult * int_cst_value (CHREC_RIGHT (chrec));
> > +      A[index][0] = mult * chrec_right;
> >        return initialize_matrix_A (A, CHREC_LEFT (chrec), index + 1, mult);
> >  
> >      case PLUS_EXPR:
> > @@ -4193,17 +4209,28 @@ lambda_vector_first_nz (lambda_vector vec1, int n, 
> > int start)
> >  /* Add a multiple of row R1 of matrix MAT with N columns to row R2:
> >     R2 = R2 + CONST1 * R1.  */
> >  
> > -static void
> > +static bool
> >  lambda_matrix_row_add (lambda_matrix mat, int n, int r1, int r2,
> >                    lambda_int const1)
> >  {
> >    int i;
> >  
> >    if (const1 == 0)
> > -    return;
> > +    return true;
> >  
> >    for (i = 0; i < n; i++)
> > -    mat[r2][i] += const1 * mat[r1][i];
> > +    {
> > +      bool ovf;
> > +      lambda_int tem = mul_hwi (mat[r1][i], const1, &ovf);
> > +      if (ovf)
> > +   return false;
> > +      lambda_int tem2 = add_hwi (mat[r2][i], tem, &ovf);
> > +      if (ovf || tem2 == HOST_WIDE_INT_MIN)
> > +   return false;
> > +      mat[r2][i] = tem2;
> > +    }
> > +
> > +  return true;
> >  }
> >  
> >  /* Multiply vector VEC1 of length SIZE by a constant CONST1,
> > @@ -4258,7 +4285,7 @@ lambda_vector_equal (lambda_vector vec1, 
> > lambda_vector vec2, int size)
> >     Ref: Algorithm 2.1 page 33 in "Loop Transformations for
> >     Restructuring Compilers" Utpal Banerjee.  */
> >  
> > -static void
> > +static bool
> >  lambda_matrix_right_hermite (lambda_matrix A, int m, int n,
> >                          lambda_matrix S, lambda_matrix U)
> >  {
> > @@ -4276,24 +4303,26 @@ lambda_matrix_right_hermite (lambda_matrix A, int 
> > m, int n,
> >         {
> >           while (S[i][j] != 0)
> >             {
> > -             lambda_int sigma, factor, a, b;
> > +             lambda_int factor, a, b;
> >  
> >               a = S[i-1][j];
> >               b = S[i][j];
> > -             sigma = ((a < 0) ^ (b < 0)) ? -1: 1;
> > -             unsigned HOST_WIDE_INT abs_a = absu_hwi (a);
> > -             unsigned HOST_WIDE_INT abs_b = absu_hwi (b);
> > -             factor = sigma * (lambda_int)(abs_a / abs_b);
> > +             gcc_assert (a != HOST_WIDE_INT_MIN);
> > +             factor = a / b;
> >  
> > -             lambda_matrix_row_add (S, n, i, i-1, -factor);
> > +             if (!lambda_matrix_row_add (S, n, i, i-1, -factor))
> > +               return false;
> >               std::swap (S[i], S[i-1]);
> >  
> > -             lambda_matrix_row_add (U, m, i, i-1, -factor);
> > +             if (!lambda_matrix_row_add (U, m, i, i-1, -factor))
> > +               return false;
> >               std::swap (U[i], U[i-1]);
> >             }
> >         }
> >     }
> >      }
> > +
> > +  return true;
> >  }
> >  
> >  /* Determines the overlapping elements due to accesses CHREC_A and
> > @@ -4410,7 +4439,13 @@ analyze_subscript_affine_affine (tree chrec_a,
> >      }
> >  
> >    /* U.A = S */
> > -  lambda_matrix_right_hermite (A, dim, 1, S, U);
> > +  if (!lambda_matrix_right_hermite (A, dim, 1, S, U))
> > +    {
> > +      *overlaps_a = conflict_fn_not_known ();
> > +      *overlaps_b = conflict_fn_not_known ();
> > +      *last_conflicts = chrec_dont_know;
> > +      goto end_analyze_subs_aa;
> > +    }
> >  
> >    if (S[0][0] < 0)
> >      {
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to