#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*/ memcpy(float *, float const *, int);
float *bezier2_split(float *dest, size_t d, float const *p, double t) {
  double s;
  float const *p0, *p1, *p2;
  float *q1, *q2, *q3;
  size_t i;
  p0 = p;
  p1 = p0 + d;
  p2 = p1 + d;
  q1 = dest;
  q2 = q1 + d;
  q3 = q2 + d;
  if (t <= 0.0) {
    (void)memcpy(q1, p0, sizeof(float) * d);
    (void)memcpy(q2, p0, sizeof(float) * d);
    (void)memcpy(q3, p1, sizeof(float) * d);
    return dest;
  }
  if (t >= 1.0) {
    (void)memcpy(q1, p1, sizeof(float) * d);
    (void)memcpy(q2, p2, sizeof(float) * d);
    (void)memcpy(q3, p2, sizeof(float) * d);
    return dest;
  }
  s = 1.0 - t;
  for (i = 0; i < d; i++) {
    q1[i] = s * p0[i] + t * p1[i];
    q3[i] = s * p1[i] + t * p2[i];
    q2[i] = s * q1[i] + t * q3[i];
  }
  return dest;
}


x86 assembly (clang, -O0):
<bezier2_split>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
movsd  %xmm0,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
mov    -0x18(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rax
mov    -0x18(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x48(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
mov    -0x18(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x58(%rbp)
mov    -0x58(%rbp),%rax
mov    -0x18(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x60(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x28(%rbp),%xmm0
jb     11e5 <bezier2_split+0xd5>
mov    -0x50(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edx
call   1030 <memcpy@plt>
mov    -0x58(%rbp),%rdi
mov    -0x38(%rbp),%rsi
mov    -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edx
call   1030 <memcpy@plt>
mov    -0x60(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edx
call   1030 <memcpy@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    136a <bezier2_split+0x25a>
movsd  -0x28(%rbp),%xmm0
movsd  0xe0e(%rip),%xmm1
ucomisd %xmm1,%xmm0
jb     124e <bezier2_split+0x13e>
mov    -0x50(%rbp),%rdi
mov    -0x40(%rbp),%rsi
mov    -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edx
call   1030 <memcpy@plt>
mov    -0x58(%rbp),%rdi
mov    -0x48(%rbp),%rsi
mov    -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edx
call   1030 <memcpy@plt>
mov    -0x60(%rbp),%rdi
mov    -0x48(%rbp),%rsi
mov    -0x18(%rbp),%rax
shl    $0x2,%rax
mov    %eax,%edx
call   1030 <memcpy@plt>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    136a <bezier2_split+0x25a>
movsd  0xdaa(%rip),%xmm0
subsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x30(%rbp)
movq   $0x0,-0x68(%rbp)
mov    -0x68(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1362 <bezier2_split+0x252>
movsd  -0x30(%rbp),%xmm0
mov    -0x38(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  -0x28(%rbp),%xmm1
mov    -0x40(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x50(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movsd  -0x30(%rbp),%xmm0
mov    -0x40(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  -0x28(%rbp),%xmm1
mov    -0x48(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x60(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
movsd  -0x30(%rbp),%xmm0
mov    -0x50(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm1
cvtss2sd %xmm1,%xmm2
movsd  -0x28(%rbp),%xmm1
mov    -0x60(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm3,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
mov    -0x58(%rbp),%rax
mov    -0x68(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x68(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x68(%rbp)
jmp    1268 <bezier2_split+0x158>
mov    -0x10(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<bezier2_split>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
mov    %rdx,%rbp
mov    %rsi,%r12
mov    %rdi,%r14
lea    (%rdx,%rsi,4),%rbx
lea    (%rdi,%rsi,4),%r13
lea    0x0(,%rsi,4),%rcx
add    %r13,%rcx
xorpd  %xmm1,%xmm1
ucomisd %xmm0,%xmm1
jae    11ee <bezier2_split+0xde>
lea    (%rbx,%r12,4),%r15
ucomisd 0xeaf(%rip),%xmm0
jae    1219 <bezier2_split+0x109>
test   %r12,%r12
je     124a <bezier2_split+0x13a>
movsd  0xe98(%rip),%xmm1
subsd  %xmm0,%xmm1
xor    %eax,%eax
xchg   %ax,%ax
movss  0x0(%rbp,%rax,4),%xmm2
cvtss2sd %xmm2,%xmm2
movss  (%rbx,%rax,4),%xmm3
cvtss2sd %xmm3,%xmm3
mulsd  %xmm0,%xmm3
mulsd  %xmm1,%xmm2
addsd  %xmm3,%xmm2
cvtsd2ss %xmm2,%xmm2
movss  %xmm2,(%r14,%rax,4)
movss  (%rbx,%rax,4),%xmm3
cvtss2sd %xmm3,%xmm3
movss  (%r15,%rax,4),%xmm4
cvtss2sd %xmm4,%xmm4
mulsd  %xmm0,%xmm4
mulsd  %xmm1,%xmm3
addsd  %xmm4,%xmm3
cvtsd2ss %xmm3,%xmm3
cvtss2sd %xmm2,%xmm2
xorps  %xmm4,%xmm4
cvtss2sd %xmm3,%xmm4
mulsd  %xmm0,%xmm4
mulsd  %xmm1,%xmm2
addsd  %xmm4,%xmm2
cvtsd2ss %xmm2,%xmm2
movss  %xmm3,(%rcx,%rax,4)
movss  %xmm2,0x0(%r13,%rax,4)
add    $0x1,%rax
cmp    %rax,%r12
jne    1170 <bezier2_split+0x60>
jmp    124a <bezier2_split+0x13a>
shl    $0x2,%r12d
mov    %rcx,%r15
mov    %r14,%rdi
mov    %rbp,%rsi
mov    %r12d,%edx
call   1030 <memcpy@plt>
mov    %r13,%rdi
mov    %rbp,%rsi
mov    %r12d,%edx
call   1030 <memcpy@plt>
mov    %r15,%rdi
mov    %rbx,%rsi
jmp    1242 <bezier2_split+0x132>
shl    $0x2,%r12d
mov    %rcx,%rbp
mov    %r14,%rdi
mov    %rbx,%rsi
mov    %r12d,%edx
call   1030 <memcpy@plt>
mov    %r13,%rdi
mov    %r15,%rsi
mov    %r12d,%edx
call   1030 <memcpy@plt>
mov    %rbp,%rdi
mov    %r15,%rsi
mov    %r12d,%edx
call   1030 <memcpy@plt>
mov    %r14,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define float* @bezier2_split(float* %0, i64 %1, float* %2, double %3) {
%5 = alloca float*
%6 = alloca float*
%7 = alloca i64
%8 = alloca float*
%9 = alloca double
%10 = alloca double
%11 = alloca float*
%12 = alloca float*
%13 = alloca float*
%14 = alloca float*
%15 = alloca float*
%16 = alloca float*
%17 = alloca i64
store float* %0, float** %6
store i64 %1, i64* %7
store float* %2, float** %8
store double %3, double* %9
%18 = load float*, float** %8
store float* %18, float** %11
%19 = load float*, float** %11
%20 = load i64, i64* %7
%21 = getelementptr inbounds float, float* %19, i64 %20
store float* %21, float** %12
%22 = load float*, float** %12
%23 = load i64, i64* %7
%24 = getelementptr inbounds float, float* %22, i64 %23
store float* %24, float** %13
%25 = load float*, float** %6
store float* %25, float** %14
%26 = load float*, float** %14
%27 = load i64, i64* %7
%28 = getelementptr inbounds float, float* %26, i64 %27
store float* %28, float** %15
%29 = load float*, float** %15
%30 = load i64, i64* %7
%31 = getelementptr inbounds float, float* %29, i64 %30
store float* %31, float** %16
%32 = load double, double* %9
%33 = fcmp ole double %32, 0.000000e+00
br i1 %33, label %34, label %54
34: ; preds = %4
%35 = load float*, float** %14
%36 = load float*, float** %11
%37 = load i64, i64* %7
%38 = mul i64 4, %37
%39 = trunc i64 %38 to i32
%40 = call i32 @memcpy(float* %35, float* %36, i32 %39)
%41 = load float*, float** %15
%42 = load float*, float** %11
%43 = load i64, i64* %7
%44 = mul i64 4, %43
%45 = trunc i64 %44 to i32
%46 = call i32 @memcpy(float* %41, float* %42, i32 %45)
%47 = load float*, float** %16
%48 = load float*, float** %12
%49 = load i64, i64* %7
%50 = mul i64 4, %49
%51 = trunc i64 %50 to i32
%52 = call i32 @memcpy(float* %47, float* %48, i32 %51)
%53 = load float*, float** %6
store float* %53, float** %5
br label %144
54: ; preds = %4
%55 = load double, double* %9
%56 = fcmp oge double %55, 1.000000e+00
br i1 %56, label %57, label %77
57: ; preds = %54
%58 = load float*, float** %14
%59 = load float*, float** %12
%60 = load i64, i64* %7
%61 = mul i64 4, %60
%62 = trunc i64 %61 to i32
%63 = call i32 @memcpy(float* %58, float* %59, i32 %62)
%64 = load float*, float** %15
%65 = load float*, float** %13
%66 = load i64, i64* %7
%67 = mul i64 4, %66
%68 = trunc i64 %67 to i32
%69 = call i32 @memcpy(float* %64, float* %65, i32 %68)
%70 = load float*, float** %16
%71 = load float*, float** %13
%72 = load i64, i64* %7
%73 = mul i64 4, %72
%74 = trunc i64 %73 to i32
%75 = call i32 @memcpy(float* %70, float* %71, i32 %74)
%76 = load float*, float** %6
store float* %76, float** %5
br label %144
77: ; preds = %54
%78 = load double, double* %9
%79 = fsub double 1.000000e+00, %78
store double %79, double* %10
store i64 0, i64* %17
br label %80
80: ; preds = %139, %77
%81 = load i64, i64* %17
%82 = load i64, i64* %7
%83 = icmp ult i64 %81, %82
br i1 %83, label %84, label %142
84: ; preds = %80
%85 = load double, double* %10
%86 = load float*, float** %11
%87 = load i64, i64* %17
%88 = getelementptr inbounds float, float* %86, i64 %87
%89 = load float, float* %88
%90 = fpext float %89 to double
%91 = load double, double* %9
%92 = load float*, float** %12
%93 = load i64, i64* %17
%94 = getelementptr inbounds float, float* %92, i64 %93
%95 = load float, float* %94
%96 = fpext float %95 to double
%97 = fmul double %91, %96
%98 = call double @llvm.fmuladd.f64(double %85, double %90, double %97)
%99 = fptrunc double %98 to float
%100 = load float*, float** %14
%101 = load i64, i64* %17
%102 = getelementptr inbounds float, float* %100, i64 %101
store float %99, float* %102
%103 = load double, double* %10
%104 = load float*, float** %12
%105 = load i64, i64* %17
%106 = getelementptr inbounds float, float* %104, i64 %105
%107 = load float, float* %106
%108 = fpext float %107 to double
%109 = load double, double* %9
%110 = load float*, float** %13
%111 = load i64, i64* %17
%112 = getelementptr inbounds float, float* %110, i64 %111
%113 = load float, float* %112
%114 = fpext float %113 to double
%115 = fmul double %109, %114
%116 = call double @llvm.fmuladd.f64(double %103, double %108, double %115)
%117 = fptrunc double %116 to float
%118 = load float*, float** %16
%119 = load i64, i64* %17
%120 = getelementptr inbounds float, float* %118, i64 %119
store float %117, float* %120
%121 = load double, double* %10
%122 = load float*, float** %14
%123 = load i64, i64* %17
%124 = getelementptr inbounds float, float* %122, i64 %123
%125 = load float, float* %124
%126 = fpext float %125 to double
%127 = load double, double* %9
%128 = load float*, float** %16
%129 = load i64, i64* %17
%130 = getelementptr inbounds float, float* %128, i64 %129
%131 = load float, float* %130
%132 = fpext float %131 to double
%133 = fmul double %127, %132
%134 = call double @llvm.fmuladd.f64(double %121, double %126, double %133)
%135 = fptrunc double %134 to float
%136 = load float*, float** %15
%137 = load i64, i64* %17
%138 = getelementptr inbounds float, float* %136, i64 %137
store float %135, float* %138
br label %139
139: ; preds = %84
%140 = load i64, i64* %17
%141 = add i64 %140, 1
store i64 %141, i64* %17
br label %80
142: ; preds = %80
%143 = load float*, float** %6
store float* %143, float** %5
br label %144
144: ; preds = %142, %57, %34
%145 = load float*, float** %5
ret float* %145
}

LLVM IR (-O2):
define float* @bezier2_split(float* returned %0, i64 %1, float* %2, double %3) {
%5 = getelementptr inbounds float, float* %2, i64 %1
%6 = getelementptr inbounds float, float* %5, i64 %1
%7 = getelementptr inbounds float, float* %0, i64 %1
%8 = getelementptr inbounds float, float* %7, i64 %1
%9 = fcmp ugt double %3, 0.000000e+00
br i1 %9, label %16, label %10
10: ; preds = %4
%11 = trunc i64 %1 to i32
%12 = shl i32 %11, 2
%13 = tail call i32 @memcpy(float* %0, float* %2, i32 %12)
%14 = tail call i32 @memcpy(float* %7, float* %2, i32 %12)
%15 = tail call i32 @memcpy(float* %8, float* %5, i32 %12)
br label %56
16: ; preds = %4
%17 = fcmp ult double %3, 1.000000e+00
br i1 %17, label %24, label %18
18: ; preds = %16
%19 = trunc i64 %1 to i32
%20 = shl i32 %19, 2
%21 = tail call i32 @memcpy(float* %0, float* %5, i32 %20)
%22 = tail call i32 @memcpy(float* %7, float* %6, i32 %20)
%23 = tail call i32 @memcpy(float* %8, float* %6, i32 %20)
br label %56
24: ; preds = %16
%25 = fsub double 1.000000e+00, %3
%26 = icmp eq i64 %1, 0
br i1 %26, label %56, label %27
27: ; preds = %24, %27
%28 = phi i64 [ %54, %27 ], [ 0, %24 ]
%29 = getelementptr inbounds float, float* %2, i64 %28
%30 = load float, float* %29
%31 = fpext float %30 to double
%32 = getelementptr inbounds float, float* %5, i64 %28
%33 = load float, float* %32
%34 = fpext float %33 to double
%35 = fmul double %34, %3
%36 = tail call double @llvm.fmuladd.f64(double %25, double %31, double %35)
%37 = fptrunc double %36 to float
%38 = getelementptr inbounds float, float* %0, i64 %28
store float %37, float* %38
%39 = load float, float* %32
%40 = fpext float %39 to double
%41 = getelementptr inbounds float, float* %6, i64 %28
%42 = load float, float* %41
%43 = fpext float %42 to double
%44 = fmul double %43, %3
%45 = tail call double @llvm.fmuladd.f64(double %25, double %40, double %44)
%46 = fptrunc double %45 to float
%47 = getelementptr inbounds float, float* %8, i64 %28
store float %46, float* %47
%48 = fpext float %37 to double
%49 = fpext float %46 to double
%50 = fmul double %49, %3
%51 = tail call double @llvm.fmuladd.f64(double %25, double %48, double %50)
%52 = fptrunc double %51 to float
%53 = getelementptr inbounds float, float* %7, i64 %28
store float %52, float* %53
%54 = add nuw i64 %28, 1
%55 = icmp eq i64 %54, %1
br i1 %55, label %56, label %27
56: ; preds = %27, %24, %18, %10
ret float* %0
}