234 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-- -mattr=sse4.1 | FileCheck %s --check-prefix=SSE3; RUN: llc < %s -mtriple=x86_64-- -mattr=avx | FileCheck %s --check-prefix=AVX4; RUN: llc < %s -mtriple=x86_64-- -mattr=avx512f,avx512vl | FileCheck %s --check-prefix=AVX5 6; PR37751 - https://bugs.llvm.org/show_bug.cgi?id=377517; We can't combine into 'round' instructions because the behavior is different for out-of-range values.8 9declare <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float>)10declare <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double>)11declare i32 @llvm.x86.sse.cvttss2si(<4 x float>)12declare i64 @llvm.x86.sse.cvttss2si64(<4 x float>)13declare i32 @llvm.x86.sse2.cvttsd2si(<2 x double>)14declare i64 @llvm.x86.sse2.cvttsd2si64(<2 x double>)15 16define float @float_to_int_to_float_mem_f32_i32(ptr %p) #0 {17; SSE-LABEL: float_to_int_to_float_mem_f32_i32:18; SSE: # %bb.0:19; SSE-NEXT: cvttss2si (%rdi), %eax20; SSE-NEXT: cvtsi2ss %eax, %xmm021; SSE-NEXT: retq22;23; AVX-LABEL: float_to_int_to_float_mem_f32_i32:24; AVX: # %bb.0:25; AVX-NEXT: vcvttss2si (%rdi), %eax26; AVX-NEXT: vcvtsi2ss %eax, %xmm15, %xmm027; AVX-NEXT: retq28 %x = load <4 x float>, ptr %p, align 1629 %fptosi = tail call i32 @llvm.x86.sse.cvttss2si(<4 x float> %x)30 %sitofp = sitofp i32 %fptosi to float31 ret float %sitofp32}33 34define float @float_to_int_to_float_reg_f32_i32(<4 x float> %x) #0 {35; SSE-LABEL: float_to_int_to_float_reg_f32_i32:36; SSE: # %bb.0:37; SSE-NEXT: cvttss2si %xmm0, %eax38; SSE-NEXT: xorps %xmm0, %xmm039; SSE-NEXT: cvtsi2ss %eax, %xmm040; SSE-NEXT: retq41;42; AVX-LABEL: float_to_int_to_float_reg_f32_i32:43; AVX: # %bb.0:44; AVX-NEXT: vcvttss2si %xmm0, %eax45; AVX-NEXT: vcvtsi2ss %eax, %xmm15, %xmm046; AVX-NEXT: retq47 %fptosi = tail call i32 @llvm.x86.sse.cvttss2si(<4 x float> %x)48 %sitofp = sitofp i32 %fptosi to float49 ret float %sitofp50}51 52define float @float_to_int_to_float_mem_f32_i64(ptr %p) #0 {53; SSE-LABEL: float_to_int_to_float_mem_f32_i64:54; SSE: # %bb.0:55; SSE-NEXT: cvttss2si (%rdi), %rax56; SSE-NEXT: cvtsi2ss %rax, %xmm057; SSE-NEXT: retq58;59; AVX-LABEL: float_to_int_to_float_mem_f32_i64:60; AVX: # %bb.0:61; AVX-NEXT: vcvttss2si (%rdi), %rax62; AVX-NEXT: vcvtsi2ss %rax, %xmm15, %xmm063; AVX-NEXT: retq64 %x = load <4 x float>, ptr %p, align 1665 %fptosi = tail call i64 @llvm.x86.sse.cvttss2si64(<4 x float> %x)66 %sitofp = sitofp i64 %fptosi to float67 ret float %sitofp68}69 70define float @float_to_int_to_float_reg_f32_i64(<4 x float> %x) #0 {71; SSE-LABEL: float_to_int_to_float_reg_f32_i64:72; SSE: # %bb.0:73; SSE-NEXT: cvttss2si %xmm0, %rax74; SSE-NEXT: xorps %xmm0, %xmm075; SSE-NEXT: cvtsi2ss %rax, %xmm076; SSE-NEXT: retq77;78; AVX-LABEL: float_to_int_to_float_reg_f32_i64:79; AVX: # %bb.0:80; AVX-NEXT: vcvttss2si %xmm0, %rax81; AVX-NEXT: vcvtsi2ss %rax, %xmm15, %xmm082; AVX-NEXT: retq83 %fptosi = tail call i64 @llvm.x86.sse.cvttss2si64(<4 x float> %x)84 %sitofp = sitofp i64 %fptosi to float85 ret float %sitofp86}87 88define double @float_to_int_to_float_mem_f64_i32(ptr %p) #0 {89; SSE-LABEL: float_to_int_to_float_mem_f64_i32:90; SSE: # %bb.0:91; SSE-NEXT: cvttsd2si (%rdi), %eax92; SSE-NEXT: cvtsi2sd %eax, %xmm093; SSE-NEXT: retq94;95; AVX-LABEL: float_to_int_to_float_mem_f64_i32:96; AVX: # %bb.0:97; AVX-NEXT: vcvttsd2si (%rdi), %eax98; AVX-NEXT: vcvtsi2sd %eax, %xmm15, %xmm099; AVX-NEXT: retq100 %x = load <2 x double>, ptr %p, align 16101 %fptosi = tail call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> %x)102 %sitofp = sitofp i32 %fptosi to double103 ret double %sitofp104}105 106define double @float_to_int_to_float_reg_f64_i32(<2 x double> %x) #0 {107; SSE-LABEL: float_to_int_to_float_reg_f64_i32:108; SSE: # %bb.0:109; SSE-NEXT: cvttsd2si %xmm0, %eax110; SSE-NEXT: xorps %xmm0, %xmm0111; SSE-NEXT: cvtsi2sd %eax, %xmm0112; SSE-NEXT: retq113;114; AVX-LABEL: float_to_int_to_float_reg_f64_i32:115; AVX: # %bb.0:116; AVX-NEXT: vcvttsd2si %xmm0, %eax117; AVX-NEXT: vcvtsi2sd %eax, %xmm15, %xmm0118; AVX-NEXT: retq119 %fptosi = tail call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> %x)120 %sitofp = sitofp i32 %fptosi to double121 ret double %sitofp122}123 124define double @float_to_int_to_float_mem_f64_i64(ptr %p) #0 {125; SSE-LABEL: float_to_int_to_float_mem_f64_i64:126; SSE: # %bb.0:127; SSE-NEXT: cvttsd2si (%rdi), %rax128; SSE-NEXT: cvtsi2sd %rax, %xmm0129; SSE-NEXT: retq130;131; AVX-LABEL: float_to_int_to_float_mem_f64_i64:132; AVX: # %bb.0:133; AVX-NEXT: vcvttsd2si (%rdi), %rax134; AVX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0135; AVX-NEXT: retq136 %x = load <2 x double>, ptr %p, align 16137 %fptosi = tail call i64 @llvm.x86.sse2.cvttsd2si64(<2 x double> %x)138 %sitofp = sitofp i64 %fptosi to double139 ret double %sitofp140}141 142define double @float_to_int_to_float_reg_f64_i64(<2 x double> %x) #0 {143; SSE-LABEL: float_to_int_to_float_reg_f64_i64:144; SSE: # %bb.0:145; SSE-NEXT: cvttsd2si %xmm0, %rax146; SSE-NEXT: xorps %xmm0, %xmm0147; SSE-NEXT: cvtsi2sd %rax, %xmm0148; SSE-NEXT: retq149;150; AVX-LABEL: float_to_int_to_float_reg_f64_i64:151; AVX: # %bb.0:152; AVX-NEXT: vcvttsd2si %xmm0, %rax153; AVX-NEXT: vcvtsi2sd %rax, %xmm15, %xmm0154; AVX-NEXT: retq155 %fptosi = tail call i64 @llvm.x86.sse2.cvttsd2si64(<2 x double> %x)156 %sitofp = sitofp i64 %fptosi to double157 ret double %sitofp158}159 160define <4 x float> @float_to_int_to_float_mem_v4f32(ptr %p) #0 {161; SSE-LABEL: float_to_int_to_float_mem_v4f32:162; SSE: # %bb.0:163; SSE-NEXT: cvttps2dq (%rdi), %xmm0164; SSE-NEXT: cvtdq2ps %xmm0, %xmm0165; SSE-NEXT: retq166;167; AVX-LABEL: float_to_int_to_float_mem_v4f32:168; AVX: # %bb.0:169; AVX-NEXT: vcvttps2dq (%rdi), %xmm0170; AVX-NEXT: vcvtdq2ps %xmm0, %xmm0171; AVX-NEXT: retq172 %x = load <4 x float>, ptr %p, align 16173 %fptosi = tail call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %x)174 %sitofp = sitofp <4 x i32> %fptosi to <4 x float>175 ret <4 x float> %sitofp176}177 178define <4 x float> @float_to_int_to_float_reg_v4f32(<4 x float> %x) #0 {179; SSE-LABEL: float_to_int_to_float_reg_v4f32:180; SSE: # %bb.0:181; SSE-NEXT: cvttps2dq %xmm0, %xmm0182; SSE-NEXT: cvtdq2ps %xmm0, %xmm0183; SSE-NEXT: retq184;185; AVX-LABEL: float_to_int_to_float_reg_v4f32:186; AVX: # %bb.0:187; AVX-NEXT: vcvttps2dq %xmm0, %xmm0188; AVX-NEXT: vcvtdq2ps %xmm0, %xmm0189; AVX-NEXT: retq190 %fptosi = tail call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %x)191 %sitofp = sitofp <4 x i32> %fptosi to <4 x float>192 ret <4 x float> %sitofp193}194 195define <2 x double> @float_to_int_to_float_mem_v2f64(ptr %p) #0 {196; SSE-LABEL: float_to_int_to_float_mem_v2f64:197; SSE: # %bb.0:198; SSE-NEXT: cvttpd2dq (%rdi), %xmm0199; SSE-NEXT: cvtdq2pd %xmm0, %xmm0200; SSE-NEXT: retq201;202; AVX-LABEL: float_to_int_to_float_mem_v2f64:203; AVX: # %bb.0:204; AVX-NEXT: vcvttpd2dqx (%rdi), %xmm0205; AVX-NEXT: vcvtdq2pd %xmm0, %xmm0206; AVX-NEXT: retq207 %x = load <2 x double>, ptr %p, align 16208 %fptosi = tail call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %x)209 %concat = shufflevector <4 x i32> %fptosi, <4 x i32> undef, <2 x i32> <i32 0, i32 1>210 %sitofp = sitofp <2 x i32> %concat to <2 x double>211 ret <2 x double> %sitofp212}213 214define <2 x double> @float_to_int_to_float_reg_v2f64(<2 x double> %x) #0 {215; SSE-LABEL: float_to_int_to_float_reg_v2f64:216; SSE: # %bb.0:217; SSE-NEXT: cvttpd2dq %xmm0, %xmm0218; SSE-NEXT: cvtdq2pd %xmm0, %xmm0219; SSE-NEXT: retq220;221; AVX-LABEL: float_to_int_to_float_reg_v2f64:222; AVX: # %bb.0:223; AVX-NEXT: vcvttpd2dq %xmm0, %xmm0224; AVX-NEXT: vcvtdq2pd %xmm0, %xmm0225; AVX-NEXT: retq226 %fptosi = tail call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %x)227 %concat = shufflevector <4 x i32> %fptosi, <4 x i32> undef, <2 x i32> <i32 0, i32 1>228 %sitofp = sitofp <2 x i32> %concat to <2 x double>229 ret <2 x double> %sitofp230}231 232attributes #0 = { "no-signed-zeros-fp-math"="true" }233 234