This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix for SSE conditional move patterns
- To: rth at cygnus dot com, gcc-patches at gcc dot gnu dot org, patches at x86-64 dot org
- Subject: Fix for SSE conditional move patterns
- From: Jan Hubicka <jh at suse dot cz>
- Date: Wed, 14 Mar 2001 14:40:27 +0100
Hi
This has turned out to be quite unfortunate thinko in my previous patch.
I've assumed I can convert all SSE conditionals to i387 conditionals just
by swapping operands, but this is not true for EQ/NE pair (i387 supports
just UNEQ/UNNE).
The patch handles this by adding separate patch that canonicalizes each
EQ/NE to NE conditional move and then split it to i387 conditional moves
if needed.
Honza
Tue Mar 13 15:29:16 CET 2001 Jan Hubicka <jh@suse.cz>
* i386.c (ix86_expand_fp_movcc): Do not attempt to construct
SSE based conditional moves on LTGT/UNEQ conditions;
Canonicalize EQ to NE.
* i386.md (sse_mov?fcc): Disallow EQ and NE in IEEE mode.
(sse_mov?fcc_ne): New.
*** i386.c Mon Mar 12 16:27:45 2001
--- /home/hubicka/x86-64/gcc/gcc/config/i386/i386.c Tue Mar 13 14:00:59 2001
*************** ix86_expand_fp_movcc (operands)
*** 6113,6118 ****
--- 7622,7630 ----
if (((TARGET_SSE && GET_MODE (operands[0]) == SFmode)
|| (TARGET_SSE2 && GET_MODE (operands[0]) == DFmode))
&& GET_MODE (ix86_compare_op0) == GET_MODE (operands[0])
+ /* The SSE comparisons does not support the LTGT/UNEQ pair. */
+ && (flag_fast_math
+ || (GET_CODE (operands[1]) != LTGT && GET_CODE (operands[1]) != UNEQ))
/* We may be called from the post-reload splitter. */
&& (!REG_P (operands[0])
|| SSE_REG_P (operands[0])
*************** ix86_expand_fp_movcc (operands)
*** 6172,6179 ****
ix86_compare_op1);
}
/* Similary try to manage result to be first operand of conditional
! move. */
! if (rtx_equal_p (operands[0], operands[3]))
{
rtx tmp = operands[2];
operands[2] = operands[3];
--- 7684,7693 ----
ix86_compare_op1);
}
/* Similary try to manage result to be first operand of conditional
! move. We also don't support the EQ comparison on SSE, so try to
! avoid it. */
! if (rtx_equal_p (operands[0], operands[3])
! || GET_CODE (operands[1]) == EQ)
{
rtx tmp = operands[2];
operands[2] = operands[3];
*** i386.md Tue Mar 13 13:51:49 2001
--- /home/hubicka/x86-64/gcc/gcc/config/i386/i386.md Tue Mar 13 15:06:22 2001
***************
*** 12830,12835 ****
--- 15800,15808 ----
;; based moves emulation or to usual cmove sequence. Little bit unfortunate
;; fact is that compares supported by the cmp??ss instructions are exactly
;; swapped of those supported by cmove sequence.
+ ;; The EQ/NE comparisons also needs bit care, since they are not directly
+ ;; supported by i387 comparisons and we do need to emit two conditional moves
+ ;; in tandem.
(define_insn "sse_movsfcc"
[(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
***************
*** 12841,12846 ****
--- 15814,15833 ----
(clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
(clobber (reg:CC 17))]
"TARGET_SSE
+ && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
+ && (!flag_fast_math
+ || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
+ "#")
+
+ (define_insn "sse_movsfcc_ne"
+ [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
+ (if_then_else:SF (ne (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
+ (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
+ (match_operand:SF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
+ (match_operand:SF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
+ (clobber (match_scratch:SF 5 "=1,&4,X,X,X,X"))
+ (clobber (reg:CC 17))]
+ "TARGET_SSE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"#")
***************
*** 12854,12859 ****
--- 15841,15860 ----
(clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
(clobber (reg:CC 17))]
"TARGET_SSE2
+ && (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)
+ && (!flag_fast_math
+ || (GET_CODE (operands[1]) != EQ && GET_CODE (operands[1]) != NE))"
+ "#")
+
+ (define_insn "sse_movdfcc_ne"
+ [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
+ (if_then_else:DF (ne (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,xm#f,f#x,xm#f")
+ (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,x#f,f#x,x#f"))
+ (match_operand:DF 1 "nonimmediate_operand" "x#fr,0#fr,0#fx,0#fx,0#rx,0#rx")
+ (match_operand:DF 2 "nonimmediate_operand" "x#fr,x#fr,f#fx,f#fx,rm#rx,rm#rx")))
+ (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X"))
+ (clobber (reg:CC 17))]
+ "TARGET_SSE
&& (GET_CODE (operands[2]) != MEM || GET_CODE (operands[3]) != MEM)"
"#")