predicates.md (rs6000_cbranch_operator): Accept some unordered comparison operators when...
* config/rs6000/predicates.md (rs6000_cbranch_operator): Accept some unordered comparison operators when -fno-trapping-math is in effect on the e500. * config/rs6000/rs6000.c (rs6000_generate_compare): Remove dead code and implement unordered comparison operators properly on the e500. From-SVN: r199557
This commit is contained in:
parent
a8c50132e9
commit
4172215d0a
@ -1,3 +1,11 @@
|
||||
2013-05-31 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* config/rs6000/predicates.md (rs6000_cbranch_operator): Accept some
|
||||
unordered comparison operators when -fno-trapping-math is in effect
|
||||
on the e500.
|
||||
* config/rs6000/rs6000.c (rs6000_generate_compare): Remove dead code
|
||||
and implement unordered comparison operators properly on the e500.
|
||||
|
||||
2013-05-31 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* simplify-rtx.c (simplify_byte_swapping_operation): Use proper macro
|
||||
|
@ -1121,9 +1121,16 @@
|
||||
GET_MODE (XEXP (op, 0))),
|
||||
1"))))
|
||||
|
||||
;; Return 1 if OP is a valid comparison operator for "cbranch" instructions.
|
||||
;; If we're assuming that FP operations cannot generate user-visible traps,
|
||||
;; then on e500 we can use the ordered-signaling instructions to implement
|
||||
;; the unordered-quiet FP comparison predicates modulo a reversal.
|
||||
(define_predicate "rs6000_cbranch_operator"
|
||||
(if_then_else (match_test "TARGET_HARD_FLOAT && !TARGET_FPRS")
|
||||
(match_operand 0 "ordered_comparison_operator")
|
||||
(if_then_else (match_test "flag_trapping_math")
|
||||
(match_operand 0 "ordered_comparison_operator")
|
||||
(ior (match_operand 0 "ordered_comparison_operator")
|
||||
(match_code ("unlt,unle,ungt,unge"))))
|
||||
(match_operand 0 "comparison_operator")))
|
||||
|
||||
;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
|
||||
|
@ -16087,16 +16087,41 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
|
||||
{
|
||||
rtx cmp, or_result, compare_result2;
|
||||
enum machine_mode op_mode = GET_MODE (op0);
|
||||
bool reverse_p;
|
||||
|
||||
if (op_mode == VOIDmode)
|
||||
op_mode = GET_MODE (op1);
|
||||
|
||||
/* First reverse the condition codes that aren't directly supported. */
|
||||
switch (code)
|
||||
{
|
||||
case NE:
|
||||
case UNLT:
|
||||
case UNLE:
|
||||
case UNGT:
|
||||
case UNGE:
|
||||
code = reverse_condition_maybe_unordered (code);
|
||||
reverse_p = true;
|
||||
break;
|
||||
|
||||
case EQ:
|
||||
case LT:
|
||||
case LE:
|
||||
case GT:
|
||||
case GE:
|
||||
reverse_p = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* The E500 FP compare instructions toggle the GT bit (CR bit 1) only.
|
||||
This explains the following mess. */
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case EQ: case UNEQ: case NE: case LTGT:
|
||||
case EQ:
|
||||
switch (op_mode)
|
||||
{
|
||||
case SFmode:
|
||||
@ -16122,7 +16147,8 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
|
||||
}
|
||||
break;
|
||||
|
||||
case GT: case GTU: case UNGT: case UNGE: case GE: case GEU:
|
||||
case GT:
|
||||
case GE:
|
||||
switch (op_mode)
|
||||
{
|
||||
case SFmode:
|
||||
@ -16148,7 +16174,8 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
|
||||
}
|
||||
break;
|
||||
|
||||
case LT: case LTU: case UNLT: case UNLE: case LE: case LEU:
|
||||
case LT:
|
||||
case LE:
|
||||
switch (op_mode)
|
||||
{
|
||||
case SFmode:
|
||||
@ -16173,24 +16200,16 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
|
||||
gcc_unreachable ();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
/* Synthesize LE and GE from LT/GT || EQ. */
|
||||
if (code == LE || code == GE || code == LEU || code == GEU)
|
||||
if (code == LE || code == GE)
|
||||
{
|
||||
emit_insn (cmp);
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case LE: code = LT; break;
|
||||
case GE: code = GT; break;
|
||||
case LEU: code = LT; break;
|
||||
case GEU: code = GT; break;
|
||||
default: gcc_unreachable ();
|
||||
}
|
||||
|
||||
compare_result2 = gen_reg_rtx (CCFPmode);
|
||||
|
||||
/* Do the EQ. */
|
||||
@ -16217,23 +16236,18 @@ rs6000_generate_compare (rtx cmp, enum machine_mode mode)
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
emit_insn (cmp);
|
||||
|
||||
/* OR them together. */
|
||||
or_result = gen_reg_rtx (CCFPmode);
|
||||
cmp = gen_e500_cr_ior_compare (or_result, compare_result,
|
||||
compare_result2);
|
||||
compare_result2);
|
||||
compare_result = or_result;
|
||||
code = EQ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (code == NE || code == LTGT)
|
||||
code = NE;
|
||||
else
|
||||
code = EQ;
|
||||
}
|
||||
|
||||
code = reverse_p ? NE : EQ;
|
||||
|
||||
emit_insn (cmp);
|
||||
}
|
||||
else
|
||||
|
@ -1,3 +1,10 @@
|
||||
2013-05-31 Eric Botcazou <ebotcazou@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.
|
||||
|
||||
2013-05-31 Marcus Shawcroft <marcus.shawcroft@arm.com>
|
||||
|
||||
* g++.dg/torture/pr54684.C: Add -fno-short-enums.
|
||||
|
29
gcc/testsuite/gcc.target/powerpc/e500-ord-1.c
Normal file
29
gcc/testsuite/gcc.target/powerpc/e500-ord-1.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* { 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" } } */
|
29
gcc/testsuite/gcc.target/powerpc/e500-ord-2.c
Normal file
29
gcc/testsuite/gcc.target/powerpc/e500-ord-2.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* { 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" } } */
|
29
gcc/testsuite/gcc.target/powerpc/e500-unord-1.c
Normal file
29
gcc/testsuite/gcc.target/powerpc/e500-unord-1.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* { 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" } } */
|
29
gcc/testsuite/gcc.target/powerpc/e500-unord-2.c
Normal file
29
gcc/testsuite/gcc.target/powerpc/e500-unord-2.c
Normal file
@ -0,0 +1,29 @@
|
||||
/* { 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" } } */
|
Loading…
Reference in New Issue
Block a user