> I'm okay with most of the change, but I have a question: What happened
> to the unsigned comparisons and LTGT?

Unsigned comparisons aren't used for FP (the whole block of code is dominated 
by a FLOAT_MODE_P (mode) test).  LTGT and UNEQ were wrong (but unused) since 
they were implemented as NE and EQ respectively and therefore didn't return 
the correct result for NaNs.  In fact, all the unordered operators were wrong 
(but unused) since they were implemented as their ordered counterpart.

> I'm not going to insist, but this probably deserves an e500-specific
> testcase that it's generating the correct results and not calling
> libgcc for unordered comparisons.

Note that, for originally unordered comparisons, there has always been a call 
to libgcc as rs6000_cbranch_operator is ordered_comparison_operator on e500
(hence the wrong implementation in rs6000_generate_compare was unused).  But, 
indeed, we should verify that we don't generate them when the comparisons are 
originally ordered, with and without -ftrapping-math.

I have attached 4 testcases:
 - e500-ord-1.c: ordered/signaling predicates, -ftrapping-math
 - e500-ord-2.c: ordered/signaling predicates, -fno-trapping-math
 - e500-unord-1.c: C99 unordered/quiet predicates, -ftrapping-math
 - e500-unord-2.c: C99 unordered/quiet predicates, -fno-trapping-math

With the unpatched compiler:
  - e500-ord-1.c: no calls to __unordsf2 (optimal)
  - e500-ord-2.c: calls to __unordsf2 (the very issue I'm fixing)
  - e500-unord-1.c: calls to __unordsf2 (optimal)
  - e500-unord-2.c: calls to __unordsf2 (useless since -fno-trapping-math)

With the patched compiler:
  - e500-ord-1.c: no calls to __unordsf2 (optimal)
  - e500-ord-2.c: no calls to __unordsf2 (optimal)
  - e500-unord-1.c: calls to __unordsf2 (optimal)
  - e500-unord-2.c: no calls to __unordsf2 (optimal)


2013-05-31  Eric Botcazou  <ebotca...@adacore.com>

        * gcc.target/powerpc/e500-ord-1.c: New test.
        * gcc.target/powerpc/e500-ord-2.c: Likewise.
        * gcc.target/powerpc/e500-unord-1.c: Likewise.
        * gcc.target/powerpc/e500-unord-2.c: Likewise.


-- 
Eric Botcazou
/* { dg-do compile { target powerpc*-*-eabi* } } */
/* { dg-options "-O -ftrapping-math -fdump-rtl-final" } */

int isgreater (float f1, float f2)
{
  int r = (f1 > f2);
  return !r ?  -1 : 1;
}

int isgreaterequal (float f1, float f2)
{
  int r = (f1 >= f2);
  return !r ?  -1 : 1;
}

int isless (float f1, float f2)
{
  int r = (f1 < f2);
  return !r ?  -1 : 1;
}

int islessequal (float f1, float f2)
{
  int r = (f1 <= f2);
  return !r ?  -1 : 1;
}

/* { dg-final { scan-rtl-dump-not "__unordsf2" "final" } } */
/* { dg-final { cleanup-rtl-dump "final" } } */
/* { dg-do compile { target powerpc*-*-eabi* } } */
/* { dg-options "-O -fno-trapping-math -fdump-rtl-final" } */

int isgreater (float f1, float f2)
{
  int r = (f1 > f2);
  return !r ?  -1 : 1;
}

int isgreaterequal (float f1, float f2)
{
  int r = (f1 >= f2);
  return !r ?  -1 : 1;
}

int isless (float f1, float f2)
{
  int r = (f1 < f2);
  return !r ?  -1 : 1;
}

int islessequal (float f1, float f2)
{
  int r = (f1 <= f2);
  return !r ?  -1 : 1;
}

/* { dg-final { scan-rtl-dump-not "__unordsf2" "final" } } */
/* { dg-final { cleanup-rtl-dump "final" } } */
/* { dg-do compile { target powerpc*-*-eabi* } } */
/* { dg-options "-O -ftrapping-math -fdump-rtl-final" } */

int isgreater (float f1, float f2)
{
  int r = __builtin_isgreater (f1, f2);
  return !r ?  -1 : 1;
}

int isgreaterequal (float f1, float f2)
{
  int r = __builtin_isgreaterequal (f1, f2);
  return !r ?  -1 : 1;
}

int isless (float f1, float f2)
{
  int r = __builtin_isless (f1, f2);
  return !r ?  -1 : 1;
}

int islessequal (float f1, float f2)
{
  int r = __builtin_islessequal (f1, f2);
  return !r ?  -1 : 1;
}

/* { dg-final { scan-rtl-dump-times "__unordsf2" 4 "final" } } */
/* { dg-final { cleanup-rtl-dump "final" } } */
/* { dg-do compile { target powerpc*-*-eabi* } } */
/* { dg-options "-O -fno-trapping-math -fdump-rtl-final" } */

int isgreater (float f1, float f2)
{
  int r = __builtin_isgreater (f1, f2);
  return !r ?  -1 : 1;
}

int isgreaterequal (float f1, float f2)
{
  int r = __builtin_isgreaterequal (f1, f2);
  return !r ?  -1 : 1;
}

int isless (float f1, float f2)
{
  int r = __builtin_isless (f1, f2);
  return !r ?  -1 : 1;
}

int islessequal (float f1, float f2)
{
  int r = __builtin_islessequal (f1, f2);
  return !r ?  -1 : 1;
}

/* { dg-final { scan-rtl-dump-not "__unordsf2" "final" } } */
/* { dg-final { cleanup-rtl-dump "final" } } */

Reply via email to