https://gcc.gnu.org/g:4ee9e8319abfeec1a9ba452661cb3d55aef684fa

commit r16-3474-g4ee9e8319abfeec1a9ba452661cb3d55aef684fa
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sat Aug 30 18:29:04 2025 +0200

    phiopt, math-opts: Adjust spaceship_replacement and optimize_spaceship for 
recent libstdc++ changes [PR121698]
    
    libstdc++ changed its ABI in <compare> for C++20 recently (under the
    C++20 is still experimental rule).  In addition to the -1, 0, 1 values
    for less, equal, greater it now uses -128 for unordered instead of
    former 2 and changes some of the operators, instead of checks like
    (_M_value & ~1) == _M_value in some cases it now uses _M_reverse()
    which is negation in unsigned char type + conversion back to the original
    type. _M_reverse() thus turns the -1, 0, 1, -128 values into
    1, 0, -1, -128.  Note libc++ uses value -127 instead of 2/-128.
    
    Now, the middle-end has some optimizations which rely on the particular
    implementation and don't optimize if not.  One is optimize_spaceship
    which on some targets (currently x86, aarch64 and s390) attempts to use
    better comparison instructions (ideally just one floating point comparison
    to get all 4 possible outcomes plus some flag tests or magic instead of
    2 or 3 floating point comparisons).  This one can actually handle
    arbitrary int non-[-1,1] values for unordered but still has a default
    of 2.  The patch changes that default to -128 so that even if something
    is expanded as branches if it is later during RTL optimizations determined
    to convert that into partial_ordering we get better code.
    
    The other optimization (phiopt one) is about optimizing (x <=> y) < 0
    etc. into just x < y.  This one actually relies on the exact unordered
    value (2) and has code to deal with that (_M_value & ~1) == _M_value
    kind of tests and whatever match.pd lowers it.  So, this patch partially
    rewrites it to look for -128 instead of 2, drop those
    (_M_value & ~1) == _M_value pattern recognitions and instead introduces
    pattern recognition of _M_reverse(), i.e. cast to unsigned char, negation
    in that type and cast back to the original signed type.
    
    With all these changes we get back the desired optimizations for all
    the cases we could optimize previously (note, for HONOR_NANS case
    we don't try to optimize say (x <=> y) == 0 because the original
    will raise exception if either x or y is a NaN, while turning it into
    x == y will not, but (x <=> y) <= 0 is fine (x <= y), because it
    does raise those exceptions.
    
    2025-08-30  Jakub Jelinek  <ja...@redhat.com>
    
            PR tree-optimization/121698
            * tree-ssa-phiopt.cc (spaceship_replacement): Adjust
            to handle spaceship unordered value -128 rather than 2 and
            stmts from the new std::partial_order::_M_reverse() instead
            of (_M_value & ~1) == _M_value etc.
            * doc/md.texi (spaceship@var{m}4): Use -128 instead of 2.
            * tree-ssa-math-opts.cc (optimize_spaceship): Adjust comments
            that libstdc++ unordered value is -128 rather than 2 and use
            that as the default unordered value.
            * config/i386/i386-expand.cc (ix86_expand_fp_spaceship): Use
            GEN_INT (-128) instead of const2_rtx and adjust comment accordingly.
            * config/aarch64/aarch64.cc (aarch64_expand_fp_spaceship): Likewise.
            * config/s390/s390.cc (s390_expand_fp_spaceship): Likewise.
    
            * gcc.dg/pr94589-2.c: Adjust for expected unordered value -128
            rather than 2 and negations in unsigned char instead of and with
            ~1 and comparison against original value.
            * gcc.dg/pr94589-4.c: Likewise.
            * gcc.dg/pr94589-5.c: Likewise.
            * gcc.dg/pr94589-6.c: Likewise.

Diff:
---
 gcc/config/aarch64/aarch64.cc    |   4 +-
 gcc/config/i386/i386-expand.cc   |   4 +-
 gcc/config/s390/s390.cc          |   4 +-
 gcc/doc/md.texi                  |   4 +-
 gcc/testsuite/gcc.dg/pr94589-2.c |  88 ++++++++-----
 gcc/testsuite/gcc.dg/pr94589-4.c |  84 +++++++++++++
 gcc/testsuite/gcc.dg/pr94589-5.c |  80 +++++++-----
 gcc/testsuite/gcc.dg/pr94589-6.c | 166 ++++++++++++++++++++-----
 gcc/tree-ssa-math-opts.cc        |  11 +-
 gcc/tree-ssa-phiopt.cc           | 261 ++++++++++++++++++++-------------------
 10 files changed, 473 insertions(+), 233 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
index c51105662153..fb05ea866d0b 100644
--- a/gcc/config/aarch64/aarch64.cc
+++ b/gcc/config/aarch64/aarch64.cc
@@ -31926,7 +31926,7 @@ aarch64_expand_reversed_crc_using_pmull (scalar_mode 
crc_mode,
 
 /* Expand the spaceship optab for floating-point operands.
 
-   If the result is compared against (-1, 0, 1 , 2), expand into
+   If the result is compared against (-1, 0, 1, -128), expand into
    fcmpe + conditional branch insns.
 
    Otherwise (the result is just stored as an integer), expand into
@@ -31965,7 +31965,7 @@ aarch64_expand_fp_spaceship (rtx dest, rtx op0, rtx 
op1, rtx hint)
       emit_jump (end_label);
 
       emit_label (un_label);
-      emit_move_insn (dest, const2_rtx);
+      emit_move_insn (dest, GEN_INT (-128));
       emit_jump (end_label);
 
       emit_label (gt_label);
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
index 1c788ae098ad..3278f1fea251 100644
--- a/gcc/config/i386/i386-expand.cc
+++ b/gcc/config/i386/i386-expand.cc
@@ -3151,7 +3151,7 @@ ix86_expand_setcc (rtx dest, enum rtx_code code, rtx op0, 
rtx op1)
 }
 
 /* Expand floating point op0 <=> op1, i.e.
-   dest = op0 == op1 ? 0 : op0 < op1 ? -1 : op0 > op1 ? 1 : 2.  */
+   dest = op0 == op1 ? 0 : op0 < op1 ? -1 : op0 > op1 ? 1 : -128.  */
 
 void
 ix86_expand_fp_spaceship (rtx dest, rtx op0, rtx op1, rtx op2)
@@ -3264,7 +3264,7 @@ ix86_expand_fp_spaceship (rtx dest, rtx op0, rtx op1, rtx 
op2)
   if (l2)
     {
       emit_label (l2);
-      emit_move_insn (dest, op2 == const0_rtx ? const2_rtx : op2);
+      emit_move_insn (dest, op2 == const0_rtx ? GEN_INT (-128) : op2);
     }
   emit_label (lend);
 }
diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
index d044f9a010ca..1a47f477dd3c 100644
--- a/gcc/config/s390/s390.cc
+++ b/gcc/config/s390/s390.cc
@@ -8318,7 +8318,7 @@ s390_expand_int_spaceship (rtx op0, rtx op1, rtx op2, rtx 
op3)
 }
 
 /* Expand floating-point op0 = op1 <=> op2, i.e.,
-   op0 = op1 == op2 ? 0 : op1 < op2 ? -1 : op1 > op2 ? 1 : 2.
+   op0 = op1 == op2 ? 0 : op1 < op2 ? -1 : op1 > op2 ? 1 : -128.
 
    If op3 equals const0_rtx, then we are interested in the compare only (see
    test spaceship-fp-4.c).  Otherwise, op3 is a CONST_INT different than
@@ -8368,7 +8368,7 @@ s390_expand_fp_spaceship (rtx op0, rtx op1, rtx op2, rtx 
op3)
     {
       emit_jump (l_end);
       emit_label (l_unordered);
-      rtx unord_val = op3 == const0_rtx ? const2_rtx : op3;
+      rtx unord_val = op3 == const0_rtx ? GEN_INT (-128) : op3;
       emit_move_insn (op0, unord_val);
     }
   emit_label (l_end);
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index aba93f606eca..70a27555d900 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -8595,7 +8595,7 @@ If this pattern is not defined, a call to the library 
function
 
 @cindex @code{spaceship@var{m}4} instruction pattern
 @item @samp{spaceship@var{m}4}
-Initialize output operand 0 with mode of integer type to -1, 0, 1 or 2
+Initialize output operand 0 with mode of integer type to -1, 0, 1 or -128
 if operand 1 with mode @var{m} compares less than operand 2, equal to
 operand 2, greater than operand 2 or is unordered with operand 2.
 Operand 3 should be @code{const0_rtx} if the result is used in comparisons,
@@ -8603,7 +8603,7 @@ Operand 3 should be @code{const0_rtx} if the result is 
used in comparisons,
 is integral unsigned, @code{constm1_rtx} if the result is used as integer
 value and the comparison is integral signed and some other @code{CONST_INT}
 if the result is used as integer value and the comparison is floating point.
-In the last case, instead of setting output operand 0 to 2 for unordered,
+In the last case, instead of setting output operand 0 to -128 for unordered,
 set it to operand 3.
 @var{m} should be a scalar floating point mode.
 
diff --git a/gcc/testsuite/gcc.dg/pr94589-2.c b/gcc/testsuite/gcc.dg/pr94589-2.c
index 9481b764dabf..b20cccde4931 100644
--- a/gcc/testsuite/gcc.dg/pr94589-2.c
+++ b/gcc/testsuite/gcc.dg/pr94589-2.c
@@ -1,35 +1,63 @@
 /* PR tree-optimization/94589 */
 /* { dg-do compile } */
 /* { dg-options "-O2 -g0 -ffast-math -fdump-tree-optimized" } */
-/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 
\[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 
5\\.0" 14 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 
\[ij]_\[0-9]+\\(D\\)" 28 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|==|!=|>|>=) 
5\\.0" 28 "optimized" } } */
 
 #define A __attribute__((noipa))
-A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c == 0; }
-A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c != 0; }
-A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c > 0; }
-A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c < 0; }
-A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c >= 0; }
-A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c <= 0; }
-A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c == -1; }
-A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c != -1; }
-A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c > -1; }
-A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c <= -1; }
-A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c == 1; }
-A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c != 1; }
-A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c < 1; }
-A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c >= 1; }
-A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c == 0; }
-A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c != 0; }
-A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c > 0; }
-A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c < 0; }
-A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c >= 0; }
-A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c <= 0; }
-A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c == -1; }
-A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c != -1; }
-A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c > -1; }
-A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c <= -1; }
-A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c == 1; }
-A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c != 1; }
-A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c < 1; }
-A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c >= 1; }
+A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c == 0; }
+A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c != 0; }
+A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c > 0; }
+A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c < 0; }
+A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c >= 0; }
+A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c <= 0; }
+A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c == -1; }
+A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c != -1; }
+A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c > -1; }
+A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c <= -1; }
+A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c == 1; }
+A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c != 1; }
+A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c < 1; }
+A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c >= 1; }
+A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c == 0; }
+A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c != 0; }
+A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c > 0; }
+A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c < 0; }
+A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c >= 0; }
+A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c <= 0; }
+A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c == -1; }
+A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c != -1; }
+A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c > -1; }
+A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c <= -1; }
+A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c == 1; }
+A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c != 1; }
+A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c < 1; }
+A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c >= 1; }
+A int f29 (double i, double j) { signed char c; if (i == j) c = 0; else if (i 
< j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == 0; }
+A signed char f30 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f != 0; }
+A signed char f31 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f < 0; }
+A signed char f32 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f > 0; }
+A signed char f33 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f <= 0; }
+A signed char f34 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f >= 0; }
+A signed char f35 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f == 1; }
+A signed char f36 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f != 1; }
+A signed char f37 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f < 1; }
+A signed char f38 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f >= 1; }
+A signed char f39 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f == -1; }
+A signed char f40 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f != -1; }
+A signed char f41 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f > -1; }
+A signed char f42 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f <= -1; }
+A signed char f43 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == 0; }
+A signed char f44 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f != 0; }
+A signed char f45 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f < 0; }
+A signed char f46 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f > 0; }
+A signed char f47 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f <= 0; }
+A signed char f48 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f >= 0; }
+A signed char f49 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == 1; }
+A signed char f50 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f != 1; }
+A signed char f51 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f < 1; }
+A signed char f52 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f >= 1; }
+A signed char f53 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == -1; }
+A signed char f54 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f != -1; }
+A signed char f55 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f > -1; }
+A signed char f56 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f <= -1; }
diff --git a/gcc/testsuite/gcc.dg/pr94589-4.c b/gcc/testsuite/gcc.dg/pr94589-4.c
index b2557fb07b0f..f277b6c60250 100644
--- a/gcc/testsuite/gcc.dg/pr94589-4.c
+++ b/gcc/testsuite/gcc.dg/pr94589-4.c
@@ -93,5 +93,89 @@ main ()
   D (f28, 4.0, 0);
   D (f28, 5.0, 0);
   D (f28, 6.0, 1);
+  C (f29, 7.0, 8.0, 0);
+  C (f29, 8.0, 8.0, 1);
+  C (f29, 9.0, 8.0, 0);
+  C (f30, 7.0, 8.0, 1);
+  C (f30, 8.0, 8.0, 0);
+  C (f30, 9.0, 8.0, 1);
+  C (f31, 7.0, 8.0, 0);
+  C (f31, 8.0, 8.0, 0);
+  C (f31, 9.0, 8.0, 1);
+  C (f32, 7.0, 8.0, 1);
+  C (f32, 8.0, 8.0, 0);
+  C (f32, 9.0, 8.0, 0);
+  C (f33, 7.0, 8.0, 0);
+  C (f33, 8.0, 8.0, 1);
+  C (f33, 9.0, 8.0, 1);
+  C (f34, 7.0, 8.0, 1);
+  C (f34, 8.0, 8.0, 1);
+  C (f34, 9.0, 8.0, 0);
+  C (f35, 7.0, 8.0, 1);
+  C (f35, 8.0, 8.0, 0);
+  C (f35, 9.0, 8.0, 0);
+  C (f36, 7.0, 8.0, 0);
+  C (f36, 8.0, 8.0, 1);
+  C (f36, 9.0, 8.0, 1);
+  C (f37, 7.0, 8.0, 0);
+  C (f37, 8.0, 8.0, 1);
+  C (f37, 9.0, 8.0, 1);
+  C (f38, 7.0, 8.0, 1);
+  C (f38, 8.0, 8.0, 0);
+  C (f38, 9.0, 8.0, 0);
+  C (f39, 7.0, 8.0, 0);
+  C (f39, 8.0, 8.0, 0);
+  C (f39, 9.0, 8.0, 1);
+  C (f40, 7.0, 8.0, 1);
+  C (f40, 8.0, 8.0, 1);
+  C (f40, 9.0, 8.0, 0);
+  C (f41, 7.0, 8.0, 1);
+  C (f41, 8.0, 8.0, 1);
+  C (f41, 9.0, 8.0, 0);
+  C (f42, 7.0, 8.0, 0);
+  C (f42, 8.0, 8.0, 0);
+  C (f42, 9.0, 8.0, 1);
+  D (f43, 4.0, 0);
+  D (f43, 5.0, 1);
+  D (f43, 6.0, 0);
+  D (f44, 4.0, 1);
+  D (f44, 5.0, 0);
+  D (f44, 6.0, 1);
+  D (f45, 4.0, 0);
+  D (f45, 5.0, 0);
+  D (f45, 6.0, 1);
+  D (f46, 4.0, 1);
+  D (f46, 5.0, 0);
+  D (f46, 6.0, 0);
+  D (f47, 4.0, 0);
+  D (f47, 5.0, 1);
+  D (f47, 6.0, 1);
+  D (f48, 4.0, 1);
+  D (f48, 5.0, 1);
+  D (f48, 6.0, 0);
+  D (f49, 4.0, 1);
+  D (f49, 5.0, 0);
+  D (f49, 6.0, 0);
+  D (f50, 4.0, 0);
+  D (f50, 5.0, 1);
+  D (f50, 6.0, 1);
+  D (f51, 4.0, 0);
+  D (f51, 5.0, 1);
+  D (f51, 6.0, 1);
+  D (f52, 4.0, 1);
+  D (f52, 5.0, 0);
+  D (f52, 6.0, 0);
+  D (f53, 4.0, 0);
+  D (f53, 5.0, 0);
+  D (f53, 6.0, 1);
+  D (f54, 4.0, 1);
+  D (f54, 5.0, 1);
+  D (f54, 6.0, 0);
+  D (f55, 4.0, 1);
+  D (f55, 5.0, 1);
+  D (f55, 6.0, 0);
+  D (f56, 4.0, 0);
+  D (f56, 5.0, 0);
+  D (f56, 6.0, 1);
   return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/pr94589-5.c b/gcc/testsuite/gcc.dg/pr94589-5.c
index 8777fa4d097a..65dfd057db5e 100644
--- a/gcc/testsuite/gcc.dg/pr94589-5.c
+++ b/gcc/testsuite/gcc.dg/pr94589-5.c
@@ -1,35 +1,55 @@
 /* PR tree-optimization/94589 */
 /* { dg-do compile { target inf } } */
 /* { dg-options "-O2 -g0 -fdump-tree-optimized" } */
-/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|>|>=) 
\[ij]_\[0-9]+\\(D\\)" 14 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|>|>=) 5\\.0" 14 
"optimized" } } */
+/* { dg-final { scan-tree-dump-times "\[ij]_\[0-9]+\\(D\\) (?:<|<=|>|>=) 
\[ij]_\[0-9]+\\(D\\)" 24 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "i_\[0-9]+\\(D\\) (?:<|<=|>|>=) 5\\.0" 24 
"optimized" } } */
 
 #define A __attribute__((noipa))
-A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c > 0; }
-A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c < 0; }
-A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c >= 0; }
-A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c <= 0; }
-A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c == -1; }
-A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c != -1; }
-A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c > -1; }
-A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c <= -1; }
-A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c == 1; }
-A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c != 1; }
-A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c < 1; }
-A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c >= 1; }
-A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c > 0; }
-A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c < 0; }
-A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c >= 0; }
-A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c <= 0; }
-A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c == -1; }
-A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c != -1; }
-A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c > -1; }
-A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c <= -1; }
-A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c == 1; }
-A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c != 1; }
-A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c < 1; }
-A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c >= 1; }
-A int f29 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return (c & ~1) == 0; }
-A int f30 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return (c & ~1) != 0; }
-A int f31 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return (c & ~1) == 0; }
-A int f32 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return (c & ~1) != 0; }
+A int f3 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c > 0; }
+A int f4 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c < 0; }
+A int f5 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c >= 0; }
+A int f6 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c <= 0; }
+A int f7 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c == -1; }
+A int f8 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c != -1; }
+A int f9 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c > -1; }
+A int f10 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c <= -1; }
+A int f11 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c == 1; }
+A int f12 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c != 1; }
+A int f13 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c < 1; }
+A int f14 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c >= 1; }
+A int f17 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c > 0; }
+A int f18 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c < 0; }
+A int f19 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c >= 0; }
+A int f20 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c <= 0; }
+A int f21 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c == -1; }
+A int f22 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c != -1; }
+A int f23 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c > -1; }
+A int f24 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c <= -1; }
+A int f25 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c == 1; }
+A int f26 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c != 1; }
+A int f27 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c < 1; }
+A int f28 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c >= 1; }
+A signed char f31 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f < 0; }
+A signed char f32 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f > 0; }
+A signed char f33 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f <= 0; }
+A signed char f34 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f >= 0; }
+A signed char f35 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f == 1; }
+A signed char f36 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f != 1; }
+A signed char f37 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f < 1; }
+A signed char f38 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f >= 1; }
+A signed char f39 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f == -1; }
+A signed char f40 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f != -1; }
+A signed char f41 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f > -1; }
+A signed char f42 (double i, double j) { signed char c; if (i == j) c = 0; 
else if (i < j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = 
c; unsigned char e = -d; signed char f = e; return f <= -1; }
+A signed char f45 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f < 0; }
+A signed char f46 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f > 0; }
+A signed char f47 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f <= 0; }
+A signed char f48 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f >= 0; }
+A signed char f49 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == 1; }
+A signed char f50 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f != 1; }
+A signed char f51 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f < 1; }
+A signed char f52 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f >= 1; }
+A signed char f53 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == -1; }
+A signed char f54 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f != -1; }
+A signed char f55 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f > -1; }
+A signed char f56 (double i) { signed char c; if (i == 5.0) c = 0; else if (i 
< 5.0) c = -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f <= -1; }
diff --git a/gcc/testsuite/gcc.dg/pr94589-6.c b/gcc/testsuite/gcc.dg/pr94589-6.c
index 2014c1cdcdfc..3131ab4cfae7 100644
--- a/gcc/testsuite/gcc.dg/pr94589-6.c
+++ b/gcc/testsuite/gcc.dg/pr94589-6.c
@@ -3,13 +3,19 @@
 
 #include "pr94589-5.c"
 
-A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c == 0; }
-A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = 2; return c != 0; }
-A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c == 0; }
-A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = 2; return c != 0; }
+A int f1 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c == 0; }
+A int f2 (double i, double j) { int c; if (i == j) c = 0; else if (i < j) c = 
-1; else if (i > j) c = 1; else c = -128; return c != 0; }
+A int f15 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c == 0; }
+A int f16 (double i) { int c; if (i == 5.0) c = 0; else if (i < 5.0) c = -1; 
else if (i > 5.0) c = 1; else c = -128; return c != 0; }
+A int f29 (double i, double j) { signed char c; if (i == j) c = 0; else if (i 
< j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f == 0; }
+A int f30 (double i, double j) { signed char c; if (i == j) c = 0; else if (i 
< j) c = -1; else if (i > j) c = 1; else c = -128; unsigned char d = c; 
unsigned char e = -d; signed char f = e; return f != 0; }
+A int f43 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) c 
= -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; unsigned 
char e = -d; signed char f = e; return f == 0; }
+A int f44 (double i) { signed char c; if (i == 5.0) c = 0; else if (i < 5.0) c 
= -1; else if (i > 5.0) c = 1; else c = -128; unsigned char d = c; unsigned 
char e = -d; signed char f = e; return f != 0; }
 
-#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort ()
-#define D(fn, i, r) if (fn (i) != r) __builtin_abort ()
+//#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_abort ()
+//#define D(fn, i, r) if (fn (i) != r) __builtin_abort ()
+#define C(fn, i, j, r) if (fn (i, j) != r) __builtin_printf ("%d\n", __LINE__)
+#define D(fn, i, r) if (fn (i) != r) __builtin_printf ("%d\n", __LINE__)
 
 int
 main ()
@@ -25,19 +31,19 @@ main ()
   C (f3, 7.0, 8.0, 0);
   C (f3, 8.0, 8.0, 0);
   C (f3, 9.0, 8.0, 1);
-  C (f3, __builtin_nan (""), 8.0, 1);
+  C (f3, __builtin_nan (""), 8.0, 0);
   C (f4, 7.0, 8.0, 1);
   C (f4, 8.0, 8.0, 0);
   C (f4, 9.0, 8.0, 0);
-  C (f4, __builtin_nan (""), 8.0, 0);
+  C (f4, __builtin_nan (""), 8.0, 1);
   C (f5, 7.0, 8.0, 0);
   C (f5, 8.0, 8.0, 1);
   C (f5, 9.0, 8.0, 1);
-  C (f5, __builtin_nan (""), 8.0, 1);
+  C (f5, __builtin_nan (""), 8.0, 0);
   C (f6, 7.0, 8.0, 1);
   C (f6, 8.0, 8.0, 1);
   C (f6, 9.0, 8.0, 0);
-  C (f6, __builtin_nan (""), 8.0, 0);
+  C (f6, __builtin_nan (""), 8.0, 1);
   C (f7, 7.0, 8.0, 1);
   C (f7, 8.0, 8.0, 0);
   C (f7, 9.0, 8.0, 0);
@@ -49,11 +55,11 @@ main ()
   C (f9, 7.0, 8.0, 0);
   C (f9, 8.0, 8.0, 1);
   C (f9, 9.0, 8.0, 1);
-  C (f9, __builtin_nan (""), 8.0, 1);
+  C (f9, __builtin_nan (""), 8.0, 0);
   C (f10, 7.0, 8.0, 1);
   C (f10, 8.0, 8.0, 0);
   C (f10, 9.0, 8.0, 0);
-  C (f10, __builtin_nan (""), 8.0, 0);
+  C (f10, __builtin_nan (""), 8.0, 1);
   C (f11, 7.0, 8.0, 0);
   C (f11, 8.0, 8.0, 0);
   C (f11, 9.0, 8.0, 1);
@@ -65,11 +71,11 @@ main ()
   C (f13, 7.0, 8.0, 1);
   C (f13, 8.0, 8.0, 1);
   C (f13, 9.0, 8.0, 0);
-  C (f13, __builtin_nan (""), 8.0, 0);
+  C (f13, __builtin_nan (""), 8.0, 1);
   C (f14, 7.0, 8.0, 0);
   C (f14, 8.0, 8.0, 0);
   C (f14, 9.0, 8.0, 1);
-  C (f14, __builtin_nan (""), 8.0, 1);
+  C (f14, __builtin_nan (""), 8.0, 0);
   D (f15, 4.0, 0);
   D (f15, 5.0, 1);
   D (f15, 6.0, 0);
@@ -81,19 +87,19 @@ main ()
   D (f17, 4.0, 0);
   D (f17, 5.0, 0);
   D (f17, 6.0, 1);
-  D (f17, __builtin_nan (""), 1);
+  D (f17, __builtin_nan (""), 0);
   D (f18, 4.0, 1);
   D (f18, 5.0, 0);
   D (f18, 6.0, 0);
-  D (f18, __builtin_nan (""), 0);
+  D (f18, __builtin_nan (""), 1);
   D (f19, 4.0, 0);
   D (f19, 5.0, 1);
   D (f19, 6.0, 1);
-  D (f19, __builtin_nan (""), 1);
+  D (f19, __builtin_nan (""), 0);
   D (f20, 4.0, 1);
   D (f20, 5.0, 1);
   D (f20, 6.0, 0);
-  D (f20, __builtin_nan (""), 0);
+  D (f20, __builtin_nan (""), 1);
   D (f21, 4.0, 1);
   D (f21, 5.0, 0);
   D (f21, 6.0, 0);
@@ -105,11 +111,11 @@ main ()
   D (f23, 4.0, 0);
   D (f23, 5.0, 1);
   D (f23, 6.0, 1);
-  D (f23, __builtin_nan (""), 1);
+  D (f23, __builtin_nan (""), 0);
   D (f24, 4.0, 1);
   D (f24, 5.0, 0);
   D (f24, 6.0, 0);
-  D (f24, __builtin_nan (""), 0);
+  D (f24, __builtin_nan (""), 1);
   D (f25, 4.0, 0);
   D (f25, 5.0, 0);
   D (f25, 6.0, 1);
@@ -121,26 +127,122 @@ main ()
   D (f27, 4.0, 1);
   D (f27, 5.0, 1);
   D (f27, 6.0, 0);
-  D (f27, __builtin_nan (""), 0);
+  D (f27, __builtin_nan (""), 1);
   D (f28, 4.0, 0);
   D (f28, 5.0, 0);
   D (f28, 6.0, 1);
-  D (f28, __builtin_nan (""), 1);
+  D (f28, __builtin_nan (""), 0);
   C (f29, 7.0, 8.0, 0);
   C (f29, 8.0, 8.0, 1);
-  C (f29, 9.0, 8.0, 1);
+  C (f29, 9.0, 8.0, 0);
   C (f29, __builtin_nan (""), 8.0, 0);
   C (f30, 7.0, 8.0, 1);
   C (f30, 8.0, 8.0, 0);
-  C (f30, 9.0, 8.0, 0);
+  C (f30, 9.0, 8.0, 1);
   C (f30, __builtin_nan (""), 8.0, 1);
-  D (f31, 4.0, 0);
-  D (f31, 5.0, 1);
-  D (f31, 6.0, 1);
-  D (f31, __builtin_nan (""), 0);
-  D (f32, 4.0, 1);
-  D (f32, 5.0, 0);
-  D (f32, 6.0, 0);
-  D (f32, __builtin_nan (""), 1);
+  C (f31, 7.0, 8.0, 0);
+  C (f31, 8.0, 8.0, 0);
+  C (f31, 9.0, 8.0, 1);
+  C (f31, __builtin_nan (""), 8.0, 1);
+  C (f32, 7.0, 8.0, 1);
+  C (f32, 8.0, 8.0, 0);
+  C (f32, 9.0, 8.0, 0);
+  C (f32, __builtin_nan (""), 8.0, 0);
+  C (f33, 7.0, 8.0, 0);
+  C (f33, 8.0, 8.0, 1);
+  C (f33, 9.0, 8.0, 1);
+  C (f33, __builtin_nan (""), 8.0, 1);
+  C (f34, 7.0, 8.0, 1);
+  C (f34, 8.0, 8.0, 1);
+  C (f34, 9.0, 8.0, 0);
+  C (f34, __builtin_nan (""), 8.0, 0);
+  C (f35, 7.0, 8.0, 1);
+  C (f35, 8.0, 8.0, 0);
+  C (f35, 9.0, 8.0, 0);
+  C (f35, __builtin_nan (""), 8.0, 0);
+  C (f36, 7.0, 8.0, 0);
+  C (f36, 8.0, 8.0, 1);
+  C (f36, 9.0, 8.0, 1);
+  C (f36, __builtin_nan (""), 8.0, 1);
+  C (f37, 7.0, 8.0, 0);
+  C (f37, 8.0, 8.0, 1);
+  C (f37, 9.0, 8.0, 1);
+  C (f37, __builtin_nan (""), 8.0, 1);
+  C (f38, 7.0, 8.0, 1);
+  C (f38, 8.0, 8.0, 0);
+  C (f38, 9.0, 8.0, 0);
+  C (f38, __builtin_nan (""), 8.0, 0);
+  C (f39, 7.0, 8.0, 0);
+  C (f39, 8.0, 8.0, 0);
+  C (f39, 9.0, 8.0, 1);
+  C (f39, __builtin_nan (""), 8.0, 0);
+  C (f40, 7.0, 8.0, 1);
+  C (f40, 8.0, 8.0, 1);
+  C (f40, 9.0, 8.0, 0);
+  C (f40, __builtin_nan (""), 8.0, 1);
+  C (f41, 7.0, 8.0, 1);
+  C (f41, 8.0, 8.0, 1);
+  C (f41, 9.0, 8.0, 0);
+  C (f41, __builtin_nan (""), 8.0, 0);
+  C (f42, 7.0, 8.0, 0);
+  C (f42, 8.0, 8.0, 0);
+  C (f42, 9.0, 8.0, 1);
+  C (f42, __builtin_nan (""), 8.0, 1);
+  D (f43, 4.0, 0);
+  D (f43, 5.0, 1);
+  D (f43, 6.0, 0);
+  D (f43, __builtin_nan (""), 0);
+  D (f44, 4.0, 1);
+  D (f44, 5.0, 0);
+  D (f44, 6.0, 1);
+  D (f44, __builtin_nan (""), 1);
+  D (f45, 4.0, 0);
+  D (f45, 5.0, 0);
+  D (f45, 6.0, 1);
+  D (f45, __builtin_nan (""), 1);
+  D (f46, 4.0, 1);
+  D (f46, 5.0, 0);
+  D (f46, 6.0, 0);
+  D (f46, __builtin_nan (""), 0);
+  D (f47, 4.0, 0);
+  D (f47, 5.0, 1);
+  D (f47, 6.0, 1);
+  D (f47, __builtin_nan (""), 1);
+  D (f48, 4.0, 1);
+  D (f48, 5.0, 1);
+  D (f48, 6.0, 0);
+  D (f48, __builtin_nan (""), 0);
+  D (f49, 4.0, 1);
+  D (f49, 5.0, 0);
+  D (f49, 6.0, 0);
+  D (f49, __builtin_nan (""), 0);
+  D (f50, 4.0, 0);
+  D (f50, 5.0, 1);
+  D (f50, 6.0, 1);
+  D (f50, __builtin_nan (""), 1);
+  D (f51, 4.0, 0);
+  D (f51, 5.0, 1);
+  D (f51, 6.0, 1);
+  D (f51, __builtin_nan (""), 1);
+  D (f52, 4.0, 1);
+  D (f52, 5.0, 0);
+  D (f52, 6.0, 0);
+  D (f52, __builtin_nan (""), 0);
+  D (f53, 4.0, 0);
+  D (f53, 5.0, 0);
+  D (f53, 6.0, 1);
+  D (f53, __builtin_nan (""), 0);
+  D (f54, 4.0, 1);
+  D (f54, 5.0, 1);
+  D (f54, 6.0, 0);
+  D (f54, __builtin_nan (""), 1);
+  D (f55, 4.0, 1);
+  D (f55, 5.0, 1);
+  D (f55, 6.0, 0);
+  D (f55, __builtin_nan (""), 0);
+  D (f56, 4.0, 0);
+  D (f56, 5.0, 0);
+  D (f56, 6.0, 1);
+  D (f56, __builtin_nan (""), 1);
   return 0;
 }
diff --git a/gcc/tree-ssa-math-opts.cc b/gcc/tree-ssa-math-opts.cc
index 591ecd387a6a..bfad4cf5c99d 100644
--- a/gcc/tree-ssa-math-opts.cc
+++ b/gcc/tree-ssa-math-opts.cc
@@ -6085,9 +6085,9 @@ convert_mult_to_highpart (gassign *stmt, 
gimple_stmt_iterator *gsi)
    conditional jump sequence.  If the
    <bb 6> [local count: 1073741824]:
    above has a single PHI like:
-   # _27 = PHI<0(2), -1(3), 2(4), 1(5)>
+   # _27 = PHI<0(2), -1(3), -128(4), 1(5)>
    then replace it with effectively
-   _1 = .SPACESHIP (a_2(D), b_3(D), 1);
+   _1 = .SPACESHIP (a_2(D), b_3(D), -128);
    _27 = _1;  */
 
 static void
@@ -6218,7 +6218,7 @@ optimize_spaceship (gcond *stmt)
      than 0 as last .SPACESHIP argument to tell backends it might
      consider different code generation and just cast the result
      of .SPACESHIP to the PHI result.  X above is some value
-     other than -1, 0, 1, for libstdc++ 2, for libc++ -127.  */
+     other than -1, 0, 1, for libstdc++ -128, for libc++ -127.  */
   tree arg3 = integer_zero_node;
   edge e = EDGE_SUCC (bb0, 0);
   if (e->dest == bb1)
@@ -6245,7 +6245,8 @@ optimize_spaceship (gcond *stmt)
       && integer_zerop (gimple_phi_arg_def_from_edge (phi, e))
       && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3))
     {
-      HOST_WIDE_INT argval = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? 2 : -1;
+      HOST_WIDE_INT argval
+       = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? -128 : -1;
       for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i)
        {
          edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2;
@@ -6304,7 +6305,7 @@ optimize_spaceship (gcond *stmt)
   if (HONOR_NANS (TREE_TYPE (arg1)))
     {
       if (arg3 == integer_zero_node)
-       wmax = wi::two (TYPE_PRECISION (integer_type_node));
+       wmin = wi::shwi (-128, TYPE_PRECISION (integer_type_node));
       else if (tree_int_cst_sgn (arg3) < 0)
        wmin = wi::to_wide (arg3);
       else
diff --git a/gcc/tree-ssa-phiopt.cc b/gcc/tree-ssa-phiopt.cc
index faecab6ab7aa..73341e7219a3 100644
--- a/gcc/tree-ssa-phiopt.cc
+++ b/gcc/tree-ssa-phiopt.cc
@@ -2399,7 +2399,7 @@ minmax_replacement (basic_block cond_bb, basic_block 
middle_bb, basic_block alt_
     <bb 5> [local count: 134217728]:  // middle_bb
 
     <bb 6> [local count: 1073741824]:  // phi_bb
-    # SR.27_4 = PHI <0(2), -1(3), 1(4), 2(5)>
+    # SR.27_4 = PHI <0(2), -1(3), 1(4), -128(5)>
     _2 = SR.27_4 > 0;  */
 
 static bool
@@ -2412,8 +2412,10 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
       || TYPE_UNSIGNED (TREE_TYPE (phires))
       || !tree_fits_shwi_p (arg0)
       || !tree_fits_shwi_p (arg1)
-      || !IN_RANGE (tree_to_shwi (arg0), -1, 2)
-      || !IN_RANGE (tree_to_shwi (arg1), -1, 2))
+      || (!IN_RANGE (tree_to_shwi (arg0), -1, 1)
+         && tree_to_shwi (arg0) != -128)
+      || (!IN_RANGE (tree_to_shwi (arg1), -1, 1)
+         && tree_to_shwi (arg1) != -128))
     return false;
 
   basic_block phi_bb = gimple_bb (phi);
@@ -2431,40 +2433,48 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
   tree lhs, rhs;
   gimple *orig_use_stmt = use_stmt;
   tree orig_use_lhs = NULL_TREE;
-  int prec = TYPE_PRECISION (TREE_TYPE (phires));
-  bool is_cast = false;
+  tree temps[2] = { NULL_TREE, NULL_TREE };
 
-  /* Deal with the case when match.pd has rewritten the (res & ~1) == 0
-     into res <= 1 and has left a type-cast for signed types.  */
+  /* Handle std::partial_ordering::_M_reverse(), i.e.
+     _1 = (unsigned char) phires;
+     _2 = -_1;
+     _3 = (signed char) _2;
+     and uses of _3 in comparison instead of phires.  */
   if (gimple_assign_cast_p (use_stmt))
     {
       orig_use_lhs = gimple_assign_lhs (use_stmt);
-      /* match.pd would have only done this for a signed type,
-        so the conversion must be to an unsigned one.  */
+      temps[0] = orig_use_lhs;
       tree ty1 = TREE_TYPE (gimple_assign_rhs1 (use_stmt));
       tree ty2 = TREE_TYPE (orig_use_lhs);
 
       if (!TYPE_UNSIGNED (ty2) || !INTEGRAL_TYPE_P (ty2))
        return false;
-      if (TYPE_PRECISION (ty1) > TYPE_PRECISION (ty2))
+      if (TYPE_PRECISION (ty2) != 8 || TYPE_PRECISION (ty1) < 8)
        return false;
       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
        return false;
       if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
        return false;
 
-      is_cast = true;
-    }
-  else if (is_gimple_assign (use_stmt)
-          && gimple_assign_rhs_code (use_stmt) == BIT_AND_EXPR
-          && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST
-          && (wi::to_wide (gimple_assign_rhs2 (use_stmt))
-              == wi::shifted_mask (1, prec - 1, false, prec)))
-    {
-      /* For partial_ordering result operator>= with unspec as second
-        argument is (res & 1) == res, folded by match.pd into
-        (res & ~1) == 0.  */
+      if (!is_gimple_assign (use_stmt)
+         || gimple_assign_rhs_code (use_stmt) != NEGATE_EXPR)
+       return false;
+
       orig_use_lhs = gimple_assign_lhs (use_stmt);
+      temps[1] = orig_use_lhs;
+      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
+       return false;
+      if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
+       return false;
+
+      if (!gimple_assign_cast_p (use_stmt))
+       return false;
+
+      orig_use_lhs = gimple_assign_lhs (use_stmt);
+      tree ty3 = TREE_TYPE (orig_use_lhs);
+
+      if (!useless_type_conversion_p (ty3, ty1))
+       return false;
       if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig_use_lhs))
        return false;
       if (!single_imm_use (orig_use_lhs, &use_p, &use_stmt))
@@ -2515,51 +2525,6 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
       || !IN_RANGE (tree_to_shwi (rhs), -1, 1))
     return false;
 
-  if (is_cast)
-    {
-      if (TREE_CODE (rhs) != INTEGER_CST)
-       return false;
-      /* As for -ffast-math we assume the 2 return to be
-        impossible, canonicalize (unsigned) res <= 1U or
-        (unsigned) res < 2U into res >= 0 and (unsigned) res > 1U
-        or (unsigned) res >= 2U as res < 0.  */
-      switch (cmp)
-       {
-       case LE_EXPR:
-         if (!integer_onep (rhs))
-           return false;
-         cmp = GE_EXPR;
-         break;
-       case LT_EXPR:
-         if (wi::ne_p (wi::to_widest (rhs), 2))
-           return false;
-         cmp = GE_EXPR;
-         break;
-       case GT_EXPR:
-         if (!integer_onep (rhs))
-           return false;
-         cmp = LT_EXPR;
-         break;
-       case GE_EXPR:
-         if (wi::ne_p (wi::to_widest (rhs), 2))
-           return false;
-         cmp = LT_EXPR;
-         break;
-       default:
-         return false;
-       }
-      rhs = build_zero_cst (TREE_TYPE (phires));
-    }
-  else if (orig_use_lhs)
-    {
-      if ((cmp != EQ_EXPR && cmp != NE_EXPR) || !integer_zerop (rhs))
-       return false;
-      /* As for -ffast-math we assume the 2 return to be
-        impossible, canonicalize (res & ~1) == 0 into
-        res >= 0 and (res & ~1) != 0 as res < 0.  */
-      cmp = cmp == EQ_EXPR ? GE_EXPR : LT_EXPR;
-    }
-
   if (!empty_block_p (middle_bb))
     return false;
 
@@ -2672,12 +2637,12 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
        return false;
       if (e1->flags & EDGE_TRUE_VALUE)
        {
-         if (tree_to_shwi (arg0) != 2
+         if (tree_to_shwi (arg0) != -128
              || absu_hwi (tree_to_shwi (arg1)) != 1
              || wi::to_widest (arg1) == wi::to_widest (arg2))
            return false;
        }
-      else if (tree_to_shwi (arg1) != 2
+      else if (tree_to_shwi (arg1) != -128
               || absu_hwi (tree_to_shwi (arg0)) != 1
               || wi::to_widest (arg0) == wi::to_widest (arg2))
        return false;
@@ -2797,13 +2762,11 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
       if (integer_onep (rhs))
        res_cmp = one_cmp == LT_EXPR ? GE_EXPR : LE_EXPR;
       else if (integer_zerop (rhs))
-       {
-         if (HONOR_NANS (TREE_TYPE (lhs1)) && orig_use_lhs)
-           negate_p = true;
-         res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
-       }
+       res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
       else
        return false;
+      if (HONOR_NANS (TREE_TYPE (lhs1)))
+       negate_p = true;
       break;
     case LE_EXPR:
       if (integer_zerop (rhs))
@@ -2812,6 +2775,8 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
        res_cmp = one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR;
       else
        return false;
+      if (HONOR_NANS (TREE_TYPE (lhs1)))
+       negate_p = true;
       break;
     case GT_EXPR:
       if (integer_minus_onep (rhs))
@@ -2820,28 +2785,20 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
        res_cmp = one_cmp;
       else
        return false;
-      if (HONOR_NANS (TREE_TYPE (lhs1)))
-       negate_p = true;
       break;
     case GE_EXPR:
       if (integer_zerop (rhs))
-       {
-         if (HONOR_NANS (TREE_TYPE (lhs1)) && !orig_use_lhs)
-           negate_p = true;
-         res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
-       }
+       res_cmp = one_cmp == LT_EXPR ? LE_EXPR : GE_EXPR;
       else if (integer_onep (rhs))
-       {
-         if (HONOR_NANS (TREE_TYPE (lhs1)))
-           negate_p = true;
-         res_cmp = one_cmp;
-       }
+       res_cmp = one_cmp;
       else
        return false;
       break;
     default:
       gcc_unreachable ();
     }
+  if (orig_use_lhs)
+    res_cmp = swap_tree_comparison (res_cmp);
 
   tree clhs1 = lhs1, crhs1 = rhs1;
   if (negate_p)
@@ -2883,31 +2840,68 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
       use_operand_p use_p;
       imm_use_iterator iter;
       bool has_debug_uses = false;
-      bool has_cast_debug_uses = false;
+      bool has_cast1_debug_uses = false;
+      bool has_neg_debug_uses = false;
+      bool has_cast2_debug_uses = false;
       FOR_EACH_IMM_USE_FAST (use_p, iter, phires)
        {
          gimple *use_stmt = USE_STMT (use_p);
-         if (orig_use_lhs && use_stmt == orig_use_stmt)
-           continue;
-         gcc_assert (is_gimple_debug (use_stmt));
-         has_debug_uses = true;
-         break;
+         if (is_gimple_debug (use_stmt))
+           {
+             has_debug_uses = true;
+             break;
+           }
        }
       if (orig_use_lhs)
        {
-         if (!has_debug_uses || is_cast)
-           FOR_EACH_IMM_USE_FAST (use_p, iter, orig_use_lhs)
-             {
-               gimple *use_stmt = USE_STMT (use_p);
-               gcc_assert (is_gimple_debug (use_stmt));
-               has_debug_uses = true;
-               if (is_cast)
-                 has_cast_debug_uses = true;
-             }
-         gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt);
-         tree zero = build_zero_cst (TREE_TYPE (orig_use_lhs));
-         gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
-         update_stmt (orig_use_stmt);
+         FOR_EACH_IMM_USE_FAST (use_p, iter, temps[0])
+           {
+             gimple *use_stmt = USE_STMT (use_p);
+             if (is_gimple_debug (use_stmt))
+               {
+                 has_debug_uses = true;
+                 has_cast1_debug_uses = true;
+                 break;
+               }
+           }
+         FOR_EACH_IMM_USE_FAST (use_p, iter, temps[1])
+           {
+             gimple *use_stmt = USE_STMT (use_p);
+             if (is_gimple_debug (use_stmt))
+               {
+                 has_debug_uses = true;
+                 has_cast1_debug_uses = true;
+                 has_neg_debug_uses = true;
+                 break;
+               }
+           }
+         FOR_EACH_IMM_USE_FAST (use_p, iter, orig_use_lhs)
+           {
+             gimple *use_stmt = USE_STMT (use_p);
+             if (is_gimple_debug (use_stmt))
+               {
+                 has_debug_uses = true;
+                 has_cast1_debug_uses = true;
+                 has_neg_debug_uses = true;
+                 has_cast2_debug_uses = true;
+                 break;
+               }
+           }
+         if (has_debug_uses)
+           {
+             gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt);
+             tree zero = build_zero_cst (TREE_TYPE (temps[0]));
+             gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
+             update_stmt (orig_use_stmt);
+             gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
+             zero = build_zero_cst (TREE_TYPE (temps[1]));
+             gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
+             update_stmt (SSA_NAME_DEF_STMT (temps[1]));
+             gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
+             zero = build_zero_cst (TREE_TYPE (orig_use_lhs));
+             gimple_assign_set_rhs_with_ops (&gsi, INTEGER_CST, zero);
+             update_stmt (SSA_NAME_DEF_STMT (orig_use_lhs));
+           }
        }
 
       if (has_debug_uses)
@@ -2917,10 +2911,10 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
             # DEBUG D#2 => i_2(D) == j_3(D) ? 0 : D#1
             where > stands for the comparison that yielded 1
             and replace debug uses of phi result with that D#2.
-            Ignore the value of 2 if !HONOR_NANS, because if NaNs
+            Ignore the value of -128 if !HONOR_NANS, because if NaNs
             aren't expected, all floating point numbers should be
             comparable.  If HONOR_NANS, emit something like:
-            # DEBUG D#1 => i_2(D) < j_3(D) ? -1 : 2
+            # DEBUG D#1 => i_2(D) < j_3(D) ? -1 : -128
             # DEBUG D#2 => i_2(D) > j_3(D) ? 1 : D#1
             # DEBUG D#3 => i_2(D) == j_3(D) ? 0 : D#2
             instead.  */
@@ -2933,7 +2927,7 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
              tree t = build2 (one_cmp == LT_EXPR ? GT_EXPR : LT_EXPR,
                               boolean_type_node, lhs1, rhs2);
              t = build3 (COND_EXPR, type, t, minus_one,
-                         build_int_cst (type, 2));
+                         build_int_cst (type, -128));
              gimple *g = gimple_build_debug_bind (temp3, t, phi);
              gsi_insert_before (&gsi, g, GSI_SAME_STMT);
              minus_one = temp3;
@@ -2950,35 +2944,46 @@ spaceship_replacement (basic_block cond_bb, basic_block 
middle_bb,
          g = gimple_build_debug_bind (temp2, t, phi);
          gsi_insert_before (&gsi, g, GSI_SAME_STMT);
          replace_uses_by (phires, temp2);
-         if (orig_use_lhs)
+         if (has_cast1_debug_uses)
            {
-             if (has_cast_debug_uses
-                 || (HONOR_NANS (TREE_TYPE (lhs1)) && !is_cast))
-               {
-                 tree temp3 = make_node (DEBUG_EXPR_DECL);
-                 DECL_ARTIFICIAL (temp3) = 1;
-                 TREE_TYPE (temp3) = TREE_TYPE (orig_use_lhs);
-                 SET_DECL_MODE (temp3, TYPE_MODE (type));
-                 if (has_cast_debug_uses)
-                   t = fold_convert (TREE_TYPE (temp3), temp2);
-                 else
-                   t = build2 (BIT_AND_EXPR, TREE_TYPE (temp3),
-                               temp2, build_int_cst (TREE_TYPE (temp3),
-                                                     ~1));
-                 g = gimple_build_debug_bind (temp3, t, phi);
-                 gsi_insert_before (&gsi, g, GSI_SAME_STMT);
-                 replace_uses_by (orig_use_lhs, temp3);
-               }
-             else
-               replace_uses_by (orig_use_lhs, temp2);
+             tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[0]));
+             t = fold_convert (TREE_TYPE (temps[0]), temp2);
+             g = gimple_build_debug_bind (temp3, t, phi);
+             gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+             replace_uses_by (temps[0], temp3);
+             temp2 = temp3;
+           }
+         if (has_neg_debug_uses)
+           {
+             tree temp3 = build_debug_expr_decl (TREE_TYPE (temps[1]));
+             t = fold_build1 (NEGATE_EXPR, TREE_TYPE (temps[1]), temp2);
+             g = gimple_build_debug_bind (temp3, t, phi);
+             gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+             replace_uses_by (temps[1], temp3);
+             temp2 = temp3;
+           }
+         if (has_cast2_debug_uses)
+           {
+             tree temp3 = build_debug_expr_decl (TREE_TYPE (orig_use_lhs));
+             t = fold_convert (TREE_TYPE (orig_use_lhs), temp2);
+             g = gimple_build_debug_bind (temp3, t, phi);
+             gsi_insert_before (&gsi, g, GSI_SAME_STMT);
+             replace_uses_by (orig_use_lhs, temp3);
            }
        }
     }
 
   if (orig_use_lhs)
     {
-      gimple_stmt_iterator gsi = gsi_for_stmt (orig_use_stmt);
+      gimple_stmt_iterator gsi = gsi_for_stmt (SSA_NAME_DEF_STMT 
(orig_use_lhs));
+      gsi_remove (&gsi, true);
+      gsi = gsi_for_stmt (SSA_NAME_DEF_STMT (temps[1]));
+      gsi_remove (&gsi, true);
+      gsi = gsi_for_stmt (orig_use_stmt);
       gsi_remove (&gsi, true);
+      release_ssa_name (orig_use_lhs);
+      release_ssa_name (temps[1]);
+      release_ssa_name (temps[0]);
     }
 
   gimple_stmt_iterator psi = gsi_for_stmt (phi);

Reply via email to