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)