From: David Miller <da...@davemloft.net>
Date: Wed, 02 Nov 2011 16:17:33 -0400 (EDT)

> From: Eric Botcazou <ebotca...@adacore.com>
> Date: Wed, 2 Nov 2011 13:29:45 +0100
> 
>> This has reintroduced PR target/49965.
> 
> I am working on fixing this right now, thanks for reporting Eric.

This took longer than expected to fix :-)

There are several issues that have to be considered when we emit
that TFmode libcall for a conditional move.

As you mentioned, we have to not cache any components of operands[1]
across that libcall emission.

But also, the logic used to make operands[3] == operands[0] for the
movcc (and handle cases where there is overlap with the comparison's
arguments) has to be mindful of the libcall's rewritten operands[1]
too.

The easiest way to handle this is to simply emit the TFmode libcall
before we do any of the operand switching.

Regstrapped on sparc-*-linux-gnu and committed to trunk.

--------------------
[PATCH] Fix sparc regression due to recent movcc pattern changes.

        PR target/49965
        * config/sparc/sparc.c (sparc_expand_conditional_move): Handle the
        fact that sparc_emit_float_lib_cmp modifies the comparison in
        operands[1].
---
 gcc/ChangeLog            |    7 +++++++
 gcc/config/sparc/sparc.c |   13 +++++++------
 2 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 622100e..96b9100 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-03  David S. Miller  <da...@davemloft.net>
+
+       PR target/49965
+       * config/sparc/sparc.c (sparc_expand_conditional_move): Handle the
+       fact that sparc_emit_float_lib_cmp modifies the comparison in
+       operands[1].
+
 2011-11-03  Uros Bizjak  <ubiz...@gmail.com>
 
        * sched-vis.c (print_value): Handle STRICT_LOW_PART.
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index b57a158..0daa53d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -11509,12 +11509,16 @@ sparc_expand_conditional_move (enum machine_mode 
mode, rtx *operands)
   rtx cc_reg, dst, cmp;
 
   cmp = operands[1];
-  cmp_mode = GET_MODE (XEXP (cmp, 0));
-  if (cmp_mode == DImode && !TARGET_ARCH64)
+  if (GET_MODE (XEXP (cmp, 0)) == DImode && !TARGET_ARCH64)
     return false;
 
-  dst = operands[0];
+  if (GET_MODE (XEXP (cmp, 0)) == TFmode && !TARGET_HARD_QUAD)
+    cmp = sparc_emit_float_lib_cmp (XEXP (cmp, 0), XEXP (cmp, 1), rc);
+
+  cmp_mode = GET_MODE (XEXP (cmp, 0));
+  rc = GET_CODE (cmp);
 
+  dst = operands[0];
   if (! rtx_equal_p (operands[2], dst)
       && ! rtx_equal_p (operands[3], dst))
     {
@@ -11533,9 +11537,6 @@ sparc_expand_conditional_move (enum machine_mode mode, 
rtx *operands)
         rc = reverse_condition (rc);
     }
 
-  if (cmp_mode == TFmode && !TARGET_HARD_QUAD)
-    cmp = sparc_emit_float_lib_cmp (XEXP (cmp, 0), XEXP (cmp, 1), rc);
-
   if (XEXP (cmp, 1) == const0_rtx
       && GET_CODE (XEXP (cmp, 0)) == REG
       && cmp_mode == DImode
-- 
1.7.6.401.g6a319

Reply via email to