void normalize_feature_weights(float *feature_weights, int num_features) {
  int i;
  float total_weight = 0;
  float norm_factor;
  for (i = 0; i < num_features; i++) {
    if (feature_weights[i] < 0.0)
      total_weight += -feature_weights[i];
    else
      total_weight += feature_weights[i];
  }
  norm_factor = ((float)num_features) / total_weight;
  for (i = 0; i < num_features; i++) {
    feature_weights[i] = norm_factor * feature_weights[i];
  }
  return;
}


x86 assembly (clang, -O0):
<normalize_feature_weights>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
xorps  %xmm0,%xmm0
movss  %xmm0,-0x14(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1197 <normalize_feature_weights+0x97>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
cvtss2sd %xmm0,%xmm1
xorps  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
jbe    116d <normalize_feature_weights+0x6d>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movd   %xmm0,%eax
xor    $0x80000000,%eax
movd   %eax,%xmm0
addss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x14(%rbp)
jmp    1184 <normalize_feature_weights+0x84>
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
addss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x14(%rbp)
jmp    1189 <normalize_feature_weights+0x89>
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    111a <normalize_feature_weights+0x1a>
cvtsi2ssl -0xc(%rbp),%xmm0
divss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x18(%rbp)
movl   $0x0,-0x10(%rbp)
mov    -0x10(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    11e6 <normalize_feature_weights+0xe6>
movss  -0x18(%rbp),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
mulss  (%rax,%rcx,4),%xmm0
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x10(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x10(%rbp)
jmp    11ad <normalize_feature_weights+0xad>
pop    %rbp
ret

x86 assembly (clang, -O2):
<normalize_feature_weights>:
test   %esi,%esi
jle    12e7 <normalize_feature_weights+0x1e7>
mov    %esi,%r8d
lea    -0x1(%r8),%rax
mov    %r8d,%ecx
and    $0x3,%ecx
cmp    $0x3,%rax
jae    1125 <normalize_feature_weights+0x25>
xorps  %xmm1,%xmm1
xor    %edx,%edx
jmp    11d0 <normalize_feature_weights+0xd0>
mov    %r8d,%eax
and    $0xfffffffc,%eax
xorps  %xmm0,%xmm0
xor    %edx,%edx
movaps 0xec9(%rip),%xmm2
xorps  %xmm1,%xmm1
nopw   0x0(%rax,%rax,1)
movss  (%rdi,%rdx,4),%xmm3
movss  0x4(%rdi,%rdx,4),%xmm4
movaps %xmm3,%xmm5
xorps  %xmm2,%xmm5
movaps %xmm3,%xmm6
cmpltss %xmm0,%xmm6
andps  %xmm6,%xmm5
andnps %xmm3,%xmm6
orps   %xmm5,%xmm6
addss  %xmm1,%xmm6
movaps %xmm4,%xmm1
xorps  %xmm2,%xmm1
movaps %xmm4,%xmm3
cmpltss %xmm0,%xmm3
andps  %xmm3,%xmm1
andnps %xmm4,%xmm3
orps   %xmm1,%xmm3
addss  %xmm6,%xmm3
movss  0x8(%rdi,%rdx,4),%xmm1
movaps %xmm1,%xmm4
xorps  %xmm2,%xmm4
movaps %xmm1,%xmm5
cmpltss %xmm0,%xmm5
andps  %xmm5,%xmm4
andnps %xmm1,%xmm5
orps   %xmm4,%xmm5
addss  %xmm3,%xmm5
movss  0xc(%rdi,%rdx,4),%xmm3
movaps %xmm3,%xmm4
xorps  %xmm2,%xmm4
movaps %xmm3,%xmm1
cmpltss %xmm0,%xmm1
andps  %xmm1,%xmm4
andnps %xmm3,%xmm1
orps   %xmm4,%xmm1
addss  %xmm5,%xmm1
add    $0x4,%rdx
cmp    %rdx,%rax
jne    1140 <normalize_feature_weights+0x40>
test   %rcx,%rcx
je     1219 <normalize_feature_weights+0x119>
lea    (%rdi,%rdx,4),%rax
xor    %edx,%edx
movaps 0xe1e(%rip),%xmm0
xorps  %xmm2,%xmm2
cs nopw 0x0(%rax,%rax,1)
nop
movss  (%rax,%rdx,4),%xmm3
movaps %xmm3,%xmm4
xorps  %xmm0,%xmm4
movaps %xmm3,%xmm5
cmpltss %xmm2,%xmm5
andps  %xmm5,%xmm4
andnps %xmm3,%xmm5
orps   %xmm4,%xmm5
addss  %xmm5,%xmm1
add    $0x1,%rdx
cmp    %rdx,%rcx
jne    11f0 <normalize_feature_weights+0xf0>
test   %esi,%esi
jle    12e7 <normalize_feature_weights+0x1e7>
xorps  %xmm0,%xmm0
cvtsi2ss %esi,%xmm0
divss  %xmm1,%xmm0
cmp    $0x8,%esi
jae    1238 <normalize_feature_weights+0x138>
xor    %ecx,%ecx
jmp    12d0 <normalize_feature_weights+0x1d0>
mov    %r8d,%ecx
and    $0xfffffff8,%ecx
movaps %xmm0,%xmm1
shufps $0x0,%xmm0,%xmm1
lea    -0x8(%rcx),%rax
mov    %rax,%rdx
shr    $0x3,%rdx
add    $0x1,%rdx
test   %rax,%rax
je     12e8 <normalize_feature_weights+0x1e8>
mov    %rdx,%rsi
and    $0xfffffffffffffffe,%rsi
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
movups (%rdi,%rax,4),%xmm2
movups 0x10(%rdi,%rax,4),%xmm3
movups 0x20(%rdi,%rax,4),%xmm4
movups 0x30(%rdi,%rax,4),%xmm5
mulps  %xmm1,%xmm2
mulps  %xmm1,%xmm3
movups %xmm2,(%rdi,%rax,4)
movups %xmm3,0x10(%rdi,%rax,4)
mulps  %xmm1,%xmm4
mulps  %xmm1,%xmm5
movups %xmm4,0x20(%rdi,%rax,4)
movups %xmm5,0x30(%rdi,%rax,4)
add    $0x10,%rax
add    $0xfffffffffffffffe,%rsi
jne    1270 <normalize_feature_weights+0x170>
test   $0x1,%dl
je     12c9 <normalize_feature_weights+0x1c9>
movups (%rdi,%rax,4),%xmm2
movups 0x10(%rdi,%rax,4),%xmm3
mulps  %xmm1,%xmm2
mulps  %xmm1,%xmm3
movups %xmm2,(%rdi,%rax,4)
movups %xmm3,0x10(%rdi,%rax,4)
cmp    %r8,%rcx
je     12e7 <normalize_feature_weights+0x1e7>
xchg   %ax,%ax
movss  (%rdi,%rcx,4),%xmm1
mulss  %xmm0,%xmm1
movss  %xmm1,(%rdi,%rcx,4)
add    $0x1,%rcx
cmp    %rcx,%r8
jne    12d0 <normalize_feature_weights+0x1d0>
ret
xor    %eax,%eax
test   $0x1,%dl
jne    12b1 <normalize_feature_weights+0x1b1>
jmp    12c9 <normalize_feature_weights+0x1c9>

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

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