1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 -mattr=+sse2 | FileCheck %s --check-prefix=CHECK --check-prefix=SSE 3; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 -mattr=+avx | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX1 4; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 -mattr=+avx512f | FileCheck %s --check-prefix=CHECK --check-prefix=AVX --check-prefix=AVX512 5 6declare double @__sqrt_finite(double) 7declare float @__sqrtf_finite(float) 8declare x86_fp80 @__sqrtl_finite(x86_fp80) 9declare float @llvm.sqrt.f32(float) 10declare <4 x float> @llvm.sqrt.v4f32(<4 x float>) 11declare <8 x float> @llvm.sqrt.v8f32(<8 x float>) 12declare <16 x float> @llvm.sqrt.v16f32(<16 x float>) 13 14 15define double @finite_f64_no_estimate(double %d) #0 { 16; SSE-LABEL: finite_f64_no_estimate: 17; SSE: # %bb.0: 18; SSE-NEXT: sqrtsd %xmm0, %xmm0 19; SSE-NEXT: retq 20; 21; AVX-LABEL: finite_f64_no_estimate: 22; AVX: # %bb.0: 23; AVX-NEXT: vsqrtsd %xmm0, %xmm0, %xmm0 24; AVX-NEXT: retq 25 %call = tail call double @__sqrt_finite(double %d) #2 26 ret double %call 27} 28 29; No estimates for doubles. 30 31define double @finite_f64_estimate(double %d) #1 { 32; SSE-LABEL: finite_f64_estimate: 33; SSE: # %bb.0: 34; SSE-NEXT: sqrtsd %xmm0, %xmm0 35; SSE-NEXT: retq 36; 37; AVX-LABEL: finite_f64_estimate: 38; AVX: # %bb.0: 39; AVX-NEXT: vsqrtsd %xmm0, %xmm0, %xmm0 40; AVX-NEXT: retq 41 %call = tail call double @__sqrt_finite(double %d) #2 42 ret double %call 43} 44 45define float @finite_f32_no_estimate(float %f) #0 { 46; SSE-LABEL: finite_f32_no_estimate: 47; SSE: # %bb.0: 48; SSE-NEXT: sqrtss %xmm0, %xmm0 49; SSE-NEXT: retq 50; 51; AVX-LABEL: finite_f32_no_estimate: 52; AVX: # %bb.0: 53; AVX-NEXT: vsqrtss %xmm0, %xmm0, %xmm0 54; AVX-NEXT: retq 55 %call = tail call float @__sqrtf_finite(float %f) #2 56 ret float %call 57} 58 59define float @finite_f32_estimate_ieee(float %f) #1 { 60; SSE-LABEL: finite_f32_estimate_ieee: 61; SSE: # %bb.0: 62; SSE-NEXT: sqrtss %xmm0, %xmm0 63; SSE-NEXT: retq 64; 65; AVX-LABEL: finite_f32_estimate_ieee: 66; AVX: # %bb.0: 67; AVX-NEXT: vsqrtss %xmm0, %xmm0, %xmm0 68; AVX-NEXT: retq 69 %call = tail call float @__sqrtf_finite(float %f) #2 70 ret float %call 71} 72 73define float @finite_f32_estimate_ieee_ninf(float %f) #1 { 74; SSE-LABEL: finite_f32_estimate_ieee_ninf: 75; SSE: # %bb.0: 76; SSE-NEXT: rsqrtss %xmm0, %xmm1 77; SSE-NEXT: movaps %xmm0, %xmm2 78; SSE-NEXT: mulss %xmm1, %xmm2 79; SSE-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero 80; SSE-NEXT: mulss %xmm2, %xmm3 81; SSE-NEXT: mulss %xmm1, %xmm2 82; SSE-NEXT: addss {{.*}}(%rip), %xmm2 83; SSE-NEXT: andps {{.*}}(%rip), %xmm0 84; SSE-NEXT: mulss %xmm3, %xmm2 85; SSE-NEXT: cmpltss {{.*}}(%rip), %xmm0 86; SSE-NEXT: andnps %xmm2, %xmm0 87; SSE-NEXT: retq 88; 89; AVX1-LABEL: finite_f32_estimate_ieee_ninf: 90; AVX1: # %bb.0: 91; AVX1-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 92; AVX1-NEXT: vmulss %xmm1, %xmm0, %xmm2 93; AVX1-NEXT: vmulss %xmm1, %xmm2, %xmm1 94; AVX1-NEXT: vaddss {{.*}}(%rip), %xmm1, %xmm1 95; AVX1-NEXT: vmulss {{.*}}(%rip), %xmm2, %xmm2 96; AVX1-NEXT: vandps {{.*}}(%rip), %xmm0, %xmm0 97; AVX1-NEXT: vmulss %xmm1, %xmm2, %xmm1 98; AVX1-NEXT: vcmpltss {{.*}}(%rip), %xmm0, %xmm0 99; AVX1-NEXT: vandnps %xmm1, %xmm0, %xmm0 100; AVX1-NEXT: retq 101; 102; AVX512-LABEL: finite_f32_estimate_ieee_ninf: 103; AVX512: # %bb.0: 104; AVX512-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 105; AVX512-NEXT: vmulss %xmm1, %xmm0, %xmm2 106; AVX512-NEXT: vfmadd213ss {{.*#+}} xmm1 = (xmm2 * xmm1) + mem 107; AVX512-NEXT: vmulss {{.*}}(%rip), %xmm2, %xmm2 108; AVX512-NEXT: vmulss %xmm1, %xmm2, %xmm1 109; AVX512-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN] 110; AVX512-NEXT: vandps %xmm2, %xmm0, %xmm0 111; AVX512-NEXT: vcmpltss {{.*}}(%rip), %xmm0, %k1 112; AVX512-NEXT: vxorps %xmm0, %xmm0, %xmm0 113; AVX512-NEXT: vmovss %xmm0, %xmm1, %xmm1 {%k1} 114; AVX512-NEXT: vmovaps %xmm1, %xmm0 115; AVX512-NEXT: retq 116 %call = tail call ninf float @__sqrtf_finite(float %f) #2 117 ret float %call 118} 119 120define float @finite_f32_estimate_daz(float %f) #4 { 121; SSE-LABEL: finite_f32_estimate_daz: 122; SSE: # %bb.0: 123; SSE-NEXT: sqrtss %xmm0, %xmm0 124; SSE-NEXT: retq 125; 126; AVX-LABEL: finite_f32_estimate_daz: 127; AVX: # %bb.0: 128; AVX-NEXT: vsqrtss %xmm0, %xmm0, %xmm0 129; AVX-NEXT: retq 130 %call = tail call float @__sqrtf_finite(float %f) #2 131 ret float %call 132} 133 134define float @finite_f32_estimate_daz_ninf(float %f) #4 { 135; SSE-LABEL: finite_f32_estimate_daz_ninf: 136; SSE: # %bb.0: 137; SSE-NEXT: rsqrtss %xmm0, %xmm1 138; SSE-NEXT: movaps %xmm0, %xmm2 139; SSE-NEXT: mulss %xmm1, %xmm2 140; SSE-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero 141; SSE-NEXT: mulss %xmm2, %xmm3 142; SSE-NEXT: mulss %xmm1, %xmm2 143; SSE-NEXT: addss {{.*}}(%rip), %xmm2 144; SSE-NEXT: mulss %xmm3, %xmm2 145; SSE-NEXT: xorps %xmm1, %xmm1 146; SSE-NEXT: cmpeqss %xmm1, %xmm0 147; SSE-NEXT: andnps %xmm2, %xmm0 148; SSE-NEXT: retq 149; 150; AVX1-LABEL: finite_f32_estimate_daz_ninf: 151; AVX1: # %bb.0: 152; AVX1-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 153; AVX1-NEXT: vmulss %xmm1, %xmm0, %xmm2 154; AVX1-NEXT: vmulss %xmm1, %xmm2, %xmm1 155; AVX1-NEXT: vaddss {{.*}}(%rip), %xmm1, %xmm1 156; AVX1-NEXT: vmulss {{.*}}(%rip), %xmm2, %xmm2 157; AVX1-NEXT: vmulss %xmm1, %xmm2, %xmm1 158; AVX1-NEXT: vxorps %xmm2, %xmm2, %xmm2 159; AVX1-NEXT: vcmpeqss %xmm2, %xmm0, %xmm0 160; AVX1-NEXT: vandnps %xmm1, %xmm0, %xmm0 161; AVX1-NEXT: retq 162; 163; AVX512-LABEL: finite_f32_estimate_daz_ninf: 164; AVX512: # %bb.0: 165; AVX512-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 166; AVX512-NEXT: vmulss %xmm1, %xmm0, %xmm2 167; AVX512-NEXT: vfmadd213ss {{.*#+}} xmm1 = (xmm2 * xmm1) + mem 168; AVX512-NEXT: vmulss {{.*}}(%rip), %xmm2, %xmm2 169; AVX512-NEXT: vmulss %xmm1, %xmm2, %xmm1 170; AVX512-NEXT: vxorps %xmm2, %xmm2, %xmm2 171; AVX512-NEXT: vcmpeqss %xmm2, %xmm0, %k1 172; AVX512-NEXT: vmovss %xmm2, %xmm1, %xmm1 {%k1} 173; AVX512-NEXT: vmovaps %xmm1, %xmm0 174; AVX512-NEXT: retq 175 %call = tail call ninf float @__sqrtf_finite(float %f) #2 176 ret float %call 177} 178 179define x86_fp80 @finite_f80_no_estimate(x86_fp80 %ld) #0 { 180; CHECK-LABEL: finite_f80_no_estimate: 181; CHECK: # %bb.0: 182; CHECK-NEXT: fldt {{[0-9]+}}(%rsp) 183; CHECK-NEXT: fsqrt 184; CHECK-NEXT: retq 185 %call = tail call x86_fp80 @__sqrtl_finite(x86_fp80 %ld) #2 186 ret x86_fp80 %call 187} 188 189; Don't die on the impossible. 190 191define x86_fp80 @finite_f80_estimate_but_no(x86_fp80 %ld) #1 { 192; CHECK-LABEL: finite_f80_estimate_but_no: 193; CHECK: # %bb.0: 194; CHECK-NEXT: fldt {{[0-9]+}}(%rsp) 195; CHECK-NEXT: fsqrt 196; CHECK-NEXT: retq 197 %call = tail call x86_fp80 @__sqrtl_finite(x86_fp80 %ld) #2 198 ret x86_fp80 %call 199} 200 201; PR34994 - https://bugs.llvm.org/show_bug.cgi?id=34994 202 203define float @sqrtf_check_denorms(float %x) #3 { 204; SSE-LABEL: sqrtf_check_denorms: 205; SSE: # %bb.0: 206; SSE-NEXT: sqrtss %xmm0, %xmm0 207; SSE-NEXT: retq 208; 209; AVX-LABEL: sqrtf_check_denorms: 210; AVX: # %bb.0: 211; AVX-NEXT: vsqrtss %xmm0, %xmm0, %xmm0 212; AVX-NEXT: retq 213 %call = tail call float @__sqrtf_finite(float %x) #2 214 ret float %call 215} 216 217define float @sqrtf_check_denorms_ninf(float %x) #3 { 218; SSE-LABEL: sqrtf_check_denorms_ninf: 219; SSE: # %bb.0: 220; SSE-NEXT: rsqrtss %xmm0, %xmm1 221; SSE-NEXT: movaps %xmm0, %xmm2 222; SSE-NEXT: mulss %xmm1, %xmm2 223; SSE-NEXT: movss {{.*#+}} xmm3 = mem[0],zero,zero,zero 224; SSE-NEXT: mulss %xmm2, %xmm3 225; SSE-NEXT: mulss %xmm1, %xmm2 226; SSE-NEXT: addss {{.*}}(%rip), %xmm2 227; SSE-NEXT: andps {{.*}}(%rip), %xmm0 228; SSE-NEXT: mulss %xmm3, %xmm2 229; SSE-NEXT: cmpltss {{.*}}(%rip), %xmm0 230; SSE-NEXT: andnps %xmm2, %xmm0 231; SSE-NEXT: retq 232; 233; AVX1-LABEL: sqrtf_check_denorms_ninf: 234; AVX1: # %bb.0: 235; AVX1-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 236; AVX1-NEXT: vmulss %xmm1, %xmm0, %xmm2 237; AVX1-NEXT: vmulss %xmm1, %xmm2, %xmm1 238; AVX1-NEXT: vaddss {{.*}}(%rip), %xmm1, %xmm1 239; AVX1-NEXT: vmulss {{.*}}(%rip), %xmm2, %xmm2 240; AVX1-NEXT: vandps {{.*}}(%rip), %xmm0, %xmm0 241; AVX1-NEXT: vmulss %xmm1, %xmm2, %xmm1 242; AVX1-NEXT: vcmpltss {{.*}}(%rip), %xmm0, %xmm0 243; AVX1-NEXT: vandnps %xmm1, %xmm0, %xmm0 244; AVX1-NEXT: retq 245; 246; AVX512-LABEL: sqrtf_check_denorms_ninf: 247; AVX512: # %bb.0: 248; AVX512-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 249; AVX512-NEXT: vmulss %xmm1, %xmm0, %xmm2 250; AVX512-NEXT: vfmadd213ss {{.*#+}} xmm1 = (xmm2 * xmm1) + mem 251; AVX512-NEXT: vmulss {{.*}}(%rip), %xmm2, %xmm2 252; AVX512-NEXT: vmulss %xmm1, %xmm2, %xmm1 253; AVX512-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN] 254; AVX512-NEXT: vandps %xmm2, %xmm0, %xmm0 255; AVX512-NEXT: vcmpltss {{.*}}(%rip), %xmm0, %k1 256; AVX512-NEXT: vxorps %xmm0, %xmm0, %xmm0 257; AVX512-NEXT: vmovss %xmm0, %xmm1, %xmm1 {%k1} 258; AVX512-NEXT: vmovaps %xmm1, %xmm0 259; AVX512-NEXT: retq 260 %call = tail call ninf float @__sqrtf_finite(float %x) #2 261 ret float %call 262} 263 264define <4 x float> @sqrt_v4f32_check_denorms(<4 x float> %x) #3 { 265; SSE-LABEL: sqrt_v4f32_check_denorms: 266; SSE: # %bb.0: 267; SSE-NEXT: sqrtps %xmm0, %xmm0 268; SSE-NEXT: retq 269; 270; AVX-LABEL: sqrt_v4f32_check_denorms: 271; AVX: # %bb.0: 272; AVX-NEXT: vsqrtps %xmm0, %xmm0 273; AVX-NEXT: retq 274 %call = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) #2 275 ret <4 x float> %call 276} 277 278define <4 x float> @sqrt_v4f32_check_denorms_ninf(<4 x float> %x) #3 { 279; SSE-LABEL: sqrt_v4f32_check_denorms_ninf: 280; SSE: # %bb.0: 281; SSE-NEXT: rsqrtps %xmm0, %xmm2 282; SSE-NEXT: movaps %xmm0, %xmm1 283; SSE-NEXT: mulps %xmm2, %xmm1 284; SSE-NEXT: movaps {{.*#+}} xmm3 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 285; SSE-NEXT: mulps %xmm1, %xmm3 286; SSE-NEXT: mulps %xmm2, %xmm1 287; SSE-NEXT: addps {{.*}}(%rip), %xmm1 288; SSE-NEXT: andps {{.*}}(%rip), %xmm0 289; SSE-NEXT: mulps %xmm3, %xmm1 290; SSE-NEXT: movaps {{.*#+}} xmm2 = [1.17549435E-38,1.17549435E-38,1.17549435E-38,1.17549435E-38] 291; SSE-NEXT: cmpleps %xmm0, %xmm2 292; SSE-NEXT: andps %xmm2, %xmm1 293; SSE-NEXT: movaps %xmm1, %xmm0 294; SSE-NEXT: retq 295; 296; AVX1-LABEL: sqrt_v4f32_check_denorms_ninf: 297; AVX1: # %bb.0: 298; AVX1-NEXT: vrsqrtps %xmm0, %xmm1 299; AVX1-NEXT: vmulps %xmm1, %xmm0, %xmm2 300; AVX1-NEXT: vmulps {{.*}}(%rip), %xmm2, %xmm3 301; AVX1-NEXT: vmulps %xmm1, %xmm2, %xmm1 302; AVX1-NEXT: vaddps {{.*}}(%rip), %xmm1, %xmm1 303; AVX1-NEXT: vandps {{.*}}(%rip), %xmm0, %xmm0 304; AVX1-NEXT: vmulps %xmm1, %xmm3, %xmm1 305; AVX1-NEXT: vmovaps {{.*#+}} xmm2 = [1.17549435E-38,1.17549435E-38,1.17549435E-38,1.17549435E-38] 306; AVX1-NEXT: vcmpleps %xmm0, %xmm2, %xmm0 307; AVX1-NEXT: vandps %xmm1, %xmm0, %xmm0 308; AVX1-NEXT: retq 309; 310; AVX512-LABEL: sqrt_v4f32_check_denorms_ninf: 311; AVX512: # %bb.0: 312; AVX512-NEXT: vrsqrtps %xmm0, %xmm1 313; AVX512-NEXT: vmulps %xmm1, %xmm0, %xmm2 314; AVX512-NEXT: vbroadcastss {{.*#+}} xmm3 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0] 315; AVX512-NEXT: vfmadd231ps {{.*#+}} xmm3 = (xmm2 * xmm1) + xmm3 316; AVX512-NEXT: vbroadcastss {{.*#+}} xmm1 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 317; AVX512-NEXT: vmulps %xmm1, %xmm2, %xmm1 318; AVX512-NEXT: vmulps %xmm3, %xmm1, %xmm1 319; AVX512-NEXT: vbroadcastss {{.*#+}} xmm2 = [NaN,NaN,NaN,NaN] 320; AVX512-NEXT: vandps %xmm2, %xmm0, %xmm0 321; AVX512-NEXT: vbroadcastss {{.*#+}} xmm2 = [1.17549435E-38,1.17549435E-38,1.17549435E-38,1.17549435E-38] 322; AVX512-NEXT: vcmpleps %xmm0, %xmm2, %xmm0 323; AVX512-NEXT: vandps %xmm1, %xmm0, %xmm0 324; AVX512-NEXT: retq 325 %call = tail call ninf <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) #2 326 ret <4 x float> %call 327} 328 329define float @f32_no_estimate(float %x) #0 { 330; SSE-LABEL: f32_no_estimate: 331; SSE: # %bb.0: 332; SSE-NEXT: sqrtss %xmm0, %xmm1 333; SSE-NEXT: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 334; SSE-NEXT: divss %xmm1, %xmm0 335; SSE-NEXT: retq 336; 337; AVX-LABEL: f32_no_estimate: 338; AVX: # %bb.0: 339; AVX-NEXT: vsqrtss %xmm0, %xmm0, %xmm0 340; AVX-NEXT: vmovss {{.*#+}} xmm1 = mem[0],zero,zero,zero 341; AVX-NEXT: vdivss %xmm0, %xmm1, %xmm0 342; AVX-NEXT: retq 343 %sqrt = tail call float @llvm.sqrt.f32(float %x) 344 %div = fdiv fast float 1.0, %sqrt 345 ret float %div 346} 347 348define float @f32_estimate(float %x) #1 { 349; SSE-LABEL: f32_estimate: 350; SSE: # %bb.0: 351; SSE-NEXT: rsqrtss %xmm0, %xmm1 352; SSE-NEXT: mulss %xmm1, %xmm0 353; SSE-NEXT: mulss %xmm1, %xmm0 354; SSE-NEXT: addss {{.*}}(%rip), %xmm0 355; SSE-NEXT: mulss {{.*}}(%rip), %xmm1 356; SSE-NEXT: mulss %xmm1, %xmm0 357; SSE-NEXT: retq 358; 359; AVX1-LABEL: f32_estimate: 360; AVX1: # %bb.0: 361; AVX1-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 362; AVX1-NEXT: vmulss %xmm1, %xmm0, %xmm0 363; AVX1-NEXT: vmulss %xmm1, %xmm0, %xmm0 364; AVX1-NEXT: vaddss {{.*}}(%rip), %xmm0, %xmm0 365; AVX1-NEXT: vmulss {{.*}}(%rip), %xmm1, %xmm1 366; AVX1-NEXT: vmulss %xmm0, %xmm1, %xmm0 367; AVX1-NEXT: retq 368; 369; AVX512-LABEL: f32_estimate: 370; AVX512: # %bb.0: 371; AVX512-NEXT: vrsqrtss %xmm0, %xmm0, %xmm1 372; AVX512-NEXT: vmulss %xmm1, %xmm0, %xmm0 373; AVX512-NEXT: vfmadd213ss {{.*#+}} xmm0 = (xmm1 * xmm0) + mem 374; AVX512-NEXT: vmulss {{.*}}(%rip), %xmm1, %xmm1 375; AVX512-NEXT: vmulss %xmm0, %xmm1, %xmm0 376; AVX512-NEXT: retq 377 %sqrt = tail call float @llvm.sqrt.f32(float %x) 378 %div = fdiv fast float 1.0, %sqrt 379 ret float %div 380} 381 382define <4 x float> @v4f32_no_estimate(<4 x float> %x) #0 { 383; SSE-LABEL: v4f32_no_estimate: 384; SSE: # %bb.0: 385; SSE-NEXT: sqrtps %xmm0, %xmm1 386; SSE-NEXT: movaps {{.*#+}} xmm0 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0] 387; SSE-NEXT: divps %xmm1, %xmm0 388; SSE-NEXT: retq 389; 390; AVX1-LABEL: v4f32_no_estimate: 391; AVX1: # %bb.0: 392; AVX1-NEXT: vsqrtps %xmm0, %xmm0 393; AVX1-NEXT: vmovaps {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0] 394; AVX1-NEXT: vdivps %xmm0, %xmm1, %xmm0 395; AVX1-NEXT: retq 396; 397; AVX512-LABEL: v4f32_no_estimate: 398; AVX512: # %bb.0: 399; AVX512-NEXT: vsqrtps %xmm0, %xmm0 400; AVX512-NEXT: vbroadcastss {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0] 401; AVX512-NEXT: vdivps %xmm0, %xmm1, %xmm0 402; AVX512-NEXT: retq 403 %sqrt = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 404 %div = fdiv fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt 405 ret <4 x float> %div 406} 407 408define <4 x float> @v4f32_estimate(<4 x float> %x) #1 { 409; SSE-LABEL: v4f32_estimate: 410; SSE: # %bb.0: 411; SSE-NEXT: rsqrtps %xmm0, %xmm1 412; SSE-NEXT: mulps %xmm1, %xmm0 413; SSE-NEXT: mulps %xmm1, %xmm0 414; SSE-NEXT: addps {{.*}}(%rip), %xmm0 415; SSE-NEXT: mulps {{.*}}(%rip), %xmm1 416; SSE-NEXT: mulps %xmm1, %xmm0 417; SSE-NEXT: retq 418; 419; AVX1-LABEL: v4f32_estimate: 420; AVX1: # %bb.0: 421; AVX1-NEXT: vrsqrtps %xmm0, %xmm1 422; AVX1-NEXT: vmulps %xmm1, %xmm0, %xmm0 423; AVX1-NEXT: vmulps %xmm1, %xmm0, %xmm0 424; AVX1-NEXT: vaddps {{.*}}(%rip), %xmm0, %xmm0 425; AVX1-NEXT: vmulps {{.*}}(%rip), %xmm1, %xmm1 426; AVX1-NEXT: vmulps %xmm0, %xmm1, %xmm0 427; AVX1-NEXT: retq 428; 429; AVX512-LABEL: v4f32_estimate: 430; AVX512: # %bb.0: 431; AVX512-NEXT: vrsqrtps %xmm0, %xmm1 432; AVX512-NEXT: vmulps %xmm1, %xmm0, %xmm0 433; AVX512-NEXT: vbroadcastss {{.*#+}} xmm2 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0] 434; AVX512-NEXT: vfmadd231ps {{.*#+}} xmm2 = (xmm1 * xmm0) + xmm2 435; AVX512-NEXT: vbroadcastss {{.*#+}} xmm0 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 436; AVX512-NEXT: vmulps %xmm0, %xmm1, %xmm0 437; AVX512-NEXT: vmulps %xmm2, %xmm0, %xmm0 438; AVX512-NEXT: retq 439 %sqrt = tail call <4 x float> @llvm.sqrt.v4f32(<4 x float> %x) 440 %div = fdiv fast <4 x float> <float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt 441 ret <4 x float> %div 442} 443 444define <8 x float> @v8f32_no_estimate(<8 x float> %x) #0 { 445; SSE-LABEL: v8f32_no_estimate: 446; SSE: # %bb.0: 447; SSE-NEXT: sqrtps %xmm1, %xmm2 448; SSE-NEXT: sqrtps %xmm0, %xmm3 449; SSE-NEXT: movaps {{.*#+}} xmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0] 450; SSE-NEXT: movaps %xmm1, %xmm0 451; SSE-NEXT: divps %xmm3, %xmm0 452; SSE-NEXT: divps %xmm2, %xmm1 453; SSE-NEXT: retq 454; 455; AVX1-LABEL: v8f32_no_estimate: 456; AVX1: # %bb.0: 457; AVX1-NEXT: vsqrtps %ymm0, %ymm0 458; AVX1-NEXT: vmovaps {{.*#+}} ymm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0] 459; AVX1-NEXT: vdivps %ymm0, %ymm1, %ymm0 460; AVX1-NEXT: retq 461; 462; AVX512-LABEL: v8f32_no_estimate: 463; AVX512: # %bb.0: 464; AVX512-NEXT: vsqrtps %ymm0, %ymm0 465; AVX512-NEXT: vbroadcastss {{.*#+}} ymm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0] 466; AVX512-NEXT: vdivps %ymm0, %ymm1, %ymm0 467; AVX512-NEXT: retq 468 %sqrt = tail call <8 x float> @llvm.sqrt.v8f32(<8 x float> %x) 469 %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt 470 ret <8 x float> %div 471} 472 473define <8 x float> @v8f32_estimate(<8 x float> %x) #1 { 474; SSE-LABEL: v8f32_estimate: 475; SSE: # %bb.0: 476; SSE-NEXT: rsqrtps %xmm0, %xmm2 477; SSE-NEXT: movaps {{.*#+}} xmm3 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 478; SSE-NEXT: mulps %xmm2, %xmm0 479; SSE-NEXT: mulps %xmm2, %xmm0 480; SSE-NEXT: mulps %xmm3, %xmm2 481; SSE-NEXT: movaps {{.*#+}} xmm4 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0] 482; SSE-NEXT: addps %xmm4, %xmm0 483; SSE-NEXT: mulps %xmm2, %xmm0 484; SSE-NEXT: rsqrtps %xmm1, %xmm2 485; SSE-NEXT: mulps %xmm2, %xmm3 486; SSE-NEXT: mulps %xmm2, %xmm1 487; SSE-NEXT: mulps %xmm2, %xmm1 488; SSE-NEXT: addps %xmm4, %xmm1 489; SSE-NEXT: mulps %xmm3, %xmm1 490; SSE-NEXT: retq 491; 492; AVX1-LABEL: v8f32_estimate: 493; AVX1: # %bb.0: 494; AVX1-NEXT: vrsqrtps %ymm0, %ymm1 495; AVX1-NEXT: vmulps %ymm1, %ymm0, %ymm0 496; AVX1-NEXT: vmulps %ymm1, %ymm0, %ymm0 497; AVX1-NEXT: vaddps {{.*}}(%rip), %ymm0, %ymm0 498; AVX1-NEXT: vmulps {{.*}}(%rip), %ymm1, %ymm1 499; AVX1-NEXT: vmulps %ymm0, %ymm1, %ymm0 500; AVX1-NEXT: retq 501; 502; AVX512-LABEL: v8f32_estimate: 503; AVX512: # %bb.0: 504; AVX512-NEXT: vrsqrtps %ymm0, %ymm1 505; AVX512-NEXT: vmulps %ymm1, %ymm0, %ymm0 506; AVX512-NEXT: vbroadcastss {{.*#+}} ymm2 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0] 507; AVX512-NEXT: vfmadd231ps {{.*#+}} ymm2 = (ymm1 * ymm0) + ymm2 508; AVX512-NEXT: vbroadcastss {{.*#+}} ymm0 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 509; AVX512-NEXT: vmulps %ymm0, %ymm1, %ymm0 510; AVX512-NEXT: vmulps %ymm2, %ymm0, %ymm0 511; AVX512-NEXT: retq 512 %sqrt = tail call <8 x float> @llvm.sqrt.v8f32(<8 x float> %x) 513 %div = fdiv fast <8 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt 514 ret <8 x float> %div 515} 516 517define <16 x float> @v16f32_no_estimate(<16 x float> %x) #0 { 518; SSE-LABEL: v16f32_no_estimate: 519; SSE: # %bb.0: 520; SSE-NEXT: sqrtps %xmm3, %xmm4 521; SSE-NEXT: sqrtps %xmm2, %xmm5 522; SSE-NEXT: sqrtps %xmm1, %xmm2 523; SSE-NEXT: sqrtps %xmm0, %xmm1 524; SSE-NEXT: movaps {{.*#+}} xmm3 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0] 525; SSE-NEXT: movaps %xmm3, %xmm0 526; SSE-NEXT: divps %xmm1, %xmm0 527; SSE-NEXT: movaps %xmm3, %xmm1 528; SSE-NEXT: divps %xmm2, %xmm1 529; SSE-NEXT: movaps %xmm3, %xmm2 530; SSE-NEXT: divps %xmm5, %xmm2 531; SSE-NEXT: divps %xmm4, %xmm3 532; SSE-NEXT: retq 533; 534; AVX1-LABEL: v16f32_no_estimate: 535; AVX1: # %bb.0: 536; AVX1-NEXT: vsqrtps %ymm1, %ymm1 537; AVX1-NEXT: vsqrtps %ymm0, %ymm0 538; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0] 539; AVX1-NEXT: vdivps %ymm0, %ymm2, %ymm0 540; AVX1-NEXT: vdivps %ymm1, %ymm2, %ymm1 541; AVX1-NEXT: retq 542; 543; AVX512-LABEL: v16f32_no_estimate: 544; AVX512: # %bb.0: 545; AVX512-NEXT: vsqrtps %zmm0, %zmm0 546; AVX512-NEXT: vbroadcastss {{.*#+}} zmm1 = [1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0,1.0E+0] 547; AVX512-NEXT: vdivps %zmm0, %zmm1, %zmm0 548; AVX512-NEXT: retq 549 %sqrt = tail call <16 x float> @llvm.sqrt.v16f32(<16 x float> %x) 550 %div = fdiv fast <16 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt 551 ret <16 x float> %div 552} 553 554define <16 x float> @v16f32_estimate(<16 x float> %x) #1 { 555; SSE-LABEL: v16f32_estimate: 556; SSE: # %bb.0: 557; SSE-NEXT: rsqrtps %xmm0, %xmm5 558; SSE-NEXT: movaps {{.*#+}} xmm4 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 559; SSE-NEXT: mulps %xmm5, %xmm0 560; SSE-NEXT: mulps %xmm5, %xmm0 561; SSE-NEXT: movaps %xmm5, %xmm6 562; SSE-NEXT: mulps %xmm4, %xmm6 563; SSE-NEXT: movaps {{.*#+}} xmm5 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0] 564; SSE-NEXT: addps %xmm5, %xmm0 565; SSE-NEXT: mulps %xmm6, %xmm0 566; SSE-NEXT: rsqrtps %xmm1, %xmm6 567; SSE-NEXT: mulps %xmm6, %xmm1 568; SSE-NEXT: mulps %xmm6, %xmm1 569; SSE-NEXT: mulps %xmm4, %xmm6 570; SSE-NEXT: addps %xmm5, %xmm1 571; SSE-NEXT: mulps %xmm6, %xmm1 572; SSE-NEXT: rsqrtps %xmm2, %xmm6 573; SSE-NEXT: mulps %xmm6, %xmm2 574; SSE-NEXT: mulps %xmm6, %xmm2 575; SSE-NEXT: mulps %xmm4, %xmm6 576; SSE-NEXT: addps %xmm5, %xmm2 577; SSE-NEXT: mulps %xmm6, %xmm2 578; SSE-NEXT: rsqrtps %xmm3, %xmm6 579; SSE-NEXT: mulps %xmm6, %xmm4 580; SSE-NEXT: mulps %xmm6, %xmm3 581; SSE-NEXT: mulps %xmm6, %xmm3 582; SSE-NEXT: addps %xmm5, %xmm3 583; SSE-NEXT: mulps %xmm4, %xmm3 584; SSE-NEXT: retq 585; 586; AVX1-LABEL: v16f32_estimate: 587; AVX1: # %bb.0: 588; AVX1-NEXT: vrsqrtps %ymm0, %ymm2 589; AVX1-NEXT: vmovaps {{.*#+}} ymm3 = [-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1,-5.0E-1] 590; AVX1-NEXT: vmulps %ymm3, %ymm2, %ymm4 591; AVX1-NEXT: vmulps %ymm2, %ymm0, %ymm0 592; AVX1-NEXT: vmulps %ymm2, %ymm0, %ymm0 593; AVX1-NEXT: vmovaps {{.*#+}} ymm2 = [-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0,-3.0E+0] 594; AVX1-NEXT: vaddps %ymm2, %ymm0, %ymm0 595; AVX1-NEXT: vmulps %ymm0, %ymm4, %ymm0 596; AVX1-NEXT: vrsqrtps %ymm1, %ymm4 597; AVX1-NEXT: vmulps %ymm3, %ymm4, %ymm3 598; AVX1-NEXT: vmulps %ymm4, %ymm1, %ymm1 599; AVX1-NEXT: vmulps %ymm4, %ymm1, %ymm1 600; AVX1-NEXT: vaddps %ymm2, %ymm1, %ymm1 601; AVX1-NEXT: vmulps %ymm1, %ymm3, %ymm1 602; AVX1-NEXT: retq 603; 604; AVX512-LABEL: v16f32_estimate: 605; AVX512: # %bb.0: 606; AVX512-NEXT: vrsqrt14ps %zmm0, %zmm1 607; AVX512-NEXT: vmulps %zmm1, %zmm0, %zmm0 608; AVX512-NEXT: vfmadd213ps {{.*#+}} zmm0 = (zmm1 * zmm0) + mem 609; AVX512-NEXT: vmulps {{.*}}(%rip){1to16}, %zmm1, %zmm1 610; AVX512-NEXT: vmulps %zmm0, %zmm1, %zmm0 611; AVX512-NEXT: retq 612 %sqrt = tail call <16 x float> @llvm.sqrt.v16f32(<16 x float> %x) 613 %div = fdiv fast <16 x float> <float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0, float 1.0>, %sqrt 614 ret <16 x float> %div 615} 616 617 618attributes #0 = { "unsafe-fp-math"="true" "reciprocal-estimates"="!sqrtf,!vec-sqrtf,!divf,!vec-divf" } 619attributes #1 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" } 620attributes #2 = { nounwind readnone } 621attributes #3 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" "denormal-fp-math"="ieee" } 622attributes #4 = { "unsafe-fp-math"="true" "reciprocal-estimates"="sqrt,vec-sqrt" "denormal-fp-math"="ieee,preserve-sign" } 623