OSDN Git Service

new folding rule
authordavidxl <davidxl@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 17:00:37 +0000 (17:00 +0000)
committerdavidxl <davidxl@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 20 Apr 2010 17:00:37 +0000 (17:00 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158567 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/fold-const.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/tree-ssa/fold-compare.C [new file with mode: 0644]

index 15507e2..687bde1 100644 (file)
@@ -1,3 +1,8 @@
+2010-04-20  Xinliang David Li  <davidxl@gcc.gnu.org>
+
+       PR middle-end/41952
+       * fold-const.c (fold_comparison): New folding rule. 
+
 2010-04-20  Anatoly Sokolov  <aesok@post.ru
 
        * double-int.h (double_int_setbit): Declare.
index 85f9cd1..cdae661 100644 (file)
@@ -8643,9 +8643,33 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
          offset1 = TREE_OPERAND (arg1, 1);
        }
 
+      /* A local variable can never be pointed to by
+         the default SSA name of an incoming parameter.  */
+      if ((TREE_CODE (arg0) == ADDR_EXPR
+           && indirect_base0
+           && TREE_CODE (base0) == VAR_DECL
+           && auto_var_in_fn_p (base0, current_function_decl)
+           && !indirect_base1
+           && TREE_CODE (base1) == SSA_NAME
+           && TREE_CODE (SSA_NAME_VAR (base1)) == PARM_DECL
+           && SSA_NAME_IS_DEFAULT_DEF (base1))
+          || (TREE_CODE (arg1) == ADDR_EXPR
+              && indirect_base1
+              && TREE_CODE (base1) == VAR_DECL
+              && auto_var_in_fn_p (base1, current_function_decl)
+              && !indirect_base0
+              && TREE_CODE (base0) == SSA_NAME
+              && TREE_CODE (SSA_NAME_VAR (base0)) == PARM_DECL
+              && SSA_NAME_IS_DEFAULT_DEF (base0)))
+        {
+          if (code == NE_EXPR)
+            return constant_boolean_node (1, type);
+          else if (code == EQ_EXPR)
+            return constant_boolean_node (0, type);
+        }
       /* If we have equivalent bases we might be able to simplify.  */
-      if (indirect_base0 == indirect_base1
-         && operand_equal_p (base0, base1, 0))
+      else if (indirect_base0 == indirect_base1
+               && operand_equal_p (base0, base1, 0))
        {
          /* We can fold this expression to a constant if the non-constant
             offset parts are equal.  */
index ff7904b..6d9cb8b 100644 (file)
@@ -1,3 +1,7 @@
+2010-04-20  Xinliang David Li  <davidxl@google.com>
+
+       * g++.dg/tree-ssa/fold-compare.C: New.
+
 2010-04-20  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/39417
diff --git a/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C b/gcc/testsuite/g++.dg/tree-ssa/fold-compare.C
new file mode 100644 (file)
index 0000000..2b4c411
--- /dev/null
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct ExtentsBase {
+ ExtentsBase() : startx_(), endx_() { }
+ ExtentsBase(const ExtentsBase &b) {
+  *this = b;
+ }
+
+ const ExtentsBase & operator=(const ExtentsBase &b) {
+  if (this != &b) {
+    startx_ = b.startx_;
+  }
+  return *this;
+ }
+
+ int startx_;
+  int endx_;
+};
+
+int f(const ExtentsBase &e1) {
+ ExtentsBase my_extents = e1;
+ return my_extents.startx_;
+}
+
+/* { dg-final { scan-tree-dump-not "&my_extents" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+