diff options
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/optabs.c | 100 |
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; } |