#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*/ assert(int);
double exp(double);
double log(double);
void calcDiagptableFlex(double z, int numberOfCategories, double *rptr,
                        double *EIGN, double *diagptable, const int numStates) {
  int i, l;
  double lz, lza[64];
  const int rates = numStates - 1;
  assert(numStates <= 64);
  if (z < 1.0E-15)
    lz = log(1.0E-15);
  else
    lz = log(z);
  for (l = 0; l < rates; l++)
    lza[l] = EIGN[l] * lz;
  for (i = 0; i < numberOfCategories; i++) {
    diagptable[i * numStates] = 1.0;
    for (l = 1; l < numStates; l++)
      diagptable[i * numStates + l] = exp(rptr[i] * lza[l - 1]);
  }
}


x86 assembly (clang, -O0):
<calcDiagptableFlex>:
push   %rbp
mov    %rsp,%rbp
sub    $0x250,%rsp
movsd  %xmm0,-0x8(%rbp)
mov    %edi,-0xc(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
mov    %r8d,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x244(%rbp)
cmpl   $0x40,-0x2c(%rbp)
setle  %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
movsd  0xe88(%rip),%xmm0
ucomisd -0x8(%rbp),%xmm0
jbe    119a <calcDiagptableFlex+0x6a>
movsd  0xe75(%rip),%xmm0
call   1050 <log@plt>
movsd  %xmm0,-0x40(%rbp)
jmp    11a9 <calcDiagptableFlex+0x79>
movsd  -0x8(%rbp),%xmm0
call   1050 <log@plt>
movsd  %xmm0,-0x40(%rbp)
movl   $0x0,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x244(%rbp),%eax
jge    11ec <calcDiagptableFlex+0xbc>
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mulsd  -0x40(%rbp),%xmm0
movslq -0x34(%rbp),%rax
movsd  %xmm0,-0x240(%rbp,%rax,8)
ff ff
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11b0 <calcDiagptableFlex+0x80>
movl   $0x0,-0x30(%rbp)
mov    -0x30(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1287 <calcDiagptableFlex+0x157>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%ecx
imul   -0x2c(%rbp),%ecx
movslq %ecx,%rcx
movsd  0xdf3(%rip),%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x1,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x2c(%rbp),%eax
jge    1274 <calcDiagptableFlex+0x144>
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x34(%rbp),%eax
sub    $0x1,%eax
cltq
mulsd  -0x240(%rbp,%rax,8),%xmm0
ff ff
call   1040 <exp@plt>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%ecx
imul   -0x2c(%rbp),%ecx
add    -0x34(%rbp),%ecx
movslq %ecx,%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1221 <calcDiagptableFlex+0xf1>
jmp    1279 <calcDiagptableFlex+0x149>
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
jmp    11f3 <calcDiagptableFlex+0xc3>
add    $0x250,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<calcDiagptableFlex>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x228,%rsp
mov    %rcx,0x10(%rsp)
mov    %rdx,%rbp
mov    %rsi,%rbx
mov    %edi,%r12d
movsd  %xmm0,0x8(%rsp)
xor    %edi,%edi
mov    %r8,(%rsp)
cmp    $0x41,%r8d
setl   %dil
call   1030 <assert@plt>
movsd  0xe98(%rip),%xmm0
movsd  0x8(%rsp),%xmm1
ucomisd %xmm1,%xmm0
jbe    118f <calcDiagptableFlex+0x5f>
movsd  0xe7c(%rip),%xmm0
cmpl   $0x2,(%rsp)
jge    11a2 <calcDiagptableFlex+0x72>
jmp    1289 <calcDiagptableFlex+0x159>
movapd %xmm1,%xmm0
call   1050 <log@plt>
cmpl   $0x2,(%rsp)
jl     1289 <calcDiagptableFlex+0x159>
mov    (%rsp),%rax
lea    -0x1(%rax),%ecx
mov    %ecx,%eax
cmp    $0x4,%ecx
jae    11b7 <calcDiagptableFlex+0x87>
xor    %ecx,%ecx
jmp    1270 <calcDiagptableFlex+0x140>
mov    %eax,%ecx
and    $0xfffffffc,%ecx
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
lea    -0x4(%rcx),%rdx
mov    %rdx,%rsi
shr    $0x2,%rsi
add    $0x1,%rsi
test   %rdx,%rdx
je     1345 <calcDiagptableFlex+0x215>
mov    %rsi,%rdi
and    $0xfffffffffffffffe,%rdi
xor    %edx,%edx
cs nopw 0x0(%rax,%rax,1)
nop
movupd 0x0(%rbp,%rdx,8),%xmm2
movupd 0x10(%rbp,%rdx,8),%xmm3
mulpd  %xmm1,%xmm2
mulpd  %xmm1,%xmm3
movapd %xmm2,0x20(%rsp,%rdx,8)
movapd %xmm3,0x30(%rsp,%rdx,8)
movupd 0x20(%rbp,%rdx,8),%xmm2
movupd 0x30(%rbp,%rdx,8),%xmm3
mulpd  %xmm1,%xmm2
mulpd  %xmm1,%xmm3
movapd %xmm2,0x40(%rsp,%rdx,8)
movapd %xmm3,0x50(%rsp,%rdx,8)
add    $0x8,%rdx
add    $0xfffffffffffffffe,%rdi
jne    11f0 <calcDiagptableFlex+0xc0>
test   $0x1,%sil
je     1260 <calcDiagptableFlex+0x130>
movupd 0x0(%rbp,%rdx,8),%xmm2
movupd 0x10(%rbp,%rdx,8),%xmm3
mulpd  %xmm1,%xmm2
mulpd  %xmm1,%xmm3
movapd %xmm2,0x20(%rsp,%rdx,8)
movapd %xmm3,0x30(%rsp,%rdx,8)
cmp    %rax,%rcx
je     1289 <calcDiagptableFlex+0x159>
cs nopw 0x0(%rax,%rax,1)
nop
movsd  0x0(%rbp,%rcx,8),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x20(%rsp,%rcx,8)
add    $0x1,%rcx
cmp    %rcx,%rax
jne    1270 <calcDiagptableFlex+0x140>
test   %r12d,%r12d
jle    1333 <calcDiagptableFlex+0x203>
mov    (%rsp),%rax
movslq %eax,%rcx
mov    %r12d,%edx
mov    %rdx,0x8(%rsp)
mov    %eax,%ebp
mov    0x10(%rsp),%rax
lea    0x8(%rax),%r14
mov    %rcx,%r15
lea    0x0(,%rcx,8),%rax
mov    %rax,0x18(%rsp)
add    $0xffffffffffffffff,%rbp
xor    %r12d,%r12d
jmp    12e0 <calcDiagptableFlex+0x1b0>
cs nopw 0x0(%rax,%rax,1)
nop
add    $0x1,%r12
add    0x18(%rsp),%r14
cmp    0x8(%rsp),%r12
je     1333 <calcDiagptableFlex+0x203>
mov    %r12,%rax
imul   %r15,%rax
mov    0x10(%rsp),%rcx
movabs $0x3ff0000000000000,%rdx
mov    %rdx,(%rcx,%rax,8)
cmpl   $0x2,(%rsp)
jl     12d0 <calcDiagptableFlex+0x1a0>
xor    %r13d,%r13d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movsd  (%rbx,%r12,8),%xmm0
mulsd  0x20(%rsp,%r13,8),%xmm0
call   1040 <exp@plt>
movsd  %xmm0,(%r14,%r13,8)
add    $0x1,%r13
cmp    %r13,%rbp
jne    1310 <calcDiagptableFlex+0x1e0>
jmp    12d0 <calcDiagptableFlex+0x1a0>
add    $0x228,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
xor    %edx,%edx
test   $0x1,%sil
jne    1240 <calcDiagptableFlex+0x110>
jmp    1260 <calcDiagptableFlex+0x130>

LLVM IR (-O0):
define void @calcDiagptableFlex(double %0, i32 %1, double* %2, double* %3, double* %4, i32 %5) {
%7 = alloca double
%8 = alloca i32
%9 = alloca double*
%10 = alloca double*
%11 = alloca double*
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca double
%16 = alloca [64 x double]
%17 = alloca i32
store double %0, double* %7
store i32 %1, i32* %8
store double* %2, double** %9
store double* %3, double** %10
store double* %4, double** %11
store i32 %5, i32* %12
%18 = load i32, i32* %12
%19 = sub nsw i32 %18, 1
store i32 %19, i32* %17
%20 = load i32, i32* %12
%21 = icmp sle i32 %20, 64
%22 = zext i1 %21 to i32
%23 = call i32 @assert(i32 %22)
%24 = load double, double* %7
%25 = fcmp olt double %24, 1.000000e-15
br i1 %25, label %26, label %28
26: ; preds = %6
%27 = call double @log(double 1.000000e-15)
store double %27, double* %15
br label %31
28: ; preds = %6
%29 = load double, double* %7
%30 = call double @log(double %29)
store double %30, double* %15
br label %31
31: ; preds = %28, %26
store i32 0, i32* %14
br label %32
32: ; preds = %47, %31
%33 = load i32, i32* %14
%34 = load i32, i32* %17
%35 = icmp slt i32 %33, %34
br i1 %35, label %36, label %50
36: ; preds = %32
%37 = load double*, double** %10
%38 = load i32, i32* %14
%39 = sext i32 %38 to i64
%40 = getelementptr inbounds double, double* %37, i64 %39
%41 = load double, double* %40
%42 = load double, double* %15
%43 = fmul double %41, %42
%44 = load i32, i32* %14
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds [64 x double], [64 x double]* %16, i64 0, i64 %45
store double %43, double* %46
br label %47
47: ; preds = %36
%48 = load i32, i32* %14
%49 = add nsw i32 %48, 1
store i32 %49, i32* %14
br label %32
50: ; preds = %32
store i32 0, i32* %13
br label %51
51: ; preds = %91, %50
%52 = load i32, i32* %13
%53 = load i32, i32* %8
%54 = icmp slt i32 %52, %53
br i1 %54, label %55, label %94
55: ; preds = %51
%56 = load double*, double** %11
%57 = load i32, i32* %13
%58 = load i32, i32* %12
%59 = mul nsw i32 %57, %58
%60 = sext i32 %59 to i64
%61 = getelementptr inbounds double, double* %56, i64 %60
store double 1.000000e+00, double* %61
store i32 1, i32* %14
br label %62
62: ; preds = %87, %55
%63 = load i32, i32* %14
%64 = load i32, i32* %12
%65 = icmp slt i32 %63, %64
br i1 %65, label %66, label %90
66: ; preds = %62
%67 = load double*, double** %9
%68 = load i32, i32* %13
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds double, double* %67, i64 %69
%71 = load double, double* %70
%72 = load i32, i32* %14
%73 = sub nsw i32 %72, 1
%74 = sext i32 %73 to i64
%75 = getelementptr inbounds [64 x double], [64 x double]* %16, i64 0, i64 %74
%76 = load double, double* %75
%77 = fmul double %71, %76
%78 = call double @exp(double %77)
%79 = load double*, double** %11
%80 = load i32, i32* %13
%81 = load i32, i32* %12
%82 = mul nsw i32 %80, %81
%83 = load i32, i32* %14
%84 = add nsw i32 %82, %83
%85 = sext i32 %84 to i64
%86 = getelementptr inbounds double, double* %79, i64 %85
store double %78, double* %86
br label %87
87: ; preds = %66
%88 = load i32, i32* %14
%89 = add nsw i32 %88, 1
store i32 %89, i32* %14
br label %62
90: ; preds = %62
br label %91
91: ; preds = %90
%92 = load i32, i32* %13
%93 = add nsw i32 %92, 1
store i32 %93, i32* %13
br label %51
94: ; preds = %51
ret void
}

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