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? 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) > {