412 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE23; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+ssse3 | FileCheck %s --check-prefixes=SSE,SSSE34; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE415; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=AVX6; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=AVX7 8;9; Partial Vector Loads - PR1673910;11 12define <4 x float> @load_float4_float3(ptr nocapture readonly dereferenceable(16)) nofree nosync {13; SSE-LABEL: load_float4_float3:14; SSE: # %bb.0:15; SSE-NEXT: movups (%rdi), %xmm016; SSE-NEXT: retq17;18; AVX-LABEL: load_float4_float3:19; AVX: # %bb.0:20; AVX-NEXT: vmovups (%rdi), %xmm021; AVX-NEXT: retq22 %p1 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 123 %p2 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 224 %ld0 = load float, ptr %0, align 425 %ld1 = load float, ptr %p1, align 426 %ld2 = load float, ptr %p2, align 427 %r0 = insertelement <4 x float> undef, float %ld0, i32 028 %r1 = insertelement <4 x float> %r0, float %ld1, i32 129 %r2 = insertelement <4 x float> %r1, float %ld2, i32 230 ret <4 x float> %r231}32 33define <4 x float> @load_float4_float3_0122(ptr nocapture readonly dereferenceable(16)) nofree nosync {34; SSE-LABEL: load_float4_float3_0122:35; SSE: # %bb.0:36; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero37; SSE-NEXT: movups (%rdi), %xmm038; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]39; SSE-NEXT: retq40;41; AVX-LABEL: load_float4_float3_0122:42; AVX: # %bb.0:43; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero44; AVX-NEXT: vmovups (%rdi), %xmm145; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0]46; AVX-NEXT: retq47 %p1 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 148 %p2 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 249 %ld0 = load float, ptr %0, align 450 %ld1 = load float, ptr %p1, align 451 %ld2 = load float, ptr %p2, align 452 %r0 = insertelement <4 x float> undef, float %ld0, i32 053 %r1 = insertelement <4 x float> %r0, float %ld1, i32 154 %r2 = insertelement <4 x float> %r1, float %ld2, i32 255 %r3 = insertelement <4 x float> %r2, float %ld2, i32 356 ret <4 x float> %r357}58 59define <8 x float> @load_float8_float3(ptr nocapture readonly dereferenceable(16)) nofree nosync {60; SSE-LABEL: load_float8_float3:61; SSE: # %bb.0:62; SSE-NEXT: movups (%rdi), %xmm063; SSE-NEXT: retq64;65; AVX-LABEL: load_float8_float3:66; AVX: # %bb.0:67; AVX-NEXT: vmovups (%rdi), %xmm068; AVX-NEXT: retq69 %p1 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 170 %p2 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 271 %ld0 = load float, ptr %0, align 472 %ld1 = load float, ptr %p1, align 473 %ld2 = load float, ptr %p2, align 474 %r0 = insertelement <8 x float> undef, float %ld0, i32 075 %r1 = insertelement <8 x float> %r0, float %ld1, i32 176 %r2 = insertelement <8 x float> %r1, float %ld2, i32 277 ret <8 x float> %r278}79 80define <8 x float> @load_float8_float3_0122(ptr nocapture readonly dereferenceable(16)) nofree nosync {81; SSE-LABEL: load_float8_float3_0122:82; SSE: # %bb.0:83; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero84; SSE-NEXT: movups (%rdi), %xmm085; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]86; SSE-NEXT: retq87;88; AVX-LABEL: load_float8_float3_0122:89; AVX: # %bb.0:90; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero91; AVX-NEXT: vmovups (%rdi), %xmm192; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0]93; AVX-NEXT: retq94 %p1 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 195 %p2 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 296 %ld0 = load float, ptr %0, align 497 %ld1 = load float, ptr %p1, align 498 %ld2 = load float, ptr %p2, align 499 %r0 = insertelement <8 x float> undef, float %ld0, i32 0100 %r1 = insertelement <8 x float> %r0, float %ld1, i32 1101 %r2 = insertelement <8 x float> %r1, float %ld2, i32 2102 %r3 = insertelement <8 x float> %r2, float %ld2, i32 3103 ret <8 x float> %r3104}105 106define <4 x float> @load_float4_float3_as_float2_float(ptr nocapture readonly dereferenceable(16)) nofree nosync {107; SSE-LABEL: load_float4_float3_as_float2_float:108; SSE: # %bb.0:109; SSE-NEXT: movups (%rdi), %xmm0110; SSE-NEXT: retq111;112; AVX-LABEL: load_float4_float3_as_float2_float:113; AVX: # %bb.0:114; AVX-NEXT: vmovups (%rdi), %xmm0115; AVX-NEXT: retq116 %2 = load <2 x float>, ptr %0, align 4117 %3 = extractelement <2 x float> %2, i32 0118 %4 = insertelement <4 x float> undef, float %3, i32 0119 %5 = extractelement <2 x float> %2, i32 1120 %6 = insertelement <4 x float> %4, float %5, i32 1121 %7 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 2122 %8 = load float, ptr %7, align 4123 %9 = insertelement <4 x float> %6, float %8, i32 2124 ret <4 x float> %9125}126 127define <4 x float> @load_float4_float3_as_float2_float_0122(ptr nocapture readonly dereferenceable(16)) nofree nosync {128; SSE-LABEL: load_float4_float3_as_float2_float_0122:129; SSE: # %bb.0:130; SSE-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero131; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero132; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]133; SSE-NEXT: retq134;135; AVX-LABEL: load_float4_float3_as_float2_float_0122:136; AVX: # %bb.0:137; AVX-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero138; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero139; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]140; AVX-NEXT: retq141 %2 = load <2 x float>, ptr %0, align 4142 %3 = extractelement <2 x float> %2, i32 0143 %4 = insertelement <4 x float> undef, float %3, i32 0144 %5 = extractelement <2 x float> %2, i32 1145 %6 = insertelement <4 x float> %4, float %5, i32 1146 %7 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 2147 %8 = load float, ptr %7, align 4148 %9 = insertelement <4 x float> %6, float %8, i32 2149 %10 = insertelement <4 x float> %9, float %8, i32 3150 ret <4 x float> %10151}152 153define <4 x float> @load_float4_float3_trunc(ptr nocapture readonly dereferenceable(16)) {154; SSE-LABEL: load_float4_float3_trunc:155; SSE: # %bb.0:156; SSE-NEXT: movaps (%rdi), %xmm0157; SSE-NEXT: retq158;159; AVX-LABEL: load_float4_float3_trunc:160; AVX: # %bb.0:161; AVX-NEXT: vmovaps (%rdi), %xmm0162; AVX-NEXT: retq163 %2 = load i64, ptr %0, align 16164 %3 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 2165 %4 = load i64, ptr %3, align 8166 %5 = trunc i64 %2 to i32167 %6 = bitcast i32 %5 to float168 %7 = insertelement <4 x float> undef, float %6, i32 0169 %8 = lshr i64 %2, 32170 %9 = trunc i64 %8 to i32171 %10 = bitcast i32 %9 to float172 %11 = insertelement <4 x float> %7, float %10, i32 1173 %12 = trunc i64 %4 to i32174 %13 = bitcast i32 %12 to float175 %14 = insertelement <4 x float> %11, float %13, i32 2176 ret <4 x float> %14177}178 179define <4 x float> @load_float4_float3_trunc_0122(ptr nocapture readonly dereferenceable(16)) nofree nosync {180; SSE-LABEL: load_float4_float3_trunc_0122:181; SSE: # %bb.0:182; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero183; SSE-NEXT: movaps (%rdi), %xmm0184; SSE-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,1],xmm1[0,0]185; SSE-NEXT: retq186;187; AVX-LABEL: load_float4_float3_trunc_0122:188; AVX: # %bb.0:189; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero190; AVX-NEXT: vmovaps (%rdi), %xmm1191; AVX-NEXT: vshufps {{.*#+}} xmm0 = xmm1[0,1],xmm0[0,0]192; AVX-NEXT: retq193 %2 = load i64, ptr %0, align 16194 %3 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 2195 %4 = load i64, ptr %3, align 8196 %5 = trunc i64 %2 to i32197 %6 = bitcast i32 %5 to float198 %7 = insertelement <4 x float> undef, float %6, i32 0199 %8 = lshr i64 %2, 32200 %9 = trunc i64 %8 to i32201 %10 = bitcast i32 %9 to float202 %11 = insertelement <4 x float> %7, float %10, i32 1203 %12 = trunc i64 %4 to i32204 %13 = bitcast i32 %12 to float205 %14 = insertelement <4 x float> %11, float %13, i32 2206 %15 = insertelement <4 x float> %14, float %13, i32 3207 ret <4 x float> %15208}209 210define <4 x float> @load_float4_float3_trunc_0123(ptr nocapture readonly dereferenceable(16)) nofree nosync {211; SSE2-LABEL: load_float4_float3_trunc_0123:212; SSE2: # %bb.0:213; SSE2-NEXT: movaps (%rdi), %xmm0214; SSE2-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]215; SSE2-NEXT: retq216;217; SSSE3-LABEL: load_float4_float3_trunc_0123:218; SSSE3: # %bb.0:219; SSSE3-NEXT: movaps (%rdi), %xmm0220; SSSE3-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]221; SSSE3-NEXT: retq222;223; SSE41-LABEL: load_float4_float3_trunc_0123:224; SSE41: # %bb.0:225; SSE41-NEXT: movaps (%rdi), %xmm0226; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]227; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]228; SSE41-NEXT: retq229;230; AVX-LABEL: load_float4_float3_trunc_0123:231; AVX: # %bb.0:232; AVX-NEXT: vmovaps (%rdi), %xmm0233; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]234; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]235; AVX-NEXT: retq236 %2 = load i64, ptr %0, align 16237 %3 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 2238 %4 = load i64, ptr %3, align 8239 %5 = trunc i64 %2 to i32240 %6 = bitcast i32 %5 to float241 %7 = insertelement <4 x float> undef, float %6, i32 0242 %8 = lshr i64 %2, 32243 %9 = trunc i64 %8 to i32244 %10 = bitcast i32 %9 to float245 %11 = insertelement <4 x float> %7, float %10, i32 1246 %12 = trunc i64 %4 to i32247 %13 = bitcast i32 %12 to float248 %14 = insertelement <4 x float> %11, float %13, i32 2249 %15 = lshr i64 %4, 32250 %16 = trunc i64 %15 to i32251 %17 = bitcast i32 %16 to float252 %18 = insertelement <4 x float> %14, float %17, i32 3253 ret <4 x float> %18254}255 256define <4 x float> @load_float4_float3_trunc_0123_unaligned(ptr nocapture readonly dereferenceable(16)) nofree nosync {257; SSE2-LABEL: load_float4_float3_trunc_0123_unaligned:258; SSE2: # %bb.0:259; SSE2-NEXT: movups (%rdi), %xmm0260; SSE2-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]261; SSE2-NEXT: retq262;263; SSSE3-LABEL: load_float4_float3_trunc_0123_unaligned:264; SSSE3: # %bb.0:265; SSSE3-NEXT: movups (%rdi), %xmm0266; SSSE3-NEXT: movhps {{.*#+}} xmm0 = xmm0[0,1],mem[0,1]267; SSSE3-NEXT: retq268;269; SSE41-LABEL: load_float4_float3_trunc_0123_unaligned:270; SSE41: # %bb.0:271; SSE41-NEXT: movups (%rdi), %xmm0272; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]273; SSE41-NEXT: insertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]274; SSE41-NEXT: retq275;276; AVX-LABEL: load_float4_float3_trunc_0123_unaligned:277; AVX: # %bb.0:278; AVX-NEXT: vmovups (%rdi), %xmm0279; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1],mem[0],xmm0[3]280; AVX-NEXT: vinsertps {{.*#+}} xmm0 = xmm0[0,1,2],mem[0]281; AVX-NEXT: retq282 %2 = load i64, ptr %0, align 1283 %3 = getelementptr inbounds <4 x float>, ptr %0, i64 0, i64 2284 %4 = load i64, ptr %3, align 1285 %5 = trunc i64 %2 to i32286 %6 = bitcast i32 %5 to float287 %7 = insertelement <4 x float> undef, float %6, i32 0288 %8 = lshr i64 %2, 32289 %9 = trunc i64 %8 to i32290 %10 = bitcast i32 %9 to float291 %11 = insertelement <4 x float> %7, float %10, i32 1292 %12 = trunc i64 %4 to i32293 %13 = bitcast i32 %12 to float294 %14 = insertelement <4 x float> %11, float %13, i32 2295 %15 = lshr i64 %4, 32296 %16 = trunc i64 %15 to i32297 %17 = bitcast i32 %16 to float298 %18 = insertelement <4 x float> %14, float %17, i32 3299 ret <4 x float> %18300}301 302; PR21780303define <4 x double> @load_double4_0u2u(ptr nocapture readonly dereferenceable(32)) nofree nosync {304; SSE2-LABEL: load_double4_0u2u:305; SSE2: # %bb.0:306; SSE2-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero307; SSE2-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero308; SSE2-NEXT: movlhps {{.*#+}} xmm0 = xmm0[0,0]309; SSE2-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0,0]310; SSE2-NEXT: retq311;312; SSSE3-LABEL: load_double4_0u2u:313; SSSE3: # %bb.0:314; SSSE3-NEXT: movddup {{.*#+}} xmm0 = mem[0,0]315; SSSE3-NEXT: movddup {{.*#+}} xmm1 = mem[0,0]316; SSSE3-NEXT: retq317;318; SSE41-LABEL: load_double4_0u2u:319; SSE41: # %bb.0:320; SSE41-NEXT: movddup {{.*#+}} xmm0 = mem[0,0]321; SSE41-NEXT: movddup {{.*#+}} xmm1 = mem[0,0]322; SSE41-NEXT: retq323;324; AVX-LABEL: load_double4_0u2u:325; AVX: # %bb.0:326; AVX-NEXT: vmovddup {{.*#+}} ymm0 = mem[0,0,2,2]327; AVX-NEXT: retq328 %2 = load double, ptr %0, align 8329 %3 = insertelement <4 x double> undef, double %2, i32 0330 %4 = getelementptr inbounds double, ptr %0, i64 2331 %5 = load double, ptr %4, align 8332 %6 = insertelement <4 x double> %3, double %5, i32 2333 %7 = shufflevector <4 x double> %6, <4 x double> undef, <4 x i32> <i32 0, i32 0, i32 2, i32 2>334 ret <4 x double> %7335}336 337; Test case identified in rL366501338@h = dso_local local_unnamed_addr global i8 0, align 1339define dso_local i32 @load_partial_illegal_type() {340; SSE2-LABEL: load_partial_illegal_type:341; SSE2: # %bb.0:342; SSE2-NEXT: movzwl h(%rip), %eax343; SSE2-NEXT: movd %eax, %xmm0344; SSE2-NEXT: pand {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0345; SSE2-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0346; SSE2-NEXT: movd %xmm0, %eax347; SSE2-NEXT: retq348;349; SSSE3-LABEL: load_partial_illegal_type:350; SSSE3: # %bb.0:351; SSSE3-NEXT: movzwl h(%rip), %eax352; SSSE3-NEXT: movd %eax, %xmm0353; SSSE3-NEXT: pshufb {{.*#+}} xmm0 = xmm0[0,1],zero,xmm0[3,u,u,u,u,u,u,u,u,u,u,u,u]354; SSSE3-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0355; SSSE3-NEXT: movd %xmm0, %eax356; SSSE3-NEXT: retq357;358; SSE41-LABEL: load_partial_illegal_type:359; SSE41: # %bb.0:360; SSE41-NEXT: movzwl h(%rip), %eax361; SSE41-NEXT: movd %eax, %xmm0362; SSE41-NEXT: movl $2, %eax363; SSE41-NEXT: pinsrb $2, %eax, %xmm0364; SSE41-NEXT: movd %xmm0, %eax365; SSE41-NEXT: retq366;367; AVX-LABEL: load_partial_illegal_type:368; AVX: # %bb.0:369; AVX-NEXT: movzwl h(%rip), %eax370; AVX-NEXT: vmovd %eax, %xmm0371; AVX-NEXT: movl $2, %eax372; AVX-NEXT: vpinsrb $2, %eax, %xmm0, %xmm0373; AVX-NEXT: vmovd %xmm0, %eax374; AVX-NEXT: retq375 %1 = load <2 x i8>, ptr @h, align 1376 %2 = shufflevector <2 x i8> %1, <2 x i8> undef, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>377 %3 = insertelement <4 x i8> %2, i8 2, i32 2378 %4 = bitcast <4 x i8> %3 to i32379 ret i32 %4380}381 382define dso_local void @PR43227(ptr %explicit_0, ptr %explicit_1) {383; SSE-LABEL: PR43227:384; SSE: # %bb.0:385; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero386; SSE-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero387; SSE-NEXT: movlhps {{.*#+}} xmm1 = xmm1[0],xmm0[0]388; SSE-NEXT: xorps %xmm0, %xmm0389; SSE-NEXT: movaps %xmm0, 672(%rsi)390; SSE-NEXT: movaps %xmm1, 688(%rsi)391; SSE-NEXT: retq392;393; AVX-LABEL: PR43227:394; AVX: # %bb.0:395; AVX-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero396; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero397; AVX-NEXT: vmovlhps {{.*#+}} xmm0 = xmm1[0],xmm0[0]398; AVX-NEXT: vxorps %xmm1, %xmm1, %xmm1399; AVX-NEXT: vinsertf128 $1, %xmm0, %ymm1, %ymm0400; AVX-NEXT: vmovaps %ymm0, 672(%rsi)401; AVX-NEXT: vzeroupper402; AVX-NEXT: retq403 %1 = getelementptr i32, ptr %explicit_0, i64 63404 %2 = load <3 x i32>, ptr %1, align 1405 %3 = shufflevector <3 x i32> %2, <3 x i32> undef, <2 x i32> <i32 1, i32 2>406 %4 = shufflevector <2 x i32> %3, <2 x i32> undef, <8 x i32> <i32 0, i32 1, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef>407 %5 = shufflevector <8 x i32> <i32 0, i32 0, i32 0, i32 0, i32 undef, i32 0, i32 undef, i32 0>, <8 x i32> %4, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 5, i32 9, i32 7>408 %6 = getelementptr inbounds <8 x i32>, ptr %explicit_1, i64 21409 store <8 x i32> %5, ptr %6, align 32410 ret void411}412