aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/optabs.c100
2 files changed, 62 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7f1d29a..28c74e2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2010-05-09 Paolo Bonzini <bonzini@gnu.org>
+
+ PR target/43610
+ * optabs.c (prepare_float_lib_cmp): Allow reversing the comparison
+ even if !FLOAT_LIB_COMPARE_RETURNS_BOOL. Always compute true_rtx and
+ false_rtx. Use false_rtx to compute the correct *ptest for reversed
+ comparisons for which !FLOAT_LIB_COMPARE_RETURNS_BOOL.
+
2010-05-25 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (loc_descr_plus_const): When offset is negative, use
diff --git a/gcc/optabs.c b/gcc/optabs.c
index a36075d..3c5424d 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4331,6 +4331,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
enum rtx_code reversed = reverse_condition_maybe_unordered (comparison);
enum machine_mode orig_mode = GET_MODE (x);
enum machine_mode mode, cmp_mode;
+ rtx true_rtx, false_rtx;
rtx value, target, insns, equiv;
rtx libfunc = 0;
bool reversed_p = false;
@@ -4354,8 +4355,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
}
if (code_to_optab[reversed]
- && (libfunc = optab_libfunc (code_to_optab[reversed], mode))
- && FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
+ && (libfunc = optab_libfunc (code_to_optab[reversed], mode)))
{
comparison = reversed;
reversed_p = true;
@@ -4374,6 +4374,51 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
/* Attach a REG_EQUAL note describing the semantics of the libcall to
the RTL. The allows the RTL optimizers to delete the libcall if the
condition can be determined at compile-time. */
+ if (comparison == UNORDERED
+ || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
+ {
+ true_rtx = const_true_rtx;
+ false_rtx = const0_rtx;
+ }
+ else
+ {
+ switch (comparison)
+ {
+ case EQ:
+ true_rtx = const0_rtx;
+ false_rtx = const_true_rtx;
+ break;
+
+ case NE:
+ true_rtx = const_true_rtx;
+ false_rtx = const0_rtx;
+ break;
+
+ case GT:
+ true_rtx = const1_rtx;
+ false_rtx = const0_rtx;
+ break;
+
+ case GE:
+ true_rtx = const0_rtx;
+ false_rtx = constm1_rtx;
+ break;
+
+ case LT:
+ true_rtx = constm1_rtx;
+ false_rtx = const0_rtx;
+ break;
+
+ case LE:
+ true_rtx = const0_rtx;
+ false_rtx = const1_rtx;
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+
if (comparison == UNORDERED)
{
rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x);
@@ -4385,47 +4430,8 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
{
equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
- {
- rtx true_rtx, false_rtx;
-
- switch (comparison)
- {
- case EQ:
- true_rtx = const0_rtx;
- false_rtx = const_true_rtx;
- break;
-
- case NE:
- true_rtx = const_true_rtx;
- false_rtx = const0_rtx;
- break;
-
- case GT:
- true_rtx = const1_rtx;
- false_rtx = const0_rtx;
- break;
-
- case GE:
- true_rtx = const0_rtx;
- false_rtx = constm1_rtx;
- break;
-
- case LT:
- true_rtx = constm1_rtx;
- false_rtx = const0_rtx;
- break;
-
- case LE:
- true_rtx = const0_rtx;
- false_rtx = const1_rtx;
- break;
-
- default:
- gcc_unreachable ();
- }
- equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
- equiv, true_rtx, false_rtx);
- }
+ equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
+ equiv, true_rtx, false_rtx);
}
start_sequence ();
@@ -4438,10 +4444,12 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
emit_libcall_block (insns, target, value, equiv);
if (comparison == UNORDERED
- || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
- comparison = reversed_p ? EQ : NE;
+ || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
+ || reversed_p)
+ *ptest = gen_rtx_fmt_ee (reversed_p ? EQ : NE, VOIDmode, target, false_rtx);
+ else
+ *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
- *ptest = gen_rtx_fmt_ee (comparison, VOIDmode, target, const0_rtx);
*pmode = cmp_mode;
}