#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 */
double **dmatrix(size_t const, size_t const);
double **deye(const size_t n) {
  size_t i;
  double **m = dmatrix(n, n);
  for (i = 0; i < n; i++) {
    m[i][i] = 1.0;
  }
  return m;
}


x86 assembly (clang, -O0):
<deye>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x8(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x8(%rbp),%rsi
call   1030 <dmatrix@plt>
mov    %rax,-0x18(%rbp)
movq   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%rax
cmp    -0x8(%rbp),%rax
jae    1171 <deye+0x61>
mov    -0x18(%rbp),%rax
mov    -0x10(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x10(%rbp),%rcx
movsd  0xea5(%rip),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1135 <deye+0x25>
mov    -0x18(%rbp),%rax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<deye>:
push   %rbx
mov    %rdi,%rbx
mov    %rdi,%rsi
call   1030 <dmatrix@plt>
test   %rbx,%rbx
je     11a2 <deye+0x92>
lea    -0x1(%rbx),%rsi
mov    %ebx,%ecx
and    $0x3,%ecx
movabs $0x3ff0000000000000,%rdx
cmp    $0x3,%rsi
jae    1142 <deye+0x32>
xor    %esi,%esi
jmp    117f <deye+0x6f>
and    $0xfffffffffffffffc,%rbx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
mov    (%rax,%rsi,8),%rdi
mov    %rdx,(%rdi,%rsi,8)
mov    0x8(%rax,%rsi,8),%rdi
mov    %rdx,0x8(%rdi,%rsi,8)
mov    0x10(%rax,%rsi,8),%rdi
mov    %rdx,0x10(%rdi,%rsi,8)
mov    0x18(%rax,%rsi,8),%rdi
mov    %rdx,0x18(%rdi,%rsi,8)
add    $0x4,%rsi
cmp    %rsi,%rbx
jne    1150 <deye+0x40>
test   %rcx,%rcx
je     11a2 <deye+0x92>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    (%rax,%rsi,8),%rdi
mov    %rdx,(%rdi,%rsi,8)
add    $0x1,%rsi
add    $0xffffffffffffffff,%rcx
jne    1190 <deye+0x80>
pop    %rbx
ret

LLVM IR (-O0):
define double** @deye(i64 %0) {
%2 = alloca i64
%3 = alloca i64
%4 = alloca double**
store i64 %0, i64* %2
%5 = load i64, i64* %2
%6 = load i64, i64* %2
%7 = call double** @dmatrix(i64 %5, i64 %6)
store double** %7, double*** %4
store i64 0, i64* %3
br label %8
8: ; preds = %19, %1
%9 = load i64, i64* %3
%10 = load i64, i64* %2
%11 = icmp ult i64 %9, %10
br i1 %11, label %12, label %22
12: ; preds = %8
%13 = load double**, double*** %4
%14 = load i64, i64* %3
%15 = getelementptr inbounds double*, double** %13, i64 %14
%16 = load double*, double** %15
%17 = load i64, i64* %3
%18 = getelementptr inbounds double, double* %16, i64 %17
store double 1.000000e+00, double* %18
br label %19
19: ; preds = %12
%20 = load i64, i64* %3
%21 = add i64 %20, 1
store i64 %21, i64* %3
br label %8
22: ; preds = %8
%23 = load double**, double*** %4
ret double** %23
}

LLVM IR (-O2):
define double** @deye(i64 %0) {
%2 = tail call double** @dmatrix(i64 %0, i64 %0)
%3 = icmp eq i64 %0, 0
br i1 %3, label %43, label %4
4: ; preds = %1
%5 = add i64 %0, -1
%6 = and i64 %0, 3
%7 = icmp ult i64 %5, 3
br i1 %7, label %31, label %8
8: ; preds = %4
%9 = and i64 %0, -4
br label %10
10: ; preds = %10, %8
%11 = phi i64 [ 0, %8 ], [ %28, %10 ]
%12 = phi i64 [ 0, %8 ], [ %29, %10 ]
%13 = getelementptr inbounds double*, double** %2, i64 %11
%14 = load double*, double** %13
%15 = getelementptr inbounds double, double* %14, i64 %11
store double 1.000000e+00, double* %15
%16 = or i64 %11, 1
%17 = getelementptr inbounds double*, double** %2, i64 %16
%18 = load double*, double** %17
%19 = getelementptr inbounds double, double* %18, i64 %16
store double 1.000000e+00, double* %19
%20 = or i64 %11, 2
%21 = getelementptr inbounds double*, double** %2, i64 %20
%22 = load double*, double** %21
%23 = getelementptr inbounds double, double* %22, i64 %20
store double 1.000000e+00, double* %23
%24 = or i64 %11, 3
%25 = getelementptr inbounds double*, double** %2, i64 %24
%26 = load double*, double** %25
%27 = getelementptr inbounds double, double* %26, i64 %24
store double 1.000000e+00, double* %27
%28 = add nuw i64 %11, 4
%29 = add i64 %12, 4
%30 = icmp eq i64 %29, %9
br i1 %30, label %31, label %10
31: ; preds = %10, %4
%32 = phi i64 [ 0, %4 ], [ %28, %10 ]
%33 = icmp eq i64 %6, 0
br i1 %33, label %43, label %34
34: ; preds = %31, %34
%35 = phi i64 [ %40, %34 ], [ %32, %31 ]
%36 = phi i64 [ %41, %34 ], [ 0, %31 ]
%37 = getelementptr inbounds double*, double** %2, i64 %35
%38 = load double*, double** %37
%39 = getelementptr inbounds double, double* %38, i64 %35
store double 1.000000e+00, double* %39
%40 = add nuw i64 %35, 1
%41 = add i64 %36, 1
%42 = icmp eq i64 %41, %6
br i1 %42, label %43, label %34
43: ; preds = %31, %34, %1
ret double** %2
}