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: psrad $31, %xmm0 33; X32-SSE2-NEXT: movmskps %xmm0, %eax 34; X32-SSE2-NEXT: retl 35; 36; X32-AVX2-LABEL: PR15215_bad: 37; X32-AVX2: # %bb.0: # %entry 38; X32-AVX2-NEXT: vpslld $31, %xmm0, %xmm0 39; X32-AVX2-NEXT: vpsrad $31, %xmm0, %xmm0 40; X32-AVX2-NEXT: vmovmskps %xmm0, %eax 41; X32-AVX2-NEXT: retl 42; 43; X64-LABEL: PR15215_bad: 44; X64: # %bb.0: # %entry 45; X64-NEXT: addb %cl, %cl 46; X64-NEXT: andb $1, %dl 47; X64-NEXT: orb %cl, %dl 48; X64-NEXT: shlb $2, %dl 49; X64-NEXT: addb %sil, %sil 50; X64-NEXT: andb $1, %dil 51; X64-NEXT: orb %sil, %dil 52; X64-NEXT: andb $3, %dil 53; X64-NEXT: orb %dl, %dil 54; X64-NEXT: movzbl %dil, %eax 55; X64-NEXT: andl $15, %eax 56; X64-NEXT: retq 57; 58; X64-SSE2-LABEL: PR15215_bad: 59; X64-SSE2: # %bb.0: # %entry 60; X64-SSE2-NEXT: pslld $31, %xmm0 61; X64-SSE2-NEXT: psrad $31, %xmm0 62; X64-SSE2-NEXT: movmskps %xmm0, %eax 63; X64-SSE2-NEXT: retq 64; 65; X64-AVX2-LABEL: PR15215_bad: 66; X64-AVX2: # %bb.0: # %entry 67; X64-AVX2-NEXT: vpslld $31, %xmm0, %xmm0 68; X64-AVX2-NEXT: vpsrad $31, %xmm0, %xmm0 69; X64-AVX2-NEXT: vmovmskps %xmm0, %eax 70; X64-AVX2-NEXT: retq 71entry: 72 %0 = trunc <4 x i32> %input to <4 x i1> 73 %1 = bitcast <4 x i1> %0 to i4 74 %2 = zext i4 %1 to i32 75 ret i32 %2 76} 77 78define i32 @PR15215_good(<4 x i32> %input) { 79; X32-LABEL: PR15215_good: 80; X32: # %bb.0: # %entry 81; X32-NEXT: pushl %esi 82; X32-NEXT: .cfi_def_cfa_offset 8 83; X32-NEXT: .cfi_offset %esi, -8 84; X32-NEXT: movzbl {{[0-9]+}}(%esp), %eax 85; X32-NEXT: andl $1, %eax 86; X32-NEXT: movzbl {{[0-9]+}}(%esp), %ecx 87; X32-NEXT: andl $1, %ecx 88; X32-NEXT: movzbl {{[0-9]+}}(%esp), %edx 89; X32-NEXT: andl $1, %edx 90; X32-NEXT: movzbl {{[0-9]+}}(%esp), %esi 91; X32-NEXT: andl $1, %esi 92; X32-NEXT: leal (%eax,%ecx,2), %eax 93; X32-NEXT: leal (%eax,%edx,4), %eax 94; X32-NEXT: leal (%eax,%esi,8), %eax 95; X32-NEXT: popl %esi 96; X32-NEXT: retl 97; 98; X32-SSE2-LABEL: PR15215_good: 99; X32-SSE2: # %bb.0: # %entry 100; X32-SSE2-NEXT: pushl %esi 101; X32-SSE2-NEXT: .cfi_def_cfa_offset 8 102; X32-SSE2-NEXT: .cfi_offset %esi, -8 103; X32-SSE2-NEXT: movd %xmm0, %eax 104; X32-SSE2-NEXT: andl $1, %eax 105; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3] 106; X32-SSE2-NEXT: movd %xmm1, %ecx 107; X32-SSE2-NEXT: andl $1, %ecx 108; X32-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1] 109; X32-SSE2-NEXT: movd %xmm1, %edx 110; X32-SSE2-NEXT: andl $1, %edx 111; X32-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3] 112; X32-SSE2-NEXT: movd %xmm0, %esi 113; X32-SSE2-NEXT: andl $1, %esi 114; X32-SSE2-NEXT: leal (%eax,%ecx,2), %eax 115; X32-SSE2-NEXT: leal (%eax,%edx,4), %eax 116; X32-SSE2-NEXT: leal (%eax,%esi,8), %eax 117; X32-SSE2-NEXT: popl %esi 118; X32-SSE2-NEXT: retl 119; 120; X32-AVX2-LABEL: PR15215_good: 121; X32-AVX2: # %bb.0: # %entry 122; X32-AVX2-NEXT: pushl %esi 123; X32-AVX2-NEXT: .cfi_def_cfa_offset 8 124; X32-AVX2-NEXT: .cfi_offset %esi, -8 125; X32-AVX2-NEXT: vmovd %xmm0, %eax 126; X32-AVX2-NEXT: andl $1, %eax 127; X32-AVX2-NEXT: vpextrd $1, %xmm0, %ecx 128; X32-AVX2-NEXT: andl $1, %ecx 129; X32-AVX2-NEXT: vpextrd $2, %xmm0, %edx 130; X32-AVX2-NEXT: andl $1, %edx 131; X32-AVX2-NEXT: vpextrd $3, %xmm0, %esi 132; X32-AVX2-NEXT: andl $1, %esi 133; X32-AVX2-NEXT: leal (%eax,%ecx,2), %eax 134; X32-AVX2-NEXT: leal (%eax,%edx,4), %eax 135; X32-AVX2-NEXT: leal (%eax,%esi,8), %eax 136; X32-AVX2-NEXT: popl %esi 137; X32-AVX2-NEXT: retl 138; 139; X64-LABEL: PR15215_good: 140; X64: # %bb.0: # %entry 141; X64-NEXT: # kill: def $ecx killed $ecx def $rcx 142; X64-NEXT: # kill: def $edx killed $edx def $rdx 143; X64-NEXT: # kill: def $esi killed $esi def $rsi 144; X64-NEXT: # kill: def $edi killed $edi def $rdi 145; X64-NEXT: andl $1, %edi 146; X64-NEXT: andl $1, %esi 147; X64-NEXT: andl $1, %edx 148; X64-NEXT: andl $1, %ecx 149; X64-NEXT: leal (%rdi,%rsi,2), %eax 150; X64-NEXT: leal (%rax,%rdx,4), %eax 151; X64-NEXT: leal (%rax,%rcx,8), %eax 152; X64-NEXT: retq 153; 154; X64-SSE2-LABEL: PR15215_good: 155; X64-SSE2: # %bb.0: # %entry 156; X64-SSE2-NEXT: movd %xmm0, %eax 157; X64-SSE2-NEXT: andl $1, %eax 158; X64-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,2,3] 159; X64-SSE2-NEXT: movd %xmm1, %ecx 160; X64-SSE2-NEXT: andl $1, %ecx 161; X64-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,0,1] 162; X64-SSE2-NEXT: movd %xmm1, %edx 163; X64-SSE2-NEXT: andl $1, %edx 164; X64-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,1,2,3] 165; X64-SSE2-NEXT: movd %xmm0, %esi 166; X64-SSE2-NEXT: andl $1, %esi 167; X64-SSE2-NEXT: leal (%rax,%rcx,2), %eax 168; X64-SSE2-NEXT: leal (%rax,%rdx,4), %eax 169; X64-SSE2-NEXT: leal (%rax,%rsi,8), %eax 170; X64-SSE2-NEXT: retq 171; 172; X64-AVX2-LABEL: PR15215_good: 173; X64-AVX2: # %bb.0: # %entry 174; X64-AVX2-NEXT: vmovd %xmm0, %eax 175; X64-AVX2-NEXT: andl $1, %eax 176; X64-AVX2-NEXT: vpextrd $1, %xmm0, %ecx 177; X64-AVX2-NEXT: andl $1, %ecx 178; X64-AVX2-NEXT: vpextrd $2, %xmm0, %edx 179; X64-AVX2-NEXT: andl $1, %edx 180; X64-AVX2-NEXT: vpextrd $3, %xmm0, %esi 181; X64-AVX2-NEXT: andl $1, %esi 182; X64-AVX2-NEXT: leal (%rax,%rcx,2), %eax 183; X64-AVX2-NEXT: leal (%rax,%rdx,4), %eax 184; X64-AVX2-NEXT: leal (%rax,%rsi,8), %eax 185; X64-AVX2-NEXT: retq 186entry: 187 %0 = trunc <4 x i32> %input to <4 x i1> 188 %1 = extractelement <4 x i1> %0, i32 0 189 %e1 = select i1 %1, i32 1, i32 0 190 %2 = extractelement <4 x i1> %0, i32 1 191 %e2 = select i1 %2, i32 2, i32 0 192 %3 = extractelement <4 x i1> %0, i32 2 193 %e3 = select i1 %3, i32 4, i32 0 194 %4 = extractelement <4 x i1> %0, i32 3 195 %e4 = select i1 %4, i32 8, i32 0 196 %5 = or i32 %e1, %e2 197 %6 = or i32 %5, %e3 198 %7 = or i32 %6, %e4 199 ret i32 %7 200} 201