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]

Fix for SSE conditional move patterns


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)"
    "#")
  


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