[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