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
4
5@array = weak dso_local global [4 x i32] zeroinitializer
6
7define 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
14;
15; X64-LABEL: test_lshr_and:
16; X64:       # %bb.0:
17; X64-NEXT:    # kill: def $edi killed $edi def $rdi
18; X64-NEXT:    shrl $2, %edi
19; X64-NEXT:    andl $3, %edi
20; X64-NEXT:    movl array(,%rdi,4), %eax
21; X64-NEXT:    retq
22  %tmp2 = lshr i32 %x, 2
23  %tmp3 = and i32 %tmp2, 3
24  %tmp4 = getelementptr [4 x i32], ptr @array, i32 0, i32 %tmp3
25  %tmp5 = load i32, ptr %tmp4, align 4
26  ret i32 %tmp5
27}
28
29define dso_local ptr @test_exact1(i32 %a, i32 %b, ptr %x)  {
30; X32-LABEL: test_exact1:
31; X32:       # %bb.0:
32; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
33; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
34; X32-NEXT:    sarl %eax
35; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
36; X32-NEXT:    retl
37;
38; X64-LABEL: test_exact1:
39; X64:       # %bb.0:
40; X64-NEXT:    subl %edi, %esi
41; X64-NEXT:    sarl $3, %esi
42; X64-NEXT:    movslq %esi, %rax
43; X64-NEXT:    leaq (%rdx,%rax,4), %rax
44; X64-NEXT:    retq
45  %sub = sub i32 %b, %a
46  %shr = ashr exact i32 %sub, 3
47  %gep = getelementptr inbounds i32, ptr %x, i32 %shr
48  ret ptr %gep
49}
50
51define dso_local ptr @test_exact2(i32 %a, i32 %b, ptr %x)  {
52; X32-LABEL: test_exact2:
53; X32:       # %bb.0:
54; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
55; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
56; X32-NEXT:    sarl %eax
57; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
58; X32-NEXT:    retl
59;
60; X64-LABEL: test_exact2:
61; X64:       # %bb.0:
62; X64-NEXT:    subl %edi, %esi
63; X64-NEXT:    sarl $3, %esi
64; X64-NEXT:    movslq %esi, %rax
65; X64-NEXT:    leaq (%rdx,%rax,4), %rax
66; X64-NEXT:    retq
67  %sub = sub i32 %b, %a
68  %shr = ashr exact i32 %sub, 3
69  %gep = getelementptr inbounds i32, ptr %x, i32 %shr
70  ret ptr %gep
71}
72
73define dso_local ptr @test_exact3(i32 %a, i32 %b, ptr %x)  {
74; X32-LABEL: test_exact3:
75; X32:       # %bb.0:
76; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
77; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
78; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
79; X32-NEXT:    retl
80;
81; X64-LABEL: test_exact3:
82; X64:       # %bb.0:
83; X64-NEXT:    subl %edi, %esi
84; X64-NEXT:    sarl $2, %esi
85; X64-NEXT:    movslq %esi, %rax
86; X64-NEXT:    leaq (%rdx,%rax,4), %rax
87; X64-NEXT:    retq
88  %sub = sub i32 %b, %a
89  %shr = ashr exact i32 %sub, 2
90  %gep = getelementptr inbounds i32, ptr %x, i32 %shr
91  ret ptr %gep
92}
93
94define dso_local ptr @test_exact4(i32 %a, i32 %b, ptr %x)  {
95; X32-LABEL: test_exact4:
96; X32:       # %bb.0:
97; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
98; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
99; X32-NEXT:    shrl %eax
100; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
101; X32-NEXT:    retl
102;
103; X64-LABEL: test_exact4:
104; X64:       # %bb.0:
105; X64-NEXT:    # kill: def $esi killed $esi def $rsi
106; X64-NEXT:    subl %edi, %esi
107; X64-NEXT:    shrl $3, %esi
108; X64-NEXT:    leaq (%rdx,%rsi,4), %rax
109; X64-NEXT:    retq
110  %sub = sub i32 %b, %a
111  %shr = lshr exact i32 %sub, 3
112  %gep = getelementptr inbounds i32, ptr %x, i32 %shr
113  ret ptr %gep
114}
115
116define dso_local ptr @test_exact5(i32 %a, i32 %b, ptr %x)  {
117; X32-LABEL: test_exact5:
118; X32:       # %bb.0:
119; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
120; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
121; X32-NEXT:    shrl %eax
122; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
123; X32-NEXT:    retl
124;
125; X64-LABEL: test_exact5:
126; X64:       # %bb.0:
127; X64-NEXT:    # kill: def $esi killed $esi def $rsi
128; X64-NEXT:    subl %edi, %esi
129; X64-NEXT:    shrl $3, %esi
130; X64-NEXT:    leaq (%rdx,%rsi,4), %rax
131; X64-NEXT:    retq
132  %sub = sub i32 %b, %a
133  %shr = lshr exact i32 %sub, 3
134  %gep = getelementptr inbounds i32, ptr %x, i32 %shr
135  ret ptr %gep
136}
137
138define dso_local ptr @test_exact6(i32 %a, i32 %b, ptr %x)  {
139; X32-LABEL: test_exact6:
140; X32:       # %bb.0:
141; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
142; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
143; X32-NEXT:    addl {{[0-9]+}}(%esp), %eax
144; X32-NEXT:    retl
145;
146; X64-LABEL: test_exact6:
147; X64:       # %bb.0:
148; X64-NEXT:    # kill: def $esi killed $esi def $rsi
149; X64-NEXT:    subl %edi, %esi
150; X64-NEXT:    leaq (%rsi,%rdx), %rax
151; X64-NEXT:    retq
152  %sub = sub i32 %b, %a
153  %shr = lshr exact i32 %sub, 2
154  %gep = getelementptr inbounds i32, ptr %x, i32 %shr
155  ret ptr %gep
156}
157
158; PR42644 - https://bugs.llvm.org/show_bug.cgi?id=42644
159
160define i64 @ashr_add_shl_i32(i64 %r) nounwind {
161; X32-LABEL: ashr_add_shl_i32:
162; X32:       # %bb.0:
163; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
164; X32-NEXT:    incl %eax
165; X32-NEXT:    movl %eax, %edx
166; X32-NEXT:    sarl $31, %edx
167; X32-NEXT:    retl
168;
169; X64-LABEL: ashr_add_shl_i32:
170; X64:       # %bb.0:
171; X64-NEXT:    incl %edi
172; X64-NEXT:    movslq %edi, %rax
173; X64-NEXT:    retq
174  %conv = shl i64 %r, 32
175  %sext = add i64 %conv, 4294967296
176  %conv1 = ashr i64 %sext, 32
177  ret i64 %conv1
178}
179
180define i64 @ashr_add_shl_i8(i64 %r) nounwind {
181; X32-LABEL: ashr_add_shl_i8:
182; X32:       # %bb.0:
183; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
184; X32-NEXT:    addb $2, %al
185; X32-NEXT:    movsbl %al, %eax
186; X32-NEXT:    movl %eax, %edx
187; X32-NEXT:    sarl $31, %edx
188; X32-NEXT:    retl
189;
190; X64-LABEL: ashr_add_shl_i8:
191; X64:       # %bb.0:
192; X64-NEXT:    addb $2, %dil
193; X64-NEXT:    movsbq %dil, %rax
194; X64-NEXT:    retq
195  %conv = shl i64 %r, 56
196  %sext = add i64 %conv, 144115188075855872
197  %conv1 = ashr i64 %sext, 56
198  ret i64 %conv1
199}
200
201define <4 x i32> @ashr_add_shl_v4i8(<4 x i32> %r) nounwind {
202; X32-LABEL: ashr_add_shl_v4i8:
203; X32:       # %bb.0:
204; X32-NEXT:    pushl %edi
205; X32-NEXT:    pushl %esi
206; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
207; X32-NEXT:    movb {{[0-9]+}}(%esp), %cl
208; X32-NEXT:    movb {{[0-9]+}}(%esp), %dl
209; X32-NEXT:    movb {{[0-9]+}}(%esp), %ch
210; X32-NEXT:    movb {{[0-9]+}}(%esp), %dh
211; X32-NEXT:    incb %dh
212; X32-NEXT:    movsbl %dh, %esi
213; X32-NEXT:    incb %ch
214; X32-NEXT:    movsbl %ch, %edi
215; X32-NEXT:    incb %dl
216; X32-NEXT:    movsbl %dl, %edx
217; X32-NEXT:    incb %cl
218; X32-NEXT:    movsbl %cl, %ecx
219; X32-NEXT:    movl %ecx, 12(%eax)
220; X32-NEXT:    movl %edx, 8(%eax)
221; X32-NEXT:    movl %edi, 4(%eax)
222; X32-NEXT:    movl %esi, (%eax)
223; X32-NEXT:    popl %esi
224; X32-NEXT:    popl %edi
225; X32-NEXT:    retl $4
226;
227; X64-LABEL: ashr_add_shl_v4i8:
228; X64:       # %bb.0:
229; X64-NEXT:    pslld $24, %xmm0
230; X64-NEXT:    paddd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0
231; X64-NEXT:    psrad $24, %xmm0
232; X64-NEXT:    retq
233  %conv = shl <4 x i32> %r, <i32 24, i32 24, i32 24, i32 24>
234  %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216>
235  %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24>
236  ret <4 x i32> %conv1
237}
238
239define i64 @ashr_add_shl_i36(i64 %r) nounwind {
240; X32-LABEL: ashr_add_shl_i36:
241; X32:       # %bb.0:
242; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
243; X32-NEXT:    shll $4, %edx
244; X32-NEXT:    movl %edx, %eax
245; X32-NEXT:    sarl $4, %eax
246; X32-NEXT:    sarl $31, %edx
247; X32-NEXT:    retl
248;
249; X64-LABEL: ashr_add_shl_i36:
250; X64:       # %bb.0:
251; X64-NEXT:    movq %rdi, %rax
252; X64-NEXT:    shlq $36, %rax
253; X64-NEXT:    sarq $36, %rax
254; X64-NEXT:    retq
255  %conv = shl i64 %r, 36
256  %sext = add i64 %conv, 4294967296
257  %conv1 = ashr i64 %sext, 36
258  ret i64 %conv1
259}
260
261define i64 @ashr_add_shl_mismatch_shifts1(i64 %r) nounwind {
262; X32-LABEL: ashr_add_shl_mismatch_shifts1:
263; X32:       # %bb.0:
264; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
265; X32-NEXT:    incl %eax
266; X32-NEXT:    movl %eax, %edx
267; X32-NEXT:    sarl $31, %edx
268; X32-NEXT:    retl
269;
270; X64-LABEL: ashr_add_shl_mismatch_shifts1:
271; X64:       # %bb.0:
272; X64-NEXT:    shlq $8, %rdi
273; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
274; X64-NEXT:    addq %rdi, %rax
275; X64-NEXT:    sarq $32, %rax
276; X64-NEXT:    retq
277  %conv = shl i64 %r, 8
278  %sext = add i64 %conv, 4294967296
279  %conv1 = ashr i64 %sext, 32
280  ret i64 %conv1
281}
282
283define i64 @ashr_add_shl_mismatch_shifts2(i64 %r) nounwind {
284; X32-LABEL: ashr_add_shl_mismatch_shifts2:
285; X32:       # %bb.0:
286; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
287; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
288; X32-NEXT:    shrl $8, %edx
289; X32-NEXT:    incl %edx
290; X32-NEXT:    shrdl $8, %edx, %eax
291; X32-NEXT:    shrl $8, %edx
292; X32-NEXT:    retl
293;
294; X64-LABEL: ashr_add_shl_mismatch_shifts2:
295; X64:       # %bb.0:
296; X64-NEXT:    shrq $8, %rdi
297; X64-NEXT:    movabsq $4294967296, %rax # imm = 0x100000000
298; X64-NEXT:    addq %rdi, %rax
299; X64-NEXT:    shrq $8, %rax
300; X64-NEXT:    retq
301  %conv = lshr i64 %r, 8
302  %sext = add i64 %conv, 4294967296
303  %conv1 = ashr i64 %sext, 8
304  ret i64 %conv1
305}
306
307define dso_local i32 @ashr_add_shl_i32_i8_extra_use1(i32 %r, ptr %p) nounwind {
308; X32-LABEL: ashr_add_shl_i32_i8_extra_use1:
309; X32:       # %bb.0:
310; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
311; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
312; X32-NEXT:    shll $24, %eax
313; X32-NEXT:    addl $33554432, %eax # imm = 0x2000000
314; X32-NEXT:    movl %eax, (%ecx)
315; X32-NEXT:    sarl $24, %eax
316; X32-NEXT:    retl
317;
318; X64-LABEL: ashr_add_shl_i32_i8_extra_use1:
319; X64:       # %bb.0:
320; X64-NEXT:    # kill: def $edi killed $edi def $rdi
321; X64-NEXT:    shll $24, %edi
322; X64-NEXT:    leal 33554432(%rdi), %eax
323; X64-NEXT:    movl %eax, (%rsi)
324; X64-NEXT:    sarl $24, %eax
325; X64-NEXT:    retq
326  %conv = shl i32 %r, 24
327  %sext = add i32 %conv, 33554432
328  store i32 %sext, ptr %p
329  %conv1 = ashr i32 %sext, 24
330  ret i32 %conv1
331}
332
333define dso_local i32 @ashr_add_shl_i32_i8_extra_use2(i32 %r, ptr %p) nounwind {
334; X32-LABEL: ashr_add_shl_i32_i8_extra_use2:
335; X32:       # %bb.0:
336; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
337; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
338; X32-NEXT:    shll $24, %eax
339; X32-NEXT:    movl %eax, (%ecx)
340; X32-NEXT:    addl $33554432, %eax # imm = 0x2000000
341; X32-NEXT:    sarl $24, %eax
342; X32-NEXT:    retl
343;
344; X64-LABEL: ashr_add_shl_i32_i8_extra_use2:
345; X64:       # %bb.0:
346; X64-NEXT:    # kill: def $edi killed $edi def $rdi
347; X64-NEXT:    shll $24, %edi
348; X64-NEXT:    movl %edi, (%rsi)
349; X64-NEXT:    leal 33554432(%rdi), %eax
350; X64-NEXT:    sarl $24, %eax
351; X64-NEXT:    retq
352  %conv = shl i32 %r, 24
353  store i32 %conv, ptr %p
354  %sext = add i32 %conv, 33554432
355  %conv1 = ashr i32 %sext, 24
356  ret i32 %conv1
357}
358
359define dso_local i32 @ashr_add_shl_i32_i8_extra_use3(i32 %r, ptr %p1, ptr %p2) nounwind {
360; X32-LABEL: ashr_add_shl_i32_i8_extra_use3:
361; X32:       # %bb.0:
362; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
363; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
364; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
365; X32-NEXT:    shll $24, %eax
366; X32-NEXT:    movl %eax, (%edx)
367; X32-NEXT:    addl $33554432, %eax # imm = 0x2000000
368; X32-NEXT:    movl %eax, (%ecx)
369; X32-NEXT:    sarl $24, %eax
370; X32-NEXT:    retl
371;
372; X64-LABEL: ashr_add_shl_i32_i8_extra_use3:
373; X64:       # %bb.0:
374; X64-NEXT:    # kill: def $edi killed $edi def $rdi
375; X64-NEXT:    shll $24, %edi
376; X64-NEXT:    movl %edi, (%rsi)
377; X64-NEXT:    leal 33554432(%rdi), %eax
378; X64-NEXT:    movl %eax, (%rdx)
379; X64-NEXT:    sarl $24, %eax
380; X64-NEXT:    retq
381  %conv = shl i32 %r, 24
382  store i32 %conv, ptr %p1
383  %sext = add i32 %conv, 33554432
384  store i32 %sext, ptr %p2
385  %conv1 = ashr i32 %sext, 24
386  ret i32 %conv1
387}
388
389%"class.QPainterPath" = type { double, double, i32 }
390
391define dso_local void @PR42880(i32 %t0) {
392; X32-LABEL: PR42880:
393; X32:       # %bb.0:
394; X32-NEXT:    xorl %eax, %eax
395; X32-NEXT:    testb %al, %al
396; X32-NEXT:    je .LBB16_1
397; X32-NEXT:  # %bb.2: # %if
398; X32-NEXT:  .LBB16_1: # %then
399;
400; X64-LABEL: PR42880:
401; X64:       # %bb.0:
402; X64-NEXT:    xorl %eax, %eax
403; X64-NEXT:    testb %al, %al
404; X64-NEXT:    je .LBB16_1
405; X64-NEXT:  # %bb.2: # %if
406; X64-NEXT:  .LBB16_1: # %then
407  %sub = add nsw i32 %t0, -1
408  %add.ptr.i94 = getelementptr inbounds %"class.QPainterPath", ptr null, i32 %sub
409  %x = ptrtoint ptr %add.ptr.i94 to i32
410  %sub2 = sub i32 %x, 0
411  %div = sdiv exact i32 %sub2, 24
412  br i1 undef, label %if, label %then
413
414then:
415  %t1 = xor i32 %div, -1
416  unreachable
417
418if:
419  unreachable
420}
421
422; The mul here is the equivalent of (neg (shl X, 32)).
423define i64 @ashr_add_neg_shl_i32(i64 %r) nounwind {
424; X32-LABEL: ashr_add_neg_shl_i32:
425; X32:       # %bb.0:
426; X32-NEXT:    movl $1, %eax
427; X32-NEXT:    subl {{[0-9]+}}(%esp), %eax
428; X32-NEXT:    movl %eax, %edx
429; X32-NEXT:    sarl $31, %edx
430; X32-NEXT:    retl
431;
432; X64-LABEL: ashr_add_neg_shl_i32:
433; X64:       # %bb.0:
434; X64-NEXT:    movl $1, %eax
435; X64-NEXT:    subl %edi, %eax
436; X64-NEXT:    cltq
437; X64-NEXT:    retq
438  %conv = mul i64 %r, -4294967296
439  %sext = add i64 %conv, 4294967296
440  %conv1 = ashr i64 %sext, 32
441  ret i64 %conv1
442}
443
444; The mul here is the equivalent of (neg (shl X, 56)).
445define i64 @ashr_add_neg_shl_i8(i64 %r) nounwind {
446; X32-LABEL: ashr_add_neg_shl_i8:
447; X32:       # %bb.0:
448; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
449; X32-NEXT:    shll $24, %eax
450; X32-NEXT:    movl $33554432, %edx # imm = 0x2000000
451; X32-NEXT:    subl %eax, %edx
452; X32-NEXT:    movl %edx, %eax
453; X32-NEXT:    sarl $24, %eax
454; X32-NEXT:    sarl $31, %edx
455; X32-NEXT:    retl
456;
457; X64-LABEL: ashr_add_neg_shl_i8:
458; X64:       # %bb.0:
459; X64-NEXT:    movb $2, %al
460; X64-NEXT:    subb %dil, %al
461; X64-NEXT:    movsbq %al, %rax
462; X64-NEXT:    retq
463  %conv = mul i64 %r, -72057594037927936
464  %sext = add i64 %conv, 144115188075855872
465  %conv1 = ashr i64 %sext, 56
466  ret i64 %conv1
467}
468
469; The mul here is the equivalent of (neg (shl X, 24)).
470define <4 x i32> @ashr_add_neg_shl_v4i8(<4 x i32> %r) nounwind {
471; X32-LABEL: ashr_add_neg_shl_v4i8:
472; X32:       # %bb.0:
473; X32-NEXT:    pushl %edi
474; X32-NEXT:    pushl %esi
475; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
476; X32-NEXT:    movb $1, %cl
477; X32-NEXT:    movb $1, %dl
478; X32-NEXT:    subb {{[0-9]+}}(%esp), %dl
479; X32-NEXT:    movsbl %dl, %edx
480; X32-NEXT:    movb $1, %ch
481; X32-NEXT:    subb {{[0-9]+}}(%esp), %ch
482; X32-NEXT:    movsbl %ch, %esi
483; X32-NEXT:    movb $1, %ch
484; X32-NEXT:    subb {{[0-9]+}}(%esp), %ch
485; X32-NEXT:    movsbl %ch, %edi
486; X32-NEXT:    subb {{[0-9]+}}(%esp), %cl
487; X32-NEXT:    movsbl %cl, %ecx
488; X32-NEXT:    movl %ecx, 12(%eax)
489; X32-NEXT:    movl %edi, 8(%eax)
490; X32-NEXT:    movl %esi, 4(%eax)
491; X32-NEXT:    movl %edx, (%eax)
492; X32-NEXT:    popl %esi
493; X32-NEXT:    popl %edi
494; X32-NEXT:    retl $4
495;
496; X64-LABEL: ashr_add_neg_shl_v4i8:
497; X64:       # %bb.0:
498; X64-NEXT:    pslld $24, %xmm0
499; X64-NEXT:    movdqa {{.*#+}} xmm1 = [16777216,16777216,16777216,16777216]
500; X64-NEXT:    psubd %xmm0, %xmm1
501; X64-NEXT:    psrad $24, %xmm1
502; X64-NEXT:    movdqa %xmm1, %xmm0
503; X64-NEXT:    retq
504  %conv = mul <4 x i32> %r, <i32 -16777216, i32 -16777216, i32 -16777216, i32 -16777216>
505  %sext = add <4 x i32> %conv, <i32 16777216, i32 16777216, i32 16777216, i32 16777216>
506  %conv1 = ashr <4 x i32> %sext, <i32 24, i32 24, i32 24, i32 24>
507  ret <4 x i32> %conv1
508}
509