#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(unsigned char);
short **generate_matrix(unsigned char size) {
  unsigned char i;
  short **matrix;
  matrix = malloc(size * sizeof(short *));
  for (i = 0; i < size; i++) {
    matrix[i] = malloc(size * sizeof(short));
  }
  return matrix;
}


x86 assembly (clang, -O0):
<generate_matrix>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
movzbl -0x1(%rbp),%eax
shl    $0x3,%rax
movzbl %al,%edi
call   1030 <malloc@plt>
mov    %rax,-0x10(%rbp)
movb   $0x0,-0x2(%rbp)
movzbl -0x2(%rbp),%eax
movzbl -0x1(%rbp),%ecx
cmp    %ecx,%eax
jge    1172 <generate_matrix+0x62>
movzbl -0x1(%rbp),%eax
shl    $0x1,%rax
movzbl %al,%edi
call   1030 <malloc@plt>
mov    %rax,%rdx
mov    -0x10(%rbp),%rax
movzbl -0x2(%rbp),%ecx
mov    %rdx,(%rax,%rcx,8)
mov    -0x2(%rbp),%al
add    $0x1,%al
mov    %al,-0x2(%rbp)
jmp    1136 <generate_matrix+0x26>
mov    -0x10(%rbp),%rax
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<generate_matrix>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %edi,%r14d
lea    0x0(,%r14,8),%eax
movzbl %al,%edi
call   1030 <malloc@plt>
mov    %rax,%r15
test   %r14d,%r14d
je     1154 <generate_matrix+0x44>
movzbl %r14b,%r12d
lea    (%r14,%r14,1),%eax
xor    %ebx,%ebx
movzbl %al,%ebp
mov    %ebp,%edi
call   1030 <malloc@plt>
mov    %rax,(%r15,%rbx,8)
add    $0x1,%rbx
cmp    %rbx,%r12
jne    1140 <generate_matrix+0x30>
mov    %r15,%rax
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i16** @generate_matrix(i8 zeroext %0) {
%2 = alloca i8
%3 = alloca i8
%4 = alloca i16**
store i8 %0, i8* %2
%5 = load i8, i8* %2
%6 = zext i8 %5 to i64
%7 = mul i64 %6, 8
%8 = trunc i64 %7 to i8
%9 = call i8* @malloc(i8 zeroext %8)
%10 = bitcast i8* %9 to i16**
store i16** %10, i16*** %4
store i8 0, i8* %3
br label %11
11: ; preds = %28, %1
%12 = load i8, i8* %3
%13 = zext i8 %12 to i32
%14 = load i8, i8* %2
%15 = zext i8 %14 to i32
%16 = icmp slt i32 %13, %15
br i1 %16, label %17, label %31
17: ; preds = %11
%18 = load i8, i8* %2
%19 = zext i8 %18 to i64
%20 = mul i64 %19, 2
%21 = trunc i64 %20 to i8
%22 = call i8* @malloc(i8 zeroext %21)
%23 = bitcast i8* %22 to i16*
%24 = load i16**, i16*** %4
%25 = load i8, i8* %3
%26 = zext i8 %25 to i64
%27 = getelementptr inbounds i16*, i16** %24, i64 %26
store i16* %23, i16** %27
br label %28
28: ; preds = %17
%29 = load i8, i8* %3
%30 = add i8 %29, 1
store i8 %30, i8* %3
br label %11
31: ; preds = %11
%32 = load i16**, i16*** %4
ret i16** %32
}

LLVM IR (-O2):
define noalias i16** @generate_matrix(i8 zeroext %0) {
%2 = shl i8 %0, 3
%3 = tail call i8* @malloc(i8 zeroext %2)
%4 = bitcast i8* %3 to i16**
%5 = icmp eq i8 %0, 0
br i1 %5, label %16, label %6
6: ; preds = %1
%7 = shl i8 %0, 1
%8 = zext i8 %0 to i64
br label %9
9: ; preds = %6, %9
%10 = phi i64 [ 0, %6 ], [ %14, %9 ]
%11 = tail call i8* @malloc(i8 zeroext %7)
%12 = getelementptr inbounds i16*, i16** %4, i64 %10
%13 = bitcast i16** %12 to i8**
store i8* %11, i8** %13
%14 = add nuw nsw i64 %10, 1
%15 = icmp eq i64 %14, %8
br i1 %15, label %16, label %9
16: ; preds = %9, %1
ret i16** %4
}