#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 exp(float);
int multiexp_tau_array(float xincr, float param[], float *y, float **dy_dparam,
                       int nx, int nparam) {
  int i, j;
  float ex;
  float a2[20];
  double exincr[20];
  double excur[20];
  if (xincr <= 0)
    return -1;
  for (j = 1; j < nparam - 1; j += 2) {
    if (param[j + 1] < 0)
      return -1;
    excur[j] = 1.0;
    exincr[j] = exp(-xincr / (double)param[j + 1]);
    a2[j] = 1 / (param[j + 1] * param[j + 1]);
  }
  for (i = 0; i < nx; i++) {
    y[i] = 0;
    for (j = 1; j < nparam - 1; j += 2) {
      dy_dparam[i][j] = ex = (float)excur[j];
      ex *= param[j];
      y[i] += ex;
      dy_dparam[i][j + 1] = ex * xincr * (float)i * a2[j];
      excur[j] *= exincr[j];
    }
  }
  return 0;
}


x86 assembly (clang, -O0):
<multiexp_tau_array>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1d0,%rsp
movss  %xmm0,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    %r8d,-0x28(%rbp)
xorps  %xmm0,%xmm0
ucomiss -0x8(%rbp),%xmm0
jb     114c <multiexp_tau_array+0x3c>
movl   $0xffffffff,-0x4(%rbp)
jmp    1349 <multiexp_tau_array+0x239>
movl   $0x1,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    -0x28(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1230 <multiexp_tau_array+0x120>
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
xorps  %xmm0,%xmm0
ucomiss (%rax,%rcx,4),%xmm0
jbe    118a <multiexp_tau_array+0x7a>
movl   $0xffffffff,-0x4(%rbp)
jmp    1349 <multiexp_tau_array+0x239>
movslq -0x30(%rbp),%rax
movsd  0xe72(%rip),%xmm0
movsd  %xmm0,-0x1d0(%rbp,%rax,8)
ff ff
movss  -0x8(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
cvtss2sd %xmm0,%xmm0
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm1
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
call   1030 <exp@plt>
movslq -0x30(%rbp),%rax
movsd  %xmm0,-0x130(%rbp,%rax,8)
ff ff
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm1
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
mulss  (%rax,%rcx,4),%xmm1
movss  0xdef(%rip),%xmm0
divss  %xmm1,%xmm0
movslq -0x30(%rbp),%rax
movss  %xmm0,-0x90(%rbp,%rax,4)
ff ff
mov    -0x30(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x30(%rbp)
jmp    1153 <multiexp_tau_array+0x43>
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    1342 <multiexp_tau_array+0x232>
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
xorps  %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
movl   $0x1,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    -0x28(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    132f <multiexp_tau_array+0x21f>
movslq -0x30(%rbp),%rax
movsd  -0x1d0(%rbp,%rax,8),%xmm0
ff ff
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,-0x34(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movslq -0x30(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x10(%rbp),%rax
movslq -0x30(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mulss  -0x34(%rbp),%xmm0
movss  %xmm0,-0x34(%rbp)
movss  -0x34(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
addss  (%rax,%rcx,4),%xmm0
movss  %xmm0,(%rax,%rcx,4)
movss  -0x34(%rbp),%xmm0
mulss  -0x8(%rbp),%xmm0
cvtsi2ssl -0x2c(%rbp),%xmm1
mulss  %xmm1,%xmm0
movslq -0x30(%rbp),%rax
mulss  -0x90(%rbp,%rax,4),%xmm0
ff ff
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x30(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movss  %xmm0,(%rax,%rcx,4)
movslq -0x30(%rbp),%rax
movsd  -0x130(%rbp,%rax,8),%xmm0
ff ff
movslq -0x30(%rbp),%rax
mulsd  -0x1d0(%rbp,%rax,8),%xmm0
ff ff
movsd  %xmm0,-0x1d0(%rbp,%rax,8)
ff ff
mov    -0x30(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x30(%rbp)
jmp    125a <multiexp_tau_array+0x14a>
jmp    1334 <multiexp_tau_array+0x224>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1237 <multiexp_tau_array+0x127>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x1d0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<multiexp_tau_array>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x1c8,%rsp
movaps %xmm0,%xmm4
mov    $0xffffffff,%eax
xorps  %xmm0,%xmm0
ucomiss %xmm4,%xmm0
jae    1296 <multiexp_tau_array+0x186>
mov    %r8d,%r15d
mov    %rsi,%rbx
mov    %rdi,%r12
mov    %ecx,0x4(%rsp)
mov    %rdx,0x8(%rsp)
lea    -0x1(%r15),%eax
mov    %eax,(%rsp)
cmp    $0x3,%r8d
jl     11dd <multiexp_tau_array+0xcd>
movaps 0xea1(%rip),%xmm0
xorps  %xmm4,%xmm0
movaps %xmm0,0x10(%rsp)
mov    (%rsp),%r13d
mov    $0x1,%ebp
movabs $0x3ff0000000000000,%r14
movaps %xmm4,0x20(%rsp)
nop
movss  0x4(%r12,%rbp,4),%xmm1
xorps  %xmm0,%xmm0
ucomiss %xmm1,%xmm0
ja     1291 <multiexp_tau_array+0x181>
mov    %r14,0x80(%rsp,%rbp,8)
movaps 0x10(%rsp),%xmm0
divss  %xmm1,%xmm0
call   1030 <exp@plt>
movaps 0x20(%rsp),%xmm4
movsd  %xmm0,0x120(%rsp,%rbp,8)
movss  0x4(%r12,%rbp,4),%xmm0
mulss  %xmm0,%xmm0
movss  0xe46(%rip),%xmm1
divss  %xmm0,%xmm1
movss  %xmm1,0x30(%rsp,%rbp,4)
add    $0x2,%rbp
cmp    %r13,%rbp
jb     1180 <multiexp_tau_array+0x70>
mov    0x4(%rsp),%ecx
test   %ecx,%ecx
jle    128d <multiexp_tau_array+0x17d>
movslq (%rsp),%rax
mov    %ecx,%ecx
xor    %edx,%edx
mov    0x8(%rsp),%rbp
jmp    120d <multiexp_tau_array+0xfd>
nopl   0x0(%rax,%rax,1)
add    $0x1,%rdx
cmp    %rcx,%rdx
je     128d <multiexp_tau_array+0x17d>
movl   $0x0,(%rbx,%rdx,4)
cmp    $0x3,%r15d
jl     1200 <multiexp_tau_array+0xf0>
mov    0x0(%rbp,%rdx,8),%rsi
xorps  %xmm0,%xmm0
cvtsi2ss %edx,%xmm0
mov    $0x1,%edi
nopl   0x0(%rax,%rax,1)
movsd  0x80(%rsp,%rdi,8),%xmm1
xorps  %xmm2,%xmm2
cvtsd2ss %xmm1,%xmm2
movss  %xmm2,(%rsi,%rdi,4)
mulss  (%r12,%rdi,4),%xmm2
movss  (%rbx,%rdx,4),%xmm3
addss  %xmm2,%xmm3
movss  %xmm3,(%rbx,%rdx,4)
mulss  %xmm4,%xmm2
mulss  %xmm0,%xmm2
mulss  0x30(%rsp,%rdi,4),%xmm2
movss  %xmm2,0x4(%rsi,%rdi,4)
mulsd  0x120(%rsp,%rdi,8),%xmm1
movsd  %xmm1,0x80(%rsp,%rdi,8)
add    $0x2,%rdi
cmp    %rax,%rdi
jl     1230 <multiexp_tau_array+0x120>
jmp    1200 <multiexp_tau_array+0xf0>
xor    %eax,%eax
jmp    1296 <multiexp_tau_array+0x186>
mov    $0xffffffff,%eax
add    $0x1c8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @multiexp_tau_array(float %0, float* %1, float* %2, float** %3, i32 %4, i32 %5) {
%7 = alloca i32
%8 = alloca float
%9 = alloca float*
%10 = alloca float*
%11 = alloca float**
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca float
%17 = alloca [20 x float]
%18 = alloca [20 x double]
%19 = alloca [20 x double]
store float %0, float* %8
store float* %1, float** %9
store float* %2, float** %10
store float** %3, float*** %11
store i32 %4, i32* %12
store i32 %5, i32* %13
%20 = load float, float* %8
%21 = fcmp ole float %20, 0.000000e+00
br i1 %21, label %22, label %23
22: ; preds = %6
store i32 -1, i32* %7
br label %158
23: ; preds = %6
store i32 1, i32* %15
br label %24
24: ; preds = %75, %23
%25 = load i32, i32* %15
%26 = load i32, i32* %13
%27 = sub nsw i32 %26, 1
%28 = icmp slt i32 %25, %27
br i1 %28, label %29, label %78
29: ; preds = %24
%30 = load float*, float** %9
%31 = load i32, i32* %15
%32 = add nsw i32 %31, 1
%33 = sext i32 %32 to i64
%34 = getelementptr inbounds float, float* %30, i64 %33
%35 = load float, float* %34
%36 = fcmp olt float %35, 0.000000e+00
br i1 %36, label %37, label %38
37: ; preds = %29
store i32 -1, i32* %7
br label %158
38: ; preds = %29
%39 = load i32, i32* %15
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds [20 x double], [20 x double]* %19, i64 0, i64 %40
store double 1.000000e+00, double* %41
%42 = load float, float* %8
%43 = fneg float %42
%44 = fpext float %43 to double
%45 = load float*, float** %9
%46 = load i32, i32* %15
%47 = add nsw i32 %46, 1
%48 = sext i32 %47 to i64
%49 = getelementptr inbounds float, float* %45, i64 %48
%50 = load float, float* %49
%51 = fpext float %50 to double
%52 = fdiv double %44, %51
%53 = fptrunc double %52 to float
%54 = call double @exp(float %53)
%55 = load i32, i32* %15
%56 = sext i32 %55 to i64
%57 = getelementptr inbounds [20 x double], [20 x double]* %18, i64 0, i64 %56
store double %54, double* %57
%58 = load float*, float** %9
%59 = load i32, i32* %15
%60 = add nsw i32 %59, 1
%61 = sext i32 %60 to i64
%62 = getelementptr inbounds float, float* %58, i64 %61
%63 = load float, float* %62
%64 = load float*, float** %9
%65 = load i32, i32* %15
%66 = add nsw i32 %65, 1
%67 = sext i32 %66 to i64
%68 = getelementptr inbounds float, float* %64, i64 %67
%69 = load float, float* %68
%70 = fmul float %63, %69
%71 = fdiv float 1.000000e+00, %70
%72 = load i32, i32* %15
%73 = sext i32 %72 to i64
%74 = getelementptr inbounds [20 x float], [20 x float]* %17, i64 0, i64 %73
store float %71, float* %74
br label %75
75: ; preds = %38
%76 = load i32, i32* %15
%77 = add nsw i32 %76, 2
store i32 %77, i32* %15
br label %24
78: ; preds = %24
store i32 0, i32* %14
br label %79
79: ; preds = %154, %78
%80 = load i32, i32* %14
%81 = load i32, i32* %12
%82 = icmp slt i32 %80, %81
br i1 %82, label %83, label %157
83: ; preds = %79
%84 = load float*, float** %10
%85 = load i32, i32* %14
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds float, float* %84, i64 %86
store float 0.000000e+00, float* %87
store i32 1, i32* %15
br label %88
88: ; preds = %150, %83
%89 = load i32, i32* %15
%90 = load i32, i32* %13
%91 = sub nsw i32 %90, 1
%92 = icmp slt i32 %89, %91
br i1 %92, label %93, label %153
93: ; preds = %88
%94 = load i32, i32* %15
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds [20 x double], [20 x double]* %19, i64 0, i64 %95
%97 = load double, double* %96
%98 = fptrunc double %97 to float
store float %98, float* %16
%99 = load float**, float*** %11
%100 = load i32, i32* %14
%101 = sext i32 %100 to i64
%102 = getelementptr inbounds float*, float** %99, i64 %101
%103 = load float*, float** %102
%104 = load i32, i32* %15
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds float, float* %103, i64 %105
store float %98, float* %106
%107 = load float*, float** %9
%108 = load i32, i32* %15
%109 = sext i32 %108 to i64
%110 = getelementptr inbounds float, float* %107, i64 %109
%111 = load float, float* %110
%112 = load float, float* %16
%113 = fmul float %112, %111
store float %113, float* %16
%114 = load float, float* %16
%115 = load float*, float** %10
%116 = load i32, i32* %14
%117 = sext i32 %116 to i64
%118 = getelementptr inbounds float, float* %115, i64 %117
%119 = load float, float* %118
%120 = fadd float %119, %114
store float %120, float* %118
%121 = load float, float* %16
%122 = load float, float* %8
%123 = fmul float %121, %122
%124 = load i32, i32* %14
%125 = sitofp i32 %124 to float
%126 = fmul float %123, %125
%127 = load i32, i32* %15
%128 = sext i32 %127 to i64
%129 = getelementptr inbounds [20 x float], [20 x float]* %17, i64 0, i64 %128
%130 = load float, float* %129
%131 = fmul float %126, %130
%132 = load float**, float*** %11
%133 = load i32, i32* %14
%134 = sext i32 %133 to i64
%135 = getelementptr inbounds float*, float** %132, i64 %134
%136 = load float*, float** %135
%137 = load i32, i32* %15
%138 = add nsw i32 %137, 1
%139 = sext i32 %138 to i64
%140 = getelementptr inbounds float, float* %136, i64 %139
store float %131, float* %140
%141 = load i32, i32* %15
%142 = sext i32 %141 to i64
%143 = getelementptr inbounds [20 x double], [20 x double]* %18, i64 0, i64 %142
%144 = load double, double* %143
%145 = load i32, i32* %15
%146 = sext i32 %145 to i64
%147 = getelementptr inbounds [20 x double], [20 x double]* %19, i64 0, i64 %146
%148 = load double, double* %147
%149 = fmul double %148, %144
store double %149, double* %147
br label %150
150: ; preds = %93
%151 = load i32, i32* %15
%152 = add nsw i32 %151, 2
store i32 %152, i32* %15
br label %88
153: ; preds = %88
br label %154
154: ; preds = %153
%155 = load i32, i32* %14
%156 = add nsw i32 %155, 1
store i32 %156, i32* %14
br label %79
157: ; preds = %79
store i32 0, i32* %7
br label %158
158: ; preds = %157, %37, %22
%159 = load i32, i32* %7
ret i32 %159
}

LLVM IR (-O2):
define i32 @multiexp_tau_array(float %0, float* nocapture %1, float* nocapture %2, float** nocapture %3, i32 %4, i32 %5) {
%7 = alloca [20 x float]
%8 = alloca [20 x double]
%9 = alloca [20 x double]
%10 = bitcast [20 x float]* %7 to i8*
%11 = bitcast [20 x double]* %8 to i8*
%12 = bitcast [20 x double]* %9 to i8*
%13 = fcmp ugt float %0, 0.000000e+00
br i1 %13, label %14, label %76
14: ; preds = %6
%15 = add nsw i32 %5, -1
%16 = icmp sgt i32 %5, 2
br i1 %16, label %17, label %20
17: ; preds = %14
%18 = fneg float %0
%19 = zext i32 %15 to i64
br label %25
20: ; preds = %31, %14
%21 = icmp sgt i32 %4, 0
br i1 %21, label %22, label %76
22: ; preds = %20
%23 = sext i32 %15 to i64
%24 = zext i32 %4 to i64
br label %42
25: ; preds = %17, %31
%26 = phi i64 [ 1, %17 ], [ %40, %31 ]
%27 = add nuw nsw i64 %26, 1
%28 = getelementptr inbounds float, float* %1, i64 %27
%29 = load float, float* %28
%30 = fcmp olt float %29, 0.000000e+00
br i1 %30, label %76, label %31
31: ; preds = %25
%32 = getelementptr inbounds [20 x double], [20 x double]* %9, i64 0, i64 %26
store double 1.000000e+00, double* %32
%33 = fdiv float %18, %29
%34 = tail call double @exp(float %33)
%35 = getelementptr inbounds [20 x double], [20 x double]* %8, i64 0, i64 %26
store double %34, double* %35
%36 = load float, float* %28
%37 = fmul float %36, %36
%38 = fdiv float 1.000000e+00, %37
%39 = getelementptr inbounds [20 x float], [20 x float]* %7, i64 0, i64 %26
store float %38, float* %39
%40 = add nuw nsw i64 %26, 2
%41 = icmp ult i64 %40, %19
br i1 %41, label %25, label %20
42: ; preds = %22, %73
%43 = phi i64 [ 0, %22 ], [ %74, %73 ]
%44 = getelementptr inbounds float, float* %2, i64 %43
store float 0.000000e+00, float* %44
br i1 %16, label %45, label %73
45: ; preds = %42
%46 = getelementptr inbounds float*, float** %3, i64 %43
%47 = load float*, float** %46
%48 = trunc i64 %43 to i32
%49 = sitofp i32 %48 to float
br label %50
50: ; preds = %45, %50
%51 = phi i64 [ 1, %45 ], [ %71, %50 ]
%52 = getelementptr inbounds [20 x double], [20 x double]* %9, i64 0, i64 %51
%53 = load double, double* %52
%54 = fptrunc double %53 to float
%55 = getelementptr inbounds float, float* %47, i64 %51
store float %54, float* %55
%56 = getelementptr inbounds float, float* %1, i64 %51
%57 = load float, float* %56
%58 = fmul float %57, %54
%59 = load float, float* %44
%60 = fadd float %59, %58
store float %60, float* %44
%61 = fmul float %58, %0
%62 = fmul float %61, %49
%63 = getelementptr inbounds [20 x float], [20 x float]* %7, i64 0, i64 %51
%64 = load float, float* %63
%65 = fmul float %62, %64
%66 = add nuw nsw i64 %51, 1
%67 = getelementptr inbounds float, float* %47, i64 %66
store float %65, float* %67
%68 = getelementptr inbounds [20 x double], [20 x double]* %8, i64 0, i64 %51
%69 = load double, double* %68
%70 = fmul double %53, %69
store double %70, double* %52
%71 = add nuw nsw i64 %51, 2
%72 = icmp slt i64 %71, %23
br i1 %72, label %50, label %73
73: ; preds = %50, %42
%74 = add nuw nsw i64 %43, 1
%75 = icmp eq i64 %74, %24
br i1 %75, label %76, label %42
76: ; preds = %25, %73, %20, %6
%77 = phi i32 [ -1, %6 ], [ 0, %20 ], [ 0, %73 ], [ -1, %25 ]
ret i32 %77
}