re PR middle-end/37807 (Exponential compile time with MMX builtins.)
authorRalph Loader <suckfish@ihug.co.nz>
Mon, 10 Nov 2008 09:08:15 +0000 (10:08 +0100)
committerUros Bizjak <uros@gcc.gnu.org>
Mon, 10 Nov 2008 09:08:15 +0000 (10:08 +0100)
PR middle-end/37807
PR middle-end/37809
* combine.c (force_to_mode): Do not process vector types.

* rtlanal.c (nonzero_bits1): Do not process vector types.
(num_sign_bit_copies1): Likewise.

testsuite/ChangeLog

PR middle-end/37807
PR middle-end/37809
* gcc/testsuite/gcc.target/i386/mmx-8.c: New test.

From-SVN: r141732

gcc/ChangeLog
gcc/combine.c
gcc/rtlanal.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/mmx-8.c [new file with mode: 0644]

index 1d869ee09a32b05ae53cb94b41ca30916a8459ff..62f857f4aa6fa512f54973b9be37652ea96f9a01 100644 (file)
@@ -1,3 +1,12 @@
+2008-11-10  Ralph Loader  <suckfish@ihug.co.nz>
+
+       PR middle-end/37807
+       PR middle-end/37809
+       * combine.c (force_to_mode): Do not process vector types.
+
+       * rtlanal.c (nonzero_bits1): Do not process vector types.
+       (num_sign_bit_copies1): Likewise.
+
 2008-11-09  Thomas Schwinge  <tschwinge@gnu.org>
 
        * config/i386/gnu.h: Add copyright and licensing header.
index e76049a49ef44015124edaf0991eb6ace549dfd7..b8a43356b461e2a9d9a678075b07a4da61acf1cb 100644 (file)
@@ -7323,6 +7323,10 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
       && (GET_MODE_MASK (GET_MODE (x)) & ~mask) == 0)
     return gen_lowpart (mode, x);
 
+  /* The arithmetic simplifications here do the wrong thing on vector modes.  */
+  if (VECTOR_MODE_P (mode) || VECTOR_MODE_P (GET_MODE (x)))
+      return gen_lowpart (mode, x);
+
   switch (code)
     {
     case CLOBBER:
index b2038aa840fc902b8ccd5ac30c9f99f5540411fe..5d9df2cc0892d14504af44be86c1f52d7e362951 100644 (file)
@@ -3681,8 +3681,9 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
   enum rtx_code code;
   unsigned int mode_width = GET_MODE_BITSIZE (mode);
 
-  /* For floating-point values, assume all bits are needed.  */
-  if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode))
+  /* For floating-point and vector values, assume all bits are needed.  */
+  if (FLOAT_MODE_P (GET_MODE (x)) || FLOAT_MODE_P (mode)
+      || VECTOR_MODE_P (GET_MODE (x)) || VECTOR_MODE_P (mode))
     return nonzero;
 
   /* If X is wider than MODE, use its mode instead.  */
@@ -4195,7 +4196,8 @@ num_sign_bit_copies1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
   if (mode == VOIDmode)
     mode = GET_MODE (x);
 
-  if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x)))
+  if (mode == VOIDmode || FLOAT_MODE_P (mode) || FLOAT_MODE_P (GET_MODE (x))
+      || VECTOR_MODE_P (GET_MODE (x)) || VECTOR_MODE_P (mode))
     return 1;
 
   /* For a smaller object, just ignore the high bits.  */
index 5c1b974971e55fc7a84e34a3282f90967b5beed7..28665feb76bbda2b3ad095abd74012b454ea0f56 100644 (file)
@@ -1,7 +1,13 @@
+2008-11-02  Ralph Loader  <suckfish@ihug.co.nz>
+
+       PR middle-end/37807
+       PR middle-end/37809
+       * gcc/testsuite/gcc.target/i386/mmx-8.c: New test.
+
 2008-11-09  Paul Thomas  <pault@gcc.gnu.org>
 
-        PR fortran/37836
-        * gfortran.dg/minmaxval_1.f90: New test.
+       PR fortran/37836
+       * gfortran.dg/minmaxval_1.f90: New test.
 
 2008-11-09  Eric Botcazou  <ebotcazou@adacore.com>
 
@@ -17,8 +23,7 @@
 
 2008-11-07  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
-       * g++.dg/ipa/iinline-1.C: Remove -c flag, add -fpie for PIC
-       targets.
+       * g++.dg/ipa/iinline-1.C: Remove -c flag, add -fpie for PIC targets.
 
        * gcc.dg/tree-ssa/inline-2.c (foo): Add 'inline' keyword.
 
diff --git a/gcc/testsuite/gcc.target/i386/mmx-8.c b/gcc/testsuite/gcc.target/i386/mmx-8.c
new file mode 100644 (file)
index 0000000..c90083b
--- /dev/null
@@ -0,0 +1,137 @@
+/* PR middle-end/37809 */
+
+/* { dg-do run } */
+/* { dg-options "-O2 -mmmx" } */
+
+#include <mmintrin.h>
+
+#include "mmx-check.h"
+
+// Various tests of cases where it is incorrect to optimise vectors as if they
+// were integers of the same width.
+
+extern void abort (void);
+
+void __attribute__ ((noinline))
+Sshift()
+{
+    volatile __m64 y = (__m64) 0xffffffffll;
+    __m64 x = y & (__m64) 0xffffffffll;
+    x = _m_psradi (x, 1);
+    x &= (__m64) 0x80000000ll;
+    if (0 == (long long) x)
+        abort();
+}
+
+#define SHIFTU(F,B,S,T)                         \
+    void F()                                    \
+    {                                           \
+        volatile __m64 y = (__m64) 0ll;         \
+        __m64 x = y | (__m64) (1llu << B);      \
+        if (S > 0)                              \
+            x = _m_pslldi (x, S);               \
+        else                                    \
+            x = _m_psrldi (x, -S);              \
+        if (T > 0)                              \
+            x = _m_pslldi (x, T);               \
+        else                                    \
+            x = _m_psrldi (x, -T);              \
+        x &= (__m64) (1llu << (B + S + T));     \
+        if ((long long) x)                      \
+            abort();                            \
+    }
+
+SHIFTU (shiftU1, 31, 1, -1)
+SHIFTU (shiftU2, 32, -1, 1)
+SHIFTU (shiftU3, 31, 1, 0)
+SHIFTU (shiftU4, 32, -1, 0)
+
+void __attribute__ ((noinline))
+add_1()
+{
+    volatile long long ONE = 1;
+    long long one = ONE;
+
+    __m64 a = (__m64) one;
+    __m64 b = (__m64) -one;
+    __m64 c = a + b;
+    if (0 == (long long) c)
+        abort();
+}
+
+void __attribute__ ((noinline))
+add_2()
+{
+    volatile long long ONE = 1;
+    long long one = ONE;
+
+    __m64 a = (__m64) one;
+    __m64 b = (__m64) -one;
+    __m64 c = _m_paddd (a, b);
+    if (0 == (long long) c)
+        abort();
+}
+
+void __attribute__ ((noinline))
+mult_1()
+{
+    volatile __m64 y = (__m64) 0ll;
+    __m64 x = y | (__m64) (1ll << 32);
+    x = x * (__m64) 1ll;
+    x &= (__m64) (1ll << 32);
+    if (0 != (long long) x)
+        abort();
+}
+
+void __attribute__ ((noinline))
+mult_2()
+{
+    volatile int foo = 1;
+    unsigned long long one = foo & 1;
+
+    __m64 x = (__m64) (one << 16);
+    x *= x;
+    x &= (__m64) (1ll << 32);
+    if (0 != (long long) x)
+        abort();
+}
+
+void __attribute__ ((noinline))
+mult_3()
+{
+    volatile __m64 y = (__m64) (1ll << 32);
+    __m64 a = y;
+    __m64 b = y * (__m64) 1ll;
+    if (((long long) a) == (long long) b)
+        abort();
+}
+
+void __attribute__ ((noinline))
+div_1()
+{
+    volatile __m64 y = (__m64) 0ll;
+    __m64 x = y | (__m64) (1ull << 32);
+    x |= (__m64) 1ull;
+    x = x / x;
+    if (1ll == (long long) x)
+        abort();
+}
+
+
+void mmx_test (void)
+{
+    Sshift();
+    shiftU1();
+    shiftU2();
+    shiftU3();
+    shiftU4();
+
+    add_1();
+    add_2();
+
+    mult_1();
+    mult_2();
+    mult_3();
+
+    div_1();
+}