Patchwork [alpha] : Fix ICE in alpha_emit_conditional_move, at config/alpha/alpha.c:2649

login
register
mail settings
Submitter Uros Bizjak
Date May 11, 2012, 12:40 p.m.
Message ID <CAFULd4ahkAPV+mjax2s_LwNmzzLpnF=UOO4LD3Lg3Xe_oSBmoA@mail.gmail.com>
Download mbox | patch
Permalink /patch/158509/
State New
Headers show

Comments

Uros Bizjak - May 11, 2012, 12:40 p.m.
On Fri, May 11, 2012 at 1:54 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> Hello!
>
> Recently testsuite/gcc.c-torture/execute/ieee/pr50310.c started to ICE
> when compiled with -O3 -mieee on alphaev68-pc-linux-gnu:
>
> $ ~/gcc-build-alpha/gcc/cc1 -O3 -mieee -quiet pr50310.c
> pr50310.c: In function ‘foo’:
> pr50310.c:31:20: internal compiler error: in
> alpha_emit_conditional_move, at config/alpha/alpha.c:2649
>     s3[10 * 4 + i] = __builtin_isunordered (s1[i], s2[i]) ? -1.0 : 0.0;
>                    ^
> Please submit a full bug report,
> with preprocessed source if appropriate.
> See <http://gcc.gnu.org/bugs.html> for instructions.
>
> It turned out that UNORDERED and ORDERED RTX codes are not handled in
> alpha_emit_conditional_move. Attached patch fixes this oversight.
>
> 2012-05-11  Uros Bizjak  <ubizjak@gmail.com>
>
>        * config/alpha/alpha.c (alpha_emit_conditional_branch): Handle
>        ORDERED and UNORDERED conditions.
>
> Patch was bootstrapped and regression tested on
> alphaev68-pc-linux-gnu.  OK for mainline SVN and release branches?

Oops, wrong patch was attached. Attached is the correct one.

Uros.
Richard Henderson - May 11, 2012, 2:31 p.m.
On 05/11/2012 05:40 AM, Uros Bizjak wrote:
>>  2012-05-11  Uros Bizjak<ubizjak@gmail.com>
>>
>>          * config/alpha/alpha.c (alpha_emit_conditional_branch): Handle
>>          ORDERED and UNORDERED conditions.

Ok.


r~

Patch

Index: config/alpha/alpha.c
===================================================================
--- config/alpha/alpha.c	(revision 187394)
+++ config/alpha/alpha.c	(working copy)
@@ -2335,7 +2335,7 @@  alpha_emit_conditional_branch (rtx operands[], enu
     {
     case EQ:  case LE:  case LT:  case LEU:  case LTU:
     case UNORDERED:
-      /* We have these compares: */
+      /* We have these compares.  */
       cmp_code = code, branch_code = NE;
       break;
 
@@ -2572,13 +2572,15 @@  alpha_emit_conditional_move (rtx cmp, enum machine
       switch (code)
 	{
 	case EQ: case LE: case LT: case LEU: case LTU:
+	case UNORDERED:
 	  /* We have these compares.  */
 	  cmp_code = code, code = NE;
 	  break;
 
 	case NE:
-	  /* This must be reversed.  */
-	  cmp_code = EQ, code = EQ;
+	case ORDERED:
+	  /* These must be reversed.  */
+	  cmp_code = reverse_condition (code), code = EQ;
 	  break;
 
 	case GE: case GT: case GEU: case GTU:
@@ -2598,6 +2600,14 @@  alpha_emit_conditional_move (rtx cmp, enum machine
 	  gcc_unreachable ();
 	}
 
+      if (cmp_mode == DImode)
+	{
+	  if (!reg_or_0_operand (op0, DImode))
+	    op0 = force_reg (DImode, op0);
+	  if (!reg_or_8bit_operand (op1, DImode))
+	    op1 = force_reg (DImode, op1);
+	}
+
       tem = gen_reg_rtx (cmp_mode);
       emit_insn (gen_rtx_SET (VOIDmode, tem,
 			      gen_rtx_fmt_ee (cmp_code, cmp_mode,
@@ -2609,6 +2619,14 @@  alpha_emit_conditional_move (rtx cmp, enum machine
       local_fast_math = 1;
     }
 
+  if (cmp_mode == DImode)
+    {
+      if (!reg_or_0_operand (op0, DImode))
+	op0 = force_reg (DImode, op0);
+      if (!reg_or_8bit_operand (op1, DImode))
+	op1 = force_reg (DImode, op1);
+    }
+
   /* We may be able to use a conditional move directly.
      This avoids emitting spurious compares.  */
   if (signed_comparison_operator (cmp, VOIDmode)
@@ -2627,11 +2645,13 @@  alpha_emit_conditional_move (rtx cmp, enum machine
   switch (code)
     {
     case EQ:  case LE:  case LT:  case LEU:  case LTU:
+    case UNORDERED:
       /* We have these compares: */
       break;
 
     case NE:
-      /* This must be reversed.  */
+    case ORDERED:
+      /* These must be reversed.  */
       code = reverse_condition (code);
       cmov_code = EQ;
       break;