RFH PR 5877 (sse comparisons)

Jan Hubicka jh@suse.cz
Thu Mar 14 03:47:00 GMT 2002


> 
> /* PR optimization/5887 */
> /* { dg-do compile } */
> /* { dg-options "-O2" } */
> /* { dg-options "-O2 -msse -ffast-math" { target i?86-*-* } } */
> 
> void bar (float *a, float *b);
> 
> void foo (char *x)
> {
>   float a, b;
>   char c[256];
>   int i, j;
> 
>   bar (&a, &b);
>   for (i = 0; i < 256; i++)
>     {
>       float v = a;
>       if (v < 0.0f) v = 0.0f;
>       if (v < 255.0f) v = 255.0f;
>       c[i] = v;
>       a += b;
>     }
> 
>   for (j = 0; j < 256; j++)
>     x[j] = c[j];
> }
> 
> (insn 161 213 164 (parallel[
>             (set (reg/v:SF 8 st(0) [65])
>                 (if_then_else:SF (unlt (mem/f:SF (plus:SI (reg/f:SI 6 ebp)
>                                 (const_int -272 [0xfffffef0])) [3 S4 A32])
>                         (reg:SF 21 exmm0 [78]))
>                     (reg:SF 10 st(2))
>                     (reg/v:SF 8 st(0) [65])))
>             (clobber (scratch:SF))
>             (clobber (reg:CC 17 flags))
>         ] ) 637 {sse_movsfcc} (nil)
>     (nil))
> 
> je splitnuto na:
> 
> (insn 214 213 215 (set (reg:CCFP 17 flags)
>         (compare:CCFP (reg:SF 21 exmm0 [78])
>             (mem/f:SF (plus:SI (reg/f:SI 6 ebp)
>                     (const_int -272 [0xfffffef0])) [3 S4 A32]))) -1 (nil)
>     (nil))
> 
> (insn 215 214 164 (set (reg/v:SF 8 st(0) [65])
>         (if_then_else:SF (gt (reg:CCFP 17 flags)
>                 (const_int 0 [0x0]))
>             (reg:SF 10 st(2))
>             (reg/v:SF 8 st(0) [65]))) -1 (nil)
>     (nil))
> 

Hi,
this patch should solve the problem.  The sse comparison act in swapped
way compared to i387 comparisons so the splitter is swapping them, but
since pattern has constraints in non-swapped way, the resulting code is
invalid.

I've also noticed that SSE_FLOAT_MODE_P is returning 0 when TARGET_SSE_MATH
is disabled.  THis is not correct - we still want to use SSE for operations
that can be safely done in it w/o losing the extra precisity glibc (and
perhaps some other) folks depends on.

Bootstrapped/regtested i386, but I can not give it proper testing with
SSE code right now :(
OK for branch?

Honza

Thu Mar 14 12:42:38 CET 2002  Jan Hubicka  <jh@suse.cz>
	* i386.h (SSE_FLOAT_MODE_P): Kill bogus TARGET_SSE_MATH check.
	* i386.c (sse_mov?fcc*): Swap operands for cases they will be swapped
	later.

Index: i386.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.h,v
retrieving revision 1.252
diff -c -3 -p -r1.252 i386.h
*** i386.h	2002/03/13 05:42:35	1.252
--- i386.h	2002/03/14 11:41:19
*************** enum reg_class
*** 1315,1321 ****
  #define SSE_REG_P(N) (REG_P (N) && SSE_REGNO_P (REGNO (N)))
  
  #define SSE_FLOAT_MODE_P(MODE) \
!   ((TARGET_SSE_MATH && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode))
  
  #define MMX_REGNO_P(N) ((N) >= FIRST_MMX_REG && (N) <= LAST_MMX_REG)
  #define MMX_REG_P(XOP) (REG_P (XOP) && MMX_REGNO_P (REGNO (XOP)))
--- 1315,1321 ----
  #define SSE_REG_P(N) (REG_P (N) && SSE_REGNO_P (REGNO (N)))
  
  #define SSE_FLOAT_MODE_P(MODE) \
!   ((MODE) == SFmode || (TARGET_SSE2 && (MODE) == DFmode))
  
  #define MMX_REGNO_P(N) ((N) >= FIRST_MMX_REG && (N) <= LAST_MMX_REG)
  #define MMX_REG_P(XOP) (REG_P (XOP) && MMX_REGNO_P (REGNO (XOP)))
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.340
diff -c -3 -p -r1.340 i386.md
*** i386.md	2002/03/06 00:06:05	1.340
--- i386.md	2002/03/14 11:41:29
***************
*** 16538,16545 ****
  (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")
  	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
! 			[(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
! 			 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
  		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
  		      (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
     (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
--- 16538,16545 ----
  (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")
  	(if_then_else:SF (match_operator 1 "sse_comparison_operator"
! 			[(match_operand:SF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")
! 			 (match_operand:SF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")])
  		      (match_operand:SF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
  		      (match_operand:SF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
     (clobber (match_scratch:SF 6 "=2,&4,X,X,X,X,X,X,X,X"))
***************
*** 16552,16559 ****
  
  (define_insn "sse_movsfcc_eq"
    [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
! 	(if_then_else:SF (eq (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,&3,X,X,X,X"))
--- 16552,16559 ----
  
  (define_insn "sse_movsfcc_eq"
    [(set (match_operand:SF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
! 	(if_then_else:SF (eq (match_operand:SF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,x#f,f#x,x#f")
! 			     (match_operand:SF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,xm#f,f#x,xm#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,&3,X,X,X,X"))
***************
*** 16565,16572 ****
  (define_insn "sse_movdfcc"
    [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
  	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
! 			[(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")
! 			 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")])
  		      (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
  		      (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
     (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
--- 16565,16572 ----
  (define_insn "sse_movdfcc"
    [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?f#xr,?f#xr,?r#xf,?r#xf,?r#xf,?r#xf")
  	(if_then_else:DF (match_operator 1 "sse_comparison_operator"
! 			[(match_operand:DF 4 "nonimmediate_operand" "0#fx,x#fx,f#x,f#x,x#f,x#f,f#x,f#x,x#f,x#f")
! 			 (match_operand:DF 5 "nonimmediate_operand" "xm#f,xm#f,f#x,f#x,xm#f,xm#f,f#x,f#x,xm#f,xm#f")])
  		      (match_operand:DF 2 "nonimmediate_operand" "x#fr,0#fr,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx,0#rx")
  		      (match_operand:DF 3 "nonimmediate_operand" "x#fr,x#fr,0#fx,f#fx,0#fx,f#fx,0#fx,rm#rx,0#rx,rm#rx")))
     (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X"))
***************
*** 16579,16586 ****
  
  (define_insn "sse_movdfcc_eq"
    [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
! 	(if_then_else:DF (eq (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"))
--- 16579,16586 ----
  
  (define_insn "sse_movdfcc_eq"
    [(set (match_operand:DF 0 "register_operand" "=&x#rf,x#rf,?f#xr,?f#xr,?r#xf,?r#xf")
! 	(if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fx,x#fx,f#x,x#f,f#x,x#f")
! 			     (match_operand:DF 4 "nonimmediate_operand" "xm#f,xm#f,f#x,xm#f,f#x,xm#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"))
***************
*** 16594,16600 ****
    [(set (match_operand 0 "register_operand" "")
  	(if_then_else (match_operator 1 "comparison_operator"
  			[(match_operand 4 "nonimmediate_operand" "")
! 			 (match_operand 5 "register_operand" "")])
  		      (match_operand 2 "nonimmediate_operand" "")
  		      (match_operand 3 "nonimmediate_operand" "")))
     (clobber (match_operand 6 "" ""))
--- 16594,16600 ----
    [(set (match_operand 0 "register_operand" "")
  	(if_then_else (match_operator 1 "comparison_operator"
  			[(match_operand 4 "nonimmediate_operand" "")
! 			 (match_operand 5 "nonimmediate_operand" "")])
  		      (match_operand 2 "nonimmediate_operand" "")
  		      (match_operand 3 "nonimmediate_operand" "")))
     (clobber (match_operand 6 "" ""))



More information about the Gcc-patches mailing list