Bug 36143 - [4.4 Regression]: FAIL: g++.dg/tree-ssa/pr19637.C
Summary: [4.4 Regression]: FAIL: g++.dg/tree-ssa/pr19637.C
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P2 normal
Target Milestone: 4.5.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization, xfail
Depends on: 38747
Blocks:
  Show dependency treegraph
 
Reported: 2008-05-05 21:29 UTC by H.J. Lu
Modified: 2012-03-13 13:04 UTC (History)
6 users (show)

See Also:
Host:
Target:
Build:
Known to work: 4.5.0
Known to fail: 4.4.4
Last reconfirmed: 2010-03-30 17:25:40


Attachments
gcc44-pr36143.patch (573 bytes, patch)
2008-12-03 15:20 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description H.J. Lu 2008-05-05 21:29:09 UTC
Revision 134947 caused

FAIL: g++.dg/tree-ssa/pr19637.C scan-tree-dump-times dom1 "return 1;" 3

on Linux/ia32 and Linux/Intel64.
Comment 1 Andrew Pinski 2008-05-05 21:30:39 UTC
Yes I saw this, this is because we are not creating a VIEW_CONVERT_EXPR for the first indirect reference, I think it has something to do with the placement new.  I will look at it when I get home tonight.
Comment 2 Hans-Peter Nilsson 2008-05-06 01:05:18 UTC
FWIW, noticed on cris-elf as well, where additionally, for the record,
gfortran.dg/transfer_assumed_size_1.f90 regressed.  From gfortran.log:

PASS: gfortran.dg/transfer_assumed_size_1.f90  -O2  (test for excess errors)
core: 4 byte read to unmapped address 0x2a000 at 0x16248^M
program stopped with signal 11.^M
FAIL: gfortran.dg/transfer_assumed_size_1.f90  -O2  execution test

which I'd rather not dig further into until the g++.dg/tree-ssa/pr19637.C s fixed.
Comment 3 Andrew Pinski 2008-05-06 03:56:00 UTC
(In reply to comment #2)
> FWIW, noticed on cris-elf as well, where additionally, for the record,
> gfortran.dg/transfer_assumed_size_1.f90 regressed.  From gfortran.log:

I just checked on i686-darwin and there is no changes that were produced by the VIEW_CONVERT_EXPR changes in forwprop.  That is forwprop does not produce any VIEW_CONVERT_EXPR for that testcase.

g++.dg/tree-ssa/pr19637.C is just a missed optimization and not about wrong code in this case.
Comment 4 Andrew Pinski 2008-05-06 04:09:32 UTC
So for &i[0], we don't convert it to VCE but the others we convert it but we don't get to the point convert to VCE for the placement new case for some reason ...
Comment 5 Andrew Pinski 2008-05-06 04:15:07 UTC
Oh we don't handle VCE On the left hand side for many different reasons.  One is because if we set only part of the variable, we could get possible invalid gimple as we are only setting part of a SSA_NAME.  I am un-assigning myself for now.
Comment 6 rguenther@suse.de 2008-05-06 10:22:39 UTC
Subject: Re:  [4.4 Regression]: FAIL: g++.dg/tree-ssa/pr19637.C

On Tue, 6 May 2008, pinskia at gcc dot gnu dot org wrote:

> ------- Comment #5 from pinskia at gcc dot gnu dot org  2008-05-06 04:15 -------
> Oh we don't handle VCE On the left hand side for many different reasons.  One
> is because if we set only part of the variable, we could get possible invalid
> gimple as we are only setting part of a SSA_NAME.  I am un-assigning myself for
> now.

We fold

  i.1_7 = (struct Foo *) &i;
  D.2236_8 = i.1_7->i[0];

to

  D.2236_8 = VIEW_CONVERT_EXPR<struct Foo>(i).i[0];

which is fine in principle but misses a folding to i[0].  
maybe_fold_offset_to_{array,component}_ref in tree-ssa-ccp.c should
be extended to handle this case, invoked via fold_stmt.

Richard.
Comment 7 Hans-Peter Nilsson 2008-05-07 17:08:39 UTC
Also seen on cris-elf with the revision as mentioned and still there as late as r135041.  Pinskia, are you going to revert it, fix it or should we xfail the test?
Comment 8 Andrew Pinski 2008-05-07 17:21:10 UTC
Fix it:
[andrew-pinskis-computer:local/gcc/gcc] apinski% svn diff
Index: tree-ssa-forwprop.c
===================================================================
--- tree-ssa-forwprop.c (revision 135021)
+++ tree-ssa-forwprop.c (working copy)
@@ -132,6 +132,16 @@ along with GCC; see the file COPYING3.  
      res = VIEW_CONVERT_EXPR<type1>(type2var)
 
    Or
+     ptr = (type1*)&type2var;
+     *ptr = res
+
+   Will get turned into (if type1 and type2 are the same size
+   and neither have volatile on them and is not a scalar):
+    VIEW_CONVERT_EXPR<type1>(type2var) = res
+  FIXME: The last constraint is not needed if DECL_GIMPLE_REG_P is expended
+  to all types
+
+   Or
 
      ptr = &x[0];
      ptr2 = ptr + <constant>;
@@ -573,6 +583,7 @@ forward_propagate_addr_expr_1 (tree name
 {
   tree lhs, rhs, array_ref;
   tree *rhsp, *lhsp;
+  bool in_reference_lhs = false;
 
   gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
 
@@ -602,7 +613,10 @@ forward_propagate_addr_expr_1 (tree name
      ADDR_EXPR will not appear on the LHS.  */
   lhsp = &GIMPLE_STMT_OPERAND (use_stmt, 0);
   while (handled_component_p (*lhsp))
-    lhsp = &TREE_OPERAND (*lhsp, 0);
+    {
+      lhsp = &TREE_OPERAND (*lhsp, 0);
+      in_reference_lhs = true;
+    }
   lhs = *lhsp;
 
   /* Now see if the LHS node is an INDIRECT_REF using NAME.  If so, 
@@ -617,6 +631,43 @@ forward_propagate_addr_expr_1 (tree name
                                    TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
     {
       *lhsp = unshare_expr (TREE_OPERAND (def_rhs, 0));
+      lhs = *lhsp;
+      fold_stmt_inplace (use_stmt);
+      tidy_after_forward_propagate_addr (use_stmt);
+
+      /* Continue propagating into the RHS if this was not the only use.  */
+      if (single_use_p)
+       return true;
+    }
+    
+  /* Now see if the LHS node is an INDIRECT_REF using NAME.  If so, 
+     propagate the ADDR_EXPR into the use of NAME and try to
+     create a VCE for the result.  */
+  if (TREE_CODE (lhs) == INDIRECT_REF
+      && TREE_OPERAND (lhs, 0) == name
+      && TYPE_SIZE (TREE_TYPE (lhs))
+      && TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
+      /* Function decls should not be used for VCE either as it could be
+         a function descriptor that we want and not the actual function code.  */
+      && TREE_CODE (TREE_OPERAND (def_rhs, 0)) != FUNCTION_DECL
+      /* We should not convert volatile loads to non volatile loads. */
+      && !TYPE_VOLATILE (TREE_TYPE (lhs))
+      && !TYPE_VOLATILE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))) 
+      && operand_equal_p (TYPE_SIZE (TREE_TYPE (lhs)),
+                         TYPE_SIZE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))), 0)
+      /* Check for aggregate types so we don't end up with a SSA_NAME inside
+         a VIEW_CONVERT_EXPR on the lhs. 
+        FIXME: this can go away when DECL_GIMPLE_REG_P is extended for all
+        scalar types.  */
+      && (AGGREGATE_TYPE_P (TREE_TYPE (TREE_OPERAND (def_rhs, 0)))
+         || TREE_CODE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))) == VECTOR_TYPE
+         || TREE_CODE (TREE_TYPE (TREE_OPERAND (def_rhs, 0))) == COMPLEX_TYPE))
+    {
+      tree new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
+      /* Use build1 here as we not produce a right hand side so we need to keep
+         around the VCE.  */
+      new_lhs = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (lhs), new_lhs);
+      *lhsp = new_lhs;
       fold_stmt_inplace (use_stmt);
       tidy_after_forward_propagate_addr (use_stmt);
 
@@ -673,9 +724,10 @@ forward_propagate_addr_expr_1 (tree name
       if (TREE_CODE (new_rhs) != VIEW_CONVERT_EXPR)
        {
          block_stmt_iterator bsi = bsi_for_stmt (use_stmt);
-         new_rhs = force_gimple_operand_bsi (&bsi, new_rhs, true, NULL, true, BSI_SAME_STMT);
-         /* As we change the deference to a SSA_NAME, we need to return false to make sure that
-            the statement does not get removed.  */
+         new_rhs = force_gimple_operand_bsi (&bsi, new_rhs, true, NULL, true,
+                                             BSI_SAME_STMT);
+         /* As we change the deference to a SSA_NAME, we need to return false
+            to make sure that the statement does not get removed.  */
          res = false;
        }
       *rhsp = new_rhs;
Comment 9 Hans-Peter Nilsson 2008-05-21 11:14:35 UTC
If the patch is ready and tested, fine: post it.
Do you need help testing?  If something else needs done, please be explicit.
Otherwise, it seems this PR is ripe for being marked as an xfail.
Comment 10 Kaveh Ghazi 2008-05-25 18:13:41 UTC
Failure also occurs on x86_64-unknown-linux-gnu and i686-unknown-linux-gnu, see:

x86_64: http://gcc.gnu.org/ml/gcc-testresults/2008-05/msg02221.html
i686: http://gcc.gnu.org/ml/gcc-testresults/2008-05/msg01800.html
Comment 11 Hans-Peter Nilsson 2008-07-21 02:38:26 UTC
Subject: Bug 36143

Author: hp
Date: Mon Jul 21 02:37:36 2008
New Revision: 138020

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=138020
Log:
	PR middle-end/36143
	* g++.dg/tree-ssa/pr19637.C: XFAIL.

Modified:
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/tree-ssa/pr19637.C

Comment 12 Jakub Jelinek 2008-12-03 15:20:18 UTC
Created attachment 16813 [details]
gcc44-pr36143.patch

I've tried to implement what Richi suggested in #c6, unfortunately that didn't fix the failure.
After forwprop1 foo_char and foo_void contain:
  D.2279_5 = (struct Foo *) &i;
  D.2279_5->i[0] ={v} 1;
  D.2281_11 = i[0];
but the optimizers don't figure out that ((struct Foo *) &i)->i[0]
and i[0] is the same thing.
Comment 13 Richard Biener 2008-12-03 15:33:27 UTC
We should be able to go via a VIEW_CONVERT_EXPR when propagating (struct Foo *) &i
into the LHS dereference D.2279_5->i[0].  That is, convert that to

  VIEW_CONVERT_EXPR <struct Foo> (i)->i[0]

and further fold that by noting that the final access is at offset zero and
of the same type as i.  (or more generally, for a final offset zero access
always strip all component-refs and fold to
VIEW_CONVERT_EXPR <final-access-type> (i)).
Comment 14 Richard Biener 2009-09-24 13:47:54 UTC
Subject: Bug 36143

Author: rguenth
Date: Thu Sep 24 13:47:26 2009
New Revision: 152122

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=152122
Log:
2009-09-24  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/36143
	PR tree-optimization/38747
	* tree-ssa-forwprop.c (forward_propagate_addr_expr_1): Only
	create VIEW_CONVERT_EXPRs for TBAA compatible accesses.

	* gcc.dg/tree-ssa/fre-vce-1.c: XFAIL.
	* gcc.dg/tree-ssa/forwprop-6.c: Likewise.
	* g++.dg/torture/pr38747.C: New testcase.
	* g++.dg/tree-ssa/pr19637.C: Un-XFAIL.

Added:
    trunk/gcc/testsuite/g++.dg/torture/pr38747.C
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/testsuite/ChangeLog
    trunk/gcc/testsuite/g++.dg/tree-ssa/pr19637.C
    trunk/gcc/testsuite/gcc.dg/tree-ssa/forwprop-6.c
    trunk/gcc/testsuite/gcc.dg/tree-ssa/fre-vce-1.c
    trunk/gcc/tree-ssa-forwprop.c

Comment 15 Richard Biener 2009-09-24 13:49:07 UTC
Fixed on the trunk.
Comment 16 Kaveh Ghazi 2010-03-30 17:25:40 UTC
PASSes on 4.5 trunk, but still XFAILs on 4.4 branch.  Since it's a 4.4 regression, should the patch be backported to 4.4 ?
Comment 17 Andrew Pinski 2011-11-29 23:06:25 UTC
No longer working on this.
Comment 18 Jakub Jelinek 2012-03-13 13:04:30 UTC
Fixed in 4.5+, 4.4 is no longer supported.