#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 */
void vector_upd_diffs_operation_inner(
    const void *restrict ctx, const size_t _offset, double *const restrict _v0,
    double *const restrict _v1, double *const restrict _v2,
    double *const restrict _v3, const size_t _num_elems) {
  size_t _i;
  (void)ctx;
  for (_i = 0; _i < _num_elems; ++_i) {
    size_t index = _offset + _i;
    double *const yp = _v0 + _i;
    double *const phi0 = _v1 + _i;
    double *const phik = _v2 + _i;
    double *const phikp1 = _v3 + _i;
    (void)index;
    {
      {
        *phik = *yp - *phi0;
        *phikp1 = *phik - *phikp1;
      }
    }
  }
}


x86 assembly (clang, -O0):
<vector_upd_diffs_operation_inner>:
push   %rbp
mov    %rsp,%rbp
mov    0x10(%rbp),%rax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    0x10(%rbp),%rax
jae    11cf <vector_upd_diffs_operation_inner+0xcf>
mov    -0x10(%rbp),%rax
add    -0x38(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x18(%rbp),%rax
mov    -0x38(%rbp),%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x48(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x38(%rbp),%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x58(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x38(%rbp),%rcx
shl    $0x3,%rcx
add    %rcx,%rax
mov    %rax,-0x60(%rbp)
mov    -0x48(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x50(%rbp),%rax
subsd  (%rax),%xmm0
mov    -0x58(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x58(%rbp),%rax
movsd  (%rax),%xmm0
mov    -0x60(%rbp),%rax
subsd  (%rax),%xmm0
mov    -0x60(%rbp),%rax
movsd  %xmm0,(%rax)
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1128 <vector_upd_diffs_operation_inner+0x28>
pop    %rbp
ret

x86 assembly (clang, -O2):
<vector_upd_diffs_operation_inner>:
mov    0x8(%rsp),%r11
test   %r11,%r11
je     1205 <vector_upd_diffs_operation_inner+0x105>
cmp    $0x1,%r11
jne    111b <vector_upd_diffs_operation_inner+0x1b>
xor    %esi,%esi
jmp    11e0 <vector_upd_diffs_operation_inner+0xe0>
mov    %r11,%rsi
and    $0xfffffffffffffffe,%rsi
lea    -0x2(%rsi),%rax
mov    %rax,%r10
shr    %r10
add    $0x1,%r10
test   %rax,%rax
je     1206 <vector_upd_diffs_operation_inner+0x106>
mov    %r10,%rax
and    $0xfffffffffffffffe,%rax
xor    %edi,%edi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movupd (%rdx,%rdi,8),%xmm0
movupd (%rcx,%rdi,8),%xmm1
subpd  %xmm1,%xmm0
movupd %xmm0,(%r8,%rdi,8)
movupd (%r9,%rdi,8),%xmm1
subpd  %xmm1,%xmm0
movupd %xmm0,(%r9,%rdi,8)
movupd 0x10(%rdx,%rdi,8),%xmm0
movupd 0x10(%rcx,%rdi,8),%xmm1
subpd  %xmm1,%xmm0
movupd %xmm0,0x10(%r8,%rdi,8)
movupd 0x10(%r9,%rdi,8),%xmm1
subpd  %xmm1,%xmm0
movupd %xmm0,0x10(%r9,%rdi,8)
add    $0x4,%rdi
add    $0xfffffffffffffffe,%rax
jne    1150 <vector_upd_diffs_operation_inner+0x50>
test   $0x1,%r10b
je     11d1 <vector_upd_diffs_operation_inner+0xd1>
movupd (%rdx,%rdi,8),%xmm0
movupd (%rcx,%rdi,8),%xmm1
subpd  %xmm1,%xmm0
movupd %xmm0,(%r8,%rdi,8)
movupd (%r9,%rdi,8),%xmm1
subpd  %xmm1,%xmm0
movupd %xmm0,(%r9,%rdi,8)
cmp    %r11,%rsi
je     1205 <vector_upd_diffs_operation_inner+0x105>
cs nopw 0x0(%rax,%rax,1)
movsd  (%rdx,%rsi,8),%xmm0
subsd  (%rcx,%rsi,8),%xmm0
movsd  %xmm0,(%r8,%rsi,8)
subsd  (%r9,%rsi,8),%xmm0
movsd  %xmm0,(%r9,%rsi,8)
add    $0x1,%rsi
cmp    %rsi,%r11
jne    11e0 <vector_upd_diffs_operation_inner+0xe0>
ret
xor    %edi,%edi
test   $0x1,%r10b
jne    11ad <vector_upd_diffs_operation_inner+0xad>
jmp    11d1 <vector_upd_diffs_operation_inner+0xd1>

LLVM IR (-O0):
define void @vector_upd_diffs_operation_inner(i8* noalias %0, i64 %1, double* noalias %2, double* noalias %3, double* noalias %4, double* noalias %5, i64 %6) {
%8 = alloca i8*
%9 = alloca i64
%10 = alloca double*
%11 = alloca double*
%12 = alloca double*
%13 = alloca double*
%14 = alloca i64
%15 = alloca i64
%16 = alloca i64
%17 = alloca double*
%18 = alloca double*
%19 = alloca double*
%20 = alloca double*
store i8* %0, i8** %8
store i64 %1, i64* %9
store double* %2, double** %10
store double* %3, double** %11
store double* %4, double** %12
store double* %5, double** %13
store i64 %6, i64* %14
%21 = load i8*, i8** %8
store i64 0, i64* %15
br label %22
22: ; preds = %55, %7
%23 = load i64, i64* %15
%24 = load i64, i64* %14
%25 = icmp ult i64 %23, %24
br i1 %25, label %26, label %58
26: ; preds = %22
%27 = load i64, i64* %9
%28 = load i64, i64* %15
%29 = add i64 %27, %28
store i64 %29, i64* %16
%30 = load double*, double** %10
%31 = load i64, i64* %15
%32 = getelementptr inbounds double, double* %30, i64 %31
store double* %32, double** %17
%33 = load double*, double** %11
%34 = load i64, i64* %15
%35 = getelementptr inbounds double, double* %33, i64 %34
store double* %35, double** %18
%36 = load double*, double** %12
%37 = load i64, i64* %15
%38 = getelementptr inbounds double, double* %36, i64 %37
store double* %38, double** %19
%39 = load double*, double** %13
%40 = load i64, i64* %15
%41 = getelementptr inbounds double, double* %39, i64 %40
store double* %41, double** %20
%42 = load i64, i64* %16
%43 = load double*, double** %17
%44 = load double, double* %43
%45 = load double*, double** %18
%46 = load double, double* %45
%47 = fsub double %44, %46
%48 = load double*, double** %19
store double %47, double* %48
%49 = load double*, double** %19
%50 = load double, double* %49
%51 = load double*, double** %20
%52 = load double, double* %51
%53 = fsub double %50, %52
%54 = load double*, double** %20
store double %53, double* %54
br label %55
55: ; preds = %26
%56 = load i64, i64* %15
%57 = add i64 %56, 1
store i64 %57, i64* %15
br label %22
58: ; preds = %22
ret void
}

LLVM IR (-O2):
define void @vector_upd_diffs_operation_inner(i8* noalias nocapture readnone %0, i64 %1, double* noalias nocapture %2, double* noalias nocapture %3, double* noalias nocapture writeonly %4, double* noalias nocapture %5, i64 %6) {
switch i64 %6, label %8 [
i64 0, label %87
i64 1, label %72
]
8: ; preds = %7
%9 = and i64 %6, -2
%10 = add i64 %9, -2
%11 = lshr exact i64 %10, 1
%12 = add nuw i64 %11, 1
%13 = and i64 %12, 1
%14 = icmp eq i64 %10, 0
br i1 %14, label %52, label %15
15: ; preds = %8
%16 = and i64 %12, -2
br label %17
17: ; preds = %17, %15
%18 = phi i64 [ 0, %15 ], [ %49, %17 ]
%19 = phi i64 [ 0, %15 ], [ %50, %17 ]
%20 = getelementptr inbounds double, double* %2, i64 %18
%21 = getelementptr inbounds double, double* %3, i64 %18
%22 = getelementptr inbounds double, double* %4, i64 %18
%23 = getelementptr inbounds double, double* %5, i64 %18
%24 = bitcast double* %20 to <2 x double>*
%25 = load <2 x double>, <2 x double>* %24
%26 = bitcast double* %21 to <2 x double>*
%27 = load <2 x double>, <2 x double>* %26
%28 = fsub <2 x double> %25, %27
%29 = bitcast double* %22 to <2 x double>*
store <2 x double> %28, <2 x double>* %29
%30 = bitcast double* %23 to <2 x double>*
%31 = load <2 x double>, <2 x double>* %30
%32 = fsub <2 x double> %28, %31
%33 = bitcast double* %23 to <2 x double>*
store <2 x double> %32, <2 x double>* %33
%34 = or i64 %18, 2
%35 = getelementptr inbounds double, double* %2, i64 %34
%36 = getelementptr inbounds double, double* %3, i64 %34
%37 = getelementptr inbounds double, double* %4, i64 %34
%38 = getelementptr inbounds double, double* %5, i64 %34
%39 = bitcast double* %35 to <2 x double>*
%40 = load <2 x double>, <2 x double>* %39
%41 = bitcast double* %36 to <2 x double>*
%42 = load <2 x double>, <2 x double>* %41
%43 = fsub <2 x double> %40, %42
%44 = bitcast double* %37 to <2 x double>*
store <2 x double> %43, <2 x double>* %44
%45 = bitcast double* %38 to <2 x double>*
%46 = load <2 x double>, <2 x double>* %45
%47 = fsub <2 x double> %43, %46
%48 = bitcast double* %38 to <2 x double>*
store <2 x double> %47, <2 x double>* %48
%49 = add nuw i64 %18, 4
%50 = add nuw i64 %19, 2
%51 = icmp eq i64 %50, %16
br i1 %51, label %52, label %17
52: ; preds = %17, %8
%53 = phi i64 [ 0, %8 ], [ %49, %17 ]
%54 = icmp eq i64 %13, 0
br i1 %54, label %70, label %55
55: ; preds = %52
%56 = getelementptr inbounds double, double* %2, i64 %53
%57 = getelementptr inbounds double, double* %3, i64 %53
%58 = getelementptr inbounds double, double* %4, i64 %53
%59 = getelementptr inbounds double, double* %5, i64 %53
%60 = bitcast double* %56 to <2 x double>*
%61 = load <2 x double>, <2 x double>* %60
%62 = bitcast double* %57 to <2 x double>*
%63 = load <2 x double>, <2 x double>* %62
%64 = fsub <2 x double> %61, %63
%65 = bitcast double* %58 to <2 x double>*
store <2 x double> %64, <2 x double>* %65
%66 = bitcast double* %59 to <2 x double>*
%67 = load <2 x double>, <2 x double>* %66
%68 = fsub <2 x double> %64, %67
%69 = bitcast double* %59 to <2 x double>*
store <2 x double> %68, <2 x double>* %69
br label %70
70: ; preds = %52, %55
%71 = icmp eq i64 %9, %6
br i1 %71, label %87, label %72
72: ; preds = %7, %70
%73 = phi i64 [ 0, %7 ], [ %9, %70 ]
br label %74
74: ; preds = %72, %74
%75 = phi i64 [ %85, %74 ], [ %73, %72 ]
%76 = getelementptr inbounds double, double* %2, i64 %75
%77 = getelementptr inbounds double, double* %3, i64 %75
%78 = getelementptr inbounds double, double* %4, i64 %75
%79 = getelementptr inbounds double, double* %5, i64 %75
%80 = load double, double* %76
%81 = load double, double* %77
%82 = fsub double %80, %81
store double %82, double* %78
%83 = load double, double* %79
%84 = fsub double %82, %83
store double %84, double* %79
%85 = add nuw i64 %75, 1
%86 = icmp eq i64 %85, %6
br i1 %86, label %87, label %74
87: ; preds = %74, %70, %7
ret void
}