aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRalph Loader <suckfish@ihug.co.nz>2008-11-10 10:08:15 +0100
committerUros Bizjak <uros@gcc.gnu.org>2008-11-10 10:08:15 +0100
commitff596cd202305b7d7c4f4511fdd505a01c6a5ece (patch)
treef53c161297245fe4c06c693cc1f4ccf690cedb88
parent75223c17538213f86175b988a1b876fdd735d86c (diff)
downloadgcc-ff596cd202305b7d7c4f4511fdd505a01c6a5ece.zip
gcc-ff596cd202305b7d7c4f4511fdd505a01c6a5ece.tar.gz
gcc-ff596cd202305b7d7c4f4511fdd505a01c6a5ece.tar.bz2
re PR middle-end/37807 (Exponential compile time with MMX builtins.)
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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/combine.c4
-rw-r--r--gcc/rtlanal.c8
-rw-r--r--gcc/testsuite/ChangeLog13
-rw-r--r--gcc/testsuite/gcc.target/i386/mmx-8.c137
5 files changed, 164 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1d869ee..62f857f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/combine.c b/gcc/combine.c
index e76049a..b8a4335 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -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:
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index b2038aa..5d9df2c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 5c1b974..28665fe 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..c90083b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/mmx-8.c
@@ -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();
+}