[AArch64,ELF] Restrict MOVZ/MOVK to non-PIC large code model (#70178)
[llvm-project.git] / llvm / test / CodeGen / X86 / shift-combine.ll
blobcf45641fba632120139375d09eb250c0990b8b7f
1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2 ; RUN: llc -mtriple=i686-unknown < %s | FileCheck %s --check-prefix=X32
3 ; RUN: llc -mtriple=x86_64-unknown < %s | FileCheck %s --check-prefix=X64
5 @array = weak dso_local global [4 x i32] zeroinitializer
7 define dso_local i32 @test_lshr_and(i32 %x) {
8 ; X32-LABEL: test_lshr_and:
9 ; X32:       # %bb.0:
10 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
11 ; X32-NEXT:    andl $12, %eax
12 ; X32-NEXT:    movl array(%eax), %eax
13 ; X32-NEXT:    retl
15 ; X64-LABEL: test_lshr_and:
16 ; X64:       # %bb.0:
17 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
18 ; X64-NEXT:    andl $12, %edi
19 ; X64-NEXT:    movl array(%rdi), %eax
20 ; X64-NEXT:    retq
21   %tmp2 = lshr i32 %x, 2
22   %tmp3 = and i32 %tmp2, 3
23   %tmp4 = getelementptr [4 x i32], ptr @array, i32 0, i32 %tmp3
24   %tmp5 = load i32, ptr %tmp4, align 4
25   ret i32 %tmp5
28 define dso_local ptr @test_exact1(i32 %a, i32 %b, ptr %x)  {
29 ; X32-LABEL: test_exact1:
30 ; X32:       # %bb.0:
31 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
32 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
33 ; X32-NEXT:    sarl %eax
34 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
35 ; X32-NEXT:    retl
37 ; X64-LABEL: test_exact1:
38 ; X64:       # %bb.0:
39 ; X64-NEXT:    subl %edi, %esi
40 ; X64-NEXT:    sarl $3, %esi
41 ; X64-NEXT:    movslq %esi, %rax
42 ; X64-NEXT:    leaq (%rdx,%rax,4), %rax
43 ; X64-NEXT:    retq
44   %sub = sub i32 %b, %a
45   %shr = ashr exact i32 %sub, 3
46   %gep = getelementptr inbounds i32, ptr %x, i32 %shr
47   ret ptr %gep
50 define dso_local ptr @test_exact2(i32 %a, i32 %b, ptr %x)  {
51 ; X32-LABEL: test_exact2:
52 ; X32:       # %bb.0:
53 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
54 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
55 ; X32-NEXT:    sarl %eax
56 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
57 ; X32-NEXT:    retl
59 ; X64-LABEL: test_exact2:
60 ; X64:       # %bb.0:
61 ; X64-NEXT:    subl %edi, %esi
62 ; X64-NEXT:    sarl $3, %esi
63 ; X64-NEXT:    movslq %esi, %rax
64 ; X64-NEXT:    leaq (%rdx,%rax,4), %rax
65 ; X64-NEXT:    retq
66   %sub = sub i32 %b, %a
67   %shr = ashr exact i32 %sub, 3
68   %gep = getelementptr inbounds i32, ptr %x, i32 %shr
69   ret ptr %gep
72 define dso_local ptr @test_exact3(i32 %a, i32 %b, ptr %x)  {
73 ; X32-LABEL: test_exact3:
74 ; X32:       # %bb.0:
75 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
76 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
77 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
78 ; X32-NEXT:    retl
80 ; X64-LABEL: test_exact3:
81 ; X64:       # %bb.0:
82 ; X64-NEXT:    subl %edi, %esi
83 ; X64-NEXT:    sarl $2, %esi
84 ; X64-NEXT:    movslq %esi, %rax
85 ; X64-NEXT:    leaq (%rdx,%rax,4), %rax
86 ; X64-NEXT:    retq
87   %sub = sub i32 %b, %a
88   %shr = ashr exact i32 %sub, 2
89   %gep = getelementptr inbounds i32, ptr %x, i32 %shr
90   ret ptr %gep
93 define dso_local ptr @test_exact4(i32 %a, i32 %b, ptr %x)  {
94 ; X32-LABEL: test_exact4:
95 ; X32:       # %bb.0:
96 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
97 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
98 ; X32-NEXT:    shrl %eax
99 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
100 ; X32-NEXT:    retl
102 ; X64-LABEL: test_exact4:
103 ; X64:       # %bb.0:
104 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
105 ; X64-NEXT:    subl %edi, %esi
106 ; X64-NEXT:    shrl %esi
107 ; X64-NEXT:    leaq (%rsi,%rdx), %rax
108 ; X64-NEXT:    retq
109   %sub = sub i32 %b, %a
110   %shr = lshr exact i32 %sub, 3
111   %gep = getelementptr inbounds i32, ptr %x, i32 %shr
112   ret ptr %gep
115 define dso_local ptr @test_exact5(i32 %a, i32 %b, ptr %x)  {
116 ; X32-LABEL: test_exact5:
117 ; X32:       # %bb.0:
118 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
119 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
120 ; X32-NEXT:    shrl %eax
121 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
122 ; X32-NEXT:    retl
124 ; X64-LABEL: test_exact5:
125 ; X64:       # %bb.0:
126 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
127 ; X64-NEXT:    subl %edi, %esi
128 ; X64-NEXT:    shrl %esi
129 ; X64-NEXT:    leaq (%rsi,%rdx), %rax
130 ; X64-NEXT:    retq
131   %sub = sub i32 %b, %a
132   %shr = lshr exact i32 %sub, 3
133   %gep = getelementptr inbounds i32, ptr %x, i32 %shr
134   ret ptr %gep
137 define dso_local ptr @test_exact6(i32 %a, i32 %b, ptr %x)  {
138 ; X32-LABEL: test_exact6:
139 ; X32:       # %bb.0:
140 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
141 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
142 ; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
143 ; X32-NEXT:    retl
145 ; X64-LABEL: test_exact6:
146 ; X64:       # %bb.0:
147 ; X64-NEXT:    # kill: def $esi killed $esi def $rsi
148 ; X64-NEXT:    subl %edi, %esi
149 ; X64-NEXT:    leaq (%rsi,%rdx), %rax
150 ; X64-NEXT:    retq
151   %sub = sub i32 %b, %a
152   %shr = lshr exact i32 %sub, 2
153   %gep = getelementptr inbounds i32, ptr %x, i32 %shr
154   ret ptr %gep
157 ; PR42644 - https://bugs.llvm.org/show_bug.cgi?id=42644
159 define i64 @ashr_add_shl_i32(i64 %r) nounwind {
160 ; X32-LABEL: ashr_add_shl_i32:
161 ; X32:       # %bb.0:
162 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
163 ; X32-NEXT:    incl %eax
164 ; X32-NEXT:    movl %eax, %edx
165 ; X32-NEXT:    sarl $31, %edx
166 ; X32-NEXT:    retl
168 ; X64-LABEL: ashr_add_shl_i32:
169 ; X64:       # %bb.0:
170 ; X64-NEXT:    incl %edi
171 ; X64-NEXT:    movslq %edi, %rax
172 ; X64-NEXT:    retq
173   %conv = shl i64 %r, 32
174   %sext = add i64 %conv, 4294967296
175   %conv1 = ashr i64 %sext, 32
176   ret i64 %conv1
179 define i64 @ashr_add_shl_i8(i64 %r) nounwind {
180 ; X32-LABEL: ashr_add_shl_i8:
181 ; X32:       # %bb.0:
182 ; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
183 ; X32-NEXT:    addb $2, %al
184 ; X32-NEXT:    movsbl %al, %eax
185 ; X32-NEXT:    movl %eax, %edx
186 ; X32-NEXT:    sarl $31, %edx
187 ; X32-NEXT:    retl
189 ; X64-LABEL: ashr_add_shl_i8:
190 ; X64:       # %bb.0:
191 ; X64-NEXT:    addb $2, %dil
192 ; X64-NEXT:    movsbq %dil, %rax
193 ; X64-NEXT:    retq
194   %conv = shl i64 %r, 56
195   %sext = add i64 %conv, 144115188075855872
196   %conv1 = ashr i64 %sext, 56
197   ret i64 %conv1
200 define <4 x i32> @ashr_add_shl_v4i8(<4 x i32> %r) nounwind {
201 ; X32-LABEL: ashr_add_shl_v4i8:
202 ; X32:       # %bb.0:
203 ; X32-NEXT:    pushl %edi
204 ; X32-NEXT:    pushl %esi
205 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
206 ; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
207 ; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %edx
208 ; X32-NEXT:    movb {{[0-9]+}}(%esp), %ch
209 ; X32-NEXT:    movb {{[0-9]+}}(%esp), %dh
210 ; X32-NEXT:    incb %dh
211 ; X32-NEXT:    movsbl %dh, %esi
212 ; X32-NEXT:    incb %ch
213 ; X32-NEXT:    movsbl %ch, %edi
214 ; X32-NEXT:    incb %dl
215 ; X32-NEXT:    movsbl %dl, %edx
216 ; X32-NEXT:    incb %cl
217 ; X32-NEXT:    movsbl %cl, %ecx
218 ; X32-NEXT:    movl %ecx, 12(%eax)
219 ; X32-NEXT:    movl %edx, 8(%eax)
220 ; X32-NEXT:    movl %edi, 4(%eax)
221 ; X32-NEXT:    movl %esi, (%eax)
222 ; X32-NEXT:    popl %esi
223 ; X32-NEXT:    popl %edi
224 ; X32-NEXT:    retl $4
226 ; X64-LABEL: ashr_add_shl_v4i8:
227 ; X64:       # %bb.0:
228 ; X64-NEXT:    pslld $24, %xmm0
229 ; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
230 ; X64-NEXT:    psrad $24, %xmm0
231 ; X64-NEXT:    retq
232   %conv = shl <4 x i32> %r, <i32 24, i32 24, i32 24, i32 24>
233   %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216>
234   %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24>
235   ret <4 x i32> %conv1
238 define i64 @ashr_add_shl_i36(i64 %r) nounwind {
239 ; X32-LABEL: ashr_add_shl_i36:
240 ; X32:       # %bb.0:
241 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
242 ; X32-NEXT:    shll $4, %edx
243 ; X32-NEXT:    movl %edx, %eax
244 ; X32-NEXT:    sarl $4, %eax
245 ; X32-NEXT:    sarl $31, %edx
246 ; X32-NEXT:    retl
248 ; X64-LABEL: ashr_add_shl_i36:
249 ; X64:       # %bb.0:
250 ; X64-NEXT:    movq %rdi, %rax
251 ; X64-NEXT:    shlq $36, %rax
252 ; X64-NEXT:    sarq $36, %rax
253 ; X64-NEXT:    retq
254   %conv = shl i64 %r, 36
255   %sext = add i64 %conv, 4294967296
256   %conv1 = ashr i64 %sext, 36
257   ret i64 %conv1
260 define i64 @ashr_add_shl_mismatch_shifts1(i64 %r) nounwind {
261 ; X32-LABEL: ashr_add_shl_mismatch_shifts1:
262 ; X32:       # %bb.0:
263 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
264 ; X32-NEXT:    incl %eax
265 ; X32-NEXT:    movl %eax, %edx
266 ; X32-NEXT:    sarl $31, %edx
267 ; X32-NEXT:    retl
269 ; X64-LABEL: ashr_add_shl_mismatch_shifts1:
270 ; X64:       # %bb.0:
271 ; X64-NEXT:    shlq $8, %rdi
272 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
273 ; X64-NEXT:    addq %rdi, %rax
274 ; X64-NEXT:    sarq $32, %rax
275 ; X64-NEXT:    retq
276   %conv = shl i64 %r, 8
277   %sext = add i64 %conv, 4294967296
278   %conv1 = ashr i64 %sext, 32
279   ret i64 %conv1
282 define i64 @ashr_add_shl_mismatch_shifts2(i64 %r) nounwind {
283 ; X32-LABEL: ashr_add_shl_mismatch_shifts2:
284 ; X32:       # %bb.0:
285 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
286 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
287 ; X32-NEXT:    shrl $8, %edx
288 ; X32-NEXT:    incl %edx
289 ; X32-NEXT:    shrdl $8, %edx, %eax
290 ; X32-NEXT:    shrl $8, %edx
291 ; X32-NEXT:    retl
293 ; X64-LABEL: ashr_add_shl_mismatch_shifts2:
294 ; X64:       # %bb.0:
295 ; X64-NEXT:    shrq $8, %rdi
296 ; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
297 ; X64-NEXT:    addq %rdi, %rax
298 ; X64-NEXT:    shrq $8, %rax
299 ; X64-NEXT:    retq
300   %conv = lshr i64 %r, 8
301   %sext = add i64 %conv, 4294967296
302   %conv1 = ashr i64 %sext, 8
303   ret i64 %conv1
306 define dso_local i32 @ashr_add_shl_i32_i8_extra_use1(i32 %r, ptr %p) nounwind {
307 ; X32-LABEL: ashr_add_shl_i32_i8_extra_use1:
308 ; X32:       # %bb.0:
309 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
310 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
311 ; X32-NEXT:    shll $24, %eax
312 ; X32-NEXT:    addl $33554432, %eax # imm = 0x2000000
313 ; X32-NEXT:    movl %eax, (%ecx)
314 ; X32-NEXT:    sarl $24, %eax
315 ; X32-NEXT:    retl
317 ; X64-LABEL: ashr_add_shl_i32_i8_extra_use1:
318 ; X64:       # %bb.0:
319 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
320 ; X64-NEXT:    shll $24, %edi
321 ; X64-NEXT:    leal 33554432(%rdi), %eax
322 ; X64-NEXT:    movl %eax, (%rsi)
323 ; X64-NEXT:    sarl $24, %eax
324 ; X64-NEXT:    retq
325   %conv = shl i32 %r, 24
326   %sext = add i32 %conv, 33554432
327   store i32 %sext, ptr %p
328   %conv1 = ashr i32 %sext, 24
329   ret i32 %conv1
332 define dso_local i32 @ashr_add_shl_i32_i8_extra_use2(i32 %r, ptr %p) nounwind {
333 ; X32-LABEL: ashr_add_shl_i32_i8_extra_use2:
334 ; X32:       # %bb.0:
335 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
336 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
337 ; X32-NEXT:    shll $24, %eax
338 ; X32-NEXT:    movl %eax, (%ecx)
339 ; X32-NEXT:    addl $33554432, %eax # imm = 0x2000000
340 ; X32-NEXT:    sarl $24, %eax
341 ; X32-NEXT:    retl
343 ; X64-LABEL: ashr_add_shl_i32_i8_extra_use2:
344 ; X64:       # %bb.0:
345 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
346 ; X64-NEXT:    shll $24, %edi
347 ; X64-NEXT:    movl %edi, (%rsi)
348 ; X64-NEXT:    leal 33554432(%rdi), %eax
349 ; X64-NEXT:    sarl $24, %eax
350 ; X64-NEXT:    retq
351   %conv = shl i32 %r, 24
352   store i32 %conv, ptr %p
353   %sext = add i32 %conv, 33554432
354   %conv1 = ashr i32 %sext, 24
355   ret i32 %conv1
358 define dso_local i32 @ashr_add_shl_i32_i8_extra_use3(i32 %r, ptr %p1, ptr %p2) nounwind {
359 ; X32-LABEL: ashr_add_shl_i32_i8_extra_use3:
360 ; X32:       # %bb.0:
361 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
362 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
363 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
364 ; X32-NEXT:    shll $24, %eax
365 ; X32-NEXT:    movl %eax, (%edx)
366 ; X32-NEXT:    addl $33554432, %eax # imm = 0x2000000
367 ; X32-NEXT:    movl %eax, (%ecx)
368 ; X32-NEXT:    sarl $24, %eax
369 ; X32-NEXT:    retl
371 ; X64-LABEL: ashr_add_shl_i32_i8_extra_use3:
372 ; X64:       # %bb.0:
373 ; X64-NEXT:    # kill: def $edi killed $edi def $rdi
374 ; X64-NEXT:    shll $24, %edi
375 ; X64-NEXT:    movl %edi, (%rsi)
376 ; X64-NEXT:    leal 33554432(%rdi), %eax
377 ; X64-NEXT:    movl %eax, (%rdx)
378 ; X64-NEXT:    sarl $24, %eax
379 ; X64-NEXT:    retq
380   %conv = shl i32 %r, 24
381   store i32 %conv, ptr %p1
382   %sext = add i32 %conv, 33554432
383   store i32 %sext, ptr %p2
384   %conv1 = ashr i32 %sext, 24
385   ret i32 %conv1
388 %"class.QPainterPath" = type { double, double, i32 }
390 define dso_local void @PR42880(i32 %t0) {
391 ; X32-LABEL: PR42880:
392 ; X32:       # %bb.0:
393 ; X32-NEXT:    xorl %eax, %eax
394 ; X32-NEXT:    testb %al, %al
395 ; X32-NEXT:    je .LBB16_1
396 ; X32-NEXT:  # %bb.2: # %if
397 ; X32-NEXT:  .LBB16_1: # %then
399 ; X64-LABEL: PR42880:
400 ; X64:       # %bb.0:
401 ; X64-NEXT:    xorl %eax, %eax
402 ; X64-NEXT:    testb %al, %al
403 ; X64-NEXT:    je .LBB16_1
404 ; X64-NEXT:  # %bb.2: # %if
405 ; X64-NEXT:  .LBB16_1: # %then
406   %sub = add nsw i32 %t0, -1
407   %add.ptr.i94 = getelementptr inbounds %"class.QPainterPath", ptr null, i32 %sub
408   %x = ptrtoint ptr %add.ptr.i94 to i32
409   %sub2 = sub i32 %x, 0
410   %div = sdiv exact i32 %sub2, 24
411   br i1 undef, label %if, label %then
413 then:
414   %t1 = xor i32 %div, -1
415   unreachable
418   unreachable
421 ; The mul here is the equivalent of (neg (shl X, 32)).
422 define i64 @ashr_add_neg_shl_i32(i64 %r) nounwind {
423 ; X32-LABEL: ashr_add_neg_shl_i32:
424 ; X32:       # %bb.0:
425 ; X32-NEXT:    movl $1, %eax
426 ; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
427 ; X32-NEXT:    movl %eax, %edx
428 ; X32-NEXT:    sarl $31, %edx
429 ; X32-NEXT:    retl
431 ; X64-LABEL: ashr_add_neg_shl_i32:
432 ; X64:       # %bb.0:
433 ; X64-NEXT:    movl $1, %eax
434 ; X64-NEXT:    subl %edi, %eax
435 ; X64-NEXT:    cltq
436 ; X64-NEXT:    retq
437   %conv = mul i64 %r, -4294967296
438   %sext = add i64 %conv, 4294967296
439   %conv1 = ashr i64 %sext, 32
440   ret i64 %conv1
443 ; The mul here is the equivalent of (neg (shl X, 56)).
444 define i64 @ashr_add_neg_shl_i8(i64 %r) nounwind {
445 ; X32-LABEL: ashr_add_neg_shl_i8:
446 ; X32:       # %bb.0:
447 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
448 ; X32-NEXT:    shll $24, %eax
449 ; X32-NEXT:    movl $33554432, %edx # imm = 0x2000000
450 ; X32-NEXT:    subl %eax, %edx
451 ; X32-NEXT:    movl %edx, %eax
452 ; X32-NEXT:    sarl $24, %eax
453 ; X32-NEXT:    sarl $31, %edx
454 ; X32-NEXT:    retl
456 ; X64-LABEL: ashr_add_neg_shl_i8:
457 ; X64:       # %bb.0:
458 ; X64-NEXT:    movb $2, %al
459 ; X64-NEXT:    subb %dil, %al
460 ; X64-NEXT:    movsbq %al, %rax
461 ; X64-NEXT:    retq
462   %conv = mul i64 %r, -72057594037927936
463   %sext = add i64 %conv, 144115188075855872
464   %conv1 = ashr i64 %sext, 56
465   ret i64 %conv1
468 ; The mul here is the equivalent of (neg (shl X, 24)).
469 define <4 x i32> @ashr_add_neg_shl_v4i8(<4 x i32> %r) nounwind {
470 ; X32-LABEL: ashr_add_neg_shl_v4i8:
471 ; X32:       # %bb.0:
472 ; X32-NEXT:    pushl %edi
473 ; X32-NEXT:    pushl %esi
474 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
475 ; X32-NEXT:    movb $1, %cl
476 ; X32-NEXT:    movb $1, %dl
477 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %dl
478 ; X32-NEXT:    movsbl %dl, %edx
479 ; X32-NEXT:    movb $1, %ch
480 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %ch
481 ; X32-NEXT:    movsbl %ch, %esi
482 ; X32-NEXT:    movb $1, %ch
483 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %ch
484 ; X32-NEXT:    movsbl %ch, %edi
485 ; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
486 ; X32-NEXT:    movsbl %cl, %ecx
487 ; X32-NEXT:    movl %ecx, 12(%eax)
488 ; X32-NEXT:    movl %edi, 8(%eax)
489 ; X32-NEXT:    movl %esi, 4(%eax)
490 ; X32-NEXT:    movl %edx, (%eax)
491 ; X32-NEXT:    popl %esi
492 ; X32-NEXT:    popl %edi
493 ; X32-NEXT:    retl $4
495 ; X64-LABEL: ashr_add_neg_shl_v4i8:
496 ; X64:       # %bb.0:
497 ; X64-NEXT:    pslld $24, %xmm0
498 ; X64-NEXT:    movdqa {{.*#+}} xmm1 = [16777216,16777216,16777216,16777216]
499 ; X64-NEXT:    psubd %xmm0, %xmm1
500 ; X64-NEXT:    psrad $24, %xmm1
501 ; X64-NEXT:    movdqa %xmm1, %xmm0
502 ; X64-NEXT:    retq
503   %conv = mul <4 x i32> %r, <i32 -16777216, i32 -16777216, i32 -16777216, i32 -16777216>
504   %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216>
505   %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24>
506   ret <4 x i32> %conv1
509 define i32 @or_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
510 ; X32-LABEL: or_tree_with_shifts_i32:
511 ; X32:       # %bb.0:
512 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
513 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
514 ; X32-NEXT:    shll $16, %eax
515 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
516 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
517 ; X32-NEXT:    retl
519 ; X64-LABEL: or_tree_with_shifts_i32:
520 ; X64:       # %bb.0:
521 ; X64-NEXT:    movl %esi, %eax
522 ; X64-NEXT:    orl %edx, %edi
523 ; X64-NEXT:    shll $16, %edi
524 ; X64-NEXT:    orl %ecx, %eax
525 ; X64-NEXT:    orl %edi, %eax
526 ; X64-NEXT:    retq
527   %a.shifted = shl i32 %a, 16
528   %c.shifted = shl i32 %c, 16
529   %or.ab = or i32 %a.shifted, %b
530   %or.cd = or i32 %c.shifted, %d
531   %r = or i32 %or.ab, %or.cd
532   ret i32 %r
535 define i32 @xor_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
536 ; X32-LABEL: xor_tree_with_shifts_i32:
537 ; X32:       # %bb.0:
538 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
539 ; X32-NEXT:    xorl {{[0-9]+}}(%esp), %eax
540 ; X32-NEXT:    shrl $16, %eax
541 ; X32-NEXT:    xorl {{[0-9]+}}(%esp), %eax
542 ; X32-NEXT:    xorl {{[0-9]+}}(%esp), %eax
543 ; X32-NEXT:    retl
545 ; X64-LABEL: xor_tree_with_shifts_i32:
546 ; X64:       # %bb.0:
547 ; X64-NEXT:    movl %esi, %eax
548 ; X64-NEXT:    xorl %edx, %edi
549 ; X64-NEXT:    shrl $16, %edi
550 ; X64-NEXT:    xorl %ecx, %eax
551 ; X64-NEXT:    xorl %edi, %eax
552 ; X64-NEXT:    retq
553   %a.shifted = lshr i32 %a, 16
554   %c.shifted = lshr i32 %c, 16
555   %xor.ab = xor i32 %a.shifted, %b
556   %xor.cd = xor i32 %d, %c.shifted
557   %r = xor i32 %xor.ab, %xor.cd
558   ret i32 %r
561 define i32 @and_tree_with_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
562 ; X32-LABEL: and_tree_with_shifts_i32:
563 ; X32:       # %bb.0:
564 ; X32-NEXT:    movswl {{[0-9]+}}(%esp), %eax
565 ; X32-NEXT:    movswl {{[0-9]+}}(%esp), %ecx
566 ; X32-NEXT:    andl {{[0-9]+}}(%esp), %ecx
567 ; X32-NEXT:    andl {{[0-9]+}}(%esp), %eax
568 ; X32-NEXT:    andl %ecx, %eax
569 ; X32-NEXT:    retl
571 ; X64-LABEL: and_tree_with_shifts_i32:
572 ; X64:       # %bb.0:
573 ; X64-NEXT:    movl %esi, %eax
574 ; X64-NEXT:    andl %edx, %edi
575 ; X64-NEXT:    sarl $16, %edi
576 ; X64-NEXT:    andl %ecx, %eax
577 ; X64-NEXT:    andl %edi, %eax
578 ; X64-NEXT:    retq
579   %a.shifted = ashr i32 %a, 16
580   %c.shifted = ashr i32 %c, 16
581   %and.ab = and i32 %b, %a.shifted
582   %and.cd = and i32 %c.shifted, %d
583   %r = and i32 %and.ab, %and.cd
584   ret i32 %r
587 define i32 @logic_tree_with_shifts_var_i32(i32 %a, i32 %b, i32 %c, i32 %d, i32 %s) {
588 ; X32-LABEL: logic_tree_with_shifts_var_i32:
589 ; X32:       # %bb.0:
590 ; X32-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
591 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
592 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
593 ; X32-NEXT:    shll %cl, %eax
594 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
595 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
596 ; X32-NEXT:    retl
598 ; X64-LABEL: logic_tree_with_shifts_var_i32:
599 ; X64:       # %bb.0:
600 ; X64-NEXT:    movl %ecx, %eax
601 ; X64-NEXT:    orl %edx, %edi
602 ; X64-NEXT:    movl %r8d, %ecx
603 ; X64-NEXT:    shll %cl, %edi
604 ; X64-NEXT:    orl %esi, %eax
605 ; X64-NEXT:    orl %edi, %eax
606 ; X64-NEXT:    retq
607   %a.shifted = shl i32 %a, %s
608   %c.shifted = shl i32 %c, %s
609   %or.ab = or i32 %b, %a.shifted
610   %or.cd = or i32 %d, %c.shifted
611   %r = or i32 %or.ab, %or.cd
612   ret i32 %r
615 define i32 @logic_tree_with_mismatching_shifts_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
616 ; X32-LABEL: logic_tree_with_mismatching_shifts_i32:
617 ; X32:       # %bb.0:
618 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
619 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
620 ; X32-NEXT:    shll $15, %ecx
621 ; X32-NEXT:    shll $16, %eax
622 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
623 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
624 ; X32-NEXT:    orl %ecx, %eax
625 ; X32-NEXT:    retl
627 ; X64-LABEL: logic_tree_with_mismatching_shifts_i32:
628 ; X64:       # %bb.0:
629 ; X64-NEXT:    movl %edx, %eax
630 ; X64-NEXT:    shll $15, %edi
631 ; X64-NEXT:    shll $16, %eax
632 ; X64-NEXT:    orl %esi, %edi
633 ; X64-NEXT:    orl %ecx, %eax
634 ; X64-NEXT:    orl %edi, %eax
635 ; X64-NEXT:    retq
636   %a.shifted = shl i32 %a, 15
637   %c.shifted = shl i32 %c, 16
638   %or.ab = or i32 %a.shifted, %b
639   %or.cd = or i32 %c.shifted, %d
640   %r = or i32 %or.ab, %or.cd
641   ret i32 %r
644 define i32 @logic_tree_with_mismatching_shifts2_i32(i32 %a, i32 %b, i32 %c, i32 %d) {
645 ; X32-LABEL: logic_tree_with_mismatching_shifts2_i32:
646 ; X32:       # %bb.0:
647 ; X32-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
648 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
649 ; X32-NEXT:    shll $16, %ecx
650 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
651 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
652 ; X32-NEXT:    orl %ecx, %eax
653 ; X32-NEXT:    retl
655 ; X64-LABEL: logic_tree_with_mismatching_shifts2_i32:
656 ; X64:       # %bb.0:
657 ; X64-NEXT:    movl %edx, %eax
658 ; X64-NEXT:    shll $16, %edi
659 ; X64-NEXT:    shrl $16, %eax
660 ; X64-NEXT:    orl %esi, %edi
661 ; X64-NEXT:    orl %ecx, %eax
662 ; X64-NEXT:    orl %edi, %eax
663 ; X64-NEXT:    retq
664   %a.shifted = shl i32 %a, 16
665   %c.shifted = lshr i32 %c, 16
666   %or.ab = or i32 %a.shifted, %b
667   %or.cd = or i32 %c.shifted, %d
668   %r = or i32 %or.ab, %or.cd
669   ret i32 %r
672 define <4 x i32> @or_tree_with_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {
673 ; X32-LABEL: or_tree_with_shifts_vec_i32:
674 ; X32:       # %bb.0:
675 ; X32-NEXT:    pushl %edi
676 ; X32-NEXT:    .cfi_def_cfa_offset 8
677 ; X32-NEXT:    pushl %esi
678 ; X32-NEXT:    .cfi_def_cfa_offset 12
679 ; X32-NEXT:    .cfi_offset %esi, -12
680 ; X32-NEXT:    .cfi_offset %edi, -8
681 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
682 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
683 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
684 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
685 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
686 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
687 ; X32-NEXT:    shll $16, %ecx
688 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
689 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
690 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edx
691 ; X32-NEXT:    shll $16, %edx
692 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edx
693 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edx
694 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %esi
695 ; X32-NEXT:    shll $16, %esi
696 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %esi
697 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %esi
698 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edi
699 ; X32-NEXT:    shll $16, %edi
700 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edi
701 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edi
702 ; X32-NEXT:    movl %edi, 12(%eax)
703 ; X32-NEXT:    movl %esi, 8(%eax)
704 ; X32-NEXT:    movl %edx, 4(%eax)
705 ; X32-NEXT:    movl %ecx, (%eax)
706 ; X32-NEXT:    popl %esi
707 ; X32-NEXT:    .cfi_def_cfa_offset 8
708 ; X32-NEXT:    popl %edi
709 ; X32-NEXT:    .cfi_def_cfa_offset 4
710 ; X32-NEXT:    retl $4
712 ; X64-LABEL: or_tree_with_shifts_vec_i32:
713 ; X64:       # %bb.0:
714 ; X64-NEXT:    por %xmm2, %xmm0
715 ; X64-NEXT:    pslld $16, %xmm0
716 ; X64-NEXT:    por %xmm3, %xmm1
717 ; X64-NEXT:    por %xmm1, %xmm0
718 ; X64-NEXT:    retq
719   %a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
720   %c.shifted = shl <4 x i32> %c, <i32 16, i32 16, i32 16, i32 16>
721   %or.ab = or <4 x i32> %a.shifted, %b
722   %or.cd = or <4 x i32> %c.shifted, %d
723   %r = or <4 x i32> %or.ab, %or.cd
724   ret <4 x i32> %r
727 define <4 x i32> @or_tree_with_mismatching_shifts_vec_i32(<4 x i32> %a, <4 x i32> %b, <4 x i32> %c, <4 x i32> %d) {
728 ; X32-LABEL: or_tree_with_mismatching_shifts_vec_i32:
729 ; X32:       # %bb.0:
730 ; X32-NEXT:    pushl %edi
731 ; X32-NEXT:    .cfi_def_cfa_offset 8
732 ; X32-NEXT:    pushl %esi
733 ; X32-NEXT:    .cfi_def_cfa_offset 12
734 ; X32-NEXT:    .cfi_offset %esi, -12
735 ; X32-NEXT:    .cfi_offset %edi, -8
736 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
737 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
738 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
739 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %edi
740 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
741 ; X32-NEXT:    shll $16, %eax
742 ; X32-NEXT:    shll $17, %ecx
743 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
744 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %ecx
745 ; X32-NEXT:    orl %eax, %ecx
746 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
747 ; X32-NEXT:    shll $16, %eax
748 ; X32-NEXT:    shll $17, %edx
749 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
750 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edx
751 ; X32-NEXT:    orl %eax, %edx
752 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
753 ; X32-NEXT:    shll $16, %eax
754 ; X32-NEXT:    shll $17, %esi
755 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
756 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %esi
757 ; X32-NEXT:    orl %eax, %esi
758 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
759 ; X32-NEXT:    shll $16, %eax
760 ; X32-NEXT:    shll $17, %edi
761 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %eax
762 ; X32-NEXT:    orl {{[0-9]+}}(%esp), %edi
763 ; X32-NEXT:    orl %eax, %edi
764 ; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
765 ; X32-NEXT:    movl %ecx, 12(%eax)
766 ; X32-NEXT:    movl %edx, 8(%eax)
767 ; X32-NEXT:    movl %esi, 4(%eax)
768 ; X32-NEXT:    movl %edi, (%eax)
769 ; X32-NEXT:    popl %esi
770 ; X32-NEXT:    .cfi_def_cfa_offset 8
771 ; X32-NEXT:    popl %edi
772 ; X32-NEXT:    .cfi_def_cfa_offset 4
773 ; X32-NEXT:    retl $4
775 ; X64-LABEL: or_tree_with_mismatching_shifts_vec_i32:
776 ; X64:       # %bb.0:
777 ; X64-NEXT:    pslld $16, %xmm0
778 ; X64-NEXT:    pslld $17, %xmm2
779 ; X64-NEXT:    por %xmm1, %xmm0
780 ; X64-NEXT:    por %xmm3, %xmm2
781 ; X64-NEXT:    por %xmm2, %xmm0
782 ; X64-NEXT:    retq
783   %a.shifted = shl <4 x i32> %a, <i32 16, i32 16, i32 16, i32 16>
784   %c.shifted = shl <4 x i32> %c, <i32 17, i32 17, i32 17, i32 17>
785   %or.ab = or <4 x i32> %a.shifted, %b
786   %or.cd = or <4 x i32> %c.shifted, %d
787   %r = or <4 x i32> %or.ab, %or.cd
788   ret <4 x i32> %r