re PR rtl-optimization/69570 (if-conversion bug on i?86)
authorJakub Jelinek <jakub@redhat.com>
Mon, 1 Feb 2016 08:47:27 +0000 (09:47 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Mon, 1 Feb 2016 08:47:27 +0000 (09:47 +0100)
PR rtl-optimization/69570
* ifcvt.c (bb_ok_for_noce_convert_multiple_sets): Return true only
if there is more than one set, not if there is a single set.

* g++.dg/opt/pr69570.C: New test.

From-SVN: r233033

gcc/ChangeLog
gcc/ifcvt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/pr69570.C [new file with mode: 0644]

index bf63f26202d748078d493a272fc7599875c19fbb..b0ba5c2302ee7893587d4f467c67d33559a58b07 100644 (file)
@@ -1,3 +1,9 @@
+2016-02-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/69570
+       * ifcvt.c (bb_ok_for_noce_convert_multiple_sets): Return true only
+       if there is more than one set, not if there is a single set.
+
 2016-02-01  Richard Henderson  <rth@redhat.com>
 
        PR rtl-opt/69535
index 74958fb76d06e61e3f32c5465950c9b54ef6439b..53cb41f1ffa7d8bbdd2665ba986bf325977398d3 100644 (file)
@@ -3295,7 +3295,7 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb,
   if (count > limit)
     return false;
 
-  return count > 0;
+  return count > 1;
 }
 
 /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
index d05a689e7b2ed53e3d93a76e02c2cb8c357188a8..6462028e62edbbb975723fb1605dbd1cd03cd786 100644 (file)
@@ -1,3 +1,8 @@
+2016-02-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/69570
+       * g++.dg/opt/pr69570.C: New test.
+
 2016-02-01  Richard Henderson  <rth@redhat.com>
 
        * gcc.dg/pr69535.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/pr69570.C b/gcc/testsuite/g++.dg/opt/pr69570.C
new file mode 100644 (file)
index 0000000..11ed416
--- /dev/null
@@ -0,0 +1,70 @@
+// PR rtl-optimization/69570
+// { dg-do run }
+// { dg-options "-O2" }
+// { dg-additional-options "-fpic" { target fpic } }
+// { dg-additional-options "-march=i686" { target ia32 } }
+
+template <typename T> inline const T &
+min (const T &a, const T &b)
+{
+  if (b < a)
+    return b;
+  return a;
+}
+
+template <typename T> inline const T &
+max (const T &a, const T &b)
+{
+  if (a < b)
+    return b;
+  return a;
+}
+
+static inline void
+foo (unsigned x, unsigned y, unsigned z, double &h, double &s, double &l)
+{
+  double r = x / 255.0;
+  double g = y / 255.0;
+  double b = z / 255.0;
+  double m = max (r, max (g, b));
+  double n = min (r, min (g, b));
+  double d = m - n;
+  double e = m + n;
+  h = 0.0, s = 0.0, l = e / 2.0;
+  if (d > 0.0)
+    {
+      s = l > 0.5 ? d / (2.0 - e) : d / e;
+      if (m == r && m != g)
+        h = (g - b) / d + (g < b ? 6.0 : 0.0);
+      if (m == g && m != b)
+        h = (b - r) / d + 2.0;
+      if (m == b && m != r)
+        h = (r - g) / d + 4.0;
+      h /= 6.0;
+    }
+}
+
+__attribute__ ((noinline, noclone))
+void bar (unsigned x[3], double y[3])
+{
+  double h, s, l;
+  foo (x[0], x[1], x[2], h, s, l);
+  y[0] = h;
+  y[1] = s;
+  y[2] = l;
+}
+
+int
+main ()
+{
+  unsigned x[3] = { 0, 128, 0 };
+  double y[3];
+
+  bar (x, y);
+  if (__builtin_fabs (y[0] - 0.33333) > 0.001
+      || __builtin_fabs (y[1] - 1) > 0.001
+      || __builtin_fabs (y[2] - 0.25098) > 0.001)
+    __builtin_abort ();
+
+  return 0;
+}