#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 */
struct noeud {
  int dummy;
};

/* Variables and functions */
int /*<<< orphan*/ get_next_br(struct noeud *, struct noeud *, double **,
                               double **, struct noeud **, struct noeud **);
double tree_bal(struct noeud *centre, struct noeud *p1, struct noeud *p2) {
  double ld, lg, pg, pd, *abup1, *abup2, *abdown1, *abdown2;
  struct noeud *f1, *f2;
  get_next_br(centre, p1, &abup1, &abdown1, &f1, &f2);
  if (f1 != NULL)
    lg = tree_bal(p1, f1, f2);
  else
    lg = 0.0;
  get_next_br(centre, p2, &abup2, &abdown2, &f1, &f2);
  if (f1 != NULL)
    ld = tree_bal(p2, f1, f2);
  else
    ld = 0.0;
  pg = lg + 1;
  pd = ld + 1;
  if (pg > pd)
    pd = pg;
  else
    pg = pd;
  *abup1 = *abdown1 = pg - lg;
  *abup2 = *abdown2 = pd - ld;
  return (pg);
}


x86 assembly (clang, -O0):
<tree_bal>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
lea    -0x40(%rbp),%rdx
lea    -0x50(%rbp),%rcx
lea    -0x60(%rbp),%r8
lea    -0x68(%rbp),%r9
call   1040 <get_next_br@plt>
cmpq   $0x0,-0x60(%rbp)
je     1177 <tree_bal+0x57>
mov    -0x10(%rbp),%rdi
mov    -0x60(%rbp),%rsi
mov    -0x68(%rbp),%rdx
call   1030 <tree_bal@plt>
movsd  %xmm0,-0x28(%rbp)
jmp    117f <tree_bal+0x5f>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x28(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rsi
lea    -0x48(%rbp),%rdx
lea    -0x58(%rbp),%rcx
lea    -0x60(%rbp),%r8
lea    -0x68(%rbp),%r9
call   1040 <get_next_br@plt>
cmpq   $0x0,-0x60(%rbp)
je     11c2 <tree_bal+0xa2>
mov    -0x18(%rbp),%rdi
mov    -0x60(%rbp),%rsi
mov    -0x68(%rbp),%rdx
call   1030 <tree_bal@plt>
movsd  %xmm0,-0x20(%rbp)
jmp    11ca <tree_bal+0xaa>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  0xe2e(%rip),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  0xe1c(%rip),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x30(%rbp),%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    120d <tree_bal+0xed>
movsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
jmp    1217 <tree_bal+0xf7>
movsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x30(%rbp),%xmm0
subsd  -0x28(%rbp),%xmm0
mov    -0x50(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x40(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x38(%rbp),%xmm0
subsd  -0x20(%rbp),%xmm0
mov    -0x58(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x48(%rbp),%rax
movsd  %xmm0,(%rax)
movsd  -0x30(%rbp),%xmm0
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<tree_bal>:
push   %r15
push   %r14
push   %rbx
sub    $0x40,%rsp
mov    %rdx,%r14
mov    %rsi,%rbx
mov    %rdi,%r15
lea    0x38(%rsp),%rdx
lea    0x28(%rsp),%rcx
lea    0x10(%rsp),%r8
lea    0x8(%rsp),%r9
call   1040 <get_next_br@plt>
mov    0x10(%rsp),%rsi
xorpd  %xmm0,%xmm0
test   %rsi,%rsi
je     1166 <tree_bal+0x46>
mov    0x8(%rsp),%rdx
mov    %rbx,%rdi
call   1030 <tree_bal@plt>
movsd  %xmm0,0x18(%rsp)
lea    0x30(%rsp),%rdx
lea    0x20(%rsp),%rcx
lea    0x10(%rsp),%r8
lea    0x8(%rsp),%r9
mov    %r15,%rdi
mov    %r14,%rsi
call   1040 <get_next_br@plt>
mov    0x10(%rsp),%rsi
test   %rsi,%rsi
xorpd  %xmm3,%xmm3
je     11aa <tree_bal+0x8a>
mov    0x8(%rsp),%rdx
mov    %r14,%rdi
call   1030 <tree_bal@plt>
movapd %xmm0,%xmm3
movsd  0xe4e(%rip),%xmm1
movsd  0x18(%rsp),%xmm4
movapd %xmm4,%xmm0
addsd  %xmm1,%xmm0
addsd  %xmm3,%xmm1
maxsd  %xmm1,%xmm0
movapd %xmm0,%xmm1
movapd %xmm0,%xmm2
subsd  %xmm4,%xmm2
mov    0x28(%rsp),%rax
movsd  %xmm2,(%rax)
mov    0x38(%rsp),%rax
movsd  %xmm2,(%rax)
subsd  %xmm3,%xmm1
mov    0x20(%rsp),%rax
movsd  %xmm1,(%rax)
mov    0x30(%rsp),%rax
movsd  %xmm1,(%rax)
add    $0x40,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
%struct.noeud = type { i32 }
define double @tree_bal(%struct.noeud* %0, %struct.noeud* %1, %struct.noeud* %2) {
%4 = alloca %struct.noeud*
%5 = alloca %struct.noeud*
%6 = alloca %struct.noeud*
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double*
%12 = alloca double*
%13 = alloca double*
%14 = alloca double*
%15 = alloca %struct.noeud*
%16 = alloca %struct.noeud*
store %struct.noeud* %0, %struct.noeud** %4
store %struct.noeud* %1, %struct.noeud** %5
store %struct.noeud* %2, %struct.noeud** %6
%17 = load %struct.noeud*, %struct.noeud** %4
%18 = load %struct.noeud*, %struct.noeud** %5
%19 = call i32 @get_next_br(%struct.noeud* %17, %struct.noeud* %18, double** %11, double** %13, %struct.noeud** %15, %struct.noeud** %16)
%20 = load %struct.noeud*, %struct.noeud** %15
%21 = icmp ne %struct.noeud* %20, null
br i1 %21, label %22, label %27
22: ; preds = %3
%23 = load %struct.noeud*, %struct.noeud** %5
%24 = load %struct.noeud*, %struct.noeud** %15
%25 = load %struct.noeud*, %struct.noeud** %16
%26 = call double @tree_bal(%struct.noeud* %23, %struct.noeud* %24, %struct.noeud* %25)
store double %26, double* %8
br label %28
27: ; preds = %3
store double 0.000000e+00, double* %8
br label %28
28: ; preds = %27, %22
%29 = load %struct.noeud*, %struct.noeud** %4
%30 = load %struct.noeud*, %struct.noeud** %6
%31 = call i32 @get_next_br(%struct.noeud* %29, %struct.noeud* %30, double** %12, double** %14, %struct.noeud** %15, %struct.noeud** %16)
%32 = load %struct.noeud*, %struct.noeud** %15
%33 = icmp ne %struct.noeud* %32, null
br i1 %33, label %34, label %39
34: ; preds = %28
%35 = load %struct.noeud*, %struct.noeud** %6
%36 = load %struct.noeud*, %struct.noeud** %15
%37 = load %struct.noeud*, %struct.noeud** %16
%38 = call double @tree_bal(%struct.noeud* %35, %struct.noeud* %36, %struct.noeud* %37)
store double %38, double* %7
br label %40
39: ; preds = %28
store double 0.000000e+00, double* %7
br label %40
40: ; preds = %39, %34
%41 = load double, double* %8
%42 = fadd double %41, 1.000000e+00
store double %42, double* %9
%43 = load double, double* %7
%44 = fadd double %43, 1.000000e+00
store double %44, double* %10
%45 = load double, double* %9
%46 = load double, double* %10
%47 = fcmp ogt double %45, %46
br i1 %47, label %48, label %50
48: ; preds = %40
%49 = load double, double* %9
store double %49, double* %10
br label %52
50: ; preds = %40
%51 = load double, double* %10
store double %51, double* %9
br label %52
52: ; preds = %50, %48
%53 = load double, double* %9
%54 = load double, double* %8
%55 = fsub double %53, %54
%56 = load double*, double** %13
store double %55, double* %56
%57 = load double*, double** %11
store double %55, double* %57
%58 = load double, double* %10
%59 = load double, double* %7
%60 = fsub double %58, %59
%61 = load double*, double** %14
store double %60, double* %61
%62 = load double*, double** %12
store double %60, double* %62
%63 = load double, double* %9
ret double %63
}

LLVM IR (-O2):
%struct.noeud = type { i32 }
define double @tree_bal(%struct.noeud* %0, %struct.noeud* %1, %struct.noeud* %2) {
%4 = alloca double*
%5 = alloca double*
%6 = alloca double*
%7 = alloca double*
%8 = alloca %struct.noeud*
%9 = alloca %struct.noeud*
%10 = bitcast double** %4 to i8*
%11 = bitcast double** %5 to i8*
%12 = bitcast double** %6 to i8*
%13 = bitcast double** %7 to i8*
%14 = bitcast %struct.noeud** %8 to i8*
%15 = bitcast %struct.noeud** %9 to i8*
%16 = call i32 @get_next_br(%struct.noeud* %0, %struct.noeud* %1, double** %4, double** %6, %struct.noeud** %8, %struct.noeud** %9)
%17 = load %struct.noeud*, %struct.noeud** %8
%18 = icmp eq %struct.noeud* %17, null
br i1 %18, label %22, label %19
19: ; preds = %3
%20 = load %struct.noeud*, %struct.noeud** %9
%21 = call double @tree_bal(%struct.noeud* %1, %struct.noeud* %17, %struct.noeud* %20)
br label %22
22: ; preds = %3, %19
%23 = phi double [ %21, %19 ], [ 0.000000e+00, %3 ]
%24 = call i32 @get_next_br(%struct.noeud* %0, %struct.noeud* %2, double** %5, double** %7, %struct.noeud** %8, %struct.noeud** %9)
%25 = load %struct.noeud*, %struct.noeud** %8
%26 = icmp eq %struct.noeud* %25, null
br i1 %26, label %30, label %27
27: ; preds = %22
%28 = load %struct.noeud*, %struct.noeud** %9
%29 = call double @tree_bal(%struct.noeud* %2, %struct.noeud* %25, %struct.noeud* %28)
br label %30
30: ; preds = %22, %27
%31 = phi double [ %29, %27 ], [ 0.000000e+00, %22 ]
%32 = fadd double %23, 1.000000e+00
%33 = fadd double %31, 1.000000e+00
%34 = fcmp ogt double %32, %33
%35 = select i1 %34, double %32, double %33
%36 = fsub double %35, %23
%37 = load double*, double** %6
store double %36, double* %37
%38 = load double*, double** %4
store double %36, double* %38
%39 = fsub double %35, %31
%40 = load double*, double** %7
store double %39, double* %40
%41 = load double*, double** %5
store double %39, double* %41
ret double %35
}