270 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc -mtriple=x86_64-linux -mattr=+sse2 < %s | FileCheck %s --check-prefix=LIN-SSE23; RUN: llc -mtriple=x86_64-linux -mcpu=nehalem < %s | FileCheck %s --check-prefix=LIN-SSE44; RUN: llc -mtriple=x86_64-win32 -mattr=+sse2 < %s | FileCheck %s --check-prefix=WIN-SSE25; RUN: llc -mtriple=x86_64-win32 -mcpu=nehalem < %s | FileCheck %s --check-prefix=WIN-SSE46; RUN: llc -mtriple=i686-win32 -mcpu=nehalem < %s | FileCheck %s --check-prefix=LIN327; rdar://73985548 9; When doing vector gather-scatter index calculation with 32-bit indices,10; minimize shuffling of each individual element out of the index vector.11 12define <4 x double> @foo(ptr %p, ptr %i, ptr %h) nounwind {13; LIN-SSE2-LABEL: foo:14; LIN-SSE2: # %bb.0:15; LIN-SSE2-NEXT: movdqa (%rsi), %xmm016; LIN-SSE2-NEXT: pand (%rdx), %xmm017; LIN-SSE2-NEXT: movd %xmm0, %eax18; LIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]19; LIN-SSE2-NEXT: movd %xmm1, %ecx20; LIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]21; LIN-SSE2-NEXT: movd %xmm1, %edx22; LIN-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]23; LIN-SSE2-NEXT: movd %xmm0, %esi24; LIN-SSE2-NEXT: cltq25; LIN-SSE2-NEXT: movslq %ecx, %rcx26; LIN-SSE2-NEXT: movslq %edx, %rdx27; LIN-SSE2-NEXT: movslq %esi, %rsi28; LIN-SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero29; LIN-SSE2-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]30; LIN-SSE2-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero31; LIN-SSE2-NEXT: movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]32; LIN-SSE2-NEXT: retq33;34; LIN-SSE4-LABEL: foo:35; LIN-SSE4: # %bb.0:36; LIN-SSE4-NEXT: movdqa (%rsi), %xmm037; LIN-SSE4-NEXT: pand (%rdx), %xmm038; LIN-SSE4-NEXT: movd %xmm0, %eax39; LIN-SSE4-NEXT: pextrd $1, %xmm0, %ecx40; LIN-SSE4-NEXT: pextrd $2, %xmm0, %edx41; LIN-SSE4-NEXT: pextrd $3, %xmm0, %esi42; LIN-SSE4-NEXT: cltq43; LIN-SSE4-NEXT: movslq %ecx, %rcx44; LIN-SSE4-NEXT: movslq %edx, %rdx45; LIN-SSE4-NEXT: movslq %esi, %rsi46; LIN-SSE4-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero47; LIN-SSE4-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]48; LIN-SSE4-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero49; LIN-SSE4-NEXT: movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]50; LIN-SSE4-NEXT: retq51;52; WIN-SSE2-LABEL: foo:53; WIN-SSE2: # %bb.0:54; WIN-SSE2-NEXT: movdqa (%rdx), %xmm055; WIN-SSE2-NEXT: pand (%r8), %xmm056; WIN-SSE2-NEXT: movd %xmm0, %eax57; WIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]58; WIN-SSE2-NEXT: movd %xmm1, %edx59; WIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]60; WIN-SSE2-NEXT: movd %xmm1, %r8d61; WIN-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]62; WIN-SSE2-NEXT: movd %xmm0, %r9d63; WIN-SSE2-NEXT: cltq64; WIN-SSE2-NEXT: movslq %edx, %rdx65; WIN-SSE2-NEXT: movslq %r8d, %r866; WIN-SSE2-NEXT: movslq %r9d, %r967; WIN-SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero68; WIN-SSE2-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]69; WIN-SSE2-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero70; WIN-SSE2-NEXT: movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]71; WIN-SSE2-NEXT: retq72;73; WIN-SSE4-LABEL: foo:74; WIN-SSE4: # %bb.0:75; WIN-SSE4-NEXT: movdqa (%rdx), %xmm076; WIN-SSE4-NEXT: pand (%r8), %xmm077; WIN-SSE4-NEXT: movd %xmm0, %eax78; WIN-SSE4-NEXT: pextrd $1, %xmm0, %edx79; WIN-SSE4-NEXT: pextrd $2, %xmm0, %r8d80; WIN-SSE4-NEXT: pextrd $3, %xmm0, %r9d81; WIN-SSE4-NEXT: cltq82; WIN-SSE4-NEXT: movslq %edx, %rdx83; WIN-SSE4-NEXT: movslq %r8d, %r884; WIN-SSE4-NEXT: movslq %r9d, %r985; WIN-SSE4-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero86; WIN-SSE4-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]87; WIN-SSE4-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero88; WIN-SSE4-NEXT: movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]89; WIN-SSE4-NEXT: retq90;91; LIN32-LABEL: foo:92; LIN32: # %bb.0:93; LIN32-NEXT: pushl %edi94; LIN32-NEXT: pushl %esi95; LIN32-NEXT: movl {{[0-9]+}}(%esp), %eax96; LIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx97; LIN32-NEXT: movdqa (%ecx), %xmm098; LIN32-NEXT: pand (%eax), %xmm099; LIN32-NEXT: movl {{[0-9]+}}(%esp), %eax100; LIN32-NEXT: movd %xmm0, %ecx101; LIN32-NEXT: pextrd $1, %xmm0, %edx102; LIN32-NEXT: pextrd $2, %xmm0, %esi103; LIN32-NEXT: pextrd $3, %xmm0, %edi104; LIN32-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero105; LIN32-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]106; LIN32-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero107; LIN32-NEXT: movhps {{.*#+}} xmm1 = xmm1[0,1],mem[0,1]108; LIN32-NEXT: popl %esi109; LIN32-NEXT: popl %edi110; LIN32-NEXT: retl111 %a = load <4 x i32>, ptr %i112 %b = load <4 x i32>, ptr %h113 %j = and <4 x i32> %a, %b114 %d0 = extractelement <4 x i32> %j, i32 0115 %d1 = extractelement <4 x i32> %j, i32 1116 %d2 = extractelement <4 x i32> %j, i32 2117 %d3 = extractelement <4 x i32> %j, i32 3118 %q0 = getelementptr double, ptr %p, i32 %d0119 %q1 = getelementptr double, ptr %p, i32 %d1120 %q2 = getelementptr double, ptr %p, i32 %d2121 %q3 = getelementptr double, ptr %p, i32 %d3122 %r0 = load double, ptr %q0123 %r1 = load double, ptr %q1124 %r2 = load double, ptr %q2125 %r3 = load double, ptr %q3126 %v0 = insertelement <4 x double> undef, double %r0, i32 0127 %v1 = insertelement <4 x double> %v0, double %r1, i32 1128 %v2 = insertelement <4 x double> %v1, double %r2, i32 2129 %v3 = insertelement <4 x double> %v2, double %r3, i32 3130 ret <4 x double> %v3131}132 133; Check that the sequence previously used above, which bounces the vector off the134; cache works for x86-32. Note that in this case it will not be used for index135; calculation, since indexes are 32-bit, not 64.136define <4 x i64> @old(ptr %p, ptr %i, ptr %h, i64 %f) nounwind {137; LIN-SSE2-LABEL: old:138; LIN-SSE2: # %bb.0:139; LIN-SSE2-NEXT: movdqa (%rsi), %xmm0140; LIN-SSE2-NEXT: pand (%rdx), %xmm0141; LIN-SSE2-NEXT: movd %xmm0, %eax142; LIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]143; LIN-SSE2-NEXT: movd %xmm1, %edx144; LIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]145; LIN-SSE2-NEXT: movd %xmm1, %esi146; LIN-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]147; LIN-SSE2-NEXT: movd %xmm0, %edi148; LIN-SSE2-NEXT: andl %ecx, %eax149; LIN-SSE2-NEXT: andl %ecx, %edx150; LIN-SSE2-NEXT: andl %ecx, %esi151; LIN-SSE2-NEXT: andl %ecx, %edi152; LIN-SSE2-NEXT: movd %eax, %xmm0153; LIN-SSE2-NEXT: movd %edx, %xmm1154; LIN-SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]155; LIN-SSE2-NEXT: movd %edi, %xmm2156; LIN-SSE2-NEXT: movd %esi, %xmm1157; LIN-SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]158; LIN-SSE2-NEXT: retq159;160; LIN-SSE4-LABEL: old:161; LIN-SSE4: # %bb.0:162; LIN-SSE4-NEXT: movdqa (%rsi), %xmm0163; LIN-SSE4-NEXT: pand (%rdx), %xmm0164; LIN-SSE4-NEXT: movd %xmm0, %eax165; LIN-SSE4-NEXT: pextrd $1, %xmm0, %edx166; LIN-SSE4-NEXT: pextrd $2, %xmm0, %esi167; LIN-SSE4-NEXT: pextrd $3, %xmm0, %edi168; LIN-SSE4-NEXT: andl %ecx, %eax169; LIN-SSE4-NEXT: andl %ecx, %edx170; LIN-SSE4-NEXT: andl %ecx, %esi171; LIN-SSE4-NEXT: andl %ecx, %edi172; LIN-SSE4-NEXT: movd %edx, %xmm1173; LIN-SSE4-NEXT: movd %eax, %xmm0174; LIN-SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]175; LIN-SSE4-NEXT: movd %edi, %xmm2176; LIN-SSE4-NEXT: movd %esi, %xmm1177; LIN-SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]178; LIN-SSE4-NEXT: retq179;180; WIN-SSE2-LABEL: old:181; WIN-SSE2: # %bb.0:182; WIN-SSE2-NEXT: movdqa (%rdx), %xmm0183; WIN-SSE2-NEXT: pand (%r8), %xmm0184; WIN-SSE2-NEXT: movd %xmm0, %eax185; WIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[1,1,1,1]186; WIN-SSE2-NEXT: movd %xmm1, %ecx187; WIN-SSE2-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]188; WIN-SSE2-NEXT: movd %xmm1, %edx189; WIN-SSE2-NEXT: pshufd {{.*#+}} xmm0 = xmm0[3,3,3,3]190; WIN-SSE2-NEXT: movd %xmm0, %r8d191; WIN-SSE2-NEXT: andl %r9d, %eax192; WIN-SSE2-NEXT: andl %r9d, %ecx193; WIN-SSE2-NEXT: andl %r9d, %edx194; WIN-SSE2-NEXT: andl %r9d, %r8d195; WIN-SSE2-NEXT: movd %eax, %xmm0196; WIN-SSE2-NEXT: movd %ecx, %xmm1197; WIN-SSE2-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]198; WIN-SSE2-NEXT: movd %r8d, %xmm2199; WIN-SSE2-NEXT: movd %edx, %xmm1200; WIN-SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]201; WIN-SSE2-NEXT: retq202;203; WIN-SSE4-LABEL: old:204; WIN-SSE4: # %bb.0:205; WIN-SSE4-NEXT: movdqa (%rdx), %xmm0206; WIN-SSE4-NEXT: pand (%r8), %xmm0207; WIN-SSE4-NEXT: movd %xmm0, %eax208; WIN-SSE4-NEXT: pextrd $1, %xmm0, %ecx209; WIN-SSE4-NEXT: pextrd $2, %xmm0, %edx210; WIN-SSE4-NEXT: pextrd $3, %xmm0, %r8d211; WIN-SSE4-NEXT: andl %r9d, %eax212; WIN-SSE4-NEXT: andl %r9d, %ecx213; WIN-SSE4-NEXT: andl %r9d, %edx214; WIN-SSE4-NEXT: andl %r9d, %r8d215; WIN-SSE4-NEXT: movd %ecx, %xmm1216; WIN-SSE4-NEXT: movd %eax, %xmm0217; WIN-SSE4-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]218; WIN-SSE4-NEXT: movd %r8d, %xmm2219; WIN-SSE4-NEXT: movd %edx, %xmm1220; WIN-SSE4-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]221; WIN-SSE4-NEXT: retq222;223; LIN32-LABEL: old:224; LIN32: # %bb.0:225; LIN32-NEXT: pushl %edi226; LIN32-NEXT: pushl %esi227; LIN32-NEXT: movl {{[0-9]+}}(%esp), %eax228; LIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx229; LIN32-NEXT: movdqa (%ecx), %xmm0230; LIN32-NEXT: pand (%eax), %xmm0231; LIN32-NEXT: movl {{[0-9]+}}(%esp), %ecx232; LIN32-NEXT: movd %xmm0, %edx233; LIN32-NEXT: pextrd $1, %xmm0, %esi234; LIN32-NEXT: pextrd $2, %xmm0, %eax235; LIN32-NEXT: pextrd $3, %xmm0, %edi236; LIN32-NEXT: andl %ecx, %edx237; LIN32-NEXT: andl %ecx, %esi238; LIN32-NEXT: andl %ecx, %eax239; LIN32-NEXT: andl %ecx, %edi240; LIN32-NEXT: movd %esi, %xmm1241; LIN32-NEXT: movd %edx, %xmm0242; LIN32-NEXT: punpcklqdq {{.*#+}} xmm0 = xmm0[0],xmm1[0]243; LIN32-NEXT: movd %edi, %xmm2244; LIN32-NEXT: movd %eax, %xmm1245; LIN32-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]246; LIN32-NEXT: popl %esi247; LIN32-NEXT: popl %edi248; LIN32-NEXT: retl249 %a = load <4 x i32>, ptr %i250 %b = load <4 x i32>, ptr %h251 %j = and <4 x i32> %a, %b252 %d0 = extractelement <4 x i32> %j, i32 0253 %d1 = extractelement <4 x i32> %j, i32 1254 %d2 = extractelement <4 x i32> %j, i32 2255 %d3 = extractelement <4 x i32> %j, i32 3256 %q0 = zext i32 %d0 to i64257 %q1 = zext i32 %d1 to i64258 %q2 = zext i32 %d2 to i64259 %q3 = zext i32 %d3 to i64260 %r0 = and i64 %q0, %f261 %r1 = and i64 %q1, %f262 %r2 = and i64 %q2, %f263 %r3 = and i64 %q3, %f264 %v0 = insertelement <4 x i64> undef, i64 %r0, i32 0265 %v1 = insertelement <4 x i64> %v0, i64 %r1, i32 1266 %v2 = insertelement <4 x i64> %v1, i64 %r2, i32 2267 %v3 = insertelement <4 x i64> %v2, i64 %r3, i32 3268 ret <4 x i64> %v3269}270