#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 */
void *malloc_or_die(int);
int **allocate_matrix(int M, int N, int fill) {
  int i, j;
  int **matrix = malloc_or_die(M * sizeof(int *));
  for (i = 0; i < M; i++)
    matrix[i] = malloc_or_die(N * sizeof(int));
  for (i = 0; i < M; i++)
    for (j = 0; j < N; j++)
      matrix[i][j] = fill;
  return matrix;
}


x86 assembly (clang, -O0):
<allocate_matrix>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
mov    %edx,-0xc(%rbp)
movslq -0x4(%rbp),%rax
shl    $0x3,%rax
mov    %eax,%edi
call   1030 <malloc_or_die@plt>
mov    %rax,-0x20(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    1173 <allocate_matrix+0x63>
movslq -0x8(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edi
call   1030 <malloc_or_die@plt>
mov    %rax,%rdx
mov    -0x20(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    %rdx,(%rax,%rcx,8)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    113b <allocate_matrix+0x2b>
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0x4(%rbp),%eax
jge    11d0 <allocate_matrix+0xc0>
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    11bd <allocate_matrix+0xad>
mov    -0xc(%rbp),%edx
mov    -0x20(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x14(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    118d <allocate_matrix+0x7d>
jmp    11c2 <allocate_matrix+0xb2>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    117a <allocate_matrix+0x6a>
mov    -0x20(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<allocate_matrix>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %edx,%ebx
mov    %esi,%r14d
mov    %edi,%r12d
lea    0x0(,%r12,8),%edi
call   1030 <malloc_or_die@plt>
mov    %rax,%r15
test   %r12d,%r12d
jle    12d1 <allocate_matrix+0x1c1>
lea    0x0(,%r14,4),%ebp
mov    %r12,(%rsp)
mov    %r12d,%r13d
xor    %r12d,%r12d
xchg   %ax,%ax
mov    %ebp,%edi
call   1030 <malloc_or_die@plt>
mov    %rax,(%r15,%r12,8)
add    $0x1,%r12
cmp    %r12,%r13
jne    1150 <allocate_matrix+0x40>
cmpl   $0x0,(%rsp)
jle    12d1 <allocate_matrix+0x1c1>
mov    %r14d,%eax
mov    %eax,%r11d
and    $0xfffffff8,%r11d
lea    -0x8(%r11),%r8
mov    %r8,%r9
shr    $0x3,%r9
add    $0x1,%r9
movd   %ebx,%xmm0
pshufd $0x0,%xmm0,%xmm0
mov    %r9d,%r10d
and    $0x7,%r10d
and    $0xfffffffffffffff8,%r9
mov    %r10,%rdi
shl    $0x5,%rdi
xor    %ebp,%ebp
jmp    11bd <allocate_matrix+0xad>
cs nopw 0x0(%rax,%rax,1)
add    $0x1,%rbp
cmp    %r13,%rbp
je     12d1 <allocate_matrix+0x1c1>
test   %r14d,%r14d
jle    11b0 <allocate_matrix+0xa0>
mov    (%r15,%rbp,8),%rdx
cmp    $0x8,%r14d
jae    11e0 <allocate_matrix+0xd0>
xor    %ecx,%ecx
jmp    12c0 <allocate_matrix+0x1b0>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
cmp    $0x38,%r8
jae    11ed <allocate_matrix+0xdd>
xor    %esi,%esi
jmp    1285 <allocate_matrix+0x175>
mov    %r9,%rcx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movdqu %xmm0,(%rdx,%rsi,4)
movdqu %xmm0,0x10(%rdx,%rsi,4)
movdqu %xmm0,0x20(%rdx,%rsi,4)
movdqu %xmm0,0x30(%rdx,%rsi,4)
movdqu %xmm0,0x40(%rdx,%rsi,4)
movdqu %xmm0,0x50(%rdx,%rsi,4)
movdqu %xmm0,0x60(%rdx,%rsi,4)
movdqu %xmm0,0x70(%rdx,%rsi,4)
movdqu %xmm0,0x80(%rdx,%rsi,4)
movdqu %xmm0,0x90(%rdx,%rsi,4)
movdqu %xmm0,0xa0(%rdx,%rsi,4)
movdqu %xmm0,0xb0(%rdx,%rsi,4)
movdqu %xmm0,0xc0(%rdx,%rsi,4)
movdqu %xmm0,0xd0(%rdx,%rsi,4)
movdqu %xmm0,0xe0(%rdx,%rsi,4)
movdqu %xmm0,0xf0(%rdx,%rsi,4)
add    $0x40,%rsi
add    $0xfffffffffffffff8,%rcx
jne    1200 <allocate_matrix+0xf0>
test   %r10,%r10
je     12b4 <allocate_matrix+0x1a4>
lea    (%rdx,%rsi,4),%rcx
add    $0x10,%rcx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movdqu %xmm0,-0x10(%rcx,%rsi,1)
movdqu %xmm0,(%rcx,%rsi,1)
add    $0x20,%rsi
cmp    %rsi,%rdi
jne    12a0 <allocate_matrix+0x190>
mov    %r11,%rcx
cmp    %rax,%r11
je     11b0 <allocate_matrix+0xa0>
mov    %ebx,(%rdx,%rcx,4)
add    $0x1,%rcx
cmp    %rcx,%rax
jne    12c0 <allocate_matrix+0x1b0>
jmp    11b0 <allocate_matrix+0xa0>
mov    %r15,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32** @allocate_matrix(i32 %0, i32 %1, i32 %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32**
store i32 %0, i32* %4
store i32 %1, i32* %5
store i32 %2, i32* %6
%10 = load i32, i32* %4
%11 = sext i32 %10 to i64
%12 = mul i64 %11, 8
%13 = trunc i64 %12 to i32
%14 = call i8* @malloc_or_die(i32 %13)
%15 = bitcast i8* %14 to i32**
store i32** %15, i32*** %9
store i32 0, i32* %7
br label %16
16: ; preds = %31, %3
%17 = load i32, i32* %7
%18 = load i32, i32* %4
%19 = icmp slt i32 %17, %18
br i1 %19, label %20, label %34
20: ; preds = %16
%21 = load i32, i32* %5
%22 = sext i32 %21 to i64
%23 = mul i64 %22, 4
%24 = trunc i64 %23 to i32
%25 = call i8* @malloc_or_die(i32 %24)
%26 = bitcast i8* %25 to i32*
%27 = load i32**, i32*** %9
%28 = load i32, i32* %7
%29 = sext i32 %28 to i64
%30 = getelementptr inbounds i32*, i32** %27, i64 %29
store i32* %26, i32** %30
br label %31
31: ; preds = %20
%32 = load i32, i32* %7
%33 = add nsw i32 %32, 1
store i32 %33, i32* %7
br label %16
34: ; preds = %16
store i32 0, i32* %7
br label %35
35: ; preds = %58, %34
%36 = load i32, i32* %7
%37 = load i32, i32* %4
%38 = icmp slt i32 %36, %37
br i1 %38, label %39, label %61
39: ; preds = %35
store i32 0, i32* %8
br label %40
40: ; preds = %54, %39
%41 = load i32, i32* %8
%42 = load i32, i32* %5
%43 = icmp slt i32 %41, %42
br i1 %43, label %44, label %57
44: ; preds = %40
%45 = load i32, i32* %6
%46 = load i32**, i32*** %9
%47 = load i32, i32* %7
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds i32*, i32** %46, i64 %48
%50 = load i32*, i32** %49
%51 = load i32, i32* %8
%52 = sext i32 %51 to i64
%53 = getelementptr inbounds i32, i32* %50, i64 %52
store i32 %45, i32* %53
br label %54
54: ; preds = %44
%55 = load i32, i32* %8
%56 = add nsw i32 %55, 1
store i32 %56, i32* %8
br label %40
57: ; preds = %40
br label %58
58: ; preds = %57
%59 = load i32, i32* %7
%60 = add nsw i32 %59, 1
store i32 %60, i32* %7
br label %35
61: ; preds = %35
%62 = load i32**, i32*** %9
ret i32** %62
}

LLVM IR (-O2):
define i32** @allocate_matrix(i32 %0, i32 %1, i32 %2) {
%4 = shl i32 %0, 3
%5 = tail call i8* @malloc_or_die(i32 %4)
%6 = bitcast i8* %5 to i32**
%7 = icmp sgt i32 %0, 0
br i1 %7, label %8, label %112
8: ; preds = %3
%9 = shl i32 %1, 2
%10 = zext i32 %0 to i64
br label %31
11: ; preds = %31
br i1 %7, label %12, label %112
12: ; preds = %11
%13 = icmp sgt i32 %1, 0
%14 = zext i32 %0 to i64
%15 = zext i32 %1 to i64
%16 = and i64 %15, 4294967288
%17 = add nsw i64 %16, -8
%18 = lshr exact i64 %17, 3
%19 = add nuw nsw i64 %18, 1
%20 = icmp ult i32 %1, 8
%21 = and i64 %15, 4294967288
%22 = insertelement <4 x i32> poison, i32 %2, i64 0
%23 = shufflevector <4 x i32> %22, <4 x i32> poison, <4 x i32> zeroinitializer
%24 = insertelement <4 x i32> poison, i32 %2, i64 0
%25 = shufflevector <4 x i32> %24, <4 x i32> poison, <4 x i32> zeroinitializer
%26 = and i64 %19, 7
%27 = icmp ult i64 %17, 56
%28 = and i64 %19, 4611686018427387896
%29 = icmp eq i64 %26, 0
%30 = icmp eq i64 %21, %15
br label %38
31: ; preds = %8, %31
%32 = phi i64 [ 0, %8 ], [ %36, %31 ]
%33 = tail call i8* @malloc_or_die(i32 %9)
%34 = getelementptr inbounds i32*, i32** %6, i64 %32
%35 = bitcast i32** %34 to i8**
store i8* %33, i8** %35
%36 = add nuw nsw i64 %32, 1
%37 = icmp eq i64 %36, %10
br i1 %37, label %11, label %31
38: ; preds = %12, %109
%39 = phi i64 [ 0, %12 ], [ %110, %109 ]
br i1 %13, label %40, label %109
40: ; preds = %38
%41 = getelementptr inbounds i32*, i32** %6, i64 %39
%42 = load i32*, i32** %41
br i1 %20, label %102, label %43
43: ; preds = %40
br i1 %27, label %89, label %44
44: ; preds = %43, %44
%45 = phi i64 [ %86, %44 ], [ 0, %43 ]
%46 = phi i64 [ %87, %44 ], [ 0, %43 ]
%47 = getelementptr inbounds i32, i32* %42, i64 %45
%48 = bitcast i32* %47 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %48
%49 = getelementptr inbounds i32, i32* %47, i64 4
%50 = bitcast i32* %49 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %50
%51 = or i64 %45, 8
%52 = getelementptr inbounds i32, i32* %42, i64 %51
%53 = bitcast i32* %52 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %53
%54 = getelementptr inbounds i32, i32* %52, i64 4
%55 = bitcast i32* %54 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %55
%56 = or i64 %45, 16
%57 = getelementptr inbounds i32, i32* %42, i64 %56
%58 = bitcast i32* %57 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %58
%59 = getelementptr inbounds i32, i32* %57, i64 4
%60 = bitcast i32* %59 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %60
%61 = or i64 %45, 24
%62 = getelementptr inbounds i32, i32* %42, i64 %61
%63 = bitcast i32* %62 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %63
%64 = getelementptr inbounds i32, i32* %62, i64 4
%65 = bitcast i32* %64 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %65
%66 = or i64 %45, 32
%67 = getelementptr inbounds i32, i32* %42, i64 %66
%68 = bitcast i32* %67 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %68
%69 = getelementptr inbounds i32, i32* %67, i64 4
%70 = bitcast i32* %69 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %70
%71 = or i64 %45, 40
%72 = getelementptr inbounds i32, i32* %42, i64 %71
%73 = bitcast i32* %72 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %73
%74 = getelementptr inbounds i32, i32* %72, i64 4
%75 = bitcast i32* %74 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %75
%76 = or i64 %45, 48
%77 = getelementptr inbounds i32, i32* %42, i64 %76
%78 = bitcast i32* %77 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %78
%79 = getelementptr inbounds i32, i32* %77, i64 4
%80 = bitcast i32* %79 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %80
%81 = or i64 %45, 56
%82 = getelementptr inbounds i32, i32* %42, i64 %81
%83 = bitcast i32* %82 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %83
%84 = getelementptr inbounds i32, i32* %82, i64 4
%85 = bitcast i32* %84 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %85
%86 = add nuw i64 %45, 64
%87 = add nuw i64 %46, 8
%88 = icmp eq i64 %87, %28
br i1 %88, label %89, label %44
89: ; preds = %44, %43
%90 = phi i64 [ 0, %43 ], [ %86, %44 ]
br i1 %29, label %101, label %91
91: ; preds = %89, %91
%92 = phi i64 [ %98, %91 ], [ %90, %89 ]
%93 = phi i64 [ %99, %91 ], [ 0, %89 ]
%94 = getelementptr inbounds i32, i32* %42, i64 %92
%95 = bitcast i32* %94 to <4 x i32>*
store <4 x i32> %23, <4 x i32>* %95
%96 = getelementptr inbounds i32, i32* %94, i64 4
%97 = bitcast i32* %96 to <4 x i32>*
store <4 x i32> %25, <4 x i32>* %97
%98 = add nuw i64 %92, 8
%99 = add i64 %93, 1
%100 = icmp eq i64 %99, %26
br i1 %100, label %101, label %91
101: ; preds = %91, %89
br i1 %30, label %109, label %102
102: ; preds = %40, %101
%103 = phi i64 [ 0, %40 ], [ %21, %101 ]
br label %104
104: ; preds = %102, %104
%105 = phi i64 [ %107, %104 ], [ %103, %102 ]
%106 = getelementptr inbounds i32, i32* %42, i64 %105
store i32 %2, i32* %106
%107 = add nuw nsw i64 %105, 1
%108 = icmp eq i64 %107, %15
br i1 %108, label %109, label %104
109: ; preds = %104, %101, %38
%110 = add nuw nsw i64 %39, 1
%111 = icmp eq i64 %110, %14
br i1 %111, label %112, label %38
112: ; preds = %109, %3, %11
ret i32** %6
}