void givens(x, y, c, s) double x, y;
double *c, *s;
{
  double norm;
  norm = sqrt(x * x + y * y);
  if (norm == 0.0) {
    *c = 1.0;
    *s = 0.0;
  } else {
    *c = x / norm;
    *s = y / norm;
  }
}


x86 assembly (clang, -O0):
<givens>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x8(%rbp)
movsd  %xmm1,-0x10(%rbp)
mov    %rdi,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
movsd  -0x8(%rbp),%xmm0
movsd  -0x8(%rbp),%xmm2
movsd  -0x10(%rbp),%xmm1
mulsd  -0x10(%rbp),%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
call   1030 <sqrt@plt>
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1188 <givens+0x78>
jp     1188 <givens+0x78>
mov    -0x18(%rbp),%rax
movsd  0xe8c(%rip),%xmm0
movsd  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax)
jmp    11ac <givens+0x9c>
movsd  -0x8(%rbp),%xmm0
divsd  -0x28(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x10(%rbp),%xmm0
divsd  -0x28(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movsd  %xmm0,(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<givens>:
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %rsi,%r14
mov    %rdi,%rbx
movapd %xmm0,%xmm3
movapd %xmm1,%xmm2
mulsd  %xmm1,%xmm2
mulsd  %xmm0,%xmm0
addsd  %xmm2,%xmm0
xorpd  %xmm2,%xmm2
ucomisd %xmm2,%xmm0
jb     1141 <givens+0x31>
sqrtsd %xmm0,%xmm0
jmp    1162 <givens+0x52>
movsd  %xmm1,0x10(%rsp)
movsd  %xmm3,0x8(%rsp)
call   1030 <sqrt@plt>
xorpd  %xmm2,%xmm2
movsd  0x8(%rsp),%xmm3
movsd  0x10(%rsp),%xmm1
ucomisd %xmm2,%xmm0
jne    117d <givens+0x6d>
jp     117d <givens+0x6d>
movabs $0x3ff0000000000000,%rax
mov    %rax,(%rbx)
xorpd  %xmm1,%xmm1
jmp    1189 <givens+0x79>
divsd  %xmm0,%xmm3
movsd  %xmm3,(%rbx)
divsd  %xmm0,%xmm1
movsd  %xmm1,(%r14)
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define void @givens(double %0, double %1, double* %2, double* %3) {
%5 = alloca double
%6 = alloca double
%7 = alloca double*
%8 = alloca double*
%9 = alloca double
store double %0, double* %5
store double %1, double* %6
store double* %2, double** %7
store double* %3, double** %8
%10 = load double, double* %5
%11 = load double, double* %5
%12 = load double, double* %6
%13 = load double, double* %6
%14 = fmul double %12, %13
%15 = call double @llvm.fmuladd.f64(double %10, double %11, double %14)
%16 = call double @sqrt(double %15)
store double %16, double* %9
%17 = load double, double* %9
%18 = fcmp oeq double %17, 0.000000e+00
br i1 %18, label %19, label %22
19: ; preds = %4
%20 = load double*, double** %7
store double 1.000000e+00, double* %20
%21 = load double*, double** %8
store double 0.000000e+00, double* %21
br label %31
22: ; preds = %4
%23 = load double, double* %5
%24 = load double, double* %9
%25 = fdiv double %23, %24
%26 = load double*, double** %7
store double %25, double* %26
%27 = load double, double* %6
%28 = load double, double* %9
%29 = fdiv double %27, %28
%30 = load double*, double** %8
store double %29, double* %30
br label %31
31: ; preds = %22, %19
ret void
}

LLVM IR (-O2):
define void @givens(double %0, double %1, double* nocapture writeonly %2, double* nocapture writeonly %3) {
%5 = fmul double %1, %1
%6 = tail call double @llvm.fmuladd.f64(double %0, double %0, double %5)
%7 = tail call double @sqrt(double %6)
%8 = fcmp oeq double %7, 0.000000e+00
br i1 %8, label %9, label %10
9: ; preds = %4
store double 1.000000e+00, double* %2
br label %13
10: ; preds = %4
%11 = fdiv double %0, %7
store double %11, double* %2
%12 = fdiv double %1, %7
br label %13
13: ; preds = %10, %9
%14 = phi double [ %12, %10 ], [ 0.000000e+00, %9 ]
store double %14, double* %3
ret void
}