llvm.org GIT mirror llvm / 4c4d4fd
[NFC][Codegen] Add tests for hoisting and-by-const from "logical shift", when then eq-comparing with 0 This was initially reported as: https://reviews.llvm.org/D62818 https://rise4fun.com/Alive/oPH git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@362455 91177308-0d34-0410-b5e6-96231b3b80d8 Roman Lebedev 3 months ago
6 changed file(s) with 4931 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s --check-prefixes=CHECK,AARCH64
2
3 ; We are looking for the following pattern here:
4 ; (X & (C l>> Y)) ==/!= 0
5 ; It may be optimal to hoist the constant:
6 ; ((X << Y) & C) ==/!= 0
7
8 ;------------------------------------------------------------------------------;
9 ; A few scalar test
10 ;------------------------------------------------------------------------------;
11
12 ; i8 scalar
13
14 define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
15 ; CHECK-LABEL: scalar_i8_signbit_eq:
16 ; CHECK: // %bb.0:
17 ; CHECK-NEXT: mov w8, #128
18 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
19 ; CHECK-NEXT: lsr w8, w8, w1
20 ; CHECK-NEXT: and w8, w8, w0
21 ; CHECK-NEXT: tst w8, #0xff
22 ; CHECK-NEXT: cset w0, eq
23 ; CHECK-NEXT: ret
24 %t0 = lshr i8 128, %y
25 %t1 = and i8 %t0, %x
26 %res = icmp eq i8 %t1, 0
27 ret i1 %res
28 }
29
30 define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
31 ; CHECK-LABEL: scalar_i8_lowestbit_eq:
32 ; CHECK: // %bb.0:
33 ; CHECK-NEXT: mov w8, #1
34 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
35 ; CHECK-NEXT: lsr w8, w8, w1
36 ; CHECK-NEXT: and w8, w8, w0
37 ; CHECK-NEXT: tst w8, #0xff
38 ; CHECK-NEXT: cset w0, eq
39 ; CHECK-NEXT: ret
40 %t0 = lshr i8 1, %y
41 %t1 = and i8 %t0, %x
42 %res = icmp eq i8 %t1, 0
43 ret i1 %res
44 }
45
46 define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
47 ; CHECK-LABEL: scalar_i8_bitsinmiddle_eq:
48 ; CHECK: // %bb.0:
49 ; CHECK-NEXT: mov w8, #24
50 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
51 ; CHECK-NEXT: lsr w8, w8, w1
52 ; CHECK-NEXT: and w8, w8, w0
53 ; CHECK-NEXT: tst w8, #0xff
54 ; CHECK-NEXT: cset w0, eq
55 ; CHECK-NEXT: ret
56 %t0 = lshr i8 24, %y
57 %t1 = and i8 %t0, %x
58 %res = icmp eq i8 %t1, 0
59 ret i1 %res
60 }
61
62 ; i16 scalar
63
64 define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
65 ; CHECK-LABEL: scalar_i16_signbit_eq:
66 ; CHECK: // %bb.0:
67 ; CHECK-NEXT: mov w8, #32768
68 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
69 ; CHECK-NEXT: lsr w8, w8, w1
70 ; CHECK-NEXT: and w8, w8, w0
71 ; CHECK-NEXT: tst w8, #0xffff
72 ; CHECK-NEXT: cset w0, eq
73 ; CHECK-NEXT: ret
74 %t0 = lshr i16 32768, %y
75 %t1 = and i16 %t0, %x
76 %res = icmp eq i16 %t1, 0
77 ret i1 %res
78 }
79
80 define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
81 ; CHECK-LABEL: scalar_i16_lowestbit_eq:
82 ; CHECK: // %bb.0:
83 ; CHECK-NEXT: mov w8, #1
84 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
85 ; CHECK-NEXT: lsr w8, w8, w1
86 ; CHECK-NEXT: and w8, w8, w0
87 ; CHECK-NEXT: tst w8, #0xffff
88 ; CHECK-NEXT: cset w0, eq
89 ; CHECK-NEXT: ret
90 %t0 = lshr i16 1, %y
91 %t1 = and i16 %t0, %x
92 %res = icmp eq i16 %t1, 0
93 ret i1 %res
94 }
95
96 define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
97 ; CHECK-LABEL: scalar_i16_bitsinmiddle_eq:
98 ; CHECK: // %bb.0:
99 ; CHECK-NEXT: mov w8, #4080
100 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
101 ; CHECK-NEXT: lsr w8, w8, w1
102 ; CHECK-NEXT: and w8, w8, w0
103 ; CHECK-NEXT: tst w8, #0xffff
104 ; CHECK-NEXT: cset w0, eq
105 ; CHECK-NEXT: ret
106 %t0 = lshr i16 4080, %y
107 %t1 = and i16 %t0, %x
108 %res = icmp eq i16 %t1, 0
109 ret i1 %res
110 }
111
112 ; i32 scalar
113
114 define i1 @scalar_i32_signbit_eq(i32 %x, i32 %y) nounwind {
115 ; CHECK-LABEL: scalar_i32_signbit_eq:
116 ; CHECK: // %bb.0:
117 ; CHECK-NEXT: mov w8, #-2147483648
118 ; CHECK-NEXT: lsr w8, w8, w1
119 ; CHECK-NEXT: tst w8, w0
120 ; CHECK-NEXT: cset w0, eq
121 ; CHECK-NEXT: ret
122 %t0 = lshr i32 2147483648, %y
123 %t1 = and i32 %t0, %x
124 %res = icmp eq i32 %t1, 0
125 ret i1 %res
126 }
127
128 define i1 @scalar_i32_lowestbit_eq(i32 %x, i32 %y) nounwind {
129 ; CHECK-LABEL: scalar_i32_lowestbit_eq:
130 ; CHECK: // %bb.0:
131 ; CHECK-NEXT: mov w8, #1
132 ; CHECK-NEXT: lsr w8, w8, w1
133 ; CHECK-NEXT: tst w8, w0
134 ; CHECK-NEXT: cset w0, eq
135 ; CHECK-NEXT: ret
136 %t0 = lshr i32 1, %y
137 %t1 = and i32 %t0, %x
138 %res = icmp eq i32 %t1, 0
139 ret i1 %res
140 }
141
142 define i1 @scalar_i32_bitsinmiddle_eq(i32 %x, i32 %y) nounwind {
143 ; CHECK-LABEL: scalar_i32_bitsinmiddle_eq:
144 ; CHECK: // %bb.0:
145 ; CHECK-NEXT: mov w8, #16776960
146 ; CHECK-NEXT: lsr w8, w8, w1
147 ; CHECK-NEXT: tst w8, w0
148 ; CHECK-NEXT: cset w0, eq
149 ; CHECK-NEXT: ret
150 %t0 = lshr i32 16776960, %y
151 %t1 = and i32 %t0, %x
152 %res = icmp eq i32 %t1, 0
153 ret i1 %res
154 }
155
156 ; i64 scalar
157
158 define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
159 ; CHECK-LABEL: scalar_i64_signbit_eq:
160 ; CHECK: // %bb.0:
161 ; CHECK-NEXT: mov x8, #-9223372036854775808
162 ; CHECK-NEXT: lsr x8, x8, x1
163 ; CHECK-NEXT: tst x8, x0
164 ; CHECK-NEXT: cset w0, eq
165 ; CHECK-NEXT: ret
166 %t0 = lshr i64 9223372036854775808, %y
167 %t1 = and i64 %t0, %x
168 %res = icmp eq i64 %t1, 0
169 ret i1 %res
170 }
171
172 define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
173 ; CHECK-LABEL: scalar_i64_lowestbit_eq:
174 ; CHECK: // %bb.0:
175 ; CHECK-NEXT: mov w8, #1
176 ; CHECK-NEXT: lsr x8, x8, x1
177 ; CHECK-NEXT: tst x8, x0
178 ; CHECK-NEXT: cset w0, eq
179 ; CHECK-NEXT: ret
180 %t0 = lshr i64 1, %y
181 %t1 = and i64 %t0, %x
182 %res = icmp eq i64 %t1, 0
183 ret i1 %res
184 }
185
186 define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
187 ; CHECK-LABEL: scalar_i64_bitsinmiddle_eq:
188 ; CHECK: // %bb.0:
189 ; CHECK-NEXT: mov x8, #281474976645120
190 ; CHECK-NEXT: lsr x8, x8, x1
191 ; CHECK-NEXT: tst x8, x0
192 ; CHECK-NEXT: cset w0, eq
193 ; CHECK-NEXT: ret
194 %t0 = lshr i64 281474976645120, %y
195 %t1 = and i64 %t0, %x
196 %res = icmp eq i64 %t1, 0
197 ret i1 %res
198 }
199
200 ;------------------------------------------------------------------------------;
201 ; A few trivial vector tests
202 ;------------------------------------------------------------------------------;
203
204 define <4 x i1> @vec_4xi32_splat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
205 ; CHECK-LABEL: vec_4xi32_splat_eq:
206 ; CHECK: // %bb.0:
207 ; CHECK-NEXT: neg v1.4s, v1.4s
208 ; CHECK-NEXT: movi v2.4s, #1
209 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
210 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
211 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
212 ; CHECK-NEXT: xtn v0.4h, v0.4s
213 ; CHECK-NEXT: ret
214 %t0 = lshr <4 x i32> , %y
215 %t1 = and <4 x i32> %t0, %x
216 %res = icmp eq <4 x i32> %t1,
217 ret <4 x i1> %res
218 }
219
220 define <4 x i1> @vec_4xi32_nonsplat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
221 ; CHECK-LABEL: vec_4xi32_nonsplat_eq:
222 ; CHECK: // %bb.0:
223 ; CHECK-NEXT: adrp x8, .LCPI13_0
224 ; CHECK-NEXT: ldr q2, [x8, :lo12:.LCPI13_0]
225 ; CHECK-NEXT: neg v1.4s, v1.4s
226 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
227 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
228 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
229 ; CHECK-NEXT: xtn v0.4h, v0.4s
230 ; CHECK-NEXT: ret
231 %t0 = lshr <4 x i32> , %y
232 %t1 = and <4 x i32> %t0, %x
233 %res = icmp eq <4 x i32> %t1,
234 ret <4 x i1> %res
235 }
236
237 define <4 x i1> @vec_4xi32_nonsplat_undef0_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
238 ; CHECK-LABEL: vec_4xi32_nonsplat_undef0_eq:
239 ; CHECK: // %bb.0:
240 ; CHECK-NEXT: neg v1.4s, v1.4s
241 ; CHECK-NEXT: movi v2.4s, #1
242 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
243 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
244 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
245 ; CHECK-NEXT: xtn v0.4h, v0.4s
246 ; CHECK-NEXT: ret
247 %t0 = lshr <4 x i32> , %y
248 %t1 = and <4 x i32> %t0, %x
249 %res = icmp eq <4 x i32> %t1,
250 ret <4 x i1> %res
251 }
252 define <4 x i1> @vec_4xi32_nonsplat_undef1_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
253 ; CHECK-LABEL: vec_4xi32_nonsplat_undef1_eq:
254 ; CHECK: // %bb.0:
255 ; CHECK-NEXT: neg v1.4s, v1.4s
256 ; CHECK-NEXT: movi v2.4s, #1
257 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
258 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
259 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
260 ; CHECK-NEXT: xtn v0.4h, v0.4s
261 ; CHECK-NEXT: ret
262 %t0 = lshr <4 x i32> , %y
263 %t1 = and <4 x i32> %t0, %x
264 %res = icmp eq <4 x i32> %t1,
265 ret <4 x i1> %res
266 }
267 define <4 x i1> @vec_4xi32_nonsplat_undef2_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
268 ; CHECK-LABEL: vec_4xi32_nonsplat_undef2_eq:
269 ; CHECK: // %bb.0:
270 ; CHECK-NEXT: neg v1.4s, v1.4s
271 ; CHECK-NEXT: movi v2.4s, #1
272 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
273 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
274 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
275 ; CHECK-NEXT: xtn v0.4h, v0.4s
276 ; CHECK-NEXT: ret
277 %t0 = lshr <4 x i32> , %y
278 %t1 = and <4 x i32> %t0, %x
279 %res = icmp eq <4 x i32> %t1,
280 ret <4 x i1> %res
281 }
282
283 ;------------------------------------------------------------------------------;
284 ; A special tests
285 ;------------------------------------------------------------------------------;
286
287 define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
288 ; CHECK-LABEL: scalar_i8_signbit_ne:
289 ; CHECK: // %bb.0:
290 ; CHECK-NEXT: mov w8, #128
291 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
292 ; CHECK-NEXT: lsr w8, w8, w1
293 ; CHECK-NEXT: and w8, w8, w0
294 ; CHECK-NEXT: tst w8, #0xff
295 ; CHECK-NEXT: cset w0, ne
296 ; CHECK-NEXT: ret
297 %t0 = lshr i8 128, %y
298 %t1 = and i8 %t0, %x
299 %res = icmp ne i8 %t1, 0 ; we are perfectly happy with 'ne' predicate
300 ret i1 %res
301 }
302
303 ;------------------------------------------------------------------------------;
304 ; A few negative tests
305 ;------------------------------------------------------------------------------;
306
307 define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
308 ; CHECK-LABEL: negative_scalar_i8_bitsinmiddle_slt:
309 ; CHECK: // %bb.0:
310 ; CHECK-NEXT: mov w8, #24
311 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
312 ; CHECK-NEXT: lsr w8, w8, w1
313 ; CHECK-NEXT: and w8, w8, w0
314 ; CHECK-NEXT: sxtb w8, w8
315 ; CHECK-NEXT: cmp w8, #0 // =0
316 ; CHECK-NEXT: cset w0, lt
317 ; CHECK-NEXT: ret
318 %t0 = lshr i8 24, %y
319 %t1 = and i8 %t0, %x
320 %res = icmp slt i8 %t1, 0
321 ret i1 %res
322 }
323
324 define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
325 ; CHECK-LABEL: scalar_i8_signbit_eq_with_nonzero:
326 ; CHECK: // %bb.0:
327 ; CHECK-NEXT: mov w8, #128
328 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
329 ; CHECK-NEXT: lsr w8, w8, w1
330 ; CHECK-NEXT: and w8, w8, w0
331 ; CHECK-NEXT: and w8, w8, #0xff
332 ; CHECK-NEXT: cmp w8, #1 // =1
333 ; CHECK-NEXT: cset w0, eq
334 ; CHECK-NEXT: ret
335 %t0 = lshr i8 128, %y
336 %t1 = and i8 %t0, %x
337 %res = icmp eq i8 %t1, 1 ; should be comparing with 0
338 ret i1 %res
339 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=aarch64-unknown-unknown < %s | FileCheck %s --check-prefixes=CHECK,AARCH64
2
3 ; We are looking for the following pattern here:
4 ; (X & (C << Y)) ==/!= 0
5 ; It may be optimal to hoist the constant:
6 ; ((X l>> Y) & C) ==/!= 0
7
8 ;------------------------------------------------------------------------------;
9 ; A few scalar test
10 ;------------------------------------------------------------------------------;
11
12 ; i8 scalar
13
14 define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
15 ; CHECK-LABEL: scalar_i8_signbit_eq:
16 ; CHECK: // %bb.0:
17 ; CHECK-NEXT: mov w8, #-128
18 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
19 ; CHECK-NEXT: lsl w8, w8, w1
20 ; CHECK-NEXT: and w8, w8, w0
21 ; CHECK-NEXT: tst w8, #0xff
22 ; CHECK-NEXT: cset w0, eq
23 ; CHECK-NEXT: ret
24 %t0 = shl i8 128, %y
25 %t1 = and i8 %t0, %x
26 %res = icmp eq i8 %t1, 0
27 ret i1 %res
28 }
29
30 define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
31 ; CHECK-LABEL: scalar_i8_lowestbit_eq:
32 ; CHECK: // %bb.0:
33 ; CHECK-NEXT: mov w8, #1
34 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
35 ; CHECK-NEXT: lsl w8, w8, w1
36 ; CHECK-NEXT: and w8, w8, w0
37 ; CHECK-NEXT: tst w8, #0xff
38 ; CHECK-NEXT: cset w0, eq
39 ; CHECK-NEXT: ret
40 %t0 = shl i8 1, %y
41 %t1 = and i8 %t0, %x
42 %res = icmp eq i8 %t1, 0
43 ret i1 %res
44 }
45
46 define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
47 ; CHECK-LABEL: scalar_i8_bitsinmiddle_eq:
48 ; CHECK: // %bb.0:
49 ; CHECK-NEXT: mov w8, #24
50 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
51 ; CHECK-NEXT: lsl w8, w8, w1
52 ; CHECK-NEXT: and w8, w8, w0
53 ; CHECK-NEXT: tst w8, #0xff
54 ; CHECK-NEXT: cset w0, eq
55 ; CHECK-NEXT: ret
56 %t0 = shl i8 24, %y
57 %t1 = and i8 %t0, %x
58 %res = icmp eq i8 %t1, 0
59 ret i1 %res
60 }
61
62 ; i16 scalar
63
64 define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
65 ; CHECK-LABEL: scalar_i16_signbit_eq:
66 ; CHECK: // %bb.0:
67 ; CHECK-NEXT: mov w8, #-32768
68 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
69 ; CHECK-NEXT: lsl w8, w8, w1
70 ; CHECK-NEXT: and w8, w8, w0
71 ; CHECK-NEXT: tst w8, #0xffff
72 ; CHECK-NEXT: cset w0, eq
73 ; CHECK-NEXT: ret
74 %t0 = shl i16 32768, %y
75 %t1 = and i16 %t0, %x
76 %res = icmp eq i16 %t1, 0
77 ret i1 %res
78 }
79
80 define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
81 ; CHECK-LABEL: scalar_i16_lowestbit_eq:
82 ; CHECK: // %bb.0:
83 ; CHECK-NEXT: mov w8, #1
84 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
85 ; CHECK-NEXT: lsl w8, w8, w1
86 ; CHECK-NEXT: and w8, w8, w0
87 ; CHECK-NEXT: tst w8, #0xffff
88 ; CHECK-NEXT: cset w0, eq
89 ; CHECK-NEXT: ret
90 %t0 = shl i16 1, %y
91 %t1 = and i16 %t0, %x
92 %res = icmp eq i16 %t1, 0
93 ret i1 %res
94 }
95
96 define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
97 ; CHECK-LABEL: scalar_i16_bitsinmiddle_eq:
98 ; CHECK: // %bb.0:
99 ; CHECK-NEXT: mov w8, #4080
100 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
101 ; CHECK-NEXT: lsl w8, w8, w1
102 ; CHECK-NEXT: and w8, w8, w0
103 ; CHECK-NEXT: tst w8, #0xffff
104 ; CHECK-NEXT: cset w0, eq
105 ; CHECK-NEXT: ret
106 %t0 = shl i16 4080, %y
107 %t1 = and i16 %t0, %x
108 %res = icmp eq i16 %t1, 0
109 ret i1 %res
110 }
111
112 ; i32 scalar
113
114 define i1 @scalar_i32_signbit_eq(i32 %x, i32 %y) nounwind {
115 ; CHECK-LABEL: scalar_i32_signbit_eq:
116 ; CHECK: // %bb.0:
117 ; CHECK-NEXT: mov w8, #-2147483648
118 ; CHECK-NEXT: lsl w8, w8, w1
119 ; CHECK-NEXT: tst w8, w0
120 ; CHECK-NEXT: cset w0, eq
121 ; CHECK-NEXT: ret
122 %t0 = shl i32 2147483648, %y
123 %t1 = and i32 %t0, %x
124 %res = icmp eq i32 %t1, 0
125 ret i1 %res
126 }
127
128 define i1 @scalar_i32_lowestbit_eq(i32 %x, i32 %y) nounwind {
129 ; CHECK-LABEL: scalar_i32_lowestbit_eq:
130 ; CHECK: // %bb.0:
131 ; CHECK-NEXT: mov w8, #1
132 ; CHECK-NEXT: lsl w8, w8, w1
133 ; CHECK-NEXT: tst w8, w0
134 ; CHECK-NEXT: cset w0, eq
135 ; CHECK-NEXT: ret
136 %t0 = shl i32 1, %y
137 %t1 = and i32 %t0, %x
138 %res = icmp eq i32 %t1, 0
139 ret i1 %res
140 }
141
142 define i1 @scalar_i32_bitsinmiddle_eq(i32 %x, i32 %y) nounwind {
143 ; CHECK-LABEL: scalar_i32_bitsinmiddle_eq:
144 ; CHECK: // %bb.0:
145 ; CHECK-NEXT: mov w8, #16776960
146 ; CHECK-NEXT: lsl w8, w8, w1
147 ; CHECK-NEXT: tst w8, w0
148 ; CHECK-NEXT: cset w0, eq
149 ; CHECK-NEXT: ret
150 %t0 = shl i32 16776960, %y
151 %t1 = and i32 %t0, %x
152 %res = icmp eq i32 %t1, 0
153 ret i1 %res
154 }
155
156 ; i64 scalar
157
158 define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
159 ; CHECK-LABEL: scalar_i64_signbit_eq:
160 ; CHECK: // %bb.0:
161 ; CHECK-NEXT: mov x8, #-9223372036854775808
162 ; CHECK-NEXT: lsl x8, x8, x1
163 ; CHECK-NEXT: tst x8, x0
164 ; CHECK-NEXT: cset w0, eq
165 ; CHECK-NEXT: ret
166 %t0 = shl i64 9223372036854775808, %y
167 %t1 = and i64 %t0, %x
168 %res = icmp eq i64 %t1, 0
169 ret i1 %res
170 }
171
172 define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
173 ; CHECK-LABEL: scalar_i64_lowestbit_eq:
174 ; CHECK: // %bb.0:
175 ; CHECK-NEXT: mov w8, #1
176 ; CHECK-NEXT: lsl x8, x8, x1
177 ; CHECK-NEXT: tst x8, x0
178 ; CHECK-NEXT: cset w0, eq
179 ; CHECK-NEXT: ret
180 %t0 = shl i64 1, %y
181 %t1 = and i64 %t0, %x
182 %res = icmp eq i64 %t1, 0
183 ret i1 %res
184 }
185
186 define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
187 ; CHECK-LABEL: scalar_i64_bitsinmiddle_eq:
188 ; CHECK: // %bb.0:
189 ; CHECK-NEXT: mov x8, #281474976645120
190 ; CHECK-NEXT: lsl x8, x8, x1
191 ; CHECK-NEXT: tst x8, x0
192 ; CHECK-NEXT: cset w0, eq
193 ; CHECK-NEXT: ret
194 %t0 = shl i64 281474976645120, %y
195 %t1 = and i64 %t0, %x
196 %res = icmp eq i64 %t1, 0
197 ret i1 %res
198 }
199
200 ;------------------------------------------------------------------------------;
201 ; A few trivial vector tests
202 ;------------------------------------------------------------------------------;
203
204 define <4 x i1> @vec_4xi32_splat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
205 ; CHECK-LABEL: vec_4xi32_splat_eq:
206 ; CHECK: // %bb.0:
207 ; CHECK-NEXT: movi v2.4s, #1
208 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
209 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
210 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
211 ; CHECK-NEXT: xtn v0.4h, v0.4s
212 ; CHECK-NEXT: ret
213 %t0 = shl <4 x i32> , %y
214 %t1 = and <4 x i32> %t0, %x
215 %res = icmp eq <4 x i32> %t1,
216 ret <4 x i1> %res
217 }
218
219 define <4 x i1> @vec_4xi32_nonsplat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
220 ; CHECK-LABEL: vec_4xi32_nonsplat_eq:
221 ; CHECK: // %bb.0:
222 ; CHECK-NEXT: adrp x8, .LCPI13_0
223 ; CHECK-NEXT: ldr q2, [x8, :lo12:.LCPI13_0]
224 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
225 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
226 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
227 ; CHECK-NEXT: xtn v0.4h, v0.4s
228 ; CHECK-NEXT: ret
229 %t0 = shl <4 x i32> , %y
230 %t1 = and <4 x i32> %t0, %x
231 %res = icmp eq <4 x i32> %t1,
232 ret <4 x i1> %res
233 }
234
235 define <4 x i1> @vec_4xi32_nonsplat_undef0_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
236 ; CHECK-LABEL: vec_4xi32_nonsplat_undef0_eq:
237 ; CHECK: // %bb.0:
238 ; CHECK-NEXT: movi v2.4s, #1
239 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
240 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
241 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
242 ; CHECK-NEXT: xtn v0.4h, v0.4s
243 ; CHECK-NEXT: ret
244 %t0 = shl <4 x i32> , %y
245 %t1 = and <4 x i32> %t0, %x
246 %res = icmp eq <4 x i32> %t1,
247 ret <4 x i1> %res
248 }
249 define <4 x i1> @vec_4xi32_nonsplat_undef1_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
250 ; CHECK-LABEL: vec_4xi32_nonsplat_undef1_eq:
251 ; CHECK: // %bb.0:
252 ; CHECK-NEXT: movi v2.4s, #1
253 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
254 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
255 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
256 ; CHECK-NEXT: xtn v0.4h, v0.4s
257 ; CHECK-NEXT: ret
258 %t0 = shl <4 x i32> , %y
259 %t1 = and <4 x i32> %t0, %x
260 %res = icmp eq <4 x i32> %t1,
261 ret <4 x i1> %res
262 }
263 define <4 x i1> @vec_4xi32_nonsplat_undef2_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
264 ; CHECK-LABEL: vec_4xi32_nonsplat_undef2_eq:
265 ; CHECK: // %bb.0:
266 ; CHECK-NEXT: movi v2.4s, #1
267 ; CHECK-NEXT: ushl v1.4s, v2.4s, v1.4s
268 ; CHECK-NEXT: and v0.16b, v1.16b, v0.16b
269 ; CHECK-NEXT: cmeq v0.4s, v0.4s, #0
270 ; CHECK-NEXT: xtn v0.4h, v0.4s
271 ; CHECK-NEXT: ret
272 %t0 = shl <4 x i32> , %y
273 %t1 = and <4 x i32> %t0, %x
274 %res = icmp eq <4 x i32> %t1,
275 ret <4 x i1> %res
276 }
277
278 ;------------------------------------------------------------------------------;
279 ; A special tests
280 ;------------------------------------------------------------------------------;
281
282 define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
283 ; CHECK-LABEL: scalar_i8_signbit_ne:
284 ; CHECK: // %bb.0:
285 ; CHECK-NEXT: mov w8, #-128
286 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
287 ; CHECK-NEXT: lsl w8, w8, w1
288 ; CHECK-NEXT: and w8, w8, w0
289 ; CHECK-NEXT: tst w8, #0xff
290 ; CHECK-NEXT: cset w0, ne
291 ; CHECK-NEXT: ret
292 %t0 = shl i8 128, %y
293 %t1 = and i8 %t0, %x
294 %res = icmp ne i8 %t1, 0 ; we are perfectly happy with 'ne' predicate
295 ret i1 %res
296 }
297
298 ;------------------------------------------------------------------------------;
299 ; A few negative tests
300 ;------------------------------------------------------------------------------;
301
302 define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
303 ; CHECK-LABEL: negative_scalar_i8_bitsinmiddle_slt:
304 ; CHECK: // %bb.0:
305 ; CHECK-NEXT: mov w8, #24
306 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
307 ; CHECK-NEXT: lsl w8, w8, w1
308 ; CHECK-NEXT: and w8, w8, w0
309 ; CHECK-NEXT: sxtb w8, w8
310 ; CHECK-NEXT: cmp w8, #0 // =0
311 ; CHECK-NEXT: cset w0, lt
312 ; CHECK-NEXT: ret
313 %t0 = shl i8 24, %y
314 %t1 = and i8 %t0, %x
315 %res = icmp slt i8 %t1, 0
316 ret i1 %res
317 }
318
319 define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
320 ; CHECK-LABEL: scalar_i8_signbit_eq_with_nonzero:
321 ; CHECK: // %bb.0:
322 ; CHECK-NEXT: mov w8, #-128
323 ; CHECK-NEXT: // kill: def $w1 killed $w1 def $x1
324 ; CHECK-NEXT: lsl w8, w8, w1
325 ; CHECK-NEXT: and w8, w8, w0
326 ; CHECK-NEXT: and w8, w8, #0xff
327 ; CHECK-NEXT: cmp w8, #1 // =1
328 ; CHECK-NEXT: cset w0, eq
329 ; CHECK-NEXT: ret
330 %t0 = shl i8 128, %y
331 %t1 = and i8 %t0, %x
332 %res = icmp eq i8 %t1, 1 ; should be comparing with 0
333 ret i1 %res
334 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=armv6 < %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM6
2 ; RUN: llc -mtriple=armv7 < %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM78,ARM7
3 ; RUN: llc -mtriple=armv8a < %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM78,ARM8
4 ; RUN: llc -mtriple=thumbv6 < %s | FileCheck %s --check-prefixes=CHECK,THUMB,THUMB6
5 ; RUN: llc -mtriple=thumbv7 < %s | FileCheck %s --check-prefixes=CHECK,THUMB,THUMB78,THUMB7
6 ; RUN: llc -mtriple=thumbv8-eabi < %s | FileCheck %s --check-prefixes=CHECK,THUMB,THUMB78,THUMB8
7
8 ; We are looking for the following pattern here:
9 ; (X & (C l>> Y)) ==/!= 0
10 ; It may be optimal to hoist the constant:
11 ; ((X << Y) & C) ==/!= 0
12
13 ;------------------------------------------------------------------------------;
14 ; A few scalar test
15 ;------------------------------------------------------------------------------;
16
17 ; i8 scalar
18
19 define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
20 ; ARM-LABEL: scalar_i8_signbit_eq:
21 ; ARM: @ %bb.0:
22 ; ARM-NEXT: uxtb r1, r1
23 ; ARM-NEXT: mov r2, #128
24 ; ARM-NEXT: and r0, r0, r2, lsr r1
25 ; ARM-NEXT: uxtb r0, r0
26 ; ARM-NEXT: clz r0, r0
27 ; ARM-NEXT: lsr r0, r0, #5
28 ; ARM-NEXT: bx lr
29 ;
30 ; THUMB6-LABEL: scalar_i8_signbit_eq:
31 ; THUMB6: @ %bb.0:
32 ; THUMB6-NEXT: uxtb r1, r1
33 ; THUMB6-NEXT: movs r2, #128
34 ; THUMB6-NEXT: lsrs r2, r1
35 ; THUMB6-NEXT: ands r2, r0
36 ; THUMB6-NEXT: uxtb r1, r2
37 ; THUMB6-NEXT: rsbs r0, r1, #0
38 ; THUMB6-NEXT: adcs r0, r1
39 ; THUMB6-NEXT: bx lr
40 ;
41 ; THUMB78-LABEL: scalar_i8_signbit_eq:
42 ; THUMB78: @ %bb.0:
43 ; THUMB78-NEXT: uxtb r1, r1
44 ; THUMB78-NEXT: movs r2, #128
45 ; THUMB78-NEXT: lsr.w r1, r2, r1
46 ; THUMB78-NEXT: ands r0, r1
47 ; THUMB78-NEXT: uxtb r0, r0
48 ; THUMB78-NEXT: clz r0, r0
49 ; THUMB78-NEXT: lsrs r0, r0, #5
50 ; THUMB78-NEXT: bx lr
51 %t0 = lshr i8 128, %y
52 %t1 = and i8 %t0, %x
53 %res = icmp eq i8 %t1, 0
54 ret i1 %res
55 }
56
57 define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
58 ; ARM-LABEL: scalar_i8_lowestbit_eq:
59 ; ARM: @ %bb.0:
60 ; ARM-NEXT: uxtb r1, r1
61 ; ARM-NEXT: mov r2, #1
62 ; ARM-NEXT: and r0, r0, r2, lsr r1
63 ; ARM-NEXT: uxtb r0, r0
64 ; ARM-NEXT: clz r0, r0
65 ; ARM-NEXT: lsr r0, r0, #5
66 ; ARM-NEXT: bx lr
67 ;
68 ; THUMB6-LABEL: scalar_i8_lowestbit_eq:
69 ; THUMB6: @ %bb.0:
70 ; THUMB6-NEXT: uxtb r1, r1
71 ; THUMB6-NEXT: movs r2, #1
72 ; THUMB6-NEXT: lsrs r2, r1
73 ; THUMB6-NEXT: ands r2, r0
74 ; THUMB6-NEXT: uxtb r1, r2
75 ; THUMB6-NEXT: rsbs r0, r1, #0
76 ; THUMB6-NEXT: adcs r0, r1
77 ; THUMB6-NEXT: bx lr
78 ;
79 ; THUMB78-LABEL: scalar_i8_lowestbit_eq:
80 ; THUMB78: @ %bb.0:
81 ; THUMB78-NEXT: uxtb r1, r1
82 ; THUMB78-NEXT: movs r2, #1
83 ; THUMB78-NEXT: lsr.w r1, r2, r1
84 ; THUMB78-NEXT: ands r0, r1
85 ; THUMB78-NEXT: uxtb r0, r0
86 ; THUMB78-NEXT: clz r0, r0
87 ; THUMB78-NEXT: lsrs r0, r0, #5
88 ; THUMB78-NEXT: bx lr
89 %t0 = lshr i8 1, %y
90 %t1 = and i8 %t0, %x
91 %res = icmp eq i8 %t1, 0
92 ret i1 %res
93 }
94
95 define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
96 ; ARM-LABEL: scalar_i8_bitsinmiddle_eq:
97 ; ARM: @ %bb.0:
98 ; ARM-NEXT: uxtb r1, r1
99 ; ARM-NEXT: mov r2, #24
100 ; ARM-NEXT: and r0, r0, r2, lsr r1
101 ; ARM-NEXT: uxtb r0, r0
102 ; ARM-NEXT: clz r0, r0
103 ; ARM-NEXT: lsr r0, r0, #5
104 ; ARM-NEXT: bx lr
105 ;
106 ; THUMB6-LABEL: scalar_i8_bitsinmiddle_eq:
107 ; THUMB6: @ %bb.0:
108 ; THUMB6-NEXT: uxtb r1, r1
109 ; THUMB6-NEXT: movs r2, #24
110 ; THUMB6-NEXT: lsrs r2, r1
111 ; THUMB6-NEXT: ands r2, r0
112 ; THUMB6-NEXT: uxtb r1, r2
113 ; THUMB6-NEXT: rsbs r0, r1, #0
114 ; THUMB6-NEXT: adcs r0, r1
115 ; THUMB6-NEXT: bx lr
116 ;
117 ; THUMB78-LABEL: scalar_i8_bitsinmiddle_eq:
118 ; THUMB78: @ %bb.0:
119 ; THUMB78-NEXT: uxtb r1, r1
120 ; THUMB78-NEXT: movs r2, #24
121 ; THUMB78-NEXT: lsr.w r1, r2, r1
122 ; THUMB78-NEXT: ands r0, r1
123 ; THUMB78-NEXT: uxtb r0, r0
124 ; THUMB78-NEXT: clz r0, r0
125 ; THUMB78-NEXT: lsrs r0, r0, #5
126 ; THUMB78-NEXT: bx lr
127 %t0 = lshr i8 24, %y
128 %t1 = and i8 %t0, %x
129 %res = icmp eq i8 %t1, 0
130 ret i1 %res
131 }
132
133 ; i16 scalar
134
135 define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
136 ; ARM-LABEL: scalar_i16_signbit_eq:
137 ; ARM: @ %bb.0:
138 ; ARM-NEXT: uxth r1, r1
139 ; ARM-NEXT: mov r2, #32768
140 ; ARM-NEXT: and r0, r0, r2, lsr r1
141 ; ARM-NEXT: uxth r0, r0
142 ; ARM-NEXT: clz r0, r0
143 ; ARM-NEXT: lsr r0, r0, #5
144 ; ARM-NEXT: bx lr
145 ;
146 ; THUMB6-LABEL: scalar_i16_signbit_eq:
147 ; THUMB6: @ %bb.0:
148 ; THUMB6-NEXT: uxth r1, r1
149 ; THUMB6-NEXT: movs r2, #1
150 ; THUMB6-NEXT: lsls r2, r2, #15
151 ; THUMB6-NEXT: lsrs r2, r1
152 ; THUMB6-NEXT: ands r2, r0
153 ; THUMB6-NEXT: uxth r1, r2
154 ; THUMB6-NEXT: rsbs r0, r1, #0
155 ; THUMB6-NEXT: adcs r0, r1
156 ; THUMB6-NEXT: bx lr
157 ;
158 ; THUMB78-LABEL: scalar_i16_signbit_eq:
159 ; THUMB78: @ %bb.0:
160 ; THUMB78-NEXT: uxth r1, r1
161 ; THUMB78-NEXT: mov.w r2, #32768
162 ; THUMB78-NEXT: lsr.w r1, r2, r1
163 ; THUMB78-NEXT: ands r0, r1
164 ; THUMB78-NEXT: uxth r0, r0
165 ; THUMB78-NEXT: clz r0, r0
166 ; THUMB78-NEXT: lsrs r0, r0, #5
167 ; THUMB78-NEXT: bx lr
168 %t0 = lshr i16 32768, %y
169 %t1 = and i16 %t0, %x
170 %res = icmp eq i16 %t1, 0
171 ret i1 %res
172 }
173
174 define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
175 ; ARM-LABEL: scalar_i16_lowestbit_eq:
176 ; ARM: @ %bb.0:
177 ; ARM-NEXT: uxth r1, r1
178 ; ARM-NEXT: mov r2, #1
179 ; ARM-NEXT: and r0, r0, r2, lsr r1
180 ; ARM-NEXT: uxth r0, r0
181 ; ARM-NEXT: clz r0, r0
182 ; ARM-NEXT: lsr r0, r0, #5
183 ; ARM-NEXT: bx lr
184 ;
185 ; THUMB6-LABEL: scalar_i16_lowestbit_eq:
186 ; THUMB6: @ %bb.0:
187 ; THUMB6-NEXT: uxth r1, r1
188 ; THUMB6-NEXT: movs r2, #1
189 ; THUMB6-NEXT: lsrs r2, r1
190 ; THUMB6-NEXT: ands r2, r0
191 ; THUMB6-NEXT: uxth r1, r2
192 ; THUMB6-NEXT: rsbs r0, r1, #0
193 ; THUMB6-NEXT: adcs r0, r1
194 ; THUMB6-NEXT: bx lr
195 ;
196 ; THUMB78-LABEL: scalar_i16_lowestbit_eq:
197 ; THUMB78: @ %bb.0:
198 ; THUMB78-NEXT: uxth r1, r1
199 ; THUMB78-NEXT: movs r2, #1
200 ; THUMB78-NEXT: lsr.w r1, r2, r1
201 ; THUMB78-NEXT: ands r0, r1
202 ; THUMB78-NEXT: uxth r0, r0
203 ; THUMB78-NEXT: clz r0, r0
204 ; THUMB78-NEXT: lsrs r0, r0, #5
205 ; THUMB78-NEXT: bx lr
206 %t0 = lshr i16 1, %y
207 %t1 = and i16 %t0, %x
208 %res = icmp eq i16 %t1, 0
209 ret i1 %res
210 }
211
212 define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
213 ; ARM-LABEL: scalar_i16_bitsinmiddle_eq:
214 ; ARM: @ %bb.0:
215 ; ARM-NEXT: uxth r1, r1
216 ; ARM-NEXT: mov r2, #4080
217 ; ARM-NEXT: and r0, r0, r2, lsr r1
218 ; ARM-NEXT: uxth r0, r0
219 ; ARM-NEXT: clz r0, r0
220 ; ARM-NEXT: lsr r0, r0, #5
221 ; ARM-NEXT: bx lr
222 ;
223 ; THUMB6-LABEL: scalar_i16_bitsinmiddle_eq:
224 ; THUMB6: @ %bb.0:
225 ; THUMB6-NEXT: uxth r1, r1
226 ; THUMB6-NEXT: movs r2, #255
227 ; THUMB6-NEXT: lsls r2, r2, #4
228 ; THUMB6-NEXT: lsrs r2, r1
229 ; THUMB6-NEXT: ands r2, r0
230 ; THUMB6-NEXT: uxth r1, r2
231 ; THUMB6-NEXT: rsbs r0, r1, #0
232 ; THUMB6-NEXT: adcs r0, r1
233 ; THUMB6-NEXT: bx lr
234 ;
235 ; THUMB78-LABEL: scalar_i16_bitsinmiddle_eq:
236 ; THUMB78: @ %bb.0:
237 ; THUMB78-NEXT: uxth r1, r1
238 ; THUMB78-NEXT: mov.w r2, #4080
239 ; THUMB78-NEXT: lsr.w r1, r2, r1
240 ; THUMB78-NEXT: ands r0, r1
241 ; THUMB78-NEXT: uxth r0, r0
242 ; THUMB78-NEXT: clz r0, r0
243 ; THUMB78-NEXT: lsrs r0, r0, #5
244 ; THUMB78-NEXT: bx lr
245 %t0 = lshr i16 4080, %y
246 %t1 = and i16 %t0, %x
247 %res = icmp eq i16 %t1, 0
248 ret i1 %res
249 }
250
251 ; i32 scalar
252
253 define i1 @scalar_i32_signbit_eq(i32 %x, i32 %y) nounwind {
254 ; ARM-LABEL: scalar_i32_signbit_eq:
255 ; ARM: @ %bb.0:
256 ; ARM-NEXT: mov r2, #-2147483648
257 ; ARM-NEXT: and r0, r0, r2, lsr r1
258 ; ARM-NEXT: clz r0, r0
259 ; ARM-NEXT: lsr r0, r0, #5
260 ; ARM-NEXT: bx lr
261 ;
262 ; THUMB6-LABEL: scalar_i32_signbit_eq:
263 ; THUMB6: @ %bb.0:
264 ; THUMB6-NEXT: movs r2, #1
265 ; THUMB6-NEXT: lsls r2, r2, #31
266 ; THUMB6-NEXT: lsrs r2, r1
267 ; THUMB6-NEXT: ands r2, r0
268 ; THUMB6-NEXT: rsbs r0, r2, #0
269 ; THUMB6-NEXT: adcs r0, r2
270 ; THUMB6-NEXT: bx lr
271 ;
272 ; THUMB78-LABEL: scalar_i32_signbit_eq:
273 ; THUMB78: @ %bb.0:
274 ; THUMB78-NEXT: mov.w r2, #-2147483648
275 ; THUMB78-NEXT: lsr.w r1, r2, r1
276 ; THUMB78-NEXT: ands r0, r1
277 ; THUMB78-NEXT: clz r0, r0
278 ; THUMB78-NEXT: lsrs r0, r0, #5
279 ; THUMB78-NEXT: bx lr
280 %t0 = lshr i32 2147483648, %y
281 %t1 = and i32 %t0, %x
282 %res = icmp eq i32 %t1, 0
283 ret i1 %res
284 }
285
286 define i1 @scalar_i32_lowestbit_eq(i32 %x, i32 %y) nounwind {
287 ; ARM-LABEL: scalar_i32_lowestbit_eq:
288 ; ARM: @ %bb.0:
289 ; ARM-NEXT: mov r2, #1
290 ; ARM-NEXT: and r0, r0, r2, lsr r1
291 ; ARM-NEXT: clz r0, r0
292 ; ARM-NEXT: lsr r0, r0, #5
293 ; ARM-NEXT: bx lr
294 ;
295 ; THUMB6-LABEL: scalar_i32_lowestbit_eq:
296 ; THUMB6: @ %bb.0:
297 ; THUMB6-NEXT: movs r2, #1
298 ; THUMB6-NEXT: lsrs r2, r1
299 ; THUMB6-NEXT: ands r2, r0
300 ; THUMB6-NEXT: rsbs r0, r2, #0
301 ; THUMB6-NEXT: adcs r0, r2
302 ; THUMB6-NEXT: bx lr
303 ;
304 ; THUMB78-LABEL: scalar_i32_lowestbit_eq:
305 ; THUMB78: @ %bb.0:
306 ; THUMB78-NEXT: movs r2, #1
307 ; THUMB78-NEXT: lsr.w r1, r2, r1
308 ; THUMB78-NEXT: ands r0, r1
309 ; THUMB78-NEXT: clz r0, r0
310 ; THUMB78-NEXT: lsrs r0, r0, #5
311 ; THUMB78-NEXT: bx lr
312 %t0 = lshr i32 1, %y
313 %t1 = and i32 %t0, %x
314 %res = icmp eq i32 %t1, 0
315 ret i1 %res
316 }
317
318 define i1 @scalar_i32_bitsinmiddle_eq(i32 %x, i32 %y) nounwind {
319 ; ARM6-LABEL: scalar_i32_bitsinmiddle_eq:
320 ; ARM6: @ %bb.0:
321 ; ARM6-NEXT: mov r2, #65280
322 ; ARM6-NEXT: orr r2, r2, #16711680
323 ; ARM6-NEXT: and r0, r0, r2, lsr r1
324 ; ARM6-NEXT: clz r0, r0
325 ; ARM6-NEXT: lsr r0, r0, #5
326 ; ARM6-NEXT: bx lr
327 ;
328 ; ARM78-LABEL: scalar_i32_bitsinmiddle_eq:
329 ; ARM78: @ %bb.0:
330 ; ARM78-NEXT: movw r2, #65280
331 ; ARM78-NEXT: movt r2, #255
332 ; ARM78-NEXT: and r0, r0, r2, lsr r1
333 ; ARM78-NEXT: clz r0, r0
334 ; ARM78-NEXT: lsr r0, r0, #5
335 ; ARM78-NEXT: bx lr
336 ;
337 ; THUMB6-LABEL: scalar_i32_bitsinmiddle_eq:
338 ; THUMB6: @ %bb.0:
339 ; THUMB6-NEXT: ldr r2, .LCPI8_0
340 ; THUMB6-NEXT: lsrs r2, r1
341 ; THUMB6-NEXT: ands r2, r0
342 ; THUMB6-NEXT: rsbs r0, r2, #0
343 ; THUMB6-NEXT: adcs r0, r2
344 ; THUMB6-NEXT: bx lr
345 ; THUMB6-NEXT: .p2align 2
346 ; THUMB6-NEXT: @ %bb.1:
347 ; THUMB6-NEXT: .LCPI8_0:
348 ; THUMB6-NEXT: .long 16776960 @ 0xffff00
349 ;
350 ; THUMB78-LABEL: scalar_i32_bitsinmiddle_eq:
351 ; THUMB78: @ %bb.0:
352 ; THUMB78-NEXT: movw r2, #65280
353 ; THUMB78-NEXT: movt r2, #255
354 ; THUMB78-NEXT: lsr.w r1, r2, r1
355 ; THUMB78-NEXT: ands r0, r1
356 ; THUMB78-NEXT: clz r0, r0
357 ; THUMB78-NEXT: lsrs r0, r0, #5
358 ; THUMB78-NEXT: bx lr
359 %t0 = lshr i32 16776960, %y
360 %t1 = and i32 %t0, %x
361 %res = icmp eq i32 %t1, 0
362 ret i1 %res
363 }
364
365 ; i64 scalar
366
367 define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
368 ; ARM6-LABEL: scalar_i64_signbit_eq:
369 ; ARM6: @ %bb.0:
370 ; ARM6-NEXT: push {r11, lr}
371 ; ARM6-NEXT: mov r12, #-2147483648
372 ; ARM6-NEXT: sub lr, r2, #32
373 ; ARM6-NEXT: lsr r3, r12, r2
374 ; ARM6-NEXT: rsb r2, r2, #32
375 ; ARM6-NEXT: cmp lr, #0
376 ; ARM6-NEXT: lsl r2, r12, r2
377 ; ARM6-NEXT: movge r3, #0
378 ; ARM6-NEXT: lsrge r2, r12, lr
379 ; ARM6-NEXT: and r1, r3, r1
380 ; ARM6-NEXT: and r0, r2, r0
381 ; ARM6-NEXT: orr r0, r0, r1
382 ; ARM6-NEXT: clz r0, r0
383 ; ARM6-NEXT: lsr r0, r0, #5
384 ; ARM6-NEXT: pop {r11, pc}
385 ;
386 ; ARM78-LABEL: scalar_i64_signbit_eq:
387 ; ARM78: @ %bb.0:
388 ; ARM78-NEXT: push {r11, lr}
389 ; ARM78-NEXT: mov r12, #-2147483648
390 ; ARM78-NEXT: sub lr, r2, #32
391 ; ARM78-NEXT: lsr r3, r12, r2
392 ; ARM78-NEXT: rsb r2, r2, #32
393 ; ARM78-NEXT: cmp lr, #0
394 ; ARM78-NEXT: lsl r2, r12, r2
395 ; ARM78-NEXT: movwge r3, #0
396 ; ARM78-NEXT: lsrge r2, r12, lr
397 ; ARM78-NEXT: and r1, r3, r1
398 ; ARM78-NEXT: and r0, r2, r0
399 ; ARM78-NEXT: orr r0, r0, r1
400 ; ARM78-NEXT: clz r0, r0
401 ; ARM78-NEXT: lsr r0, r0, #5
402 ; ARM78-NEXT: pop {r11, pc}
403 ;
404 ; THUMB6-LABEL: scalar_i64_signbit_eq:
405 ; THUMB6: @ %bb.0:
406 ; THUMB6-NEXT: push {r4, r5, r7, lr}
407 ; THUMB6-NEXT: mov r4, r1
408 ; THUMB6-NEXT: mov r5, r0
409 ; THUMB6-NEXT: movs r0, #1
410 ; THUMB6-NEXT: lsls r1, r0, #31
411 ; THUMB6-NEXT: movs r0, #0
412 ; THUMB6-NEXT: bl __lshrdi3
413 ; THUMB6-NEXT: ands r1, r4
414 ; THUMB6-NEXT: ands r0, r5
415 ; THUMB6-NEXT: orrs r0, r1
416 ; THUMB6-NEXT: rsbs r1, r0, #0
417 ; THUMB6-NEXT: adcs r0, r1
418 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
419 ;
420 ; THUMB7-LABEL: scalar_i64_signbit_eq:
421 ; THUMB7: @ %bb.0:
422 ; THUMB7-NEXT: push {r7, lr}
423 ; THUMB7-NEXT: rsb.w r3, r2, #32
424 ; THUMB7-NEXT: mov.w r12, #-2147483648
425 ; THUMB7-NEXT: sub.w lr, r2, #32
426 ; THUMB7-NEXT: lsr.w r2, r12, r2
427 ; THUMB7-NEXT: lsl.w r3, r12, r3
428 ; THUMB7-NEXT: cmp.w lr, #0
429 ; THUMB7-NEXT: it ge
430 ; THUMB7-NEXT: lsrge.w r3, r12, lr
431 ; THUMB7-NEXT: it ge
432 ; THUMB7-NEXT: movge r2, #0
433 ; THUMB7-NEXT: ands r0, r3
434 ; THUMB7-NEXT: ands r1, r2
435 ; THUMB7-NEXT: orrs r0, r1
436 ; THUMB7-NEXT: clz r0, r0
437 ; THUMB7-NEXT: lsrs r0, r0, #5
438 ; THUMB7-NEXT: pop {r7, pc}
439 ;
440 ; THUMB8-LABEL: scalar_i64_signbit_eq:
441 ; THUMB8: @ %bb.0:
442 ; THUMB8-NEXT: .save {r7, lr}
443 ; THUMB8-NEXT: push {r7, lr}
444 ; THUMB8-NEXT: rsb.w r3, r2, #32
445 ; THUMB8-NEXT: sub.w lr, r2, #32
446 ; THUMB8-NEXT: mov.w r12, #-2147483648
447 ; THUMB8-NEXT: cmp.w lr, #0
448 ; THUMB8-NEXT: lsl.w r3, r12, r3
449 ; THUMB8-NEXT: lsr.w r2, r12, r2
450 ; THUMB8-NEXT: it ge
451 ; THUMB8-NEXT: lsrge.w r3, r12, lr
452 ; THUMB8-NEXT: it ge
453 ; THUMB8-NEXT: movge r2, #0
454 ; THUMB8-NEXT: ands r0, r3
455 ; THUMB8-NEXT: ands r1, r2
456 ; THUMB8-NEXT: orrs r0, r1
457 ; THUMB8-NEXT: clz r0, r0
458 ; THUMB8-NEXT: lsrs r0, r0, #5
459 ; THUMB8-NEXT: pop {r7, pc}
460 %t0 = lshr i64 9223372036854775808, %y
461 %t1 = and i64 %t0, %x
462 %res = icmp eq i64 %t1, 0
463 ret i1 %res
464 }
465
466 define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
467 ; ARM6-LABEL: scalar_i64_lowestbit_eq:
468 ; ARM6: @ %bb.0:
469 ; ARM6-NEXT: mov r1, #1
470 ; ARM6-NEXT: lsr r1, r1, r2
471 ; ARM6-NEXT: sub r2, r2, #32
472 ; ARM6-NEXT: cmp r2, #0
473 ; ARM6-NEXT: movge r1, #0
474 ; ARM6-NEXT: and r0, r1, r0
475 ; ARM6-NEXT: clz r0, r0
476 ; ARM6-NEXT: lsr r0, r0, #5
477 ; ARM6-NEXT: bx lr
478 ;
479 ; ARM78-LABEL: scalar_i64_lowestbit_eq:
480 ; ARM78: @ %bb.0:
481 ; ARM78-NEXT: mov r1, #1
482 ; ARM78-NEXT: lsr r1, r1, r2
483 ; ARM78-NEXT: sub r2, r2, #32
484 ; ARM78-NEXT: cmp r2, #0
485 ; ARM78-NEXT: movwge r1, #0
486 ; ARM78-NEXT: and r0, r1, r0
487 ; ARM78-NEXT: clz r0, r0
488 ; ARM78-NEXT: lsr r0, r0, #5
489 ; ARM78-NEXT: bx lr
490 ;
491 ; THUMB6-LABEL: scalar_i64_lowestbit_eq:
492 ; THUMB6: @ %bb.0:
493 ; THUMB6-NEXT: push {r4, r5, r7, lr}
494 ; THUMB6-NEXT: mov r4, r1
495 ; THUMB6-NEXT: mov r5, r0
496 ; THUMB6-NEXT: movs r0, #1
497 ; THUMB6-NEXT: movs r1, #0
498 ; THUMB6-NEXT: bl __lshrdi3
499 ; THUMB6-NEXT: ands r1, r4
500 ; THUMB6-NEXT: ands r0, r5
501 ; THUMB6-NEXT: orrs r0, r1
502 ; THUMB6-NEXT: rsbs r1, r0, #0
503 ; THUMB6-NEXT: adcs r0, r1
504 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
505 ;
506 ; THUMB78-LABEL: scalar_i64_lowestbit_eq:
507 ; THUMB78: @ %bb.0:
508 ; THUMB78-NEXT: movs r1, #1
509 ; THUMB78-NEXT: lsrs r1, r2
510 ; THUMB78-NEXT: subs r2, #32
511 ; THUMB78-NEXT: cmp r2, #0
512 ; THUMB78-NEXT: it ge
513 ; THUMB78-NEXT: movge r1, #0
514 ; THUMB78-NEXT: ands r0, r1
515 ; THUMB78-NEXT: clz r0, r0
516 ; THUMB78-NEXT: lsrs r0, r0, #5
517 ; THUMB78-NEXT: bx lr
518 %t0 = lshr i64 1, %y
519 %t1 = and i64 %t0, %x
520 %res = icmp eq i64 %t1, 0
521 ret i1 %res
522 }
523
524 define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
525 ; ARM6-LABEL: scalar_i64_bitsinmiddle_eq:
526 ; ARM6: @ %bb.0:
527 ; ARM6-NEXT: push {r11, lr}
528 ; ARM6-NEXT: mov r12, #255
529 ; ARM6-NEXT: sub lr, r2, #32
530 ; ARM6-NEXT: orr r12, r12, #65280
531 ; ARM6-NEXT: cmp lr, #0
532 ; ARM6-NEXT: lsr r3, r12, r2
533 ; ARM6-NEXT: movge r3, #0
534 ; ARM6-NEXT: and r1, r3, r1
535 ; ARM6-NEXT: mov r3, #16711680
536 ; ARM6-NEXT: cmp lr, #0
537 ; ARM6-NEXT: orr r3, r3, #-16777216
538 ; ARM6-NEXT: lsr r3, r3, r2
539 ; ARM6-NEXT: rsb r2, r2, #32
540 ; ARM6-NEXT: orr r2, r3, r12, lsl r2
541 ; ARM6-NEXT: lsrge r2, r12, lr
542 ; ARM6-NEXT: and r0, r2, r0
543 ; ARM6-NEXT: orr r0, r0, r1
544 ; ARM6-NEXT: clz r0, r0
545 ; ARM6-NEXT: lsr r0, r0, #5
546 ; ARM6-NEXT: pop {r11, pc}
547 ;
548 ; ARM78-LABEL: scalar_i64_bitsinmiddle_eq:
549 ; ARM78: @ %bb.0:
550 ; ARM78-NEXT: push {r11, lr}
551 ; ARM78-NEXT: movw r12, #65535
552 ; ARM78-NEXT: sub lr, r2, #32
553 ; ARM78-NEXT: lsr r3, r12, r2
554 ; ARM78-NEXT: cmp lr, #0
555 ; ARM78-NEXT: movwge r3, #0
556 ; ARM78-NEXT: and r1, r3, r1
557 ; ARM78-NEXT: movw r3, #0
558 ; ARM78-NEXT: cmp lr, #0
559 ; ARM78-NEXT: movt r3, #65535
560 ; ARM78-NEXT: lsr r3, r3, r2
561 ; ARM78-NEXT: rsb r2, r2, #32
562 ; ARM78-NEXT: orr r2, r3, r12, lsl r2
563 ; ARM78-NEXT: lsrge r2, r12, lr
564 ; ARM78-NEXT: and r0, r2, r0
565 ; ARM78-NEXT: orr r0, r0, r1
566 ; ARM78-NEXT: clz r0, r0
567 ; ARM78-NEXT: lsr r0, r0, #5
568 ; ARM78-NEXT: pop {r11, pc}
569 ;
570 ; THUMB6-LABEL: scalar_i64_bitsinmiddle_eq:
571 ; THUMB6: @ %bb.0:
572 ; THUMB6-NEXT: push {r4, r5, r7, lr}
573 ; THUMB6-NEXT: mov r4, r1
574 ; THUMB6-NEXT: mov r5, r0
575 ; THUMB6-NEXT: ldr r0, .LCPI11_0
576 ; THUMB6-NEXT: ldr r1, .LCPI11_1
577 ; THUMB6-NEXT: bl __lshrdi3
578 ; THUMB6-NEXT: ands r1, r4
579 ; THUMB6-NEXT: ands r0, r5
580 ; THUMB6-NEXT: orrs r0, r1
581 ; THUMB6-NEXT: rsbs r1, r0, #0
582 ; THUMB6-NEXT: adcs r0, r1
583 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
584 ; THUMB6-NEXT: .p2align 2
585 ; THUMB6-NEXT: @ %bb.1:
586 ; THUMB6-NEXT: .LCPI11_0:
587 ; THUMB6-NEXT: .long 4294901760 @ 0xffff0000
588 ; THUMB6-NEXT: .LCPI11_1:
589 ; THUMB6-NEXT: .long 65535 @ 0xffff
590 ;
591 ; THUMB7-LABEL: scalar_i64_bitsinmiddle_eq:
592 ; THUMB7: @ %bb.0:
593 ; THUMB7-NEXT: push {r7, lr}
594 ; THUMB7-NEXT: movs r3, #0
595 ; THUMB7-NEXT: movw lr, #65535
596 ; THUMB7-NEXT: movt r3, #65535
597 ; THUMB7-NEXT: lsr.w r12, r3, r2
598 ; THUMB7-NEXT: rsb.w r3, r2, #32
599 ; THUMB7-NEXT: lsl.w r3, lr, r3
600 ; THUMB7-NEXT: orr.w r3, r3, r12
601 ; THUMB7-NEXT: sub.w r12, r2, #32
602 ; THUMB7-NEXT: lsr.w r2, lr, r2
603 ; THUMB7-NEXT: cmp.w r12, #0
604 ; THUMB7-NEXT: it ge
605 ; THUMB7-NEXT: lsrge.w r3, lr, r12
606 ; THUMB7-NEXT: it ge
607 ; THUMB7-NEXT: movge r2, #0
608 ; THUMB7-NEXT: ands r0, r3
609 ; THUMB7-NEXT: ands r1, r2
610 ; THUMB7-NEXT: orrs r0, r1
611 ; THUMB7-NEXT: clz r0, r0
612 ; THUMB7-NEXT: lsrs r0, r0, #5
613 ; THUMB7-NEXT: pop {r7, pc}
614 ;
615 ; THUMB8-LABEL: scalar_i64_bitsinmiddle_eq:
616 ; THUMB8: @ %bb.0:
617 ; THUMB8-NEXT: .save {r7, lr}
618 ; THUMB8-NEXT: push {r7, lr}
619 ; THUMB8-NEXT: movs r3, #0
620 ; THUMB8-NEXT: movw lr, #65535
621 ; THUMB8-NEXT: movt r3, #65535
622 ; THUMB8-NEXT: lsr.w r12, r3, r2
623 ; THUMB8-NEXT: rsb.w r3, r2, #32
624 ; THUMB8-NEXT: lsl.w r3, lr, r3
625 ; THUMB8-NEXT: orr.w r3, r3, r12
626 ; THUMB8-NEXT: sub.w r12, r2, #32
627 ; THUMB8-NEXT: cmp.w r12, #0
628 ; THUMB8-NEXT: lsr.w r2, lr, r2
629 ; THUMB8-NEXT: it ge
630 ; THUMB8-NEXT: lsrge.w r3, lr, r12
631 ; THUMB8-NEXT: it ge
632 ; THUMB8-NEXT: movge r2, #0
633 ; THUMB8-NEXT: ands r0, r3
634 ; THUMB8-NEXT: ands r1, r2
635 ; THUMB8-NEXT: orrs r0, r1
636 ; THUMB8-NEXT: clz r0, r0
637 ; THUMB8-NEXT: lsrs r0, r0, #5
638 ; THUMB8-NEXT: pop {r7, pc}
639 %t0 = lshr i64 281474976645120, %y
640 %t1 = and i64 %t0, %x
641 %res = icmp eq i64 %t1, 0
642 ret i1 %res
643 }
644
645 ;------------------------------------------------------------------------------;
646 ; A few trivial vector tests
647 ;------------------------------------------------------------------------------;
648
649 define <4 x i1> @vec_4xi32_splat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
650 ; ARM6-LABEL: vec_4xi32_splat_eq:
651 ; ARM6: @ %bb.0:
652 ; ARM6-NEXT: push {r11, lr}
653 ; ARM6-NEXT: ldr r12, [sp, #8]
654 ; ARM6-NEXT: mov lr, #1
655 ; ARM6-NEXT: and r0, r0, lr, lsr r12
656 ; ARM6-NEXT: ldr r12, [sp, #12]
657 ; ARM6-NEXT: clz r0, r0
658 ; ARM6-NEXT: and r1, r1, lr, lsr r12
659 ; ARM6-NEXT: ldr r12, [sp, #16]
660 ; ARM6-NEXT: clz r1, r1
661 ; ARM6-NEXT: lsr r0, r0, #5
662 ; ARM6-NEXT: and r2, r2, lr, lsr r12
663 ; ARM6-NEXT: ldr r12, [sp, #20]
664 ; ARM6-NEXT: clz r2, r2
665 ; ARM6-NEXT: lsr r1, r1, #5
666 ; ARM6-NEXT: and r3, r3, lr, lsr r12
667 ; ARM6-NEXT: lsr r2, r2, #5
668 ; ARM6-NEXT: clz r3, r3
669 ; ARM6-NEXT: lsr r3, r3, #5
670 ; ARM6-NEXT: pop {r11, pc}
671 ;
672 ; ARM78-LABEL: vec_4xi32_splat_eq:
673 ; ARM78: @ %bb.0:
674 ; ARM78-NEXT: mov r12, sp
675 ; ARM78-NEXT: vld1.64 {d16, d17}, [r12]
676 ; ARM78-NEXT: vmov.i32 q9, #0x1
677 ; ARM78-NEXT: vneg.s32 q8, q8
678 ; ARM78-NEXT: vshl.u32 q8, q9, q8
679 ; ARM78-NEXT: vmov d19, r2, r3
680 ; ARM78-NEXT: vmov d18, r0, r1
681 ; ARM78-NEXT: vtst.32 q8, q8, q9
682 ; ARM78-NEXT: vmvn q8, q8
683 ; ARM78-NEXT: vmovn.i32 d16, q8
684 ; ARM78-NEXT: vmov r0, r1, d16
685 ; ARM78-NEXT: bx lr
686 ;
687 ; THUMB6-LABEL: vec_4xi32_splat_eq:
688 ; THUMB6: @ %bb.0:
689 ; THUMB6-NEXT: push {r4, r5, r6, lr}
690 ; THUMB6-NEXT: ldr r5, [sp, #16]
691 ; THUMB6-NEXT: movs r4, #1
692 ; THUMB6-NEXT: mov r6, r4
693 ; THUMB6-NEXT: lsrs r6, r5
694 ; THUMB6-NEXT: ands r6, r0
695 ; THUMB6-NEXT: rsbs r0, r6, #0
696 ; THUMB6-NEXT: adcs r0, r6
697 ; THUMB6-NEXT: ldr r5, [sp, #20]
698 ; THUMB6-NEXT: mov r6, r4
699 ; THUMB6-NEXT: lsrs r6, r5
700 ; THUMB6-NEXT: ands r6, r1
701 ; THUMB6-NEXT: rsbs r1, r6, #0
702 ; THUMB6-NEXT: adcs r1, r6
703 ; THUMB6-NEXT: ldr r5, [sp, #24]
704 ; THUMB6-NEXT: mov r6, r4
705 ; THUMB6-NEXT: lsrs r6, r5
706 ; THUMB6-NEXT: ands r6, r2
707 ; THUMB6-NEXT: rsbs r2, r6, #0
708 ; THUMB6-NEXT: adcs r2, r6
709 ; THUMB6-NEXT: ldr r5, [sp, #28]
710 ; THUMB6-NEXT: lsrs r4, r5
711 ; THUMB6-NEXT: ands r4, r3
712 ; THUMB6-NEXT: rsbs r3, r4, #0
713 ; THUMB6-NEXT: adcs r3, r4
714 ; THUMB6-NEXT: pop {r4, r5, r6, pc}
715 ;
716 ; THUMB78-LABEL: vec_4xi32_splat_eq:
717 ; THUMB78: @ %bb.0:
718 ; THUMB78-NEXT: mov r12, sp
719 ; THUMB78-NEXT: vld1.64 {d16, d17}, [r12]
720 ; THUMB78-NEXT: vmov.i32 q9, #0x1
721 ; THUMB78-NEXT: vneg.s32 q8, q8
722 ; THUMB78-NEXT: vshl.u32 q8, q9, q8
723 ; THUMB78-NEXT: vmov d19, r2, r3
724 ; THUMB78-NEXT: vmov d18, r0, r1
725 ; THUMB78-NEXT: vtst.32 q8, q8, q9
726 ; THUMB78-NEXT: vmvn q8, q8
727 ; THUMB78-NEXT: vmovn.i32 d16, q8
728 ; THUMB78-NEXT: vmov r0, r1, d16
729 ; THUMB78-NEXT: bx lr
730 %t0 = lshr <4 x i32> , %y
731 %t1 = and <4 x i32> %t0, %x
732 %res = icmp eq <4 x i32> %t1,
733 ret <4 x i1> %res
734 }
735
736 define <4 x i1> @vec_4xi32_nonsplat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
737 ; ARM6-LABEL: vec_4xi32_nonsplat_eq:
738 ; ARM6: @ %bb.0:
739 ; ARM6-NEXT: ldr r12, [sp, #4]
740 ; ARM6-NEXT: mov r0, #1
741 ; ARM6-NEXT: and r0, r1, r0, lsr r12
742 ; ARM6-NEXT: ldr r12, [sp, #8]
743 ; ARM6-NEXT: clz r0, r0
744 ; ARM6-NEXT: lsr r1, r0, #5
745 ; ARM6-NEXT: mov r0, #65280
746 ; ARM6-NEXT: orr r0, r0, #16711680
747 ; ARM6-NEXT: and r0, r2, r0, lsr r12
748 ; ARM6-NEXT: ldr r12, [sp, #12]
749 ; ARM6-NEXT: clz r0, r0
750 ; ARM6-NEXT: lsr r2, r0, #5
751 ; ARM6-NEXT: mov r0, #-2147483648
752 ; ARM6-NEXT: and r0, r3, r0, lsr r12
753 ; ARM6-NEXT: clz r0, r0
754 ; ARM6-NEXT: lsr r3, r0, #5
755 ; ARM6-NEXT: mov r0, #1
756 ; ARM6-NEXT: bx lr
757 ;
758 ; ARM78-LABEL: vec_4xi32_nonsplat_eq:
759 ; ARM78: @ %bb.0:
760 ; ARM78-NEXT: mov r12, sp
761 ; ARM78-NEXT: vld1.64 {d16, d17}, [r12]
762 ; ARM78-NEXT: adr r12, .LCPI13_0
763 ; ARM78-NEXT: vneg.s32 q8, q8
764 ; ARM78-NEXT: vld1.64 {d18, d19}, [r12:128]
765 ; ARM78-NEXT: vshl.u32 q8, q9, q8
766 ; ARM78-NEXT: vmov d19, r2, r3
767 ; ARM78-NEXT: vmov d18, r0, r1
768 ; ARM78-NEXT: vtst.32 q8, q8, q9
769 ; ARM78-NEXT: vmvn q8, q8
770 ; ARM78-NEXT: vmovn.i32 d16, q8
771 ; ARM78-NEXT: vmov r0, r1, d16
772 ; ARM78-NEXT: bx lr
773 ; ARM78-NEXT: .p2align 4
774 ; ARM78-NEXT: @ %bb.1:
775 ; ARM78-NEXT: .LCPI13_0:
776 ; ARM78-NEXT: .long 0 @ 0x0
777 ; ARM78-NEXT: .long 1 @ 0x1
778 ; ARM78-NEXT: .long 16776960 @ 0xffff00
779 ; ARM78-NEXT: .long 2147483648 @ 0x80000000
780 ;
781 ; THUMB6-LABEL: vec_4xi32_nonsplat_eq:
782 ; THUMB6: @ %bb.0:
783 ; THUMB6-NEXT: push {r4, r5, r7, lr}
784 ; THUMB6-NEXT: ldr r4, [sp, #20]
785 ; THUMB6-NEXT: movs r0, #1
786 ; THUMB6-NEXT: mov r5, r0
787 ; THUMB6-NEXT: lsrs r5, r4
788 ; THUMB6-NEXT: ands r5, r1
789 ; THUMB6-NEXT: rsbs r1, r5, #0
790 ; THUMB6-NEXT: adcs r1, r5
791 ; THUMB6-NEXT: ldr r4, [sp, #24]
792 ; THUMB6-NEXT: ldr r5, .LCPI13_0
793 ; THUMB6-NEXT: lsrs r5, r4
794 ; THUMB6-NEXT: ands r5, r2
795 ; THUMB6-NEXT: rsbs r2, r5, #0
796 ; THUMB6-NEXT: adcs r2, r5
797 ; THUMB6-NEXT: lsls r4, r0, #31
798 ; THUMB6-NEXT: ldr r5, [sp, #28]
799 ; THUMB6-NEXT: lsrs r4, r5
800 ; THUMB6-NEXT: ands r4, r3
801 ; THUMB6-NEXT: rsbs r3, r4, #0
802 ; THUMB6-NEXT: adcs r3, r4
803 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
804 ; THUMB6-NEXT: .p2align 2
805 ; THUMB6-NEXT: @ %bb.1:
806 ; THUMB6-NEXT: .LCPI13_0:
807 ; THUMB6-NEXT: .long 16776960 @ 0xffff00
808 ;
809 ; THUMB78-LABEL: vec_4xi32_nonsplat_eq:
810 ; THUMB78: @ %bb.0:
811 ; THUMB78-NEXT: mov r12, sp
812 ; THUMB78-NEXT: vld1.64 {d16, d17}, [r12]
813 ; THUMB78-NEXT: adr.w r12, .LCPI13_0
814 ; THUMB78-NEXT: vneg.s32 q8, q8
815 ; THUMB78-NEXT: vld1.64 {d18, d19}, [r12:128]
816 ; THUMB78-NEXT: vshl.u32 q8, q9, q8
817 ; THUMB78-NEXT: vmov d19, r2, r3
818 ; THUMB78-NEXT: vmov d18, r0, r1
819 ; THUMB78-NEXT: vtst.32 q8, q8, q9
820 ; THUMB78-NEXT: vmvn q8, q8
821 ; THUMB78-NEXT: vmovn.i32 d16, q8
822 ; THUMB78-NEXT: vmov r0, r1, d16
823 ; THUMB78-NEXT: bx lr
824 ; THUMB78-NEXT: .p2align 4
825 ; THUMB78-NEXT: @ %bb.1:
826 ; THUMB78-NEXT: .LCPI13_0:
827 ; THUMB78-NEXT: .long 0 @ 0x0
828 ; THUMB78-NEXT: .long 1 @ 0x1
829 ; THUMB78-NEXT: .long 16776960 @ 0xffff00
830 ; THUMB78-NEXT: .long 2147483648 @ 0x80000000
831 %t0 = lshr <4 x i32> , %y
832 %t1 = and <4 x i32> %t0, %x
833 %res = icmp eq <4 x i32> %t1,
834 ret <4 x i1> %res
835 }
836
837 define <4 x i1> @vec_4xi32_nonsplat_undef0_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
838 ; ARM6-LABEL: vec_4xi32_nonsplat_undef0_eq:
839 ; ARM6: @ %bb.0:
840 ; ARM6-NEXT: push {r11, lr}
841 ; ARM6-NEXT: ldr r2, [sp, #12]
842 ; ARM6-NEXT: mov lr, #1
843 ; ARM6-NEXT: ldr r12, [sp, #8]
844 ; ARM6-NEXT: and r1, r1, lr, lsr r2
845 ; ARM6-NEXT: ldr r2, [sp, #20]
846 ; ARM6-NEXT: and r0, r0, lr, lsr r12
847 ; ARM6-NEXT: clz r1, r1
848 ; ARM6-NEXT: clz r0, r0
849 ; ARM6-NEXT: and r2, r3, lr, lsr r2
850 ; ARM6-NEXT: lsr r1, r1, #5
851 ; ARM6-NEXT: clz r2, r2
852 ; ARM6-NEXT: lsr r0, r0, #5
853 ; ARM6-NEXT: lsr r3, r2, #5
854 ; ARM6-NEXT: mov r2, #1
855 ; ARM6-NEXT: pop {r11, pc}
856 ;
857 ; ARM78-LABEL: vec_4xi32_nonsplat_undef0_eq:
858 ; ARM78: @ %bb.0:
859 ; ARM78-NEXT: mov r12, sp
860 ; ARM78-NEXT: vld1.64 {d16, d17}, [r12]
861 ; ARM78-NEXT: vmov.i32 q9, #0x1
862 ; ARM78-NEXT: vneg.s32 q8, q8
863 ; ARM78-NEXT: vshl.u32 q8, q9, q8
864 ; ARM78-NEXT: vmov d19, r2, r3
865 ; ARM78-NEXT: vmov d18, r0, r1
866 ; ARM78-NEXT: vtst.32 q8, q8, q9
867 ; ARM78-NEXT: vmvn q8, q8
868 ; ARM78-NEXT: vmovn.i32 d16, q8
869 ; ARM78-NEXT: vmov r0, r1, d16
870 ; ARM78-NEXT: bx lr
871 ;
872 ; THUMB6-LABEL: vec_4xi32_nonsplat_undef0_eq:
873 ; THUMB6: @ %bb.0:
874 ; THUMB6-NEXT: push {r4, r5, r7, lr}
875 ; THUMB6-NEXT: ldr r4, [sp, #16]
876 ; THUMB6-NEXT: movs r2, #1
877 ; THUMB6-NEXT: mov r5, r2
878 ; THUMB6-NEXT: lsrs r5, r4
879 ; THUMB6-NEXT: ands r5, r0
880 ; THUMB6-NEXT: rsbs r0, r5, #0
881 ; THUMB6-NEXT: adcs r0, r5
882 ; THUMB6-NEXT: ldr r4, [sp, #20]
883 ; THUMB6-NEXT: mov r5, r2
884 ; THUMB6-NEXT: lsrs r5, r4
885 ; THUMB6-NEXT: ands r5, r1
886 ; THUMB6-NEXT: rsbs r1, r5, #0
887 ; THUMB6-NEXT: adcs r1, r5
888 ; THUMB6-NEXT: ldr r4, [sp, #28]
889 ; THUMB6-NEXT: mov r5, r2
890 ; THUMB6-NEXT: lsrs r5, r4
891 ; THUMB6-NEXT: ands r5, r3
892 ; THUMB6-NEXT: rsbs r3, r5, #0
893 ; THUMB6-NEXT: adcs r3, r5
894 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
895 ;
896 ; THUMB78-LABEL: vec_4xi32_nonsplat_undef0_eq:
897 ; THUMB78: @ %bb.0:
898 ; THUMB78-NEXT: mov r12, sp
899 ; THUMB78-NEXT: vld1.64 {d16, d17}, [r12]
900 ; THUMB78-NEXT: vmov.i32 q9, #0x1
901 ; THUMB78-NEXT: vneg.s32 q8, q8
902 ; THUMB78-NEXT: vshl.u32 q8, q9, q8
903 ; THUMB78-NEXT: vmov d19, r2, r3
904 ; THUMB78-NEXT: vmov d18, r0, r1
905 ; THUMB78-NEXT: vtst.32 q8, q8, q9
906 ; THUMB78-NEXT: vmvn q8, q8
907 ; THUMB78-NEXT: vmovn.i32 d16, q8
908 ; THUMB78-NEXT: vmov r0, r1, d16
909 ; THUMB78-NEXT: bx lr
910 %t0 = lshr <4 x i32> , %y
911 %t1 = and <4 x i32> %t0, %x
912 %res = icmp eq <4 x i32> %t1,
913 ret <4 x i1> %res
914 }
915 define <4 x i1> @vec_4xi32_nonsplat_undef1_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
916 ; ARM6-LABEL: vec_4xi32_nonsplat_undef1_eq:
917 ; ARM6: @ %bb.0:
918 ; ARM6-NEXT: push {r11, lr}
919 ; ARM6-NEXT: ldr r2, [sp, #12]
920 ; ARM6-NEXT: mov lr, #1
921 ; ARM6-NEXT: ldr r12, [sp, #8]
922 ; ARM6-NEXT: and r1, r1, lr, lsr r2
923 ; ARM6-NEXT: ldr r2, [sp, #20]
924 ; ARM6-NEXT: and r0, r0, lr, lsr r12
925 ; ARM6-NEXT: clz r1, r1
926 ; ARM6-NEXT: clz r0, r0
927 ; ARM6-NEXT: and r2, r3, lr, lsr r2
928 ; ARM6-NEXT: lsr r1, r1, #5
929 ; ARM6-NEXT: clz r2, r2
930 ; ARM6-NEXT: lsr r0, r0, #5
931 ; ARM6-NEXT: lsr r3, r2, #5
932 ; ARM6-NEXT: pop {r11, pc}
933 ;
934 ; ARM78-LABEL: vec_4xi32_nonsplat_undef1_eq:
935 ; ARM78: @ %bb.0:
936 ; ARM78-NEXT: mov r12, sp
937 ; ARM78-NEXT: vld1.64 {d16, d17}, [r12]
938 ; ARM78-NEXT: vmov.i32 q9, #0x1
939 ; ARM78-NEXT: vneg.s32 q8, q8
940 ; ARM78-NEXT: vshl.u32 q8, q9, q8
941 ; ARM78-NEXT: vmov d19, r2, r3
942 ; ARM78-NEXT: vmov d18, r0, r1
943 ; ARM78-NEXT: vtst.32 q8, q8, q9
944 ; ARM78-NEXT: vmvn q8, q8
945 ; ARM78-NEXT: vmovn.i32 d16, q8
946 ; ARM78-NEXT: vmov r0, r1, d16
947 ; ARM78-NEXT: bx lr
948 ;
949 ; THUMB6-LABEL: vec_4xi32_nonsplat_undef1_eq:
950 ; THUMB6: @ %bb.0:
951 ; THUMB6-NEXT: push {r4, r5, r7, lr}
952 ; THUMB6-NEXT: ldr r4, [sp, #16]
953 ; THUMB6-NEXT: movs r2, #1
954 ; THUMB6-NEXT: mov r5, r2
955 ; THUMB6-NEXT: lsrs r5, r4
956 ; THUMB6-NEXT: ands r5, r0
957 ; THUMB6-NEXT: rsbs r0, r5, #0
958 ; THUMB6-NEXT: adcs r0, r5
959 ; THUMB6-NEXT: ldr r4, [sp, #20]
960 ; THUMB6-NEXT: mov r5, r2
961 ; THUMB6-NEXT: lsrs r5, r4
962 ; THUMB6-NEXT: ands r5, r1
963 ; THUMB6-NEXT: rsbs r1, r5, #0
964 ; THUMB6-NEXT: adcs r1, r5
965 ; THUMB6-NEXT: ldr r4, [sp, #28]
966 ; THUMB6-NEXT: lsrs r2, r4
967 ; THUMB6-NEXT: ands r2, r3
968 ; THUMB6-NEXT: rsbs r3, r2, #0
969 ; THUMB6-NEXT: adcs r3, r2
970 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
971 ;
972 ; THUMB78-LABEL: vec_4xi32_nonsplat_undef1_eq:
973 ; THUMB78: @ %bb.0:
974 ; THUMB78-NEXT: mov r12, sp
975 ; THUMB78-NEXT: vld1.64 {d16, d17}, [r12]
976 ; THUMB78-NEXT: vmov.i32 q9, #0x1
977 ; THUMB78-NEXT: vneg.s32 q8, q8
978 ; THUMB78-NEXT: vshl.u32 q8, q9, q8
979 ; THUMB78-NEXT: vmov d19, r2, r3
980 ; THUMB78-NEXT: vmov d18, r0, r1
981 ; THUMB78-NEXT: vtst.32 q8, q8, q9
982 ; THUMB78-NEXT: vmvn q8, q8
983 ; THUMB78-NEXT: vmovn.i32 d16, q8
984 ; THUMB78-NEXT: vmov r0, r1, d16
985 ; THUMB78-NEXT: bx lr
986 %t0 = lshr <4 x i32> , %y
987 %t1 = and <4 x i32> %t0, %x
988 %res = icmp eq <4 x i32> %t1,
989 ret <4 x i1> %res
990 }
991 define <4 x i1> @vec_4xi32_nonsplat_undef2_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
992 ; ARM6-LABEL: vec_4xi32_nonsplat_undef2_eq:
993 ; ARM6: @ %bb.0:
994 ; ARM6-NEXT: push {r11, lr}
995 ; ARM6-NEXT: ldr r2, [sp, #12]
996 ; ARM6-NEXT: mov lr, #1
997 ; ARM6-NEXT: ldr r12, [sp, #8]
998 ; ARM6-NEXT: and r1, r1, lr, lsr r2
999 ; ARM6-NEXT: ldr r2, [sp, #20]
1000 ; ARM6-NEXT: and r0, r0, lr, lsr r12
1001 ; ARM6-NEXT: clz r1, r1
1002 ; ARM6-NEXT: clz r0, r0
1003 ; ARM6-NEXT: and r2, r3, lr, lsr r2
1004 ; ARM6-NEXT: lsr r1, r1, #5
1005 ; ARM6-NEXT: clz r2, r2
1006 ; ARM6-NEXT: lsr r0, r0, #5
1007 ; ARM6-NEXT: lsr r3, r2, #5
1008 ; ARM6-NEXT: pop {r11, pc}
1009 ;
1010 ; ARM78-LABEL: vec_4xi32_nonsplat_undef2_eq:
1011 ; ARM78: @ %bb.0:
1012 ; ARM78-NEXT: mov r12, sp
1013 ; ARM78-NEXT: vld1.64 {d16, d17}, [r12]
1014 ; ARM78-NEXT: vmov.i32 q9, #0x1
1015 ; ARM78-NEXT: vneg.s32 q8, q8
1016 ; ARM78-NEXT: vshl.u32 q8, q9, q8
1017 ; ARM78-NEXT: vmov d19, r2, r3
1018 ; ARM78-NEXT: vmov d18, r0, r1
1019 ; ARM78-NEXT: vtst.32 q8, q8, q9
1020 ; ARM78-NEXT: vmvn q8, q8
1021 ; ARM78-NEXT: vmovn.i32 d16, q8
1022 ; ARM78-NEXT: vmov r0, r1, d16
1023 ; ARM78-NEXT: bx lr
1024 ;
1025 ; THUMB6-LABEL: vec_4xi32_nonsplat_undef2_eq:
1026 ; THUMB6: @ %bb.0:
1027 ; THUMB6-NEXT: push {r4, r5, r7, lr}
1028 ; THUMB6-NEXT: ldr r4, [sp, #16]
1029 ; THUMB6-NEXT: movs r2, #1
1030 ; THUMB6-NEXT: mov r5, r2
1031 ; THUMB6-NEXT: lsrs r5, r4
1032 ; THUMB6-NEXT: ands r5, r0
1033 ; THUMB6-NEXT: rsbs r0, r5, #0
1034 ; THUMB6-NEXT: adcs r0, r5
1035 ; THUMB6-NEXT: ldr r4, [sp, #20]
1036 ; THUMB6-NEXT: mov r5, r2
1037 ; THUMB6-NEXT: lsrs r5, r4
1038 ; THUMB6-NEXT: ands r5, r1
1039 ; THUMB6-NEXT: rsbs r1, r5, #0
1040 ; THUMB6-NEXT: adcs r1, r5
1041 ; THUMB6-NEXT: ldr r4, [sp, #28]
1042 ; THUMB6-NEXT: lsrs r2, r4
1043 ; THUMB6-NEXT: ands r2, r3
1044 ; THUMB6-NEXT: rsbs r3, r2, #0
1045 ; THUMB6-NEXT: adcs r3, r2
1046 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
1047 ;
1048 ; THUMB78-LABEL: vec_4xi32_nonsplat_undef2_eq:
1049 ; THUMB78: @ %bb.0:
1050 ; THUMB78-NEXT: mov r12, sp
1051 ; THUMB78-NEXT: vld1.64 {d16, d17}, [r12]
1052 ; THUMB78-NEXT: vmov.i32 q9, #0x1
1053 ; THUMB78-NEXT: vneg.s32 q8, q8
1054 ; THUMB78-NEXT: vshl.u32 q8, q9, q8
1055 ; THUMB78-NEXT: vmov d19, r2, r3
1056 ; THUMB78-NEXT: vmov d18, r0, r1
1057 ; THUMB78-NEXT: vtst.32 q8, q8, q9
1058 ; THUMB78-NEXT: vmvn q8, q8
1059 ; THUMB78-NEXT: vmovn.i32 d16, q8
1060 ; THUMB78-NEXT: vmov r0, r1, d16
1061 ; THUMB78-NEXT: bx lr
1062 %t0 = lshr <4 x i32> , %y
1063 %t1 = and <4 x i32> %t0, %x
1064 %res = icmp eq <4 x i32> %t1,
1065 ret <4 x i1> %res
1066 }
1067
1068 ;------------------------------------------------------------------------------;
1069 ; A special tests
1070 ;------------------------------------------------------------------------------;
1071
1072 define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
1073 ; ARM6-LABEL: scalar_i8_signbit_ne:
1074 ; ARM6: @ %bb.0:
1075 ; ARM6-NEXT: uxtb r1, r1
1076 ; ARM6-NEXT: mov r2, #128
1077 ; ARM6-NEXT: and r0, r0, r2, lsr r1
1078 ; ARM6-NEXT: uxtb r0, r0
1079 ; ARM6-NEXT: cmp r0, #0
1080 ; ARM6-NEXT: movne r0, #1
1081 ; ARM6-NEXT: bx lr
1082 ;
1083 ; ARM78-LABEL: scalar_i8_signbit_ne:
1084 ; ARM78: @ %bb.0:
1085 ; ARM78-NEXT: uxtb r1, r1
1086 ; ARM78-NEXT: mov r2, #128
1087 ; ARM78-NEXT: and r0, r0, r2, lsr r1
1088 ; ARM78-NEXT: uxtb r0, r0
1089 ; ARM78-NEXT: cmp r0, #0
1090 ; ARM78-NEXT: movwne r0, #1
1091 ; ARM78-NEXT: bx lr
1092 ;
1093 ; THUMB6-LABEL: scalar_i8_signbit_ne:
1094 ; THUMB6: @ %bb.0:
1095 ; THUMB6-NEXT: uxtb r1, r1
1096 ; THUMB6-NEXT: movs r2, #128
1097 ; THUMB6-NEXT: lsrs r2, r1
1098 ; THUMB6-NEXT: ands r2, r0
1099 ; THUMB6-NEXT: uxtb r0, r2
1100 ; THUMB6-NEXT: subs r1, r0, #1
1101 ; THUMB6-NEXT: sbcs r0, r1
1102 ; THUMB6-NEXT: bx lr
1103 ;
1104 ; THUMB78-LABEL: scalar_i8_signbit_ne:
1105 ; THUMB78: @ %bb.0:
1106 ; THUMB78-NEXT: uxtb r1, r1
1107 ; THUMB78-NEXT: movs r2, #128
1108 ; THUMB78-NEXT: lsr.w r1, r2, r1
1109 ; THUMB78-NEXT: ands r0, r1
1110 ; THUMB78-NEXT: uxtb r0, r0
1111 ; THUMB78-NEXT: cmp r0, #0
1112 ; THUMB78-NEXT: it ne
1113 ; THUMB78-NEXT: movne r0, #1
1114 ; THUMB78-NEXT: bx lr
1115 %t0 = lshr i8 128, %y
1116 %t1 = and i8 %t0, %x
1117 %res = icmp ne i8 %t1, 0 ; we are perfectly happy with 'ne' predicate
1118 ret i1 %res
1119 }
1120
1121 ;------------------------------------------------------------------------------;
1122 ; A few negative tests
1123 ;------------------------------------------------------------------------------;
1124
1125 define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
1126 ; ARM6-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1127 ; ARM6: @ %bb.0:
1128 ; ARM6-NEXT: uxtb r1, r1
1129 ; ARM6-NEXT: mov r2, #24
1130 ; ARM6-NEXT: and r0, r0, r2, lsr r1
1131 ; ARM6-NEXT: sxtb r1, r0
1132 ; ARM6-NEXT: mov r0, #0
1133 ; ARM6-NEXT: cmp r1, #0
1134 ; ARM6-NEXT: movlt r0, #1
1135 ; ARM6-NEXT: bx lr
1136 ;
1137 ; ARM78-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1138 ; ARM78: @ %bb.0:
1139 ; ARM78-NEXT: uxtb r1, r1
1140 ; ARM78-NEXT: mov r2, #24
1141 ; ARM78-NEXT: and r0, r0, r2, lsr r1
1142 ; ARM78-NEXT: sxtb r1, r0
1143 ; ARM78-NEXT: mov r0, #0
1144 ; ARM78-NEXT: cmp r1, #0
1145 ; ARM78-NEXT: movwlt r0, #1
1146 ; ARM78-NEXT: bx lr
1147 ;
1148 ; THUMB6-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1149 ; THUMB6: @ %bb.0:
1150 ; THUMB6-NEXT: uxtb r1, r1
1151 ; THUMB6-NEXT: movs r2, #24
1152 ; THUMB6-NEXT: lsrs r2, r1
1153 ; THUMB6-NEXT: ands r2, r0
1154 ; THUMB6-NEXT: sxtb r0, r2
1155 ; THUMB6-NEXT: cmp r0, #0
1156 ; THUMB6-NEXT: blt .LBB18_2
1157 ; THUMB6-NEXT: @ %bb.1:
1158 ; THUMB6-NEXT: movs r0, #0
1159 ; THUMB6-NEXT: bx lr
1160 ; THUMB6-NEXT: .LBB18_2:
1161 ; THUMB6-NEXT: movs r0, #1
1162 ; THUMB6-NEXT: bx lr
1163 ;
1164 ; THUMB78-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1165 ; THUMB78: @ %bb.0:
1166 ; THUMB78-NEXT: uxtb r1, r1
1167 ; THUMB78-NEXT: movs r2, #24
1168 ; THUMB78-NEXT: lsr.w r1, r2, r1
1169 ; THUMB78-NEXT: ands r0, r1
1170 ; THUMB78-NEXT: sxtb r1, r0
1171 ; THUMB78-NEXT: movs r0, #0
1172 ; THUMB78-NEXT: cmp r1, #0
1173 ; THUMB78-NEXT: it lt
1174 ; THUMB78-NEXT: movlt r0, #1
1175 ; THUMB78-NEXT: bx lr
1176 %t0 = lshr i8 24, %y
1177 %t1 = and i8 %t0, %x
1178 %res = icmp slt i8 %t1, 0
1179 ret i1 %res
1180 }
1181
1182 define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
1183 ; ARM-LABEL: scalar_i8_signbit_eq_with_nonzero:
1184 ; ARM: @ %bb.0:
1185 ; ARM-NEXT: uxtb r1, r1
1186 ; ARM-NEXT: mov r2, #128
1187 ; ARM-NEXT: and r0, r0, r2, lsr r1
1188 ; ARM-NEXT: mvn r1, #0
1189 ; ARM-NEXT: uxtab r0, r1, r0
1190 ; ARM-NEXT: clz r0, r0
1191 ; ARM-NEXT: lsr r0, r0, #5
1192 ; ARM-NEXT: bx lr
1193 ;
1194 ; THUMB6-LABEL: scalar_i8_signbit_eq_with_nonzero:
1195 ; THUMB6: @ %bb.0:
1196 ; THUMB6-NEXT: uxtb r1, r1
1197 ; THUMB6-NEXT: movs r2, #128
1198 ; THUMB6-NEXT: lsrs r2, r1
1199 ; THUMB6-NEXT: ands r2, r0
1200 ; THUMB6-NEXT: uxtb r0, r2
1201 ; THUMB6-NEXT: subs r1, r0, #1
1202 ; THUMB6-NEXT: rsbs r0, r1, #0
1203 ; THUMB6-NEXT: adcs r0, r1
1204 ; THUMB6-NEXT: bx lr
1205 ;
1206 ; THUMB78-LABEL: scalar_i8_signbit_eq_with_nonzero:
1207 ; THUMB78: @ %bb.0:
1208 ; THUMB78-NEXT: uxtb r1, r1
1209 ; THUMB78-NEXT: movs r2, #128
1210 ; THUMB78-NEXT: lsr.w r1, r2, r1
1211 ; THUMB78-NEXT: ands r0, r1
1212 ; THUMB78-NEXT: mov.w r1, #-1
1213 ; THUMB78-NEXT: uxtab r0, r1, r0
1214 ; THUMB78-NEXT: clz r0, r0
1215 ; THUMB78-NEXT: lsrs r0, r0, #5
1216 ; THUMB78-NEXT: bx lr
1217 %t0 = lshr i8 128, %y
1218 %t1 = and i8 %t0, %x
1219 %res = icmp eq i8 %t1, 1 ; should be comparing with 0
1220 ret i1 %res
1221 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=armv6 < %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM6
2 ; RUN: llc -mtriple=armv7 < %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM78,ARM7
3 ; RUN: llc -mtriple=armv8a < %s | FileCheck %s --check-prefixes=CHECK,ARM,ARM78,ARM8
4 ; RUN: llc -mtriple=thumbv6 < %s | FileCheck %s --check-prefixes=CHECK,THUMB,THUMB6
5 ; RUN: llc -mtriple=thumbv7 < %s | FileCheck %s --check-prefixes=CHECK,THUMB,THUMB78,THUMB7
6 ; RUN: llc -mtriple=thumbv8-eabi < %s | FileCheck %s --check-prefixes=CHECK,THUMB,THUMB78,THUMB8
7
8 ; We are looking for the following pattern here:
9 ; (X & (C << Y)) ==/!= 0
10 ; It may be optimal to hoist the constant:
11 ; ((X l>> Y) & C) ==/!= 0
12
13 ;------------------------------------------------------------------------------;
14 ; A few scalar test
15 ;------------------------------------------------------------------------------;
16
17 ; i8 scalar
18
19 define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
20 ; ARM-LABEL: scalar_i8_signbit_eq:
21 ; ARM: @ %bb.0:
22 ; ARM-NEXT: uxtb r1, r1
23 ; ARM-NEXT: mvn r2, #127
24 ; ARM-NEXT: and r0, r0, r2, lsl r1
25 ; ARM-NEXT: uxtb r0, r0
26 ; ARM-NEXT: clz r0, r0
27 ; ARM-NEXT: lsr r0, r0, #5
28 ; ARM-NEXT: bx lr
29 ;
30 ; THUMB6-LABEL: scalar_i8_signbit_eq:
31 ; THUMB6: @ %bb.0:
32 ; THUMB6-NEXT: uxtb r1, r1
33 ; THUMB6-NEXT: movs r2, #127
34 ; THUMB6-NEXT: mvns r2, r2
35 ; THUMB6-NEXT: lsls r2, r1
36 ; THUMB6-NEXT: ands r2, r0
37 ; THUMB6-NEXT: uxtb r1, r2
38 ; THUMB6-NEXT: rsbs r0, r1, #0
39 ; THUMB6-NEXT: adcs r0, r1
40 ; THUMB6-NEXT: bx lr
41 ;
42 ; THUMB78-LABEL: scalar_i8_signbit_eq:
43 ; THUMB78: @ %bb.0:
44 ; THUMB78-NEXT: uxtb r1, r1
45 ; THUMB78-NEXT: mvn r2, #127
46 ; THUMB78-NEXT: lsl.w r1, r2, r1
47 ; THUMB78-NEXT: ands r0, r1
48 ; THUMB78-NEXT: uxtb r0, r0
49 ; THUMB78-NEXT: clz r0, r0
50 ; THUMB78-NEXT: lsrs r0, r0, #5
51 ; THUMB78-NEXT: bx lr
52 %t0 = shl i8 128, %y
53 %t1 = and i8 %t0, %x
54 %res = icmp eq i8 %t1, 0
55 ret i1 %res
56 }
57
58 define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
59 ; ARM-LABEL: scalar_i8_lowestbit_eq:
60 ; ARM: @ %bb.0:
61 ; ARM-NEXT: uxtb r1, r1
62 ; ARM-NEXT: mov r2, #1
63 ; ARM-NEXT: and r0, r0, r2, lsl r1
64 ; ARM-NEXT: uxtb r0, r0
65 ; ARM-NEXT: clz r0, r0
66 ; ARM-NEXT: lsr r0, r0, #5
67 ; ARM-NEXT: bx lr
68 ;
69 ; THUMB6-LABEL: scalar_i8_lowestbit_eq:
70 ; THUMB6: @ %bb.0:
71 ; THUMB6-NEXT: uxtb r1, r1
72 ; THUMB6-NEXT: movs r2, #1
73 ; THUMB6-NEXT: lsls r2, r1
74 ; THUMB6-NEXT: ands r2, r0
75 ; THUMB6-NEXT: uxtb r1, r2
76 ; THUMB6-NEXT: rsbs r0, r1, #0
77 ; THUMB6-NEXT: adcs r0, r1
78 ; THUMB6-NEXT: bx lr
79 ;
80 ; THUMB78-LABEL: scalar_i8_lowestbit_eq:
81 ; THUMB78: @ %bb.0:
82 ; THUMB78-NEXT: uxtb r1, r1
83 ; THUMB78-NEXT: movs r2, #1
84 ; THUMB78-NEXT: lsl.w r1, r2, r1
85 ; THUMB78-NEXT: ands r0, r1
86 ; THUMB78-NEXT: uxtb r0, r0
87 ; THUMB78-NEXT: clz r0, r0
88 ; THUMB78-NEXT: lsrs r0, r0, #5
89 ; THUMB78-NEXT: bx lr
90 %t0 = shl i8 1, %y
91 %t1 = and i8 %t0, %x
92 %res = icmp eq i8 %t1, 0
93 ret i1 %res
94 }
95
96 define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
97 ; ARM-LABEL: scalar_i8_bitsinmiddle_eq:
98 ; ARM: @ %bb.0:
99 ; ARM-NEXT: uxtb r1, r1
100 ; ARM-NEXT: mov r2, #24
101 ; ARM-NEXT: and r0, r0, r2, lsl r1
102 ; ARM-NEXT: uxtb r0, r0
103 ; ARM-NEXT: clz r0, r0
104 ; ARM-NEXT: lsr r0, r0, #5
105 ; ARM-NEXT: bx lr
106 ;
107 ; THUMB6-LABEL: scalar_i8_bitsinmiddle_eq:
108 ; THUMB6: @ %bb.0:
109 ; THUMB6-NEXT: uxtb r1, r1
110 ; THUMB6-NEXT: movs r2, #24
111 ; THUMB6-NEXT: lsls r2, r1
112 ; THUMB6-NEXT: ands r2, r0
113 ; THUMB6-NEXT: uxtb r1, r2
114 ; THUMB6-NEXT: rsbs r0, r1, #0
115 ; THUMB6-NEXT: adcs r0, r1
116 ; THUMB6-NEXT: bx lr
117 ;
118 ; THUMB78-LABEL: scalar_i8_bitsinmiddle_eq:
119 ; THUMB78: @ %bb.0:
120 ; THUMB78-NEXT: uxtb r1, r1
121 ; THUMB78-NEXT: movs r2, #24
122 ; THUMB78-NEXT: lsl.w r1, r2, r1
123 ; THUMB78-NEXT: ands r0, r1
124 ; THUMB78-NEXT: uxtb r0, r0
125 ; THUMB78-NEXT: clz r0, r0
126 ; THUMB78-NEXT: lsrs r0, r0, #5
127 ; THUMB78-NEXT: bx lr
128 %t0 = shl i8 24, %y
129 %t1 = and i8 %t0, %x
130 %res = icmp eq i8 %t1, 0
131 ret i1 %res
132 }
133
134 ; i16 scalar
135
136 define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
137 ; ARM6-LABEL: scalar_i16_signbit_eq:
138 ; ARM6: @ %bb.0:
139 ; ARM6-NEXT: ldr r2, .LCPI3_0
140 ; ARM6-NEXT: uxth r1, r1
141 ; ARM6-NEXT: and r0, r0, r2, lsl r1
142 ; ARM6-NEXT: uxth r0, r0
143 ; ARM6-NEXT: clz r0, r0
144 ; ARM6-NEXT: lsr r0, r0, #5
145 ; ARM6-NEXT: bx lr
146 ; ARM6-NEXT: .p2align 2
147 ; ARM6-NEXT: @ %bb.1:
148 ; ARM6-NEXT: .LCPI3_0:
149 ; ARM6-NEXT: .long 4294934528 @ 0xffff8000
150 ;
151 ; ARM78-LABEL: scalar_i16_signbit_eq:
152 ; ARM78: @ %bb.0:
153 ; ARM78-NEXT: movw r2, #32768
154 ; ARM78-NEXT: uxth r1, r1
155 ; ARM78-NEXT: movt r2, #65535
156 ; ARM78-NEXT: and r0, r0, r2, lsl r1
157 ; ARM78-NEXT: uxth r0, r0
158 ; ARM78-NEXT: clz r0, r0
159 ; ARM78-NEXT: lsr r0, r0, #5
160 ; ARM78-NEXT: bx lr
161 ;
162 ; THUMB6-LABEL: scalar_i16_signbit_eq:
163 ; THUMB6: @ %bb.0:
164 ; THUMB6-NEXT: uxth r1, r1
165 ; THUMB6-NEXT: ldr r2, .LCPI3_0
166 ; THUMB6-NEXT: lsls r2, r1
167 ; THUMB6-NEXT: ands r2, r0
168 ; THUMB6-NEXT: uxth r1, r2
169 ; THUMB6-NEXT: rsbs r0, r1, #0
170 ; THUMB6-NEXT: adcs r0, r1
171 ; THUMB6-NEXT: bx lr
172 ; THUMB6-NEXT: .p2align 2
173 ; THUMB6-NEXT: @ %bb.1:
174 ; THUMB6-NEXT: .LCPI3_0:
175 ; THUMB6-NEXT: .long 4294934528 @ 0xffff8000
176 ;
177 ; THUMB78-LABEL: scalar_i16_signbit_eq:
178 ; THUMB78: @ %bb.0:
179 ; THUMB78-NEXT: movw r2, #32768
180 ; THUMB78-NEXT: uxth r1, r1
181 ; THUMB78-NEXT: movt r2, #65535
182 ; THUMB78-NEXT: lsl.w r1, r2, r1
183 ; THUMB78-NEXT: ands r0, r1
184 ; THUMB78-NEXT: uxth r0, r0
185 ; THUMB78-NEXT: clz r0, r0
186 ; THUMB78-NEXT: lsrs r0, r0, #5
187 ; THUMB78-NEXT: bx lr
188 %t0 = shl i16 32768, %y
189 %t1 = and i16 %t0, %x
190 %res = icmp eq i16 %t1, 0
191 ret i1 %res
192 }
193
194 define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
195 ; ARM-LABEL: scalar_i16_lowestbit_eq:
196 ; ARM: @ %bb.0:
197 ; ARM-NEXT: uxth r1, r1
198 ; ARM-NEXT: mov r2, #1
199 ; ARM-NEXT: and r0, r0, r2, lsl r1
200 ; ARM-NEXT: uxth r0, r0
201 ; ARM-NEXT: clz r0, r0
202 ; ARM-NEXT: lsr r0, r0, #5
203 ; ARM-NEXT: bx lr
204 ;
205 ; THUMB6-LABEL: scalar_i16_lowestbit_eq:
206 ; THUMB6: @ %bb.0:
207 ; THUMB6-NEXT: uxth r1, r1
208 ; THUMB6-NEXT: movs r2, #1
209 ; THUMB6-NEXT: lsls r2, r1
210 ; THUMB6-NEXT: ands r2, r0
211 ; THUMB6-NEXT: uxth r1, r2
212 ; THUMB6-NEXT: rsbs r0, r1, #0
213 ; THUMB6-NEXT: adcs r0, r1
214 ; THUMB6-NEXT: bx lr
215 ;
216 ; THUMB78-LABEL: scalar_i16_lowestbit_eq:
217 ; THUMB78: @ %bb.0:
218 ; THUMB78-NEXT: uxth r1, r1
219 ; THUMB78-NEXT: movs r2, #1
220 ; THUMB78-NEXT: lsl.w r1, r2, r1
221 ; THUMB78-NEXT: ands r0, r1
222 ; THUMB78-NEXT: uxth r0, r0
223 ; THUMB78-NEXT: clz r0, r0
224 ; THUMB78-NEXT: lsrs r0, r0, #5
225 ; THUMB78-NEXT: bx lr
226 %t0 = shl i16 1, %y
227 %t1 = and i16 %t0, %x
228 %res = icmp eq i16 %t1, 0
229 ret i1 %res
230 }
231
232 define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
233 ; ARM-LABEL: scalar_i16_bitsinmiddle_eq:
234 ; ARM: @ %bb.0:
235 ; ARM-NEXT: uxth r1, r1
236 ; ARM-NEXT: mov r2, #4080
237 ; ARM-NEXT: and r0, r0, r2, lsl r1
238 ; ARM-NEXT: uxth r0, r0
239 ; ARM-NEXT: clz r0, r0
240 ; ARM-NEXT: lsr r0, r0, #5
241 ; ARM-NEXT: bx lr
242 ;
243 ; THUMB6-LABEL: scalar_i16_bitsinmiddle_eq:
244 ; THUMB6: @ %bb.0:
245 ; THUMB6-NEXT: uxth r1, r1
246 ; THUMB6-NEXT: movs r2, #255
247 ; THUMB6-NEXT: lsls r2, r2, #4
248 ; THUMB6-NEXT: lsls r2, r1
249 ; THUMB6-NEXT: ands r2, r0
250 ; THUMB6-NEXT: uxth r1, r2
251 ; THUMB6-NEXT: rsbs r0, r1, #0
252 ; THUMB6-NEXT: adcs r0, r1
253 ; THUMB6-NEXT: bx lr
254 ;
255 ; THUMB78-LABEL: scalar_i16_bitsinmiddle_eq:
256 ; THUMB78: @ %bb.0:
257 ; THUMB78-NEXT: uxth r1, r1
258 ; THUMB78-NEXT: mov.w r2, #4080
259 ; THUMB78-NEXT: lsl.w r1, r2, r1
260 ; THUMB78-NEXT: ands r0, r1
261 ; THUMB78-NEXT: uxth r0, r0
262 ; THUMB78-NEXT: clz r0, r0
263 ; THUMB78-NEXT: lsrs r0, r0, #5
264 ; THUMB78-NEXT: bx lr
265 %t0 = shl i16 4080, %y
266 %t1 = and i16 %t0, %x
267 %res = icmp eq i16 %t1, 0
268 ret i1 %res
269 }
270
271 ; i32 scalar
272
273 define i1 @scalar_i32_signbit_eq(i32 %x, i32 %y) nounwind {
274 ; ARM-LABEL: scalar_i32_signbit_eq:
275 ; ARM: @ %bb.0:
276 ; ARM-NEXT: mov r2, #-2147483648
277 ; ARM-NEXT: and r0, r0, r2, lsl r1
278 ; ARM-NEXT: clz r0, r0
279 ; ARM-NEXT: lsr r0, r0, #5
280 ; ARM-NEXT: bx lr
281 ;
282 ; THUMB6-LABEL: scalar_i32_signbit_eq:
283 ; THUMB6: @ %bb.0:
284 ; THUMB6-NEXT: movs r2, #1
285 ; THUMB6-NEXT: lsls r2, r2, #31
286 ; THUMB6-NEXT: lsls r2, r1
287 ; THUMB6-NEXT: ands r2, r0
288 ; THUMB6-NEXT: rsbs r0, r2, #0
289 ; THUMB6-NEXT: adcs r0, r2
290 ; THUMB6-NEXT: bx lr
291 ;
292 ; THUMB78-LABEL: scalar_i32_signbit_eq:
293 ; THUMB78: @ %bb.0:
294 ; THUMB78-NEXT: mov.w r2, #-2147483648
295 ; THUMB78-NEXT: lsl.w r1, r2, r1
296 ; THUMB78-NEXT: ands r0, r1
297 ; THUMB78-NEXT: clz r0, r0
298 ; THUMB78-NEXT: lsrs r0, r0, #5
299 ; THUMB78-NEXT: bx lr
300 %t0 = shl i32 2147483648, %y
301 %t1 = and i32 %t0, %x
302 %res = icmp eq i32 %t1, 0
303 ret i1 %res
304 }
305
306 define i1 @scalar_i32_lowestbit_eq(i32 %x, i32 %y) nounwind {
307 ; ARM-LABEL: scalar_i32_lowestbit_eq:
308 ; ARM: @ %bb.0:
309 ; ARM-NEXT: mov r2, #1
310 ; ARM-NEXT: and r0, r0, r2, lsl r1
311 ; ARM-NEXT: clz r0, r0
312 ; ARM-NEXT: lsr r0, r0, #5
313 ; ARM-NEXT: bx lr
314 ;
315 ; THUMB6-LABEL: scalar_i32_lowestbit_eq:
316 ; THUMB6: @ %bb.0:
317 ; THUMB6-NEXT: movs r2, #1
318 ; THUMB6-NEXT: lsls r2, r1
319 ; THUMB6-NEXT: ands r2, r0
320 ; THUMB6-NEXT: rsbs r0, r2, #0
321 ; THUMB6-NEXT: adcs r0, r2
322 ; THUMB6-NEXT: bx lr
323 ;
324 ; THUMB78-LABEL: scalar_i32_lowestbit_eq:
325 ; THUMB78: @ %bb.0:
326 ; THUMB78-NEXT: movs r2, #1
327 ; THUMB78-NEXT: lsl.w r1, r2, r1
328 ; THUMB78-NEXT: ands r0, r1
329 ; THUMB78-NEXT: clz r0, r0
330 ; THUMB78-NEXT: lsrs r0, r0, #5
331 ; THUMB78-NEXT: bx lr
332 %t0 = shl i32 1, %y
333 %t1 = and i32 %t0, %x
334 %res = icmp eq i32 %t1, 0
335 ret i1 %res
336 }
337
338 define i1 @scalar_i32_bitsinmiddle_eq(i32 %x, i32 %y) nounwind {
339 ; ARM6-LABEL: scalar_i32_bitsinmiddle_eq:
340 ; ARM6: @ %bb.0:
341 ; ARM6-NEXT: mov r2, #65280
342 ; ARM6-NEXT: orr r2, r2, #16711680
343 ; ARM6-NEXT: and r0, r0, r2, lsl r1
344 ; ARM6-NEXT: clz r0, r0
345 ; ARM6-NEXT: lsr r0, r0, #5
346 ; ARM6-NEXT: bx lr
347 ;
348 ; ARM78-LABEL: scalar_i32_bitsinmiddle_eq:
349 ; ARM78: @ %bb.0:
350 ; ARM78-NEXT: movw r2, #65280
351 ; ARM78-NEXT: movt r2, #255
352 ; ARM78-NEXT: and r0, r0, r2, lsl r1
353 ; ARM78-NEXT: clz r0, r0
354 ; ARM78-NEXT: lsr r0, r0, #5
355 ; ARM78-NEXT: bx lr
356 ;
357 ; THUMB6-LABEL: scalar_i32_bitsinmiddle_eq:
358 ; THUMB6: @ %bb.0:
359 ; THUMB6-NEXT: ldr r2, .LCPI8_0
360 ; THUMB6-NEXT: lsls r2, r1
361 ; THUMB6-NEXT: ands r2, r0
362 ; THUMB6-NEXT: rsbs r0, r2, #0
363 ; THUMB6-NEXT: adcs r0, r2
364 ; THUMB6-NEXT: bx lr
365 ; THUMB6-NEXT: .p2align 2
366 ; THUMB6-NEXT: @ %bb.1:
367 ; THUMB6-NEXT: .LCPI8_0:
368 ; THUMB6-NEXT: .long 16776960 @ 0xffff00
369 ;
370 ; THUMB78-LABEL: scalar_i32_bitsinmiddle_eq:
371 ; THUMB78: @ %bb.0:
372 ; THUMB78-NEXT: movw r2, #65280
373 ; THUMB78-NEXT: movt r2, #255
374 ; THUMB78-NEXT: lsl.w r1, r2, r1
375 ; THUMB78-NEXT: ands r0, r1
376 ; THUMB78-NEXT: clz r0, r0
377 ; THUMB78-NEXT: lsrs r0, r0, #5
378 ; THUMB78-NEXT: bx lr
379 %t0 = shl i32 16776960, %y
380 %t1 = and i32 %t0, %x
381 %res = icmp eq i32 %t1, 0
382 ret i1 %res
383 }
384
385 ; i64 scalar
386
387 define i1 @scalar_i64_signbit_eq(i64 %x, i64 %y) nounwind {
388 ; ARM6-LABEL: scalar_i64_signbit_eq:
389 ; ARM6: @ %bb.0:
390 ; ARM6-NEXT: mov r0, #-2147483648
391 ; ARM6-NEXT: lsl r0, r0, r2
392 ; ARM6-NEXT: sub r2, r2, #32
393 ; ARM6-NEXT: cmp r2, #0
394 ; ARM6-NEXT: movge r0, #0
395 ; ARM6-NEXT: and r0, r0, r1
396 ; ARM6-NEXT: clz r0, r0
397 ; ARM6-NEXT: lsr r0, r0, #5
398 ; ARM6-NEXT: bx lr
399 ;
400 ; ARM78-LABEL: scalar_i64_signbit_eq:
401 ; ARM78: @ %bb.0:
402 ; ARM78-NEXT: mov r0, #-2147483648
403 ; ARM78-NEXT: lsl r0, r0, r2
404 ; ARM78-NEXT: sub r2, r2, #32
405 ; ARM78-NEXT: cmp r2, #0
406 ; ARM78-NEXT: movwge r0, #0
407 ; ARM78-NEXT: and r0, r0, r1
408 ; ARM78-NEXT: clz r0, r0
409 ; ARM78-NEXT: lsr r0, r0, #5
410 ; ARM78-NEXT: bx lr
411 ;
412 ; THUMB6-LABEL: scalar_i64_signbit_eq:
413 ; THUMB6: @ %bb.0:
414 ; THUMB6-NEXT: push {r4, r5, r7, lr}
415 ; THUMB6-NEXT: mov r4, r1
416 ; THUMB6-NEXT: mov r5, r0
417 ; THUMB6-NEXT: movs r0, #1
418 ; THUMB6-NEXT: lsls r1, r0, #31
419 ; THUMB6-NEXT: movs r0, #0
420 ; THUMB6-NEXT: bl __ashldi3
421 ; THUMB6-NEXT: ands r1, r4
422 ; THUMB6-NEXT: ands r0, r5
423 ; THUMB6-NEXT: orrs r0, r1
424 ; THUMB6-NEXT: rsbs r1, r0, #0
425 ; THUMB6-NEXT: adcs r0, r1
426 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
427 ;
428 ; THUMB78-LABEL: scalar_i64_signbit_eq:
429 ; THUMB78: @ %bb.0:
430 ; THUMB78-NEXT: mov.w r0, #-2147483648
431 ; THUMB78-NEXT: lsls r0, r2
432 ; THUMB78-NEXT: subs r2, #32
433 ; THUMB78-NEXT: cmp r2, #0
434 ; THUMB78-NEXT: it ge
435 ; THUMB78-NEXT: movge r0, #0
436 ; THUMB78-NEXT: ands r0, r1
437 ; THUMB78-NEXT: clz r0, r0
438 ; THUMB78-NEXT: lsrs r0, r0, #5
439 ; THUMB78-NEXT: bx lr
440 %t0 = shl i64 9223372036854775808, %y
441 %t1 = and i64 %t0, %x
442 %res = icmp eq i64 %t1, 0
443 ret i1 %res
444 }
445
446 define i1 @scalar_i64_lowestbit_eq(i64 %x, i64 %y) nounwind {
447 ; ARM6-LABEL: scalar_i64_lowestbit_eq:
448 ; ARM6: @ %bb.0:
449 ; ARM6-NEXT: push {r11, lr}
450 ; ARM6-NEXT: mov r12, #1
451 ; ARM6-NEXT: sub lr, r2, #32
452 ; ARM6-NEXT: lsl r3, r12, r2
453 ; ARM6-NEXT: rsb r2, r2, #32
454 ; ARM6-NEXT: cmp lr, #0
455 ; ARM6-NEXT: lsr r2, r12, r2
456 ; ARM6-NEXT: movge r3, #0
457 ; ARM6-NEXT: lslge r2, r12, lr
458 ; ARM6-NEXT: and r0, r3, r0
459 ; ARM6-NEXT: and r1, r2, r1
460 ; ARM6-NEXT: orr r0, r0, r1
461 ; ARM6-NEXT: clz r0, r0
462 ; ARM6-NEXT: lsr r0, r0, #5
463 ; ARM6-NEXT: pop {r11, pc}
464 ;
465 ; ARM78-LABEL: scalar_i64_lowestbit_eq:
466 ; ARM78: @ %bb.0:
467 ; ARM78-NEXT: push {r11, lr}
468 ; ARM78-NEXT: mov r12, #1
469 ; ARM78-NEXT: sub lr, r2, #32
470 ; ARM78-NEXT: lsl r3, r12, r2
471 ; ARM78-NEXT: rsb r2, r2, #32
472 ; ARM78-NEXT: cmp lr, #0
473 ; ARM78-NEXT: lsr r2, r12, r2
474 ; ARM78-NEXT: movwge r3, #0
475 ; ARM78-NEXT: lslge r2, r12, lr
476 ; ARM78-NEXT: and r0, r3, r0
477 ; ARM78-NEXT: and r1, r2, r1
478 ; ARM78-NEXT: orr r0, r0, r1
479 ; ARM78-NEXT: clz r0, r0
480 ; ARM78-NEXT: lsr r0, r0, #5
481 ; ARM78-NEXT: pop {r11, pc}
482 ;
483 ; THUMB6-LABEL: scalar_i64_lowestbit_eq:
484 ; THUMB6: @ %bb.0:
485 ; THUMB6-NEXT: push {r4, r5, r7, lr}
486 ; THUMB6-NEXT: mov r4, r1
487 ; THUMB6-NEXT: mov r5, r0
488 ; THUMB6-NEXT: movs r0, #1
489 ; THUMB6-NEXT: movs r1, #0
490 ; THUMB6-NEXT: bl __ashldi3
491 ; THUMB6-NEXT: ands r1, r4
492 ; THUMB6-NEXT: ands r0, r5
493 ; THUMB6-NEXT: orrs r0, r1
494 ; THUMB6-NEXT: rsbs r1, r0, #0
495 ; THUMB6-NEXT: adcs r0, r1
496 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
497 ;
498 ; THUMB7-LABEL: scalar_i64_lowestbit_eq:
499 ; THUMB7: @ %bb.0:
500 ; THUMB7-NEXT: push {r7, lr}
501 ; THUMB7-NEXT: rsb.w r3, r2, #32
502 ; THUMB7-NEXT: mov.w r12, #1
503 ; THUMB7-NEXT: sub.w lr, r2, #32
504 ; THUMB7-NEXT: lsl.w r2, r12, r2
505 ; THUMB7-NEXT: lsr.w r3, r12, r3
506 ; THUMB7-NEXT: cmp.w lr, #0
507 ; THUMB7-NEXT: it ge
508 ; THUMB7-NEXT: lslge.w r3, r12, lr
509 ; THUMB7-NEXT: it ge
510 ; THUMB7-NEXT: movge r2, #0
511 ; THUMB7-NEXT: ands r1, r3
512 ; THUMB7-NEXT: ands r0, r2
513 ; THUMB7-NEXT: orrs r0, r1
514 ; THUMB7-NEXT: clz r0, r0
515 ; THUMB7-NEXT: lsrs r0, r0, #5
516 ; THUMB7-NEXT: pop {r7, pc}
517 ;
518 ; THUMB8-LABEL: scalar_i64_lowestbit_eq:
519 ; THUMB8: @ %bb.0:
520 ; THUMB8-NEXT: .save {r7, lr}
521 ; THUMB8-NEXT: push {r7, lr}
522 ; THUMB8-NEXT: rsb.w r3, r2, #32
523 ; THUMB8-NEXT: sub.w lr, r2, #32
524 ; THUMB8-NEXT: mov.w r12, #1
525 ; THUMB8-NEXT: cmp.w lr, #0
526 ; THUMB8-NEXT: lsr.w r3, r12, r3
527 ; THUMB8-NEXT: lsl.w r2, r12, r2
528 ; THUMB8-NEXT: it ge
529 ; THUMB8-NEXT: lslge.w r3, r12, lr
530 ; THUMB8-NEXT: it ge
531 ; THUMB8-NEXT: movge r2, #0
532 ; THUMB8-NEXT: ands r1, r3
533 ; THUMB8-NEXT: ands r0, r2
534 ; THUMB8-NEXT: orrs r0, r1
535 ; THUMB8-NEXT: clz r0, r0
536 ; THUMB8-NEXT: lsrs r0, r0, #5
537 ; THUMB8-NEXT: pop {r7, pc}
538 %t0 = shl i64 1, %y
539 %t1 = and i64 %t0, %x
540 %res = icmp eq i64 %t1, 0
541 ret i1 %res
542 }
543
544 define i1 @scalar_i64_bitsinmiddle_eq(i64 %x, i64 %y) nounwind {
545 ; ARM6-LABEL: scalar_i64_bitsinmiddle_eq:
546 ; ARM6: @ %bb.0:
547 ; ARM6-NEXT: push {r4, lr}
548 ; ARM6-NEXT: mov r12, #16711680
549 ; ARM6-NEXT: sub lr, r2, #32
550 ; ARM6-NEXT: orr r12, r12, #-16777216
551 ; ARM6-NEXT: cmp lr, #0
552 ; ARM6-NEXT: mov r4, #255
553 ; ARM6-NEXT: lsl r3, r12, r2
554 ; ARM6-NEXT: orr r4, r4, #65280
555 ; ARM6-NEXT: movge r3, #0
556 ; ARM6-NEXT: and r0, r3, r0
557 ; ARM6-NEXT: rsb r3, r2, #32
558 ; ARM6-NEXT: cmp lr, #0
559 ; ARM6-NEXT: lsr r3, r12, r3
560 ; ARM6-NEXT: orr r2, r3, r4, lsl r2
561 ; ARM6-NEXT: lslge r2, r12, lr
562 ; ARM6-NEXT: and r1, r2, r1
563 ; ARM6-NEXT: orr r0, r0, r1
564 ; ARM6-NEXT: clz r0, r0
565 ; ARM6-NEXT: lsr r0, r0, #5
566 ; ARM6-NEXT: pop {r4, pc}
567 ;
568 ; ARM78-LABEL: scalar_i64_bitsinmiddle_eq:
569 ; ARM78: @ %bb.0:
570 ; ARM78-NEXT: push {r4, lr}
571 ; ARM78-NEXT: movw r12, #0
572 ; ARM78-NEXT: sub lr, r2, #32
573 ; ARM78-NEXT: movt r12, #65535
574 ; ARM78-NEXT: cmp lr, #0
575 ; ARM78-NEXT: lsl r3, r12, r2
576 ; ARM78-NEXT: movw r4, #65535
577 ; ARM78-NEXT: movwge r3, #0
578 ; ARM78-NEXT: and r0, r3, r0
579 ; ARM78-NEXT: rsb r3, r2, #32
580 ; ARM78-NEXT: cmp lr, #0
581 ; ARM78-NEXT: lsr r3, r12, r3
582 ; ARM78-NEXT: orr r2, r3, r4, lsl r2
583 ; ARM78-NEXT: lslge r2, r12, lr
584 ; ARM78-NEXT: and r1, r2, r1
585 ; ARM78-NEXT: orr r0, r0, r1
586 ; ARM78-NEXT: clz r0, r0
587 ; ARM78-NEXT: lsr r0, r0, #5
588 ; ARM78-NEXT: pop {r4, pc}
589 ;
590 ; THUMB6-LABEL: scalar_i64_bitsinmiddle_eq:
591 ; THUMB6: @ %bb.0:
592 ; THUMB6-NEXT: push {r4, r5, r7, lr}
593 ; THUMB6-NEXT: mov r4, r1
594 ; THUMB6-NEXT: mov r5, r0
595 ; THUMB6-NEXT: ldr r0, .LCPI11_0
596 ; THUMB6-NEXT: ldr r1, .LCPI11_1
597 ; THUMB6-NEXT: bl __ashldi3
598 ; THUMB6-NEXT: ands r1, r4
599 ; THUMB6-NEXT: ands r0, r5
600 ; THUMB6-NEXT: orrs r0, r1
601 ; THUMB6-NEXT: rsbs r1, r0, #0
602 ; THUMB6-NEXT: adcs r0, r1
603 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
604 ; THUMB6-NEXT: .p2align 2
605 ; THUMB6-NEXT: @ %bb.1:
606 ; THUMB6-NEXT: .LCPI11_0:
607 ; THUMB6-NEXT: .long 4294901760 @ 0xffff0000
608 ; THUMB6-NEXT: .LCPI11_1:
609 ; THUMB6-NEXT: .long 65535 @ 0xffff
610 ;
611 ; THUMB7-LABEL: scalar_i64_bitsinmiddle_eq:
612 ; THUMB7: @ %bb.0:
613 ; THUMB7-NEXT: push {r7, lr}
614 ; THUMB7-NEXT: movw r3, #65535
615 ; THUMB7-NEXT: movw lr, #0
616 ; THUMB7-NEXT: lsl.w r12, r3, r2
617 ; THUMB7-NEXT: rsb.w r3, r2, #32
618 ; THUMB7-NEXT: movt lr, #65535
619 ; THUMB7-NEXT: lsr.w r3, lr, r3
620 ; THUMB7-NEXT: orr.w r3, r3, r12
621 ; THUMB7-NEXT: sub.w r12, r2, #32
622 ; THUMB7-NEXT: lsl.w r2, lr, r2
623 ; THUMB7-NEXT: cmp.w r12, #0
624 ; THUMB7-NEXT: it ge
625 ; THUMB7-NEXT: lslge.w r3, lr, r12
626 ; THUMB7-NEXT: it ge
627 ; THUMB7-NEXT: movge r2, #0
628 ; THUMB7-NEXT: ands r1, r3
629 ; THUMB7-NEXT: ands r0, r2
630 ; THUMB7-NEXT: orrs r0, r1
631 ; THUMB7-NEXT: clz r0, r0
632 ; THUMB7-NEXT: lsrs r0, r0, #5
633 ; THUMB7-NEXT: pop {r7, pc}
634 ;
635 ; THUMB8-LABEL: scalar_i64_bitsinmiddle_eq:
636 ; THUMB8: @ %bb.0:
637 ; THUMB8-NEXT: .save {r7, lr}
638 ; THUMB8-NEXT: push {r7, lr}
639 ; THUMB8-NEXT: movw r3, #65535
640 ; THUMB8-NEXT: movw lr, #0
641 ; THUMB8-NEXT: lsl.w r12, r3, r2
642 ; THUMB8-NEXT: rsb.w r3, r2, #32
643 ; THUMB8-NEXT: movt lr, #65535
644 ; THUMB8-NEXT: lsr.w r3, lr, r3
645 ; THUMB8-NEXT: orr.w r3, r3, r12
646 ; THUMB8-NEXT: sub.w r12, r2, #32
647 ; THUMB8-NEXT: cmp.w r12, #0
648 ; THUMB8-NEXT: lsl.w r2, lr, r2
649 ; THUMB8-NEXT: it ge
650 ; THUMB8-NEXT: lslge.w r3, lr, r12
651 ; THUMB8-NEXT: it ge
652 ; THUMB8-NEXT: movge r2, #0
653 ; THUMB8-NEXT: ands r1, r3
654 ; THUMB8-NEXT: ands r0, r2
655 ; THUMB8-NEXT: orrs r0, r1
656 ; THUMB8-NEXT: clz r0, r0
657 ; THUMB8-NEXT: lsrs r0, r0, #5
658 ; THUMB8-NEXT: pop {r7, pc}
659 %t0 = shl i64 281474976645120, %y
660 %t1 = and i64 %t0, %x
661 %res = icmp eq i64 %t1, 0
662 ret i1 %res
663 }
664
665 ;------------------------------------------------------------------------------;
666 ; A few trivial vector tests
667 ;------------------------------------------------------------------------------;
668
669 define <4 x i1> @vec_4xi32_splat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
670 ; ARM6-LABEL: vec_4xi32_splat_eq:
671 ; ARM6: @ %bb.0:
672 ; ARM6-NEXT: push {r11, lr}
673 ; ARM6-NEXT: ldr r12, [sp, #8]
674 ; ARM6-NEXT: mov lr, #1
675 ; ARM6-NEXT: and r0, r0, lr, lsl r12
676 ; ARM6-NEXT: ldr r12, [sp, #12]
677 ; ARM6-NEXT: clz r0, r0
678 ; ARM6-NEXT: and r1, r1, lr, lsl r12
679 ; ARM6-NEXT: ldr r12, [sp, #16]
680 ; ARM6-NEXT: clz r1, r1
681 ; ARM6-NEXT: lsr r0, r0, #5
682 ; ARM6-NEXT: and r2, r2, lr, lsl r12
683 ; ARM6-NEXT: ldr r12, [sp, #20]
684 ; ARM6-NEXT: clz r2, r2
685 ; ARM6-NEXT: lsr r1, r1, #5
686 ; ARM6-NEXT: and r3, r3, lr, lsl r12
687 ; ARM6-NEXT: lsr r2, r2, #5
688 ; ARM6-NEXT: clz r3, r3
689 ; ARM6-NEXT: lsr r3, r3, #5
690 ; ARM6-NEXT: pop {r11, pc}
691 ;
692 ; ARM78-LABEL: vec_4xi32_splat_eq:
693 ; ARM78: @ %bb.0:
694 ; ARM78-NEXT: vmov.i32 q8, #0x1
695 ; ARM78-NEXT: mov r12, sp
696 ; ARM78-NEXT: vld1.64 {d18, d19}, [r12]
697 ; ARM78-NEXT: vshl.u32 q8, q8, q9
698 ; ARM78-NEXT: vmov d19, r2, r3
699 ; ARM78-NEXT: vmov d18, r0, r1
700 ; ARM78-NEXT: vtst.32 q8, q8, q9
701 ; ARM78-NEXT: vmvn q8, q8
702 ; ARM78-NEXT: vmovn.i32 d16, q8
703 ; ARM78-NEXT: vmov r0, r1, d16
704 ; ARM78-NEXT: bx lr
705 ;
706 ; THUMB6-LABEL: vec_4xi32_splat_eq:
707 ; THUMB6: @ %bb.0:
708 ; THUMB6-NEXT: push {r4, r5, r6, lr}
709 ; THUMB6-NEXT: ldr r5, [sp, #16]
710 ; THUMB6-NEXT: movs r4, #1
711 ; THUMB6-NEXT: mov r6, r4
712 ; THUMB6-NEXT: lsls r6, r5
713 ; THUMB6-NEXT: ands r6, r0
714 ; THUMB6-NEXT: rsbs r0, r6, #0
715 ; THUMB6-NEXT: adcs r0, r6
716 ; THUMB6-NEXT: ldr r5, [sp, #20]
717 ; THUMB6-NEXT: mov r6, r4
718 ; THUMB6-NEXT: lsls r6, r5
719 ; THUMB6-NEXT: ands r6, r1
720 ; THUMB6-NEXT: rsbs r1, r6, #0
721 ; THUMB6-NEXT: adcs r1, r6
722 ; THUMB6-NEXT: ldr r5, [sp, #24]
723 ; THUMB6-NEXT: mov r6, r4
724 ; THUMB6-NEXT: lsls r6, r5
725 ; THUMB6-NEXT: ands r6, r2
726 ; THUMB6-NEXT: rsbs r2, r6, #0
727 ; THUMB6-NEXT: adcs r2, r6
728 ; THUMB6-NEXT: ldr r5, [sp, #28]
729 ; THUMB6-NEXT: lsls r4, r5
730 ; THUMB6-NEXT: ands r4, r3
731 ; THUMB6-NEXT: rsbs r3, r4, #0
732 ; THUMB6-NEXT: adcs r3, r4
733 ; THUMB6-NEXT: pop {r4, r5, r6, pc}
734 ;
735 ; THUMB78-LABEL: vec_4xi32_splat_eq:
736 ; THUMB78: @ %bb.0:
737 ; THUMB78-NEXT: vmov.i32 q8, #0x1
738 ; THUMB78-NEXT: mov r12, sp
739 ; THUMB78-NEXT: vld1.64 {d18, d19}, [r12]
740 ; THUMB78-NEXT: vshl.u32 q8, q8, q9
741 ; THUMB78-NEXT: vmov d19, r2, r3
742 ; THUMB78-NEXT: vmov d18, r0, r1
743 ; THUMB78-NEXT: vtst.32 q8, q8, q9
744 ; THUMB78-NEXT: vmvn q8, q8
745 ; THUMB78-NEXT: vmovn.i32 d16, q8
746 ; THUMB78-NEXT: vmov r0, r1, d16
747 ; THUMB78-NEXT: bx lr
748 %t0 = shl <4 x i32> , %y
749 %t1 = and <4 x i32> %t0, %x
750 %res = icmp eq <4 x i32> %t1,
751 ret <4 x i1> %res
752 }
753
754 define <4 x i1> @vec_4xi32_nonsplat_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
755 ; ARM6-LABEL: vec_4xi32_nonsplat_eq:
756 ; ARM6: @ %bb.0:
757 ; ARM6-NEXT: ldr r12, [sp, #4]
758 ; ARM6-NEXT: mov r0, #1
759 ; ARM6-NEXT: and r0, r1, r0, lsl r12
760 ; ARM6-NEXT: ldr r12, [sp, #8]
761 ; ARM6-NEXT: clz r0, r0
762 ; ARM6-NEXT: lsr r1, r0, #5
763 ; ARM6-NEXT: mov r0, #65280
764 ; ARM6-NEXT: orr r0, r0, #16711680
765 ; ARM6-NEXT: and r0, r2, r0, lsl r12
766 ; ARM6-NEXT: ldr r12, [sp, #12]
767 ; ARM6-NEXT: clz r0, r0
768 ; ARM6-NEXT: lsr r2, r0, #5
769 ; ARM6-NEXT: mov r0, #-2147483648
770 ; ARM6-NEXT: and r0, r3, r0, lsl r12
771 ; ARM6-NEXT: clz r0, r0
772 ; ARM6-NEXT: lsr r3, r0, #5
773 ; ARM6-NEXT: mov r0, #1
774 ; ARM6-NEXT: bx lr
775 ;
776 ; ARM78-LABEL: vec_4xi32_nonsplat_eq:
777 ; ARM78: @ %bb.0:
778 ; ARM78-NEXT: mov r12, sp
779 ; ARM78-NEXT: vld1.64 {d16, d17}, [r12]
780 ; ARM78-NEXT: adr r12, .LCPI13_0
781 ; ARM78-NEXT: vld1.64 {d18, d19}, [r12:128]
782 ; ARM78-NEXT: vshl.u32 q8, q9, q8
783 ; ARM78-NEXT: vmov d19, r2, r3
784 ; ARM78-NEXT: vmov d18, r0, r1
785 ; ARM78-NEXT: vtst.32 q8, q8, q9
786 ; ARM78-NEXT: vmvn q8, q8
787 ; ARM78-NEXT: vmovn.i32 d16, q8
788 ; ARM78-NEXT: vmov r0, r1, d16
789 ; ARM78-NEXT: bx lr
790 ; ARM78-NEXT: .p2align 4
791 ; ARM78-NEXT: @ %bb.1:
792 ; ARM78-NEXT: .LCPI13_0:
793 ; ARM78-NEXT: .long 0 @ 0x0
794 ; ARM78-NEXT: .long 1 @ 0x1
795 ; ARM78-NEXT: .long 16776960 @ 0xffff00
796 ; ARM78-NEXT: .long 2147483648 @ 0x80000000
797 ;
798 ; THUMB6-LABEL: vec_4xi32_nonsplat_eq:
799 ; THUMB6: @ %bb.0:
800 ; THUMB6-NEXT: push {r4, r5, r7, lr}
801 ; THUMB6-NEXT: ldr r4, [sp, #20]
802 ; THUMB6-NEXT: movs r0, #1
803 ; THUMB6-NEXT: mov r5, r0
804 ; THUMB6-NEXT: lsls r5, r4
805 ; THUMB6-NEXT: ands r5, r1
806 ; THUMB6-NEXT: rsbs r1, r5, #0
807 ; THUMB6-NEXT: adcs r1, r5
808 ; THUMB6-NEXT: ldr r4, [sp, #24]
809 ; THUMB6-NEXT: ldr r5, .LCPI13_0
810 ; THUMB6-NEXT: lsls r5, r4
811 ; THUMB6-NEXT: ands r5, r2
812 ; THUMB6-NEXT: rsbs r2, r5, #0
813 ; THUMB6-NEXT: adcs r2, r5
814 ; THUMB6-NEXT: lsls r4, r0, #31
815 ; THUMB6-NEXT: ldr r5, [sp, #28]
816 ; THUMB6-NEXT: lsls r4, r5
817 ; THUMB6-NEXT: ands r4, r3
818 ; THUMB6-NEXT: rsbs r3, r4, #0
819 ; THUMB6-NEXT: adcs r3, r4
820 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
821 ; THUMB6-NEXT: .p2align 2
822 ; THUMB6-NEXT: @ %bb.1:
823 ; THUMB6-NEXT: .LCPI13_0:
824 ; THUMB6-NEXT: .long 16776960 @ 0xffff00
825 ;
826 ; THUMB78-LABEL: vec_4xi32_nonsplat_eq:
827 ; THUMB78: @ %bb.0:
828 ; THUMB78-NEXT: mov r12, sp
829 ; THUMB78-NEXT: vld1.64 {d16, d17}, [r12]
830 ; THUMB78-NEXT: adr.w r12, .LCPI13_0
831 ; THUMB78-NEXT: vld1.64 {d18, d19}, [r12:128]
832 ; THUMB78-NEXT: vshl.u32 q8, q9, q8
833 ; THUMB78-NEXT: vmov d19, r2, r3
834 ; THUMB78-NEXT: vmov d18, r0, r1
835 ; THUMB78-NEXT: vtst.32 q8, q8, q9
836 ; THUMB78-NEXT: vmvn q8, q8
837 ; THUMB78-NEXT: vmovn.i32 d16, q8
838 ; THUMB78-NEXT: vmov r0, r1, d16
839 ; THUMB78-NEXT: bx lr
840 ; THUMB78-NEXT: .p2align 4
841 ; THUMB78-NEXT: @ %bb.1:
842 ; THUMB78-NEXT: .LCPI13_0:
843 ; THUMB78-NEXT: .long 0 @ 0x0
844 ; THUMB78-NEXT: .long 1 @ 0x1
845 ; THUMB78-NEXT: .long 16776960 @ 0xffff00
846 ; THUMB78-NEXT: .long 2147483648 @ 0x80000000
847 %t0 = shl <4 x i32> , %y
848 %t1 = and <4 x i32> %t0, %x
849 %res = icmp eq <4 x i32> %t1,
850 ret <4 x i1> %res
851 }
852
853 define <4 x i1> @vec_4xi32_nonsplat_undef0_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
854 ; ARM6-LABEL: vec_4xi32_nonsplat_undef0_eq:
855 ; ARM6: @ %bb.0:
856 ; ARM6-NEXT: push {r11, lr}
857 ; ARM6-NEXT: ldr r2, [sp, #12]
858 ; ARM6-NEXT: mov lr, #1
859 ; ARM6-NEXT: ldr r12, [sp, #8]
860 ; ARM6-NEXT: and r1, r1, lr, lsl r2
861 ; ARM6-NEXT: ldr r2, [sp, #20]
862 ; ARM6-NEXT: and r0, r0, lr, lsl r12
863 ; ARM6-NEXT: clz r1, r1
864 ; ARM6-NEXT: clz r0, r0
865 ; ARM6-NEXT: and r2, r3, lr, lsl r2
866 ; ARM6-NEXT: lsr r1, r1, #5
867 ; ARM6-NEXT: clz r2, r2
868 ; ARM6-NEXT: lsr r0, r0, #5
869 ; ARM6-NEXT: lsr r3, r2, #5
870 ; ARM6-NEXT: mov r2, #1
871 ; ARM6-NEXT: pop {r11, pc}
872 ;
873 ; ARM78-LABEL: vec_4xi32_nonsplat_undef0_eq:
874 ; ARM78: @ %bb.0:
875 ; ARM78-NEXT: vmov.i32 q8, #0x1
876 ; ARM78-NEXT: mov r12, sp
877 ; ARM78-NEXT: vld1.64 {d18, d19}, [r12]
878 ; ARM78-NEXT: vshl.u32 q8, q8, q9
879 ; ARM78-NEXT: vmov d19, r2, r3
880 ; ARM78-NEXT: vmov d18, r0, r1
881 ; ARM78-NEXT: vtst.32 q8, q8, q9
882 ; ARM78-NEXT: vmvn q8, q8
883 ; ARM78-NEXT: vmovn.i32 d16, q8
884 ; ARM78-NEXT: vmov r0, r1, d16
885 ; ARM78-NEXT: bx lr
886 ;
887 ; THUMB6-LABEL: vec_4xi32_nonsplat_undef0_eq:
888 ; THUMB6: @ %bb.0:
889 ; THUMB6-NEXT: push {r4, r5, r7, lr}
890 ; THUMB6-NEXT: ldr r4, [sp, #16]
891 ; THUMB6-NEXT: movs r2, #1
892 ; THUMB6-NEXT: mov r5, r2
893 ; THUMB6-NEXT: lsls r5, r4
894 ; THUMB6-NEXT: ands r5, r0
895 ; THUMB6-NEXT: rsbs r0, r5, #0
896 ; THUMB6-NEXT: adcs r0, r5
897 ; THUMB6-NEXT: ldr r4, [sp, #20]
898 ; THUMB6-NEXT: mov r5, r2
899 ; THUMB6-NEXT: lsls r5, r4
900 ; THUMB6-NEXT: ands r5, r1
901 ; THUMB6-NEXT: rsbs r1, r5, #0
902 ; THUMB6-NEXT: adcs r1, r5
903 ; THUMB6-NEXT: ldr r4, [sp, #28]
904 ; THUMB6-NEXT: mov r5, r2
905 ; THUMB6-NEXT: lsls r5, r4
906 ; THUMB6-NEXT: ands r5, r3
907 ; THUMB6-NEXT: rsbs r3, r5, #0
908 ; THUMB6-NEXT: adcs r3, r5
909 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
910 ;
911 ; THUMB78-LABEL: vec_4xi32_nonsplat_undef0_eq:
912 ; THUMB78: @ %bb.0:
913 ; THUMB78-NEXT: vmov.i32 q8, #0x1
914 ; THUMB78-NEXT: mov r12, sp
915 ; THUMB78-NEXT: vld1.64 {d18, d19}, [r12]
916 ; THUMB78-NEXT: vshl.u32 q8, q8, q9
917 ; THUMB78-NEXT: vmov d19, r2, r3
918 ; THUMB78-NEXT: vmov d18, r0, r1
919 ; THUMB78-NEXT: vtst.32 q8, q8, q9
920 ; THUMB78-NEXT: vmvn q8, q8
921 ; THUMB78-NEXT: vmovn.i32 d16, q8
922 ; THUMB78-NEXT: vmov r0, r1, d16
923 ; THUMB78-NEXT: bx lr
924 %t0 = shl <4 x i32> , %y
925 %t1 = and <4 x i32> %t0, %x
926 %res = icmp eq <4 x i32> %t1,
927 ret <4 x i1> %res
928 }
929 define <4 x i1> @vec_4xi32_nonsplat_undef1_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
930 ; ARM6-LABEL: vec_4xi32_nonsplat_undef1_eq:
931 ; ARM6: @ %bb.0:
932 ; ARM6-NEXT: push {r11, lr}
933 ; ARM6-NEXT: ldr r2, [sp, #12]
934 ; ARM6-NEXT: mov lr, #1
935 ; ARM6-NEXT: ldr r12, [sp, #8]
936 ; ARM6-NEXT: and r1, r1, lr, lsl r2
937 ; ARM6-NEXT: ldr r2, [sp, #20]
938 ; ARM6-NEXT: and r0, r0, lr, lsl r12
939 ; ARM6-NEXT: clz r1, r1
940 ; ARM6-NEXT: clz r0, r0
941 ; ARM6-NEXT: and r2, r3, lr, lsl r2
942 ; ARM6-NEXT: lsr r1, r1, #5
943 ; ARM6-NEXT: clz r2, r2
944 ; ARM6-NEXT: lsr r0, r0, #5
945 ; ARM6-NEXT: lsr r3, r2, #5
946 ; ARM6-NEXT: pop {r11, pc}
947 ;
948 ; ARM78-LABEL: vec_4xi32_nonsplat_undef1_eq:
949 ; ARM78: @ %bb.0:
950 ; ARM78-NEXT: vmov.i32 q8, #0x1
951 ; ARM78-NEXT: mov r12, sp
952 ; ARM78-NEXT: vld1.64 {d18, d19}, [r12]
953 ; ARM78-NEXT: vshl.u32 q8, q8, q9
954 ; ARM78-NEXT: vmov d19, r2, r3
955 ; ARM78-NEXT: vmov d18, r0, r1
956 ; ARM78-NEXT: vtst.32 q8, q8, q9
957 ; ARM78-NEXT: vmvn q8, q8
958 ; ARM78-NEXT: vmovn.i32 d16, q8
959 ; ARM78-NEXT: vmov r0, r1, d16
960 ; ARM78-NEXT: bx lr
961 ;
962 ; THUMB6-LABEL: vec_4xi32_nonsplat_undef1_eq:
963 ; THUMB6: @ %bb.0:
964 ; THUMB6-NEXT: push {r4, r5, r7, lr}
965 ; THUMB6-NEXT: ldr r4, [sp, #16]
966 ; THUMB6-NEXT: movs r2, #1
967 ; THUMB6-NEXT: mov r5, r2
968 ; THUMB6-NEXT: lsls r5, r4
969 ; THUMB6-NEXT: ands r5, r0
970 ; THUMB6-NEXT: rsbs r0, r5, #0
971 ; THUMB6-NEXT: adcs r0, r5
972 ; THUMB6-NEXT: ldr r4, [sp, #20]
973 ; THUMB6-NEXT: mov r5, r2
974 ; THUMB6-NEXT: lsls r5, r4
975 ; THUMB6-NEXT: ands r5, r1
976 ; THUMB6-NEXT: rsbs r1, r5, #0
977 ; THUMB6-NEXT: adcs r1, r5
978 ; THUMB6-NEXT: ldr r4, [sp, #28]
979 ; THUMB6-NEXT: lsls r2, r4
980 ; THUMB6-NEXT: ands r2, r3
981 ; THUMB6-NEXT: rsbs r3, r2, #0
982 ; THUMB6-NEXT: adcs r3, r2
983 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
984 ;
985 ; THUMB78-LABEL: vec_4xi32_nonsplat_undef1_eq:
986 ; THUMB78: @ %bb.0:
987 ; THUMB78-NEXT: vmov.i32 q8, #0x1
988 ; THUMB78-NEXT: mov r12, sp
989 ; THUMB78-NEXT: vld1.64 {d18, d19}, [r12]
990 ; THUMB78-NEXT: vshl.u32 q8, q8, q9
991 ; THUMB78-NEXT: vmov d19, r2, r3
992 ; THUMB78-NEXT: vmov d18, r0, r1
993 ; THUMB78-NEXT: vtst.32 q8, q8, q9
994 ; THUMB78-NEXT: vmvn q8, q8
995 ; THUMB78-NEXT: vmovn.i32 d16, q8
996 ; THUMB78-NEXT: vmov r0, r1, d16
997 ; THUMB78-NEXT: bx lr
998 %t0 = shl <4 x i32> , %y
999 %t1 = and <4 x i32> %t0, %x
1000 %res = icmp eq <4 x i32> %t1,
1001 ret <4 x i1> %res
1002 }
1003 define <4 x i1> @vec_4xi32_nonsplat_undef2_eq(<4 x i32> %x, <4 x i32> %y) nounwind {
1004 ; ARM6-LABEL: vec_4xi32_nonsplat_undef2_eq:
1005 ; ARM6: @ %bb.0:
1006 ; ARM6-NEXT: push {r11, lr}
1007 ; ARM6-NEXT: ldr r2, [sp, #12]
1008 ; ARM6-NEXT: mov lr, #1
1009 ; ARM6-NEXT: ldr r12, [sp, #8]
1010 ; ARM6-NEXT: and r1, r1, lr, lsl r2
1011 ; ARM6-NEXT: ldr r2, [sp, #20]
1012 ; ARM6-NEXT: and r0, r0, lr, lsl r12
1013 ; ARM6-NEXT: clz r1, r1
1014 ; ARM6-NEXT: clz r0, r0
1015 ; ARM6-NEXT: and r2, r3, lr, lsl r2
1016 ; ARM6-NEXT: lsr r1, r1, #5
1017 ; ARM6-NEXT: clz r2, r2
1018 ; ARM6-NEXT: lsr r0, r0, #5
1019 ; ARM6-NEXT: lsr r3, r2, #5
1020 ; ARM6-NEXT: pop {r11, pc}
1021 ;
1022 ; ARM78-LABEL: vec_4xi32_nonsplat_undef2_eq:
1023 ; ARM78: @ %bb.0:
1024 ; ARM78-NEXT: vmov.i32 q8, #0x1
1025 ; ARM78-NEXT: mov r12, sp
1026 ; ARM78-NEXT: vld1.64 {d18, d19}, [r12]
1027 ; ARM78-NEXT: vshl.u32 q8, q8, q9
1028 ; ARM78-NEXT: vmov d19, r2, r3
1029 ; ARM78-NEXT: vmov d18, r0, r1
1030 ; ARM78-NEXT: vtst.32 q8, q8, q9
1031 ; ARM78-NEXT: vmvn q8, q8
1032 ; ARM78-NEXT: vmovn.i32 d16, q8
1033 ; ARM78-NEXT: vmov r0, r1, d16
1034 ; ARM78-NEXT: bx lr
1035 ;
1036 ; THUMB6-LABEL: vec_4xi32_nonsplat_undef2_eq:
1037 ; THUMB6: @ %bb.0:
1038 ; THUMB6-NEXT: push {r4, r5, r7, lr}
1039 ; THUMB6-NEXT: ldr r4, [sp, #16]
1040 ; THUMB6-NEXT: movs r2, #1
1041 ; THUMB6-NEXT: mov r5, r2
1042 ; THUMB6-NEXT: lsls r5, r4
1043 ; THUMB6-NEXT: ands r5, r0
1044 ; THUMB6-NEXT: rsbs r0, r5, #0
1045 ; THUMB6-NEXT: adcs r0, r5
1046 ; THUMB6-NEXT: ldr r4, [sp, #20]
1047 ; THUMB6-NEXT: mov r5, r2
1048 ; THUMB6-NEXT: lsls r5, r4
1049 ; THUMB6-NEXT: ands r5, r1
1050 ; THUMB6-NEXT: rsbs r1, r5, #0
1051 ; THUMB6-NEXT: adcs r1, r5
1052 ; THUMB6-NEXT: ldr r4, [sp, #28]
1053 ; THUMB6-NEXT: lsls r2, r4
1054 ; THUMB6-NEXT: ands r2, r3
1055 ; THUMB6-NEXT: rsbs r3, r2, #0
1056 ; THUMB6-NEXT: adcs r3, r2
1057 ; THUMB6-NEXT: pop {r4, r5, r7, pc}
1058 ;
1059 ; THUMB78-LABEL: vec_4xi32_nonsplat_undef2_eq:
1060 ; THUMB78: @ %bb.0:
1061 ; THUMB78-NEXT: vmov.i32 q8, #0x1
1062 ; THUMB78-NEXT: mov r12, sp
1063 ; THUMB78-NEXT: vld1.64 {d18, d19}, [r12]
1064 ; THUMB78-NEXT: vshl.u32 q8, q8, q9
1065 ; THUMB78-NEXT: vmov d19, r2, r3
1066 ; THUMB78-NEXT: vmov d18, r0, r1
1067 ; THUMB78-NEXT: vtst.32 q8, q8, q9
1068 ; THUMB78-NEXT: vmvn q8, q8
1069 ; THUMB78-NEXT: vmovn.i32 d16, q8
1070 ; THUMB78-NEXT: vmov r0, r1, d16
1071 ; THUMB78-NEXT: bx lr
1072 %t0 = shl <4 x i32> , %y
1073 %t1 = and <4 x i32> %t0, %x
1074 %res = icmp eq <4 x i32> %t1,
1075 ret <4 x i1> %res
1076 }
1077
1078 ;------------------------------------------------------------------------------;
1079 ; A special tests
1080 ;------------------------------------------------------------------------------;
1081
1082 define i1 @scalar_i8_signbit_ne(i8 %x, i8 %y) nounwind {
1083 ; ARM6-LABEL: scalar_i8_signbit_ne:
1084 ; ARM6: @ %bb.0:
1085 ; ARM6-NEXT: uxtb r1, r1
1086 ; ARM6-NEXT: mvn r2, #127
1087 ; ARM6-NEXT: and r0, r0, r2, lsl r1
1088 ; ARM6-NEXT: uxtb r0, r0
1089 ; ARM6-NEXT: cmp r0, #0
1090 ; ARM6-NEXT: movne r0, #1
1091 ; ARM6-NEXT: bx lr
1092 ;
1093 ; ARM78-LABEL: scalar_i8_signbit_ne:
1094 ; ARM78: @ %bb.0:
1095 ; ARM78-NEXT: uxtb r1, r1
1096 ; ARM78-NEXT: mvn r2, #127
1097 ; ARM78-NEXT: and r0, r0, r2, lsl r1
1098 ; ARM78-NEXT: uxtb r0, r0
1099 ; ARM78-NEXT: cmp r0, #0
1100 ; ARM78-NEXT: movwne r0, #1
1101 ; ARM78-NEXT: bx lr
1102 ;
1103 ; THUMB6-LABEL: scalar_i8_signbit_ne:
1104 ; THUMB6: @ %bb.0:
1105 ; THUMB6-NEXT: uxtb r1, r1
1106 ; THUMB6-NEXT: movs r2, #127
1107 ; THUMB6-NEXT: mvns r2, r2
1108 ; THUMB6-NEXT: lsls r2, r1
1109 ; THUMB6-NEXT: ands r2, r0
1110 ; THUMB6-NEXT: uxtb r0, r2
1111 ; THUMB6-NEXT: subs r1, r0, #1
1112 ; THUMB6-NEXT: sbcs r0, r1
1113 ; THUMB6-NEXT: bx lr
1114 ;
1115 ; THUMB78-LABEL: scalar_i8_signbit_ne:
1116 ; THUMB78: @ %bb.0:
1117 ; THUMB78-NEXT: uxtb r1, r1
1118 ; THUMB78-NEXT: mvn r2, #127
1119 ; THUMB78-NEXT: lsl.w r1, r2, r1
1120 ; THUMB78-NEXT: ands r0, r1
1121 ; THUMB78-NEXT: uxtb r0, r0
1122 ; THUMB78-NEXT: cmp r0, #0
1123 ; THUMB78-NEXT: it ne
1124 ; THUMB78-NEXT: movne r0, #1
1125 ; THUMB78-NEXT: bx lr
1126 %t0 = shl i8 128, %y
1127 %t1 = and i8 %t0, %x
1128 %res = icmp ne i8 %t1, 0 ; we are perfectly happy with 'ne' predicate
1129 ret i1 %res
1130 }
1131
1132 ;------------------------------------------------------------------------------;
1133 ; A few negative tests
1134 ;------------------------------------------------------------------------------;
1135
1136 define i1 @negative_scalar_i8_bitsinmiddle_slt(i8 %x, i8 %y) nounwind {
1137 ; ARM6-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1138 ; ARM6: @ %bb.0:
1139 ; ARM6-NEXT: uxtb r1, r1
1140 ; ARM6-NEXT: mov r2, #24
1141 ; ARM6-NEXT: and r0, r0, r2, lsl r1
1142 ; ARM6-NEXT: sxtb r1, r0
1143 ; ARM6-NEXT: mov r0, #0
1144 ; ARM6-NEXT: cmp r1, #0
1145 ; ARM6-NEXT: movlt r0, #1
1146 ; ARM6-NEXT: bx lr
1147 ;
1148 ; ARM78-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1149 ; ARM78: @ %bb.0:
1150 ; ARM78-NEXT: uxtb r1, r1
1151 ; ARM78-NEXT: mov r2, #24
1152 ; ARM78-NEXT: and r0, r0, r2, lsl r1
1153 ; ARM78-NEXT: sxtb r1, r0
1154 ; ARM78-NEXT: mov r0, #0
1155 ; ARM78-NEXT: cmp r1, #0
1156 ; ARM78-NEXT: movwlt r0, #1
1157 ; ARM78-NEXT: bx lr
1158 ;
1159 ; THUMB6-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1160 ; THUMB6: @ %bb.0:
1161 ; THUMB6-NEXT: uxtb r1, r1
1162 ; THUMB6-NEXT: movs r2, #24
1163 ; THUMB6-NEXT: lsls r2, r1
1164 ; THUMB6-NEXT: ands r2, r0
1165 ; THUMB6-NEXT: sxtb r0, r2
1166 ; THUMB6-NEXT: cmp r0, #0
1167 ; THUMB6-NEXT: blt .LBB18_2
1168 ; THUMB6-NEXT: @ %bb.1:
1169 ; THUMB6-NEXT: movs r0, #0
1170 ; THUMB6-NEXT: bx lr
1171 ; THUMB6-NEXT: .LBB18_2:
1172 ; THUMB6-NEXT: movs r0, #1
1173 ; THUMB6-NEXT: bx lr
1174 ;
1175 ; THUMB78-LABEL: negative_scalar_i8_bitsinmiddle_slt:
1176 ; THUMB78: @ %bb.0:
1177 ; THUMB78-NEXT: uxtb r1, r1
1178 ; THUMB78-NEXT: movs r2, #24
1179 ; THUMB78-NEXT: lsl.w r1, r2, r1
1180 ; THUMB78-NEXT: ands r0, r1
1181 ; THUMB78-NEXT: sxtb r1, r0
1182 ; THUMB78-NEXT: movs r0, #0
1183 ; THUMB78-NEXT: cmp r1, #0
1184 ; THUMB78-NEXT: it lt
1185 ; THUMB78-NEXT: movlt r0, #1
1186 ; THUMB78-NEXT: bx lr
1187 %t0 = shl i8 24, %y
1188 %t1 = and i8 %t0, %x
1189 %res = icmp slt i8 %t1, 0
1190 ret i1 %res
1191 }
1192
1193 define i1 @scalar_i8_signbit_eq_with_nonzero(i8 %x, i8 %y) nounwind {
1194 ; ARM-LABEL: scalar_i8_signbit_eq_with_nonzero:
1195 ; ARM: @ %bb.0:
1196 ; ARM-NEXT: uxtb r1, r1
1197 ; ARM-NEXT: mvn r2, #127
1198 ; ARM-NEXT: and r0, r0, r2, lsl r1
1199 ; ARM-NEXT: mvn r1, #0
1200 ; ARM-NEXT: uxtab r0, r1, r0
1201 ; ARM-NEXT: clz r0, r0
1202 ; ARM-NEXT: lsr r0, r0, #5
1203 ; ARM-NEXT: bx lr
1204 ;
1205 ; THUMB6-LABEL: scalar_i8_signbit_eq_with_nonzero:
1206 ; THUMB6: @ %bb.0:
1207 ; THUMB6-NEXT: uxtb r1, r1
1208 ; THUMB6-NEXT: movs r2, #127
1209 ; THUMB6-NEXT: mvns r2, r2
1210 ; THUMB6-NEXT: lsls r2, r1
1211 ; THUMB6-NEXT: ands r2, r0
1212 ; THUMB6-NEXT: uxtb r0, r2
1213 ; THUMB6-NEXT: subs r1, r0, #1
1214 ; THUMB6-NEXT: rsbs r0, r1, #0
1215 ; THUMB6-NEXT: adcs r0, r1
1216 ; THUMB6-NEXT: bx lr
1217 ;
1218 ; THUMB78-LABEL: scalar_i8_signbit_eq_with_nonzero:
1219 ; THUMB78: @ %bb.0:
1220 ; THUMB78-NEXT: uxtb r1, r1
1221 ; THUMB78-NEXT: mvn r2, #127
1222 ; THUMB78-NEXT: lsl.w r1, r2, r1
1223 ; THUMB78-NEXT: ands r0, r1
1224 ; THUMB78-NEXT: mov.w r1, #-1
1225 ; THUMB78-NEXT: uxtab r0, r1, r0
1226 ; THUMB78-NEXT: clz r0, r0
1227 ; THUMB78-NEXT: lsrs r0, r0, #5
1228 ; THUMB78-NEXT: bx lr
1229 %t0 = shl i8 128, %y
1230 %t1 = and i8 %t0, %x
1231 %res = icmp eq i8 %t1, 1 ; should be comparing with 0
1232 ret i1 %res
1233 }
0 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
1 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2 < %s | FileCheck %s --check-prefixes=CHECK,X86,X86-NOBMI
2 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2,+bmi < %s | FileCheck %s --check-prefixes=CHECK,X86,X86-BMI,X86,X86-BMI1
3 ; RUN: llc -mtriple=i686-unknown-linux-gnu -mattr=+sse,sse2,+bmi,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X86,X86-BMI,X86,X86-BMI12
4 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2 < %s | FileCheck %s --check-prefixes=CHECK,X64,X64-NOBMI
5 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2,+bmi < %s | FileCheck %s --check-prefixes=CHECK,X64,X64-BMI,X64,X64-BMI1
6 ; RUN: llc -mtriple=x86_64-unknown-linux-gnu -mattr=+sse,sse2,+bmi,+bmi2 < %s | FileCheck %s --check-prefixes=CHECK,X64,X64-BMI,X64,X64-BMI12
7
8 ; We are looking for the following pattern here:
9 ; (X & (C l>> Y)) ==/!= 0
10 ; It may be optimal to hoist the constant:
11 ; ((X << Y) & C) ==/!= 0
12
13 ;------------------------------------------------------------------------------;
14 ; A few scalar test
15 ;------------------------------------------------------------------------------;
16
17 ; i8 scalar
18
19 define i1 @scalar_i8_signbit_eq(i8 %x, i8 %y) nounwind {
20 ; X86-LABEL: scalar_i8_signbit_eq:
21 ; X86: # %bb.0:
22 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
23 ; X86-NEXT: movb $-128, %al
24 ; X86-NEXT: shrb %cl, %al
25 ; X86-NEXT: testb %al, {{[0-9]+}}(%esp)
26 ; X86-NEXT: sete %al
27 ; X86-NEXT: retl
28 ;
29 ; X64-LABEL: scalar_i8_signbit_eq:
30 ; X64: # %bb.0:
31 ; X64-NEXT: movl %esi, %ecx
32 ; X64-NEXT: movb $-128, %al
33 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
34 ; X64-NEXT: shrb %cl, %al
35 ; X64-NEXT: testb %dil, %al
36 ; X64-NEXT: sete %al
37 ; X64-NEXT: retq
38 %t0 = lshr i8 128, %y
39 %t1 = and i8 %t0, %x
40 %res = icmp eq i8 %t1, 0
41 ret i1 %res
42 }
43
44 define i1 @scalar_i8_lowestbit_eq(i8 %x, i8 %y) nounwind {
45 ; X86-LABEL: scalar_i8_lowestbit_eq:
46 ; X86: # %bb.0:
47 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
48 ; X86-NEXT: movb $1, %al
49 ; X86-NEXT: shrb %cl, %al
50 ; X86-NEXT: testb %al, {{[0-9]+}}(%esp)
51 ; X86-NEXT: sete %al
52 ; X86-NEXT: retl
53 ;
54 ; X64-LABEL: scalar_i8_lowestbit_eq:
55 ; X64: # %bb.0:
56 ; X64-NEXT: movl %esi, %ecx
57 ; X64-NEXT: movb $1, %al
58 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
59 ; X64-NEXT: shrb %cl, %al
60 ; X64-NEXT: testb %dil, %al
61 ; X64-NEXT: sete %al
62 ; X64-NEXT: retq
63 %t0 = lshr i8 1, %y
64 %t1 = and i8 %t0, %x
65 %res = icmp eq i8 %t1, 0
66 ret i1 %res
67 }
68
69 define i1 @scalar_i8_bitsinmiddle_eq(i8 %x, i8 %y) nounwind {
70 ; X86-LABEL: scalar_i8_bitsinmiddle_eq:
71 ; X86: # %bb.0:
72 ; X86-NEXT: movb {{[0-9]+}}(%esp), %cl
73 ; X86-NEXT: movb $24, %al
74 ; X86-NEXT: shrb %cl, %al
75 ; X86-NEXT: testb %al, {{[0-9]+}}(%esp)
76 ; X86-NEXT: sete %al
77 ; X86-NEXT: retl
78 ;
79 ; X64-LABEL: scalar_i8_bitsinmiddle_eq:
80 ; X64: # %bb.0:
81 ; X64-NEXT: movl %esi, %ecx
82 ; X64-NEXT: movb $24, %al
83 ; X64-NEXT: # kill: def $cl killed $cl killed $ecx
84 ; X64-NEXT: shrb %cl, %al
85 ; X64-NEXT: testb %dil, %al
86 ; X64-NEXT: sete %al
87 ; X64-NEXT: retq
88 %t0 = lshr i8 24, %y
89 %t1 = and i8 %t0, %x
90 %res = icmp eq i8 %t1, 0
91 ret i1 %res
92 }
93
94 ; i16 scalar
95
96 define i1 @scalar_i16_signbit_eq(i16 %x, i16 %y) nounwind {
97 ; X86-NOBMI-LABEL: scalar_i16_signbit_eq:
98 ; X86-NOBMI: # %bb.0:
99 ; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl
100 ; X86-NOBMI-NEXT: movl $32768, %eax # imm = 0x8000
101 ; X86-NOBMI-NEXT: shrl %cl, %eax
102 ; X86-NOBMI-NEXT: testw %ax, {{[0-9]+}}(%esp)
103 ; X86-NOBMI-NEXT: sete %al
104 ; X86-NOBMI-NEXT: retl
105 ;
106 ; X86-BMI1-LABEL: scalar_i16_signbit_eq:
107 ; X86-BMI1: # %bb.0:
108 ; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl
109 ; X86-BMI1-NEXT: movl $32768, %eax # imm = 0x8000
110 ; X86-BMI1-NEXT: shrl %cl, %eax
111 ; X86-BMI1-NEXT: testw %ax, {{[0-9]+}}(%esp)
112 ; X86-BMI1-NEXT: sete %al
113 ; X86-BMI1-NEXT: retl
114 ;
115 ; X86-BMI12-LABEL: scalar_i16_signbit_eq:
116 ; X86-BMI12: # %bb.0:
117 ; X86-BMI12-NEXT: movb {{[0-9]+}}(%esp), %al
118 ; X86-BMI12-NEXT: movl $32768, %ecx # imm = 0x8000
119 ; X86-BMI12-NEXT: shrxl %eax, %ecx, %eax
120 ; X86-BMI12-NEXT: testw %ax, {{[0-9]+}}(%esp)
121 ; X86-BMI12-NEXT: sete %al
122 ; X86-BMI12-NEXT: retl
123 ;
124 ; X64-NOBMI-LABEL: scalar_i16_signbit_eq:
125 ; X64-NOBMI: # %bb.0:
126 ; X64-NOBMI-NEXT: movl %esi, %ecx
127 ; X64-NOBMI-NEXT: movl $32768, %eax # imm = 0x8000
128 ; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx
129 ; X64-NOBMI-NEXT: shrl %cl, %eax
130 ; X64-NOBMI-NEXT: testw %di, %ax
131 ; X64-NOBMI-NEXT: sete %al
132 ; X64-NOBMI-NEXT: retq
133 ;
134 ; X64-BMI1-LABEL: scalar_i16_signbit_eq:
135 ; X64-BMI1: # %bb.0:
136 ; X64-BMI1-NEXT: movl %esi, %ecx
137 ; X64-BMI1-NEXT: movl $32768, %eax # imm = 0x8000
138 ; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx
139 ; X64-BMI1-NEXT: shrl %cl, %eax
140 ; X64-BMI1-NEXT: testw %di, %ax
141 ; X64-BMI1-NEXT: sete %al
142 ; X64-BMI1-NEXT: retq
143 ;
144 ; X64-BMI12-LABEL: scalar_i16_signbit_eq:
145 ; X64-BMI12: # %bb.0:
146 ; X64-BMI12-NEXT: movl $32768, %eax # imm = 0x8000
147 ; X64-BMI12-NEXT: shrxl %esi, %eax, %eax
148 ; X64-BMI12-NEXT: testw %di, %ax
149 ; X64-BMI12-NEXT: sete %al
150 ; X64-BMI12-NEXT: retq
151 %t0 = lshr i16 32768, %y
152 %t1 = and i16 %t0, %x
153 %res = icmp eq i16 %t1, 0
154 ret i1 %res
155 }
156
157 define i1 @scalar_i16_lowestbit_eq(i16 %x, i16 %y) nounwind {
158 ; X86-NOBMI-LABEL: scalar_i16_lowestbit_eq:
159 ; X86-NOBMI: # %bb.0:
160 ; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl
161 ; X86-NOBMI-NEXT: movl $1, %eax
162 ; X86-NOBMI-NEXT: shrl %cl, %eax
163 ; X86-NOBMI-NEXT: testw %ax, {{[0-9]+}}(%esp)
164 ; X86-NOBMI-NEXT: sete %al
165 ; X86-NOBMI-NEXT: retl
166 ;
167 ; X86-BMI1-LABEL: scalar_i16_lowestbit_eq:
168 ; X86-BMI1: # %bb.0:
169 ; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl
170 ; X86-BMI1-NEXT: movl $1, %eax
171 ; X86-BMI1-NEXT: shrl %cl, %eax
172 ; X86-BMI1-NEXT: testw %ax, {{[0-9]+}}(%esp)
173 ; X86-BMI1-NEXT: sete %al
174 ; X86-BMI1-NEXT: retl
175 ;
176 ; X86-BMI12-LABEL: scalar_i16_lowestbit_eq:
177 ; X86-BMI12: # %bb.0:
178 ; X86-BMI12-NEXT: movb {{[0-9]+}}(%esp), %al
179 ; X86-BMI12-NEXT: movl $1, %ecx
180 ; X86-BMI12-NEXT: shrxl %eax, %ecx, %eax
181 ; X86-BMI12-NEXT: testw %ax, {{[0-9]+}}(%esp)
182 ; X86-BMI12-NEXT: sete %al
183 ; X86-BMI12-NEXT: retl
184 ;
185 ; X64-NOBMI-LABEL: scalar_i16_lowestbit_eq:
186 ; X64-NOBMI: # %bb.0:
187 ; X64-NOBMI-NEXT: movl %esi, %ecx
188 ; X64-NOBMI-NEXT: movl $1, %eax
189 ; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx
190 ; X64-NOBMI-NEXT: shrl %cl, %eax
191 ; X64-NOBMI-NEXT: testw %di, %ax
192 ; X64-NOBMI-NEXT: sete %al
193 ; X64-NOBMI-NEXT: retq
194 ;
195 ; X64-BMI1-LABEL: scalar_i16_lowestbit_eq:
196 ; X64-BMI1: # %bb.0:
197 ; X64-BMI1-NEXT: movl %esi, %ecx
198 ; X64-BMI1-NEXT: movl $1, %eax
199 ; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx
200 ; X64-BMI1-NEXT: shrl %cl, %eax
201 ; X64-BMI1-NEXT: testw %di, %ax
202 ; X64-BMI1-NEXT: sete %al
203 ; X64-BMI1-NEXT: retq
204 ;
205 ; X64-BMI12-LABEL: scalar_i16_lowestbit_eq:
206 ; X64-BMI12: # %bb.0:
207 ; X64-BMI12-NEXT: movl $1, %eax
208 ; X64-BMI12-NEXT: shrxl %esi, %eax, %eax
209 ; X64-BMI12-NEXT: testw %di, %ax
210 ; X64-BMI12-NEXT: sete %al
211 ; X64-BMI12-NEXT: retq
212 %t0 = lshr i16 1, %y
213 %t1 = and i16 %t0, %x
214 %res = icmp eq i16 %t1, 0
215 ret i1 %res
216 }
217
218 define i1 @scalar_i16_bitsinmiddle_eq(i16 %x, i16 %y) nounwind {
219 ; X86-NOBMI-LABEL: scalar_i16_bitsinmiddle_eq:
220 ; X86-NOBMI: # %bb.0:
221 ; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl
222 ; X86-NOBMI-NEXT: movl $4080, %eax # imm = 0xFF0
223 ; X86-NOBMI-NEXT: shrl %cl, %eax
224 ; X86-NOBMI-NEXT: testw %ax, {{[0-9]+}}(%esp)
225 ; X86-NOBMI-NEXT: sete %al
226 ; X86-NOBMI-NEXT: retl
227 ;
228 ; X86-BMI1-LABEL: scalar_i16_bitsinmiddle_eq:
229 ; X86-BMI1: # %bb.0:
230 ; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl
231 ; X86-BMI1-NEXT: movl $4080, %eax # imm = 0xFF0
232 ; X86-BMI1-NEXT: shrl %cl, %eax
233 ; X86-BMI1-NEXT: testw %ax, {{[0-9]+}}(%esp)
234 ; X86-BMI1-NEXT: sete %al
235 ; X86-BMI1-NEXT: retl
236 ;
237 ; X86-BMI12-LABEL: scalar_i16_bitsinmiddle_eq:
238 ; X86-BMI12: # %bb.0:
239 ; X86-BMI12-NEXT: movb {{[0-9]+}}(%esp), %al
240 ; X86-BMI12-NEXT: movl $4080, %ecx # imm = 0xFF0
241 ; X86-BMI12-NEXT: shrxl %eax, %ecx, %eax
242 ; X86-BMI12-NEXT: testw %ax, {{[0-9]+}}(%esp)
243 ; X86-BMI12-NEXT: sete %al
244 ; X86-BMI12-NEXT: retl
245 ;
246 ; X64-NOBMI-LABEL: scalar_i16_bitsinmiddle_eq:
247 ; X64-NOBMI: # %bb.0:
248 ; X64-NOBMI-NEXT: movl %esi, %ecx
249 ; X64-NOBMI-NEXT: movl $4080, %eax # imm = 0xFF0
250 ; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx
251 ; X64-NOBMI-NEXT: shrl %cl, %eax
252 ; X64-NOBMI-NEXT: testw %di, %ax
253 ; X64-NOBMI-NEXT: sete %al
254 ; X64-NOBMI-NEXT: retq
255 ;
256 ; X64-BMI1-LABEL: scalar_i16_bitsinmiddle_eq:
257 ; X64-BMI1: # %bb.0:
258 ; X64-BMI1-NEXT: movl %esi, %ecx
259 ; X64-BMI1-NEXT: movl $4080, %eax # imm = 0xFF0
260 ; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx
261 ; X64-BMI1-NEXT: shrl %cl, %eax
262 ; X64-BMI1-NEXT: testw %di, %ax
263 ; X64-BMI1-NEXT: sete %al
264 ; X64-BMI1-NEXT: retq
265 ;
266 ; X64-BMI12-LABEL: scalar_i16_bitsinmiddle_eq:
267 ; X64-BMI12: # %bb.0:
268 ; X64-BMI12-NEXT: movl $4080, %eax # imm = 0xFF0
269 ; X64-BMI12-NEXT: shrxl %esi, %eax, %eax
270 ; X64-BMI12-NEXT: testw %di, %ax
271 ; X64-BMI12-NEXT: sete %al
272 ; X64-BMI12-NEXT: retq
273 %t0 = lshr i16 4080, %y
274 %t1 = and i16 %t0, %x
275 %res = icmp eq i16 %t1, 0
276 ret i1 %res
277 }
278
279 ; i32 scalar
280
281 define i1 @scalar_i32_signbit_eq(i32 %x, i32 %y) nounwind {
282 ; X86-NOBMI-LABEL: scalar_i32_signbit_eq:
283 ; X86-NOBMI: # %bb.0:
284 ; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl
285 ; X86-NOBMI-NEXT: movl $-2147483648, %eax # imm = 0x80000000
286 ; X86-NOBMI-NEXT: shrl %cl, %eax
287 ; X86-NOBMI-NEXT: testl %eax, {{[0-9]+}}(%esp)
288 ; X86-NOBMI-NEXT: sete %al
289 ; X86-NOBMI-NEXT: retl
290 ;
291 ; X86-BMI1-LABEL: scalar_i32_signbit_eq:
292 ; X86-BMI1: # %bb.0:
293 ; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl
294 ; X86-BMI1-NEXT: movl $-2147483648, %eax # imm = 0x80000000
295 ; X86-BMI1-NEXT: shrl %cl, %eax
296 ; X86-BMI1-NEXT: testl %eax, {{[0-9]+}}(%esp)
297 ; X86-BMI1-NEXT: sete %al
298 ; X86-BMI1-NEXT: retl
299 ;
300 ; X86-BMI12-LABEL: scalar_i32_signbit_eq:
301 ; X86-BMI12: # %bb.0:
302 ; X86-BMI12-NEXT: movb {{[0-9]+}}(%esp), %al
303 ; X86-BMI12-NEXT: movl $-2147483648, %ecx # imm = 0x80000000
304 ; X86-BMI12-NEXT: shrxl %eax, %ecx, %eax
305 ; X86-BMI12-NEXT: testl %eax, {{[0-9]+}}(%esp)
306 ; X86-BMI12-NEXT: sete %al
307 ; X86-BMI12-NEXT: retl
308 ;
309 ; X64-NOBMI-LABEL: scalar_i32_signbit_eq:
310 ; X64-NOBMI: # %bb.0:
311 ; X64-NOBMI-NEXT: movl %esi, %ecx
312 ; X64-NOBMI-NEXT: movl $-2147483648, %eax # imm = 0x80000000
313 ; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx
314 ; X64-NOBMI-NEXT: shrl %cl, %eax
315 ; X64-NOBMI-NEXT: testl %edi, %eax
316 ; X64-NOBMI-NEXT: sete %al
317 ; X64-NOBMI-NEXT: retq
318 ;
319 ; X64-BMI1-LABEL: scalar_i32_signbit_eq:
320 ; X64-BMI1: # %bb.0:
321 ; X64-BMI1-NEXT: movl %esi, %ecx
322 ; X64-BMI1-NEXT: movl $-2147483648, %eax # imm = 0x80000000
323 ; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx
324 ; X64-BMI1-NEXT: shrl %cl, %eax
325 ; X64-BMI1-NEXT: testl %edi, %eax
326 ; X64-BMI1-NEXT: sete %al
327 ; X64-BMI1-NEXT: retq
328 ;
329 ; X64-BMI12-LABEL: scalar_i32_signbit_eq:
330 ; X64-BMI12: # %bb.0:
331 ; X64-BMI12-NEXT: movl $-2147483648, %eax # imm = 0x80000000
332 ; X64-BMI12-NEXT: shrxl %esi, %eax, %eax
333 ; X64-BMI12-NEXT: testl %edi, %eax
334 ; X64-BMI12-NEXT: sete %al
335 ; X64-BMI12-NEXT: retq
336 %t0 = lshr i32 2147483648, %y
337 %t1 = and i32 %t0, %x
338 %res = icmp eq i32 %t1, 0
339 ret i1 %res
340 }
341
342 define i1 @scalar_i32_lowestbit_eq(i32 %x, i32 %y) nounwind {
343 ; X86-NOBMI-LABEL: scalar_i32_lowestbit_eq:
344 ; X86-NOBMI: # %bb.0:
345 ; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl
346 ; X86-NOBMI-NEXT: movl $1, %eax
347 ; X86-NOBMI-NEXT: shrl %cl, %eax
348 ; X86-NOBMI-NEXT: testl %eax, {{[0-9]+}}(%esp)
349 ; X86-NOBMI-NEXT: sete %al
350 ; X86-NOBMI-NEXT: retl
351 ;
352 ; X86-BMI1-LABEL: scalar_i32_lowestbit_eq:
353 ; X86-BMI1: # %bb.0:
354 ; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl
355 ; X86-BMI1-NEXT: movl $1, %eax
356 ; X86-BMI1-NEXT: shrl %cl, %eax
357 ; X86-BMI1-NEXT: testl %eax, {{[0-9]+}}(%esp)
358 ; X86-BMI1-NEXT: sete %al
359 ; X86-BMI1-NEXT: retl
360 ;
361 ; X86-BMI12-LABEL: scalar_i32_lowestbit_eq:
362 ; X86-BMI12: # %bb.0:
363 ; X86-BMI12-NEXT: movb {{[0-9]+}}(%esp), %al
364 ; X86-BMI12-NEXT: movl $1, %ecx
365 ; X86-BMI12-NEXT: shrxl %eax, %ecx, %eax
366 ; X86-BMI12-NEXT: testl %eax, {{[0-9]+}}(%esp)
367 ; X86-BMI12-NEXT: sete %al
368 ; X86-BMI12-NEXT: retl
369 ;
370 ; X64-NOBMI-LABEL: scalar_i32_lowestbit_eq:
371 ; X64-NOBMI: # %bb.0:
372 ; X64-NOBMI-NEXT: movl %esi, %ecx
373 ; X64-NOBMI-NEXT: movl $1, %eax
374 ; X64-NOBMI-NEXT: # kill: def $cl killed $cl killed $ecx
375 ; X64-NOBMI-NEXT: shrl %cl, %eax
376 ; X64-NOBMI-NEXT: testl %edi, %eax
377 ; X64-NOBMI-NEXT: sete %al
378 ; X64-NOBMI-NEXT: retq
379 ;
380 ; X64-BMI1-LABEL: scalar_i32_lowestbit_eq:
381 ; X64-BMI1: # %bb.0:
382 ; X64-BMI1-NEXT: movl %esi, %ecx
383 ; X64-BMI1-NEXT: movl $1, %eax
384 ; X64-BMI1-NEXT: # kill: def $cl killed $cl killed $ecx
385 ; X64-BMI1-NEXT: shrl %cl, %eax
386 ; X64-BMI1-NEXT: testl %edi, %eax
387 ; X64-BMI1-NEXT: sete %al
388 ; X64-BMI1-NEXT: retq
389 ;
390 ; X64-BMI12-LABEL: scalar_i32_lowestbit_eq:
391 ; X64-BMI12: # %bb.0:
392 ; X64-BMI12-NEXT: movl $1, %eax
393 ; X64-BMI12-NEXT: shrxl %esi, %eax, %eax
394 ; X64-BMI12-NEXT: testl %edi, %eax
395 ; X64-BMI12-NEXT: sete %al
396 ; X64-BMI12-NEXT: retq
397 %t0 = lshr i32 1, %y
398 %t1 = and i32 %t0, %x
399 %res = icmp eq i32 %t1, 0
400 ret i1 %res
401 }
402
403 define i1 @scalar_i32_bitsinmiddle_eq(i32 %x, i32 %y) nounwind {
404 ; X86-NOBMI-LABEL: scalar_i32_bitsinmiddle_eq:
405 ; X86-NOBMI: # %bb.0:
406 ; X86-NOBMI-NEXT: movb {{[0-9]+}}(%esp), %cl
407 ; X86-NOBMI-NEXT: movl $16776960, %eax # imm = 0xFFFF00
408 ; X86-NOBMI-NEXT: shrl %cl, %eax
409 ; X86-NOBMI-NEXT: testl %eax, {{[0-9]+}}(%esp)
410 ; X86-NOBMI-NEXT: sete %al
411 ; X86-NOBMI-NEXT: retl
412 ;
413 ; X86-BMI1-LABEL: scalar_i32_bitsinmiddle_eq:
414 ; X86-BMI1: # %bb.0:
415 ; X86-BMI1-NEXT: movb {{[0-9]+}}(%esp), %cl
416 ; X86-BMI1-NEXT: movl $16776960, %eax # imm = 0xFFFF00
417 ; X86-BMI1-NEXT: shrl %cl, %eax
418 ; X86-BMI1-NEXT: testl %eax, {{[0-9]+}}(%esp)
419 ; X86-BMI1-NEXT: sete %al
420 ; X86-BMI1-NEXT: retl
421 ;
422 ; X86-BMI12-LABEL: scalar_i32_bitsinmiddle_eq:
423 ; X86-BMI12: # %bb.0:
424 ; X86-BMI12-NEXT: movb {{[0-9]+}}(%esp), %al
425 ; X86-BMI12-NEXT: movl $16776960, %ecx # imm = 0xFFFF00
426 ; X86-BMI12-NEXT: shrxl %eax, %ecx, %eax
427 ; X86-BMI12-NEXT: t