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