#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 ListNode {
  int dummy;
};

/* Variables and functions */
int getListLength(struct ListNode *);
struct ListNode *getMiddleNode(struct ListNode *);
struct ListNode *mergeTwoLists(struct ListNode *, struct ListNode *);
struct ListNode *mergeList(struct ListNode *head) {
  struct ListNode *middle;
  struct ListNode *h;
  struct ListNode *m;
  struct ListNode *rn;
  if (getListLength(head) < 2)
    return head;
  middle = getMiddleNode(head);
  h = mergeList(head);
  m = mergeList(middle);
  rn = mergeTwoLists(h, m);
  return rn;
}


x86 assembly (clang, -O0):
<mergeList>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <getListLength@plt>
cmp    $0x2,%eax
jge    116b <mergeList+0x2b>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    11ab <mergeList+0x6b>
mov    -0x10(%rbp),%rdi
call   1040 <getMiddleNode@plt>
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rdi
call   1060 <mergeList@plt>
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rdi
call   1060 <mergeList@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1050 <mergeTwoLists@plt>
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<mergeList>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%rbx
call   1030 <getListLength@plt>
cmp    $0x1,%eax
jg     115c <mergeList+0x1c>
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
mov    %rbx,%rdi
call   1040 <getMiddleNode@plt>
mov    %rax,%r14
mov    %rbx,%rdi
call   1060 <mergeList@plt>
mov    %rax,%rbx
mov    %r14,%rdi
call   1060 <mergeList@plt>
mov    %rbx,%rdi
mov    %rax,%rsi
add    $0x8,%rsp
pop    %rbx
pop    %r14
jmp    1050 <mergeTwoLists@plt>

LLVM IR (-O0):
%struct.ListNode = type { i32 }
define %struct.ListNode* @mergeList(%struct.ListNode* %0) {
%2 = alloca %struct.ListNode*
%3 = alloca %struct.ListNode*
%4 = alloca %struct.ListNode*
%5 = alloca %struct.ListNode*
%6 = alloca %struct.ListNode*
%7 = alloca %struct.ListNode*
store %struct.ListNode* %0, %struct.ListNode** %3
%8 = load %struct.ListNode*, %struct.ListNode** %3
%9 = call i32 @getListLength(%struct.ListNode* %8)
%10 = icmp slt i32 %9, 2
br i1 %10, label %11, label %13
11: ; preds = %1
%12 = load %struct.ListNode*, %struct.ListNode** %3
store %struct.ListNode* %12, %struct.ListNode** %2
br label %24
13: ; preds = %1
%14 = load %struct.ListNode*, %struct.ListNode** %3
%15 = call %struct.ListNode* @getMiddleNode(%struct.ListNode* %14)
store %struct.ListNode* %15, %struct.ListNode** %4
%16 = load %struct.ListNode*, %struct.ListNode** %3
%17 = call %struct.ListNode* @mergeList(%struct.ListNode* %16)
store %struct.ListNode* %17, %struct.ListNode** %5
%18 = load %struct.ListNode*, %struct.ListNode** %4
%19 = call %struct.ListNode* @mergeList(%struct.ListNode* %18)
store %struct.ListNode* %19, %struct.ListNode** %6
%20 = load %struct.ListNode*, %struct.ListNode** %5
%21 = load %struct.ListNode*, %struct.ListNode** %6
%22 = call %struct.ListNode* @mergeTwoLists(%struct.ListNode* %20, %struct.ListNode* %21)
store %struct.ListNode* %22, %struct.ListNode** %7
%23 = load %struct.ListNode*, %struct.ListNode** %7
store %struct.ListNode* %23, %struct.ListNode** %2
br label %24
24: ; preds = %13, %11
%25 = load %struct.ListNode*, %struct.ListNode** %2
ret %struct.ListNode* %25
}

LLVM IR (-O2):
%struct.ListNode = type { i32 }
define %struct.ListNode* @mergeList(%struct.ListNode* %0) {
%2 = tail call i32 @getListLength(%struct.ListNode* %0)
%3 = icmp slt i32 %2, 2
br i1 %3, label %4, label %6
4: ; preds = %1, %6
%5 = phi %struct.ListNode* [ %10, %6 ], [ %0, %1 ]
ret %struct.ListNode* %5
6: ; preds = %1
%7 = tail call %struct.ListNode* @getMiddleNode(%struct.ListNode* %0)
%8 = tail call %struct.ListNode* @mergeList(%struct.ListNode* %0)
%9 = tail call %struct.ListNode* @mergeList(%struct.ListNode* %7)
%10 = tail call %struct.ListNode* @mergeTwoLists(%struct.ListNode* %8, %struct.ListNode* %9)
br label %4
}