From 0d9cee199b8be3887885182a1cdad4e7b9f8b31e Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Mon, 10 Nov 2008 13:20:55 +0100 Subject: [PATCH] backport: re PR middle-end/37807 (Exponential compile time with MMX builtins.) Backport from mainline: 2008-11-10 Ralph Loader 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: Backport from mainline: 2008-11-10 Ralph Loader PR middle-end/37807 PR middle-end/37809 * gcc/testsuite/gcc.target/i386/mmx-8.c: New test. From-SVN: r141737 --- gcc/ChangeLog | 12 +++ gcc/combine.c | 4 + gcc/rtlanal.c | 8 +- gcc/testsuite/ChangeLog | 9 ++ gcc/testsuite/gcc.target/i386/mmx-8.c | 150 ++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/mmx-8.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 97aff4063df1..7cc2bad79bfb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2008-11-10 Uros Bizjak + + Backport from mainline: + 2008-11-10 Ralph Loader + + 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-06 Rainer Orth PR bootstrap/33100 diff --git a/gcc/combine.c b/gcc/combine.c index 4806cdfa6d07..14bac70e58d7 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -6908,6 +6908,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 b16da4a0956f..2b71e9ddf688 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -3400,8 +3400,9 @@ nonzero_bits1 (rtx x, enum machine_mode mode, 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. */ @@ -3914,7 +3915,8 @@ num_sign_bit_copies1 (rtx x, enum machine_mode mode, 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 360c91a9aebb..8a66787dd267 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2008-11-10 Uros Bizjak + + Backport from mainline: + 2008-11-10 Ralph Loader + + PR middle-end/37807 + PR middle-end/37809 + * gcc/testsuite/gcc.target/i386/mmx-8.c: New test. + 2008-10-07 H.J. Lu Backport from mainline: 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 000000000000..bb5e8a8337a2 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mmx-8.c @@ -0,0 +1,150 @@ +/* PR middle-end/37809 */ + +/* { dg-do run } */ +/* { dg-options "-O2 -mmmx" } */ + +#include +#include "../../gcc.dg/i386-cpuid.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); +extern void exit (int); + +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(); +} + +int main() +{ + unsigned long cpu_facilities; + + cpu_facilities = i386_cpuid (); + + if ((cpu_facilities & bit_MMX) == 0) + exit (0); + + mmx_test (); + return 0; +} -- 2.47.2