void dataframe_copy(int **dest, int **src) {
  int i;
  if (dest[-1][0] < src[-1][1]) {
    dest = (int **)realloc(dest - 1, (src[-1][1] + 1) * sizeof(int *)) + 1;
    assert(dest);
    dest[-1][0] = src[-1][1];
  }
  memmove(dest[-1] + 1, src[-1] + 1, 3 * sizeof(int));
  for (i = 0; i < src[-1][1]; i++) {
    if (dest[i][-2] < src[i][-1]) {
      dest[i] = (int *)realloc(dest[i] - 2, (src[i][-1] + 2)) + 2;
      assert(dest[i]);
      dest[i][-2] = src[i][-1];
    }
    memmove(dest[i] - 1, src[i] - 1, (src[i][-1] + 1) * sizeof(int));
  }
}


x86 assembly (clang, -O0):
<dataframe_copy>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x8(%rax),%rax
mov    (%rax),%eax
mov    -0x10(%rbp),%rcx
mov    -0x8(%rcx),%rcx
cmp    0x4(%rcx),%eax
jge    11a5 <dataframe_copy+0x75>
mov    -0x8(%rbp),%rdi
add    $0xfffffffffffffff8,%rdi
mov    -0x10(%rbp),%rax
mov    -0x8(%rax),%rax
mov    0x4(%rax),%eax
add    $0x1,%eax
movslq %eax,%rsi
shl    $0x3,%rsi
call   1040 <realloc@plt>
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%rax
mov    -0x8(%rax),%rax
mov    0x4(%rax),%ecx
mov    -0x8(%rbp),%rax
mov    -0x8(%rax),%rax
mov    %ecx,(%rax)
mov    -0x8(%rbp),%rax
mov    -0x8(%rax),%rax
add    $0x4,%rax
mov    -0x10(%rbp),%rcx
mov    -0x8(%rcx),%rdx
add    $0x4,%rdx
mov    (%rdx),%rcx
mov    0x8(%rdx),%edx
mov    %edx,0x8(%rax)
mov    %rcx,(%rax)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
mov    -0x8(%rcx),%rcx
cmp    0x4(%rcx),%eax
jge    12c2 <dataframe_copy+0x192>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x8(%rax),%eax
mov    -0x10(%rbp),%rcx
movslq -0x14(%rbp),%rdx
mov    (%rcx,%rdx,8),%rcx
cmp    -0x4(%rcx),%eax
jge    1276 <dataframe_copy+0x146>
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rdi
add    $0xfffffffffffffff8,%rdi
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x4(%rax),%eax
add    $0x2,%eax
movslq %eax,%rsi
call   1040 <realloc@plt>
mov    %rax,%rdx
add    $0x8,%rdx
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rdi
mov    $0x0,%al
call   1030 <assert@plt>
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x4(%rax),%ecx
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rdx
mov    (%rax,%rdx,8),%rax
mov    %ecx,-0x8(%rax)
mov    -0x8(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rdi
add    $0xfffffffffffffffc,%rdi
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rsi
add    $0xfffffffffffffffc,%rsi
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x4(%rax),%eax
add    $0x1,%eax
movslq %eax,%rdx
shl    $0x2,%rdx
call   1050 <memmove@plt>
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    11d0 <dataframe_copy+0xa0>
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<dataframe_copy>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rsi,%r12
mov    %rdi,%r14
mov    -0x8(%rdi),%rax
mov    -0x8(%rsi),%rcx
movslq 0x4(%rcx),%rdx
cmp    %edx,(%rax)
jge    1180 <dataframe_copy+0x50>
add    $0xfffffffffffffff8,%r14
lea    0x8(,%rdx,8),%rsi
mov    %r14,%rdi
call   1040 <realloc@plt>
mov    %rax,%r15
lea    0x8(%rax),%r14
mov    %r14,%rdi
xor    %eax,%eax
call   1030 <assert@plt>
mov    -0x8(%r12),%rcx
mov    0x4(%rcx),%edx
mov    (%r15),%rax
mov    %edx,(%rax)
mov    0x4(%rcx),%rdx
mov    0xc(%rcx),%ecx
mov    %ecx,0xc(%rax)
mov    %rdx,0x4(%rax)
mov    -0x8(%r12),%rax
cmpl   $0x0,0x4(%rax)
jle    120b <dataframe_copy+0xdb>
xor    %ebx,%ebx
jmp    11c9 <dataframe_copy+0x99>
nopl   (%rax)
add    $0xfffffffffffffffc,%rdi
add    $0xfffffffffffffffc,%rsi
cltq
lea    0x4(,%rax,4),%rdx
call   1050 <memmove@plt>
add    $0x1,%rbx
mov    -0x8(%r12),%rax
movslq 0x4(%rax),%rax
cmp    %rax,%rbx
jge    120b <dataframe_copy+0xdb>
mov    (%r14,%rbx,8),%rdi
mov    (%r12,%rbx,8),%rsi
mov    -0x4(%rsi),%eax
cmp    %eax,-0x8(%rdi)
jge    11a0 <dataframe_copy+0x70>
add    $0xfffffffffffffff8,%rdi
movslq %eax,%rsi
add    $0x2,%rsi
call   1040 <realloc@plt>
lea    0x8(%rax),%rdi
mov    %rdi,(%r14,%rbx,8)
xor    %eax,%eax
call   1030 <assert@plt>
mov    (%r12,%rbx,8),%rsi
mov    -0x4(%rsi),%eax
mov    (%r14,%rbx,8),%rdi
mov    %eax,-0x8(%rdi)
mov    -0x4(%rsi),%eax
jmp    11a0 <dataframe_copy+0x70>
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define void @dataframe_copy(i32** %0, i32** %1) {
%3 = alloca i32**
%4 = alloca i32**
%5 = alloca i32
store i32** %0, i32*** %3
store i32** %1, i32*** %4
%6 = load i32**, i32*** %3
%7 = getelementptr inbounds i32*, i32** %6, i64 -1
%8 = load i32*, i32** %7
%9 = getelementptr inbounds i32, i32* %8, i64 0
%10 = load i32, i32* %9
%11 = load i32**, i32*** %4
%12 = getelementptr inbounds i32*, i32** %11, i64 -1
%13 = load i32*, i32** %12
%14 = getelementptr inbounds i32, i32* %13, i64 1
%15 = load i32, i32* %14
%16 = icmp slt i32 %10, %15
br i1 %16, label %17, label %43
17: ; preds = %2
%18 = load i32**, i32*** %3
%19 = getelementptr inbounds i32*, i32** %18, i64 -1
%20 = bitcast i32** %19 to i8*
%21 = load i32**, i32*** %4
%22 = getelementptr inbounds i32*, i32** %21, i64 -1
%23 = load i32*, i32** %22
%24 = getelementptr inbounds i32, i32* %23, i64 1
%25 = load i32, i32* %24
%26 = add nsw i32 %25, 1
%27 = sext i32 %26 to i64
%28 = mul i64 %27, 8
%29 = call i8* @realloc(i8* %20, i64 %28)
%30 = bitcast i8* %29 to i32**
%31 = getelementptr inbounds i32*, i32** %30, i64 1
store i32** %31, i32*** %3
%32 = load i32**, i32*** %3
%33 = call i32 (i32**, ...) bitcast (i32 (...)* @assert to i32 (i32**, ...)*)(i32** %32)
%34 = load i32**, i32*** %4
%35 = getelementptr inbounds i32*, i32** %34, i64 -1
%36 = load i32*, i32** %35
%37 = getelementptr inbounds i32, i32* %36, i64 1
%38 = load i32, i32* %37
%39 = load i32**, i32*** %3
%40 = getelementptr inbounds i32*, i32** %39, i64 -1
%41 = load i32*, i32** %40
%42 = getelementptr inbounds i32, i32* %41, i64 0
store i32 %38, i32* %42
br label %43
43: ; preds = %17, %2
%44 = load i32**, i32*** %3
%45 = getelementptr inbounds i32*, i32** %44, i64 -1
%46 = load i32*, i32** %45
%47 = getelementptr inbounds i32, i32* %46, i64 1
%48 = bitcast i32* %47 to i8*
%49 = load i32**, i32*** %4
%50 = getelementptr inbounds i32*, i32** %49, i64 -1
%51 = load i32*, i32** %50
%52 = getelementptr inbounds i32, i32* %51, i64 1
%53 = bitcast i32* %52 to i8*
store i32 0, i32* %5
br label %54
54: ; preds = %146, %43
%55 = load i32, i32* %5
%56 = load i32**, i32*** %4
%57 = getelementptr inbounds i32*, i32** %56, i64 -1
%58 = load i32*, i32** %57
%59 = getelementptr inbounds i32, i32* %58, i64 1
%60 = load i32, i32* %59
%61 = icmp slt i32 %55, %60
br i1 %61, label %62, label %149
62: ; preds = %54
%63 = load i32**, i32*** %3
%64 = load i32, i32* %5
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds i32*, i32** %63, i64 %65
%67 = load i32*, i32** %66
%68 = getelementptr inbounds i32, i32* %67, i64 -2
%69 = load i32, i32* %68
%70 = load i32**, i32*** %4
%71 = load i32, i32* %5
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds i32*, i32** %70, i64 %72
%74 = load i32*, i32** %73
%75 = getelementptr inbounds i32, i32* %74, i64 -1
%76 = load i32, i32* %75
%77 = icmp slt i32 %69, %76
br i1 %77, label %78, label %121
78: ; preds = %62
%79 = load i32**, i32*** %3
%80 = load i32, i32* %5
%81 = sext i32 %80 to i64
%82 = getelementptr inbounds i32*, i32** %79, i64 %81
%83 = load i32*, i32** %82
%84 = getelementptr inbounds i32, i32* %83, i64 -2
%85 = bitcast i32* %84 to i8*
%86 = load i32**, i32*** %4
%87 = load i32, i32* %5
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds i32*, i32** %86, i64 %88
%90 = load i32*, i32** %89
%91 = getelementptr inbounds i32, i32* %90, i64 -1
%92 = load i32, i32* %91
%93 = add nsw i32 %92, 2
%94 = sext i32 %93 to i64
%95 = call i8* @realloc(i8* %85, i64 %94)
%96 = bitcast i8* %95 to i32*
%97 = getelementptr inbounds i32, i32* %96, i64 2
%98 = load i32**, i32*** %3
%99 = load i32, i32* %5
%100 = sext i32 %99 to i64
%101 = getelementptr inbounds i32*, i32** %98, i64 %100
store i32* %97, i32** %101
%102 = load i32**, i32*** %3
%103 = load i32, i32* %5
%104 = sext i32 %103 to i64
%105 = getelementptr inbounds i32*, i32** %102, i64 %104
%106 = load i32*, i32** %105
%107 = call i32 (i32*, ...) bitcast (i32 (...)* @assert to i32 (i32*, ...)*)(i32* %106)
%108 = load i32**, i32*** %4
%109 = load i32, i32* %5
%110 = sext i32 %109 to i64
%111 = getelementptr inbounds i32*, i32** %108, i64 %110
%112 = load i32*, i32** %111
%113 = getelementptr inbounds i32, i32* %112, i64 -1
%114 = load i32, i32* %113
%115 = load i32**, i32*** %3
%116 = load i32, i32* %5
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds i32*, i32** %115, i64 %117
%119 = load i32*, i32** %118
%120 = getelementptr inbounds i32, i32* %119, i64 -2
store i32 %114, i32* %120
br label %121
121: ; preds = %78, %62
%122 = load i32**, i32*** %3
%123 = load i32, i32* %5
%124 = sext i32 %123 to i64
%125 = getelementptr inbounds i32*, i32** %122, i64 %124
%126 = load i32*, i32** %125
%127 = getelementptr inbounds i32, i32* %126, i64 -1
%128 = bitcast i32* %127 to i8*
%129 = load i32**, i32*** %4
%130 = load i32, i32* %5
%131 = sext i32 %130 to i64
%132 = getelementptr inbounds i32*, i32** %129, i64 %131
%133 = load i32*, i32** %132
%134 = getelementptr inbounds i32, i32* %133, i64 -1
%135 = bitcast i32* %134 to i8*
%136 = load i32**, i32*** %4
%137 = load i32, i32* %5
%138 = sext i32 %137 to i64
%139 = getelementptr inbounds i32*, i32** %136, i64 %138
%140 = load i32*, i32** %139
%141 = getelementptr inbounds i32, i32* %140, i64 -1
%142 = load i32, i32* %141
%143 = add nsw i32 %142, 1
%144 = sext i32 %143 to i64
%145 = mul i64 %144, 4
br label %146
146: ; preds = %121
%147 = load i32, i32* %5
%148 = add nsw i32 %147, 1
store i32 %148, i32* %5
br label %54
149: ; preds = %54
ret void
}

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