#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 */
int linear_roots(double *, double *);
double sgn(double);
double sqrt(double);
extern int quadratic_roots(double *a, double *r) {
  double B, C, D;
  if ((((a[2]) > -1e-30) && ((a[2]) < 1e-30)))
    return linear_roots(a, r);
  B = a[1] / a[2];
  C = a[0] / a[2];
  D = B * B - 4 * C;
  if ((((D) > -1e-30) && ((D) < 1e-30))) {
    r[0] = -B / 2;
    return 1;
  } else if (D < 0)
    return 0;
  double sD = sqrt(D);
  if ((((B) > -1e-30) && ((B) < 1e-30))) {
    r[0] = sD / 2;
    r[1] = -sD / 2;
  } else {
    double t = -(B + sgn(B) * sD) / 2;
    r[0] = t;
    r[1] = C / t;
  }
  return 2;
}


x86 assembly (clang, -O0):
<quadratic_roots>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x10(%rax),%xmm0
movsd  0xeaf(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1187 <quadratic_roots+0x57>
mov    -0x10(%rbp),%rax
movsd  0xea1(%rip),%xmm0
ucomisd 0x10(%rax),%xmm0
jbe    1187 <quadratic_roots+0x57>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1030 <linear_roots@plt>
mov    %eax,-0x4(%rbp)
jmp    1371 <quadratic_roots+0x241>
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
divsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x10(%rbp),%rax
divsd  0x10(%rax),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x20(%rbp),%xmm2
movsd  0xe4a(%rip),%xmm1
mulsd  -0x28(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
movsd  0xe04(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1255 <quadratic_roots+0x125>
movsd  0xdfa(%rip),%xmm0
ucomisd -0x30(%rbp),%xmm0
jbe    1255 <quadratic_roots+0x125>
movsd  -0x20(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xddb(%rip),%xmm1
divsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movl   $0x1,-0x4(%rbp)
jmp    1371 <quadratic_roots+0x241>
xorps  %xmm0,%xmm0
ucomisd -0x30(%rbp),%xmm0
jbe    126f <quadratic_roots+0x13f>
movl   $0x0,-0x4(%rbp)
jmp    1371 <quadratic_roots+0x241>
jmp    1274 <quadratic_roots+0x144>
movsd  -0x30(%rbp),%xmm0
call   1050 <sqrt@plt>
movsd  %xmm0,-0x38(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  0xd70(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    12fc <quadratic_roots+0x1cc>
movsd  0xd66(%rip),%xmm0
ucomisd -0x20(%rbp),%xmm0
jbe    12fc <quadratic_roots+0x1cc>
movsd  -0x38(%rbp),%xmm0
movsd  0xd5e(%rip),%xmm1
divsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x38(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xd2e(%rip),%xmm1
divsd  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x8(%rax)
jmp    136a <quadratic_roots+0x23a>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1040 <sgn@plt>
movsd  -0x48(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  0xcd7(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x40(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x28(%rbp),%xmm0
divsd  -0x40(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movsd  %xmm0,0x8(%rax)
movl   $0x2,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<quadratic_roots>:
push   %rbx
sub    $0x20,%rsp
mov    %rsi,%rbx
movsd  0x10(%rdi),%xmm0
ucomisd 0xebb(%rip),%xmm0
jbe    1162 <quadratic_roots+0x32>
movsd  0xeb9(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    1162 <quadratic_roots+0x32>
mov    %rbx,%rsi
add    $0x20,%rsp
pop    %rbx
jmp    1030 <linear_roots@plt>
movsd  (%rdi),%xmm2
movsd  0x8(%rdi),%xmm3
divsd  %xmm0,%xmm3
divsd  %xmm0,%xmm2
movsd  0xe95(%rip),%xmm1
mulsd  %xmm2,%xmm1
movapd %xmm3,%xmm0
mulsd  %xmm3,%xmm0
addsd  %xmm1,%xmm0
ucomisd 0xe6d(%rip),%xmm0
jbe    11b9 <quadratic_roots+0x89>
movsd  0xe6b(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    11b9 <quadratic_roots+0x89>
mulsd  0xe6d(%rip),%xmm3
movsd  %xmm3,(%rbx)
mov    $0x1,%eax
jmp    125f <quadratic_roots+0x12f>
xor    %eax,%eax
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
ja     125f <quadratic_roots+0x12f>
ucomisd %xmm1,%xmm0
movsd  %xmm2,0x8(%rsp)
movsd  %xmm3,(%rsp)
jb     11ed <quadratic_roots+0xbd>
xorps  %xmm1,%xmm1
sqrtsd %xmm0,%xmm1
ucomisd 0xe17(%rip),%xmm3
ja     1205 <quadratic_roots+0xd5>
jmp    1225 <quadratic_roots+0xf5>
call   1050 <sqrt@plt>
movsd  (%rsp),%xmm3
movapd %xmm0,%xmm1
ucomisd 0xdfd(%rip),%xmm3
jbe    1225 <quadratic_roots+0xf5>
movsd  0xdfb(%rip),%xmm0
ucomisd %xmm3,%xmm0
jbe    1225 <quadratic_roots+0xf5>
unpcklpd %xmm1,%xmm1
mulpd  0xe01(%rip),%xmm1
movupd %xmm1,(%rbx)
jmp    125a <quadratic_roots+0x12a>
movapd %xmm3,%xmm0
movapd %xmm1,0x10(%rsp)
call   1040 <sgn@plt>
mulsd  0x10(%rsp),%xmm0
addsd  (%rsp),%xmm0
mulsd  0xdd1(%rip),%xmm0
movsd  %xmm0,(%rbx)
movsd  0x8(%rsp),%xmm1
divsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rbx)
mov    $0x2,%eax
add    $0x20,%rsp
pop    %rbx
ret

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

LLVM IR (-O2):
define i32 @quadratic_roots(double* %0, double* %1) {
%3 = getelementptr inbounds double, double* %0, i64 2
%4 = load double, double* %3
%5 = fcmp ogt double %4, -1.000000e-30
%6 = fcmp olt double %4, 1.000000e-30
%7 = and i1 %5, %6
br i1 %7, label %8, label %10
8: ; preds = %2
%9 = tail call i32 @linear_roots(double* %0, double* %1)
br label %41
10: ; preds = %2
%11 = getelementptr inbounds double, double* %0, i64 1
%12 = load double, double* %11
%13 = fdiv double %12, %4
%14 = load double, double* %0
%15 = fdiv double %14, %4
%16 = fmul double %15, -4.000000e+00
%17 = tail call double @llvm.fmuladd.f64(double %13, double %13, double %16)
%18 = fcmp ogt double %17, -1.000000e-30
%19 = fcmp olt double %17, 1.000000e-30
%20 = and i1 %18, %19
br i1 %20, label %21, label %23
21: ; preds = %10
%22 = fmul double %13, -5.000000e-01
store double %22, double* %1
br label %41
23: ; preds = %10
%24 = fcmp olt double %17, 0.000000e+00
br i1 %24, label %41, label %25
25: ; preds = %23
%26 = tail call double @sqrt(double %17)
%27 = fcmp ogt double %13, -1.000000e-30
%28 = fcmp olt double %13, 1.000000e-30
%29 = and i1 %27, %28
br i1 %29, label %30, label %35
30: ; preds = %25
%31 = insertelement <2 x double> poison, double %26, i64 0
%32 = shufflevector <2 x double> %31, <2 x double> poison, <2 x i32> zeroinitializer
%33 = fmul <2 x double> %32, <double 5.000000e-01, double -5.000000e-01>
%34 = bitcast double* %1 to <2 x double>*
store <2 x double> %33, <2 x double>* %34
br label %41
35: ; preds = %25
%36 = tail call double @sgn(double %13)
%37 = tail call double @llvm.fmuladd.f64(double %36, double %26, double %13)
%38 = fmul double %37, -5.000000e-01
store double %38, double* %1
%39 = fdiv double %15, %38
%40 = getelementptr inbounds double, double* %1, i64 1
store double %39, double* %40
br label %41
41: ; preds = %30, %35, %23, %21, %8
%42 = phi i32 [ %9, %8 ], [ 1, %21 ], [ 0, %23 ], [ 2, %35 ], [ 2, %30 ]
ret i32 %42
}