303 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+mmx,+sse2 | FileCheck %s --check-prefix=X863; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+mmx,+sse2 | FileCheck %s --check-prefix=X644 5; If we are transferring XMM conversion results to MMX registers we could use the MMX equivalents6; (CVTPD2PI/CVTTPD2PI + CVTPS2PI/CVTTPS2PI) without affecting rounding/exceptions etc.7 8define void @cvt_v2f64_v2i32(<2 x double>, ptr) nounwind {9; X86-LABEL: cvt_v2f64_v2i32:10; X86: # %bb.0:11; X86-NEXT: movl {{[0-9]+}}(%esp), %eax12; X86-NEXT: cvtpd2pi %xmm0, %mm013; X86-NEXT: paddd %mm0, %mm014; X86-NEXT: movq %mm0, (%eax)15; X86-NEXT: retl16;17; X64-LABEL: cvt_v2f64_v2i32:18; X64: # %bb.0:19; X64-NEXT: cvtpd2pi %xmm0, %mm020; X64-NEXT: paddd %mm0, %mm021; X64-NEXT: movq %mm0, (%rdi)22; X64-NEXT: retq23 %3 = tail call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> %0)24 %4 = bitcast <4 x i32> %3 to <2 x i64>25 %5 = extractelement <2 x i64> %4, i32 026 %6 = bitcast i64 %5 to <1 x i64>27 %7 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %6, <1 x i64> %6)28 %8 = bitcast <1 x i64> %7 to i6429 %9 = insertelement <1 x i64> undef, i64 %8, i32 030 store <1 x i64> %9, ptr %131 ret void32}33 34define void @cvtt_v2f64_v2i32(<2 x double>, ptr) nounwind {35; X86-LABEL: cvtt_v2f64_v2i32:36; X86: # %bb.0:37; X86-NEXT: movl {{[0-9]+}}(%esp), %eax38; X86-NEXT: cvttpd2pi %xmm0, %mm039; X86-NEXT: paddd %mm0, %mm040; X86-NEXT: movq %mm0, (%eax)41; X86-NEXT: retl42;43; X64-LABEL: cvtt_v2f64_v2i32:44; X64: # %bb.0:45; X64-NEXT: cvttpd2pi %xmm0, %mm046; X64-NEXT: paddd %mm0, %mm047; X64-NEXT: movq %mm0, (%rdi)48; X64-NEXT: retq49 %3 = tail call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %0)50 %4 = bitcast <4 x i32> %3 to <2 x i64>51 %5 = extractelement <2 x i64> %4, i32 052 %6 = bitcast i64 %5 to <1 x i64>53 %7 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %6, <1 x i64> %6)54 %8 = bitcast <1 x i64> %7 to i6455 %9 = insertelement <1 x i64> undef, i64 %8, i32 056 store <1 x i64> %9, ptr %157 ret void58}59 60define void @fptosi_v2f64_v2i32(<2 x double>, ptr) nounwind {61; X86-LABEL: fptosi_v2f64_v2i32:62; X86: # %bb.0:63; X86-NEXT: movl {{[0-9]+}}(%esp), %eax64; X86-NEXT: cvttpd2pi %xmm0, %mm065; X86-NEXT: paddd %mm0, %mm066; X86-NEXT: movq %mm0, (%eax)67; X86-NEXT: retl68;69; X64-LABEL: fptosi_v2f64_v2i32:70; X64: # %bb.0:71; X64-NEXT: cvttpd2pi %xmm0, %mm072; X64-NEXT: paddd %mm0, %mm073; X64-NEXT: movq %mm0, (%rdi)74; X64-NEXT: retq75 %3 = fptosi <2 x double> %0 to <2 x i32>76 %4 = bitcast <2 x i32> %3 to <1 x i64>77 %5 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %4, <1 x i64> %4)78 %6 = bitcast <1 x i64> %5 to i6479 %7 = insertelement <1 x i64> undef, i64 %6, i32 080 store <1 x i64> %7, ptr %181 ret void82}83 84define void @cvt_v2f32_v2i32(<4 x float>, ptr) nounwind {85; X86-LABEL: cvt_v2f32_v2i32:86; X86: # %bb.0:87; X86-NEXT: movl {{[0-9]+}}(%esp), %eax88; X86-NEXT: cvtps2pi %xmm0, %mm089; X86-NEXT: paddd %mm0, %mm090; X86-NEXT: movq %mm0, (%eax)91; X86-NEXT: retl92;93; X64-LABEL: cvt_v2f32_v2i32:94; X64: # %bb.0:95; X64-NEXT: cvtps2pi %xmm0, %mm096; X64-NEXT: paddd %mm0, %mm097; X64-NEXT: movq %mm0, (%rdi)98; X64-NEXT: retq99 %3 = tail call <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float> %0)100 %4 = bitcast <4 x i32> %3 to <2 x i64>101 %5 = extractelement <2 x i64> %4, i32 0102 %6 = bitcast i64 %5 to <1 x i64>103 %7 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %6, <1 x i64> %6)104 %8 = bitcast <1 x i64> %7 to i64105 %9 = insertelement <1 x i64> undef, i64 %8, i32 0106 store <1 x i64> %9, ptr %1107 ret void108}109 110define void @cvtt_v2f32_v2i32(<4 x float>, ptr) nounwind {111; X86-LABEL: cvtt_v2f32_v2i32:112; X86: # %bb.0:113; X86-NEXT: movl {{[0-9]+}}(%esp), %eax114; X86-NEXT: cvttps2pi %xmm0, %mm0115; X86-NEXT: paddd %mm0, %mm0116; X86-NEXT: movq %mm0, (%eax)117; X86-NEXT: retl118;119; X64-LABEL: cvtt_v2f32_v2i32:120; X64: # %bb.0:121; X64-NEXT: cvttps2pi %xmm0, %mm0122; X64-NEXT: paddd %mm0, %mm0123; X64-NEXT: movq %mm0, (%rdi)124; X64-NEXT: retq125 %3 = tail call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %0)126 %4 = bitcast <4 x i32> %3 to <2 x i64>127 %5 = extractelement <2 x i64> %4, i32 0128 %6 = bitcast i64 %5 to <1 x i64>129 %7 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %6, <1 x i64> %6)130 %8 = bitcast <1 x i64> %7 to i64131 %9 = insertelement <1 x i64> undef, i64 %8, i32 0132 store <1 x i64> %9, ptr %1133 ret void134}135 136define void @fptosi_v4f32_v4i32(<4 x float>, ptr) nounwind {137; X86-LABEL: fptosi_v4f32_v4i32:138; X86: # %bb.0:139; X86-NEXT: movl {{[0-9]+}}(%esp), %eax140; X86-NEXT: cvttps2pi %xmm0, %mm0141; X86-NEXT: paddd %mm0, %mm0142; X86-NEXT: movq %mm0, (%eax)143; X86-NEXT: retl144;145; X64-LABEL: fptosi_v4f32_v4i32:146; X64: # %bb.0:147; X64-NEXT: cvttps2pi %xmm0, %mm0148; X64-NEXT: paddd %mm0, %mm0149; X64-NEXT: movq %mm0, (%rdi)150; X64-NEXT: retq151 %3 = fptosi <4 x float> %0 to <4 x i32>152 %4 = shufflevector <4 x i32> %3, <4 x i32> undef, <2 x i32> <i32 0, i32 1>153 %5 = bitcast <2 x i32> %4 to <1 x i64>154 %6 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %5, <1 x i64> %5)155 %7 = bitcast <1 x i64> %6 to i64156 %8 = insertelement <1 x i64> undef, i64 %7, i32 0157 store <1 x i64> %8, ptr %1158 ret void159}160 161define void @fptosi_v2f32_v2i32(<4 x float>, ptr) nounwind {162; X86-LABEL: fptosi_v2f32_v2i32:163; X86: # %bb.0:164; X86-NEXT: movl {{[0-9]+}}(%esp), %eax165; X86-NEXT: cvttps2pi %xmm0, %mm0166; X86-NEXT: paddd %mm0, %mm0167; X86-NEXT: movq %mm0, (%eax)168; X86-NEXT: retl169;170; X64-LABEL: fptosi_v2f32_v2i32:171; X64: # %bb.0:172; X64-NEXT: cvttps2pi %xmm0, %mm0173; X64-NEXT: paddd %mm0, %mm0174; X64-NEXT: movq %mm0, (%rdi)175; X64-NEXT: retq176 %3 = fptosi <4 x float> %0 to <4 x i32>177 %4 = bitcast <4 x i32> %3 to <2 x i64>178 %5 = extractelement <2 x i64> %4, i32 0179 %6 = bitcast i64 %5 to <1 x i64>180 %7 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %6, <1 x i64> %6)181 %8 = bitcast <1 x i64> %7 to i64182 %9 = insertelement <1 x i64> undef, i64 %8, i32 0183 store <1 x i64> %9, ptr %1184 ret void185}186 187; FIXME: If we are transferring MMX registers to XMM for conversion we could use the MMX equivalents188; (CVTPI2PD + CVTPI2PS) without affecting rounding/exceptions etc.189 190define <2 x double> @sitofp_v2i32_v2f64(ptr) nounwind {191; X86-LABEL: sitofp_v2i32_v2f64:192; X86: # %bb.0:193; X86-NEXT: pushl %ebp194; X86-NEXT: movl %esp, %ebp195; X86-NEXT: andl $-8, %esp196; X86-NEXT: subl $8, %esp197; X86-NEXT: movl 8(%ebp), %eax198; X86-NEXT: movq (%eax), %mm0199; X86-NEXT: paddd %mm0, %mm0200; X86-NEXT: movq %mm0, (%esp)201; X86-NEXT: cvtdq2pd (%esp), %xmm0202; X86-NEXT: movl %ebp, %esp203; X86-NEXT: popl %ebp204; X86-NEXT: retl205;206; X64-LABEL: sitofp_v2i32_v2f64:207; X64: # %bb.0:208; X64-NEXT: movq (%rdi), %mm0209; X64-NEXT: paddd %mm0, %mm0210; X64-NEXT: movq2dq %mm0, %xmm0211; X64-NEXT: cvtdq2pd %xmm0, %xmm0212; X64-NEXT: retq213 %2 = load <1 x i64>, ptr %0, align 8214 %3 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %2, <1 x i64> %2)215 %4 = bitcast <1 x i64> %3 to i64216 %5 = insertelement <2 x i64> undef, i64 %4, i32 0217 %6 = bitcast <2 x i64> %5 to <4 x i32>218 %7 = shufflevector <4 x i32> %6, <4 x i32> undef, <2 x i32> <i32 0, i32 1>219 %8 = sitofp <2 x i32> %7 to <2 x double>220 ret <2 x double> %8221}222 223define <4 x float> @sitofp_v2i32_v2f32(ptr) nounwind {224; X86-LABEL: sitofp_v2i32_v2f32:225; X86: # %bb.0:226; X86-NEXT: movl {{[0-9]+}}(%esp), %eax227; X86-NEXT: movq (%eax), %mm0228; X86-NEXT: paddd %mm0, %mm0229; X86-NEXT: movq2dq %mm0, %xmm0230; X86-NEXT: cvtdq2ps %xmm0, %xmm0231; X86-NEXT: retl232;233; X64-LABEL: sitofp_v2i32_v2f32:234; X64: # %bb.0:235; X64-NEXT: movq (%rdi), %mm0236; X64-NEXT: paddd %mm0, %mm0237; X64-NEXT: movq2dq %mm0, %xmm0238; X64-NEXT: cvtdq2ps %xmm0, %xmm0239; X64-NEXT: retq240 %2 = load <1 x i64>, ptr %0, align 8241 %3 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %2, <1 x i64> %2)242 %4 = bitcast <1 x i64> %3 to <2 x i32>243 %5 = shufflevector <2 x i32> %4, <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>244 %6 = sitofp <4 x i32> %5 to <4 x float>245 ret <4 x float> %6246}247 248define <4 x float> @cvt_v2i32_v2f32(ptr) nounwind {249; X86-LABEL: cvt_v2i32_v2f32:250; X86: # %bb.0:251; X86-NEXT: pushl %ebp252; X86-NEXT: movl %esp, %ebp253; X86-NEXT: andl $-8, %esp254; X86-NEXT: subl $8, %esp255; X86-NEXT: movl 8(%ebp), %eax256; X86-NEXT: movq (%eax), %mm0257; X86-NEXT: paddd %mm0, %mm0258; X86-NEXT: movq %mm0, (%esp)259; X86-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero260; X86-NEXT: cvtdq2ps %xmm0, %xmm0261; X86-NEXT: movl %ebp, %esp262; X86-NEXT: popl %ebp263; X86-NEXT: retl264;265; X64-LABEL: cvt_v2i32_v2f32:266; X64: # %bb.0:267; X64-NEXT: movq (%rdi), %mm0268; X64-NEXT: paddd %mm0, %mm0269; X64-NEXT: movq2dq %mm0, %xmm0270; X64-NEXT: cvtdq2ps %xmm0, %xmm0271; X64-NEXT: retq272 %2 = load <1 x i64>, ptr %0, align 8273 %3 = tail call <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64> %2, <1 x i64> %2)274 %4 = bitcast <1 x i64> %3 to i64275 %5 = insertelement <2 x i64> undef, i64 %4, i32 0276 %6 = insertelement <2 x i64> %5, i64 0, i32 1277 %7 = bitcast <2 x i64> %6 to <4 x i32>278 %8 = tail call <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32> %7)279 ret <4 x float> %8280}281 282define noundef <2 x i64> @cvt_f64_v2i64(double %a0) {283; X86-LABEL: cvt_f64_v2i64:284; X86: # %bb.0:285; X86-NEXT: movsd {{.*#+}} xmm0 = mem[0],zero286; X86-NEXT: retl287;288; X64-LABEL: cvt_f64_v2i64:289; X64: # %bb.0:290; X64-NEXT: movq {{.*#+}} xmm0 = xmm0[0],zero291; X64-NEXT: retq292 %bc = bitcast double %a0 to <1 x i64>293 %r = shufflevector <1 x i64> %bc, <1 x i64> zeroinitializer, <2 x i32> <i32 0, i32 1>294 ret <2 x i64> %r295}296 297declare <1 x i64> @llvm.x86.mmx.padd.d(<1 x i64>, <1 x i64>)298declare <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double>)299declare <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double>)300declare <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float>)301declare <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float>)302declare <4 x float> @llvm.x86.sse2.cvtdq2ps(<4 x i32>)303