I am testing the following patch teaching VRP predicate analysis about

  __x.5_4 = (long unsigned int) "hello";
  __y.6_5 = (long unsigned int) _3;
  if (__x.5_4 != __y.6_5)

so that we know sth about the relation of the converted entities.
This appearantly (didn't back out other stuff) helps PR88775
after Jakubs changes to libstdc++ (before his changes a related
VN patch helped which meanwhile shows miscompiling
20_util/function_objects/comparisons_pointer.cc...).

I now see DOM performing all required optimization thanks to it
using the EVRP machinery.

Bootstrap & regtest running on x86_64-unknown-linux-gnu.

OK for trunk?

Any idea how we can have a reliable testcase for the std::string
optimization?

Thanks,
Richard.

>From 78a345845651565daac295f8dfbfc64cf5e8ccf3 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguent...@suse.de>
Date: Thu, 10 Jan 2019 14:34:22 +0100
Subject: [PATCH] fix-pr88775-2

2019-01-10  Richard Biener  <rguent...@suse.de>

        PR tree-optimization/88775
        * tree-vrp.c (register_edge_assert_for_2): Register asserts
        from (T) a CMP (T) b.

diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 8d18e19d6e4..1efb907ae5e 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3247,6 +3247,42 @@ register_edge_assert_for_2 (tree name, edge e,
            }
        }
     }
+
+  /* For things like (T)a CMP (T)b register asserts for a CMP b if possible.  
*/
+  if (TREE_CODE_CLASS (comp_code) == tcc_comparison
+      && TREE_CODE (val) == SSA_NAME
+      && (INTEGRAL_TYPE_P (TREE_TYPE (val))
+         || POINTER_TYPE_P (TREE_TYPE (val))))
+    {
+      gassign *def1 = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (name));
+      gassign *def2 = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (val));
+      if (def1 && def2
+         && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def1))
+         && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def2))
+         && types_compatible_p (TREE_TYPE (gimple_assign_rhs1 (def1)),
+                                TREE_TYPE (gimple_assign_rhs1 (def2)))
+         && (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def1)))
+             <= TYPE_PRECISION (TREE_TYPE (val)))
+         && (comp_code == EQ_EXPR
+             || comp_code == NE_EXPR
+             || (TYPE_SIGN (TREE_TYPE (val))
+                 == TYPE_SIGN (TREE_TYPE (gimple_assign_rhs1 (def1))))
+             || (TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def1)))
+                 && (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def1)))
+                     < TYPE_PRECISION (TREE_TYPE (val))))))
+       {
+         tree op0 = gimple_assign_rhs1 (def1);
+         tree op1 = gimple_assign_rhs1 (def2);
+         enum tree_code alt_comp_code = comp_code;
+         if (TREE_CODE (op0) != SSA_NAME)
+           {
+             alt_comp_code = swap_tree_comparison (alt_comp_code);
+             std::swap (op0, op1);
+           }
+         if (TREE_CODE (op0) == SSA_NAME)
+           add_assert_info (asserts, op0, op0, alt_comp_code, op1);
+       }
+    }
 }
 
 /* OP is an operand of a truth value expression which is known to have

Reply via email to