public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs.
@ 2010-12-07 23:01 Sebastian Pop
  2010-12-08  0:14 ` Sebastian Pop
  0 siblings, 1 reply; 7+ messages in thread
From: Sebastian Pop @ 2010-12-07 23:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther, Sebastian Pop

Hi,

First we were calling gimple_assign_rhs1 on a function call, and this
patch avoids this.  Then we were constructing a strange MEM_REF:
MEM[(unsigned char *)&u1.buf] = 0; because an ADDR_EXPR is considered
simple in force_gimple_operand.  This patch forces the result of the
gimplified expression to be in a new variable that can then be used to
rename the old variable.

I am testing this patch on amd64-linux.  Ok for trunk?

Thanks,
Sebastian

2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>

	PR tree-optimization/45230
	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
	only on the RHS of a GIMPLE_ASSIGN.  Call force_gimple_operand with
	a new variable.

	* gcc.dg/graphite/id-pr45230-1.c: New.
---
 gcc/ChangeLog                                |    7 ++
 gcc/sese.c                                   |   14 ++--
 gcc/testsuite/ChangeLog                      |    5 +
 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c |  140 ++++++++++++++++++++++++++
 4 files changed, 159 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff52686..e285f41 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/45230
+	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
+	only on the RHS of a GIMPLE_ASSIGN.  Call force_gimple_operand with
+	a new variable.
+
 2010-12-07  Paul Koning  <ni1d@arrl.net>
 
 	* config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define.
diff --git a/gcc/sese.c b/gcc/sese.c
index 65f8556..6de2d3b 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -492,7 +492,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
   FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
     {
       tree old_name = USE_FROM_PTR (use_p);
-      tree new_expr, scev;
+      tree new_expr, scev, var;
       gimple_seq stmts;
 
       if (TREE_CODE (old_name) != SSA_NAME
@@ -510,13 +510,12 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 	      || (TREE_CODE (new_expr) != SSA_NAME
 		  && is_gimple_reg (old_name)))
 	    {
-	      tree var = create_tmp_var (type_old_name, "var");
+	      var = create_tmp_var (type_old_name, "var");
 
 	      if (type_old_name != type_new_expr)
 		new_expr = fold_convert (type_old_name, new_expr);
 
-	      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
-	      new_expr = force_gimple_operand (new_expr, &stmts, true, NULL);
+	      new_expr = force_gimple_operand (new_expr, &stmts, true, var);
 	      gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
 	    }
 
@@ -542,13 +541,14 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 		  && !tree_contains_chrecs (new_expr, NULL));
 
       /* Replace the old_name with the new_expr.  */
+      var = create_tmp_var (TREE_TYPE (old_name), "var");
       new_expr = force_gimple_operand (unshare_expr (new_expr), &stmts,
-				       true, NULL_TREE);
+				       true, var);
       gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
       replace_exp (use_p, new_expr);
 
-
-      if (TREE_CODE (new_expr) == INTEGER_CST)
+      if (TREE_CODE (new_expr) == INTEGER_CST
+	  && gimple_code (copy) == GIMPLE_ASSIGN)
 	{
 	  tree rhs = gimple_assign_rhs1 (copy);
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 96275ed..52be35c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
 2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
 
+	PR tree-optimization/45230
+	* gcc.dg/graphite/id-pr45230-1.c: New.
+
+2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
+
 	PR tree-optimization/44676
 	* gcc.dg/graphite/id-pr44676.c: New.
 
diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
new file mode 100644
index 0000000..ba14fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 2002  Free Software Foundation.
+
+   Test strncmp with various combinations of pointer alignments and lengths to
+   make sure any optimizations in the library are correct.
+
+   Written by Michael Meissner, March 9, 2002.  */
+
+#include <string.h>
+#include <stddef.h>
+
+#ifndef MAX_OFFSET
+#define MAX_OFFSET (sizeof (long long))
+#endif
+
+#ifndef MAX_TEST
+#define MAX_TEST (8 * sizeof (long long))
+#endif
+
+#ifndef MAX_EXTRA
+#define MAX_EXTRA (sizeof (long long))
+#endif
+
+#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
+
+static union {
+  unsigned char buf[MAX_LENGTH];
+  long long align_int;
+  long double align_fp;
+} u1, u2;
+
+void
+test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
+{
+  int value = strncmp ((char *) s1, (char *) s2, len);
+
+  if (expected < 0 && value >= 0)
+    __builtin_abort ();
+  else if (expected == 0 && value != 0)
+    __builtin_abort ();
+  else if (expected > 0 && value <= 0)
+    __builtin_abort ();
+}
+
+main ()
+{
+  size_t off1, off2, len, i;
+  unsigned char *buf1, *buf2;
+  unsigned char *mod1, *mod2;
+  unsigned char *p1, *p2;
+
+  for (off1 = 0; off1 < MAX_OFFSET; off1++)
+    for (off2 = 0; off2 < MAX_OFFSET; off2++)
+      for (len = 0; len < MAX_TEST; len++)
+	{
+	  p1 = u1.buf;
+	  for (i = 0; i < off1; i++)
+	    *p1++ = '\0';
+
+	  buf1 = p1;
+	  for (i = 0; i < len; i++)
+	    *p1++ = 'a';
+
+	  mod1 = p1;
+	  for (i = 0; i < MAX_EXTRA; i++)
+	    *p1++ = 'x';
+
+	  p2 = u2.buf;
+	  for (i = 0; i < off2; i++)
+	    *p2++ = '\0';
+
+	  buf2 = p2;
+	  for (i = 0; i < len; i++)
+	    *p2++ = 'a';
+
+	  mod2 = p2;
+	  for (i = 0; i < MAX_EXTRA; i++)
+	    *p2++ = 'x';
+
+	  mod1[0] = '\0';
+	  mod2[0] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, 0);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'a';
+	  mod1[1] = '\0';
+	  mod2[0] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = '\0';
+	  mod2[0] = 'a';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'b';
+	  mod1[1] = '\0';
+	  mod2[0] = 'c';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'c';
+	  mod1[1] = '\0';
+	  mod2[0] = 'b';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'b';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\251';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\251';
+	  mod1[1] = '\0';
+	  mod2[0] = 'b';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\251';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\252';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\252';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\251';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+	}
+
+  __builtin_exit (0);
+}
-- 
1.7.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs.
  2010-12-07 23:01 [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs Sebastian Pop
@ 2010-12-08  0:14 ` Sebastian Pop
  2010-12-08  8:22   ` Sebastian Pop
                     ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Sebastian Pop @ 2010-12-08  0:14 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther, Sebastian Pop

Hi,

This is a slightly modified version of the previous patch: apparently
force_gimple_operand does not create the MODIFY_EXPR when the
expression is already simple, so this time we create the MODIFY_EXPR
before calling force_gimple_operand.  This fixes one more bug.

Ok for trunk after regstrap on amd64-linux?

Thanks,
Sebastian

2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>

	PR tree-optimization/45230
	PR tree-optimization/45370
	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
	only on the RHS of a GIMPLE_ASSIGN.  Assign the new expression to
	a new variable before renaming.

	* gcc.dg/graphite/id-pr45230-1.c: New.
	* gfortran.dg/graphite/id-pr45370.f90: New.
---
 gcc/ChangeLog                                     |    8 ++
 gcc/sese.c                                        |   15 ++-
 gcc/testsuite/ChangeLog                           |    7 +
 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c      |  140 +++++++++++++++++++++
 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 |  103 +++++++++++++++
 5 files changed, 267 insertions(+), 6 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
 create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff52686..77eea2d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/45230
+	PR tree-optimization/45370
+	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
+	only on the RHS of a GIMPLE_ASSIGN.  Assign the new expression to
+	a new variable before renaming.
+
 2010-12-07  Paul Koning  <ni1d@arrl.net>
 
 	* config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define.
diff --git a/gcc/sese.c b/gcc/sese.c
index 65f8556..7741bdf 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -492,7 +492,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
   FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
     {
       tree old_name = USE_FROM_PTR (use_p);
-      tree new_expr, scev;
+      tree type_old_name = TREE_TYPE (old_name);
+      tree new_expr, scev, var;
       gimple_seq stmts;
 
       if (TREE_CODE (old_name) != SSA_NAME
@@ -503,20 +504,20 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
       new_expr = get_rename (rename_map, old_name);
       if (new_expr)
 	{
-	  tree type_old_name = TREE_TYPE (old_name);
 	  tree type_new_expr = TREE_TYPE (new_expr);
 
 	  if (type_old_name != type_new_expr
 	      || (TREE_CODE (new_expr) != SSA_NAME
 		  && is_gimple_reg (old_name)))
 	    {
-	      tree var = create_tmp_var (type_old_name, "var");
+	      var = create_tmp_var (type_old_name, "var");
 
 	      if (type_old_name != type_new_expr)
 		new_expr = fold_convert (type_old_name, new_expr);
 
 	      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
-	      new_expr = force_gimple_operand (new_expr, &stmts, true, NULL);
+	      new_expr = force_gimple_operand (new_expr, &stmts, true,
+					       NULL_TREE);
 	      gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
 	    }
 
@@ -542,13 +543,15 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 		  && !tree_contains_chrecs (new_expr, NULL));
 
       /* Replace the old_name with the new_expr.  */
+      var = create_tmp_var (type_old_name, "var");
+      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
       new_expr = force_gimple_operand (unshare_expr (new_expr), &stmts,
 				       true, NULL_TREE);
       gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
       replace_exp (use_p, new_expr);
 
-
-      if (TREE_CODE (new_expr) == INTEGER_CST)
+      if (TREE_CODE (new_expr) == INTEGER_CST
+	  && gimple_code (copy) == GIMPLE_ASSIGN)
 	{
 	  tree rhs = gimple_assign_rhs1 (copy);
 
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 96275ed..71d73d6 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,12 @@
 2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
 
+	PR tree-optimization/45230
+	PR tree-optimization/45370
+	* gcc.dg/graphite/id-pr45230-1.c: New.
+	* gfortran.dg/graphite/id-pr45370.f90: New.
+
+2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
+
 	PR tree-optimization/44676
 	* gcc.dg/graphite/id-pr44676.c: New.
 
diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
new file mode 100644
index 0000000..ba14fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 2002  Free Software Foundation.
+
+   Test strncmp with various combinations of pointer alignments and lengths to
+   make sure any optimizations in the library are correct.
+
+   Written by Michael Meissner, March 9, 2002.  */
+
+#include <string.h>
+#include <stddef.h>
+
+#ifndef MAX_OFFSET
+#define MAX_OFFSET (sizeof (long long))
+#endif
+
+#ifndef MAX_TEST
+#define MAX_TEST (8 * sizeof (long long))
+#endif
+
+#ifndef MAX_EXTRA
+#define MAX_EXTRA (sizeof (long long))
+#endif
+
+#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
+
+static union {
+  unsigned char buf[MAX_LENGTH];
+  long long align_int;
+  long double align_fp;
+} u1, u2;
+
+void
+test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
+{
+  int value = strncmp ((char *) s1, (char *) s2, len);
+
+  if (expected < 0 && value >= 0)
+    __builtin_abort ();
+  else if (expected == 0 && value != 0)
+    __builtin_abort ();
+  else if (expected > 0 && value <= 0)
+    __builtin_abort ();
+}
+
+main ()
+{
+  size_t off1, off2, len, i;
+  unsigned char *buf1, *buf2;
+  unsigned char *mod1, *mod2;
+  unsigned char *p1, *p2;
+
+  for (off1 = 0; off1 < MAX_OFFSET; off1++)
+    for (off2 = 0; off2 < MAX_OFFSET; off2++)
+      for (len = 0; len < MAX_TEST; len++)
+	{
+	  p1 = u1.buf;
+	  for (i = 0; i < off1; i++)
+	    *p1++ = '\0';
+
+	  buf1 = p1;
+	  for (i = 0; i < len; i++)
+	    *p1++ = 'a';
+
+	  mod1 = p1;
+	  for (i = 0; i < MAX_EXTRA; i++)
+	    *p1++ = 'x';
+
+	  p2 = u2.buf;
+	  for (i = 0; i < off2; i++)
+	    *p2++ = '\0';
+
+	  buf2 = p2;
+	  for (i = 0; i < len; i++)
+	    *p2++ = 'a';
+
+	  mod2 = p2;
+	  for (i = 0; i < MAX_EXTRA; i++)
+	    *p2++ = 'x';
+
+	  mod1[0] = '\0';
+	  mod2[0] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, 0);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'a';
+	  mod1[1] = '\0';
+	  mod2[0] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = '\0';
+	  mod2[0] = 'a';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'b';
+	  mod1[1] = '\0';
+	  mod2[0] = 'c';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'c';
+	  mod1[1] = '\0';
+	  mod2[0] = 'b';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'b';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\251';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\251';
+	  mod1[1] = '\0';
+	  mod2[0] = 'b';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\251';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\252';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\252';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\251';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+	}
+
+  __builtin_exit (0);
+}
diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
new file mode 100644
index 0000000..e96d755
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
@@ -0,0 +1,103 @@
+! { dg-do run }
+! Test the fix for PRs29396, 29606, 30625 and 30871, in which pointers
+! to arrays with subreferences did not work.
+!
+  type :: t
+    real :: r
+    integer :: i
+    character(3) :: chr
+  end type t
+
+  type :: t2
+    real :: r(2, 2)
+    integer :: i
+    character(3) :: chr
+  end type t2
+
+  type :: s
+    type(t), pointer :: t(:)
+  end type s
+
+  integer, parameter :: sh(2) = (/2,2/)
+  real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh)
+  real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh)
+
+  type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/)
+  character(4), target :: tar2(2) = (/"abcd","efgh"/)
+  type(s), target :: tar3
+  character(2), target :: tar4(2) = (/"ab","cd"/)
+  type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/)
+
+  integer, pointer :: ptr(:)
+  character(2), pointer :: ptr2(:)
+  real, pointer :: ptr3(:)
+
+!_______________component subreference___________
+  ptr => tar1%i
+  ptr = ptr + 1              ! check the scalarizer is OK
+
+  if (any (ptr .ne. (/3, 5/))) call abort ()
+  if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort ()
+  if (any (tar1%i .ne. (/3, 5/))) call abort ()
+
+! Make sure that the other components are not touched.
+  if (any (tar1%r .ne. (/1.0, 3.0/))) call abort ()
+  if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort ()
+
+! Check that the pointer is passed correctly as an actual argument.
+  call foo (ptr)
+  if (any (tar1%i .ne. (/2, 4/))) call abort ()
+
+! And that dummy pointers are OK too.
+  call bar (ptr)
+  if (any (tar1%i .ne. (/101, 103/))) call abort ()
+
+!_______________substring subreference___________
+  ptr2 => tar2(:)(2:3)
+  ptr2 = ptr2(:)(2:2)//"z"   ! again, check the scalarizer
+
+  if (any (ptr2 .ne. (/"cz", "gz"/))) call abort ()
+  if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort ()
+  if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort ()
+
+!_______________substring component subreference___________
+  ptr2 => tar1(:)%chr(1:2)
+  ptr2 = ptr2(:)(2:2)//"q"   ! yet again, check the scalarizer
+  if (any (ptr2 .ne. (/"bq","fq"/))) call abort ()
+  if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort ()
+
+!_______________trailing array element subreference___________
+  ptr3 => tar5%r(1,2)
+  ptr3 = (/99.0, 999.0/)
+  if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort ()
+  if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort ()
+
+!_______________forall assignment___________
+  ptr2 => tar2(:)(1:2)
+  forall (i = 1:2) ptr2(i)(1:1) = "z"
+  if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort ()
+
+!_______________something more complicated___________
+  tar3%t => tar1
+  ptr3 => tar3%t%r
+  ptr3 = cos (ptr3)
+  if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort ()
+
+  ptr2 => tar3%t(:)%chr(2:3)
+  ptr2 = " x"
+  if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort ()
+
+!_______________check non-subref works still___________
+  ptr2 => tar4
+  if (any (ptr2 .ne. (/"ab","cd"/))) call abort ()
+
+contains
+  subroutine foo (arg)
+    integer :: arg(:)
+    arg = arg - 1
+  end subroutine
+  subroutine bar (arg)
+    integer, pointer :: arg(:)
+    arg = arg + 99
+  end subroutine
+end
-- 
1.7.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs.
  2010-12-08  0:14 ` Sebastian Pop
@ 2010-12-08  8:22   ` Sebastian Pop
  2010-12-08 11:57   ` Richard Guenther
  2010-12-08 14:29   ` [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs Jack Howarth
  2 siblings, 0 replies; 7+ messages in thread
From: Sebastian Pop @ 2010-12-08  8:22 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther, Sebastian Pop

On Tue, Dec 7, 2010 at 17:01, Sebastian Pop <sebpop@gmail.com> wrote:
> Hi,
>
> This is a slightly modified version of the previous patch: apparently
> force_gimple_operand does not create the MODIFY_EXPR when the
> expression is already simple, so this time we create the MODIFY_EXPR
> before calling force_gimple_operand.  This fixes one more bug.
>
> Ok for trunk after regstrap on amd64-linux?

This patch passed regstrap.  It also fixes http://gcc.gnu.org/PR45231

Sebastian

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs.
  2010-12-08  0:14 ` Sebastian Pop
  2010-12-08  8:22   ` Sebastian Pop
@ 2010-12-08 11:57   ` Richard Guenther
  2010-12-08 20:46     ` [PATCH] Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp Sebastian Pop
  2010-12-08 14:29   ` [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs Jack Howarth
  2 siblings, 1 reply; 7+ messages in thread
From: Richard Guenther @ 2010-12-08 11:57 UTC (permalink / raw)
  To: Sebastian Pop; +Cc: gcc-patches

On Tue, 7 Dec 2010, Sebastian Pop wrote:

> Hi,
> 
> This is a slightly modified version of the previous patch: apparently
> force_gimple_operand does not create the MODIFY_EXPR when the
> expression is already simple, so this time we create the MODIFY_EXPR
> before calling force_gimple_operand.  This fixes one more bug.
> 
> Ok for trunk after regstrap on amd64-linux?

See below

> Thanks,
> Sebastian
> 
> 2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
> 
> 	PR tree-optimization/45230
> 	PR tree-optimization/45370
> 	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
> 	only on the RHS of a GIMPLE_ASSIGN.  Assign the new expression to
> 	a new variable before renaming.
> 
> 	* gcc.dg/graphite/id-pr45230-1.c: New.
> 	* gfortran.dg/graphite/id-pr45370.f90: New.
> ---
>  gcc/ChangeLog                                     |    8 ++
>  gcc/sese.c                                        |   15 ++-
>  gcc/testsuite/ChangeLog                           |    7 +
>  gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c      |  140 +++++++++++++++++++++
>  gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 |  103 +++++++++++++++
>  5 files changed, 267 insertions(+), 6 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
>  create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index ff52686..77eea2d 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,11 @@
> +2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
> +
> +	PR tree-optimization/45230
> +	PR tree-optimization/45370
> +	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
> +	only on the RHS of a GIMPLE_ASSIGN.  Assign the new expression to
> +	a new variable before renaming.
> +
>  2010-12-07  Paul Koning  <ni1d@arrl.net>
>  
>  	* config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define.
> diff --git a/gcc/sese.c b/gcc/sese.c
> index 65f8556..7741bdf 100644
> --- a/gcc/sese.c
> +++ b/gcc/sese.c
> @@ -492,7 +492,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>    FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
>      {
>        tree old_name = USE_FROM_PTR (use_p);
> -      tree new_expr, scev;
> +      tree type_old_name = TREE_TYPE (old_name);
> +      tree new_expr, scev, var;
>        gimple_seq stmts;
>  
>        if (TREE_CODE (old_name) != SSA_NAME
> @@ -503,20 +504,20 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>        new_expr = get_rename (rename_map, old_name);
>        if (new_expr)
>  	{
> -	  tree type_old_name = TREE_TYPE (old_name);
>  	  tree type_new_expr = TREE_TYPE (new_expr);
>  
>  	  if (type_old_name != type_new_expr
>  	      || (TREE_CODE (new_expr) != SSA_NAME
>  		  && is_gimple_reg (old_name)))
>  	    {
> -	      tree var = create_tmp_var (type_old_name, "var");
> +	      var = create_tmp_var (type_old_name, "var");
>  
>  	      if (type_old_name != type_new_expr)
>  		new_expr = fold_convert (type_old_name, new_expr);
>  
>  	      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
> -	      new_expr = force_gimple_operand (new_expr, &stmts, true, NULL);
> +	      new_expr = force_gimple_operand (new_expr, &stmts, true,
> +					       NULL_TREE);
>  	      gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
>  	    }
>  
> @@ -542,13 +543,15 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>  		  && !tree_contains_chrecs (new_expr, NULL));
>  
>        /* Replace the old_name with the new_expr.  */
> +      var = create_tmp_var (type_old_name, "var");
> +      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
>        new_expr = force_gimple_operand (unshare_expr (new_expr), &stmts,
>  				       true, NULL_TREE);
>        gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
>        replace_exp (use_p, new_expr);

We expect that you fold a statement when you use replace_exp on it.

Thus, the following would be more appropriate:

Index: gcc/sese.c
===================================================================
--- gcc/sese.c	(revision 167583)
+++ gcc/sese.c	(working copy)
@@ -472,12 +472,13 @@ set_rename (htab_t rename_map, tree old_
    statement in LOOP, and using the induction variable renaming map
    IV_MAP.  */
 
-static void
+static bool
 rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 	     sese region, loop_p loop, VEC (tree, heap) *iv_map)
 {
   use_operand_p use_p;
   ssa_op_iter op_iter;
+  bool changed = false;
 
   if (is_gimple_debug (copy))
     {
@@ -500,6 +501,7 @@ rename_uses (gimple copy, htab_t rename_
 	  || SSA_NAME_IS_DEFAULT_DEF (old_name))
 	continue;
 
+      changed = true;
       new_expr = get_rename (rename_map, old_name);
       if (new_expr)
 	{
@@ -547,8 +549,8 @@ rename_uses (gimple copy, htab_t rename_
       gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
       replace_exp (use_p, new_expr);
 
-
-      if (TREE_CODE (new_expr) == INTEGER_CST)
+      if (TREE_CODE (new_expr) == INTEGER_CST
+	  && is_gimple_assign (copy))
 	{
 	  tree rhs = gimple_assign_rhs1 (copy);
 
@@ -558,6 +560,8 @@ rename_uses (gimple copy, htab_t rename_
 
       set_rename (rename_map, old_name, new_expr);
     }
+
+  return changed;
 }
 
 /* Duplicates the statements of basic block BB into basic block NEW_BB
@@ -611,7 +615,8 @@ graphite_copy_stmts_from_block (basic_bl
 	  set_rename (rename_map, old_name, new_name);
  	}
 
-      rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map);
+      if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map))
+	fold_stmt_inplace (copy);
 
       update_stmt (copy);
     }

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs.
  2010-12-08  0:14 ` Sebastian Pop
  2010-12-08  8:22   ` Sebastian Pop
  2010-12-08 11:57   ` Richard Guenther
@ 2010-12-08 14:29   ` Jack Howarth
  2 siblings, 0 replies; 7+ messages in thread
From: Jack Howarth @ 2010-12-08 14:29 UTC (permalink / raw)
  To: Sebastian Pop; +Cc: gcc-patches, rguenther

On Tue, Dec 07, 2010 at 05:01:19PM -0600, Sebastian Pop wrote:
> Hi,
> 
> This is a slightly modified version of the previous patch: apparently
> force_gimple_operand does not create the MODIFY_EXPR when the
> expression is already simple, so this time we create the MODIFY_EXPR
> before calling force_gimple_operand.  This fixes one more bug.
> 
> Ok for trunk after regstrap on amd64-linux?

Sebastian,
   Testresults for this patch on current gcc trunk under x86_64-apple-darwin10
are at http://gcc.gnu.org/ml/gcc-testresults/2010-12/msg00666.html. Both
PR45230 and PR45370 are fixed at -m32/-m64. Thanks.
            Jack

> 
> Thanks,
> Sebastian
> 
> 2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
> 
> 	PR tree-optimization/45230
> 	PR tree-optimization/45370
> 	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
> 	only on the RHS of a GIMPLE_ASSIGN.  Assign the new expression to
> 	a new variable before renaming.
> 
> 	* gcc.dg/graphite/id-pr45230-1.c: New.
> 	* gfortran.dg/graphite/id-pr45370.f90: New.
> ---
>  gcc/ChangeLog                                     |    8 ++
>  gcc/sese.c                                        |   15 ++-
>  gcc/testsuite/ChangeLog                           |    7 +
>  gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c      |  140 +++++++++++++++++++++
>  gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 |  103 +++++++++++++++
>  5 files changed, 267 insertions(+), 6 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
>  create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index ff52686..77eea2d 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,11 @@
> +2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
> +
> +	PR tree-optimization/45230
> +	PR tree-optimization/45370
> +	* sese.c (rename_uses): Call recompute_tree_invariant_for_addr_expr
> +	only on the RHS of a GIMPLE_ASSIGN.  Assign the new expression to
> +	a new variable before renaming.
> +
>  2010-12-07  Paul Koning  <ni1d@arrl.net>
>  
>  	* config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define.
> diff --git a/gcc/sese.c b/gcc/sese.c
> index 65f8556..7741bdf 100644
> --- a/gcc/sese.c
> +++ b/gcc/sese.c
> @@ -492,7 +492,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>    FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
>      {
>        tree old_name = USE_FROM_PTR (use_p);
> -      tree new_expr, scev;
> +      tree type_old_name = TREE_TYPE (old_name);
> +      tree new_expr, scev, var;
>        gimple_seq stmts;
>  
>        if (TREE_CODE (old_name) != SSA_NAME
> @@ -503,20 +504,20 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>        new_expr = get_rename (rename_map, old_name);
>        if (new_expr)
>  	{
> -	  tree type_old_name = TREE_TYPE (old_name);
>  	  tree type_new_expr = TREE_TYPE (new_expr);
>  
>  	  if (type_old_name != type_new_expr
>  	      || (TREE_CODE (new_expr) != SSA_NAME
>  		  && is_gimple_reg (old_name)))
>  	    {
> -	      tree var = create_tmp_var (type_old_name, "var");
> +	      var = create_tmp_var (type_old_name, "var");
>  
>  	      if (type_old_name != type_new_expr)
>  		new_expr = fold_convert (type_old_name, new_expr);
>  
>  	      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
> -	      new_expr = force_gimple_operand (new_expr, &stmts, true, NULL);
> +	      new_expr = force_gimple_operand (new_expr, &stmts, true,
> +					       NULL_TREE);
>  	      gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
>  	    }
>  
> @@ -542,13 +543,15 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>  		  && !tree_contains_chrecs (new_expr, NULL));
>  
>        /* Replace the old_name with the new_expr.  */
> +      var = create_tmp_var (type_old_name, "var");
> +      new_expr = build2 (MODIFY_EXPR, type_old_name, var, new_expr);
>        new_expr = force_gimple_operand (unshare_expr (new_expr), &stmts,
>  				       true, NULL_TREE);
>        gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
>        replace_exp (use_p, new_expr);
>  
> -
> -      if (TREE_CODE (new_expr) == INTEGER_CST)
> +      if (TREE_CODE (new_expr) == INTEGER_CST
> +	  && gimple_code (copy) == GIMPLE_ASSIGN)
>  	{
>  	  tree rhs = gimple_assign_rhs1 (copy);
>  
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 96275ed..71d73d6 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,5 +1,12 @@
>  2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
>  
> +	PR tree-optimization/45230
> +	PR tree-optimization/45370
> +	* gcc.dg/graphite/id-pr45230-1.c: New.
> +	* gfortran.dg/graphite/id-pr45370.f90: New.
> +
> +2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
> +
>  	PR tree-optimization/44676
>  	* gcc.dg/graphite/id-pr44676.c: New.
>  
> diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
> new file mode 100644
> index 0000000..ba14fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
> @@ -0,0 +1,140 @@
> +/* Copyright (C) 2002  Free Software Foundation.
> +
> +   Test strncmp with various combinations of pointer alignments and lengths to
> +   make sure any optimizations in the library are correct.
> +
> +   Written by Michael Meissner, March 9, 2002.  */
> +
> +#include <string.h>
> +#include <stddef.h>
> +
> +#ifndef MAX_OFFSET
> +#define MAX_OFFSET (sizeof (long long))
> +#endif
> +
> +#ifndef MAX_TEST
> +#define MAX_TEST (8 * sizeof (long long))
> +#endif
> +
> +#ifndef MAX_EXTRA
> +#define MAX_EXTRA (sizeof (long long))
> +#endif
> +
> +#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
> +
> +static union {
> +  unsigned char buf[MAX_LENGTH];
> +  long long align_int;
> +  long double align_fp;
> +} u1, u2;
> +
> +void
> +test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
> +{
> +  int value = strncmp ((char *) s1, (char *) s2, len);
> +
> +  if (expected < 0 && value >= 0)
> +    __builtin_abort ();
> +  else if (expected == 0 && value != 0)
> +    __builtin_abort ();
> +  else if (expected > 0 && value <= 0)
> +    __builtin_abort ();
> +}
> +
> +main ()
> +{
> +  size_t off1, off2, len, i;
> +  unsigned char *buf1, *buf2;
> +  unsigned char *mod1, *mod2;
> +  unsigned char *p1, *p2;
> +
> +  for (off1 = 0; off1 < MAX_OFFSET; off1++)
> +    for (off2 = 0; off2 < MAX_OFFSET; off2++)
> +      for (len = 0; len < MAX_TEST; len++)
> +	{
> +	  p1 = u1.buf;
> +	  for (i = 0; i < off1; i++)
> +	    *p1++ = '\0';
> +
> +	  buf1 = p1;
> +	  for (i = 0; i < len; i++)
> +	    *p1++ = 'a';
> +
> +	  mod1 = p1;
> +	  for (i = 0; i < MAX_EXTRA; i++)
> +	    *p1++ = 'x';
> +
> +	  p2 = u2.buf;
> +	  for (i = 0; i < off2; i++)
> +	    *p2++ = '\0';
> +
> +	  buf2 = p2;
> +	  for (i = 0; i < len; i++)
> +	    *p2++ = 'a';
> +
> +	  mod2 = p2;
> +	  for (i = 0; i < MAX_EXTRA; i++)
> +	    *p2++ = 'x';
> +
> +	  mod1[0] = '\0';
> +	  mod2[0] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, 0);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'a';
> +	  mod1[1] = '\0';
> +	  mod2[0] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = '\0';
> +	  mod2[0] = 'a';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'b';
> +	  mod1[1] = '\0';
> +	  mod2[0] = 'c';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'c';
> +	  mod1[1] = '\0';
> +	  mod2[0] = 'b';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'b';
> +	  mod1[1] = '\0';
> +	  mod2[0] = (unsigned char)'\251';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = (unsigned char)'\251';
> +	  mod1[1] = '\0';
> +	  mod2[0] = 'b';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = (unsigned char)'\251';
> +	  mod1[1] = '\0';
> +	  mod2[0] = (unsigned char)'\252';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = (unsigned char)'\252';
> +	  mod1[1] = '\0';
> +	  mod2[0] = (unsigned char)'\251';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +	}
> +
> +  __builtin_exit (0);
> +}
> diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> new file mode 100644
> index 0000000..e96d755
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> @@ -0,0 +1,103 @@
> +! { dg-do run }
> +! Test the fix for PRs29396, 29606, 30625 and 30871, in which pointers
> +! to arrays with subreferences did not work.
> +!
> +  type :: t
> +    real :: r
> +    integer :: i
> +    character(3) :: chr
> +  end type t
> +
> +  type :: t2
> +    real :: r(2, 2)
> +    integer :: i
> +    character(3) :: chr
> +  end type t2
> +
> +  type :: s
> +    type(t), pointer :: t(:)
> +  end type s
> +
> +  integer, parameter :: sh(2) = (/2,2/)
> +  real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh)
> +  real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh)
> +
> +  type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/)
> +  character(4), target :: tar2(2) = (/"abcd","efgh"/)
> +  type(s), target :: tar3
> +  character(2), target :: tar4(2) = (/"ab","cd"/)
> +  type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/)
> +
> +  integer, pointer :: ptr(:)
> +  character(2), pointer :: ptr2(:)
> +  real, pointer :: ptr3(:)
> +
> +!_______________component subreference___________
> +  ptr => tar1%i
> +  ptr = ptr + 1              ! check the scalarizer is OK
> +
> +  if (any (ptr .ne. (/3, 5/))) call abort ()
> +  if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort ()
> +  if (any (tar1%i .ne. (/3, 5/))) call abort ()
> +
> +! Make sure that the other components are not touched.
> +  if (any (tar1%r .ne. (/1.0, 3.0/))) call abort ()
> +  if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort ()
> +
> +! Check that the pointer is passed correctly as an actual argument.
> +  call foo (ptr)
> +  if (any (tar1%i .ne. (/2, 4/))) call abort ()
> +
> +! And that dummy pointers are OK too.
> +  call bar (ptr)
> +  if (any (tar1%i .ne. (/101, 103/))) call abort ()
> +
> +!_______________substring subreference___________
> +  ptr2 => tar2(:)(2:3)
> +  ptr2 = ptr2(:)(2:2)//"z"   ! again, check the scalarizer
> +
> +  if (any (ptr2 .ne. (/"cz", "gz"/))) call abort ()
> +  if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort ()
> +  if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort ()
> +
> +!_______________substring component subreference___________
> +  ptr2 => tar1(:)%chr(1:2)
> +  ptr2 = ptr2(:)(2:2)//"q"   ! yet again, check the scalarizer
> +  if (any (ptr2 .ne. (/"bq","fq"/))) call abort ()
> +  if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort ()
> +
> +!_______________trailing array element subreference___________
> +  ptr3 => tar5%r(1,2)
> +  ptr3 = (/99.0, 999.0/)
> +  if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort ()
> +  if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort ()
> +
> +!_______________forall assignment___________
> +  ptr2 => tar2(:)(1:2)
> +  forall (i = 1:2) ptr2(i)(1:1) = "z"
> +  if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort ()
> +
> +!_______________something more complicated___________
> +  tar3%t => tar1
> +  ptr3 => tar3%t%r
> +  ptr3 = cos (ptr3)
> +  if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort ()
> +
> +  ptr2 => tar3%t(:)%chr(2:3)
> +  ptr2 = " x"
> +  if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort ()
> +
> +!_______________check non-subref works still___________
> +  ptr2 => tar4
> +  if (any (ptr2 .ne. (/"ab","cd"/))) call abort ()
> +
> +contains
> +  subroutine foo (arg)
> +    integer :: arg(:)
> +    arg = arg - 1
> +  end subroutine
> +  subroutine bar (arg)
> +    integer, pointer :: arg(:)
> +    arg = arg + 99
> +  end subroutine
> +end
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp.
  2010-12-08 11:57   ` Richard Guenther
@ 2010-12-08 20:46     ` Sebastian Pop
  2010-12-08 21:27       ` Richard Guenther
  0 siblings, 1 reply; 7+ messages in thread
From: Sebastian Pop @ 2010-12-08 20:46 UTC (permalink / raw)
  To: gcc-patches; +Cc: rguenther, Sebastian Pop

Hi,

I am testing this patch on amd64-linux.  Ok for trunk if that passes?

Thanks,
Sebastian

2010-12-08  Richard Guenther  <rguenther@suse.de>
	    Sebastian Pop  <sebastian.pop@amd.com>

	PR tree-optimization/45230
	PR tree-optimization/45231
	PR tree-optimization/45370
	* sese.c (rename_uses): Returns a bool.  Call
	recompute_tree_invariant_for_addr_expr only on the RHS of a
	GIMPLE_ASSIGN.
	(graphite_copy_stmts_from_block): Call fold_stmt_inplace when
	rename_uses returns true.
	* tree-ssa-copy.c (replace_exp): Add a comment about calling
	fold_stmt_inplace after replace_exp.

	* gcc.dg/graphite/id-pr45230-1.c: New.
	* gcc.dg/graphite/id-pr45231.c: New.
	* gfortran.dg/graphite/id-pr45370.f90: New.
---
 gcc/ChangeLog                                     |   14 ++
 gcc/sese.c                                        |   17 ++-
 gcc/testsuite/ChangeLog                           |   10 ++
 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c      |  140 +++++++++++++++++++++
 gcc/testsuite/gcc.dg/graphite/id-pr45231.c        |   37 ++++++
 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 |  100 +++++++++++++++
 gcc/tree-ssa-copy.c                               |    5 +-
 7 files changed, 316 insertions(+), 7 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
 create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45231.c
 create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff52686..95bd5c0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2010-12-08  Richard Guenther  <rguenther@suse.de>
+	    Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/45230
+	PR tree-optimization/45231
+	PR tree-optimization/45370
+	* sese.c (rename_uses): Returns a bool.  Call
+	recompute_tree_invariant_for_addr_expr only on the RHS of a
+	GIMPLE_ASSIGN.
+	(graphite_copy_stmts_from_block): Call fold_stmt_inplace when
+	rename_uses returns true.
+	* tree-ssa-copy.c (replace_exp): Add a comment about calling
+	fold_stmt_inplace after replace_exp.
+
 2010-12-07  Paul Koning  <ni1d@arrl.net>
 
 	* config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define.
diff --git a/gcc/sese.c b/gcc/sese.c
index 65f8556..3bf6bea 100644
--- a/gcc/sese.c
+++ b/gcc/sese.c
@@ -470,14 +470,15 @@ set_rename (htab_t rename_map, tree old_name, tree expr)
    substitution map RENAME_MAP, inserting the gimplification code at
    GSI_TGT, for the translation REGION, with the original copied
    statement in LOOP, and using the induction variable renaming map
-   IV_MAP.  */
+   IV_MAP.  Returns true when something has been renamed.  */
 
-static void
+static bool
 rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 	     sese region, loop_p loop, VEC (tree, heap) *iv_map)
 {
   use_operand_p use_p;
   ssa_op_iter op_iter;
+  bool changed = false;
 
   if (is_gimple_debug (copy))
     {
@@ -486,7 +487,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
       else
 	gcc_unreachable ();
 
-      return;
+      return false;
     }
 
   FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
@@ -500,6 +501,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 	  || SSA_NAME_IS_DEFAULT_DEF (old_name))
 	continue;
 
+      changed = true;
       new_expr = get_rename (rename_map, old_name);
       if (new_expr)
 	{
@@ -547,8 +549,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
       gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
       replace_exp (use_p, new_expr);
 
-
-      if (TREE_CODE (new_expr) == INTEGER_CST)
+      if (TREE_CODE (new_expr) == INTEGER_CST
+	  && is_gimple_assign (copy))
 	{
 	  tree rhs = gimple_assign_rhs1 (copy);
 
@@ -558,6 +560,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
 
       set_rename (rename_map, old_name, new_expr);
     }
+
+  return changed;
 }
 
 /* Duplicates the statements of basic block BB into basic block NEW_BB
@@ -611,7 +615,8 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
 	  set_rename (rename_map, old_name, new_name);
  	}
 
-      rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map);
+      if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map))
+	fold_stmt_inplace (copy);
 
       update_stmt (copy);
     }
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 96275ed..3cf399d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,13 @@
+2010-12-08  Richard Guenther  <rguenther@suse.de>
+	    Sebastian Pop  <sebastian.pop@amd.com>
+
+	PR tree-optimization/45230
+	PR tree-optimization/45231
+	PR tree-optimization/45370
+	* gcc.dg/graphite/id-pr45230-1.c: New.
+	* gcc.dg/graphite/id-pr45231.c: New.
+	* gfortran.dg/graphite/id-pr45370.f90: New.
+
 2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
 
 	PR tree-optimization/44676
diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
new file mode 100644
index 0000000..ba14fe5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 2002  Free Software Foundation.
+
+   Test strncmp with various combinations of pointer alignments and lengths to
+   make sure any optimizations in the library are correct.
+
+   Written by Michael Meissner, March 9, 2002.  */
+
+#include <string.h>
+#include <stddef.h>
+
+#ifndef MAX_OFFSET
+#define MAX_OFFSET (sizeof (long long))
+#endif
+
+#ifndef MAX_TEST
+#define MAX_TEST (8 * sizeof (long long))
+#endif
+
+#ifndef MAX_EXTRA
+#define MAX_EXTRA (sizeof (long long))
+#endif
+
+#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
+
+static union {
+  unsigned char buf[MAX_LENGTH];
+  long long align_int;
+  long double align_fp;
+} u1, u2;
+
+void
+test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
+{
+  int value = strncmp ((char *) s1, (char *) s2, len);
+
+  if (expected < 0 && value >= 0)
+    __builtin_abort ();
+  else if (expected == 0 && value != 0)
+    __builtin_abort ();
+  else if (expected > 0 && value <= 0)
+    __builtin_abort ();
+}
+
+main ()
+{
+  size_t off1, off2, len, i;
+  unsigned char *buf1, *buf2;
+  unsigned char *mod1, *mod2;
+  unsigned char *p1, *p2;
+
+  for (off1 = 0; off1 < MAX_OFFSET; off1++)
+    for (off2 = 0; off2 < MAX_OFFSET; off2++)
+      for (len = 0; len < MAX_TEST; len++)
+	{
+	  p1 = u1.buf;
+	  for (i = 0; i < off1; i++)
+	    *p1++ = '\0';
+
+	  buf1 = p1;
+	  for (i = 0; i < len; i++)
+	    *p1++ = 'a';
+
+	  mod1 = p1;
+	  for (i = 0; i < MAX_EXTRA; i++)
+	    *p1++ = 'x';
+
+	  p2 = u2.buf;
+	  for (i = 0; i < off2; i++)
+	    *p2++ = '\0';
+
+	  buf2 = p2;
+	  for (i = 0; i < len; i++)
+	    *p2++ = 'a';
+
+	  mod2 = p2;
+	  for (i = 0; i < MAX_EXTRA; i++)
+	    *p2++ = 'x';
+
+	  mod1[0] = '\0';
+	  mod2[0] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, 0);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'a';
+	  mod1[1] = '\0';
+	  mod2[0] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = '\0';
+	  mod2[0] = 'a';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'b';
+	  mod1[1] = '\0';
+	  mod2[0] = 'c';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'c';
+	  mod1[1] = '\0';
+	  mod2[0] = 'b';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = 'b';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\251';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\251';
+	  mod1[1] = '\0';
+	  mod2[0] = 'b';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\251';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\252';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, -1);
+	  test (buf1, buf2, len, 0);
+
+	  mod1[0] = (unsigned char)'\252';
+	  mod1[1] = '\0';
+	  mod2[0] = (unsigned char)'\251';
+	  mod2[1] = '\0';
+	  test (buf1, buf2, MAX_LENGTH, +1);
+	  test (buf1, buf2, len, 0);
+	}
+
+  __builtin_exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45231.c b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c
new file mode 100644
index 0000000..01e9a67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c
@@ -0,0 +1,37 @@
+void
+f (n, ppt, xrot)
+{
+  int tileWidth;
+  int nlwSrc;
+  int srcx;
+  int v3, v4;
+  register unsigned long ca1, cx1, ca2, cx2;
+  unsigned long *pSrcLine;
+  register unsigned long *pDst;
+  register unsigned long *pSrc;
+  register unsigned long b, tmp;
+  unsigned long tileEndMask;
+  int v1, v2;
+  int tileEndPart;
+  int needFirst;
+  tileEndPart = 0;
+  v1 = tileEndPart << 5;
+  v2 = 32 - v1;
+  while (n--)
+    {
+      if ((srcx = (ppt - xrot) % tileWidth) < 0)
+	if (needFirst)
+	  if (nlwSrc == 1)
+	    {
+	      tmp = b;
+	      if (tileEndPart)
+		b = (*pSrc & tileEndMask) | (*pSrcLine >> v1);
+	    }
+      if (tileEndPart)
+	b = (tmp << v1) | (b >> v2);
+      if (v4 != 32)
+	*pDst = (*pDst & ((tmp << v3) | (b >> v4) & ca1 ^ cx1)
+		 ^ (((tmp << v3) | (b >> v4)) & ca2 ^ cx2));
+      *pDst = *pDst & tmp;
+    }
+}
diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
new file mode 100644
index 0000000..94eebd1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
@@ -0,0 +1,100 @@
+!
+  type :: t
+    real :: r
+    integer :: i
+    character(3) :: chr
+  end type t
+
+  type :: t2
+    real :: r(2, 2)
+    integer :: i
+    character(3) :: chr
+  end type t2
+
+  type :: s
+    type(t), pointer :: t(:)
+  end type s
+
+  integer, parameter :: sh(2) = (/2,2/)
+  real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh)
+  real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh)
+
+  type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/)
+  character(4), target :: tar2(2) = (/"abcd","efgh"/)
+  type(s), target :: tar3
+  character(2), target :: tar4(2) = (/"ab","cd"/)
+  type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/)
+
+  integer, pointer :: ptr(:)
+  character(2), pointer :: ptr2(:)
+  real, pointer :: ptr3(:)
+
+!_______________component subreference___________
+  ptr => tar1%i
+  ptr = ptr + 1              ! check the scalarizer is OK
+
+  if (any (ptr .ne. (/3, 5/))) call abort ()
+  if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort ()
+  if (any (tar1%i .ne. (/3, 5/))) call abort ()
+
+! Make sure that the other components are not touched.
+  if (any (tar1%r .ne. (/1.0, 3.0/))) call abort ()
+  if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort ()
+
+! Check that the pointer is passed correctly as an actual argument.
+  call foo (ptr)
+  if (any (tar1%i .ne. (/2, 4/))) call abort ()
+
+! And that dummy pointers are OK too.
+  call bar (ptr)
+  if (any (tar1%i .ne. (/101, 103/))) call abort ()
+
+!_______________substring subreference___________
+  ptr2 => tar2(:)(2:3)
+  ptr2 = ptr2(:)(2:2)//"z"   ! again, check the scalarizer
+
+  if (any (ptr2 .ne. (/"cz", "gz"/))) call abort ()
+  if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort ()
+  if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort ()
+
+!_______________substring component subreference___________
+  ptr2 => tar1(:)%chr(1:2)
+  ptr2 = ptr2(:)(2:2)//"q"   ! yet again, check the scalarizer
+  if (any (ptr2 .ne. (/"bq","fq"/))) call abort ()
+  if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort ()
+
+!_______________trailing array element subreference___________
+  ptr3 => tar5%r(1,2)
+  ptr3 = (/99.0, 999.0/)
+  if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort ()
+  if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort ()
+
+!_______________forall assignment___________
+  ptr2 => tar2(:)(1:2)
+  forall (i = 1:2) ptr2(i)(1:1) = "z"
+  if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort ()
+
+!_______________something more complicated___________
+  tar3%t => tar1
+  ptr3 => tar3%t%r
+  ptr3 = cos (ptr3)
+  if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort ()
+
+  ptr2 => tar3%t(:)%chr(2:3)
+  ptr2 = " x"
+  if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort ()
+
+!_______________check non-subref works still___________
+  ptr2 => tar4
+  if (any (ptr2 .ne. (/"ab","cd"/))) call abort ()
+
+contains
+  subroutine foo (arg)
+    integer :: arg(:)
+    arg = arg - 1
+  end subroutine
+  subroutine bar (arg)
+    integer, pointer :: arg(:)
+    arg = arg + 99
+  end subroutine
+end
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index d552c3a..8897275 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val)
 
    Use this version when not const/copy propagating values.  For example,
    PRE uses this version when building expressions as they would appear
-   in specific blocks taking into account actions of PHI nodes.  */
+   in specific blocks taking into account actions of PHI nodes.
+
+   The statement in which an expression has been replaced should be
+   folded using fold_stmt_inplace.  */
 
 void
 replace_exp (use_operand_p op_p, tree val)
-- 
1.7.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp.
  2010-12-08 20:46     ` [PATCH] Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp Sebastian Pop
@ 2010-12-08 21:27       ` Richard Guenther
  0 siblings, 0 replies; 7+ messages in thread
From: Richard Guenther @ 2010-12-08 21:27 UTC (permalink / raw)
  To: Sebastian Pop; +Cc: gcc-patches

On Wed, 8 Dec 2010, Sebastian Pop wrote:

> Hi,
> 
> I am testing this patch on amd64-linux.  Ok for trunk if that passes?

Ok.

Thanks,
Richard.

> Thanks,
> Sebastian
> 
> 2010-12-08  Richard Guenther  <rguenther@suse.de>
> 	    Sebastian Pop  <sebastian.pop@amd.com>
> 
> 	PR tree-optimization/45230
> 	PR tree-optimization/45231
> 	PR tree-optimization/45370
> 	* sese.c (rename_uses): Returns a bool.  Call
> 	recompute_tree_invariant_for_addr_expr only on the RHS of a
> 	GIMPLE_ASSIGN.
> 	(graphite_copy_stmts_from_block): Call fold_stmt_inplace when
> 	rename_uses returns true.
> 	* tree-ssa-copy.c (replace_exp): Add a comment about calling
> 	fold_stmt_inplace after replace_exp.
> 
> 	* gcc.dg/graphite/id-pr45230-1.c: New.
> 	* gcc.dg/graphite/id-pr45231.c: New.
> 	* gfortran.dg/graphite/id-pr45370.f90: New.
> ---
>  gcc/ChangeLog                                     |   14 ++
>  gcc/sese.c                                        |   17 ++-
>  gcc/testsuite/ChangeLog                           |   10 ++
>  gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c      |  140 +++++++++++++++++++++
>  gcc/testsuite/gcc.dg/graphite/id-pr45231.c        |   37 ++++++
>  gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 |  100 +++++++++++++++
>  gcc/tree-ssa-copy.c                               |    5 +-
>  7 files changed, 316 insertions(+), 7 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
>  create mode 100644 gcc/testsuite/gcc.dg/graphite/id-pr45231.c
>  create mode 100644 gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> 
> diff --git a/gcc/ChangeLog b/gcc/ChangeLog
> index ff52686..95bd5c0 100644
> --- a/gcc/ChangeLog
> +++ b/gcc/ChangeLog
> @@ -1,3 +1,17 @@
> +2010-12-08  Richard Guenther  <rguenther@suse.de>
> +	    Sebastian Pop  <sebastian.pop@amd.com>
> +
> +	PR tree-optimization/45230
> +	PR tree-optimization/45231
> +	PR tree-optimization/45370
> +	* sese.c (rename_uses): Returns a bool.  Call
> +	recompute_tree_invariant_for_addr_expr only on the RHS of a
> +	GIMPLE_ASSIGN.
> +	(graphite_copy_stmts_from_block): Call fold_stmt_inplace when
> +	rename_uses returns true.
> +	* tree-ssa-copy.c (replace_exp): Add a comment about calling
> +	fold_stmt_inplace after replace_exp.
> +
>  2010-12-07  Paul Koning  <ni1d@arrl.net>
>  
>  	* config/pdp11/pdp11.c (TARGET_ASM_FUNCTION_SECTION): Define.
> diff --git a/gcc/sese.c b/gcc/sese.c
> index 65f8556..3bf6bea 100644
> --- a/gcc/sese.c
> +++ b/gcc/sese.c
> @@ -470,14 +470,15 @@ set_rename (htab_t rename_map, tree old_name, tree expr)
>     substitution map RENAME_MAP, inserting the gimplification code at
>     GSI_TGT, for the translation REGION, with the original copied
>     statement in LOOP, and using the induction variable renaming map
> -   IV_MAP.  */
> +   IV_MAP.  Returns true when something has been renamed.  */
>  
> -static void
> +static bool
>  rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>  	     sese region, loop_p loop, VEC (tree, heap) *iv_map)
>  {
>    use_operand_p use_p;
>    ssa_op_iter op_iter;
> +  bool changed = false;
>  
>    if (is_gimple_debug (copy))
>      {
> @@ -486,7 +487,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>        else
>  	gcc_unreachable ();
>  
> -      return;
> +      return false;
>      }
>  
>    FOR_EACH_SSA_USE_OPERAND (use_p, copy, op_iter, SSA_OP_ALL_USES)
> @@ -500,6 +501,7 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>  	  || SSA_NAME_IS_DEFAULT_DEF (old_name))
>  	continue;
>  
> +      changed = true;
>        new_expr = get_rename (rename_map, old_name);
>        if (new_expr)
>  	{
> @@ -547,8 +549,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>        gsi_insert_seq_before (gsi_tgt, stmts, GSI_SAME_STMT);
>        replace_exp (use_p, new_expr);
>  
> -
> -      if (TREE_CODE (new_expr) == INTEGER_CST)
> +      if (TREE_CODE (new_expr) == INTEGER_CST
> +	  && is_gimple_assign (copy))
>  	{
>  	  tree rhs = gimple_assign_rhs1 (copy);
>  
> @@ -558,6 +560,8 @@ rename_uses (gimple copy, htab_t rename_map, gimple_stmt_iterator *gsi_tgt,
>  
>        set_rename (rename_map, old_name, new_expr);
>      }
> +
> +  return changed;
>  }
>  
>  /* Duplicates the statements of basic block BB into basic block NEW_BB
> @@ -611,7 +615,8 @@ graphite_copy_stmts_from_block (basic_block bb, basic_block new_bb,
>  	  set_rename (rename_map, old_name, new_name);
>   	}
>  
> -      rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map);
> +      if (rename_uses (copy, rename_map, &gsi_tgt, region, loop, iv_map))
> +	fold_stmt_inplace (copy);
>  
>        update_stmt (copy);
>      }
> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
> index 96275ed..3cf399d 100644
> --- a/gcc/testsuite/ChangeLog
> +++ b/gcc/testsuite/ChangeLog
> @@ -1,3 +1,13 @@
> +2010-12-08  Richard Guenther  <rguenther@suse.de>
> +	    Sebastian Pop  <sebastian.pop@amd.com>
> +
> +	PR tree-optimization/45230
> +	PR tree-optimization/45231
> +	PR tree-optimization/45370
> +	* gcc.dg/graphite/id-pr45230-1.c: New.
> +	* gcc.dg/graphite/id-pr45231.c: New.
> +	* gfortran.dg/graphite/id-pr45370.f90: New.
> +
>  2010-12-07  Sebastian Pop  <sebastian.pop@amd.com>
>  
>  	PR tree-optimization/44676
> diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
> new file mode 100644
> index 0000000..ba14fe5
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45230-1.c
> @@ -0,0 +1,140 @@
> +/* Copyright (C) 2002  Free Software Foundation.
> +
> +   Test strncmp with various combinations of pointer alignments and lengths to
> +   make sure any optimizations in the library are correct.
> +
> +   Written by Michael Meissner, March 9, 2002.  */
> +
> +#include <string.h>
> +#include <stddef.h>
> +
> +#ifndef MAX_OFFSET
> +#define MAX_OFFSET (sizeof (long long))
> +#endif
> +
> +#ifndef MAX_TEST
> +#define MAX_TEST (8 * sizeof (long long))
> +#endif
> +
> +#ifndef MAX_EXTRA
> +#define MAX_EXTRA (sizeof (long long))
> +#endif
> +
> +#define MAX_LENGTH (MAX_OFFSET + MAX_TEST + MAX_EXTRA)
> +
> +static union {
> +  unsigned char buf[MAX_LENGTH];
> +  long long align_int;
> +  long double align_fp;
> +} u1, u2;
> +
> +void
> +test (const unsigned char *s1, const unsigned char *s2, size_t len, int expected)
> +{
> +  int value = strncmp ((char *) s1, (char *) s2, len);
> +
> +  if (expected < 0 && value >= 0)
> +    __builtin_abort ();
> +  else if (expected == 0 && value != 0)
> +    __builtin_abort ();
> +  else if (expected > 0 && value <= 0)
> +    __builtin_abort ();
> +}
> +
> +main ()
> +{
> +  size_t off1, off2, len, i;
> +  unsigned char *buf1, *buf2;
> +  unsigned char *mod1, *mod2;
> +  unsigned char *p1, *p2;
> +
> +  for (off1 = 0; off1 < MAX_OFFSET; off1++)
> +    for (off2 = 0; off2 < MAX_OFFSET; off2++)
> +      for (len = 0; len < MAX_TEST; len++)
> +	{
> +	  p1 = u1.buf;
> +	  for (i = 0; i < off1; i++)
> +	    *p1++ = '\0';
> +
> +	  buf1 = p1;
> +	  for (i = 0; i < len; i++)
> +	    *p1++ = 'a';
> +
> +	  mod1 = p1;
> +	  for (i = 0; i < MAX_EXTRA; i++)
> +	    *p1++ = 'x';
> +
> +	  p2 = u2.buf;
> +	  for (i = 0; i < off2; i++)
> +	    *p2++ = '\0';
> +
> +	  buf2 = p2;
> +	  for (i = 0; i < len; i++)
> +	    *p2++ = 'a';
> +
> +	  mod2 = p2;
> +	  for (i = 0; i < MAX_EXTRA; i++)
> +	    *p2++ = 'x';
> +
> +	  mod1[0] = '\0';
> +	  mod2[0] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, 0);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'a';
> +	  mod1[1] = '\0';
> +	  mod2[0] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = '\0';
> +	  mod2[0] = 'a';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'b';
> +	  mod1[1] = '\0';
> +	  mod2[0] = 'c';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'c';
> +	  mod1[1] = '\0';
> +	  mod2[0] = 'b';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = 'b';
> +	  mod1[1] = '\0';
> +	  mod2[0] = (unsigned char)'\251';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = (unsigned char)'\251';
> +	  mod1[1] = '\0';
> +	  mod2[0] = 'b';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = (unsigned char)'\251';
> +	  mod1[1] = '\0';
> +	  mod2[0] = (unsigned char)'\252';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, -1);
> +	  test (buf1, buf2, len, 0);
> +
> +	  mod1[0] = (unsigned char)'\252';
> +	  mod1[1] = '\0';
> +	  mod2[0] = (unsigned char)'\251';
> +	  mod2[1] = '\0';
> +	  test (buf1, buf2, MAX_LENGTH, +1);
> +	  test (buf1, buf2, len, 0);
> +	}
> +
> +  __builtin_exit (0);
> +}
> diff --git a/gcc/testsuite/gcc.dg/graphite/id-pr45231.c b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c
> new file mode 100644
> index 0000000..01e9a67
> --- /dev/null
> +++ b/gcc/testsuite/gcc.dg/graphite/id-pr45231.c
> @@ -0,0 +1,37 @@
> +void
> +f (n, ppt, xrot)
> +{
> +  int tileWidth;
> +  int nlwSrc;
> +  int srcx;
> +  int v3, v4;
> +  register unsigned long ca1, cx1, ca2, cx2;
> +  unsigned long *pSrcLine;
> +  register unsigned long *pDst;
> +  register unsigned long *pSrc;
> +  register unsigned long b, tmp;
> +  unsigned long tileEndMask;
> +  int v1, v2;
> +  int tileEndPart;
> +  int needFirst;
> +  tileEndPart = 0;
> +  v1 = tileEndPart << 5;
> +  v2 = 32 - v1;
> +  while (n--)
> +    {
> +      if ((srcx = (ppt - xrot) % tileWidth) < 0)
> +	if (needFirst)
> +	  if (nlwSrc == 1)
> +	    {
> +	      tmp = b;
> +	      if (tileEndPart)
> +		b = (*pSrc & tileEndMask) | (*pSrcLine >> v1);
> +	    }
> +      if (tileEndPart)
> +	b = (tmp << v1) | (b >> v2);
> +      if (v4 != 32)
> +	*pDst = (*pDst & ((tmp << v3) | (b >> v4) & ca1 ^ cx1)
> +		 ^ (((tmp << v3) | (b >> v4)) & ca2 ^ cx2));
> +      *pDst = *pDst & tmp;
> +    }
> +}
> diff --git a/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90 b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> new file mode 100644
> index 0000000..94eebd1
> --- /dev/null
> +++ b/gcc/testsuite/gfortran.dg/graphite/id-pr45370.f90
> @@ -0,0 +1,100 @@
> +!
> +  type :: t
> +    real :: r
> +    integer :: i
> +    character(3) :: chr
> +  end type t
> +
> +  type :: t2
> +    real :: r(2, 2)
> +    integer :: i
> +    character(3) :: chr
> +  end type t2
> +
> +  type :: s
> +    type(t), pointer :: t(:)
> +  end type s
> +
> +  integer, parameter :: sh(2) = (/2,2/)
> +  real, parameter :: a1(2,2) = reshape ((/1.0,2.0,3.0,4.0/),sh)
> +  real, parameter :: a2(2,2) = reshape ((/5.0,6.0,7.0,8.0/),sh)
> +
> +  type(t), target :: tar1(2) = (/t(1.0, 2, "abc"), t(3.0, 4, "efg")/)
> +  character(4), target :: tar2(2) = (/"abcd","efgh"/)
> +  type(s), target :: tar3
> +  character(2), target :: tar4(2) = (/"ab","cd"/)
> +  type(t2), target :: tar5(2) = (/t2(a1, 2, "abc"), t2(a2, 4, "efg")/)
> +
> +  integer, pointer :: ptr(:)
> +  character(2), pointer :: ptr2(:)
> +  real, pointer :: ptr3(:)
> +
> +!_______________component subreference___________
> +  ptr => tar1%i
> +  ptr = ptr + 1              ! check the scalarizer is OK
> +
> +  if (any (ptr .ne. (/3, 5/))) call abort ()
> +  if (any ((/ptr(1), ptr(2)/) .ne. (/3, 5/))) call abort ()
> +  if (any (tar1%i .ne. (/3, 5/))) call abort ()
> +
> +! Make sure that the other components are not touched.
> +  if (any (tar1%r .ne. (/1.0, 3.0/))) call abort ()
> +  if (any (tar1%chr .ne. (/"abc", "efg"/))) call abort ()
> +
> +! Check that the pointer is passed correctly as an actual argument.
> +  call foo (ptr)
> +  if (any (tar1%i .ne. (/2, 4/))) call abort ()
> +
> +! And that dummy pointers are OK too.
> +  call bar (ptr)
> +  if (any (tar1%i .ne. (/101, 103/))) call abort ()
> +
> +!_______________substring subreference___________
> +  ptr2 => tar2(:)(2:3)
> +  ptr2 = ptr2(:)(2:2)//"z"   ! again, check the scalarizer
> +
> +  if (any (ptr2 .ne. (/"cz", "gz"/))) call abort ()
> +  if (any ((/ptr2(1), ptr2(2)/) .ne. (/"cz", "gz"/))) call abort ()
> +  if (any (tar2 .ne. (/"aczd", "egzh"/))) call abort ()
> +
> +!_______________substring component subreference___________
> +  ptr2 => tar1(:)%chr(1:2)
> +  ptr2 = ptr2(:)(2:2)//"q"   ! yet again, check the scalarizer
> +  if (any (ptr2 .ne. (/"bq","fq"/))) call abort ()
> +  if (any (tar1%chr .ne. (/"bqc","fqg"/))) call abort ()
> +
> +!_______________trailing array element subreference___________
> +  ptr3 => tar5%r(1,2)
> +  ptr3 = (/99.0, 999.0/)
> +  if (any (tar5(1)%r .ne. reshape ((/1.0,2.0,99.0,4.0/), sh))) call abort ()
> +  if (any (tar5(2)%r .ne. reshape ((/5.0,6.0,999.0,8.0/), sh))) call abort ()
> +
> +!_______________forall assignment___________
> +  ptr2 => tar2(:)(1:2)
> +  forall (i = 1:2) ptr2(i)(1:1) = "z"
> +  if (any (tar2 .ne. (/"zczd", "zgzh"/))) call abort ()
> +
> +!_______________something more complicated___________
> +  tar3%t => tar1
> +  ptr3 => tar3%t%r
> +  ptr3 = cos (ptr3)
> +  if (any (abs(ptr3 - (/cos(1.0_4), cos(3.0_4)/)) >= epsilon(1.0_4))) call abort ()
> +
> +  ptr2 => tar3%t(:)%chr(2:3)
> +  ptr2 = " x"
> +  if (any (tar1%chr .ne. (/"b x", "f x"/))) call abort ()
> +
> +!_______________check non-subref works still___________
> +  ptr2 => tar4
> +  if (any (ptr2 .ne. (/"ab","cd"/))) call abort ()
> +
> +contains
> +  subroutine foo (arg)
> +    integer :: arg(:)
> +    arg = arg - 1
> +  end subroutine
> +  subroutine bar (arg)
> +    integer, pointer :: arg(:)
> +    arg = arg + 99
> +  end subroutine
> +end
> diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
> index d552c3a..8897275 100644
> --- a/gcc/tree-ssa-copy.c
> +++ b/gcc/tree-ssa-copy.c
> @@ -191,7 +191,10 @@ propagate_value (use_operand_p op_p, tree val)
>  
>     Use this version when not const/copy propagating values.  For example,
>     PRE uses this version when building expressions as they would appear
> -   in specific blocks taking into account actions of PHI nodes.  */
> +   in specific blocks taking into account actions of PHI nodes.
> +
> +   The statement in which an expression has been replaced should be
> +   folded using fold_stmt_inplace.  */
>  
>  void
>  replace_exp (use_operand_p op_p, tree val)
> 

-- 
Richard Guenther <rguenther@suse.de>
Novell / SUSE Labs
SUSE LINUX Products GmbH - Nuernberg - AG Nuernberg - HRB 16746 - GF: Markus Rex

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-12-08 20:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-07 23:01 [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs Sebastian Pop
2010-12-08  0:14 ` Sebastian Pop
2010-12-08  8:22   ` Sebastian Pop
2010-12-08 11:57   ` Richard Guenther
2010-12-08 20:46     ` [PATCH] Fix PR45230, PR45231, and PR45370: fold_stmt_inplace after replace_exp Sebastian Pop
2010-12-08 21:27       ` Richard Guenther
2010-12-08 14:29   ` [PATCH] Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs Jack Howarth

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).