#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 /*<<< orphan*/ free(int *);
int *malloc(int);
void merging(int *a, int start, int end, int mid, int size) {
  int *b = malloc(size * sizeof(int));
  int left = start;
  int right = mid + 1;
  int curr = start;
  for (; left <= mid && right <= end; curr++) {
    if (a[left] <= a[right]) {
      b[curr] = a[left];
      left++;
    } else {
      b[curr] = a[right];
      right++;
    }
  }
  while (left <= mid) {
    b[curr++] = a[left++];
  }
  while (right <= end) {
    b[curr++] = a[right++];
  }
  for (int i = start; i <= end; i++) {
    a[i] = b[i];
  }
  free(b);
}


x86 assembly (clang, -O0):
<merging>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
mov    %r8d,-0x18(%rbp)
movslq -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1040 <malloc@plt>
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x24(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x24(%rbp),%ecx
xor    %eax,%eax
cmp    -0x14(%rbp),%ecx
mov    %al,-0x31(%rbp)
jg     117e <merging+0x5e>
mov    -0x28(%rbp),%eax
cmp    -0x10(%rbp),%eax
setle  %al
mov    %al,-0x31(%rbp)
mov    -0x31(%rbp),%al
test   $0x1,%al
jne    118e <merging+0x6e>
jmp    1200 <merging+0xe0>
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
mov    -0x8(%rbp),%rcx
movslq -0x28(%rbp),%rdx
cmp    (%rcx,%rdx,4),%eax
jg     11ce <merging+0xae>
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11ed <merging+0xcd>
mov    -0x8(%rbp),%rax
movslq -0x28(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x28(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    11f2 <merging+0xd2>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1161 <merging+0x41>
jmp    1205 <merging+0xe5>
mov    -0x24(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     1240 <merging+0x120>
mov    -0x8(%rbp),%rax
mov    -0x24(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x24(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x2c(%rbp)
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
jmp    1205 <merging+0xe5>
jmp    1245 <merging+0x125>
mov    -0x28(%rbp),%eax
cmp    -0x10(%rbp),%eax
jg     1280 <merging+0x160>
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x28(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x20(%rbp),%rax
mov    -0x2c(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x2c(%rbp)
movslq %ecx,%rcx
mov    %edx,(%rax,%rcx,4)
jmp    1245 <merging+0x125>
mov    -0xc(%rbp),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0x10(%rbp),%eax
jg     12b6 <merging+0x196>
mov    -0x20(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,4),%edx
mov    -0x8(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    1286 <merging+0x166>
mov    -0x20(%rbp),%rdi
call   1030 <free@plt>
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<merging>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %ecx,%r14d
mov    %edx,%r15d
mov    %esi,%ebx
mov    %rdi,%r12
lea    0x0(,%r8,4),%edi
call   1050 <malloc@plt>
lea    0x1(%r14),%r13d
movslq %ebx,%rcx
mov    %rcx,0x10(%rsp)
cmp    %r14d,%ebx
mov    %ebx,0xc(%rsp)
jg     11c5 <merging+0x95>
cmp    %r15d,%r14d
jge    11c5 <merging+0x95>
mov    %rax,%r8
mov    0x10(%rsp),%rcx
lea    (%rax,%rcx,4),%rdx
mov    %ebx,%eax
mov    %ebx,%ecx
movslq %ecx,%rcx
mov    (%r12,%rcx,4),%esi
movslq %r13d,%r13
mov    (%r12,%r13,4),%edi
xor    %ebp,%ebp
xor    %ebx,%ebx
cmp    %edi,%esi
setg   %bpl
setle  %bl
cmovg  %edi,%esi
add    %ebx,%ecx
add    %ebp,%r13d
mov    %esi,(%rdx)
add    $0x1,%eax
cmp    %r14d,%ecx
jg     11b6 <merging+0x86>
add    $0x4,%rdx
cmp    %r15d,%r13d
jle    1180 <merging+0x50>
cmp    %r14d,%ecx
jle    11d1 <merging+0xa1>
mov    %r8,%rbx
cmp    %r15d,%r13d
jle    11fe <merging+0xce>
jmp    121e <merging+0xee>
mov    %rax,%r8
mov    %ebx,%ecx
mov    %ebx,%eax
cmp    %r14d,%ecx
jg     11bb <merging+0x8b>
movslq %eax,%rbp
mov    %r8,%rbx
lea    (%r8,%rbp,4),%rdi
movslq %ecx,%rax
lea    (%r12,%rax,4),%rsi
sub    %ecx,%r14d
lea    0x4(,%r14,4),%rdx
call   1040 <memcpy@plt>
lea    (%r14,%rbp,1),%eax
add    $0x1,%eax
cmp    %r15d,%r13d
jg     121e <merging+0xee>
cltq
lea    (%rbx,%rax,4),%rdi
movslq %r13d,%rax
lea    (%r12,%rax,4),%rsi
mov    %r15d,%eax
sub    %r13d,%eax
lea    0x4(,%rax,4),%rdx
call   1040 <memcpy@plt>
sub    0xc(%rsp),%r15d
jl     123f <merging+0x10f>
mov    0x10(%rsp),%rax
lea    (%r12,%rax,4),%rdi
lea    (%rbx,%rax,4),%rsi
lea    0x4(,%r15,4),%rdx
call   1040 <memcpy@plt>
mov    %rbx,%rdi
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <free@plt>

LLVM IR (-O0):
define void @merging(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
%15 = alloca i32
store i32* %0, i32** %6
store i32 %1, i32* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
store i32 %4, i32* %10
%16 = load i32, i32* %10
%17 = sext i32 %16 to i64
%18 = mul i64 %17, 4
%19 = trunc i64 %18 to i32
%20 = call i32* @malloc(i32 %19)
store i32* %20, i32** %11
%21 = load i32, i32* %7
store i32 %21, i32* %12
%22 = load i32, i32* %9
%23 = add nsw i32 %22, 1
store i32 %23, i32* %13
%24 = load i32, i32* %7
store i32 %24, i32* %14
br label %25
25: ; preds = %72, %5
%26 = load i32, i32* %12
%27 = load i32, i32* %9
%28 = icmp sle i32 %26, %27
br i1 %28, label %29, label %33
29: ; preds = %25
%30 = load i32, i32* %13
%31 = load i32, i32* %8
%32 = icmp sle i32 %30, %31
br label %33
33: ; preds = %29, %25
%34 = phi i1 [ false, %25 ], [ %32, %29 ]
br i1 %34, label %35, label %75
35: ; preds = %33
%36 = load i32*, i32** %6
%37 = load i32, i32* %12
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds i32, i32* %36, i64 %38
%40 = load i32, i32* %39
%41 = load i32*, i32** %6
%42 = load i32, i32* %13
%43 = sext i32 %42 to i64
%44 = getelementptr inbounds i32, i32* %41, i64 %43
%45 = load i32, i32* %44
%46 = icmp sle i32 %40, %45
br i1 %46, label %47, label %59
47: ; preds = %35
%48 = load i32*, i32** %6
%49 = load i32, i32* %12
%50 = sext i32 %49 to i64
%51 = getelementptr inbounds i32, i32* %48, i64 %50
%52 = load i32, i32* %51
%53 = load i32*, i32** %11
%54 = load i32, i32* %14
%55 = sext i32 %54 to i64
%56 = getelementptr inbounds i32, i32* %53, i64 %55
store i32 %52, i32* %56
%57 = load i32, i32* %12
%58 = add nsw i32 %57, 1
store i32 %58, i32* %12
br label %71
59: ; preds = %35
%60 = load i32*, i32** %6
%61 = load i32, i32* %13
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds i32, i32* %60, i64 %62
%64 = load i32, i32* %63
%65 = load i32*, i32** %11
%66 = load i32, i32* %14
%67 = sext i32 %66 to i64
%68 = getelementptr inbounds i32, i32* %65, i64 %67
store i32 %64, i32* %68
%69 = load i32, i32* %13
%70 = add nsw i32 %69, 1
store i32 %70, i32* %13
br label %71
71: ; preds = %59, %47
br label %72
72: ; preds = %71
%73 = load i32, i32* %14
%74 = add nsw i32 %73, 1
store i32 %74, i32* %14
br label %25
75: ; preds = %33
br label %76
76: ; preds = %80, %75
%77 = load i32, i32* %12
%78 = load i32, i32* %9
%79 = icmp sle i32 %77, %78
br i1 %79, label %80, label %92
80: ; preds = %76
%81 = load i32*, i32** %6
%82 = load i32, i32* %12
%83 = add nsw i32 %82, 1
store i32 %83, i32* %12
%84 = sext i32 %82 to i64
%85 = getelementptr inbounds i32, i32* %81, i64 %84
%86 = load i32, i32* %85
%87 = load i32*, i32** %11
%88 = load i32, i32* %14
%89 = add nsw i32 %88, 1
store i32 %89, i32* %14
%90 = sext i32 %88 to i64
%91 = getelementptr inbounds i32, i32* %87, i64 %90
store i32 %86, i32* %91
br label %76
92: ; preds = %76
br label %93
93: ; preds = %97, %92
%94 = load i32, i32* %13
%95 = load i32, i32* %8
%96 = icmp sle i32 %94, %95
br i1 %96, label %97, label %109
97: ; preds = %93
%98 = load i32*, i32** %6
%99 = load i32, i32* %13
%100 = add nsw i32 %99, 1
store i32 %100, i32* %13
%101 = sext i32 %99 to i64
%102 = getelementptr inbounds i32, i32* %98, i64 %101
%103 = load i32, i32* %102
%104 = load i32*, i32** %11
%105 = load i32, i32* %14
%106 = add nsw i32 %105, 1
store i32 %106, i32* %14
%107 = sext i32 %105 to i64
%108 = getelementptr inbounds i32, i32* %104, i64 %107
store i32 %103, i32* %108
br label %93
109: ; preds = %93
%110 = load i32, i32* %7
store i32 %110, i32* %15
br label %111
111: ; preds = %125, %109
%112 = load i32, i32* %15
%113 = load i32, i32* %8
%114 = icmp sle i32 %112, %113
br i1 %114, label %115, label %128
115: ; preds = %111
%116 = load i32*, i32** %11
%117 = load i32, i32* %15
%118 = sext i32 %117 to i64
%119 = getelementptr inbounds i32, i32* %116, i64 %118
%120 = load i32, i32* %119
%121 = load i32*, i32** %6
%122 = load i32, i32* %15
%123 = sext i32 %122 to i64
%124 = getelementptr inbounds i32, i32* %121, i64 %123
store i32 %120, i32* %124
br label %125
125: ; preds = %115
%126 = load i32, i32* %15
%127 = add nsw i32 %126, 1
store i32 %127, i32* %15
br label %111
128: ; preds = %111
%129 = load i32*, i32** %11
%130 = call i32 @free(i32* %129)
ret void
}

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