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 ----

Reply via email to