From 16bf25cdb684c9923605efbd6dcdc528a5ce912a Mon Sep 17 00:00:00 2001
From: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 13 Jul 2005 16:31:23 +0000
Subject: [PATCH]         * fold-const.c (fold_binary): When comparing two
 simple ADDR_EXPR         expressions, test their _DECL operands for pointer
 equality rather         than using operand_equal_p.

        * gcc.dg/tree-ssa/pr22321.c: New test.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101974 138bc75d-0d04-0410-961f-82ee72b054a4
---
 gcc/ChangeLog                           |  6 ++++++
 gcc/fold-const.c                        | 20 +++++++++++++++++---
 gcc/testsuite/ChangeLog                 |  4 ++++
 gcc/testsuite/gcc.dg/tree-ssa/pr22321.c | 20 ++++++++++++++++++++
 4 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr22321.c

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 03ca42bd23a3..622cec8fd94c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-07-13  Jeff Law  <law@redhat.com>
+
+	* fold-const.c (fold_binary): When comparing two simple ADDR_EXPR
+	expressions, test their _DECL operands for pointer equality rather
+	than using operand_equal_p.
+
 2005-07-13  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* config/alpha/linux.h (TARGET_HAS_F_SETLKW): Renamed to ...
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index beee337487b6..3bc27eb5d3bd 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -8757,9 +8757,23 @@ fold_binary (enum tree_code code, tree type, tree op0, tree op1)
 	  && ! lookup_attribute ("alias",
 				 DECL_ATTRIBUTES (TREE_OPERAND (arg1, 0)))
 	  && ! DECL_EXTERNAL (TREE_OPERAND (arg1, 0)))
-	return constant_boolean_node (operand_equal_p (arg0, arg1, 0)
-				      ? code == EQ_EXPR : code != EQ_EXPR,
-				      type);
+	{
+	  /* We know that we're looking at the address of two
+	     non-weak, unaliased, static _DECL nodes.
+
+	     It is both wasteful and incorrect to call operand_equal_p
+	     to compare the two ADDR_EXPR nodes.  It is wasteful in that
+	     all we need to do is test pointer equality for the arguments
+	     to the two ADDR_EXPR nodes.  It is incorrect to use
+	     operand_equal_p as that function is NOT equivalent to a
+	     C equality test.  It can in fact return false for two
+	     objects which would test as equal using the C equality
+	     operator.  */
+	  bool equal = TREE_OPERAND (arg0, 0) == TREE_OPERAND (arg1, 0);
+	  return constant_boolean_node (equal
+				        ? code == EQ_EXPR : code != EQ_EXPR,
+				        type);
+	}
 
       /* If this is a comparison of two exprs that look like an
 	 ARRAY_REF of the same object, then we can fold this to a
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ebc793e978d5..145830f8c5d1 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2005-07-13  Jeff Law  <law@redhat.com>
+
+	* gcc.dg/tree-ssa/pr22321.c: New test
+
 2005-07-13  Paolo Bonzini  <bonzini@gnu.org>
 
 	PR tree-optimization/21921
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr22321.c b/gcc/testsuite/gcc.dg/tree-ssa/pr22321.c
new file mode 100644
index 000000000000..64a94ab2d76b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr22321.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fno-tree-vrp -fno-tree-copy-prop -fno-tree-ccp -fdump-tree-optimized" } */
+
+
+volatile int x;
+
+int main ()
+{
+  volatile int *vip;
+  vip = &x;
+  volatile int *cvip;
+  cvip = vip;
+
+  if (vip != cvip) return -1;
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "return 0" 1 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+
-- 
GitLab