This removes a road-block towards fixing PR64715 - the gimplifier performing an undesired "simplification" of &X + CST to &MEM[&X, CST]. IMHO this is premature there.
The fallout is small - two testcases are no longer simplified at -O0 (who cares), and devirt-40.C shows that SCEV adheres too closely to the fold view of type compatibility (I had a fix for that in my dev tree for quite some time it seeems). Of course the latter means that there might be more fallout in code that builds GENERIC and then re-gimplifies that, but I can't think of anything that wouldn't be fixed with followup passes. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Ok? Thanks, Richard. 2015-03-20 Richard Biener <rguent...@suse.de> PR middle-end/64715 * tree-chrec.c (chrec_fold_poly_cst): Use useless_type_conversion_p for type comparison and gcc_checking_assert. (chrec_fold_plus_poly_poly): Likewise. (chrec_fold_multiply_poly_poly): Likewise. (chrec_convert_1): Likewise. * gimplify.c (gimplify_expr): Remove premature folding of &X + CST to &MEM[&X, CST]. * gcc.dg/pr15347.c: Use -O. * c-c++-common/pr19807-1.c: Likewise. Index: gcc/tree-chrec.c =================================================================== --- gcc/tree-chrec.c (revision 221515) +++ gcc/tree-chrec.c (working copy) @@ -78,8 +78,8 @@ chrec_fold_poly_cst (enum tree_code code gcc_assert (poly); gcc_assert (cst); gcc_assert (TREE_CODE (poly) == POLYNOMIAL_CHREC); - gcc_assert (!is_not_constant_evolution (cst)); - gcc_assert (type == chrec_type (poly)); + gcc_checking_assert (!is_not_constant_evolution (cst)); + gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly))); switch (code) { @@ -124,10 +124,11 @@ chrec_fold_plus_poly_poly (enum tree_cod gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC); gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC); if (POINTER_TYPE_P (chrec_type (poly0))) - gcc_assert (ptrofftype_p (chrec_type (poly1))); + gcc_checking_assert (ptrofftype_p (chrec_type (poly1)) + && useless_type_conversion_p (type, chrec_type (poly0))); else - gcc_assert (chrec_type (poly0) == chrec_type (poly1)); - gcc_assert (type == chrec_type (poly0)); + gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly0)) + && useless_type_conversion_p (type, chrec_type (poly1))); /* {a, +, b}_1 + {c, +, d}_2 -> {{a, +, b}_1 + c, +, d}_2, @@ -208,8 +209,8 @@ chrec_fold_multiply_poly_poly (tree type gcc_assert (poly1); gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC); gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC); - gcc_assert (chrec_type (poly0) == chrec_type (poly1)); - gcc_assert (type == chrec_type (poly0)); + gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly0)) + && useless_type_conversion_p (type, chrec_type (poly1))); /* {a, +, b}_1 * {c, +, d}_2 -> {c*{a, +, b}_1, +, d}_2, {a, +, b}_2 * {c, +, d}_1 -> {a*{c, +, d}_1, +, b}_2, @@ -1352,7 +1353,7 @@ chrec_convert_1 (tree type, tree chrec, return chrec; ct = chrec_type (chrec); - if (ct == type) + if (useless_type_conversion_p (type, ct)) return chrec; if (!evolution_function_is_affine_p (chrec)) Index: gcc/testsuite/gcc.dg/pr15347.c =================================================================== --- gcc/testsuite/gcc.dg/pr15347.c (revision 221530) +++ gcc/testsuite/gcc.dg/pr15347.c (working copy) @@ -1,4 +1,5 @@ /* { dg-do link } */ +/* { dg-options "-O" } */ extern void link_error (void); int Index: gcc/testsuite/c-c++-common/pr19807-1.c =================================================================== --- gcc/testsuite/c-c++-common/pr19807-1.c (revision 221530) +++ gcc/testsuite/c-c++-common/pr19807-1.c (working copy) @@ -1,4 +1,5 @@ /* { dg-do link } */ +/* { dg-options "-O" } */ extern void link_error(void); int main() Index: gcc/gimplify.c =================================================================== *** gcc/gimplify.c (revision 221514) --- gcc/gimplify.c (working copy) *************** gimplify_expr (tree *expr_p, gimple_seq *** 8524,8546 **** post_p, is_gimple_val, fb_rvalue); recalculate_side_effects (*expr_p); ret = MIN (r0, r1); - /* Convert &X + CST to invariant &MEM[&X, CST]. Do this - after gimplifying operands - this is similar to how - it would be folding all gimplified stmts on creation - to have them canonicalized, which is what we eventually - should do anyway. */ - if (TREE_CODE (TREE_OPERAND (*expr_p, 1)) == INTEGER_CST - && is_gimple_min_invariant (TREE_OPERAND (*expr_p, 0))) - { - *expr_p = build_fold_addr_expr_with_type_loc - (input_location, - fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (*expr_p)), - TREE_OPERAND (*expr_p, 0), - fold_convert (ptr_type_node, - TREE_OPERAND (*expr_p, 1))), - TREE_TYPE (*expr_p)); - ret = MIN (ret, GS_OK); - } break; } --- 8524,8529 ----