1; RUN: llc < %s -mtriple=i686-unknown -mattr=+sse2 | FileCheck %s --check-prefix=ALL --check-prefix=X32 2; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+sse2 | FileCheck %s --check-prefix=ALL --check-prefix=X64 3 4; 5; Library Functions 6; 7 8define float @tst1(float %a, float %b) { 9; X32-LABEL: @tst1 10; X32: movss {{.*#+}} xmm0 = mem[0],zero,zero,zero 11; X32-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 12; X32-NEXT: movss %xmm1, 4(%esp) 13; X32-NEXT: movss %xmm0, (%esp) 14; X32-NEXT: calll copysignf 15; X32-NEXT: addl $8, %esp 16; X32-NEXT: retl 17; 18; X64-LABEL: @tst1 19; X64: movaps %xmm0, %xmm2 20; X64-NEXT: movaps %xmm1, %xmm0 21; X64-NEXT: movaps %xmm2, %xmm1 22; X64-NEXT: jmp copysignf 23 %tmp = tail call float @copysignf( float %b, float %a ) 24 ret float %tmp 25} 26 27define double @tst2(double %a, float %b, float %c) { 28; X32-LABEL: @tst2 29; X32: movsd {{.*#+}} xmm0 = mem[0],zero 30; X32-NEXT: movss {{.*#+}} xmm1 = mem[0],zero,zero,zero 31; X32-NEXT: addss 32(%esp), %xmm1 32; X32-NEXT: cvtss2sd %xmm1, %xmm1 33; X32-NEXT: movsd %xmm0, (%esp) 34; X32-NEXT: movsd %xmm1, 8(%esp) 35; X32-NEXT: calll copysign 36; X32-NEXT: addl $16, %esp 37; X32-NEXT: retl 38; 39; X64-LABEL: @tst2 40; X64: addss %xmm2, %xmm1 41; X64-NEXT: cvtss2sd %xmm1, %xmm1 42; X64-NEXT: jmp copysign 43 %tmp1 = fadd float %b, %c 44 %tmp2 = fpext float %tmp1 to double 45 %tmp = tail call double @copysign( double %a, double %tmp2 ) 46 ret double %tmp 47} 48 49declare float @copysignf(float, float) 50declare double @copysign(double, double) 51 52; 53; LLVM Intrinsic 54; 55 56define float @int1(float %a, float %b) { 57; X32-LABEL: @int1 58; X32: movss 8(%esp), %xmm0 {{.*#+}} xmm0 = mem[0],zero,zero,zero 59; X32-NEXT: andps .LCPI2_0, %xmm0 60; X32-NEXT: movss 12(%esp), %xmm1 {{.*#+}} xmm1 = mem[0],zero,zero,zero 61; X32-NEXT: andps .LCPI2_1, %xmm1 62; X32-NEXT: orps %xmm0, %xmm1 63; X32-NEXT: movss %xmm1, (%esp) 64; X32-NEXT: flds (%esp) 65; X32-NEXT: popl %eax 66; X32-NEXT: retl 67; 68; X64-LABEL: @int1 69; X64: andps .LCPI2_0(%rip), %xmm0 70; X64-NEXT: andps .LCPI2_1(%rip), %xmm1 71; X64-NEXT: orps %xmm1, %xmm0 72; X64-NEXT: retq 73 %tmp = tail call float @llvm.copysign.f32( float %b, float %a ) 74 ret float %tmp 75} 76 77define double @int2(double %a, float %b, float %c) { 78; X32-LABEL: @int2 79; X32: movss 16(%ebp), %xmm0 {{.*#+}} xmm0 = mem[0],zero,zero,zero 80; X32-NEXT: addss 20(%ebp), %xmm0 81; X32-NEXT: movsd 8(%ebp), %xmm1 {{.*#+}} xmm1 = mem[0],zero 82; X32-NEXT: andpd .LCPI3_0, %xmm1 83; X32-NEXT: cvtss2sd %xmm0, %xmm0 84; X32-NEXT: andpd .LCPI3_1, %xmm0 85; X32-NEXT: orpd %xmm1, %xmm0 86; X32-NEXT: movlpd %xmm0, (%esp) 87; X32-NEXT: fldl (%esp) 88; X32-NEXT: movl %ebp, %esp 89; X32-NEXT: popl %ebp 90; X32-NEXT: retl 91; 92; X64-LABEL: @int2 93; X64: addss %xmm2, %xmm1 94; X64-NEXT: cvtss2sd %xmm1, %xmm1 95; X64-NEXT: andpd .LCPI3_0(%rip), %xmm1 96; X64-NEXT: andpd .LCPI3_1(%rip), %xmm0 97; X64-NEXT: orpd %xmm1, %xmm0 98; X64-NEXT: retq 99 %tmp1 = fadd float %b, %c 100 %tmp2 = fpext float %tmp1 to double 101 %tmp = tail call double @llvm.copysign.f64( double %a, double %tmp2 ) 102 ret double %tmp 103} 104 105define float @cst1() { 106; X32-LABEL: @cst1 107; X32: fld1 108; X32-NEXT: fchs 109; X32-NEXT: retl 110; 111; X64-LABEL: @cst1 112; X64: movss .LCPI4_0(%rip), %xmm0 {{.*#+}} xmm0 = mem[0],zero,zero,zero 113; X64-NEXT: retq 114 %tmp = tail call float @llvm.copysign.f32( float 1.0, float -2.0 ) 115 ret float %tmp 116} 117 118define double @cst2() { 119; X32-LABEL: @cst2 120; X32: fldz 121; X32-NEXT: fchs 122; X32-NEXT: retl 123; 124; X64-LABEL: @cst2 125; X64: movsd .LCPI5_0(%rip), %xmm0 {{.*#+}} xmm0 = mem[0],zero 126; X64-NEXT: retq 127 %tmp1 = fadd float -1.0, -1.0 128 %tmp2 = fpext float %tmp1 to double 129 %tmp = tail call double @llvm.copysign.f64( double 0.0, double %tmp2 ) 130 ret double %tmp 131} 132 133declare float @llvm.copysign.f32(float %Mag, float %Sgn) 134declare double @llvm.copysign.f64(double %Mag, double %Sgn) 135