1/* PR middle-end/37809 */ 2 3/* { dg-do run } */ 4/* { dg-options "-O2 -mmmx" } */ 5 6#include <mmintrin.h> 7 8#include "mmx-check.h" 9 10// Various tests of cases where it is incorrect to optimise vectors as if they 11// were integers of the same width. 12 13extern void abort (void); 14 15void __attribute__ ((noinline)) 16Sshift() 17{ 18 volatile __m64 y = (__m64) 0xffffffffll; 19 __m64 x = y & (__m64) 0xffffffffll; 20 x = _m_psradi (x, 1); 21 x &= (__m64) 0x80000000ll; 22 if (0 == (long long) x) 23 abort(); 24} 25 26#define SHIFTU(F,B,S,T) \ 27 void F() \ 28 { \ 29 volatile __m64 y = (__m64) 0ll; \ 30 __m64 x = y | (__m64) (1llu << B); \ 31 if (S > 0) \ 32 x = _m_pslldi (x, S); \ 33 else \ 34 x = _m_psrldi (x, -S); \ 35 if (T > 0) \ 36 x = _m_pslldi (x, T); \ 37 else \ 38 x = _m_psrldi (x, -T); \ 39 x &= (__m64) (1llu << (B + S + T)); \ 40 if ((long long) x) \ 41 abort(); \ 42 } 43 44SHIFTU (shiftU1, 31, 1, -1) 45SHIFTU (shiftU2, 32, -1, 1) 46SHIFTU (shiftU3, 31, 1, 0) 47SHIFTU (shiftU4, 32, -1, 0) 48 49void __attribute__ ((noinline)) 50add_1() 51{ 52 volatile long long ONE = 1; 53 long long one = ONE; 54 55 __m64 a = (__m64) one; 56 __m64 b = (__m64) -one; 57 __m64 c = a + b; 58 if (0 == (long long) c) 59 abort(); 60} 61 62void __attribute__ ((noinline)) 63add_2() 64{ 65 volatile long long ONE = 1; 66 long long one = ONE; 67 68 __m64 a = (__m64) one; 69 __m64 b = (__m64) -one; 70 __m64 c = _m_paddd (a, b); 71 if (0 == (long long) c) 72 abort(); 73} 74 75void __attribute__ ((noinline)) 76mult_1() 77{ 78 volatile __m64 y = (__m64) 0ll; 79 __m64 x = y | (__m64) (1ll << 32); 80 x = x * (__m64) 1ll; 81 x &= (__m64) (1ll << 32); 82 if (0 != (long long) x) 83 abort(); 84} 85 86void __attribute__ ((noinline)) 87mult_2() 88{ 89 volatile int foo = 1; 90 unsigned long long one = foo & 1; 91 92 __m64 x = (__m64) (one << 16); 93 x *= x; 94 x &= (__m64) (1ll << 32); 95 if (0 != (long long) x) 96 abort(); 97} 98 99void __attribute__ ((noinline)) 100mult_3() 101{ 102 volatile __m64 y = (__m64) (1ll << 32); 103 __m64 a = y; 104 __m64 b = y * (__m64) 1ll; 105 if (((long long) a) == (long long) b) 106 abort(); 107} 108 109void __attribute__ ((noinline)) 110div_1() 111{ 112 volatile __m64 y = (__m64) 0ll; 113 __m64 x = y | (__m64) (1ull << 32); 114 x |= (__m64) 1ull; 115 x = x / x; 116 if (1ll == (long long) x) 117 abort(); 118} 119 120 121void mmx_test (void) 122{ 123 Sshift(); 124 shiftU1(); 125 shiftU2(); 126 shiftU3(); 127 shiftU4(); 128 129 add_1(); 130 add_2(); 131 132 mult_1(); 133 mult_2(); 134 mult_3(); 135 136 div_1(); 137} 138