#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 */
typedef int /*<<< orphan*/ B;
typedef int /*<<< orphan*/ A;

/* Variables and functions */
int findMaxElem(int *, int);
int findMaxElem2(int *, int);
int /*<<< orphan*/ printf(char *, int, int);
int /*<<< orphan*/ testVariousTreeAPI(int *, int);
int main(int argc, char *argv[]) {
  int A[] = {9, 7, 6, 5, 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7};
  int B[] = {5, 7, 3, 8, 2, 4, 6};
  int C[] = {9, 12, 15, 2, 3, 4, 8, 5, 6, 7, 1};
  int b = findMaxElem(A, sizeof(A) / sizeof(int));
  printf("MaxElem index %d val %d\n", b, b ? A[b] : b);
  b = findMaxElem2(A, sizeof(A) / sizeof(int));
  printf("MaxElem index %d val %d(via binary insert method\n", b, b ? A[b] : b);
  testVariousTreeAPI(B, sizeof(B) / sizeof(int));
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0xd0,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
lea    -0x60(%rbp),%rdi
lea    0xe8c(%rip),%rsi
mov    $0x48,%edx
call   1050 <memcpy@plt>
mov    0xecb(%rip),%rax
mov    %rax,-0x80(%rbp)
mov    0xec8(%rip),%rax
mov    %rax,-0x78(%rbp)
mov    0xec5(%rip),%rax
mov    %rax,-0x70(%rbp)
mov    0xec3(%rip),%eax
mov    %eax,-0x68(%rbp)
lea    -0xb0(%rbp),%rdi
lea    0xeba(%rip),%rsi
mov    $0x2c,%edx
call   1050 <memcpy@plt>
lea    -0x60(%rbp),%rdi
mov    $0x12,%esi
call   1060 <findMaxElem@plt>
mov    %eax,-0xb4(%rbp)
mov    -0xb4(%rbp),%eax
mov    %eax,-0xb8(%rbp)
cmpl   $0x0,-0xb4(%rbp)
je     1203 <main+0xb3>
movslq -0xb4(%rbp),%rax
mov    -0x60(%rbp,%rax,4),%eax
mov    %eax,-0xbc(%rbp)
jmp    120f <main+0xbf>
mov    -0xb4(%rbp),%eax
mov    %eax,-0xbc(%rbp)
mov    -0xb8(%rbp),%esi
mov    -0xbc(%rbp),%edx
lea    0xe7a(%rip),%rdi
call   1040 <printf@plt>
lea    -0x60(%rbp),%rdi
mov    $0x12,%esi
call   1070 <findMaxElem2@plt>
mov    %eax,-0xb4(%rbp)
mov    -0xb4(%rbp),%eax
mov    %eax,-0xc0(%rbp)
cmpl   $0x0,-0xb4(%rbp)
je     126a <main+0x11a>
movslq -0xb4(%rbp),%rax
mov    -0x60(%rbp,%rax,4),%eax
mov    %eax,-0xc4(%rbp)
jmp    1276 <main+0x126>
mov    -0xb4(%rbp),%eax
mov    %eax,-0xc4(%rbp)
mov    -0xc0(%rbp),%esi
mov    -0xc4(%rbp),%edx
lea    0xe2c(%rip),%rdi
call   1040 <printf@plt>
lea    -0x80(%rbp),%rdi
mov    $0x7,%esi
call   1030 <testVariousTreeAPI@plt>
mov    -0x4(%rbp),%eax
add    $0xd0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rbx
sub    $0x70,%rsp
mov    0xef4(%rip),%rax
mov    %rax,0x40(%rsp)
movaps 0xed8(%rip),%xmm0
movaps %xmm0,0x30(%rsp)
movaps 0xebc(%rip),%xmm0
movaps %xmm0,0x20(%rsp)
movaps 0xea0(%rip),%xmm0
movaps %xmm0,0x10(%rsp)
movaps 0xe84(%rip),%xmm0
movaps %xmm0,(%rsp)
movups 0xed5(%rip),%xmm0
movups %xmm0,0x5c(%rsp)
movaps 0xebd(%rip),%xmm0
movaps %xmm0,0x50(%rsp)
mov    %rsp,%rdi
mov    $0x12,%esi
call   1050 <findMaxElem@plt>
xor    %ebx,%ebx
mov    $0x0,%edx
test   %eax,%eax
je     11b6 <main+0x76>
movslq %eax,%rcx
mov    (%rsp,%rcx,4),%edx
lea    0xeaf(%rip),%rdi
mov    %eax,%esi
call   1040 <printf@plt>
mov    %rsp,%rdi
mov    $0x12,%esi
call   1060 <findMaxElem2@plt>
test   %eax,%eax
je     11db <main+0x9b>
movslq %eax,%rcx
mov    (%rsp,%rcx,4),%ebx
lea    0xea3(%rip),%rdi
mov    %eax,%esi
mov    %ebx,%edx
call   1040 <printf@plt>
lea    0x50(%rsp),%rdi
mov    $0x7,%esi
call   1030 <testVariousTreeAPI@plt>
xor    %eax,%eax
add    $0x70,%rsp
pop    %rbx
ret

LLVM IR (-O0):
@__const.main.A = [18 x i32] [i32 9, i32 7, i32 6, i32 5, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7]
@__const.main.B = [7 x i32] [i32 5, i32 7, i32 3, i32 8, i32 2, i32 4, i32 6]
@__const.main.C = [11 x i32] [i32 9, i32 12, i32 15, i32 2, i32 3, i32 4, i32 8, i32 5, i32 6, i32 7, i32 1]
@.str = [25 x i8] c"MaxElem index %d val %d\0A\00"
@.str.1 = [50 x i8] c"MaxElem index %d val %d(via binary insert method\0A\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca [18 x i32]
%7 = alloca [7 x i32]
%8 = alloca [11 x i32]
%9 = alloca i32
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%10 = bitcast [18 x i32]* %6 to i8*
%11 = bitcast [7 x i32]* %7 to i8*
%12 = bitcast [11 x i32]* %8 to i8*
%13 = getelementptr inbounds [18 x i32], [18 x i32]* %6, i64 0, i64 0
%14 = call i32 @findMaxElem(i32* %13, i32 18)
store i32 %14, i32* %9
%15 = load i32, i32* %9
%16 = load i32, i32* %9
%17 = icmp ne i32 %16, 0
br i1 %17, label %18, label %23
18: ; preds = %2
%19 = load i32, i32* %9
%20 = sext i32 %19 to i64
%21 = getelementptr inbounds [18 x i32], [18 x i32]* %6, i64 0, i64 %20
%22 = load i32, i32* %21
br label %25
23: ; preds = %2
%24 = load i32, i32* %9
br label %25
25: ; preds = %23, %18
%26 = phi i32 [ %22, %18 ], [ %24, %23 ]
%27 = call i32 @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i64 0, i64 0), i32 %15, i32 %26)
%28 = getelementptr inbounds [18 x i32], [18 x i32]* %6, i64 0, i64 0
%29 = call i32 @findMaxElem2(i32* %28, i32 18)
store i32 %29, i32* %9
%30 = load i32, i32* %9
%31 = load i32, i32* %9
%32 = icmp ne i32 %31, 0
br i1 %32, label %33, label %38
33: ; preds = %25
%34 = load i32, i32* %9
%35 = sext i32 %34 to i64
%36 = getelementptr inbounds [18 x i32], [18 x i32]* %6, i64 0, i64 %35
%37 = load i32, i32* %36
br label %40
38: ; preds = %25
%39 = load i32, i32* %9
br label %40
40: ; preds = %38, %33
%41 = phi i32 [ %37, %33 ], [ %39, %38 ]
%42 = call i32 @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.1, i64 0, i64 0), i32 %30, i32 %41)
%43 = getelementptr inbounds [7 x i32], [7 x i32]* %7, i64 0, i64 0
%44 = call i32 @testVariousTreeAPI(i32* %43, i32 7)
%45 = load i32, i32* %3
ret i32 %45
}

LLVM IR (-O2):
@__const.main.A = [18 x i32] [i32 9, i32 7, i32 6, i32 5, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7, i32 7]
@__const.main.B = [7 x i32] [i32 5, i32 7, i32 3, i32 8, i32 2, i32 4, i32 6]
@.str = [25 x i8] c"MaxElem index %d val %d\0A\00"
@.str.1 = [50 x i8] c"MaxElem index %d val %d(via binary insert method\0A\00"
define i32 @main(i32 %0, i8** nocapture readnone %1) {
%3 = alloca [18 x i32]
%4 = alloca [7 x i32]
%5 = bitcast [18 x i32]* %3 to i8*
%6 = bitcast [7 x i32]* %4 to i8*
%7 = getelementptr inbounds [18 x i32], [18 x i32]* %3, i64 0, i64 0
%8 = call i32 @findMaxElem(i32* %7, i32 18)
%9 = icmp eq i32 %8, 0
br i1 %9, label %14, label %10
10: ; preds = %2
%11 = sext i32 %8 to i64
%12 = getelementptr inbounds [18 x i32], [18 x i32]* %3, i64 0, i64 %11
%13 = load i32, i32* %12
br label %14
14: ; preds = %2, %10
%15 = phi i32 [ %13, %10 ], [ 0, %2 ]
%16 = call i32 @printf(i8* getelementptr inbounds ([25 x i8], [25 x i8]* @.str, i64 0, i64 0), i32 %8, i32 %15)
%17 = call i32 @findMaxElem2(i32* %7, i32 18)
%18 = icmp eq i32 %17, 0
br i1 %18, label %23, label %19
19: ; preds = %14
%20 = sext i32 %17 to i64
%21 = getelementptr inbounds [18 x i32], [18 x i32]* %3, i64 0, i64 %20
%22 = load i32, i32* %21
br label %23
23: ; preds = %14, %19
%24 = phi i32 [ %22, %19 ], [ 0, %14 ]
%25 = call i32 @printf(i8* getelementptr inbounds ([50 x i8], [50 x i8]* @.str.1, i64 0, i64 0), i32 %17, i32 %24)
%26 = getelementptr inbounds [7 x i32], [7 x i32]* %4, i64 0, i64 0
%27 = call i32 @testVariousTreeAPI(i32* %26, i32 7)
ret i32 0
}