From 7eae8eb2b14e45981c040b77fcdbb477572c0403 Mon Sep 17 00:00:00 2001
From: Diego Novillo <dnovillo@redhat.com>
Date: Fri, 17 Sep 2004 18:42:51 +0000
Subject: [PATCH] re PR tree-optimization/17273 (ICE in
 get_indirect_ref_operands)

	PR tree-optimization/17273
	* tree-ssa.c (replace_immediate_uses): Call fold_stmt if the
	replacement is a constant.

testsuite/ChangeLog

	PR tree-optimization/17273
	* gcc.c-torture/compile/pr17273.c: New test.

From-SVN: r87662
---
 gcc/ChangeLog                                 |  6 +++++
 gcc/testsuite/ChangeLog                       |  5 +++++
 gcc/testsuite/gcc.c-torture/compile/pr17273.c | 22 +++++++++++++++++++
 gcc/tree-ssa.c                                | 19 ++++++++++++++++
 4 files changed, 52 insertions(+)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr17273.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 04eec4c48d8c..2f32b50233db 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2004-09-17  Diego Novillo  <dnovillo@redhat.com>
+
+	PR tree-optimization/17273
+	* tree-ssa.c (replace_immediate_uses): Call fold_stmt if the
+	replacement is a constant.
+
 2004-09-17  Joseph S. Myers  <jsm@polyomino.org.uk>
 
 	* c-tree.h (enum c_typespec_keyword): New.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0a27ca6c57ed..1eda48d7e441 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-09-17  Diego Novillo  <dnovillo@redhat.com>
+
+	PR tree-optimization/17273
+	* gcc.c-torture/compile/pr17273.c: New test.
+
 2004-09-17  Joseph S. Myers  <jsm@polyomino.org.uk>
 
 	* gcc.dg/declspec-4.c, gcc.dg/declspec-5.c, gcc.dg/declspec-6.c:
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr17273.c b/gcc/testsuite/gcc.c-torture/compile/pr17273.c
new file mode 100644
index 000000000000..42d318ef69ff
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr17273.c
@@ -0,0 +1,22 @@
+struct A { int i; };
+struct B { struct A a; };
+
+void f(struct A*, struct A*);
+#define bool _Bool
+
+void bar(bool b)
+{
+  struct B * D1601;
+  struct A D1576;
+  struct A * D1593;
+  struct B * D1592;
+  struct B D1575;
+
+  D1575 = (struct B){};
+
+  if (b) D1592 = &D1575; else D1592 = &D1575;
+
+  D1593 = &D1592->a; // <-- we are prograting &D1575 into here.
+  D1576 = (struct A){};
+  f (D1593, &D1576);
+}
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 3e9b2134f9a4..f79466da38a0 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1018,6 +1018,25 @@ replace_immediate_uses (tree var, tree repl)
 	      propagate_value (use_p, repl);
 	}
 
+      /* FIXME.  If REPL is a constant, we need to fold STMT.
+	 However, fold_stmt wants a pointer to the statement, because
+	 it may happen that it needs to replace the whole statement
+	 with a new expression.  Since the current def-use machinery
+	 does not return pointers to statements, we call fold_stmt
+	 with the address of a local temporary, if that call changes
+	 the temporary then we fall on our swords.
+
+	 Note that all this will become unnecessary soon.  This
+	 pass is being replaced with a proper copy propagation pass
+	 for 4.1 (dnovillo, 2004-09-17).  */
+      if (TREE_CODE (repl) != SSA_NAME)
+	{
+	  tree tmp = stmt;
+	  fold_stmt (&tmp);
+	  if (tmp != stmt)
+	    abort ();
+	}
+
       /* If REPL is a pointer, it may have different memory tags associated
 	 with it.  For instance, VAR may have had a name tag while REPL
 	 only had a type tag.  In these cases, the virtual operands (if
-- 
GitLab