The following plugs some holes in extract_affine which failed to modulo-reduce signed values in conversions, failed to interpret pointer-plus offsets as signed (yeah, stupid GIMPLE IL...) and mishandled BIT_NOT_EXPR.
Bootstrap and regtest running on x86_64-unknown-linux-gnu. Ok? Thanks, Richard. 2017-09-19 Richard Biener <rguent...@suse.de> * graphite-sese-to-poly.c (extract_affine): Properly handle POINTER_PLUS_EXPR, BIT_NOT_EXPR and conversion to signed. Index: gcc/graphite-sese-to-poly.c =================================================================== --- gcc/graphite-sese-to-poly.c (revision 252968) +++ gcc/graphite-sese-to-poly.c (working copy) @@ -237,6 +237,7 @@ extract_affine (scop_p s, tree e, __isl_ return NULL; } + tree type = TREE_TYPE (e); switch (TREE_CODE (e)) { case POLYNOMIAL_CHREC: @@ -247,8 +248,22 @@ extract_affine (scop_p s, tree e, __isl_ res = extract_affine_mul (s, e, space); break; - case PLUS_EXPR: case POINTER_PLUS_EXPR: + { + lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space)); + /* The RHS of a pointer-plus expression is to be interpreted + as signed value. Try to look through a sign-changing conversion + first. */ + tree tem = TREE_OPERAND (e, 1); + STRIP_NOPS (tem); + rhs = extract_affine (s, tem, space); + if (TYPE_UNSIGNED (TREE_TYPE (tem))) + rhs = wrap (rhs, TYPE_PRECISION (type) - 1); + res = isl_pw_aff_add (lhs, rhs); + break; + } + + case PLUS_EXPR: lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space)); rhs = extract_affine (s, TREE_OPERAND (e, 1), space); res = isl_pw_aff_add (lhs, rhs); @@ -260,8 +275,13 @@ extract_affine (scop_p s, tree e, __isl_ res = isl_pw_aff_sub (lhs, rhs); break; - case NEGATE_EXPR: case BIT_NOT_EXPR: + lhs = extract_affine (s, integer_minus_one_node, isl_space_copy (space)); + rhs = extract_affine (s, TREE_OPERAND (e, 0), space); + res = isl_pw_aff_sub (lhs, rhs); + break; + + case NEGATE_EXPR: lhs = extract_affine (s, TREE_OPERAND (e, 0), isl_space_copy (space)); rhs = extract_affine (s, integer_minus_one_node, space); res = isl_pw_aff_mul (lhs, rhs); @@ -279,6 +299,12 @@ extract_affine (scop_p s, tree e, __isl_ return res; CASE_CONVERT: + res = extract_affine (s, TREE_OPERAND (e, 0), space); + /* signed values, even if overflow is undefined, get modulo-reduced. */ + if (! TYPE_UNSIGNED (type)) + res = wrap (res, TYPE_PRECISION (type) - 1); + break; + case NON_LVALUE_EXPR: res = extract_affine (s, TREE_OPERAND (e, 0), space); break; @@ -288,7 +314,6 @@ extract_affine (scop_p s, tree e, __isl_ break; } - tree type = TREE_TYPE (e); if (TYPE_UNSIGNED (type)) res = wrap (res, TYPE_PRECISION (type));