1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=x86_64-- -mcpu=x86-64 | FileCheck %s -check-prefix=X64 3; RUN: llc < %s -mtriple=i686-unknown | FileCheck %s -check-prefix=X86 4 5declare float @llvm.sqrt.f32(float %x); 6 7define float @fast_recip_sqrt(float %x) { 8; X64-LABEL: fast_recip_sqrt: 9; X64: # %bb.0: 10; X64-NEXT: rsqrtss %xmm0, %xmm1 11; X64-NEXT: mulss %xmm1, %xmm0 12; X64-NEXT: mulss %xmm1, %xmm0 13; X64-NEXT: addss {{.*}}(%rip), %xmm0 14; X64-NEXT: mulss {{.*}}(%rip), %xmm1 15; X64-NEXT: mulss %xmm1, %xmm0 16; X64-NEXT: retq 17; 18; X86-LABEL: fast_recip_sqrt: 19; X86: # %bb.0: 20; X86-NEXT: flds {{[0-9]+}}(%esp) 21; X86-NEXT: fsqrt 22; X86-NEXT: fld1 23; X86-NEXT: fdivp %st, %st(1) 24; X86-NEXT: retl 25 %y = call fast float @llvm.sqrt.f32(float %x) 26 %z = fdiv fast float 1.0, %y 27 ret float %z 28} 29 30declare float @llvm.fmuladd.f32(float %a, float %b, float %c); 31 32define float @fast_fmuladd_opts(float %a , float %b , float %c) { 33; X64-LABEL: fast_fmuladd_opts: 34; X64: # %bb.0: 35; X64-NEXT: mulss {{.*}}(%rip), %xmm0 36; X64-NEXT: retq 37; 38; X86-LABEL: fast_fmuladd_opts: 39; X86: # %bb.0: 40; X86-NEXT: flds {{[0-9]+}}(%esp) 41; X86-NEXT: fmuls {{\.LCPI.*}} 42; X86-NEXT: retl 43 %res = call fast float @llvm.fmuladd.f32(float %a, float 2.0, float %a) 44 ret float %res 45} 46 47; The multiply is strict. 48 49@mul1 = common global double 0.000000e+00, align 4 50 51define double @not_so_fast_mul_add(double %x) { 52; X64-LABEL: not_so_fast_mul_add: 53; X64: # %bb.0: 54; X64-NEXT: movsd {{.*#+}} xmm1 = mem[0],zero 55; X64-NEXT: mulsd %xmm0, %xmm1 56; X64-NEXT: mulsd {{.*}}(%rip), %xmm0 57; X64-NEXT: movsd %xmm1, {{.*}}(%rip) 58; X64-NEXT: retq 59; 60; X86-LABEL: not_so_fast_mul_add: 61; X86: # %bb.0: 62; X86-NEXT: fldl {{[0-9]+}}(%esp) 63; X86-NEXT: fld %st(0) 64; X86-NEXT: fmull {{\.LCPI.*}} 65; X86-NEXT: fxch %st(1) 66; X86-NEXT: fmull {{\.LCPI.*}} 67; X86-NEXT: fxch %st(1) 68; X86-NEXT: fstpl mul1 69; X86-NEXT: retl 70 %m = fmul double %x, 4.2 71 %a = fadd fast double %m, %x 72 store double %m, double* @mul1, align 4 73 ret double %a 74} 75 76; The sqrt is strict. 77 78@sqrt1 = common global float 0.000000e+00, align 4 79 80define float @not_so_fast_recip_sqrt(float %x) { 81; X64-LABEL: not_so_fast_recip_sqrt: 82; X64: # %bb.0: 83; X64-NEXT: rsqrtss %xmm0, %xmm1 84; X64-NEXT: sqrtss %xmm0, %xmm2 85; X64-NEXT: mulss %xmm1, %xmm0 86; X64-NEXT: mulss %xmm1, %xmm0 87; X64-NEXT: addss {{.*}}(%rip), %xmm0 88; X64-NEXT: mulss {{.*}}(%rip), %xmm1 89; X64-NEXT: mulss %xmm1, %xmm0 90; X64-NEXT: movss %xmm2, {{.*}}(%rip) 91; X64-NEXT: retq 92; 93; X86-LABEL: not_so_fast_recip_sqrt: 94; X86: # %bb.0: 95; X86-NEXT: flds {{[0-9]+}}(%esp) 96; X86-NEXT: fsqrt 97; X86-NEXT: fld1 98; X86-NEXT: fdiv %st(1), %st 99; X86-NEXT: fxch %st(1) 100; X86-NEXT: fstps sqrt1 101; X86-NEXT: retl 102 %y = call float @llvm.sqrt.f32(float %x) 103 %z = fdiv fast float 1.0, %y 104 store float %y, float* @sqrt1, align 4 105 %ret = fadd float %z , 14.5 106 ret float %z 107} 108 109define float @div_arcp_by_const(half %x) { 110; X64-LABEL: div_arcp_by_const: 111; X64: # %bb.0: 112; X64-NEXT: pushq %rax 113; X64-NEXT: .cfi_def_cfa_offset 16 114; X64-NEXT: movzwl %di, %edi 115; X64-NEXT: callq __gnu_h2f_ieee 116; X64-NEXT: mulss {{.*}}(%rip), %xmm0 117; X64-NEXT: callq __gnu_f2h_ieee 118; X64-NEXT: movzwl %ax, %edi 119; X64-NEXT: popq %rax 120; X64-NEXT: .cfi_def_cfa_offset 8 121; X64-NEXT: jmp __gnu_h2f_ieee@PLT # TAILCALL 122; 123; X86-LABEL: div_arcp_by_const: 124; X86: # %bb.0: 125; X86-NEXT: pushl %eax 126; X86-NEXT: .cfi_def_cfa_offset 8 127; X86-NEXT: movzwl {{[0-9]+}}(%esp), %eax 128; X86-NEXT: movl %eax, (%esp) 129; X86-NEXT: calll __gnu_h2f_ieee 130; X86-NEXT: fmuls {{\.LCPI.*}} 131; X86-NEXT: fstps (%esp) 132; X86-NEXT: calll __gnu_f2h_ieee 133; X86-NEXT: movzwl %ax, %eax 134; X86-NEXT: movl %eax, (%esp) 135; X86-NEXT: calll __gnu_h2f_ieee 136; X86-NEXT: popl %eax 137; X86-NEXT: .cfi_def_cfa_offset 4 138; X86-NEXT: retl 139 %rcp = fdiv arcp half %x, 10.0 140 %z = fpext half %rcp to float 141 ret float %z 142} 143