Commit 6597fd0b by Paolo Bonzini Committed by Paolo Bonzini

re PR target/43610 (ICE: in prepare_float_lib_cmp, at optabs.c:4392 with…

re PR target/43610 (ICE: in prepare_float_lib_cmp, at optabs.c:4392 with -fno-trapping-math and _Decimal64 comparison)

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.

From-SVN: r159813
parent 8524ba70
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> 2010-05-25 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (loc_descr_plus_const): When offset is negative, use * dwarf2out.c (loc_descr_plus_const): When offset is negative, use
......
...@@ -4331,6 +4331,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison, ...@@ -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 rtx_code reversed = reverse_condition_maybe_unordered (comparison);
enum machine_mode orig_mode = GET_MODE (x); enum machine_mode orig_mode = GET_MODE (x);
enum machine_mode mode, cmp_mode; enum machine_mode mode, cmp_mode;
rtx true_rtx, false_rtx;
rtx value, target, insns, equiv; rtx value, target, insns, equiv;
rtx libfunc = 0; rtx libfunc = 0;
bool reversed_p = false; bool reversed_p = false;
...@@ -4354,8 +4355,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison, ...@@ -4354,8 +4355,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
} }
if (code_to_optab[reversed] if (code_to_optab[reversed]
&& (libfunc = optab_libfunc (code_to_optab[reversed], mode)) && (libfunc = optab_libfunc (code_to_optab[reversed], mode)))
&& FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, reversed))
{ {
comparison = reversed; comparison = reversed;
reversed_p = true; reversed_p = true;
...@@ -4374,6 +4374,51 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison, ...@@ -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 /* 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 the RTL. The allows the RTL optimizers to delete the libcall if the
condition can be determined at compile-time. */ 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) if (comparison == UNORDERED)
{ {
rtx temp = simplify_gen_relational (NE, cmp_mode, mode, x, x); 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, ...@@ -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); equiv = simplify_gen_relational (comparison, cmp_mode, mode, x, y);
if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)) if (! FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison))
{ equiv = simplify_gen_ternary (IF_THEN_ELSE, cmp_mode, cmp_mode,
rtx true_rtx, false_rtx; equiv, 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);
}
} }
start_sequence (); start_sequence ();
...@@ -4438,10 +4444,12 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison, ...@@ -4438,10 +4444,12 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
emit_libcall_block (insns, target, value, equiv); emit_libcall_block (insns, target, value, equiv);
if (comparison == UNORDERED if (comparison == UNORDERED
|| FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)) || FLOAT_LIB_COMPARE_RETURNS_BOOL (mode, comparison)
comparison = reversed_p ? EQ : NE; || 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; *pmode = cmp_mode;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment