#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);
float *normalize(float *x, size_t ndim) {
  double s = 0;
  for (size_t j = 0; j < ndim; j++)
    s += x[j] * x[j];
  s = sqrt(s);
  for (size_t j = 0; j < ndim; j++)
    x[j] /= s;
  return x;
}


x86 assembly (clang, -O0):
<normalize>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    1177 <normalize+0x67>
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
mov    -0x20(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1130 <normalize+0x20>
movsd  -0x18(%rbp),%xmm0
call   1030 <sqrt@plt>
movsd  %xmm0,-0x18(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x10(%rbp),%rax
jae    11d0 <normalize+0xc0>
movsd  -0x18(%rbp),%xmm1
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm0
divsd  %xmm1,%xmm0
cvtsd2ss %xmm0,%xmm0
movss  %xmm0,(%rax,%rcx,4)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    118e <normalize+0x7e>
mov    -0x8(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<normalize>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%rbx
test   %rsi,%rsi
je     12cf <normalize+0x1bf>
mov    %rsi,%r14
lea    -0x1(%rsi),%rcx
mov    %r14d,%eax
and    $0x3,%eax
cmp    $0x3,%rcx
jae    113b <normalize+0x2b>
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
jmp    11a3 <normalize+0x93>
mov    %r14,%rdx
and    $0xfffffffffffffffc,%rdx
xorpd  %xmm0,%xmm0
xor    %ecx,%ecx
nopl   0x0(%rax,%rax,1)
movss  (%rbx,%rcx,4),%xmm1
movss  0x4(%rbx,%rcx,4),%xmm2
mulss  %xmm1,%xmm1
cvtss2sd %xmm1,%xmm1
addsd  %xmm0,%xmm1
mulss  %xmm2,%xmm2
xorps  %xmm0,%xmm0
cvtss2sd %xmm2,%xmm0
addsd  %xmm1,%xmm0
movss  0x8(%rbx,%rcx,4),%xmm1
mulss  %xmm1,%xmm1
cvtss2sd %xmm1,%xmm1
addsd  %xmm0,%xmm1
movss  0xc(%rbx,%rcx,4),%xmm0
mulss  %xmm0,%xmm0
cvtss2sd %xmm0,%xmm0
addsd  %xmm1,%xmm0
add    $0x4,%rcx
cmp    %rcx,%rdx
jne    1150 <normalize+0x40>
test   %rax,%rax
je     11ca <normalize+0xba>
lea    (%rbx,%rcx,4),%rcx
xor    %edx,%edx
xchg   %ax,%ax
movss  (%rcx,%rdx,4),%xmm1
mulss  %xmm1,%xmm1
cvtss2sd %xmm1,%xmm1
addsd  %xmm1,%xmm0
add    $0x1,%rdx
cmp    %rdx,%rax
jne    11b0 <normalize+0xa0>
xorpd  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     11e2 <normalize+0xd2>
sqrtsd %xmm0,%xmm0
test   %r14,%r14
jne    11f0 <normalize+0xe0>
jmp    12cf <normalize+0x1bf>
call   1030 <sqrt@plt>
test   %r14,%r14
je     12cf <normalize+0x1bf>
cmp    $0x4,%r14
jae    11fd <normalize+0xed>
xor    %eax,%eax
jmp    12b0 <normalize+0x1a0>
mov    %r14,%rax
and    $0xfffffffffffffffc,%rax
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
lea    -0x4(%rax),%rcx
mov    %rcx,%rdx
shr    $0x2,%rdx
add    $0x1,%rdx
test   %rcx,%rcx
je     12da <normalize+0x1ca>
mov    %rdx,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %ecx,%ecx
nopl   (%rax)
cvtps2pd 0x8(%rbx,%rcx,4),%xmm2
cvtps2pd (%rbx,%rcx,4),%xmm3
divpd  %xmm1,%xmm3
divpd  %xmm1,%xmm2
cvtpd2ps %xmm2,%xmm2
cvtpd2ps %xmm3,%xmm3
unpcklpd %xmm2,%xmm3
movupd %xmm3,(%rbx,%rcx,4)
cvtps2pd 0x18(%rbx,%rcx,4),%xmm2
cvtps2pd 0x10(%rbx,%rcx,4),%xmm3
divpd  %xmm1,%xmm3
divpd  %xmm1,%xmm2
cvtpd2ps %xmm2,%xmm2
cvtpd2ps %xmm3,%xmm3
unpcklpd %xmm2,%xmm3
movupd %xmm3,0x10(%rbx,%rcx,4)
add    $0x8,%rcx
add    $0xfffffffffffffffe,%rsi
jne    1230 <normalize+0x120>
test   $0x1,%dl
je     12a7 <normalize+0x197>
cvtps2pd 0x8(%rbx,%rcx,4),%xmm2
cvtps2pd (%rbx,%rcx,4),%xmm3
divpd  %xmm1,%xmm3
divpd  %xmm1,%xmm2
cvtpd2ps %xmm2,%xmm1
cvtpd2ps %xmm3,%xmm2
unpcklpd %xmm1,%xmm2
movupd %xmm2,(%rbx,%rcx,4)
cmp    %r14,%rax
je     12cf <normalize+0x1bf>
nopl   0x0(%rax)
movss  (%rbx,%rax,4),%xmm1
cvtss2sd %xmm1,%xmm1
divsd  %xmm0,%xmm1
cvtsd2ss %xmm1,%xmm1
movss  %xmm1,(%rbx,%rax,4)
add    $0x1,%rax
cmp    %rax,%r14
jne    12b0 <normalize+0x1a0>
mov    %rbx,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret
xor    %ecx,%ecx
test   $0x1,%dl
jne    1285 <normalize+0x175>
jmp    12a7 <normalize+0x197>

LLVM IR (-O0):
define float* @normalize(float* %0, i64 %1) {
%3 = alloca float*
%4 = alloca i64
%5 = alloca double
%6 = alloca i64
%7 = alloca i64
store float* %0, float** %3
store i64 %1, i64* %4
store double 0.000000e+00, double* %5
store i64 0, i64* %6
br label %8
8: ; preds = %25, %2
%9 = load i64, i64* %6
%10 = load i64, i64* %4
%11 = icmp ult i64 %9, %10
br i1 %11, label %12, label %28
12: ; preds = %8
%13 = load float*, float** %3
%14 = load i64, i64* %6
%15 = getelementptr inbounds float, float* %13, i64 %14
%16 = load float, float* %15
%17 = load float*, float** %3
%18 = load i64, i64* %6
%19 = getelementptr inbounds float, float* %17, i64 %18
%20 = load float, float* %19
%21 = fmul float %16, %20
%22 = fpext float %21 to double
%23 = load double, double* %5
%24 = fadd double %23, %22
store double %24, double* %5
br label %25
25: ; preds = %12
%26 = load i64, i64* %6
%27 = add i64 %26, 1
store i64 %27, i64* %6
br label %8
28: ; preds = %8
%29 = load double, double* %5
%30 = call double @sqrt(double %29)
store double %30, double* %5
store i64 0, i64* %7
br label %31
31: ; preds = %44, %28
%32 = load i64, i64* %7
%33 = load i64, i64* %4
%34 = icmp ult i64 %32, %33
br i1 %34, label %35, label %47
35: ; preds = %31
%36 = load double, double* %5
%37 = load float*, float** %3
%38 = load i64, i64* %7
%39 = getelementptr inbounds float, float* %37, i64 %38
%40 = load float, float* %39
%41 = fpext float %40 to double
%42 = fdiv double %41, %36
%43 = fptrunc double %42 to float
store float %43, float* %39
br label %44
44: ; preds = %35
%45 = load i64, i64* %7
%46 = add i64 %45, 1
store i64 %46, i64* %7
br label %31
47: ; preds = %31
%48 = load float*, float** %3
ret float* %48
}

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