Hello,

the pr50310 test cases are failing on SPU with internal compiler errors.
It seems that if the back-end provides a vcond pattern, it must support
all comparison operations, including unordered ones which are missing
in the SPU implementation.

Since we don't actually have any specific instruction support for those
operations on SPU, the following patch open-codes their semantics.

Tested on spu-elf, fixes the pr50310 test cases.
Committed to mainline.

Bye,
Ulrich


ChangeLog:

        PR target/50310
        * config/spu/spu.c (spu_emit_vector_compare): Support unordered
        floating-point comparisons.


Index: gcc/config/spu/spu.c
===================================================================
*** gcc/config/spu/spu.c        (revision 180156)
--- gcc/config/spu/spu.c        (working copy)
*************** spu_emit_vector_compare (enum rtx_code r
*** 6415,6427 ****
            try_again = true;
            break;
          case NE:
            /* Treat A != B as ~(A==B).  */
            {
              enum insn_code nor_code;
!             rtx eq_rtx = spu_emit_vector_compare (EQ, op0, op1, dest_mode);
              nor_code = optab_handler (one_cmpl_optab, dest_mode);
              gcc_assert (nor_code != CODE_FOR_nothing);
!             emit_insn (GEN_FCN (nor_code) (mask, eq_rtx));
              if (dmode != dest_mode)
                {
                  rtx temp = gen_reg_rtx (dest_mode);
--- 6415,6438 ----
            try_again = true;
            break;
          case NE:
+       case UNEQ:
+       case UNLE:
+       case UNLT:
+       case UNGE:
+       case UNGT:
+       case UNORDERED:
            /* Treat A != B as ~(A==B).  */
            {
+           enum rtx_code rev_code;
              enum insn_code nor_code;
!           rtx rev_mask;
! 
!           rev_code = reverse_condition_maybe_unordered (rcode);
!             rev_mask = spu_emit_vector_compare (rev_code, op0, op1, 
dest_mode);
! 
              nor_code = optab_handler (one_cmpl_optab, dest_mode);
              gcc_assert (nor_code != CODE_FOR_nothing);
!             emit_insn (GEN_FCN (nor_code) (mask, rev_mask));
              if (dmode != dest_mode)
                {
                  rtx temp = gen_reg_rtx (dest_mode);
*************** spu_emit_vector_compare (enum rtx_code r
*** 6466,6471 ****
--- 6477,6524 ----
              return mask;
            }
            break;
+         case LTGT:
+           /* Try LT OR GT */
+           {
+             rtx lt_rtx, gt_rtx;
+             enum insn_code ior_code;
+ 
+             lt_rtx = spu_emit_vector_compare (LT, op0, op1, dest_mode);
+             gt_rtx = spu_emit_vector_compare (GT, op0, op1, dest_mode);
+ 
+             ior_code = optab_handler (ior_optab, dest_mode);
+             gcc_assert (ior_code != CODE_FOR_nothing);
+             emit_insn (GEN_FCN (ior_code) (mask, lt_rtx, gt_rtx));
+             if (dmode != dest_mode)
+               {
+                 rtx temp = gen_reg_rtx (dest_mode);
+                 convert_move (temp, mask, 0);
+                 return temp;
+               }
+             return mask;
+           }
+           break;
+         case ORDERED:
+           /* Implement as (A==A) & (B==B) */
+           {
+             rtx a_rtx, b_rtx;
+             enum insn_code and_code;
+ 
+             a_rtx = spu_emit_vector_compare (EQ, op0, op0, dest_mode);
+             b_rtx = spu_emit_vector_compare (EQ, op1, op1, dest_mode);
+ 
+             and_code = optab_handler (and_optab, dest_mode);
+             gcc_assert (and_code != CODE_FOR_nothing);
+             emit_insn (GEN_FCN (and_code) (mask, a_rtx, b_rtx));
+             if (dmode != dest_mode)
+               {
+                 rtx temp = gen_reg_rtx (dest_mode);
+                 convert_move (temp, mask, 0);
+                 return temp;
+               }
+             return mask;
+           }
+           break;
          default:
            gcc_unreachable ();
          }
-- 
  Dr. Ulrich Weigand
  GNU Toolchain for Linux on System z and Cell BE
  ulrich.weig...@de.ibm.com

Reply via email to