#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(double const *);
void vectord_add(const double *self, size_t size, double value,
                 double *output) {
  assert(self);
  assert(output);
  for (size_t i = 0; i < size; i++)
    output[i] = self[i] + value;
}


x86 assembly (clang, -O0):
<vectord_add>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
mov    -0x8(%rbp),%rdi
call   1030 <assert@plt>
mov    -0x20(%rbp),%rdi
call   1030 <assert@plt>
movq   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    1181 <vectord_add+0x71>
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
addsd  -0x18(%rbp),%xmm0
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1143 <vectord_add+0x33>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<vectord_add>:
push   %r15
push   %r14
push   %rbx
sub    $0x10,%rsp
mov    %rdx,%r15
movapd %xmm0,(%rsp)
mov    %rsi,%r14
mov    %rdi,%rbx
call   1030 <assert@plt>
mov    %r15,%rdi
call   1030 <assert@plt>
movapd (%rsp),%xmm3
test   %r14,%r14
je     12aa <vectord_add+0x19a>
cmp    $0x4,%r14
jb     1162 <vectord_add+0x52>
lea    (%rbx,%r14,8),%rax
cmp    %r15,%rax
jbe    1200 <vectord_add+0xf0>
lea    (%r15,%r14,8),%rax
cmp    %rbx,%rax
jbe    1200 <vectord_add+0xf0>
xor    %eax,%eax
mov    %rax,%rcx
not    %rcx
add    %r14,%rcx
mov    %r14,%rdx
and    $0x3,%rdx
je     1199 <vectord_add+0x89>
cs nopw 0x0(%rax,%rax,1)
movsd  (%rbx,%rax,8),%xmm0
addsd  %xmm3,%xmm0
movsd  %xmm0,(%r15,%rax,8)
add    $0x1,%rax
add    $0xffffffffffffffff,%rdx
jne    1180 <vectord_add+0x70>
cmp    $0x3,%rcx
jb     12aa <vectord_add+0x19a>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movsd  (%rbx,%rax,8),%xmm0
addsd  %xmm3,%xmm0
movsd  %xmm0,(%r15,%rax,8)
movsd  0x8(%rbx,%rax,8),%xmm0
addsd  %xmm3,%xmm0
movsd  %xmm0,0x8(%r15,%rax,8)
movsd  0x10(%rbx,%rax,8),%xmm0
addsd  %xmm3,%xmm0
movsd  %xmm0,0x10(%r15,%rax,8)
movsd  0x18(%rbx,%rax,8),%xmm0
addsd  %xmm3,%xmm0
movsd  %xmm0,0x18(%r15,%rax,8)
add    $0x4,%rax
cmp    %rax,%r14
jne    11b0 <vectord_add+0xa0>
jmp    12aa <vectord_add+0x19a>
mov    %r14,%rax
and    $0xfffffffffffffffc,%rax
movapd %xmm3,%xmm0
unpcklpd %xmm3,%xmm0
lea    -0x4(%rax),%rcx
mov    %rcx,%rdx
shr    $0x2,%rdx
add    $0x1,%rdx
test   %rcx,%rcx
je     12b4 <vectord_add+0x1a4>
mov    %rdx,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %ecx,%ecx
movupd (%rbx,%rcx,8),%xmm1
movupd 0x10(%rbx,%rcx,8),%xmm2
addpd  %xmm0,%xmm1
addpd  %xmm0,%xmm2
movupd %xmm1,(%r15,%rcx,8)
movupd %xmm2,0x10(%r15,%rcx,8)
movupd 0x20(%rbx,%rcx,8),%xmm1
movupd 0x30(%rbx,%rcx,8),%xmm2
addpd  %xmm0,%xmm1
addpd  %xmm0,%xmm2
movupd %xmm1,0x20(%r15,%rcx,8)
movupd %xmm2,0x30(%r15,%rcx,8)
add    $0x8,%rcx
add    $0xfffffffffffffffe,%rsi
jne    1230 <vectord_add+0x120>
test   $0x1,%dl
je     12a1 <vectord_add+0x191>
movupd (%rbx,%rcx,8),%xmm1
movupd 0x10(%rbx,%rcx,8),%xmm2
addpd  %xmm0,%xmm1
addpd  %xmm0,%xmm2
movupd %xmm1,(%r15,%rcx,8)
movupd %xmm2,0x10(%r15,%rcx,8)
cmp    %r14,%rax
jne    1164 <vectord_add+0x54>
add    $0x10,%rsp
pop    %rbx
pop    %r14
pop    %r15
ret
xor    %ecx,%ecx
test   $0x1,%dl
jne    1281 <vectord_add+0x171>
jmp    12a1 <vectord_add+0x191>

LLVM IR (-O0):
define void @vectord_add(double* %0, i64 %1, double %2, double* %3) {
%5 = alloca double*
%6 = alloca i64
%7 = alloca double
%8 = alloca double*
%9 = alloca i64
store double* %0, double** %5
store i64 %1, i64* %6
store double %2, double* %7
store double* %3, double** %8
%10 = load double*, double** %5
%11 = call i32 @assert(double* %10)
%12 = load double*, double** %8
%13 = call i32 @assert(double* %12)
store i64 0, i64* %9
br label %14
14: ; preds = %28, %4
%15 = load i64, i64* %9
%16 = load i64, i64* %6
%17 = icmp ult i64 %15, %16
br i1 %17, label %18, label %31
18: ; preds = %14
%19 = load double*, double** %5
%20 = load i64, i64* %9
%21 = getelementptr inbounds double, double* %19, i64 %20
%22 = load double, double* %21
%23 = load double, double* %7
%24 = fadd double %22, %23
%25 = load double*, double** %8
%26 = load i64, i64* %9
%27 = getelementptr inbounds double, double* %25, i64 %26
store double %24, double* %27
br label %28
28: ; preds = %18
%29 = load i64, i64* %9
%30 = add i64 %29, 1
store i64 %30, i64* %9
br label %14
31: ; preds = %14
ret void
}

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