This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Fix __builtin_mips_mov*_c_*_ps


[ I'm going to use this thread to post follow-up patches to the
  MIPS PS/3D work.  The cc: line is quite long though, so if you've
  been trapped and want out, please let me know privately. ]

I noticed when the final RFA patch was posted that the move_tf_ps
pattern was wrong:

     (define_insn "mips_cond_move_tf_ps"
       [(set (match_operand:V2SF 0 "register_operand" "=f,f")
             (if_then_else:V2SF
              (eq:CCV2 (match_operand:CCV2 3 "register_operand" "z,z")
                       (const_int 0))
              (match_operand:V2SF 1 "register_operand" "f,0")
              (match_operand:V2SF 2 "register_operand" "0,f")))]
       "TARGET_PAIRED_SINGLE_FLOAT"
       "@
         movt.ps\t%0,%1,%y3
         movf.ps\t%0,%2,%y3"
       [(set_attr "type" "condmove")
        (set_attr "mode" "SF")])

This pattern says that operand 0 will be set to _either_ operand 1
_or_ operand 2, but that's not mov*.ps actually does; it selects
between the two input operands on an element-by-element basis.
This shows up as a failure in the attached testcase, where:

    v2sf __attribute__((noinline))
    foo (v2sf x, v2sf y)
    {
      if (__builtin_mips_any_c_lt_ps (x, y))
        x = __builtin_mips_movt_c_lt_ps (x, y, x, y);
      return x;
    }

gets "optimised" as:

        c.lt.ps $f12,$f13
        bc1any2t $fcc0,$L2
        mov.ps  $f0,$f12

        j       $31
        nop

        .align  3
$L2:
        j       $31
        mov.ps  $f0,$f13        # <------------

The patch below fixes it by using an UNSPEC instead.  Tested by
comparing the mipsisa64-elf output of MIPS's testsuite before and
after the patch.  There were no changes.

config/mips patch applied to mainline.  I'll hold off applying the
testcase until I know where it's supposed to go.

Richard


	* config/mips/mips.md (UNSPEC_MOVE_TF_PS): New.
	* config/mips/mips-ps-3d.md (mips_cond_move_tf_ps): Express as an
	UNSPEC rather than an IF_THEN_ELSE.
	* config/mips/mips.c (mips_expand_ps_cond_move_builtin): Emit
	mips_cond_move_tf_ps by name.

Index: config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.md,v
retrieving revision 1.291
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.291 mips.md
*** config/mips/mips.md	29 Aug 2004 09:19:34 -0000	1.291
--- config/mips/mips.md	29 Aug 2004 09:46:05 -0000
*************** (define_constants
*** 110,115 ****
--- 110,116 ----
     (UNSPEC_RSQRT2_D		248)
     (UNSPEC_RSQRT2_PS		249)
  
+    (UNSPEC_MOVE_TF_PS		250)
    ]
  )
  
Index: config/mips/mips-ps-3d.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips-ps-3d.md,v
retrieving revision 1.1
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.1 mips-ps-3d.md
*** config/mips/mips-ps-3d.md	29 Aug 2004 09:19:32 -0000	1.1
--- config/mips/mips-ps-3d.md	29 Aug 2004 09:46:07 -0000
*************** (define_insn "*movcc_v2sf_si"
*** 50,59 ****
  
  (define_insn "mips_cond_move_tf_ps"
    [(set (match_operand:V2SF 0 "register_operand" "=f,f")
! 	(if_then_else:V2SF
! 	 (eq:CCV2 (match_operand:CCV2 3 "register_operand" "z,z") (const_int 0))
! 	 (match_operand:V2SF 1 "register_operand" "f,0")
! 	 (match_operand:V2SF 2 "register_operand" "0,f")))]
    "TARGET_PAIRED_SINGLE_FLOAT"
    "@
      movt.ps\t%0,%1,%y3
--- 50,59 ----
  
  (define_insn "mips_cond_move_tf_ps"
    [(set (match_operand:V2SF 0 "register_operand" "=f,f")
! 	(unspec:V2SF [(match_operand:V2SF 1 "register_operand" "f,0")
! 		      (match_operand:V2SF 2 "register_operand" "0,f")
! 		      (match_operand:CCV2 3 "register_operand" "z,z")]
! 		     UNSPEC_MOVE_TF_PS))]
    "TARGET_PAIRED_SINGLE_FLOAT"
    "@
      movt.ps\t%0,%1,%y3
Index: config/mips/mips.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/mips.c,v
retrieving revision 1.457
diff -c -p -F^\([(a-zA-Z0-9_]\|#define\) -r1.457 mips.c
*** config/mips/mips.c	29 Aug 2004 09:19:32 -0000	1.457
--- config/mips/mips.c	29 Aug 2004 09:46:18 -0000
*************** mips_expand_ps_cond_move_builtin (enum m
*** 10688,10694 ****
    enum machine_mode mode0;
    enum machine_mode mode1;
    rtx temp_target;
!   rtx if_then_else;
    enum rtx_code test_code;
    int compare_value;
  
--- 10688,10695 ----
    enum machine_mode mode0;
    enum machine_mode mode1;
    rtx temp_target;
!   rtx src1;
!   rtx src2;
    enum rtx_code test_code;
    int compare_value;
  
*************** mips_expand_ps_cond_move_builtin (enum m
*** 10745,10772 ****
    switch (cmp_choice)
      {
      case MIPS_CMP_MOVT:
!       if_then_else 
! 	= gen_rtx_IF_THEN_ELSE (tmode,
! 				gen_rtx_fmt_ee (test_code, CCV2mode, 
! 						temp_target,
! 					        GEN_INT (compare_value)),
! 				op3, target);
        break;
  
      case MIPS_CMP_MOVF:
!       if_then_else 
! 	= gen_rtx_IF_THEN_ELSE (tmode,
! 				gen_rtx_fmt_ee (test_code, CCV2mode, 
! 						temp_target,
! 					        GEN_INT (compare_value)), 
! 				target, op3);
        break;
  
      default:
        return 0;
      }
  
!   emit_insn (gen_rtx_SET (VOIDmode, target, if_then_else)); 
  
    return target;
  }
--- 10746,10765 ----
    switch (cmp_choice)
      {
      case MIPS_CMP_MOVT:
!       src1 = op3;
!       src2 = target;
        break;
  
      case MIPS_CMP_MOVF:
!       src1 = target;
!       src2 = op3;
        break;
  
      default:
        return 0;
      }
  
!   emit_insn (gen_mips_cond_move_tf_ps (target, src1, src2, temp_target));
  
    return target;
  }
*** /dev/null	Fri Apr 23 00:21:55 2004
--- testsuite/gcc.dg/mips-3d-10.c	Sun Aug 29 10:40:24 2004
***************
*** 0 ****
--- 1,26 ----
+ /* { dg-do run { target mips*-*-* } } */
+ /* { dg-options "-mips64 -O2 -mips3d -mhard-float -mfp64" } */
+ 
+ void abort (void);
+ void exit (int);
+ 
+ typedef float v2sf __attribute__ ((vector_size (8)));
+ 
+ static const v2sf a = { 1, 2 };
+ static const v2sf b = { 2, 1 };
+ static const v2sf c = { 2, 2 };
+ 
+ v2sf __attribute__((noinline))
+ foo (v2sf x, v2sf y)
+ {
+   if (__builtin_mips_any_c_lt_ps (x, y))
+     x = __builtin_mips_movt_c_lt_ps (x, y, x, y);
+   return x;
+ }
+ 
+ int main()
+ {
+   if (!__builtin_mips_all_c_eq_ps (foo (a, b), c))
+     abort ();
+   exit (0);
+ }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]