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: movzbl {{[0-9]+}}(%esp), %eax 81; X32-NEXT: andl $1, %eax 82; X32-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 83; X32-NEXT: andl $1, %ecx 84; X32-NEXT: movzbl {{[0-9]+}}(%esp), %edx 85; X32-NEXT: andl $1, %edx 86; X32-NEXT: movzbl {{[0-9]+}}(%esp), %esi 87; X32-NEXT: andl $1, %esi 88; X32-NEXT: leal (%eax,%ecx,2), %eax 89; X32-NEXT: leal (%eax,%edx,4), %eax 90; X32-NEXT: leal (%eax,%esi,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: pushl %esi 98; X32-SSE2-NEXT: .cfi_def_cfa_offset 8 99; X32-SSE2-NEXT: .cfi_offset %esi, -8 100; X32-SSE2-NEXT: movd %xmm0, %eax 101; X32-SSE2-NEXT: andl $1, %eax 102; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3] 103; X32-SSE2-NEXT: movd %xmm1, %ecx 104; X32-SSE2-NEXT: andl $1, %ecx 105; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1] 106; X32-SSE2-NEXT: movd %xmm1, %edx 107; X32-SSE2-NEXT: andl $1, %edx 108; X32-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3] 109; X32-SSE2-NEXT: movd %xmm0, %esi 110; X32-SSE2-NEXT: andl $1, %esi 111; X32-SSE2-NEXT: leal (%eax,%ecx,2), %eax 112; X32-SSE2-NEXT: leal (%eax,%edx,4), %eax 113; X32-SSE2-NEXT: leal (%eax,%esi,8), %eax 114; X32-SSE2-NEXT: popl %esi 115; X32-SSE2-NEXT: .cfi_def_cfa_offset 4 116; X32-SSE2-NEXT: retl 117; 118; X32-AVX2-LABEL: PR15215_good: 119; X32-AVX2: # %bb.0: # %entry 120; X32-AVX2-NEXT: pushl %esi 121; X32-AVX2-NEXT: .cfi_def_cfa_offset 8 122; X32-AVX2-NEXT: .cfi_offset %esi, -8 123; X32-AVX2-NEXT: vmovd %xmm0, %eax 124; X32-AVX2-NEXT: andl $1, %eax 125; X32-AVX2-NEXT: vpextrd $1, %xmm0, %ecx 126; X32-AVX2-NEXT: andl $1, %ecx 127; X32-AVX2-NEXT: vpextrd $2, %xmm0, %edx 128; X32-AVX2-NEXT: andl $1, %edx 129; X32-AVX2-NEXT: vpextrd $3, %xmm0, %esi 130; X32-AVX2-NEXT: andl $1, %esi 131; X32-AVX2-NEXT: leal (%eax,%ecx,2), %eax 132; X32-AVX2-NEXT: leal (%eax,%edx,4), %eax 133; X32-AVX2-NEXT: leal (%eax,%esi,8), %eax 134; X32-AVX2-NEXT: popl %esi 135; X32-AVX2-NEXT: .cfi_def_cfa_offset 4 136; X32-AVX2-NEXT: retl 137; 138; X64-LABEL: PR15215_good: 139; X64: # %bb.0: # %entry 140; X64-NEXT: # kill: def $ecx killed $ecx def $rcx 141; X64-NEXT: # kill: def $edx killed $edx def $rdx 142; X64-NEXT: # kill: def $esi killed $esi def $rsi 143; X64-NEXT: # kill: def $edi killed $edi def $rdi 144; X64-NEXT: andl $1, %edi 145; X64-NEXT: andl $1, %esi 146; X64-NEXT: andl $1, %edx 147; X64-NEXT: andl $1, %ecx 148; X64-NEXT: leal (%rdi,%rsi,2), %eax 149; X64-NEXT: leal (%rax,%rdx,4), %eax 150; X64-NEXT: leal (%rax,%rcx,8), %eax 151; X64-NEXT: retq 152; 153; X64-SSE2-LABEL: PR15215_good: 154; X64-SSE2: # %bb.0: # %entry 155; X64-SSE2-NEXT: movd %xmm0, %eax 156; X64-SSE2-NEXT: andl $1, %eax 157; X64-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3] 158; X64-SSE2-NEXT: movd %xmm1, %ecx 159; X64-SSE2-NEXT: andl $1, %ecx 160; X64-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1] 161; X64-SSE2-NEXT: movd %xmm1, %edx 162; X64-SSE2-NEXT: andl $1, %edx 163; X64-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3] 164; X64-SSE2-NEXT: movd %xmm0, %esi 165; X64-SSE2-NEXT: andl $1, %esi 166; X64-SSE2-NEXT: leal (%rax,%rcx,2), %eax 167; X64-SSE2-NEXT: leal (%rax,%rdx,4), %eax 168; X64-SSE2-NEXT: leal (%rax,%rsi,8), %eax 169; X64-SSE2-NEXT: retq 170; 171; X64-AVX2-LABEL: PR15215_good: 172; X64-AVX2: # %bb.0: # %entry 173; X64-AVX2-NEXT: vmovd %xmm0, %eax 174; X64-AVX2-NEXT: andl $1, %eax 175; X64-AVX2-NEXT: vpextrd $1, %xmm0, %ecx 176; X64-AVX2-NEXT: andl $1, %ecx 177; X64-AVX2-NEXT: vpextrd $2, %xmm0, %edx 178; X64-AVX2-NEXT: andl $1, %edx 179; X64-AVX2-NEXT: vpextrd $3, %xmm0, %esi 180; X64-AVX2-NEXT: andl $1, %esi 181; X64-AVX2-NEXT: leal (%rax,%rcx,2), %eax 182; X64-AVX2-NEXT: leal (%rax,%rdx,4), %eax 183; X64-AVX2-NEXT: leal (%rax,%rsi,8), %eax 184; X64-AVX2-NEXT: retq 185entry: 186 %0 = trunc <4 x i32> %input to <4 x i1> 187 %1 = extractelement <4 x i1> %0, i32 0 188 %e1 = select i1 %1, i32 1, i32 0 189 %2 = extractelement <4 x i1> %0, i32 1 190 %e2 = select i1 %2, i32 2, i32 0 191 %3 = extractelement <4 x i1> %0, i32 2 192 %e3 = select i1 %3, i32 4, i32 0 193 %4 = extractelement <4 x i1> %0, i32 3 194 %e4 = select i1 %4, i32 8, i32 0 195 %5 = or i32 %e1, %e2 196 %6 = or i32 %5, %e3 197 %7 = or i32 %6, %e4 198 ret i32 %7 199} 200