diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 16e18303d63..f102049cf2a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2016-01-25 Richard Biener + + 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. + 2016-01-25 Nick Clifton PR target/66655 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 30540554b73..70fb83fce75 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-25 Richard Biener + + PR tree-optimization/69376 + * gcc.dg/torture/pr69376.c: New testcase. + 2016-01-24 Jerry DeLisle PR fortran/69397 diff --git a/gcc/testsuite/gcc.dg/torture/pr69376.c b/gcc/testsuite/gcc.dg/torture/pr69376.c new file mode 100644 index 00000000000..e907e2215fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr69376.c @@ -0,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; +} diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 311663d80a2..3570ee92a2b 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4047,7 +4047,7 @@ eliminate_dom_walker::before_dom_children (basic_block b) && ! VN_INFO_RANGE_INFO (sprime) && b == sprime_b) duplicate_ssa_name_range_info (sprime, - SSA_NAME_RANGE_TYPE (lhs), + VN_INFO_RANGE_TYPE (lhs), VN_INFO_RANGE_INFO (lhs)); } diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index b42525f8cf5..726294e2c2c 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -3139,15 +3139,24 @@ set_ssa_val_to (tree from, tree to) { /* Save old info. */ if (! VN_INFO (to)->info.range_info) - VN_INFO (to)->info.range_info = SSA_NAME_RANGE_INFO (to); + { + 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)->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; @@ -4313,7 +4322,11 @@ free_scc_vn (void) 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_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); diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 14093ddca44..e8e710b0c55 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -191,6 +191,9 @@ typedef struct vn_ssa_aux 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 }; @@ -253,6 +256,24 @@ VN_INFO_RANGE_INFO (tree name) : 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 *