#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 arr_init_linspace(double x[], double a, double rate, size_t N) {
  for (int i = 0; i < N; ++i) {
    x[i] = a + i * rate;
  }
}


x86 assembly (clang, -O0):
<arr_init_linspace>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %rsi,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
movslq -0x24(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    115d <arr_init_linspace+0x5d>
movsd  -0x10(%rbp),%xmm1
cvtsi2sdl -0x24(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm2
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
mov    -0x8(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    111d <arr_init_linspace+0x1d>
pop    %rbp
ret

x86 assembly (clang, -O2):
<arr_init_linspace>:
test   %rsi,%rsi
je     124d <arr_init_linspace+0x14d>
cmp    $0x4,%rsi
jae    1116 <arr_init_linspace+0x16>
xor    %eax,%eax
jmp    1230 <arr_init_linspace+0x130>
mov    %rsi,%rax
and    $0xfffffffffffffffc,%rax
movapd %xmm1,%xmm2
unpcklpd %xmm1,%xmm2
movapd %xmm0,%xmm3
unpcklpd %xmm0,%xmm3
lea    -0x4(%rax),%rcx
mov    %rcx,%r8
shr    $0x2,%r8
add    $0x1,%r8
test   %rcx,%rcx
je     124e <arr_init_linspace+0x14e>
mov    %r8,%rdx
and    $0xfffffffffffffffe,%rdx
movdqa 0xeac(%rip),%xmm6
xor    %ecx,%ecx
movdqa 0xeb1(%rip),%xmm8
movdqa 0xeb8(%rip),%xmm9
movdqa 0xebf(%rip),%xmm10
movdqa 0xec7(%rip),%xmm5
nopl   0x0(%rax)
movdqa %xmm6,%xmm4
cvtdq2pd %xmm6,%xmm7
paddd  %xmm8,%xmm4
cvtdq2pd %xmm4,%xmm4
mulpd  %xmm2,%xmm7
addpd  %xmm3,%xmm7
mulpd  %xmm2,%xmm4
addpd  %xmm3,%xmm4
movupd %xmm7,(%rdi,%rcx,8)
movupd %xmm4,0x10(%rdi,%rcx,8)
movdqa %xmm6,%xmm4
paddd  %xmm9,%xmm4
movdqa %xmm6,%xmm7
cvtdq2pd %xmm4,%xmm4
paddd  %xmm10,%xmm7
cvtdq2pd %xmm7,%xmm7
mulpd  %xmm2,%xmm4
addpd  %xmm3,%xmm4
mulpd  %xmm2,%xmm7
addpd  %xmm3,%xmm7
movupd %xmm4,0x20(%rdi,%rcx,8)
movupd %xmm7,0x30(%rdi,%rcx,8)
add    $0x8,%rcx
paddd  %xmm5,%xmm6
add    $0xfffffffffffffffe,%rdx
jne    1180 <arr_init_linspace+0x80>
test   $0x1,%r8b
je     1221 <arr_init_linspace+0x121>
cvtdq2pd %xmm6,%xmm4
paddd  0xe0e(%rip),%xmm6
cvtdq2pd %xmm6,%xmm5
mulpd  %xmm2,%xmm4
addpd  %xmm3,%xmm4
mulpd  %xmm2,%xmm5
addpd  %xmm3,%xmm5
movupd %xmm4,(%rdi,%rcx,8)
movupd %xmm5,0x10(%rdi,%rcx,8)
cmp    %rsi,%rax
je     124d <arr_init_linspace+0x14d>
cs nopw 0x0(%rax,%rax,1)
xorps  %xmm2,%xmm2
cvtsi2sd %eax,%xmm2
mulsd  %xmm1,%xmm2
addsd  %xmm0,%xmm2
movsd  %xmm2,(%rdi,%rax,8)
add    $0x1,%rax
cmp    %rax,%rsi
jne    1230 <arr_init_linspace+0x130>
ret
movdqa 0xdaa(%rip),%xmm6
xor    %ecx,%ecx
test   $0x1,%r8b
jne    11f6 <arr_init_linspace+0xf6>
jmp    1221 <arr_init_linspace+0x121>

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

LLVM IR (-O2):
define void @arr_init_linspace(double* nocapture writeonly %0, double %1, double %2, i64 %3) {
%5 = icmp eq i64 %3, 0
br i1 %5, label %71, label %6
6: ; preds = %4
%7 = icmp ult i64 %3, 4
br i1 %7, label %69, label %8
8: ; preds = %6
%9 = and i64 %3, -4
%10 = insertelement <2 x double> poison, double %2, i64 0
%11 = shufflevector <2 x double> %10, <2 x double> poison, <2 x i32> zeroinitializer
%12 = insertelement <2 x double> poison, double %1, i64 0
%13 = shufflevector <2 x double> %12, <2 x double> poison, <2 x i32> zeroinitializer
%14 = insertelement <2 x double> poison, double %2, i64 0
%15 = shufflevector <2 x double> %14, <2 x double> poison, <2 x i32> zeroinitializer
%16 = insertelement <2 x double> poison, double %1, i64 0
%17 = shufflevector <2 x double> %16, <2 x double> poison, <2 x i32> zeroinitializer
%18 = add i64 %9, -4
%19 = lshr exact i64 %18, 2
%20 = add nuw nsw i64 %19, 1
%21 = and i64 %20, 1
%22 = icmp eq i64 %18, 0
br i1 %22, label %53, label %23
23: ; preds = %8
%24 = and i64 %20, 9223372036854775806
br label %25
25: ; preds = %25, %23
%26 = phi i64 [ 0, %23 ], [ %49, %25 ]
%27 = phi <2 x i32> [ <i32 0, i32 1>, %23 ], [ %50, %25 ]
%28 = phi i64 [ 0, %23 ], [ %51, %25 ]
%29 = add <2 x i32> %27, <i32 2, i32 2>
%30 = sitofp <2 x i32> %27 to <2 x double>
%31 = sitofp <2 x i32> %29 to <2 x double>
%32 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %30, <2 x double> %11, <2 x double> %13)
%33 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %31, <2 x double> %15, <2 x double> %17)
%34 = getelementptr inbounds double, double* %0, i64 %26
%35 = bitcast double* %34 to <2 x double>*
store <2 x double> %32, <2 x double>* %35
%36 = getelementptr inbounds double, double* %34, i64 2
%37 = bitcast double* %36 to <2 x double>*
store <2 x double> %33, <2 x double>* %37
%38 = or i64 %26, 4
%39 = add <2 x i32> %27, <i32 4, i32 4>
%40 = add <2 x i32> %27, <i32 6, i32 6>
%41 = sitofp <2 x i32> %39 to <2 x double>
%42 = sitofp <2 x i32> %40 to <2 x double>
%43 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %41, <2 x double> %11, <2 x double> %13)
%44 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %42, <2 x double> %15, <2 x double> %17)
%45 = getelementptr inbounds double, double* %0, i64 %38
%46 = bitcast double* %45 to <2 x double>*
store <2 x double> %43, <2 x double>* %46
%47 = getelementptr inbounds double, double* %45, i64 2
%48 = bitcast double* %47 to <2 x double>*
store <2 x double> %44, <2 x double>* %48
%49 = add nuw i64 %26, 8
%50 = add <2 x i32> %27, <i32 8, i32 8>
%51 = add i64 %28, 2
%52 = icmp eq i64 %51, %24
br i1 %52, label %53, label %25
53: ; preds = %25, %8
%54 = phi i64 [ 0, %8 ], [ %49, %25 ]
%55 = phi <2 x i32> [ <i32 0, i32 1>, %8 ], [ %50, %25 ]
%56 = icmp eq i64 %21, 0
br i1 %56, label %67, label %57
57: ; preds = %53
%58 = add <2 x i32> %55, <i32 2, i32 2>
%59 = sitofp <2 x i32> %55 to <2 x double>
%60 = sitofp <2 x i32> %58 to <2 x double>
%61 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %59, <2 x double> %11, <2 x double> %13)
%62 = call <2 x double> @llvm.fmuladd.v2f64(<2 x double> %60, <2 x double> %15, <2 x double> %17)
%63 = getelementptr inbounds double, double* %0, i64 %54
%64 = bitcast double* %63 to <2 x double>*
store <2 x double> %61, <2 x double>* %64
%65 = getelementptr inbounds double, double* %63, i64 2
%66 = bitcast double* %65 to <2 x double>*
store <2 x double> %62, <2 x double>* %66
br label %67
67: ; preds = %53, %57
%68 = icmp eq i64 %9, %3
br i1 %68, label %71, label %69
69: ; preds = %6, %67
%70 = phi i64 [ 0, %6 ], [ %9, %67 ]
br label %72
71: ; preds = %72, %67, %4
ret void
72: ; preds = %69, %72
%73 = phi i64 [ %78, %72 ], [ %70, %69 ]
%74 = trunc i64 %73 to i32
%75 = sitofp i32 %74 to double
%76 = tail call double @llvm.fmuladd.f64(double %75, double %2, double %1)
%77 = getelementptr inbounds double, double* %0, i64 %73
store double %76, double* %77
%78 = add nuw nsw i64 %73, 1
%79 = icmp eq i64 %78, %3
br i1 %79, label %71, label %72
}