#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 f(double, double);
front(double *in, double *out, int nin, int nout, double *var, double *con) {
  int i;
  double a = in[0];
  double d = in[1];
  double *x = var + 1;
  double *xp = x + 81;
  xp[0] = f(x[0], a) + d * (x[1] - x[0]);
  xp[80] = f(x[80], a) + d * (x[79] - x[80]);
  for (i = 1; i < 80; i++)
    xp[i] = f(x[i], a) + d * (x[i + 1] - 2 * x[i] + x[i - 1]);
}


x86 assembly (clang, -O0):
<front>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %ecx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movsd  (%rax),%xmm0
movsd  %xmm0,-0x40(%rbp)
mov    -0x10(%rbp),%rax
movsd  0x8(%rax),%xmm0
movsd  %xmm0,-0x48(%rbp)
mov    -0x28(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
add    $0x288,%rax
mov    %rax,-0x58(%rbp)
mov    -0x50(%rbp),%rax
movsd  (%rax),%xmm0
movsd  -0x40(%rbp),%xmm1
call   1030 <f@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
mov    -0x50(%rbp),%rax
movsd  0x8(%rax),%xmm2
mov    -0x50(%rbp),%rax
subsd  (%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x58(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x50(%rbp),%rax
movsd  0x280(%rax),%xmm0
movsd  -0x40(%rbp),%xmm1
call   1030 <f@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
mov    -0x50(%rbp),%rax
movsd  0x278(%rax),%xmm2
mov    -0x50(%rbp),%rax
subsd  0x280(%rax),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x58(%rbp),%rax
movsd  %xmm0,0x280(%rax)
movl   $0x1,-0x34(%rbp)
cmpl   $0x50,-0x34(%rbp)
jge    1274 <front+0x164>
mov    -0x50(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  -0x40(%rbp),%xmm1
call   1030 <f@plt>
movaps %xmm0,%xmm1
movsd  -0x48(%rbp),%xmm0
mov    -0x50(%rbp),%rax
mov    -0x34(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm2
mov    -0x50(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm3
addsd  %xmm3,%xmm3
subsd  %xmm3,%xmm2
mov    -0x50(%rbp),%rax
mov    -0x34(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
addsd  (%rax,%rcx,8),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x58(%rbp),%rax
movslq -0x34(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11ef <front+0xdf>
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<front>:
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %r8,%r14
movsd  (%rdi),%xmm1
movsd  %xmm1,0x10(%rsp)
movsd  0x8(%rdi),%xmm0
movsd  %xmm0,0x8(%rsp)
movsd  0x8(%r8),%xmm0
call   1030 <f@plt>
movsd  0x10(%r14),%xmm1
subsd  0x8(%r14),%xmm1
mulsd  0x8(%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x290(%r14)
movsd  0x288(%r14),%xmm0
movsd  0x10(%rsp),%xmm1
call   1030 <f@plt>
movsd  0x280(%r14),%xmm1
subsd  0x288(%r14),%xmm1
mulsd  0x8(%rsp),%xmm1
addsd  %xmm0,%xmm1
movsd  %xmm1,0x510(%r14)
movsd  0x10(%r14),%xmm0
mov    $0xffffffffffffffb1,%rbx
nop
movsd  0x10(%rsp),%xmm1
call   1030 <f@plt>
movapd %xmm0,%xmm1
movsd  0x288(%r14,%rbx,8),%xmm2
movsd  0x290(%r14,%rbx,8),%xmm0
addsd  %xmm2,%xmm2
movapd %xmm0,%xmm3
subsd  %xmm2,%xmm3
addsd  0x280(%r14,%rbx,8),%xmm3
mulsd  0x8(%rsp),%xmm3
addsd  %xmm1,%xmm3
movsd  %xmm3,0x510(%r14,%rbx,8)
inc    %rbx
jne    11a0 <front+0x90>
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

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

LLVM IR (-O2):
define i32 @front(double* nocapture %0, double* nocapture readnone %1, i32 %2, i32 %3, double* nocapture %4, double* nocapture readnone %5) {
%7 = load double, double* %0
%8 = getelementptr inbounds double, double* %0, i64 1
%9 = load double, double* %8
%10 = getelementptr inbounds double, double* %4, i64 1
%11 = getelementptr inbounds double, double* %4, i64 82
%12 = load double, double* %10
%13 = tail call double @f(double %12, double %7)
%14 = getelementptr inbounds double, double* %4, i64 2
%15 = load double, double* %14
%16 = load double, double* %10
%17 = fsub double %15, %16
%18 = tail call double @llvm.fmuladd.f64(double %9, double %17, double %13)
store double %18, double* %11
%19 = getelementptr inbounds double, double* %4, i64 81
%20 = load double, double* %19
%21 = tail call double @f(double %20, double %7)
%22 = getelementptr inbounds double, double* %4, i64 80
%23 = load double, double* %22
%24 = load double, double* %19
%25 = fsub double %23, %24
%26 = tail call double @llvm.fmuladd.f64(double %9, double %25, double %21)
%27 = getelementptr inbounds double, double* %4, i64 162
store double %26, double* %27
%28 = getelementptr inbounds double, double* %4, i64 2
%29 = load double, double* %28
br label %30
30: ; preds = %6, %30
%31 = phi double [ %29, %6 ], [ %37, %30 ]
%32 = phi i64 [ 1, %6 ], [ %35, %30 ]
%33 = getelementptr inbounds double, double* %10, i64 %32
%34 = tail call double @f(double %31, double %7)
%35 = add nuw nsw i64 %32, 1
%36 = getelementptr inbounds double, double* %10, i64 %35
%37 = load double, double* %36
%38 = load double, double* %33
%39 = tail call double @llvm.fmuladd.f64(double %38, double -2.000000e+00, double %37)
%40 = getelementptr inbounds double, double* %4, i64 %32
%41 = load double, double* %40
%42 = fadd double %39, %41
%43 = tail call double @llvm.fmuladd.f64(double %9, double %42, double %34)
%44 = getelementptr inbounds double, double* %11, i64 %32
store double %43, double* %44
%45 = icmp eq i64 %35, 80
br i1 %45, label %46, label %30
46: ; preds = %30
ret i32 undef
}