From 7a04f01cb7752b4c9fab847cbb6775e4b020f6d9 Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Mon, 7 May 2012 15:31:00 +0200
Subject: [PATCH] re PR tree-optimization/53239 (VRP vs named value return opt)

	PR tree-optimization/53239
	* tree-vrp.c (get_value_range): Set VR of
	SSA_NAME_IS_DEFAULT_DEF of DECL_BY_REFERENCE RESULT_DECL
	to nonnull.

	* g++.dg/opt/vrp3.C: New test.
	* g++.dg/opt/vrp3-aux.cc: New file.
	* g++.dg/opt/vrp3.h: New file.

From-SVN: r187240
---
 gcc/ChangeLog                        |  7 +++++
 gcc/testsuite/ChangeLog              |  7 +++++
 gcc/testsuite/g++.dg/opt/vrp3-aux.cc | 21 +++++++++++++
 gcc/testsuite/g++.dg/opt/vrp3.C      | 47 ++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/opt/vrp3.h      |  9 ++++++
 gcc/tree-vrp.c                       | 25 +++++++++------
 6 files changed, 106 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/opt/vrp3-aux.cc
 create mode 100644 gcc/testsuite/g++.dg/opt/vrp3.C
 create mode 100644 gcc/testsuite/g++.dg/opt/vrp3.h

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dd7073b7448d..664bd50d7be7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/53239
+	* tree-vrp.c (get_value_range): Set VR of
+	SSA_NAME_IS_DEFAULT_DEF of DECL_BY_REFERENCE RESULT_DECL
+	to nonnull.
+
 2012-05-07  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/53195
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index e5567027f33a..323c652783a8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2012-05-07  Jakub Jelinek  <jakub@redhat.com>
+
+	PR tree-optimization/53239
+	* g++.dg/opt/vrp3.C: New test.
+	* g++.dg/opt/vrp3-aux.cc: New file.
+	* g++.dg/opt/vrp3.h: New file.
+
 2012-05-07  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>
 
 	* g++.dg/debug/dwarf2/nested-3.C: Allow for / comments and missing
diff --git a/gcc/testsuite/g++.dg/opt/vrp3-aux.cc b/gcc/testsuite/g++.dg/opt/vrp3-aux.cc
new file mode 100644
index 000000000000..fb68f6b5204c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/vrp3-aux.cc
@@ -0,0 +1,21 @@
+// { dg-do compile }
+// { dg-options "" }
+
+#include "vrp3.h"
+
+R::R ()
+{
+  r1 = r2 = 1;
+}
+
+R::R (int n, int d)
+{
+  r1 = n;
+  r2 = d;
+}
+
+int
+R::compare (R const &r, R const &s)
+{
+  return (int) (r.r1 * s.r2 - s.r1 * r.r2);
+}
diff --git a/gcc/testsuite/g++.dg/opt/vrp3.C b/gcc/testsuite/g++.dg/opt/vrp3.C
new file mode 100644
index 000000000000..90162bfe1c00
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/vrp3.C
@@ -0,0 +1,47 @@
+// PR tree-optimization/53239
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-sources "vrp3-aux.cc" }
+
+#include "vrp3.h"
+
+struct M
+{
+  M (R m);
+  R val;
+  static int compare (M const &, M const &);
+};
+
+inline M const &
+min (M const & t1, M const & t2)
+{
+  return R::compare (t1.val, t2.val) < 0 ? t1 : t2;
+}
+
+M::M (R m)
+{
+  val = m;
+}
+
+M
+test (M *x)
+{
+  M n (R (0, 0));
+
+  for (int i = 0; i < 2; i++)
+    {
+      M p = x[i];
+      n = min (n, p);
+    }
+
+  if (n.val.r2 != 2 || n.val.r1 != 1)
+    __builtin_abort ();
+  return n;
+}
+
+int
+main ()
+{
+  M x[2] = { M (R (1, 2)), M (R (1, 1)) };
+  test (x);
+}
diff --git a/gcc/testsuite/g++.dg/opt/vrp3.h b/gcc/testsuite/g++.dg/opt/vrp3.h
new file mode 100644
index 000000000000..0e97d0c491c2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/vrp3.h
@@ -0,0 +1,9 @@
+struct R
+{
+  long long r1, r2;
+  void copy (R const &r) { r1 = r.r1; r2 = r.r2; }
+  R ();
+  explicit R (int, int);
+  R (R const &r) { copy (r); }
+  static int compare (R const &, R const &);
+};
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 90660967c27f..72c647fca4ad 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -695,17 +695,22 @@ get_value_range (const_tree var)
   /* If VAR is a default definition of a parameter, the variable can
      take any value in VAR's type.  */
   sym = SSA_NAME_VAR (var);
-  if (SSA_NAME_IS_DEFAULT_DEF (var)
-      && TREE_CODE (sym) == PARM_DECL)
-    {
-      /* Try to use the "nonnull" attribute to create ~[0, 0]
-	 anti-ranges for pointers.  Note that this is only valid with
-	 default definitions of PARM_DECLs.  */
-      if (POINTER_TYPE_P (TREE_TYPE (sym))
-	  && nonnull_arg_p (sym))
+  if (SSA_NAME_IS_DEFAULT_DEF (var))
+    {
+      if (TREE_CODE (sym) == PARM_DECL)
+	{
+	  /* Try to use the "nonnull" attribute to create ~[0, 0]
+	     anti-ranges for pointers.  Note that this is only valid with
+	     default definitions of PARM_DECLs.  */
+	  if (POINTER_TYPE_P (TREE_TYPE (sym))
+	      && nonnull_arg_p (sym))
+	    set_value_range_to_nonnull (vr, TREE_TYPE (sym));
+	  else
+	    set_value_range_to_varying (vr);
+	}
+      else if (TREE_CODE (sym) == RESULT_DECL
+	       && DECL_BY_REFERENCE (sym))
 	set_value_range_to_nonnull (vr, TREE_TYPE (sym));
-      else
-	set_value_range_to_varying (vr);
     }
 
   return vr;
-- 
GitLab