blob: 973e0644b4e98980047575d024c073d63fac47b5 [file] [log] [blame]
Sanjay Patelaaf43042016-11-15 23:09:53 +00001; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
Sanjay Patelbab5d6c2015-09-20 15:58:00 +00002; RUN: llc -mtriple=x86_64-unknown-unknown -mattr=sse2 < %s | FileCheck %s
3
4; PR22428: https://llvm.org/bugs/show_bug.cgi?id=22428
5; f1, f2, f3, and f4 should use an integer logic instruction.
Sanjay Patel066139a2016-11-16 22:34:05 +00006; f5, f6, f9, and f10 should use an FP (SSE) logic instruction.
Sanjay Patelbab5d6c2015-09-20 15:58:00 +00007;
Sanjay Patel066139a2016-11-16 22:34:05 +00008; f7 and f8 are less clear.
Sanjay Patelbab5d6c2015-09-20 15:58:00 +00009;
10; For f7 and f8, the SSE instructions don't take immediate operands, so if we
11; use one of those, we either have to load a constant from memory or move the
12; scalar immediate value from an integer register over to an SSE register.
13; Optimizing for size may affect that decision. Also, note that there are no
14; scalar versions of the FP logic ops, so if we want to fold a load into a
15; logic op, we have to load or splat a 16-byte vector constant.
16
17; 1 FP operand, 1 int operand, int result
18
19define i32 @f1(float %x, i32 %y) {
20; CHECK-LABEL: f1:
21; CHECK: # BB#0:
22; CHECK-NEXT: movd %xmm0, %eax
23; CHECK-NEXT: andl %edi, %eax
24; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +000025;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000026 %bc1 = bitcast float %x to i32
27 %and = and i32 %bc1, %y
28 ret i32 %and
29}
30
31; Swap operands of the logic op.
32
33define i32 @f2(float %x, i32 %y) {
34; CHECK-LABEL: f2:
35; CHECK: # BB#0:
36; CHECK-NEXT: movd %xmm0, %eax
37; CHECK-NEXT: andl %edi, %eax
38; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +000039;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000040 %bc1 = bitcast float %x to i32
41 %and = and i32 %y, %bc1
42 ret i32 %and
43}
44
45; 1 FP operand, 1 constant operand, int result
46
47define i32 @f3(float %x) {
48; CHECK-LABEL: f3:
49; CHECK: # BB#0:
50; CHECK-NEXT: movd %xmm0, %eax
51; CHECK-NEXT: andl $1, %eax
52; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +000053;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000054 %bc1 = bitcast float %x to i32
55 %and = and i32 %bc1, 1
56 ret i32 %and
57}
58
59; Swap operands of the logic op.
60
61define i32 @f4(float %x) {
62; CHECK-LABEL: f4:
63; CHECK: # BB#0:
64; CHECK-NEXT: movd %xmm0, %eax
65; CHECK-NEXT: andl $2, %eax
66; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +000067;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000068 %bc1 = bitcast float %x to i32
69 %and = and i32 2, %bc1
70 ret i32 %and
71}
72
73; 1 FP operand, 1 integer operand, FP result
74
75define float @f5(float %x, i32 %y) {
76; CHECK-LABEL: f5:
77; CHECK: # BB#0:
Sanjay Patel066139a2016-11-16 22:34:05 +000078; CHECK-NEXT: movd %edi, %xmm1
Simon Pilgrim8893bd92016-12-07 12:10:49 +000079; CHECK-NEXT: pand %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000080; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +000081;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000082 %bc1 = bitcast float %x to i32
83 %and = and i32 %bc1, %y
84 %bc2 = bitcast i32 %and to float
85 ret float %bc2
86}
87
88; Swap operands of the logic op.
89
90define float @f6(float %x, i32 %y) {
91; CHECK-LABEL: f6:
92; CHECK: # BB#0:
Sanjay Patel066139a2016-11-16 22:34:05 +000093; CHECK-NEXT: movd %edi, %xmm1
Simon Pilgrim8893bd92016-12-07 12:10:49 +000094; CHECK-NEXT: pand %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000095; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +000096;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +000097 %bc1 = bitcast float %x to i32
98 %and = and i32 %y, %bc1
99 %bc2 = bitcast i32 %and to float
100 ret float %bc2
101}
102
103; 1 FP operand, 1 constant operand, FP result
104
105define float @f7(float %x) {
106; CHECK-LABEL: f7:
107; CHECK: # BB#0:
Sanjay Patel309c4f92015-10-27 01:28:07 +0000108; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
109; CHECK-NEXT: andps %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000110; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000111;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000112 %bc1 = bitcast float %x to i32
113 %and = and i32 %bc1, 3
114 %bc2 = bitcast i32 %and to float
115 ret float %bc2
116}
117
118; Swap operands of the logic op.
119
120define float @f8(float %x) {
121; CHECK-LABEL: f8:
122; CHECK: # BB#0:
Sanjay Patel309c4f92015-10-27 01:28:07 +0000123; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
124; CHECK-NEXT: andps %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000125; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000126;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000127 %bc1 = bitcast float %x to i32
128 %and = and i32 4, %bc1
129 %bc2 = bitcast i32 %and to float
130 ret float %bc2
131}
132
133; 2 FP operands, int result
134
135define i32 @f9(float %x, float %y) {
136; CHECK-LABEL: f9:
137; CHECK: # BB#0:
Simon Pilgrim8893bd92016-12-07 12:10:49 +0000138; CHECK-NEXT: pand %xmm1, %xmm0
Sanjay Pateldf2495f2015-09-23 17:00:06 +0000139; CHECK-NEXT: movd %xmm0, %eax
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000140; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000141;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000142 %bc1 = bitcast float %x to i32
143 %bc2 = bitcast float %y to i32
144 %and = and i32 %bc1, %bc2
145 ret i32 %and
146}
147
148; 2 FP operands, FP result
149
150define float @f10(float %x, float %y) {
151; CHECK-LABEL: f10:
152; CHECK: # BB#0:
Sanjay Pateldf2495f2015-09-23 17:00:06 +0000153; CHECK-NEXT: andps %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000154; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000155;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000156 %bc1 = bitcast float %x to i32
157 %bc2 = bitcast float %y to i32
158 %and = and i32 %bc1, %bc2
159 %bc3 = bitcast i32 %and to float
160 ret float %bc3
161}
162
163define float @or(float %x, float %y) {
164; CHECK-LABEL: or:
165; CHECK: # BB#0:
Sanjay Patelaba37552015-09-23 18:19:07 +0000166; CHECK-NEXT: orps %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000167; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000168;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000169 %bc1 = bitcast float %x to i32
170 %bc2 = bitcast float %y to i32
171 %and = or i32 %bc1, %bc2
172 %bc3 = bitcast i32 %and to float
173 ret float %bc3
174}
175
176define float @xor(float %x, float %y) {
177; CHECK-LABEL: xor:
178; CHECK: # BB#0:
Sanjay Patel1a653462015-09-23 18:33:42 +0000179; CHECK-NEXT: xorps %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000180; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000181;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000182 %bc1 = bitcast float %x to i32
183 %bc2 = bitcast float %y to i32
184 %and = xor i32 %bc1, %bc2
185 %bc3 = bitcast i32 %and to float
186 ret float %bc3
187}
188
Sanjay Patel28d15982015-10-26 23:52:42 +0000189define float @f7_or(float %x) {
190; CHECK-LABEL: f7_or:
191; CHECK: # BB#0:
Sanjay Patel309c4f92015-10-27 01:28:07 +0000192; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
193; CHECK-NEXT: orps %xmm1, %xmm0
Sanjay Patel28d15982015-10-26 23:52:42 +0000194; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000195;
Sanjay Patel28d15982015-10-26 23:52:42 +0000196 %bc1 = bitcast float %x to i32
197 %and = or i32 %bc1, 3
198 %bc2 = bitcast i32 %and to float
199 ret float %bc2
200}
201
202define float @f7_xor(float %x) {
203; CHECK-LABEL: f7_xor:
204; CHECK: # BB#0:
Sanjay Patel309c4f92015-10-27 01:28:07 +0000205; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
206; CHECK-NEXT: xorps %xmm1, %xmm0
Sanjay Patel28d15982015-10-26 23:52:42 +0000207; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000208;
Sanjay Patel28d15982015-10-26 23:52:42 +0000209 %bc1 = bitcast float %x to i32
210 %and = xor i32 %bc1, 3
211 %bc2 = bitcast i32 %and to float
212 ret float %bc2
213}
214
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000215; Make sure that doubles work too.
216
217define double @doubles(double %x, double %y) {
218; CHECK-LABEL: doubles:
219; CHECK: # BB#0:
Sanjay Patel7f3d51f2016-11-16 17:42:40 +0000220; CHECK-NEXT: andps %xmm1, %xmm0
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000221; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000222;
Sanjay Patelbab5d6c2015-09-20 15:58:00 +0000223 %bc1 = bitcast double %x to i64
224 %bc2 = bitcast double %y to i64
225 %and = and i64 %bc1, %bc2
226 %bc3 = bitcast i64 %and to double
227 ret double %bc3
228}
229
Sanjay Patel28d15982015-10-26 23:52:42 +0000230define double @f7_double(double %x) {
231; CHECK-LABEL: f7_double:
232; CHECK: # BB#0:
Sanjay Patel309c4f92015-10-27 01:28:07 +0000233; CHECK-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero
Simon Pilgrimd7518892016-12-15 16:05:29 +0000234; CHECK-NEXT: andps %xmm1, %xmm0
Sanjay Patel28d15982015-10-26 23:52:42 +0000235; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000236;
Sanjay Patel28d15982015-10-26 23:52:42 +0000237 %bc1 = bitcast double %x to i64
238 %and = and i64 %bc1, 3
239 %bc2 = bitcast i64 %and to double
240 ret double %bc2
241}
242
243; Grabbing the sign bit is a special case that could be handled
244; by movmskps/movmskpd, but if we're not shifting it over, then
245; a simple FP logic op is cheaper.
246
247define float @movmsk(float %x) {
248; CHECK-LABEL: movmsk:
249; CHECK: # BB#0:
Sanjay Patel309c4f92015-10-27 01:28:07 +0000250; CHECK-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero
251; CHECK-NEXT: andps %xmm1, %xmm0
Sanjay Patel28d15982015-10-26 23:52:42 +0000252; CHECK-NEXT: retq
Sanjay Patelaaf43042016-11-15 23:09:53 +0000253;
Sanjay Patel28d15982015-10-26 23:52:42 +0000254 %bc1 = bitcast float %x to i32
255 %and = and i32 %bc1, 2147483648
256 %bc2 = bitcast i32 %and to float
257 ret float %bc2
258}
259
Sanjay Patel13d57b92016-05-04 19:06:03 +0000260define double @bitcast_fabs(double %x) {
261; CHECK-LABEL: bitcast_fabs:
262; CHECK: # BB#0:
Craig Topper9bd62412016-08-09 03:06:33 +0000263; CHECK-NEXT: andps {{.*}}(%rip), %xmm0
Sanjay Patel13d57b92016-05-04 19:06:03 +0000264; CHECK-NEXT: retq
265;
266 %bc1 = bitcast double %x to i64
267 %and = and i64 %bc1, 9223372036854775807
268 %bc2 = bitcast i64 %and to double
269 ret double %bc2
270}
271
272define float @bitcast_fneg(float %x) {
273; CHECK-LABEL: bitcast_fneg:
274; CHECK: # BB#0:
Sanjay Patelb114fd62016-06-10 20:33:50 +0000275; CHECK-NEXT: xorps {{.*}}(%rip), %xmm0
Sanjay Patel13d57b92016-05-04 19:06:03 +0000276; CHECK-NEXT: retq
277;
278 %bc1 = bitcast float %x to i32
279 %xor = xor i32 %bc1, 2147483648
280 %bc2 = bitcast i32 %xor to float
281 ret float %bc2
282}
283
284define <2 x double> @bitcast_fabs_vec(<2 x double> %x) {
285; CHECK-LABEL: bitcast_fabs_vec:
286; CHECK: # BB#0:
287; CHECK-NEXT: andps {{.*}}(%rip), %xmm0
288; CHECK-NEXT: retq
289;
290 %bc1 = bitcast <2 x double> %x to <2 x i64>
291 %and = and <2 x i64> %bc1, <i64 9223372036854775807, i64 9223372036854775807>
292 %bc2 = bitcast <2 x i64> %and to <2 x double>
293 ret <2 x double> %bc2
294}
295
296define <4 x float> @bitcast_fneg_vec(<4 x float> %x) {
297; CHECK-LABEL: bitcast_fneg_vec:
298; CHECK: # BB#0:
299; CHECK-NEXT: xorps {{.*}}(%rip), %xmm0
300; CHECK-NEXT: retq
301;
302 %bc1 = bitcast <4 x float> %x to <4 x i32>
303 %xor = xor <4 x i32> %bc1, <i32 2147483648, i32 2147483648, i32 2147483648, i32 2147483648>
304 %bc2 = bitcast <4 x i32> %xor to <4 x float>
305 ret <4 x float> %bc2
306}
307