[PATCH] Fix PR86554 on branch
Richard Biener
rguenther@suse.de
Wed Feb 13 14:21:00 GMT 2019
This backports the fix to the GCC 8 branch where we have a different
way of determining availability.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.
Richard.
2019-02-13 Richard Biener <rguenther@suse.de>
Backport from mainline
2019-01-08 Richard Biener <rguenther@suse.de>
PR tree-optimization/86554
* tree-ssa-sccvn.c (visit_nary_op): When value-numbering to
expressions with different overflow behavior make sure there's an
available expression on the path.
* gcc.dg/torture/pr86554-1.c: New testcase.
* gcc.dg/torture/pr86554-2.c: Likewise.
Index: gcc/testsuite/gcc.dg/torture/pr86554-1.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr86554-1.c (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr86554-1.c (working copy)
@@ -0,0 +1,35 @@
+/* { dg-do run } */
+
+struct foo
+{
+ unsigned x;
+};
+typedef struct foo foo;
+
+static inline int zot(foo *f)
+{
+ int ret;
+
+ if (f->x > 0x7FFFFFFF)
+ ret = (int)(f->x - 0x7FFFFFFF);
+ else
+ ret = (int)f->x - 0x7FFFFFFF;
+ return ret;
+}
+
+void __attribute__((noinline,noclone)) bar(foo *f)
+{
+ int ret = zot(f);
+ volatile int x = ret;
+ if (ret < 1)
+ __builtin_abort ();
+}
+
+int main()
+{
+ foo f;
+ f.x = 0x800003f8;
+
+ bar(&f);
+ return 0;
+}
Index: gcc/testsuite/gcc.dg/torture/pr86554-2.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr86554-2.c (nonexistent)
+++ gcc/testsuite/gcc.dg/torture/pr86554-2.c (working copy)
@@ -0,0 +1,49 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+struct s { __INT64_TYPE__ e; };
+
+static void f (struct s *ps)
+{
+ volatile __INT64_TYPE__ m = 9223372036854775807;
+ const char *str = "11E";
+ int r;
+ __INT64_TYPE__ sum;
+
+ ps->e = 0;
+
+ for (;;)
+ {
+ if (*str++ != '1')
+ break;
+ ps->e ++;
+ }
+
+ r = 1;
+ sum = m;
+
+ if (sum >= 0 && ps->e >= 0)
+ {
+ __UINT64_TYPE__ uc;
+ uc = (__UINT64_TYPE__) sum + (__UINT64_TYPE__) ps->e;
+ if (uc > 9223372036854775807)
+ r = 2;
+ else
+ sum = 17;
+ }
+ else
+ sum = sum + ps->e;
+
+ if (sum != 9223372036854775807)
+ __builtin_abort ();
+ if (r != 2)
+ __builtin_abort ();
+ ps->e = sum;
+}
+
+int main (void)
+{
+ struct s s;
+ f (&s);
+ return 0;
+}
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c (revision 268838)
+++ gcc/tree-ssa-sccvn.c (working copy)
@@ -3619,7 +3619,17 @@ visit_nary_op (tree lhs, gassign *stmt)
ops[0] = vn_nary_op_lookup_pieces
(2, gimple_assign_rhs_code (def), type, ops, NULL);
/* We have wider operation available. */
- if (ops[0])
+ if (ops[0]
+ /* If the leader is a wrapping operation we can
+ insert it for code hoisting w/o introducing
+ undefined overflow. If it is not it has to
+ be available. See PR86554. */
+ && (TYPE_OVERFLOW_WRAPS (TREE_TYPE (ops[0]))
+ || TREE_CODE (ops[0]) != SSA_NAME
+ || SSA_NAME_IS_DEFAULT_DEF (ops[0])
+ || dominated_by_p_w_unex
+ (gimple_bb (stmt),
+ gimple_bb (SSA_NAME_DEF_STMT (ops[0])))))
{
unsigned lhs_prec = TYPE_PRECISION (type);
unsigned rhs_prec = TYPE_PRECISION (TREE_TYPE (rhs1));
More information about the Gcc-patches
mailing list