From c5c0ca9c490cfce4e4c7b0b9f6415d961079f1dc Mon Sep 17 00:00:00 2001
From: Yury Gribov <tetra2005@gmail.com>
Date: Thu, 18 Oct 2018 20:45:33 +0200
Subject: [PATCH] 2018-10-21  Yury Gribov  <tetra2005@gmail.com>

gcc/
	PR tree-optimization/87633
	* match.pd: Do not generate unordered integer comparisons.

gcc/testsuite/
	PR tree-optimization/87633
	* g++.dg/pr87633.C: New test.
---
 gcc/match.pd                   | 23 +++++++++++++----------
 gcc/testsuite/g++.dg/pr87633.C | 21 +++++++++++++++++++++
 2 files changed, 34 insertions(+), 10 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/pr87633.C

diff --git a/gcc/match.pd b/gcc/match.pd
index b36d7cc..8796a40 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -3401,7 +3401,8 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
 	(cmp @0 @1))))))
 
 /* Optimize various special cases of (FTYPE) N CMP (FTYPE) M.  */
-(for cmp (tcc_comparison)
+(for cmp  (lt le eq ne ge gt unordered ordered unlt unle ungt unge uneq ltgt)
+     icmp (lt le eq ne ge gt unordered ordered lt   le   gt   ge   eq   ne)
  (simplify
   (cmp (float@0 @1) (float @2))
    (if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (@0))
@@ -3416,15 +3417,17 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
      }
      (if (fmt.can_represent_integral_type_p (type1)
 	  && fmt.can_represent_integral_type_p (type2))
-      (if (TYPE_PRECISION (type1) > TYPE_PRECISION (type2)
-           && type1_signed_p >= type2_signed_p)
-       (cmp @1 (convert @2))
-       (if (TYPE_PRECISION (type1) < TYPE_PRECISION (type2)
-            && type1_signed_p <= type2_signed_p)
-        (cmp (convert:type2 @1) @2)
-        (if (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
-             && type1_signed_p == type2_signed_p)
-	 (cmp @1 @2)))))))))
+      (if (cmp == ORDERED_EXPR || cmp == UNORDERED_EXPR)
+       { constant_boolean_node (cmp == ORDERED_EXPR, type); }
+       (if (TYPE_PRECISION (type1) > TYPE_PRECISION (type2)
+	    && type1_signed_p >= type2_signed_p)
+	(icmp @1 (convert @2))
+	(if (TYPE_PRECISION (type1) < TYPE_PRECISION (type2)
+	     && type1_signed_p <= type2_signed_p)
+	 (icmp (convert:type2 @1) @2)
+	 (if (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
+	      && type1_signed_p == type2_signed_p)
+	  (icmp @1 @2))))))))))
 
 /* Optimize various special cases of (FTYPE) N CMP CST.  */
 (for cmp  (lt le eq ne ge gt)
diff --git a/gcc/testsuite/g++.dg/pr87633.C b/gcc/testsuite/g++.dg/pr87633.C
new file mode 100644
index 0000000..86926cd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr87633.C
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+class a {
+public:
+  double b() const;
+};
+class c {
+public:
+  int m_fn2() const;
+};
+double a::b() const {
+  return 0 == 0 ? reinterpret_cast<const c *>(this)->m_fn2() : 0;
+}
+bool d;
+void e() {
+  a f;
+  double g = f.b();
+  /* { dg-final { scan-tree-dump-not "unord" "optimized" } } */
+  d = __builtin_isnan(g);
+}
-- 
2.9.4

