#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 */
float expf(float);
float logf(float);
int stretchedexp_array(float xincr, float param[], float *y, float **dy_dparam,
                       int nx, int nparam) {
  int i;
  float ex, lxa, xah, a2inv, a3inv;
  double xa, xaincr;
  if (xincr == 0)
    return -1;
  xa = 0;
  xaincr = xincr / param[2];
  a2inv = 1 / param[2];
  a3inv = 1 / param[3];
  y[0] = param[1];
  dy_dparam[0][1] = 1;
  dy_dparam[0][2] = dy_dparam[0][3] = 0;
  for (i = 1; i < nx; i++) {
    xa += xaincr;
    lxa = logf((float)xa);
    xah = expf(lxa * a3inv);
    dy_dparam[i][1] = ex = expf(-xah);
    ex *= param[1];
    y[i] = ex;
    ex *= xah * a3inv;
    dy_dparam[i][2] = ex * a2inv;
    dy_dparam[i][3] = ex * lxa * a3inv;
  }
  return 0;
}


x86 assembly (clang, -O0):
<stretchedexp_array>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%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)
movss  -0x8(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    1163 <stretchedexp_array+0x43>
jp     1163 <stretchedexp_array+0x43>
movl   $0xffffffff,-0x4(%rbp)
jmp    12f0 <stretchedexp_array+0x1d0>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x48(%rbp)
movss  -0x8(%rbp),%xmm0
mov    -0x10(%rbp),%rax
divss  0x8(%rax),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x10(%rbp),%rax
movss  0xe72(%rip),%xmm0
divss  0x8(%rax),%xmm0
movss  %xmm0,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
movss  0xe5c(%rip),%xmm0
divss  0xc(%rax),%xmm0
movss  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
movss  0xe32(%rip),%xmm0
movss  %xmm0,0x4(%rax)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0xc(%rax)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
xorps  %xmm0,%xmm0
movss  %xmm0,0x8(%rax)
movl   $0x1,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x24(%rbp),%eax
jge    12e9 <stretchedexp_array+0x1c9>
movsd  -0x50(%rbp),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x48(%rbp),%xmm0
cvtsd2ss %xmm0,%xmm0
call   1030 <logf@plt>
movss  %xmm0,-0x34(%rbp)
movss  -0x34(%rbp),%xmm0
mulss  -0x40(%rbp),%xmm0
call   1040 <expf@plt>
movss  %xmm0,-0x38(%rbp)
movss  -0x38(%rbp),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
call   1040 <expf@plt>
movss  %xmm0,-0x30(%rbp)
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movss  %xmm0,0x4(%rax)
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
mulss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movss  -0x38(%rbp),%xmm0
mulss  -0x40(%rbp),%xmm0
mulss  -0x30(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
movss  -0x30(%rbp),%xmm0
mulss  -0x3c(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movss  %xmm0,0x8(%rax)
movss  -0x30(%rbp),%xmm0
mulss  -0x34(%rbp),%xmm0
mulss  -0x40(%rbp),%xmm0
mov    -0x20(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
movss  %xmm0,0xc(%rax)
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    11f8 <stretchedexp_array+0xd8>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<stretchedexp_array>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
mov    $0xffffffff,%r12d
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    1142 <stretchedexp_array+0x22>
jnp    125d <stretchedexp_array+0x13d>
mov    %rdx,%r14
mov    %rsi,%r15
mov    %rdi,%r13
movss  0x4(%rdi),%xmm2
movss  0x8(%rdi),%xmm1
movss  0xea3(%rip),%xmm3
movss  %xmm3,0x4(%rsp)
divss  0xc(%rdi),%xmm3
movss  %xmm2,(%rsi)
mov    (%rdx),%rax
movq   $0x3f800000,0x4(%rax)
3f
movl   $0x0,0xc(%rax)
xor    %r12d,%r12d
cmp    $0x2,%ecx
jl     125d <stretchedexp_array+0x13d>
divss  %xmm1,%xmm0
cvtss2sd %xmm0,%xmm0
movsd  %xmm0,0x18(%rsp)
movss  0x4(%rsp),%xmm0
divss  %xmm1,%xmm0
movss  %xmm0,0x4(%rsp)
mov    %ecx,%ebp
xorps  %xmm0,%xmm0
mov    $0x1,%ebx
movss  %xmm3,0x8(%rsp)
nopl   0x0(%rax,%rax,1)
addsd  0x18(%rsp),%xmm0
movsd  %xmm0,0x10(%rsp)
movsd  0x10(%rsp),%xmm0
cvtsd2ss %xmm0,%xmm0
call   1030 <logf@plt>
movaps %xmm0,%xmm1
movss  %xmm0,0xc(%rsp)
movss  0x8(%rsp),%xmm0
mulss  %xmm1,%xmm0
call   1040 <expf@plt>
movaps %xmm0,0x20(%rsp)
xorps  0xe11(%rip),%xmm0
call   1040 <expf@plt>
movss  0x8(%rsp),%xmm3
mov    (%r14,%rbx,8),%rax
movss  %xmm0,0x4(%rax)
mulss  0x4(%r13),%xmm0
movss  %xmm0,(%r15,%rbx,4)
movaps 0x20(%rsp),%xmm1
mulss  %xmm3,%xmm1
mulss  %xmm0,%xmm1
movss  0x4(%rsp),%xmm0
mulss  %xmm1,%xmm0
movss  %xmm0,0x8(%rax)
movsd  0x10(%rsp),%xmm0
mulss  0xc(%rsp),%xmm1
mulss  %xmm3,%xmm1
movss  %xmm1,0xc(%rax)
add    $0x1,%rbx
cmp    %rbx,%rbp
jne    11c0 <stretchedexp_array+0xa0>
mov    %r12d,%eax
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @stretchedexp_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 float
%16 = alloca float
%17 = alloca float
%18 = alloca float
%19 = alloca float
%20 = alloca double
%21 = alloca 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
%22 = load float, float* %8
%23 = fcmp oeq float %22, 0.000000e+00
br i1 %23, label %24, label %25
24: ; preds = %6
store i32 -1, i32* %7
br label %120
25: ; preds = %6
store double 0.000000e+00, double* %20
%26 = load float, float* %8
%27 = load float*, float** %9
%28 = getelementptr inbounds float, float* %27, i64 2
%29 = load float, float* %28
%30 = fdiv float %26, %29
%31 = fpext float %30 to double
store double %31, double* %21
%32 = load float*, float** %9
%33 = getelementptr inbounds float, float* %32, i64 2
%34 = load float, float* %33
%35 = fdiv float 1.000000e+00, %34
store float %35, float* %18
%36 = load float*, float** %9
%37 = getelementptr inbounds float, float* %36, i64 3
%38 = load float, float* %37
%39 = fdiv float 1.000000e+00, %38
store float %39, float* %19
%40 = load float*, float** %9
%41 = getelementptr inbounds float, float* %40, i64 1
%42 = load float, float* %41
%43 = load float*, float** %10
%44 = getelementptr inbounds float, float* %43, i64 0
store float %42, float* %44
%45 = load float**, float*** %11
%46 = getelementptr inbounds float*, float** %45, i64 0
%47 = load float*, float** %46
%48 = getelementptr inbounds float, float* %47, i64 1
store float 1.000000e+00, float* %48
%49 = load float**, float*** %11
%50 = getelementptr inbounds float*, float** %49, i64 0
%51 = load float*, float** %50
%52 = getelementptr inbounds float, float* %51, i64 3
store float 0.000000e+00, float* %52
%53 = load float**, float*** %11
%54 = getelementptr inbounds float*, float** %53, i64 0
%55 = load float*, float** %54
%56 = getelementptr inbounds float, float* %55, i64 2
store float 0.000000e+00, float* %56
store i32 1, i32* %14
br label %57
57: ; preds = %116, %25
%58 = load i32, i32* %14
%59 = load i32, i32* %12
%60 = icmp slt i32 %58, %59
br i1 %60, label %61, label %119
61: ; preds = %57
%62 = load double, double* %21
%63 = load double, double* %20
%64 = fadd double %63, %62
store double %64, double* %20
%65 = load double, double* %20
%66 = fptrunc double %65 to float
%67 = call float @logf(float %66)
store float %67, float* %16
%68 = load float, float* %16
%69 = load float, float* %19
%70 = fmul float %68, %69
%71 = call float @expf(float %70)
store float %71, float* %17
%72 = load float, float* %17
%73 = fneg float %72
%74 = call float @expf(float %73)
store float %74, float* %15
%75 = load float**, float*** %11
%76 = load i32, i32* %14
%77 = sext i32 %76 to i64
%78 = getelementptr inbounds float*, float** %75, i64 %77
%79 = load float*, float** %78
%80 = getelementptr inbounds float, float* %79, i64 1
store float %74, float* %80
%81 = load float*, float** %9
%82 = getelementptr inbounds float, float* %81, i64 1
%83 = load float, float* %82
%84 = load float, float* %15
%85 = fmul float %84, %83
store float %85, float* %15
%86 = load float, float* %15
%87 = load float*, float** %10
%88 = load i32, i32* %14
%89 = sext i32 %88 to i64
%90 = getelementptr inbounds float, float* %87, i64 %89
store float %86, float* %90
%91 = load float, float* %17
%92 = load float, float* %19
%93 = fmul float %91, %92
%94 = load float, float* %15
%95 = fmul float %94, %93
store float %95, float* %15
%96 = load float, float* %15
%97 = load float, float* %18
%98 = fmul float %96, %97
%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 = getelementptr inbounds float, float* %103, i64 2
store float %98, float* %104
%105 = load float, float* %15
%106 = load float, float* %16
%107 = fmul float %105, %106
%108 = load float, float* %19
%109 = fmul float %107, %108
%110 = load float**, float*** %11
%111 = load i32, i32* %14
%112 = sext i32 %111 to i64
%113 = getelementptr inbounds float*, float** %110, i64 %112
%114 = load float*, float** %113
%115 = getelementptr inbounds float, float* %114, i64 3
store float %109, float* %115
br label %116
116: ; preds = %61
%117 = load i32, i32* %14
%118 = add nsw i32 %117, 1
store i32 %118, i32* %14
br label %57
119: ; preds = %57
store i32 0, i32* %7
br label %120
120: ; preds = %119, %24
%121 = load i32, i32* %7
ret i32 %121
}

LLVM IR (-O2):
define i32 @stretchedexp_array(float %0, float* nocapture %1, float* nocapture writeonly %2, float** nocapture %3, i32 %4, i32 %5) {
%7 = fcmp oeq float %0, 0.000000e+00
br i1 %7, label %51, label %8
8: ; preds = %6
%9 = getelementptr inbounds float, float* %1, i64 2
%10 = load float, float* %9
%11 = fdiv float %0, %10
%12 = fpext float %11 to double
%13 = fdiv float 1.000000e+00, %10
%14 = getelementptr inbounds float, float* %1, i64 3
%15 = load float, float* %14
%16 = fdiv float 1.000000e+00, %15
%17 = getelementptr inbounds float, float* %1, i64 1
%18 = load float, float* %17
store float %18, float* %2
%19 = load float*, float** %3
%20 = getelementptr inbounds float, float* %19, i64 1
store float 1.000000e+00, float* %20
%21 = getelementptr inbounds float, float* %19, i64 3
store float 0.000000e+00, float* %21
%22 = getelementptr inbounds float, float* %19, i64 2
store float 0.000000e+00, float* %22
%23 = icmp sgt i32 %4, 1
br i1 %23, label %24, label %51
24: ; preds = %8
%25 = zext i32 %4 to i64
br label %26
26: ; preds = %24, %26
%27 = phi i64 [ 1, %24 ], [ %49, %26 ]
%28 = phi double [ 0.000000e+00, %24 ], [ %29, %26 ]
%29 = fadd double %28, %12
%30 = fptrunc double %29 to float
%31 = tail call float @logf(float %30)
%32 = fmul float %16, %31
%33 = tail call float @expf(float %32)
%34 = fneg float %33
%35 = tail call float @expf(float %34)
%36 = getelementptr inbounds float*, float** %3, i64 %27
%37 = load float*, float** %36
%38 = getelementptr inbounds float, float* %37, i64 1
store float %35, float* %38
%39 = load float, float* %17
%40 = fmul float %35, %39
%41 = getelementptr inbounds float, float* %2, i64 %27
store float %40, float* %41
%42 = fmul float %16, %33
%43 = fmul float %42, %40
%44 = fmul float %13, %43
%45 = getelementptr inbounds float, float* %37, i64 2
store float %44, float* %45
%46 = fmul float %31, %43
%47 = fmul float %16, %46
%48 = getelementptr inbounds float, float* %37, i64 3
store float %47, float* %48
%49 = add nuw nsw i64 %27, 1
%50 = icmp eq i64 %49, %25
br i1 %50, label %51, label %26
51: ; preds = %26, %8, %6
%52 = phi i32 [ -1, %6 ], [ 0, %8 ], [ 0, %26 ]
ret i32 %52
}