The following fixes PR86816 - CFG cleanup can introduce new SSA names which we may not query the VN lattice with.
Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. Richard. 2018-08-02 Richard Biener <rguent...@suse.de> PR tree-optimization/86816 * tree-ssa-tail-merge.c (tail_merge_valueize): New function which checks for value availability before querying it. (gvn_uses_equal): Use it. (same_succ_hash): Likewise. (gimple_equal_p): Likewise. * g++.dg/torture/pr86816.C: New testcase. Index: gcc/tree-ssa-tail-merge.c =================================================================== --- gcc/tree-ssa-tail-merge.c (revision 263190) +++ gcc/tree-ssa-tail-merge.c (working copy) @@ -286,6 +286,21 @@ struct aux_bb_info #define BB_VOP_AT_EXIT(bb) (((struct aux_bb_info *)bb->aux)->vop_at_exit) #define BB_DEP_BB(bb) (((struct aux_bb_info *)bb->aux)->dep_bb) +/* Valueization helper querying the VN lattice. */ + +static tree +tail_merge_valueize (tree name) +{ + if (TREE_CODE (name) == SSA_NAME + && has_VN_INFO (name)) + { + tree tem = VN_INFO (name)->valnum; + if (tem != VN_TOP) + return tem; + } + return name; +} + /* Returns true if the only effect a statement STMT has, is to define locally used SSA_NAMEs. */ @@ -371,7 +386,7 @@ gvn_uses_equal (tree val1, tree val2) if (val1 == val2) return true; - if (vn_valueize (val1) != vn_valueize (val2)) + if (tail_merge_valueize (val1) != tail_merge_valueize (val2)) return false; return ((TREE_CODE (val1) == SSA_NAME || CONSTANT_CLASS_P (val1)) @@ -481,7 +496,7 @@ same_succ_hash (const same_succ *e) for (i = 0; i < gimple_call_num_args (stmt); i++) { arg = gimple_call_arg (stmt, i); - arg = vn_valueize (arg); + arg = tail_merge_valueize (arg); inchash::add_expr (arg, hstate); } } @@ -1147,7 +1162,7 @@ gimple_equal_p (same_succ *same_succ, gi if (lhs1 == NULL_TREE || lhs2 == NULL_TREE) return false; if (TREE_CODE (lhs1) == SSA_NAME && TREE_CODE (lhs2) == SSA_NAME) - return vn_valueize (lhs1) == vn_valueize (lhs2); + return tail_merge_valueize (lhs1) == tail_merge_valueize (lhs2); return operand_equal_p (lhs1, lhs2, 0); case GIMPLE_ASSIGN: Index: gcc/testsuite/g++.dg/torture/pr86816.C =================================================================== --- gcc/testsuite/g++.dg/torture/pr86816.C (nonexistent) +++ gcc/testsuite/g++.dg/torture/pr86816.C (working copy) @@ -0,0 +1,42 @@ +// { dg-do compile } + +class Signal +{ +public: + int m_Mode; +}; + +class Ctx +{ +public: + bool m_Invert; + + void DoSomething(); +}; + +class Test +{ + void TestIce( Ctx& ctx, Signal* sig); +}; + +void Test::TestIce( Ctx& ctx, Signal* sig) +{ + int invert = false; + + if( ! ctx.m_Invert) + invert = ! invert; + + switch( sig->m_Mode) + { + case 1: + invert = ! invert; + break; + + case 2: + invert = true; + break; + } + + if( invert) + ctx.DoSomething(); +}