#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
double sqrt(double);
void QUADROOTS(double p[], double r[][5]) {
  double b, c, d;
  b = -p[1] / (2.0 * p[0]);
  c = p[2] / p[0];
  d = b * b - c;
  if (d >= 0.0) {
    if (b > 0.0)
      b = (r[1][2] = (sqrt(d) + b));
    else
      b = (r[1][2] = (-sqrt(d) + b));
    r[1][1] = c / b;
    r[2][1] = (r[2][2] = 0.0);
  } else {
    d = (r[2][1] = sqrt(-d));
    r[2][2] = -d;
    r[1][1] = (r[1][2] = b);
  }
  return;
}


x86 assembly (clang, -O0):
<QUADROOTS>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x8(%rax),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    -0x8(%rbp),%rax
movsd  0xeb4(%rip),%xmm1
mulsd  (%rax),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movsd  0x10(%rax),%xmm0
mov    -0x8(%rbp),%rax
divsd  (%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm2
movsd  -0x20(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     124c <QUADROOTS+0x13c>
movsd  -0x18(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jbe    11e8 <QUADROOTS+0xd8>
movsd  -0x28(%rbp),%xmm0
call   1030 <sqrt@plt>
addsd  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
movsd  %xmm0,-0x18(%rbp)
jmp    121c <QUADROOTS+0x10c>
movsd  -0x28(%rbp),%xmm0
call   1030 <sqrt@plt>
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
addsd  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
movsd  %xmm0,-0x18(%rbp)
movsd  -0x20(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x30(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x60(%rax)
mov    -0x10(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,0x58(%rax)
jmp    12b7 <QUADROOTS+0x1a7>
movsd  -0x28(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
call   1030 <sqrt@plt>
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x58(%rax)
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x60(%rax)
movsd  -0x18(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x38(%rax)
mov    -0x10(%rbp),%rax
movsd  %xmm0,0x30(%rax)
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<QUADROOTS>:
push   %rbx
sub    $0x20,%rsp
mov    %rsi,%rbx
movsd  0x8(%rdi),%xmm3
xorpd  0xedb(%rip),%xmm3
movsd  (%rdi),%xmm0
movsd  0x10(%rdi),%xmm4
divsd  %xmm0,%xmm4
addsd  %xmm0,%xmm0
divsd  %xmm0,%xmm3
movapd %xmm3,%xmm0
mulsd  %xmm3,%xmm0
subsd  %xmm4,%xmm0
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jae    1173 <QUADROOTS+0x63>
movapd 0xea8(%rip),%xmm1
xorpd  %xmm0,%xmm1
movsd  0xeac(%rip),%xmm2
ucomisd %xmm0,%xmm2
jb     117b <QUADROOTS+0x6b>
xorps  %xmm0,%xmm0
sqrtsd %xmm1,%xmm0
jmp    118e <QUADROOTS+0x7e>
jb     11ac <QUADROOTS+0x9c>
sqrtsd %xmm0,%xmm0
jmp    11c7 <QUADROOTS+0xb7>
movapd %xmm1,%xmm0
movapd %xmm3,(%rsp)
call   1030 <sqrt@plt>
movapd (%rsp),%xmm3
movsd  %xmm0,0x58(%rbx)
xorpd  0xe65(%rip),%xmm0
movlpd %xmm0,0x60(%rbx)
movsd  %xmm3,0x38(%rbx)
movsd  %xmm3,0x30(%rbx)
jmp    1203 <QUADROOTS+0xf3>
movapd %xmm3,(%rsp)
movsd  %xmm4,0x18(%rsp)
call   1030 <sqrt@plt>
movsd  0x18(%rsp),%xmm4
movapd (%rsp),%xmm3
movapd 0xe31(%rip),%xmm1
xorpd  %xmm0,%xmm1
xorpd  %xmm2,%xmm2
cmpltsd %xmm3,%xmm2
andpd  %xmm2,%xmm0
andnpd %xmm1,%xmm2
orpd   %xmm0,%xmm2
addsd  %xmm3,%xmm2
movsd  %xmm2,0x38(%rbx)
divsd  %xmm2,%xmm4
movsd  %xmm4,0x30(%rbx)
xorpd  %xmm0,%xmm0
movupd %xmm0,0x58(%rbx)
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define void @QUADROOTS(double* %0, [5 x double]* %1) {
%3 = alloca double*
%4 = alloca [5 x double]*
%5 = alloca double
%6 = alloca double
%7 = alloca double
store double* %0, double** %3
store [5 x double]* %1, [5 x double]** %4
%8 = load double*, double** %3
%9 = getelementptr inbounds double, double* %8, i64 1
%10 = load double, double* %9
%11 = fneg double %10
%12 = load double*, double** %3
%13 = getelementptr inbounds double, double* %12, i64 0
%14 = load double, double* %13
%15 = fmul double 2.000000e+00, %14
%16 = fdiv double %11, %15
store double %16, double* %5
%17 = load double*, double** %3
%18 = getelementptr inbounds double, double* %17, i64 2
%19 = load double, double* %18
%20 = load double*, double** %3
%21 = getelementptr inbounds double, double* %20, i64 0
%22 = load double, double* %21
%23 = fdiv double %19, %22
store double %23, double* %6
%24 = load double, double* %5
%25 = load double, double* %5
%26 = load double, double* %6
%27 = fneg double %26
%28 = call double @llvm.fmuladd.f64(double %24, double %25, double %27)
store double %28, double* %7
%29 = load double, double* %7
%30 = fcmp oge double %29, 0.000000e+00
br i1 %30, label %31, label %64
31: ; preds = %2
%32 = load double, double* %5
%33 = fcmp ogt double %32, 0.000000e+00
br i1 %33, label %34, label %42
34: ; preds = %31
%35 = load double, double* %7
%36 = call double @sqrt(double %35)
%37 = load double, double* %5
%38 = fadd double %36, %37
%39 = load [5 x double]*, [5 x double]** %4
%40 = getelementptr inbounds [5 x double], [5 x double]* %39, i64 1
%41 = getelementptr inbounds [5 x double], [5 x double]* %40, i64 0, i64 2
store double %38, double* %41
store double %38, double* %5
br label %51
42: ; preds = %31
%43 = load double, double* %7
%44 = call double @sqrt(double %43)
%45 = fneg double %44
%46 = load double, double* %5
%47 = fadd double %45, %46
%48 = load [5 x double]*, [5 x double]** %4
%49 = getelementptr inbounds [5 x double], [5 x double]* %48, i64 1
%50 = getelementptr inbounds [5 x double], [5 x double]* %49, i64 0, i64 2
store double %47, double* %50
store double %47, double* %5
br label %51
51: ; preds = %42, %34
%52 = load double, double* %6
%53 = load double, double* %5
%54 = fdiv double %52, %53
%55 = load [5 x double]*, [5 x double]** %4
%56 = getelementptr inbounds [5 x double], [5 x double]* %55, i64 1
%57 = getelementptr inbounds [5 x double], [5 x double]* %56, i64 0, i64 1
store double %54, double* %57
%58 = load [5 x double]*, [5 x double]** %4
%59 = getelementptr inbounds [5 x double], [5 x double]* %58, i64 2
%60 = getelementptr inbounds [5 x double], [5 x double]* %59, i64 0, i64 2
store double 0.000000e+00, double* %60
%61 = load [5 x double]*, [5 x double]** %4
%62 = getelementptr inbounds [5 x double], [5 x double]* %61, i64 2
%63 = getelementptr inbounds [5 x double], [5 x double]* %62, i64 0, i64 1
store double 0.000000e+00, double* %63
br label %83
64: ; preds = %2
%65 = load double, double* %7
%66 = fneg double %65
%67 = call double @sqrt(double %66)
%68 = load [5 x double]*, [5 x double]** %4
%69 = getelementptr inbounds [5 x double], [5 x double]* %68, i64 2
%70 = getelementptr inbounds [5 x double], [5 x double]* %69, i64 0, i64 1
store double %67, double* %70
store double %67, double* %7
%71 = load double, double* %7
%72 = fneg double %71
%73 = load [5 x double]*, [5 x double]** %4
%74 = getelementptr inbounds [5 x double], [5 x double]* %73, i64 2
%75 = getelementptr inbounds [5 x double], [5 x double]* %74, i64 0, i64 2
store double %72, double* %75
%76 = load double, double* %5
%77 = load [5 x double]*, [5 x double]** %4
%78 = getelementptr inbounds [5 x double], [5 x double]* %77, i64 1
%79 = getelementptr inbounds [5 x double], [5 x double]* %78, i64 0, i64 2
store double %76, double* %79
%80 = load [5 x double]*, [5 x double]** %4
%81 = getelementptr inbounds [5 x double], [5 x double]* %80, i64 1
%82 = getelementptr inbounds [5 x double], [5 x double]* %81, i64 0, i64 1
store double %76, double* %82
br label %83
83: ; preds = %64, %51
ret void
}

LLVM IR (-O2):
define void @QUADROOTS(double* nocapture %0, [5 x double]* nocapture writeonly %1) {
%3 = getelementptr inbounds double, double* %0, i64 1
%4 = load double, double* %3
%5 = fneg double %4
%6 = load double, double* %0
%7 = fmul double %6, 2.000000e+00
%8 = fdiv double %5, %7
%9 = getelementptr inbounds double, double* %0, i64 2
%10 = load double, double* %9
%11 = fdiv double %10, %6
%12 = fneg double %11
%13 = tail call double @llvm.fmuladd.f64(double %8, double %8, double %12)
%14 = fcmp ult double %13, 0.000000e+00
br i1 %14, label %26, label %15
15: ; preds = %2
%16 = fcmp ogt double %8, 0.000000e+00
%17 = tail call double @sqrt(double %13)
%18 = fneg double %17
%19 = select i1 %16, double %17, double %18
%20 = fadd double %8, %19
%21 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 1, i64 2
store double %20, double* %21
%22 = fdiv double %11, %20
%23 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 1, i64 1
store double %22, double* %23
%24 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 2, i64 1
%25 = bitcast double* %24 to i8*
br label %34
26: ; preds = %2
%27 = fneg double %13
%28 = tail call double @sqrt(double %27)
%29 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 2, i64 1
store double %28, double* %29
%30 = fneg double %28
%31 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 2, i64 2
store double %30, double* %31
%32 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 1, i64 2
store double %8, double* %32
%33 = getelementptr inbounds [5 x double], [5 x double]* %1, i64 1, i64 1
store double %8, double* %33
br label %34
34: ; preds = %26, %15
ret void
}