From b478fd74cbc214e61d9608da2d926e29044577fc Mon Sep 17 00:00:00 2001 From: jakub Date: Thu, 23 May 2002 09:29:29 +0000 Subject: [PATCH] PR target/6753 * config/i386/i386.md (sse_movdfcc, sse_movdfcc_eq): Use Y instead of x in constraints for clarity. (sse_mov?fcc split): abort if op2 == op3. (sse_movsfcc_const0_1, sse_movsfcc_const0_2, sse_movsfcc_const0_3, sse_movsfcc_const0_4): Add earlyclobber. (sse_movdfcc_const0_1, sse_movdfcc_const0_2, sse_movdfcc_const0_3, sse_movdfcc_const0_4): Likewise. Use DFmode, not SFmode. Use Y instead of x in constraints. * gcc.dg/20020523-1.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@53784 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 12 ++++++ gcc/config/i386/i386.md | 80 ++++++++++++++++++++------------------- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/20020523-1.c | 65 +++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 38 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/20020523-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 055b019..3e19e61 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2002-05-23 Jakub Jelinek + + PR target/6753 + * config/i386/i386.md (sse_movdfcc, sse_movdfcc_eq): Use Y instead + of x in constraints for clarity. + (sse_mov?fcc split): abort if op2 == op3. + (sse_movsfcc_const0_1, sse_movsfcc_const0_2, sse_movsfcc_const0_3, + sse_movsfcc_const0_4): Add earlyclobber. + (sse_movdfcc_const0_1, sse_movdfcc_const0_2, sse_movdfcc_const0_3, + sse_movdfcc_const0_4): Likewise. Use DFmode, not SFmode. + Use Y instead of x in constraints. + 2002-05-23 Richard Henderson * doc/extend.texi (C99 Thread-Local Edits): New subsection. diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 913dccb..1bdfac8 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -15949,12 +15949,12 @@ "#") (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") + [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?f#Yr,?f#Yr,?r#Yf,?r#Yf,?r#Yf,?r#Yf") (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"))) + [(match_operand:DF 4 "nonimmediate_operand" "0#fY,Y#fY,f#Y,f#Y,Ym#f,Ym#f,f#Y,f#Y,Ym#f,Ym#f") + (match_operand:DF 5 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,f#Y,Y#f,Y#f,f#Y,f#Y,Y#f,Y#f")]) + (match_operand:DF 2 "nonimmediate_operand" "Y#fr,0#fr,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY,0#rY") + (match_operand:DF 3 "nonimmediate_operand" "Y#fr,Y#fr,0#fY,f#fY,0#fY,f#fY,0#fY,rm#rY,0#rY,rm#rY"))) (clobber (match_scratch:DF 6 "=2,&4,X,X,X,X,X,X,X,X")) (clobber (reg:CC 17))] "TARGET_SSE2 @@ -15964,11 +15964,11 @@ "#") (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"))) + [(set (match_operand:DF 0 "register_operand" "=&Y#rf,Y#rf,?f#Yr,?f#Yr,?r#Yf,?r#Yf") + (if_then_else:DF (eq (match_operand:DF 3 "nonimmediate_operand" "%0#fY,Y#fY,f#Y,Ym#f,f#Y,Ym#f") + (match_operand:DF 4 "nonimmediate_operand" "Ym#f,Ym#f,f#Y,Y#f,f#Y,Y#f")) + (match_operand:DF 1 "nonimmediate_operand" "Y#fr,0#fr,0#fY,0#fY,0#rY,0#rY") + (match_operand:DF 2 "nonimmediate_operand" "Y#fr,Y#fr,f#fY,f#fY,rm#rY,rm#rY"))) (clobber (match_scratch:DF 5 "=1,&3,X,X,X,X")) (clobber (reg:CC 17))] "TARGET_SSE @@ -16020,6 +16020,10 @@ (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0) (subreg:TI (match_dup 7) 0)))] { + /* If op2 == op3, op3 will be clobbered before it is used. + This should be optimized out though. */ + if (operands_match_p (operands[2], operands[3])) + abort (); PUT_MODE (operands[1], GET_MODE (operands[0])); if (operands_match_p (operands[0], operands[4])) operands[6] = operands[4], operands[7] = operands[2]; @@ -16031,7 +16035,7 @@ ;; Do not brother with the integer/floating point case, since these are ;; bot considerably slower, unlike in the generic case. (define_insn "*sse_movsfcc_const0_1" - [(set (match_operand:SF 0 "register_operand" "=x") + [(set (match_operand:SF 0 "register_operand" "=&x") (if_then_else:SF (match_operator 1 "sse_comparison_operator" [(match_operand:SF 4 "register_operand" "0") (match_operand:SF 5 "nonimmediate_operand" "xm")]) @@ -16041,7 +16045,7 @@ "#") (define_insn "*sse_movsfcc_const0_2" - [(set (match_operand:SF 0 "register_operand" "=x") + [(set (match_operand:SF 0 "register_operand" "=&x") (if_then_else:SF (match_operator 1 "sse_comparison_operator" [(match_operand:SF 4 "register_operand" "0") (match_operand:SF 5 "nonimmediate_operand" "xm")]) @@ -16051,7 +16055,7 @@ "#") (define_insn "*sse_movsfcc_const0_3" - [(set (match_operand:SF 0 "register_operand" "=x") + [(set (match_operand:SF 0 "register_operand" "=&x") (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" [(match_operand:SF 4 "nonimmediate_operand" "xm") (match_operand:SF 5 "register_operand" "0")]) @@ -16061,7 +16065,7 @@ "#") (define_insn "*sse_movsfcc_const0_4" - [(set (match_operand:SF 0 "register_operand" "=x") + [(set (match_operand:SF 0 "register_operand" "=&x") (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" [(match_operand:SF 4 "nonimmediate_operand" "xm") (match_operand:SF 5 "register_operand" "0")]) @@ -16071,42 +16075,42 @@ "#") (define_insn "*sse_movdfcc_const0_1" - [(set (match_operand:SF 0 "register_operand" "=x") - (if_then_else:SF (match_operator 1 "sse_comparison_operator" - [(match_operand:SF 4 "register_operand" "0") - (match_operand:SF 5 "nonimmediate_operand" "xm")]) - (match_operand:SF 2 "register_operand" "x") - (match_operand:SF 3 "const0_operand" "X")))] + [(set (match_operand:DF 0 "register_operand" "=&Y") + (if_then_else:DF (match_operator 1 "sse_comparison_operator" + [(match_operand:DF 4 "register_operand" "0") + (match_operand:DF 5 "nonimmediate_operand" "Ym")]) + (match_operand:DF 2 "register_operand" "Y") + (match_operand:DF 3 "const0_operand" "X")))] "TARGET_SSE2" "#") (define_insn "*sse_movdfcc_const0_2" - [(set (match_operand:SF 0 "register_operand" "=x") - (if_then_else:SF (match_operator 1 "sse_comparison_operator" - [(match_operand:SF 4 "register_operand" "0") - (match_operand:SF 5 "nonimmediate_operand" "xm")]) - (match_operand:SF 2 "const0_operand" "X") - (match_operand:SF 3 "register_operand" "x")))] + [(set (match_operand:DF 0 "register_operand" "=&Y") + (if_then_else:DF (match_operator 1 "sse_comparison_operator" + [(match_operand:DF 4 "register_operand" "0") + (match_operand:DF 5 "nonimmediate_operand" "Ym")]) + (match_operand:DF 2 "const0_operand" "X") + (match_operand:DF 3 "register_operand" "Y")))] "TARGET_SSE2" "#") (define_insn "*sse_movdfcc_const0_3" - [(set (match_operand:SF 0 "register_operand" "=x") - (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" - [(match_operand:SF 4 "nonimmediate_operand" "xm") - (match_operand:SF 5 "register_operand" "0")]) - (match_operand:SF 2 "register_operand" "x") - (match_operand:SF 3 "const0_operand" "X")))] + [(set (match_operand:DF 0 "register_operand" "=&Y") + (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" + [(match_operand:DF 4 "nonimmediate_operand" "Ym") + (match_operand:DF 5 "register_operand" "0")]) + (match_operand:DF 2 "register_operand" "Y") + (match_operand:DF 3 "const0_operand" "X")))] "TARGET_SSE2" "#") (define_insn "*sse_movdfcc_const0_4" - [(set (match_operand:SF 0 "register_operand" "=x") - (if_then_else:SF (match_operator 1 "fcmov_comparison_operator" - [(match_operand:SF 4 "nonimmediate_operand" "xm") - (match_operand:SF 5 "register_operand" "0")]) - (match_operand:SF 2 "const0_operand" "X") - (match_operand:SF 3 "register_operand" "x")))] + [(set (match_operand:DF 0 "register_operand" "=&Y") + (if_then_else:DF (match_operator 1 "fcmov_comparison_operator" + [(match_operand:DF 4 "nonimmediate_operand" "Ym") + (match_operand:DF 5 "register_operand" "0")]) + (match_operand:DF 2 "const0_operand" "X") + (match_operand:DF 3 "register_operand" "Y")))] "TARGET_SSE2" "#") diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2681b7f..87ab261 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-05-23 Jakub Jelinek + + * gcc.dg/20020523-1.c: New test. + 2002-05-23 Neil Booth * objc.dg/const-str-2.m: Update now that we stop after diff --git a/gcc/testsuite/gcc.dg/20020523-1.c b/gcc/testsuite/gcc.dg/20020523-1.c new file mode 100644 index 0000000..5ae3da5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/20020523-1.c @@ -0,0 +1,65 @@ +/* PR target/6753 + This testcase was miscompiled because sse_mov?fcc_const0* + patterns were missing earlyclobber. */ +/* { dg-do run { target i386-*-* } } */ +/* { dg-options "-march=pentium3 -msse -ffast-math -O2" } */ + +extern void abort (void); +extern void exit (int); + +float one = 1.f; + +void bar (float f) +{ + if (__builtin_memcmp (&one, &f, sizeof (float))) + abort (); +} + +float foo (void) +{ + return 1.f; +} + +typedef struct +{ + float t; +} T; + +void bail_if_no_sse (void) +{ + int fl1, fl2; + + /* See if we can use cpuid. */ + __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;" + "pushl %0; popfl; pushfl; popl %0; popfl" + : "=&r" (fl1), "=&r" (fl2) + : "i" (0x00200000)); + if (((fl1 ^ fl2) & 0x00200000) == 0) + exit (0); + + /* See if cpuid gives capabilities. */ + __asm__ ("cpuid" : "=a" (fl1) : "0" (0) : "ebx", "ecx", "edx", "cc"); + if (fl1 == 0) + exit (0); + + /* See if capabilities include SSE (25th bit; 26 for SSE2). */ + __asm__ ("cpuid" : "=a" (fl1), "=d" (fl2) : "0" (1) : "ebx", "ecx", "cc"); + if ((fl2 & (1 << 25)) == 0) + exit (0); +} + +int main (void) +{ + int i; + T x[1]; + + bail_if_no_sse (); + for (i = 0; i < 1; i++) + { + x[i].t = foo (); + x[i].t = 0.f > x[i].t ? 0.f : x[i].t; + bar (x[i].t); + } + + exit (0); +} -- 2.7.4