From cc06222ab9d2b17dcd022fb903d71c9c7d776617 Mon Sep 17 00:00:00 2001
From: rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sat, 21 Oct 2006 13:23:41 +0000
Subject: [PATCH] 2006-10-21  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/3511
	* tree-ssa-pre.c (phi_translate): Fold CALL_EXPRs that
	got new invariant arguments during PHI translation.

	* gcc.dg/tree-ssa/ssa-pre-15.c: New testcase.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@117932 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                              |  6 ++++++
 gcc/testsuite/ChangeLog                    |  5 +++++
 gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c | 16 ++++++++++++++++
 gcc/tree-ssa-pre.c                         | 17 +++++++++++++++++
 4 files changed, 44 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fdaa244cfe58..eb1c3292c309 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-10-21  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/3511
+	* tree-ssa-pre.c (phi_translate): Fold CALL_EXPRs that
+	got new invariant arguments during PHI translation.
+
 2006-10-21  Richard Guenther  <rguenther@suse.de>
 
 	PR middle-end/26898
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 55d336cc162c..c30830dff1b4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-10-21  Richard Guenther  <rguenther@suse.de>
+
+	PR tree-optimization/3511
+	* gcc.dg/tree-ssa/ssa-pre-15.c: New testcase.
+
 2006-10-21  Richard Guenther  <rguenther@suse.de>
 
 	PR middle-end/26898
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c
new file mode 100644
index 000000000000..518fda854e69
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-15.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+/* Verify we PRE the strlen call, as strlen("") folds to zero.  */
+
+extern __SIZE_TYPE__ strlen (const char *);
+
+__SIZE_TYPE__ mystrlen (const char *s)
+{
+  if (!s)
+    s = "";
+  return strlen(s);
+}
+
+/* { dg-final { scan-tree-dump "= 0;" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 9c7b89faaf3f..ba32b3cfed45 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -1076,6 +1076,7 @@ phi_translate (tree expr, value_set_t set, basic_block pred,
 	    tree newexpr;
 	    tree vh = get_value_handle (expr);
 	    bool listchanged = false;
+	    bool invariantarg = false;
 	    VEC (tree, gc) *vuses = VALUE_HANDLE_VUSES (vh);
 	    VEC (tree, gc) *tvuses;
 
@@ -1134,10 +1135,26 @@ phi_translate (tree expr, value_set_t set, basic_block pred,
 		    if (newval != oldval)
 		      {
 			listchanged = true;
+			invariantarg |= is_gimple_min_invariant (newval);
 			TREE_VALUE (newwalker) = get_value_handle (newval);
 		      }
 		  }
 	      }
+
+	    /* In case of new invariant args we might try to fold the call
+	       again.  */
+	    if (invariantarg)
+	      {
+		tree tmp = fold_ternary (CALL_EXPR, TREE_TYPE (expr),
+					 newop0, newarglist, newop2);
+		if (tmp)
+		  {
+		    STRIP_TYPE_NOPS (tmp);
+		    if (is_gimple_min_invariant (tmp))
+		      return tmp;
+		  }
+	      }
+
 	    if (listchanged)
 	      vn_lookup_or_add (newarglist, NULL);
 
-- 
GitLab