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 
13 extern void abort (void);
14 
15 void __attribute__ ((noinline))
Sshift()16 Sshift()
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 
44 SHIFTU (shiftU1, 31, 1, -1)
45 SHIFTU (shiftU2, 32, -1, 1)
46 SHIFTU (shiftU3, 31, 1, 0)
47 SHIFTU (shiftU4, 32, -1, 0)
48 
49 void __attribute__ ((noinline))
add_1()50 add_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 
62 void __attribute__ ((noinline))
add_2()63 add_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 
75 void __attribute__ ((noinline))
mult_1()76 mult_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 
86 void __attribute__ ((noinline))
mult_2()87 mult_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 
99 void __attribute__ ((noinline))
mult_3()100 mult_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 
109 void __attribute__ ((noinline))
div_1()110 div_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 
mmx_test(void)121 void 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