#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 */
int /*<<< orphan*/ cov_mat(double *, double *, int, int);
int /*<<< orphan*/ denormH(double *, double *, double *);
int /*<<< orphan*/ free(double *);
int /*<<< orphan*/ lap_eig(double *, double *, int);
int /*<<< orphan*/ lin_hg(double const *, double *, int const *, int);
int /*<<< orphan*/ lin_hgN(double const *, double *, int const *, int, double *,
                           double *);
scalar_t__ malloc(int);
int /*<<< orphan*/ memcpy(double *, double *, int);
int /*<<< orphan*/ normu(double const *, int const *, int, double *, double *);
int /*<<< orphan*/ nullspace(double *, double *, int, int *);
int /*<<< orphan*/ trnm(double *, int);
void u2h(const double *u, const int *inl, int len, double *H, double *buffer) {
  double A1[3], A2[3];
  double *Z, V[9 * 9], D[9];
  int i, nullspace_buff[2 * 9];
  if (len < 4) {
    return;
  } else if (len == 4) {
    double Z2[9 * 9];
    lin_hg(u, Z2, inl, len);
    trnm(Z2, 9);
    for (i = 9 * 8; i < 9 * 9; ++i) {
      Z2[i] = 0.0;
    }
    nullspace(Z2, V, 9, nullspace_buff);
    memcpy(H, V, 3 * 3 * sizeof(double));
  } else {
    if (!buffer) {
      Z = (double *)malloc(sizeof(double) * 9 * len * 2);
    } else {
      Z = buffer;
    }
    normu(u, inl, len, A1, A2);
    lin_hgN(u, Z, inl, len, A1, A2);
    cov_mat(V, Z, 2 * len, 9);
    lap_eig(V, D, 9);
    memcpy(H, V, 3 * 3 * sizeof(double));
    denormH(H, A1, A2);
    if (!buffer) {
      free(Z);
    }
  }
}


x86 assembly (clang, -O0):
<u2h>:
push   %rbp
mov    %rsp,%rbp
sub    $0x620,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
cmpl   $0x4,-0x14(%rbp)
jge    11dd <u2h+0x2d>
jmp    1360 <u2h+0x1b0>
cmpl   $0x4,-0x14(%rbp)
jne    1286 <u2h+0xd6>
mov    -0x8(%rbp),%rdi
lea    -0x620(%rbp),%rsi
mov    -0x10(%rbp),%rdx
mov    -0x14(%rbp),%ecx
call   1060 <lin_hg@plt>
lea    -0x620(%rbp),%rdi
mov    $0x9,%esi
call   1050 <trnm@plt>
movl   $0x48,-0x344(%rbp)
cmpl   $0x51,-0x344(%rbp)
jge    124d <u2h+0x9d>
movslq -0x344(%rbp),%rax
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x620(%rbp,%rax,8)
ff ff
mov    -0x344(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x344(%rbp)
jmp    1219 <u2h+0x69>
lea    -0x620(%rbp),%rdi
lea    -0x2f0(%rbp),%rsi
lea    -0x390(%rbp),%rcx
mov    $0x9,%edx
call   10c0 <nullspace@plt>
mov    -0x20(%rbp),%rdi
lea    -0x2f0(%rbp),%rsi
mov    $0x48,%edx
call   1090 <memcpy@plt>
jmp    135b <u2h+0x1ab>
cmpq   $0x0,-0x28(%rbp)
jne    12ad <u2h+0xfd>
movslq -0x14(%rbp),%rax
imul   $0x48,%rax,%rax
shl    $0x1,%rax
mov    %eax,%edi
call   10a0 <malloc@plt>
mov    %rax,-0x68(%rbp)
jmp    12b5 <u2h+0x105>
mov    -0x28(%rbp),%rax
mov    %rax,-0x68(%rbp)
mov    -0x8(%rbp),%rdi
mov    -0x10(%rbp),%rsi
mov    -0x14(%rbp),%edx
lea    -0x40(%rbp),%rcx
lea    -0x60(%rbp),%r8
call   10b0 <normu@plt>
mov    -0x8(%rbp),%rdi
mov    -0x68(%rbp),%rsi
mov    -0x10(%rbp),%rdx
mov    -0x14(%rbp),%ecx
lea    -0x40(%rbp),%r8
lea    -0x60(%rbp),%r9
call   1070 <lin_hgN@plt>
lea    -0x2f0(%rbp),%rdi
mov    -0x68(%rbp),%rsi
mov    -0x14(%rbp),%edx
shl    $0x1,%edx
mov    $0x9,%ecx
call   10d0 <cov_mat@plt>
lea    -0x2f0(%rbp),%rdi
lea    -0x340(%rbp),%rsi
mov    $0x9,%edx
call   1080 <lap_eig@plt>
mov    -0x20(%rbp),%rdi
lea    -0x2f0(%rbp),%rsi
mov    $0x48,%edx
call   1090 <memcpy@plt>
mov    -0x20(%rbp),%rdi
lea    -0x40(%rbp),%rsi
lea    -0x60(%rbp),%rdx
call   1040 <denormH@plt>
cmpq   $0x0,-0x28(%rbp)
jne    1356 <u2h+0x1a6>
mov    -0x68(%rbp),%rdi
call   1030 <free@plt>
jmp    135b <u2h+0x1ab>
jmp    1360 <u2h+0x1b0>
add    $0x620,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<u2h>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x598,%rsp
cmp    $0x4,%edx
jl     131a <u2h+0x16a>
mov    %rcx,%r14
mov    %rsi,%rbx
mov    %rdi,%r13
jne    1262 <u2h+0xb2>
lea    0x80(%rsp),%rbp
mov    %r13,%rdi
mov    %rbp,%rsi
mov    %rbx,%rdx
mov    $0x4,%ecx
call   1060 <lin_hg@plt>
mov    %rbp,%rdi
mov    $0x9,%esi
call   1050 <trnm@plt>
xorps  %xmm0,%xmm0
movaps %xmm0,0x2c0(%rsp)
movaps %xmm0,0x2d0(%rsp)
movaps %xmm0,0x2e0(%rsp)
movaps %xmm0,0x2f0(%rsp)
movq   $0x0,0x300(%rsp)
lea    0x310(%rsp),%rbx
lea    0x10(%rsp),%rcx
mov    %rbp,%rdi
mov    %rbx,%rsi
mov    $0x9,%edx
call   10c0 <nullspace@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    $0x48,%edx
call   1090 <memcpy@plt>
jmp    131a <u2h+0x16a>
mov    %r8,%r12
mov    %edx,%ebp
mov    %r8,0x8(%rsp)
test   %r8,%r8
jne    1283 <u2h+0xd3>
mov    %ebp,%eax
shl    $0x4,%eax
lea    (%rax,%rax,8),%edi
call   10a0 <malloc@plt>
mov    %rax,0x8(%rsp)
lea    0x10(%rsp),%rcx
lea    0x60(%rsp),%r15
mov    %r13,%rdi
mov    %rbx,%rsi
mov    %ebp,%edx
mov    %r15,%r8
call   10b0 <normu@plt>
mov    %r13,%rdi
mov    0x8(%rsp),%r13
mov    %r13,%rsi
mov    %rbx,%rdx
mov    %ebp,%ecx
lea    0x10(%rsp),%r8
mov    %r15,%r9
call   1070 <lin_hgN@plt>
add    %ebp,%ebp
lea    0x310(%rsp),%rbx
mov    %rbx,%rdi
mov    %r13,%rsi
mov    %ebp,%edx
mov    $0x9,%ecx
call   10d0 <cov_mat@plt>
lea    0x80(%rsp),%rsi
mov    %rbx,%rdi
mov    $0x9,%edx
call   1080 <lap_eig@plt>
mov    %r14,%rdi
mov    %rbx,%rsi
mov    $0x48,%edx
call   1090 <memcpy@plt>
mov    %r14,%rdi
lea    0x10(%rsp),%rsi
mov    %r15,%rdx
call   1040 <denormH@plt>
test   %r12,%r12
jne    131a <u2h+0x16a>
mov    0x8(%rsp),%rdi
call   1030 <free@plt>
add    $0x598,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @u2h(double* %0, i32* %1, i32 %2, double* %3, double* %4) {
%6 = alloca double*
%7 = alloca i32*
%8 = alloca i32
%9 = alloca double*
%10 = alloca double*
%11 = alloca [3 x double]
%12 = alloca [3 x double]
%13 = alloca double*
%14 = alloca [81 x double]
%15 = alloca [9 x double]
%16 = alloca i32
%17 = alloca [18 x i32]
%18 = alloca [81 x double]
store double* %0, double** %6
store i32* %1, i32** %7
store i32 %2, i32* %8
store double* %3, double** %9
store double* %4, double** %10
%19 = load i32, i32* %8
%20 = icmp slt i32 %19, 4
br i1 %20, label %21, label %22
21: ; preds = %5
br label %100
22: ; preds = %5
%23 = load i32, i32* %8
%24 = icmp eq i32 %23, 4
br i1 %24, label %25, label %51
25: ; preds = %22
%26 = load double*, double** %6
%27 = getelementptr inbounds [81 x double], [81 x double]* %18, i64 0, i64 0
%28 = load i32*, i32** %7
%29 = load i32, i32* %8
%30 = call i32 @lin_hg(double* %26, double* %27, i32* %28, i32 %29)
%31 = getelementptr inbounds [81 x double], [81 x double]* %18, i64 0, i64 0
%32 = call i32 @trnm(double* %31, i32 9)
store i32 72, i32* %16
br label %33
33: ; preds = %40, %25
%34 = load i32, i32* %16
%35 = icmp slt i32 %34, 81
br i1 %35, label %36, label %43
36: ; preds = %33
%37 = load i32, i32* %16
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds [81 x double], [81 x double]* %18, i64 0, i64 %38
store double 0.000000e+00, double* %39
br label %40
40: ; preds = %36
%41 = load i32, i32* %16
%42 = add nsw i32 %41, 1
store i32 %42, i32* %16
br label %33
43: ; preds = %33
%44 = getelementptr inbounds [81 x double], [81 x double]* %18, i64 0, i64 0
%45 = getelementptr inbounds [81 x double], [81 x double]* %14, i64 0, i64 0
%46 = getelementptr inbounds [18 x i32], [18 x i32]* %17, i64 0, i64 0
%47 = call i32 @nullspace(double* %44, double* %45, i32 9, i32* %46)
%48 = load double*, double** %9
%49 = getelementptr inbounds [81 x double], [81 x double]* %14, i64 0, i64 0
%50 = call i32 @memcpy(double* %48, double* %49, i32 72)
br label %99
51: ; preds = %22
%52 = load double*, double** %10
%53 = icmp ne double* %52, null
br i1 %53, label %62, label %54
54: ; preds = %51
%55 = load i32, i32* %8
%56 = sext i32 %55 to i64
%57 = mul i64 72, %56
%58 = mul i64 %57, 2
%59 = trunc i64 %58 to i32
%60 = call i64 @malloc(i32 %59)
%61 = inttoptr i64 %60 to double*
store double* %61, double** %13
br label %64
62: ; preds = %51
%63 = load double*, double** %10
store double* %63, double** %13
br label %64
64: ; preds = %62, %54
%65 = load double*, double** %6
%66 = load i32*, i32** %7
%67 = load i32, i32* %8
%68 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%69 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%70 = call i32 @normu(double* %65, i32* %66, i32 %67, double* %68, double* %69)
%71 = load double*, double** %6
%72 = load double*, double** %13
%73 = load i32*, i32** %7
%74 = load i32, i32* %8
%75 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%76 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%77 = call i32 @lin_hgN(double* %71, double* %72, i32* %73, i32 %74, double* %75, double* %76)
%78 = getelementptr inbounds [81 x double], [81 x double]* %14, i64 0, i64 0
%79 = load double*, double** %13
%80 = load i32, i32* %8
%81 = mul nsw i32 2, %80
%82 = call i32 @cov_mat(double* %78, double* %79, i32 %81, i32 9)
%83 = getelementptr inbounds [81 x double], [81 x double]* %14, i64 0, i64 0
%84 = getelementptr inbounds [9 x double], [9 x double]* %15, i64 0, i64 0
%85 = call i32 @lap_eig(double* %83, double* %84, i32 9)
%86 = load double*, double** %9
%87 = getelementptr inbounds [81 x double], [81 x double]* %14, i64 0, i64 0
%88 = call i32 @memcpy(double* %86, double* %87, i32 72)
%89 = load double*, double** %9
%90 = getelementptr inbounds [3 x double], [3 x double]* %11, i64 0, i64 0
%91 = getelementptr inbounds [3 x double], [3 x double]* %12, i64 0, i64 0
%92 = call i32 @denormH(double* %89, double* %90, double* %91)
%93 = load double*, double** %10
%94 = icmp ne double* %93, null
br i1 %94, label %98, label %95
95: ; preds = %64
%96 = load double*, double** %13
%97 = call i32 @free(double* %96)
br label %98
98: ; preds = %95, %64
br label %99
99: ; preds = %98, %43
br label %100
100: ; preds = %21, %99
ret void
}

LLVM IR (-O2):
define void @u2h(double* %0, i32* %1, i32 %2, double* %3, double* %4) {
%6 = alloca [3 x double]
%7 = alloca [3 x double]
%8 = alloca [81 x double]
%9 = alloca [9 x double]
%10 = alloca [18 x i32]
%11 = alloca [81 x double]
%12 = bitcast [3 x double]* %6 to i8*
%13 = bitcast [3 x double]* %7 to i8*
%14 = bitcast [81 x double]* %8 to i8*
%15 = bitcast [9 x double]* %9 to i8*
%16 = bitcast [18 x i32]* %10 to i8*
%17 = icmp slt i32 %2, 4
br i1 %17, label %52, label %18
18: ; preds = %5
%19 = icmp eq i32 %2, 4
br i1 %19, label %20, label %31
20: ; preds = %18
%21 = bitcast [81 x double]* %11 to i8*
%22 = getelementptr inbounds [81 x double], [81 x double]* %11, i64 0, i64 0
%23 = call i32 @lin_hg(double* %0, double* %22, i32* %1, i32 4)
%24 = call i32 @trnm(double* %22, i32 9)
%25 = getelementptr inbounds [81 x double], [81 x double]* %11, i64 0, i64 72
%26 = bitcast double* %25 to i8*
%27 = getelementptr inbounds [81 x double], [81 x double]* %8, i64 0, i64 0
%28 = getelementptr inbounds [18 x i32], [18 x i32]* %10, i64 0, i64 0
%29 = call i32 @nullspace(double* %22, double* %27, i32 9, i32* %28)
%30 = call i32 @memcpy(double* %3, double* %27, i32 72)
br label %52
31: ; preds = %18
%32 = icmp eq double* %4, null
br i1 %32, label %33, label %37
33: ; preds = %31
%34 = mul i32 %2, 144
%35 = tail call i64 @malloc(i32 %34)
%36 = inttoptr i64 %35 to double*
br label %37
37: ; preds = %31, %33
%38 = phi double* [ %36, %33 ], [ %4, %31 ]
%39 = getelementptr inbounds [3 x double], [3 x double]* %6, i64 0, i64 0
%40 = getelementptr inbounds [3 x double], [3 x double]* %7, i64 0, i64 0
%41 = call i32 @normu(double* %0, i32* %1, i32 %2, double* %39, double* %40)
%42 = call i32 @lin_hgN(double* %0, double* %38, i32* %1, i32 %2, double* %39, double* %40)
%43 = getelementptr inbounds [81 x double], [81 x double]* %8, i64 0, i64 0
%44 = shl nuw nsw i32 %2, 1
%45 = call i32 @cov_mat(double* %43, double* %38, i32 %44, i32 9)
%46 = getelementptr inbounds [9 x double], [9 x double]* %9, i64 0, i64 0
%47 = call i32 @lap_eig(double* %43, double* %46, i32 9)
%48 = call i32 @memcpy(double* %3, double* %43, i32 72)
%49 = call i32 @denormH(double* %3, double* %39, double* %40)
br i1 %32, label %50, label %52
50: ; preds = %37
%51 = call i32 @free(double* %38)
br label %52
52: ; preds = %37, %50, %20, %5
ret void
}