#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 sqrt(double);
void ComputeFdualXb(int M, double *b) {
  int i = 0;
  double a = 0;
  for (i = 0; i < M - 1; i++) {
    b[i] = b[i + 1] - b[i];
  }
  b[M - 1] = 0;
  for (i = 0; i < M - 1; i++) {
    a = (double)(M - 1 - i) * (double)(i + 1) / (double)M;
    b[i] = b[i] * sqrt(a);
  }
}


x86 assembly (clang, -O0):
<ComputeFdualXb>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
movl   $0x0,-0x14(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1180 <ComputeFdualXb+0x70>
mov    -0x10(%rbp),%rax
mov    -0x14(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1135 <ComputeFdualXb+0x25>
mov    -0x10(%rbp),%rax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
xorps  %xmm0,%xmm0
movsd  %xmm0,(%rax,%rcx,8)
movl   $0x0,-0x14(%rbp)
mov    -0x14(%rbp),%eax
mov    -0x4(%rbp),%ecx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    1219 <ComputeFdualXb+0x109>
mov    -0x4(%rbp),%eax
sub    $0x1,%eax
sub    -0x14(%rbp),%eax
cvtsi2sd %eax,%xmm0
mov    -0x14(%rbp),%eax
add    $0x1,%eax
cvtsi2sd %eax,%xmm1
mulsd  %xmm1,%xmm0
cvtsi2sdl -0x4(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x20(%rbp),%xmm0
call   1030 <sqrt@plt>
movaps %xmm0,%xmm1
movsd  -0x28(%rbp),%xmm0
mulsd  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movslq -0x14(%rbp),%rcx
movsd  %xmm0,(%rax,%rcx,8)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    119c <ComputeFdualXb+0x8c>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ComputeFdualXb>:
push   %r15
push   %r14
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %rsi,%r15
lea    -0x1(%rdi),%r8d
cmp    $0x1,%edi
jle    113c <ComputeFdualXb+0x2c>
mov    %r8d,%r14d
movsd  (%r15),%xmm0
cmp    $0x4,%r8d
jae    114c <ComputeFdualXb+0x3c>
xor    %ecx,%ecx
jmp    1250 <ComputeFdualXb+0x140>
movslq %r8d,%rax
movq   $0x0,(%r15,%rax,8)
jmp    12fc <ComputeFdualXb+0x1ec>
mov    %r14d,%ecx
and    $0xfffffffc,%ecx
unpcklpd %xmm0,%xmm0
lea    -0x4(%rcx),%rdx
mov    %rdx,%rax
shr    $0x2,%rax
add    $0x1,%rax
test   %rdx,%rdx
je     1308 <ComputeFdualXb+0x1f8>
mov    %rax,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %edx,%edx
movapd %xmm0,%xmm1
nopl   0x0(%rax,%rax,1)
movupd 0x8(%r15,%rdx,8),%xmm2
movupd 0x18(%r15,%rdx,8),%xmm3
movupd 0x28(%r15,%rdx,8),%xmm4
movupd 0x38(%r15,%rdx,8),%xmm0
shufpd $0x1,%xmm2,%xmm1
movapd %xmm2,%xmm5
shufpd $0x1,%xmm3,%xmm5
subpd  %xmm1,%xmm2
movapd %xmm3,%xmm1
subpd  %xmm5,%xmm1
movupd %xmm2,(%r15,%rdx,8)
movupd %xmm1,0x10(%r15,%rdx,8)
shufpd $0x1,%xmm4,%xmm3
movapd %xmm4,%xmm1
shufpd $0x1,%xmm0,%xmm1
subpd  %xmm3,%xmm4
movapd %xmm0,%xmm2
subpd  %xmm1,%xmm2
movupd %xmm4,0x20(%r15,%rdx,8)
movupd %xmm2,0x30(%r15,%rdx,8)
add    $0x8,%rdx
movapd %xmm0,%xmm1
add    $0xfffffffffffffffe,%rsi
jne    1180 <ComputeFdualXb+0x70>
test   $0x1,%al
je     123d <ComputeFdualXb+0x12d>
lea    0x0(,%rdx,8),%rax
or     $0x8,%rax
movupd (%r15,%rax,1),%xmm1
movupd 0x10(%r15,%rax,1),%xmm2
shufpd $0x1,%xmm1,%xmm0
movapd %xmm1,%xmm3
shufpd $0x1,%xmm2,%xmm3
subpd  %xmm0,%xmm1
movapd %xmm2,%xmm0
subpd  %xmm3,%xmm2
movupd %xmm1,(%r15,%rdx,8)
movupd %xmm2,0x10(%r15,%rdx,8)
cmp    %r14,%rcx
je     1275 <ComputeFdualXb+0x165>
unpckhpd %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
movsd  0x8(%r15,%rcx,8),%xmm1
movapd %xmm1,%xmm2
subsd  %xmm0,%xmm2
movsd  %xmm2,(%r15,%rcx,8)
lea    0x1(%rcx),%rax
movapd %xmm1,%xmm0
mov    %rax,%rcx
cmp    %rax,%r14
jne    1250 <ComputeFdualXb+0x140>
movslq %r8d,%rax
movq   $0x0,(%r15,%rax,8)
cmp    $0x2,%edi
jl     12fc <ComputeFdualXb+0x1ec>
xorps  %xmm2,%xmm2
cvtsi2sd %edi,%xmm2
xor    %ebx,%ebx
xorpd  %xmm3,%xmm3
movsd  %xmm2,0x8(%rsp)
jmp    12ce <ComputeFdualXb+0x1be>
nopw   0x0(%rax,%rax,1)
movsd  %xmm1,0x10(%rsp)
call   1030 <sqrt@plt>
movsd  0x10(%rsp),%xmm1
xorpd  %xmm3,%xmm3
movsd  0x8(%rsp),%xmm2
mulsd  %xmm0,%xmm1
movsd  %xmm1,(%r15,%rbx,8)
mov    %r12,%rbx
add    $0xffffffffffffffff,%r14
je     12fc <ComputeFdualXb+0x1ec>
xorps  %xmm1,%xmm1
cvtsi2sd %r14d,%xmm1
lea    0x1(%rbx),%r12
xorps  %xmm0,%xmm0
cvtsi2sd %r12d,%xmm0
mulsd  %xmm1,%xmm0
divsd  %xmm2,%xmm0
movsd  (%r15,%rbx,8),%xmm1
ucomisd %xmm3,%xmm0
jb     12a0 <ComputeFdualXb+0x190>
sqrtsd %xmm0,%xmm0
jmp    12bb <ComputeFdualXb+0x1ab>
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret
xor    %edx,%edx
test   $0x1,%al
jne    11fd <ComputeFdualXb+0xed>
jmp    123d <ComputeFdualXb+0x12d>

LLVM IR (-O0):
define void @ComputeFdualXb(i32 %0, double* %1) {
%3 = alloca i32
%4 = alloca double*
%5 = alloca i32
%6 = alloca double
store i32 %0, i32* %3
store double* %1, double** %4
store i32 0, i32* %5
store double 0.000000e+00, double* %6
store i32 0, i32* %5
br label %7
7: ; preds = %29, %2
%8 = load i32, i32* %5
%9 = load i32, i32* %3
%10 = sub nsw i32 %9, 1
%11 = icmp slt i32 %8, %10
br i1 %11, label %12, label %32
12: ; preds = %7
%13 = load double*, double** %4
%14 = load i32, i32* %5
%15 = add nsw i32 %14, 1
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds double, double* %13, i64 %16
%18 = load double, double* %17
%19 = load double*, double** %4
%20 = load i32, i32* %5
%21 = sext i32 %20 to i64
%22 = getelementptr inbounds double, double* %19, i64 %21
%23 = load double, double* %22
%24 = fsub double %18, %23
%25 = load double*, double** %4
%26 = load i32, i32* %5
%27 = sext i32 %26 to i64
%28 = getelementptr inbounds double, double* %25, i64 %27
store double %24, double* %28
br label %29
29: ; preds = %12
%30 = load i32, i32* %5
%31 = add nsw i32 %30, 1
store i32 %31, i32* %5
br label %7
32: ; preds = %7
%33 = load double*, double** %4
%34 = load i32, i32* %3
%35 = sub nsw i32 %34, 1
%36 = sext i32 %35 to i64
%37 = getelementptr inbounds double, double* %33, i64 %36
store double 0.000000e+00, double* %37
store i32 0, i32* %5
br label %38
38: ; preds = %68, %32
%39 = load i32, i32* %5
%40 = load i32, i32* %3
%41 = sub nsw i32 %40, 1
%42 = icmp slt i32 %39, %41
br i1 %42, label %43, label %71
43: ; preds = %38
%44 = load i32, i32* %3
%45 = sub nsw i32 %44, 1
%46 = load i32, i32* %5
%47 = sub nsw i32 %45, %46
%48 = sitofp i32 %47 to double
%49 = load i32, i32* %5
%50 = add nsw i32 %49, 1
%51 = sitofp i32 %50 to double
%52 = fmul double %48, %51
%53 = load i32, i32* %3
%54 = sitofp i32 %53 to double
%55 = fdiv double %52, %54
store double %55, double* %6
%56 = load double*, double** %4
%57 = load i32, i32* %5
%58 = sext i32 %57 to i64
%59 = getelementptr inbounds double, double* %56, i64 %58
%60 = load double, double* %59
%61 = load double, double* %6
%62 = call double @sqrt(double %61)
%63 = fmul double %60, %62
%64 = load double*, double** %4
%65 = load i32, i32* %5
%66 = sext i32 %65 to i64
%67 = getelementptr inbounds double, double* %64, i64 %66
store double %63, double* %67
br label %68
68: ; preds = %43
%69 = load i32, i32* %5
%70 = add nsw i32 %69, 1
store i32 %70, i32* %5
br label %38
71: ; preds = %38
ret void
}

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