1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=-sse2 | FileCheck %s --check-prefix=X32
3; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X32-SSE2
4; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=X32-AVX2
5; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=-sse2 | FileCheck %s --check-prefix=X64
6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefix=X64-SSE2
7; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefix=X64-AVX2
8
9define i32 @PR15215_bad(<4 x i32> %input) {
10; X32-LABEL: PR15215_bad:
11; X32:       # %bb.0: # %entry
12; X32-NEXT:    movb {{[0-9]+}}(%esp), %al
13; X32-NEXT:    movb {{[0-9]+}}(%esp), %cl
14; X32-NEXT:    movb {{[0-9]+}}(%esp), %dl
15; X32-NEXT:    movb {{[0-9]+}}(%esp), %ah
16; X32-NEXT:    addb %ah, %ah
17; X32-NEXT:    andb $1, %dl
18; X32-NEXT:    orb %ah, %dl
19; X32-NEXT:    shlb $2, %dl
20; X32-NEXT:    addb %cl, %cl
21; X32-NEXT:    andb $1, %al
22; X32-NEXT:    orb %cl, %al
23; X32-NEXT:    andb $3, %al
24; X32-NEXT:    orb %dl, %al
25; X32-NEXT:    movzbl %al, %eax
26; X32-NEXT:    andl $15, %eax
27; X32-NEXT:    retl
28;
29; X32-SSE2-LABEL: PR15215_bad:
30; X32-SSE2:       # %bb.0: # %entry
31; X32-SSE2-NEXT:    pslld $31, %xmm0
32; X32-SSE2-NEXT:    movmskps %xmm0, %eax
33; X32-SSE2-NEXT:    retl
34;
35; X32-AVX2-LABEL: PR15215_bad:
36; X32-AVX2:       # %bb.0: # %entry
37; X32-AVX2-NEXT:    vpslld $31, %xmm0, %xmm0
38; X32-AVX2-NEXT:    vmovmskps %xmm0, %eax
39; X32-AVX2-NEXT:    retl
40;
41; X64-LABEL: PR15215_bad:
42; X64:       # %bb.0: # %entry
43; X64-NEXT:    addb %cl, %cl
44; X64-NEXT:    andb $1, %dl
45; X64-NEXT:    orb %cl, %dl
46; X64-NEXT:    shlb $2, %dl
47; X64-NEXT:    addb %sil, %sil
48; X64-NEXT:    andb $1, %dil
49; X64-NEXT:    orb %sil, %dil
50; X64-NEXT:    andb $3, %dil
51; X64-NEXT:    orb %dl, %dil
52; X64-NEXT:    movzbl %dil, %eax
53; X64-NEXT:    andl $15, %eax
54; X64-NEXT:    retq
55;
56; X64-SSE2-LABEL: PR15215_bad:
57; X64-SSE2:       # %bb.0: # %entry
58; X64-SSE2-NEXT:    pslld $31, %xmm0
59; X64-SSE2-NEXT:    movmskps %xmm0, %eax
60; X64-SSE2-NEXT:    retq
61;
62; X64-AVX2-LABEL: PR15215_bad:
63; X64-AVX2:       # %bb.0: # %entry
64; X64-AVX2-NEXT:    vpslld $31, %xmm0, %xmm0
65; X64-AVX2-NEXT:    vmovmskps %xmm0, %eax
66; X64-AVX2-NEXT:    retq
67entry:
68  %0 = trunc <4 x i32> %input to <4 x i1>
69  %1 = bitcast <4 x i1> %0 to i4
70  %2 = zext i4 %1 to i32
71  ret i32 %2
72}
73
74define i32 @PR15215_good(<4 x i32> %input) {
75; X32-LABEL: PR15215_good:
76; X32:       # %bb.0: # %entry
77; X32-NEXT:    pushl %esi
78; X32-NEXT:    .cfi_def_cfa_offset 8
79; X32-NEXT:    .cfi_offset %esi, -8
80; X32-NEXT:    movl {{[0-9]+}}(%esp), %eax
81; X32-NEXT:    movl {{[0-9]+}}(%esp), %ecx
82; X32-NEXT:    movl {{[0-9]+}}(%esp), %edx
83; X32-NEXT:    movl {{[0-9]+}}(%esp), %esi
84; X32-NEXT:    andl $1, %esi
85; X32-NEXT:    andl $1, %edx
86; X32-NEXT:    andl $1, %ecx
87; X32-NEXT:    andl $1, %eax
88; X32-NEXT:    leal (%esi,%edx,2), %edx
89; X32-NEXT:    leal (%edx,%ecx,4), %ecx
90; X32-NEXT:    leal (%ecx,%eax,8), %eax
91; X32-NEXT:    popl %esi
92; X32-NEXT:    .cfi_def_cfa_offset 4
93; X32-NEXT:    retl
94;
95; X32-SSE2-LABEL: PR15215_good:
96; X32-SSE2:       # %bb.0: # %entry
97; X32-SSE2-NEXT:    pslld $31, %xmm0
98; X32-SSE2-NEXT:    movmskps %xmm0, %eax
99; X32-SSE2-NEXT:    retl
100;
101; X32-AVX2-LABEL: PR15215_good:
102; X32-AVX2:       # %bb.0: # %entry
103; X32-AVX2-NEXT:    vpslld $31, %xmm0, %xmm0
104; X32-AVX2-NEXT:    vmovmskps %xmm0, %eax
105; X32-AVX2-NEXT:    retl
106;
107; X64-LABEL: PR15215_good:
108; X64:       # %bb.0: # %entry
109; X64-NEXT:    # kill: def $ecx killed $ecx def $rcx
110; X64-NEXT:    # kill: def $edx killed $edx def $rdx
111; X64-NEXT:    # kill: def $esi killed $esi def $rsi
112; X64-NEXT:    # kill: def $edi killed $edi def $rdi
113; X64-NEXT:    andl $1, %edi
114; X64-NEXT:    andl $1, %esi
115; X64-NEXT:    andl $1, %edx
116; X64-NEXT:    andl $1, %ecx
117; X64-NEXT:    leal (%rdi,%rsi,2), %eax
118; X64-NEXT:    leal (%rax,%rdx,4), %eax
119; X64-NEXT:    leal (%rax,%rcx,8), %eax
120; X64-NEXT:    retq
121;
122; X64-SSE2-LABEL: PR15215_good:
123; X64-SSE2:       # %bb.0: # %entry
124; X64-SSE2-NEXT:    pslld $31, %xmm0
125; X64-SSE2-NEXT:    movmskps %xmm0, %eax
126; X64-SSE2-NEXT:    retq
127;
128; X64-AVX2-LABEL: PR15215_good:
129; X64-AVX2:       # %bb.0: # %entry
130; X64-AVX2-NEXT:    vpslld $31, %xmm0, %xmm0
131; X64-AVX2-NEXT:    vmovmskps %xmm0, %eax
132; X64-AVX2-NEXT:    retq
133entry:
134  %0 = trunc <4 x i32> %input to <4 x i1>
135  %1 = extractelement <4 x i1> %0, i32 0
136  %e1 = select i1 %1, i32 1, i32 0
137  %2 = extractelement <4 x i1> %0, i32 1
138  %e2 = select i1 %2, i32 2, i32 0
139  %3 = extractelement <4 x i1> %0, i32 2
140  %e3 = select i1 %3, i32 4, i32 0
141  %4 = extractelement <4 x i1> %0, i32 3
142  %e4 = select i1 %4, i32 8, i32 0
143  %5 = or i32 %e1, %e2
144  %6 = or i32 %5, %e3
145  %7 = or i32 %6, %e4
146  ret i32 %7
147}
148