int get_max(int *array, int size, int x, int y, int z) {
  int val_x = x < 0 || x >= size ? -1 : array[x];
  int val_y = y < 0 || y >= size ? -1 : array[y];
  int val_z = z < 0 || z >= size ? -1 : array[z];
  if (val_x >= val_y && val_x >= val_z)
    return x;
  if (val_y >= val_x && val_y >= val_z)
    return y;
  return z;
}


x86 assembly (clang, -O0):
<get_max>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %edx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8d,-0x20(%rbp)
cmpl   $0x0,-0x18(%rbp)
jl     112b <get_max+0x2b>
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jl     1138 <get_max+0x38>
mov    $0xffffffff,%eax
mov    %eax,-0x30(%rbp)
jmp    1146 <get_max+0x46>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,-0x24(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jl     1162 <get_max+0x62>
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jl     116f <get_max+0x6f>
mov    $0xffffffff,%eax
mov    %eax,-0x34(%rbp)
jmp    117d <get_max+0x7d>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x34(%rbp)
mov    -0x34(%rbp),%eax
mov    %eax,-0x28(%rbp)
cmpl   $0x0,-0x20(%rbp)
jl     1199 <get_max+0x99>
mov    -0x20(%rbp),%eax
cmp    -0x14(%rbp),%eax
jl     11a6 <get_max+0xa6>
mov    $0xffffffff,%eax
mov    %eax,-0x38(%rbp)
jmp    11b4 <get_max+0xb4>
mov    -0x10(%rbp),%rax
movslq -0x20(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x38(%rbp)
mov    -0x38(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x28(%rbp),%eax
jl     11dd <get_max+0xdd>
mov    -0x24(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jl     11dd <get_max+0xdd>
mov    -0x18(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1206 <get_max+0x106>
mov    -0x28(%rbp),%eax
cmp    -0x24(%rbp),%eax
jl     1200 <get_max+0x100>
mov    -0x28(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jl     1200 <get_max+0x100>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1206 <get_max+0x106>
mov    -0x20(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_max>:
mov    %edx,%eax
mov    $0xffffffff,%r9d
mov    $0xffffffff,%r10d
test   %edx,%edx
js     1122 <get_max+0x22>
mov    $0xffffffff,%r10d
cmp    %esi,%eax
jge    1122 <get_max+0x22>
mov    %eax,%edx
mov    (%rdi,%rdx,4),%r10d
test   %ecx,%ecx
js     1130 <get_max+0x30>
cmp    %esi,%ecx
jge    1130 <get_max+0x30>
mov    %ecx,%edx
mov    (%rdi,%rdx,4),%r9d
mov    $0xffffffff,%edx
test   %r8d,%r8d
js     1145 <get_max+0x45>
cmp    %esi,%r8d
jge    1145 <get_max+0x45>
mov    %r8d,%edx
mov    (%rdi,%rdx,4),%edx
cmp    %edx,%r9d
cmovl  %r8d,%ecx
cmp    %r10d,%r9d
cmovl  %r8d,%ecx
cmp    %edx,%r10d
cmovl  %ecx,%eax
cmp    %r9d,%r10d
cmovl  %ecx,%eax
ret

LLVM IR (-O0):
define i32 @get_max(i32* %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = alloca i32
%7 = alloca i32*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
store i32* %0, i32** %7
store i32 %1, i32* %8
store i32 %2, i32* %9
store i32 %3, i32* %10
store i32 %4, i32* %11
%15 = load i32, i32* %9
%16 = icmp slt i32 %15, 0
br i1 %16, label %21, label %17
17: ; preds = %5
%18 = load i32, i32* %9
%19 = load i32, i32* %8
%20 = icmp sge i32 %18, %19
br i1 %20, label %21, label %22
21: ; preds = %17, %5
br label %28
22: ; preds = %17
%23 = load i32*, i32** %7
%24 = load i32, i32* %9
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds i32, i32* %23, i64 %25
%27 = load i32, i32* %26
br label %28
28: ; preds = %22, %21
%29 = phi i32 [ -1, %21 ], [ %27, %22 ]
store i32 %29, i32* %12
%30 = load i32, i32* %10
%31 = icmp slt i32 %30, 0
br i1 %31, label %36, label %32
32: ; preds = %28
%33 = load i32, i32* %10
%34 = load i32, i32* %8
%35 = icmp sge i32 %33, %34
br i1 %35, label %36, label %37
36: ; preds = %32, %28
br label %43
37: ; preds = %32
%38 = load i32*, i32** %7
%39 = load i32, i32* %10
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds i32, i32* %38, i64 %40
%42 = load i32, i32* %41
br label %43
43: ; preds = %37, %36
%44 = phi i32 [ -1, %36 ], [ %42, %37 ]
store i32 %44, i32* %13
%45 = load i32, i32* %11
%46 = icmp slt i32 %45, 0
br i1 %46, label %51, label %47
47: ; preds = %43
%48 = load i32, i32* %11
%49 = load i32, i32* %8
%50 = icmp sge i32 %48, %49
br i1 %50, label %51, label %52
51: ; preds = %47, %43
br label %58
52: ; preds = %47
%53 = load i32*, i32** %7
%54 = load i32, i32* %11
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i32, i32* %53, i64 %55
%57 = load i32, i32* %56
br label %58
58: ; preds = %52, %51
%59 = phi i32 [ -1, %51 ], [ %57, %52 ]
store i32 %59, i32* %14
%60 = load i32, i32* %12
%61 = load i32, i32* %13
%62 = icmp sge i32 %60, %61
br i1 %62, label %63, label %69
63: ; preds = %58
%64 = load i32, i32* %12
%65 = load i32, i32* %14
%66 = icmp sge i32 %64, %65
br i1 %66, label %67, label %69
67: ; preds = %63
%68 = load i32, i32* %9
store i32 %68, i32* %6
br label %81
69: ; preds = %63, %58
%70 = load i32, i32* %13
%71 = load i32, i32* %12
%72 = icmp sge i32 %70, %71
br i1 %72, label %73, label %79
73: ; preds = %69
%74 = load i32, i32* %13
%75 = load i32, i32* %14
%76 = icmp sge i32 %74, %75
br i1 %76, label %77, label %79
77: ; preds = %73
%78 = load i32, i32* %10
store i32 %78, i32* %6
br label %81
79: ; preds = %73, %69
%80 = load i32, i32* %11
store i32 %80, i32* %6
br label %81
81: ; preds = %79, %77, %67
%82 = load i32, i32* %6
ret i32 %82
}

LLVM IR (-O2):
define i32 @get_max(i32* nocapture %0, i32 %1, i32 %2, i32 %3, i32 %4) {
%6 = icmp sgt i32 %2, -1
%7 = icmp slt i32 %2, %1
%8 = and i1 %6, %7
br i1 %8, label %9, label %13
9: ; preds = %5
%10 = zext i32 %2 to i64
%11 = getelementptr inbounds i32, i32* %0, i64 %10
%12 = load i32, i32* %11
br label %13
13: ; preds = %5, %9
%14 = phi i32 [ %12, %9 ], [ -1, %5 ]
%15 = icmp sgt i32 %3, -1
%16 = icmp slt i32 %3, %1
%17 = and i1 %15, %16
br i1 %17, label %18, label %22
18: ; preds = %13
%19 = zext i32 %3 to i64
%20 = getelementptr inbounds i32, i32* %0, i64 %19
%21 = load i32, i32* %20
br label %22
22: ; preds = %13, %18
%23 = phi i32 [ %21, %18 ], [ -1, %13 ]
%24 = icmp sgt i32 %4, -1
%25 = icmp slt i32 %4, %1
%26 = and i1 %24, %25
br i1 %26, label %27, label %31
27: ; preds = %22
%28 = zext i32 %4 to i64
%29 = getelementptr inbounds i32, i32* %0, i64 %28
%30 = load i32, i32* %29
br label %31
31: ; preds = %22, %27
%32 = phi i32 [ %30, %27 ], [ -1, %22 ]
%33 = icmp slt i32 %14, %23
%34 = icmp slt i32 %14, %32
%35 = select i1 %33, i1 true, i1 %34
%36 = icmp slt i32 %23, %14
%37 = icmp slt i32 %23, %32
%38 = select i1 %36, i1 true, i1 %37
%39 = select i1 %38, i32 %4, i32 %3
%40 = select i1 %35, i32 %39, i32 %2
ret i32 %40
}