Patchwork Fix PR45230: Only GIMPLE_ASSIGNs can contain ADDR_EXPRs.

login
register
mail settings
Submitter Sebastian Pop
Date Dec. 7, 2010, 10:25 p.m.
Message ID <1291760734-19488-1-git-send-email-sebpop@gmail.com>
Download mbox | patch
Permalink /patch/74608/
State New
Headers show

Comments

Sebastian Pop - Dec. 7, 2010, 10:25 p.m.
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

Patch

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);
+}