re PR target/6753 (gcc 3.1 produces wrong code when optimizing for pentium4)
authorJakub Jelinek <jakub@redhat.com>
Thu, 23 May 2002 09:29:29 +0000 (11:29 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 23 May 2002 09:29:29 +0000 (11:29 +0200)
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.

From-SVN: r53784

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20020523-1.c [new file with mode: 0644]

index 055b019a5e5a2881488a31a2dac4e4d7eb9748be..3e19e618b680c349164cf0c262464417b9ac8e09 100644 (file)
@@ -1,3 +1,15 @@
+2002-05-23  Jakub Jelinek  <jakub@redhat.com>
+
+       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  <rth@redhat.com>
 
        * doc/extend.texi (C99 Thread-Local Edits): New subsection.
index 913dccb8e023cc658f43d7b51b888608f97e8a3a..1bdfac82a83ae903fa6de5a6dcd5ba16eb5d7dde 100644 (file)
   "#")
 
 (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
   "#")
 
 (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
    (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];
 ;; 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")])
   "#")
 
 (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")])
   "#")
 
 (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")])
   "#")
 
 (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")])
   "#")
 
 (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"
   "#")
 
index 2681b7f92abd4f067883d0dba7412c90f1e8cc27..87ab261664c2cfa9077a1ae600bb189b9864a224 100644 (file)
@@ -1,3 +1,7 @@
+2002-05-23  Jakub Jelinek  <jakub@redhat.com>
+
+       * gcc.dg/20020523-1.c: New test.
+
 2002-05-23  Neil Booth  <neil@daikokuya.demon.co.uk>
 
        * 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 (file)
index 0000000..5ae3da5
--- /dev/null
@@ -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);
+}