This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[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);
+ }