The following makes SCCVN properly save/restore SSA_NAME_ANTI_RANGE_P. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard. 2016-01-25 Richard Biener <rguent...@suse.de> PR tree-optimization/69376 * tree-ssa-sccvn.h (struct vn_ssa_aux): Add range_info_anti_range_p flag. (VN_INFO_ANTI_RANGE_P): New inline. (VN_INFO_RANGE_TYPE): Likewise. * tree-ssa-sccvn.c (set_ssa_val_to): Also record and copy SSA_NAME_ANTI_RANGE_P. (free_scc_vn): Restore SSA_NAME_ANTI_RANGE_P. * tree-ssa-pre.c (eliminate_dom_walker::before_dom_children): Properly query VN_INFO_RANGE_TYPE. * gcc.dg/torture/pr69376.c: New testcase. Index: gcc/tree-ssa-sccvn.h =================================================================== *** gcc/tree-ssa-sccvn.h (revision 232717) --- gcc/tree-ssa-sccvn.h (working copy) *************** typedef struct vn_ssa_aux *** 191,196 **** --- 191,199 ---- insertion of such with EXPR as definition is required before a use can be created of it. */ unsigned needs_insertion : 1; + + /* Whether range-info is anti-range. */ + unsigned range_info_anti_range_p : 1; } *vn_ssa_aux_t; enum vn_lookup_kind { VN_NOWALK, VN_WALK, VN_WALKREWRITE }; *************** VN_INFO_RANGE_INFO (tree name) *** 253,258 **** --- 256,279 ---- : SSA_NAME_RANGE_INFO (name)); } + /* Whether the original range info of NAME is an anti-range. */ + + inline bool + VN_INFO_ANTI_RANGE_P (tree name) + { + return (VN_INFO (name)->info.range_info + ? VN_INFO (name)->range_info_anti_range_p + : SSA_NAME_ANTI_RANGE_P (name)); + } + + /* Get at the original range info kind for NAME. */ + + inline value_range_type + VN_INFO_RANGE_TYPE (tree name) + { + return VN_INFO_ANTI_RANGE_P (name) ? VR_ANTI_RANGE : VR_RANGE; + } + /* Get at the original pointer info for NAME. */ inline ptr_info_def * Index: gcc/tree-ssa-pre.c =================================================================== *** gcc/tree-ssa-pre.c (revision 232717) --- gcc/tree-ssa-pre.c (working copy) *************** eliminate_dom_walker::before_dom_childre *** 4047,4053 **** && ! VN_INFO_RANGE_INFO (sprime) && b == sprime_b) duplicate_ssa_name_range_info (sprime, ! SSA_NAME_RANGE_TYPE (lhs), VN_INFO_RANGE_INFO (lhs)); } --- 4047,4053 ---- && ! VN_INFO_RANGE_INFO (sprime) && b == sprime_b) duplicate_ssa_name_range_info (sprime, ! VN_INFO_RANGE_TYPE (lhs), VN_INFO_RANGE_INFO (lhs)); } Index: gcc/testsuite/gcc.dg/torture/pr69376.c =================================================================== *** gcc/testsuite/gcc.dg/torture/pr69376.c (revision 0) --- gcc/testsuite/gcc.dg/torture/pr69376.c (working copy) *************** *** 0 **** --- 1,45 ---- + /* { dg-do run } */ + /* { dg-require-effective-target int32plus } */ + + int printf (const char *, ...); + + unsigned a, c, *d, f; + char b, e; + short g; + + void + fn1 () + { + unsigned h = 4294967290; + if (b >= 0) + { + h = b; + c = b / 290; + f = ~(c - (8 || h)); + if (f) + printf ("%d\n", 1); + if (f) + printf ("%d\n", f); + g = ~f; + if (c < 3) + { + int i = -h < ~c; + unsigned j; + if (i) + j = h; + h = -j * g; + } + c = h; + } + unsigned k = ~h; + char l = e || g; + if (l < 1 || k < 7) + *d = a; + } + + int + main () + { + fn1 (); + return 0; + } Index: gcc/tree-ssa-sccvn.c =================================================================== *** gcc/tree-ssa-sccvn.c (revision 232717) --- gcc/tree-ssa-sccvn.c (working copy) *************** set_ssa_val_to (tree from, tree to) *** 3139,3153 **** { /* Save old info. */ if (! VN_INFO (to)->info.range_info) ! VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to); /* Use that from the dominator. */ SSA_NAME_RANGE_INFO (to) = SSA_NAME_RANGE_INFO (from); } else { /* Save old info. */ if (! VN_INFO (to)->info.range_info) ! VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to); /* Rather than allocating memory and unioning the info just clear it. */ SSA_NAME_RANGE_INFO (to) = NULL; --- 3139,3162 ---- { /* Save old info. */ if (! VN_INFO (to)->info.range_info) ! { ! VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to); ! VN_INFO (to)->range_info_anti_range_p ! = SSA_NAME_ANTI_RANGE_P (to); ! } /* Use that from the dominator. */ SSA_NAME_RANGE_INFO (to) = SSA_NAME_RANGE_INFO (from); + SSA_NAME_ANTI_RANGE_P (to) = SSA_NAME_ANTI_RANGE_P (from); } else { /* Save old info. */ if (! VN_INFO (to)->info.range_info) ! { ! VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to); ! VN_INFO (to)->range_info_anti_range_p ! = SSA_NAME_ANTI_RANGE_P (to); ! } /* Rather than allocating memory and unioning the info just clear it. */ SSA_NAME_RANGE_INFO (to) = NULL; *************** free_scc_vn (void) *** 4313,4319 **** SSA_NAME_PTR_INFO (name) = VN_INFO (name)->info.ptr_info; else if (INTEGRAL_TYPE_P (TREE_TYPE (name)) && VN_INFO (name)->info.range_info) ! SSA_NAME_RANGE_INFO (name) = VN_INFO (name)->info.range_info; } } obstack_free (&vn_ssa_aux_obstack, NULL); --- 4322,4332 ---- SSA_NAME_PTR_INFO (name) = VN_INFO (name)->info.ptr_info; else if (INTEGRAL_TYPE_P (TREE_TYPE (name)) && VN_INFO (name)->info.range_info) ! { ! SSA_NAME_RANGE_INFO (name) = VN_INFO (name)->info.range_info; ! SSA_NAME_ANTI_RANGE_P (name) ! = VN_INFO (name)->range_info_anti_range_p; ! } } } obstack_free (&vn_ssa_aux_obstack, NULL);