#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 scalar_t__ int64_t;

/* Variables and functions */
void sorter_grail_merge_left_with_x_buf(int64_t *arr, int L1, int L2, int M) {
  int p0 = 0, p1 = L1;
  L2 += L1;
  while (p1 < L2) {
    if (p0 == L1 || ((*(arr + p0)) - (*(arr + p1))) > 0) {
      arr[M++] = arr[p1++];
    } else {
      arr[M++] = arr[p0++];
    }
  }
  if (M != p0)
    while (p0 < L1) {
      arr[M++] = arr[p0++];
    }
}


x86 assembly (clang, -O0):
<sorter_grail_merge_left_with_x_buf>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    %ecx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
mov    -0xc(%rbp),%eax
mov    %eax,-0x1c(%rbp)
mov    -0xc(%rbp),%eax
add    -0x10(%rbp),%eax
mov    %eax,-0x10(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x10(%rbp),%eax
jge    11c3 <sorter_grail_merge_left_with_x_buf+0xc3>
mov    -0x18(%rbp),%eax
cmp    -0xc(%rbp),%eax
je     1161 <sorter_grail_merge_left_with_x_buf+0x61>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x8(%rbp),%rcx
movslq -0x1c(%rbp),%rdx
sub    (%rcx,%rdx,8),%rax
cmp    $0x0,%rax
jle    1192 <sorter_grail_merge_left_with_x_buf+0x92>
mov    -0x8(%rbp),%rax
mov    -0x1c(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x1c(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x14(%rbp)
movslq %ecx,%rcx
mov    %rdx,(%rax,%rcx,8)
jmp    11be <sorter_grail_merge_left_with_x_buf+0xbe>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x18(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x14(%rbp)
movslq %ecx,%rcx
mov    %rdx,(%rax,%rcx,8)
jmp    1127 <sorter_grail_merge_left_with_x_buf+0x27>
mov    -0x14(%rbp),%eax
cmp    -0x18(%rbp),%eax
je     1216 <sorter_grail_merge_left_with_x_buf+0x116>
jmp    11d4 <sorter_grail_merge_left_with_x_buf+0xd4>
mov    -0x18(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1211 <sorter_grail_merge_left_with_x_buf+0x111>
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%ecx
mov    %ecx,%edx
add    $0x1,%edx
mov    %edx,-0x18(%rbp)
movslq %ecx,%rcx
mov    (%rax,%rcx,8),%rdx
mov    -0x8(%rbp),%rax
mov    -0x14(%rbp),%ecx
mov    %ecx,%esi
add    $0x1,%esi
mov    %esi,-0x14(%rbp)
movslq %ecx,%rcx
mov    %rdx,(%rax,%rcx,8)
jmp    11d4 <sorter_grail_merge_left_with_x_buf+0xd4>
jmp    1216 <sorter_grail_merge_left_with_x_buf+0x116>
pop    %rbp
ret

x86 assembly (clang, -O2):
<sorter_grail_merge_left_with_x_buf>:
push   %r15
push   %r14
push   %rbx
test   %edx,%edx
jle    116c <sorter_grail_merge_left_with_x_buf+0x6c>
add    %esi,%edx
movslq %ecx,%rax
lea    (%rdi,%rax,8),%rax
xor    %r8d,%r8d
mov    %esi,%r9d
jmp    1133 <sorter_grail_merge_left_with_x_buf+0x33>
nopw   0x0(%rax,%rax,1)
add    $0x1,%r8d
mov    %r10,(%rax)
add    $0x8,%rax
add    $0x1,%ecx
cmp    %edx,%r9d
jge    116f <sorter_grail_merge_left_with_x_buf+0x6f>
cmp    %esi,%r8d
jne    1150 <sorter_grail_merge_left_with_x_buf+0x50>
movslq %r9d,%rbx
mov    (%rdi,%rbx,8),%rbx
jmp    1163 <sorter_grail_merge_left_with_x_buf+0x63>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movslq %r8d,%rbx
mov    (%rdi,%rbx,8),%r10
movslq %r9d,%rbx
mov    (%rdi,%rbx,8),%rbx
cmp    %rbx,%r10
jle    1120 <sorter_grail_merge_left_with_x_buf+0x20>
add    $0x1,%r9d
mov    %rbx,%r10
jmp    1124 <sorter_grail_merge_left_with_x_buf+0x24>
xor    %r8d,%r8d
cmp    %r8d,%ecx
je     12ef <sorter_grail_merge_left_with_x_buf+0x1ef>
cmp    %esi,%r8d
jge    12ef <sorter_grail_merge_left_with_x_buf+0x1ef>
movslq %r8d,%r15
movslq %ecx,%r14
movslq %esi,%r11
mov    %r11,%r8
sub    %r15,%r8
cmp    $0x4,%r8
jb     125e <sorter_grail_merge_left_with_x_buf+0x15e>
lea    (%rdi,%r14,8),%rax
lea    (%rdi,%r11,8),%rcx
cmp    %rcx,%rax
jae    11bf <sorter_grail_merge_left_with_x_buf+0xbf>
lea    (%r14,%r11,1),%rax
sub    %r15,%rax
lea    (%rdi,%rax,8),%rax
lea    (%rdi,%r15,8),%rcx
cmp    %rax,%rcx
jb     125e <sorter_grail_merge_left_with_x_buf+0x15e>
mov    %r8,%r9
and    $0xfffffffffffffffc,%r9
lea    -0x4(%r9),%rax
mov    %rax,%r10
shr    $0x2,%r10
add    $0x1,%r10
test   %rax,%rax
je     12f5 <sorter_grail_merge_left_with_x_buf+0x1f5>
mov    %r10,%rbx
and    $0xfffffffffffffffe,%rbx
lea    (%rdi,%r14,8),%rcx
add    $0x30,%rcx
lea    (%rdi,%r15,8),%rdx
add    $0x30,%rdx
xor    %eax,%eax
nopw   0x0(%rax,%rax,1)
movups -0x30(%rdx,%rax,8),%xmm0
movups -0x20(%rdx,%rax,8),%xmm1
movups %xmm0,-0x30(%rcx,%rax,8)
movups %xmm1,-0x20(%rcx,%rax,8)
movups -0x10(%rdx,%rax,8),%xmm0
movups (%rdx,%rax,8),%xmm1
movups %xmm0,-0x10(%rcx,%rax,8)
movups %xmm1,(%rcx,%rax,8)
add    $0x8,%rax
add    $0xfffffffffffffffe,%rbx
jne    1200 <sorter_grail_merge_left_with_x_buf+0x100>
test   $0x1,%r10b
je     124f <sorter_grail_merge_left_with_x_buf+0x14f>
lea    (%rax,%r14,1),%rcx
add    %r15,%rax
movups (%rdi,%rax,8),%xmm0
movups 0x10(%rdi,%rax,8),%xmm1
movups %xmm0,(%rdi,%rcx,8)
movups %xmm1,0x10(%rdi,%rcx,8)
cmp    %r9,%r8
je     12ef <sorter_grail_merge_left_with_x_buf+0x1ef>
add    %r9,%r14
add    %r9,%r15
sub    %r15d,%esi
mov    %r15,%r8
not    %r8
add    %r11,%r8
and    $0x3,%rsi
je     129b <sorter_grail_merge_left_with_x_buf+0x19b>
neg    %rsi
xor    %eax,%eax
mov    %rdi,%rcx
nopl   0x0(%rax,%rax,1)
mov    (%rcx,%r15,8),%rdx
mov    %rdx,(%rcx,%r14,8)
add    $0x8,%rcx
add    $0xffffffffffffffff,%rax
cmp    %rax,%rsi
jne    1280 <sorter_grail_merge_left_with_x_buf+0x180>
sub    %rax,%r14
sub    %rax,%r15
cmp    $0x3,%r8
jb     12ef <sorter_grail_merge_left_with_x_buf+0x1ef>
lea    (%rdi,%r14,8),%rax
add    $0x18,%rax
sub    %r15,%r11
lea    (%rdi,%r15,8),%rcx
add    $0x18,%rcx
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
mov    -0x18(%rcx,%rdx,8),%rsi
mov    %rsi,-0x18(%rax,%rdx,8)
mov    -0x10(%rcx,%rdx,8),%rsi
mov    %rsi,-0x10(%rax,%rdx,8)
mov    -0x8(%rcx,%rdx,8),%rsi
mov    %rsi,-0x8(%rax,%rdx,8)
mov    (%rcx,%rdx,8),%rsi
mov    %rsi,(%rax,%rdx,8)
add    $0x4,%rdx
cmp    %rdx,%r11
jne    12c0 <sorter_grail_merge_left_with_x_buf+0x1c0>
pop    %rbx
pop    %r14
pop    %r15
ret
xor    %eax,%eax
test   $0x1,%r10b
jne    1236 <sorter_grail_merge_left_with_x_buf+0x136>
jmp    124f <sorter_grail_merge_left_with_x_buf+0x14f>

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

LLVM IR (-O2):
define void @sorter_grail_merge_left_with_x_buf(i64* nocapture %0, i32 %1, i32 %2, i32 %3) {
%5 = add nsw i32 %2, %1
%6 = icmp sgt i32 %2, 0
br i1 %6, label %7, label %40
7: ; preds = %4
%8 = sext i32 %3 to i64
br label %9
9: ; preds = %7, %31
%10 = phi i64 [ %8, %7 ], [ %36, %31 ]
%11 = phi i32 [ %1, %7 ], [ %34, %31 ]
%12 = phi i32 [ 0, %7 ], [ %33, %31 ]
%13 = icmp eq i32 %12, %1
br i1 %13, label %14, label %18
14: ; preds = %9
%15 = sext i32 %11 to i64
%16 = getelementptr inbounds i64, i64* %0, i64 %15
%17 = load i64, i64* %16
br label %26
18: ; preds = %9
%19 = sext i32 %12 to i64
%20 = getelementptr inbounds i64, i64* %0, i64 %19
%21 = load i64, i64* %20
%22 = sext i32 %11 to i64
%23 = getelementptr inbounds i64, i64* %0, i64 %22
%24 = load i64, i64* %23
%25 = icmp sgt i64 %21, %24
br i1 %25, label %26, label %29
26: ; preds = %14, %18
%27 = phi i64 [ %17, %14 ], [ %24, %18 ]
%28 = add nsw i32 %11, 1
br label %31
29: ; preds = %18
%30 = add nsw i32 %12, 1
br label %31
31: ; preds = %29, %26
%32 = phi i64 [ %21, %29 ], [ %27, %26 ]
%33 = phi i32 [ %30, %29 ], [ %12, %26 ]
%34 = phi i32 [ %11, %29 ], [ %28, %26 ]
%35 = getelementptr inbounds i64, i64* %0, i64 %10
store i64 %32, i64* %35
%36 = add i64 %10, 1
%37 = icmp slt i32 %34, %5
br i1 %37, label %9, label %38
38: ; preds = %31
%39 = trunc i64 %36 to i32
br label %40
40: ; preds = %38, %4
%41 = phi i32 [ %3, %4 ], [ %39, %38 ]
%42 = phi i32 [ 0, %4 ], [ %33, %38 ]
%43 = icmp ne i32 %41, %42
%44 = icmp slt i32 %42, %1
%45 = and i1 %43, %44
br i1 %45, label %46, label %169
46: ; preds = %40
%47 = sext i32 %42 to i64
%48 = sext i32 %41 to i64
%49 = sext i32 %1 to i64
%50 = sub nsw i64 %49, %47
%51 = icmp ult i64 %50, 4
br i1 %51, label %122, label %52
52: ; preds = %46
%53 = getelementptr i64, i64* %0, i64 %48
%54 = add nsw i64 %48, %49
%55 = sub nsw i64 %54, %47
%56 = getelementptr i64, i64* %0, i64 %55
%57 = getelementptr i64, i64* %0, i64 %47
%58 = getelementptr i64, i64* %0, i64 %49
%59 = icmp ult i64* %53, %58
%60 = icmp ult i64* %57, %56
%61 = and i1 %59, %60
br i1 %61, label %122, label %62
62: ; preds = %52
%63 = and i64 %50, -4
%64 = add nsw i64 %63, %48
%65 = add nsw i64 %63, %47
%66 = add nsw i64 %63, -4
%67 = lshr exact i64 %66, 2
%68 = add nuw nsw i64 %67, 1
%69 = and i64 %68, 1
%70 = icmp eq i64 %66, 0
br i1 %70, label %104, label %71
71: ; preds = %62
%72 = and i64 %68, 9223372036854775806
br label %73
73: ; preds = %73, %71
%74 = phi i64 [ 0, %71 ], [ %101, %73 ]
%75 = phi i64 [ 0, %71 ], [ %102, %73 ]
%76 = add i64 %74, %48
%77 = add i64 %74, %47
%78 = getelementptr inbounds i64, i64* %0, i64 %77
%79 = bitcast i64* %78 to <2 x i64>*
%80 = load <2 x i64>, <2 x i64>* %79
%81 = getelementptr inbounds i64, i64* %78, i64 2
%82 = bitcast i64* %81 to <2 x i64>*
%83 = load <2 x i64>, <2 x i64>* %82
%84 = getelementptr inbounds i64, i64* %0, i64 %76
%85 = bitcast i64* %84 to <2 x i64>*
store <2 x i64> %80, <2 x i64>* %85
%86 = getelementptr inbounds i64, i64* %84, i64 2
%87 = bitcast i64* %86 to <2 x i64>*
store <2 x i64> %83, <2 x i64>* %87
%88 = or i64 %74, 4
%89 = add i64 %88, %48
%90 = add i64 %88, %47
%91 = getelementptr inbounds i64, i64* %0, i64 %90
%92 = bitcast i64* %91 to <2 x i64>*
%93 = load <2 x i64>, <2 x i64>* %92
%94 = getelementptr inbounds i64, i64* %91, i64 2
%95 = bitcast i64* %94 to <2 x i64>*
%96 = load <2 x i64>, <2 x i64>* %95
%97 = getelementptr inbounds i64, i64* %0, i64 %89
%98 = bitcast i64* %97 to <2 x i64>*
store <2 x i64> %93, <2 x i64>* %98
%99 = getelementptr inbounds i64, i64* %97, i64 2
%100 = bitcast i64* %99 to <2 x i64>*
store <2 x i64> %96, <2 x i64>* %100
%101 = add nuw i64 %74, 8
%102 = add i64 %75, 2
%103 = icmp eq i64 %102, %72
br i1 %103, label %104, label %73
104: ; preds = %73, %62
%105 = phi i64 [ 0, %62 ], [ %101, %73 ]
%106 = icmp eq i64 %69, 0
br i1 %106, label %120, label %107
107: ; preds = %104
%108 = add i64 %105, %48
%109 = add i64 %105, %47
%110 = getelementptr inbounds i64, i64* %0, i64 %109
%111 = bitcast i64* %110 to <2 x i64>*
%112 = load <2 x i64>, <2 x i64>* %111
%113 = getelementptr inbounds i64, i64* %110, i64 2
%114 = bitcast i64* %113 to <2 x i64>*
%115 = load <2 x i64>, <2 x i64>* %114
%116 = getelementptr inbounds i64, i64* %0, i64 %108
%117 = bitcast i64* %116 to <2 x i64>*
store <2 x i64> %112, <2 x i64>* %117
%118 = getelementptr inbounds i64, i64* %116, i64 2
%119 = bitcast i64* %118 to <2 x i64>*
store <2 x i64> %115, <2 x i64>* %119
br label %120
120: ; preds = %104, %107
%121 = icmp eq i64 %50, %63
br i1 %121, label %169, label %122
122: ; preds = %52, %46, %120
%123 = phi i64 [ %48, %52 ], [ %48, %46 ], [ %64, %120 ]
%124 = phi i64 [ %47, %52 ], [ %47, %46 ], [ %65, %120 ]
%125 = sub nsw i64 %49, %124
%126 = xor i64 %124, -1
%127 = add nsw i64 %126, %49
%128 = and i64 %125, 3
%129 = icmp eq i64 %128, 0
br i1 %129, label %141, label %130
130: ; preds = %122, %130
%131 = phi i64 [ %137, %130 ], [ %123, %122 ]
%132 = phi i64 [ %134, %130 ], [ %124, %122 ]
%133 = phi i64 [ %139, %130 ], [ 0, %122 ]
%134 = add nsw i64 %132, 1
%135 = getelementptr inbounds i64, i64* %0, i64 %132
%136 = load i64, i64* %135
%137 = add nsw i64 %131, 1
%138 = getelementptr inbounds i64, i64* %0, i64 %131
store i64 %136, i64* %138
%139 = add i64 %133, 1
%140 = icmp eq i64 %139, %128
br i1 %140, label %141, label %130
141: ; preds = %130, %122
%142 = phi i64 [ %123, %122 ], [ %137, %130 ]
%143 = phi i64 [ %124, %122 ], [ %134, %130 ]
%144 = icmp ult i64 %127, 3
br i1 %144, label %169, label %145
145: ; preds = %141, %145
%146 = phi i64 [ %166, %145 ], [ %142, %141 ]
%147 = phi i64 [ %163, %145 ], [ %143, %141 ]
%148 = add nsw i64 %147, 1
%149 = getelementptr inbounds i64, i64* %0, i64 %147
%150 = load i64, i64* %149
%151 = add nsw i64 %146, 1
%152 = getelementptr inbounds i64, i64* %0, i64 %146
store i64 %150, i64* %152
%153 = add nsw i64 %147, 2
%154 = getelementptr inbounds i64, i64* %0, i64 %148
%155 = load i64, i64* %154
%156 = add nsw i64 %146, 2
%157 = getelementptr inbounds i64, i64* %0, i64 %151
store i64 %155, i64* %157
%158 = add nsw i64 %147, 3
%159 = getelementptr inbounds i64, i64* %0, i64 %153
%160 = load i64, i64* %159
%161 = add nsw i64 %146, 3
%162 = getelementptr inbounds i64, i64* %0, i64 %156
store i64 %160, i64* %162
%163 = add nsw i64 %147, 4
%164 = getelementptr inbounds i64, i64* %0, i64 %158
%165 = load i64, i64* %164
%166 = add nsw i64 %146, 4
%167 = getelementptr inbounds i64, i64* %0, i64 %161
store i64 %165, i64* %167
%168 = icmp eq i64 %163, %49
br i1 %168, label %169, label %145
169: ; preds = %141, %145, %120, %40
ret void
}