786 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse2 | FileCheck %s --check-prefixes=SSE,SSE23; RUN: llc < %s -mtriple=x86_64-- -mattr=+sse4.1 | FileCheck %s --check-prefixes=SSE,SSE414; RUN: llc < %s -mtriple=x86_64-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,X64-AVX15; RUN: llc < %s -mtriple=i686-- -mattr=+avx | FileCheck %s --check-prefixes=AVX,X86-AVX16 7declare i32 @llvm.fptoui.sat.i32.f32(float)8declare i64 @llvm.fptosi.sat.i64.f64(double)9 10define float @trunc_unsigned_f32(float %x) #0 {11; SSE2-LABEL: trunc_unsigned_f32:12; SSE2: # %bb.0:13; SSE2-NEXT: cvttss2si %xmm0, %rax14; SSE2-NEXT: movl %eax, %eax15; SSE2-NEXT: xorps %xmm0, %xmm016; SSE2-NEXT: cvtsi2ss %rax, %xmm017; SSE2-NEXT: retq18;19; SSE41-LABEL: trunc_unsigned_f32:20; SSE41: # %bb.0:21; SSE41-NEXT: roundss $11, %xmm0, %xmm022; SSE41-NEXT: retq23;24; X64-AVX1-LABEL: trunc_unsigned_f32:25; X64-AVX1: # %bb.0:26; X64-AVX1-NEXT: vroundss $11, %xmm0, %xmm0, %xmm027; X64-AVX1-NEXT: retq28;29; X86-AVX1-LABEL: trunc_unsigned_f32:30; X86-AVX1: # %bb.0:31; X86-AVX1-NEXT: pushl %eax32; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero33; X86-AVX1-NEXT: vroundss $11, %xmm0, %xmm0, %xmm034; X86-AVX1-NEXT: vmovss %xmm0, (%esp)35; X86-AVX1-NEXT: flds (%esp)36; X86-AVX1-NEXT: popl %eax37; X86-AVX1-NEXT: retl38 %i = fptoui float %x to i3239 %r = uitofp i32 %i to float40 ret float %r41}42 43define double @trunc_unsigned_f64(double %x) #0 {44; SSE2-LABEL: trunc_unsigned_f64:45; SSE2: # %bb.0:46; SSE2-NEXT: cvttsd2si %xmm0, %rax47; SSE2-NEXT: movq %rax, %rcx48; SSE2-NEXT: sarq $63, %rcx49; SSE2-NEXT: subsd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm050; SSE2-NEXT: cvttsd2si %xmm0, %rdx51; SSE2-NEXT: andq %rcx, %rdx52; SSE2-NEXT: orq %rax, %rdx53; SSE2-NEXT: movq %rdx, %xmm154; SSE2-NEXT: punpckldq {{.*#+}} xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]55; SSE2-NEXT: subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm156; SSE2-NEXT: movapd %xmm1, %xmm057; SSE2-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1],xmm1[1]58; SSE2-NEXT: addsd %xmm1, %xmm059; SSE2-NEXT: retq60;61; SSE41-LABEL: trunc_unsigned_f64:62; SSE41: # %bb.0:63; SSE41-NEXT: roundsd $11, %xmm0, %xmm064; SSE41-NEXT: retq65;66; X64-AVX1-LABEL: trunc_unsigned_f64:67; X64-AVX1: # %bb.0:68; X64-AVX1-NEXT: vroundsd $11, %xmm0, %xmm0, %xmm069; X64-AVX1-NEXT: retq70;71; X86-AVX1-LABEL: trunc_unsigned_f64:72; X86-AVX1: # %bb.0:73; X86-AVX1-NEXT: pushl %ebp74; X86-AVX1-NEXT: movl %esp, %ebp75; X86-AVX1-NEXT: andl $-8, %esp76; X86-AVX1-NEXT: subl $8, %esp77; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero78; X86-AVX1-NEXT: vroundsd $11, %xmm0, %xmm0, %xmm079; X86-AVX1-NEXT: vmovsd %xmm0, (%esp)80; X86-AVX1-NEXT: fldl (%esp)81; X86-AVX1-NEXT: movl %ebp, %esp82; X86-AVX1-NEXT: popl %ebp83; X86-AVX1-NEXT: retl84 %i = fptoui double %x to i6485 %r = uitofp i64 %i to double86 ret double %r87}88 89define <4 x float> @trunc_unsigned_v4f32(<4 x float> %x) #0 {90; SSE2-LABEL: trunc_unsigned_v4f32:91; SSE2: # %bb.0:92; SSE2-NEXT: cvttps2dq %xmm0, %xmm193; SSE2-NEXT: movdqa %xmm1, %xmm294; SSE2-NEXT: psrad $31, %xmm295; SSE2-NEXT: subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm096; SSE2-NEXT: cvttps2dq %xmm0, %xmm097; SSE2-NEXT: pand %xmm2, %xmm098; SSE2-NEXT: por %xmm1, %xmm099; SSE2-NEXT: movdqa {{.*#+}} xmm1 = [65535,65535,65535,65535]100; SSE2-NEXT: pand %xmm0, %xmm1101; SSE2-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1102; SSE2-NEXT: psrld $16, %xmm0103; SSE2-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0104; SSE2-NEXT: subps {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0105; SSE2-NEXT: addps %xmm1, %xmm0106; SSE2-NEXT: retq107;108; SSE41-LABEL: trunc_unsigned_v4f32:109; SSE41: # %bb.0:110; SSE41-NEXT: roundps $11, %xmm0, %xmm0111; SSE41-NEXT: retq112;113; AVX-LABEL: trunc_unsigned_v4f32:114; AVX: # %bb.0:115; AVX-NEXT: vroundps $11, %xmm0, %xmm0116; AVX-NEXT: ret{{[l|q]}}117 %i = fptoui <4 x float> %x to <4 x i32>118 %r = uitofp <4 x i32> %i to <4 x float>119 ret <4 x float> %r120}121 122define <2 x double> @trunc_unsigned_v2f64(<2 x double> %x) #0 {123; SSE2-LABEL: trunc_unsigned_v2f64:124; SSE2: # %bb.0:125; SSE2-NEXT: movsd {{.*#+}} xmm2 = [9.2233720368547758E+18,0.0E+0]126; SSE2-NEXT: movapd %xmm0, %xmm1127; SSE2-NEXT: subsd %xmm2, %xmm1128; SSE2-NEXT: cvttsd2si %xmm1, %rax129; SSE2-NEXT: cvttsd2si %xmm0, %rcx130; SSE2-NEXT: movq %rcx, %rdx131; SSE2-NEXT: sarq $63, %rdx132; SSE2-NEXT: andq %rax, %rdx133; SSE2-NEXT: orq %rcx, %rdx134; SSE2-NEXT: movq %rdx, %xmm1135; SSE2-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1,1]136; SSE2-NEXT: cvttsd2si %xmm0, %rax137; SSE2-NEXT: subsd %xmm2, %xmm0138; SSE2-NEXT: cvttsd2si %xmm0, %rcx139; SSE2-NEXT: movq %rax, %rdx140; SSE2-NEXT: sarq $63, %rdx141; SSE2-NEXT: andq %rcx, %rdx142; SSE2-NEXT: orq %rax, %rdx143; SSE2-NEXT: movq %rdx, %xmm0144; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm0[0]145; SSE2-NEXT: movdqa {{.*#+}} xmm0 = [4294967295,4294967295]146; SSE2-NEXT: pand %xmm1, %xmm0147; SSE2-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0148; SSE2-NEXT: psrlq $32, %xmm1149; SSE2-NEXT: por {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1150; SSE2-NEXT: subpd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm1151; SSE2-NEXT: addpd %xmm0, %xmm1152; SSE2-NEXT: movapd %xmm1, %xmm0153; SSE2-NEXT: retq154;155; SSE41-LABEL: trunc_unsigned_v2f64:156; SSE41: # %bb.0:157; SSE41-NEXT: roundpd $11, %xmm0, %xmm0158; SSE41-NEXT: retq159;160; AVX-LABEL: trunc_unsigned_v2f64:161; AVX: # %bb.0:162; AVX-NEXT: vroundpd $11, %xmm0, %xmm0163; AVX-NEXT: ret{{[l|q]}}164 %i = fptoui <2 x double> %x to <2 x i64>165 %r = uitofp <2 x i64> %i to <2 x double>166 ret <2 x double> %r167}168 169define <4 x double> @trunc_unsigned_v4f64(<4 x double> %x) #0 {170; SSE2-LABEL: trunc_unsigned_v4f64:171; SSE2: # %bb.0:172; SSE2-NEXT: movapd %xmm1, %xmm2173; SSE2-NEXT: movsd {{.*#+}} xmm3 = [9.2233720368547758E+18,0.0E+0]174; SSE2-NEXT: subsd %xmm3, %xmm1175; SSE2-NEXT: cvttsd2si %xmm1, %rax176; SSE2-NEXT: cvttsd2si %xmm2, %rcx177; SSE2-NEXT: movq %rcx, %rdx178; SSE2-NEXT: sarq $63, %rdx179; SSE2-NEXT: andq %rax, %rdx180; SSE2-NEXT: orq %rcx, %rdx181; SSE2-NEXT: movq %rdx, %xmm1182; SSE2-NEXT: unpckhpd {{.*#+}} xmm2 = xmm2[1,1]183; SSE2-NEXT: cvttsd2si %xmm2, %rax184; SSE2-NEXT: subsd %xmm3, %xmm2185; SSE2-NEXT: cvttsd2si %xmm2, %rcx186; SSE2-NEXT: movq %rax, %rdx187; SSE2-NEXT: sarq $63, %rdx188; SSE2-NEXT: andq %rcx, %rdx189; SSE2-NEXT: orq %rax, %rdx190; SSE2-NEXT: movq %rdx, %xmm2191; SSE2-NEXT: punpcklqdq {{.*#+}} xmm1 = xmm1[0],xmm2[0]192; SSE2-NEXT: movapd %xmm0, %xmm2193; SSE2-NEXT: subsd %xmm3, %xmm2194; SSE2-NEXT: cvttsd2si %xmm2, %rax195; SSE2-NEXT: cvttsd2si %xmm0, %rcx196; SSE2-NEXT: movq %rcx, %rdx197; SSE2-NEXT: sarq $63, %rdx198; SSE2-NEXT: andq %rax, %rdx199; SSE2-NEXT: orq %rcx, %rdx200; SSE2-NEXT: movq %rdx, %xmm2201; SSE2-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1,1]202; SSE2-NEXT: cvttsd2si %xmm0, %rax203; SSE2-NEXT: subsd %xmm3, %xmm0204; SSE2-NEXT: cvttsd2si %xmm0, %rcx205; SSE2-NEXT: movq %rax, %rdx206; SSE2-NEXT: sarq $63, %rdx207; SSE2-NEXT: andq %rcx, %rdx208; SSE2-NEXT: orq %rax, %rdx209; SSE2-NEXT: movq %rdx, %xmm0210; SSE2-NEXT: punpcklqdq {{.*#+}} xmm2 = xmm2[0],xmm0[0]211; SSE2-NEXT: movdqa {{.*#+}} xmm0 = [4294967295,4294967295]212; SSE2-NEXT: movdqa %xmm2, %xmm3213; SSE2-NEXT: pand %xmm0, %xmm3214; SSE2-NEXT: movdqa {{.*#+}} xmm4 = [4841369599423283200,4841369599423283200]215; SSE2-NEXT: por %xmm4, %xmm3216; SSE2-NEXT: psrlq $32, %xmm2217; SSE2-NEXT: movdqa {{.*#+}} xmm5 = [4985484787499139072,4985484787499139072]218; SSE2-NEXT: por %xmm5, %xmm2219; SSE2-NEXT: movapd {{.*#+}} xmm6 = [1.9342813118337666E+25,1.9342813118337666E+25]220; SSE2-NEXT: subpd %xmm6, %xmm2221; SSE2-NEXT: addpd %xmm3, %xmm2222; SSE2-NEXT: pand %xmm1, %xmm0223; SSE2-NEXT: por %xmm4, %xmm0224; SSE2-NEXT: psrlq $32, %xmm1225; SSE2-NEXT: por %xmm5, %xmm1226; SSE2-NEXT: subpd %xmm6, %xmm1227; SSE2-NEXT: addpd %xmm0, %xmm1228; SSE2-NEXT: movapd %xmm2, %xmm0229; SSE2-NEXT: retq230;231; SSE41-LABEL: trunc_unsigned_v4f64:232; SSE41: # %bb.0:233; SSE41-NEXT: roundpd $11, %xmm0, %xmm0234; SSE41-NEXT: roundpd $11, %xmm1, %xmm1235; SSE41-NEXT: retq236;237; AVX-LABEL: trunc_unsigned_v4f64:238; AVX: # %bb.0:239; AVX-NEXT: vroundpd $11, %ymm0, %ymm0240; AVX-NEXT: ret{{[l|q]}}241 %i = fptoui <4 x double> %x to <4 x i64>242 %r = uitofp <4 x i64> %i to <4 x double>243 ret <4 x double> %r244}245 246define float @trunc_signed_f32_no_fast_math(float %x) nounwind {247; SSE-LABEL: trunc_signed_f32_no_fast_math:248; SSE: # %bb.0:249; SSE-NEXT: cvttps2dq %xmm0, %xmm0250; SSE-NEXT: cvtdq2ps %xmm0, %xmm0251; SSE-NEXT: retq252;253; X64-AVX1-LABEL: trunc_signed_f32_no_fast_math:254; X64-AVX1: # %bb.0:255; X64-AVX1-NEXT: vcvttps2dq %xmm0, %xmm0256; X64-AVX1-NEXT: vcvtdq2ps %xmm0, %xmm0257; X64-AVX1-NEXT: retq258;259; X86-AVX1-LABEL: trunc_signed_f32_no_fast_math:260; X86-AVX1: # %bb.0:261; X86-AVX1-NEXT: pushl %eax262; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero263; X86-AVX1-NEXT: vcvttps2dq %xmm0, %xmm0264; X86-AVX1-NEXT: vcvtdq2ps %xmm0, %xmm0265; X86-AVX1-NEXT: vmovss %xmm0, (%esp)266; X86-AVX1-NEXT: flds (%esp)267; X86-AVX1-NEXT: popl %eax268; X86-AVX1-NEXT: retl269 %i = fptosi float %x to i32270 %r = sitofp i32 %i to float271 ret float %r272}273 274; Without -0.0, it is ok to use roundss if it is available.275 276define float @trunc_signed_f32_nsz(float %x) #0 {277; SSE2-LABEL: trunc_signed_f32_nsz:278; SSE2: # %bb.0:279; SSE2-NEXT: cvttps2dq %xmm0, %xmm0280; SSE2-NEXT: cvtdq2ps %xmm0, %xmm0281; SSE2-NEXT: retq282;283; SSE41-LABEL: trunc_signed_f32_nsz:284; SSE41: # %bb.0:285; SSE41-NEXT: roundss $11, %xmm0, %xmm0286; SSE41-NEXT: retq287;288; X64-AVX1-LABEL: trunc_signed_f32_nsz:289; X64-AVX1: # %bb.0:290; X64-AVX1-NEXT: vroundss $11, %xmm0, %xmm0, %xmm0291; X64-AVX1-NEXT: retq292;293; X86-AVX1-LABEL: trunc_signed_f32_nsz:294; X86-AVX1: # %bb.0:295; X86-AVX1-NEXT: pushl %eax296; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero297; X86-AVX1-NEXT: vroundss $11, %xmm0, %xmm0, %xmm0298; X86-AVX1-NEXT: vmovss %xmm0, (%esp)299; X86-AVX1-NEXT: flds (%esp)300; X86-AVX1-NEXT: popl %eax301; X86-AVX1-NEXT: retl302 %i = fptosi float %x to i32303 %r = sitofp i32 %i to float304 ret float %r305}306 307define double @trunc_signed32_f64_no_fast_math(double %x) nounwind {308; SSE-LABEL: trunc_signed32_f64_no_fast_math:309; SSE: # %bb.0:310; SSE-NEXT: cvttpd2dq %xmm0, %xmm0311; SSE-NEXT: cvtdq2pd %xmm0, %xmm0312; SSE-NEXT: retq313;314; X64-AVX1-LABEL: trunc_signed32_f64_no_fast_math:315; X64-AVX1: # %bb.0:316; X64-AVX1-NEXT: vcvttpd2dq %xmm0, %xmm0317; X64-AVX1-NEXT: vcvtdq2pd %xmm0, %xmm0318; X64-AVX1-NEXT: retq319;320; X86-AVX1-LABEL: trunc_signed32_f64_no_fast_math:321; X86-AVX1: # %bb.0:322; X86-AVX1-NEXT: pushl %ebp323; X86-AVX1-NEXT: movl %esp, %ebp324; X86-AVX1-NEXT: andl $-8, %esp325; X86-AVX1-NEXT: subl $8, %esp326; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero327; X86-AVX1-NEXT: vcvttpd2dq %xmm0, %xmm0328; X86-AVX1-NEXT: vcvtdq2pd %xmm0, %xmm0329; X86-AVX1-NEXT: vmovlps %xmm0, (%esp)330; X86-AVX1-NEXT: fldl (%esp)331; X86-AVX1-NEXT: movl %ebp, %esp332; X86-AVX1-NEXT: popl %ebp333; X86-AVX1-NEXT: retl334 %i = fptosi double %x to i32335 %r = sitofp i32 %i to double336 ret double %r337}338 339define double @trunc_signed32_f64_nsz(double %x) #0 {340; SSE2-LABEL: trunc_signed32_f64_nsz:341; SSE2: # %bb.0:342; SSE2-NEXT: cvttpd2dq %xmm0, %xmm0343; SSE2-NEXT: cvtdq2pd %xmm0, %xmm0344; SSE2-NEXT: retq345;346; SSE41-LABEL: trunc_signed32_f64_nsz:347; SSE41: # %bb.0:348; SSE41-NEXT: roundsd $11, %xmm0, %xmm0349; SSE41-NEXT: retq350;351; X64-AVX1-LABEL: trunc_signed32_f64_nsz:352; X64-AVX1: # %bb.0:353; X64-AVX1-NEXT: vroundsd $11, %xmm0, %xmm0, %xmm0354; X64-AVX1-NEXT: retq355;356; X86-AVX1-LABEL: trunc_signed32_f64_nsz:357; X86-AVX1: # %bb.0:358; X86-AVX1-NEXT: pushl %ebp359; X86-AVX1-NEXT: movl %esp, %ebp360; X86-AVX1-NEXT: andl $-8, %esp361; X86-AVX1-NEXT: subl $8, %esp362; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero363; X86-AVX1-NEXT: vroundsd $11, %xmm0, %xmm0, %xmm0364; X86-AVX1-NEXT: vmovsd %xmm0, (%esp)365; X86-AVX1-NEXT: fldl (%esp)366; X86-AVX1-NEXT: movl %ebp, %esp367; X86-AVX1-NEXT: popl %ebp368; X86-AVX1-NEXT: retl369 %i = fptosi double %x to i32370 %r = sitofp i32 %i to double371 ret double %r372}373 374define double @trunc_f32_signed32_f64_no_fast_math(float %x) nounwind {375; SSE-LABEL: trunc_f32_signed32_f64_no_fast_math:376; SSE: # %bb.0:377; SSE-NEXT: cvttps2dq %xmm0, %xmm0378; SSE-NEXT: cvtdq2pd %xmm0, %xmm0379; SSE-NEXT: retq380;381; X64-AVX1-LABEL: trunc_f32_signed32_f64_no_fast_math:382; X64-AVX1: # %bb.0:383; X64-AVX1-NEXT: vcvttps2dq %xmm0, %xmm0384; X64-AVX1-NEXT: vcvtdq2pd %xmm0, %xmm0385; X64-AVX1-NEXT: retq386;387; X86-AVX1-LABEL: trunc_f32_signed32_f64_no_fast_math:388; X86-AVX1: # %bb.0:389; X86-AVX1-NEXT: pushl %ebp390; X86-AVX1-NEXT: movl %esp, %ebp391; X86-AVX1-NEXT: andl $-8, %esp392; X86-AVX1-NEXT: subl $8, %esp393; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero394; X86-AVX1-NEXT: vcvttps2dq %xmm0, %xmm0395; X86-AVX1-NEXT: vcvtdq2pd %xmm0, %xmm0396; X86-AVX1-NEXT: vmovlps %xmm0, (%esp)397; X86-AVX1-NEXT: fldl (%esp)398; X86-AVX1-NEXT: movl %ebp, %esp399; X86-AVX1-NEXT: popl %ebp400; X86-AVX1-NEXT: retl401 %i = fptosi float %x to i32402 %r = sitofp i32 %i to double403 ret double %r404}405 406define double @trunc_f32_signed32_f64_nsz(float %x) #0 {407; SSE-LABEL: trunc_f32_signed32_f64_nsz:408; SSE: # %bb.0:409; SSE-NEXT: cvttps2dq %xmm0, %xmm0410; SSE-NEXT: cvtdq2pd %xmm0, %xmm0411; SSE-NEXT: retq412;413; X64-AVX1-LABEL: trunc_f32_signed32_f64_nsz:414; X64-AVX1: # %bb.0:415; X64-AVX1-NEXT: vcvttps2dq %xmm0, %xmm0416; X64-AVX1-NEXT: vcvtdq2pd %xmm0, %xmm0417; X64-AVX1-NEXT: retq418;419; X86-AVX1-LABEL: trunc_f32_signed32_f64_nsz:420; X86-AVX1: # %bb.0:421; X86-AVX1-NEXT: pushl %ebp422; X86-AVX1-NEXT: movl %esp, %ebp423; X86-AVX1-NEXT: andl $-8, %esp424; X86-AVX1-NEXT: subl $8, %esp425; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero426; X86-AVX1-NEXT: vcvttps2dq %xmm0, %xmm0427; X86-AVX1-NEXT: vcvtdq2pd %xmm0, %xmm0428; X86-AVX1-NEXT: vmovlps %xmm0, (%esp)429; X86-AVX1-NEXT: fldl (%esp)430; X86-AVX1-NEXT: movl %ebp, %esp431; X86-AVX1-NEXT: popl %ebp432; X86-AVX1-NEXT: retl433 %i = fptosi float %x to i32434 %r = sitofp i32 %i to double435 ret double %r436}437 438define float @trunc_f64_signed32_f32_no_fast_math(double %x) nounwind {439; SSE-LABEL: trunc_f64_signed32_f32_no_fast_math:440; SSE: # %bb.0:441; SSE-NEXT: cvttpd2dq %xmm0, %xmm0442; SSE-NEXT: cvtdq2ps %xmm0, %xmm0443; SSE-NEXT: retq444;445; X64-AVX1-LABEL: trunc_f64_signed32_f32_no_fast_math:446; X64-AVX1: # %bb.0:447; X64-AVX1-NEXT: vcvttpd2dq %xmm0, %xmm0448; X64-AVX1-NEXT: vcvtdq2ps %xmm0, %xmm0449; X64-AVX1-NEXT: retq450;451; X86-AVX1-LABEL: trunc_f64_signed32_f32_no_fast_math:452; X86-AVX1: # %bb.0:453; X86-AVX1-NEXT: pushl %eax454; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero455; X86-AVX1-NEXT: vcvttpd2dq %xmm0, %xmm0456; X86-AVX1-NEXT: vcvtdq2ps %xmm0, %xmm0457; X86-AVX1-NEXT: vmovss %xmm0, (%esp)458; X86-AVX1-NEXT: flds (%esp)459; X86-AVX1-NEXT: popl %eax460; X86-AVX1-NEXT: retl461 %i = fptosi double %x to i32462 %r = sitofp i32 %i to float463 ret float %r464}465 466define float @trunc_f64_signed32_f32_nsz(double %x) #0 {467; SSE-LABEL: trunc_f64_signed32_f32_nsz:468; SSE: # %bb.0:469; SSE-NEXT: cvttpd2dq %xmm0, %xmm0470; SSE-NEXT: cvtdq2ps %xmm0, %xmm0471; SSE-NEXT: retq472;473; X64-AVX1-LABEL: trunc_f64_signed32_f32_nsz:474; X64-AVX1: # %bb.0:475; X64-AVX1-NEXT: vcvttpd2dq %xmm0, %xmm0476; X64-AVX1-NEXT: vcvtdq2ps %xmm0, %xmm0477; X64-AVX1-NEXT: retq478;479; X86-AVX1-LABEL: trunc_f64_signed32_f32_nsz:480; X86-AVX1: # %bb.0:481; X86-AVX1-NEXT: pushl %eax482; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero483; X86-AVX1-NEXT: vcvttpd2dq %xmm0, %xmm0484; X86-AVX1-NEXT: vcvtdq2ps %xmm0, %xmm0485; X86-AVX1-NEXT: vmovss %xmm0, (%esp)486; X86-AVX1-NEXT: flds (%esp)487; X86-AVX1-NEXT: popl %eax488; X86-AVX1-NEXT: retl489 %i = fptosi double %x to i32490 %r = sitofp i32 %i to float491 ret float %r492}493 494define double @trunc_signed_f64_no_fast_math(double %x) nounwind {495; SSE-LABEL: trunc_signed_f64_no_fast_math:496; SSE: # %bb.0:497; SSE-NEXT: cvttsd2si %xmm0, %rax498; SSE-NEXT: xorps %xmm0, %xmm0499; SSE-NEXT: cvtsi2sd %rax, %xmm0500; SSE-NEXT: retq501;502; X64-AVX1-LABEL: trunc_signed_f64_no_fast_math:503; X64-AVX1: # %bb.0:504; X64-AVX1-NEXT: vcvttsd2si %xmm0, %rax505; X64-AVX1-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0506; X64-AVX1-NEXT: retq507;508; X86-AVX1-LABEL: trunc_signed_f64_no_fast_math:509; X86-AVX1: # %bb.0:510; X86-AVX1-NEXT: pushl %ebp511; X86-AVX1-NEXT: movl %esp, %ebp512; X86-AVX1-NEXT: andl $-8, %esp513; X86-AVX1-NEXT: subl $24, %esp514; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero515; X86-AVX1-NEXT: vmovsd %xmm0, (%esp)516; X86-AVX1-NEXT: fldl (%esp)517; X86-AVX1-NEXT: fisttpll (%esp)518; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero519; X86-AVX1-NEXT: vmovlps %xmm0, {{[0-9]+}}(%esp)520; X86-AVX1-NEXT: fildll {{[0-9]+}}(%esp)521; X86-AVX1-NEXT: fstpl {{[0-9]+}}(%esp)522; X86-AVX1-NEXT: fldl {{[0-9]+}}(%esp)523; X86-AVX1-NEXT: movl %ebp, %esp524; X86-AVX1-NEXT: popl %ebp525; X86-AVX1-NEXT: retl526 %i = fptosi double %x to i64527 %r = sitofp i64 %i to double528 ret double %r529}530 531define double @trunc_signed_f64_nsz(double %x) #0 {532; SSE2-LABEL: trunc_signed_f64_nsz:533; SSE2: # %bb.0:534; SSE2-NEXT: cvttsd2si %xmm0, %rax535; SSE2-NEXT: xorps %xmm0, %xmm0536; SSE2-NEXT: cvtsi2sd %rax, %xmm0537; SSE2-NEXT: retq538;539; SSE41-LABEL: trunc_signed_f64_nsz:540; SSE41: # %bb.0:541; SSE41-NEXT: roundsd $11, %xmm0, %xmm0542; SSE41-NEXT: retq543;544; X64-AVX1-LABEL: trunc_signed_f64_nsz:545; X64-AVX1: # %bb.0:546; X64-AVX1-NEXT: vroundsd $11, %xmm0, %xmm0, %xmm0547; X64-AVX1-NEXT: retq548;549; X86-AVX1-LABEL: trunc_signed_f64_nsz:550; X86-AVX1: # %bb.0:551; X86-AVX1-NEXT: pushl %ebp552; X86-AVX1-NEXT: movl %esp, %ebp553; X86-AVX1-NEXT: andl $-8, %esp554; X86-AVX1-NEXT: subl $8, %esp555; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero556; X86-AVX1-NEXT: vroundsd $11, %xmm0, %xmm0, %xmm0557; X86-AVX1-NEXT: vmovsd %xmm0, (%esp)558; X86-AVX1-NEXT: fldl (%esp)559; X86-AVX1-NEXT: movl %ebp, %esp560; X86-AVX1-NEXT: popl %ebp561; X86-AVX1-NEXT: retl562 %i = fptosi double %x to i64563 %r = sitofp i64 %i to double564 ret double %r565}566 567define <4 x float> @trunc_signed_v4f32_nsz(<4 x float> %x) #0 {568; SSE2-LABEL: trunc_signed_v4f32_nsz:569; SSE2: # %bb.0:570; SSE2-NEXT: cvttps2dq %xmm0, %xmm0571; SSE2-NEXT: cvtdq2ps %xmm0, %xmm0572; SSE2-NEXT: retq573;574; SSE41-LABEL: trunc_signed_v4f32_nsz:575; SSE41: # %bb.0:576; SSE41-NEXT: roundps $11, %xmm0, %xmm0577; SSE41-NEXT: retq578;579; AVX-LABEL: trunc_signed_v4f32_nsz:580; AVX: # %bb.0:581; AVX-NEXT: vroundps $11, %xmm0, %xmm0582; AVX-NEXT: ret{{[l|q]}}583 %i = fptosi <4 x float> %x to <4 x i32>584 %r = sitofp <4 x i32> %i to <4 x float>585 ret <4 x float> %r586}587 588define <2 x double> @trunc_signed_v2f64_nsz(<2 x double> %x) #0 {589; SSE2-LABEL: trunc_signed_v2f64_nsz:590; SSE2: # %bb.0:591; SSE2-NEXT: cvttsd2si %xmm0, %rax592; SSE2-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1,1]593; SSE2-NEXT: cvttsd2si %xmm0, %rcx594; SSE2-NEXT: xorps %xmm0, %xmm0595; SSE2-NEXT: cvtsi2sd %rax, %xmm0596; SSE2-NEXT: cvtsi2sd %rcx, %xmm1597; SSE2-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]598; SSE2-NEXT: retq599;600; SSE41-LABEL: trunc_signed_v2f64_nsz:601; SSE41: # %bb.0:602; SSE41-NEXT: roundpd $11, %xmm0, %xmm0603; SSE41-NEXT: retq604;605; AVX-LABEL: trunc_signed_v2f64_nsz:606; AVX: # %bb.0:607; AVX-NEXT: vroundpd $11, %xmm0, %xmm0608; AVX-NEXT: ret{{[l|q]}}609 %i = fptosi <2 x double> %x to <2 x i64>610 %r = sitofp <2 x i64> %i to <2 x double>611 ret <2 x double> %r612}613 614define <4 x double> @trunc_signed_v4f64_nsz(<4 x double> %x) #0 {615; SSE2-LABEL: trunc_signed_v4f64_nsz:616; SSE2: # %bb.0:617; SSE2-NEXT: cvttsd2si %xmm1, %rax618; SSE2-NEXT: unpckhpd {{.*#+}} xmm1 = xmm1[1,1]619; SSE2-NEXT: cvttsd2si %xmm1, %rcx620; SSE2-NEXT: cvttsd2si %xmm0, %rdx621; SSE2-NEXT: unpckhpd {{.*#+}} xmm0 = xmm0[1,1]622; SSE2-NEXT: cvttsd2si %xmm0, %rsi623; SSE2-NEXT: xorps %xmm0, %xmm0624; SSE2-NEXT: cvtsi2sd %rdx, %xmm0625; SSE2-NEXT: xorps %xmm1, %xmm1626; SSE2-NEXT: cvtsi2sd %rsi, %xmm1627; SSE2-NEXT: unpcklpd {{.*#+}} xmm0 = xmm0[0],xmm1[0]628; SSE2-NEXT: xorps %xmm1, %xmm1629; SSE2-NEXT: cvtsi2sd %rax, %xmm1630; SSE2-NEXT: cvtsi2sd %rcx, %xmm2631; SSE2-NEXT: unpcklpd {{.*#+}} xmm1 = xmm1[0],xmm2[0]632; SSE2-NEXT: retq633;634; SSE41-LABEL: trunc_signed_v4f64_nsz:635; SSE41: # %bb.0:636; SSE41-NEXT: roundpd $11, %xmm0, %xmm0637; SSE41-NEXT: roundpd $11, %xmm1, %xmm1638; SSE41-NEXT: retq639;640; AVX-LABEL: trunc_signed_v4f64_nsz:641; AVX: # %bb.0:642; AVX-NEXT: vroundpd $11, %ymm0, %ymm0643; AVX-NEXT: ret{{[l|q]}}644 %i = fptosi <4 x double> %x to <4 x i64>645 %r = sitofp <4 x i64> %i to <4 x double>646 ret <4 x double> %r647}648 649; The FTRUNC ("round**" x86 asm) fold relies on UB in the case of overflow.650; This used to be guarded with an attribute check. That allowed existing651; code to continue working based on its assumptions that float->int652; overflow had saturating behavior.653;654; Now, we expect a front-end to use IR intrinsics if it wants to avoid this655; transform.656 657define float @trunc_unsigned_f32_disable_via_intrinsic(float %x) #0 {658; SSE-LABEL: trunc_unsigned_f32_disable_via_intrinsic:659; SSE: # %bb.0:660; SSE-NEXT: cvttss2si %xmm0, %rax661; SSE-NEXT: xorl %ecx, %ecx662; SSE-NEXT: xorps %xmm1, %xmm1663; SSE-NEXT: ucomiss %xmm1, %xmm0664; SSE-NEXT: cmovael %eax, %ecx665; SSE-NEXT: ucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0666; SSE-NEXT: movl $-1, %eax667; SSE-NEXT: cmovbel %ecx, %eax668; SSE-NEXT: xorps %xmm0, %xmm0669; SSE-NEXT: cvtsi2ss %rax, %xmm0670; SSE-NEXT: retq671;672; X64-AVX1-LABEL: trunc_unsigned_f32_disable_via_intrinsic:673; X64-AVX1: # %bb.0:674; X64-AVX1-NEXT: vcvttss2si %xmm0, %rax675; X64-AVX1-NEXT: xorl %ecx, %ecx676; X64-AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1677; X64-AVX1-NEXT: vucomiss %xmm1, %xmm0678; X64-AVX1-NEXT: cmovael %eax, %ecx679; X64-AVX1-NEXT: vucomiss {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0680; X64-AVX1-NEXT: movl $-1, %eax681; X64-AVX1-NEXT: cmovbel %ecx, %eax682; X64-AVX1-NEXT: vcvtsi2ss %rax, %xmm15, %xmm0683; X64-AVX1-NEXT: retq684;685; X86-AVX1-LABEL: trunc_unsigned_f32_disable_via_intrinsic:686; X86-AVX1: # %bb.0:687; X86-AVX1-NEXT: pushl %eax688; X86-AVX1-NEXT: vmovss {{.*#+}} xmm0 = mem[0],zero,zero,zero689; X86-AVX1-NEXT: vcvttss2si %xmm0, %eax690; X86-AVX1-NEXT: movl %eax, %ecx691; X86-AVX1-NEXT: sarl $31, %ecx692; X86-AVX1-NEXT: vsubss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0, %xmm1693; X86-AVX1-NEXT: vcvttss2si %xmm1, %edx694; X86-AVX1-NEXT: andl %ecx, %edx695; X86-AVX1-NEXT: orl %eax, %edx696; X86-AVX1-NEXT: xorl %eax, %eax697; X86-AVX1-NEXT: vxorps %xmm1, %xmm1, %xmm1698; X86-AVX1-NEXT: vucomiss %xmm1, %xmm0699; X86-AVX1-NEXT: cmovael %edx, %eax700; X86-AVX1-NEXT: vucomiss {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0701; X86-AVX1-NEXT: movl $-1, %ecx702; X86-AVX1-NEXT: cmovbel %eax, %ecx703; X86-AVX1-NEXT: vmovd %ecx, %xmm0704; X86-AVX1-NEXT: vpor {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0, %xmm0705; X86-AVX1-NEXT: vsubsd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0, %xmm0706; X86-AVX1-NEXT: vcvtsd2ss %xmm0, %xmm0, %xmm0707; X86-AVX1-NEXT: vmovss %xmm0, (%esp)708; X86-AVX1-NEXT: flds (%esp)709; X86-AVX1-NEXT: popl %eax710; X86-AVX1-NEXT: retl711 %i = call i32 @llvm.fptoui.sat.i32.f32(float %x)712 %r = uitofp i32 %i to float713 ret float %r714}715 716define double @trunc_signed_f64_disable_via_intrinsic(double %x) #0 {717; SSE-LABEL: trunc_signed_f64_disable_via_intrinsic:718; SSE: # %bb.0:719; SSE-NEXT: cvttsd2si %xmm0, %rax720; SSE-NEXT: ucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0721; SSE-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF722; SSE-NEXT: cmovbeq %rax, %rcx723; SSE-NEXT: xorl %eax, %eax724; SSE-NEXT: ucomisd %xmm0, %xmm0725; SSE-NEXT: cmovnpq %rcx, %rax726; SSE-NEXT: xorps %xmm0, %xmm0727; SSE-NEXT: cvtsi2sd %rax, %xmm0728; SSE-NEXT: retq729;730; X64-AVX1-LABEL: trunc_signed_f64_disable_via_intrinsic:731; X64-AVX1: # %bb.0:732; X64-AVX1-NEXT: vcvttsd2si %xmm0, %rax733; X64-AVX1-NEXT: vucomisd {{\.?LCPI[0-9]+_[0-9]+}}(%rip), %xmm0734; X64-AVX1-NEXT: movabsq $9223372036854775807, %rcx # imm = 0x7FFFFFFFFFFFFFFF735; X64-AVX1-NEXT: cmovbeq %rax, %rcx736; X64-AVX1-NEXT: xorl %eax, %eax737; X64-AVX1-NEXT: vucomisd %xmm0, %xmm0738; X64-AVX1-NEXT: cmovnpq %rcx, %rax739; X64-AVX1-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0740; X64-AVX1-NEXT: retq741;742; X86-AVX1-LABEL: trunc_signed_f64_disable_via_intrinsic:743; X86-AVX1: # %bb.0:744; X86-AVX1-NEXT: pushl %ebp745; X86-AVX1-NEXT: movl %esp, %ebp746; X86-AVX1-NEXT: pushl %esi747; X86-AVX1-NEXT: andl $-8, %esp748; X86-AVX1-NEXT: subl $32, %esp749; X86-AVX1-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero750; X86-AVX1-NEXT: vmovsd %xmm0, (%esp)751; X86-AVX1-NEXT: fldl (%esp)752; X86-AVX1-NEXT: fisttpll (%esp)753; X86-AVX1-NEXT: xorl %eax, %eax754; X86-AVX1-NEXT: vucomisd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0755; X86-AVX1-NEXT: movl $-2147483648, %ecx # imm = 0x80000000756; X86-AVX1-NEXT: movl $0, %edx757; X86-AVX1-NEXT: jb .LBB19_2758; X86-AVX1-NEXT: # %bb.1:759; X86-AVX1-NEXT: movl {{[0-9]+}}(%esp), %ecx760; X86-AVX1-NEXT: movl (%esp), %edx761; X86-AVX1-NEXT: .LBB19_2:762; X86-AVX1-NEXT: vucomisd {{\.?LCPI[0-9]+_[0-9]+}}, %xmm0763; X86-AVX1-NEXT: movl $-1, %esi764; X86-AVX1-NEXT: cmovbel %edx, %esi765; X86-AVX1-NEXT: movl $2147483647, %edx # imm = 0x7FFFFFFF766; X86-AVX1-NEXT: cmovbel %ecx, %edx767; X86-AVX1-NEXT: vucomisd %xmm0, %xmm0768; X86-AVX1-NEXT: cmovpl %eax, %edx769; X86-AVX1-NEXT: cmovpl %eax, %esi770; X86-AVX1-NEXT: vmovd %esi, %xmm0771; X86-AVX1-NEXT: vpinsrd $1, %edx, %xmm0, %xmm0772; X86-AVX1-NEXT: vmovq %xmm0, {{[0-9]+}}(%esp)773; X86-AVX1-NEXT: fildll {{[0-9]+}}(%esp)774; X86-AVX1-NEXT: fstpl {{[0-9]+}}(%esp)775; X86-AVX1-NEXT: fldl {{[0-9]+}}(%esp)776; X86-AVX1-NEXT: leal -4(%ebp), %esp777; X86-AVX1-NEXT: popl %esi778; X86-AVX1-NEXT: popl %ebp779; X86-AVX1-NEXT: retl780 %i = call i64 @llvm.fptosi.sat.i64.f64(double %x)781 %r = sitofp i64 %i to double782 ret double %r783}784 785attributes #0 = { nounwind "no-signed-zeros-fp-math"="true" }786