void kd_tree_generate_training_patterns_indices(void *XI, float *X, int n,
                                                int dim) {
  int i;
  int j;
  for (i = 0; i < n; i++) {
    float *pattern = (float *)(XI + i * (dim * sizeof(float) + sizeof(int)));
    for (j = 0; j < dim; j++) {
      pattern[j] = X[i * dim + j];
    }
    int *index = (int *)(XI + i * (dim * sizeof(float) + sizeof(int)) +
                         dim * sizeof(float));
    *index = i;
  }
}


x86 assembly (clang, -O0):
<kd_tree_generate_training_patterns_indices>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    %ecx,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11c9 <kd_tree_generate_training_patterns_indices+0xc9>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movslq -0x18(%rbp),%rdx
shl    $0x2,%rdx
add    $0x4,%rdx
imul   %rdx,%rcx
add    %rcx,%rax
mov    %rax,-0x28(%rbp)
movl   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%eax
cmp    -0x18(%rbp),%eax
jge    1188 <kd_tree_generate_training_patterns_indices+0x88>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
imul   -0x18(%rbp),%ecx
add    -0x20(%rbp),%ecx
movslq %ecx,%rcx
movss  (%rax,%rcx,4),%xmm0
mov    -0x28(%rbp),%rax
movslq -0x20(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
mov    -0x20(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x20(%rbp)
jmp    114b <kd_tree_generate_training_patterns_indices+0x4b>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movslq -0x18(%rbp),%rdx
shl    $0x2,%rdx
add    $0x4,%rdx
imul   %rdx,%rcx
add    %rcx,%rax
movslq -0x18(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x30(%rbp)
mov    -0x1c(%rbp),%ecx
mov    -0x30(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1119 <kd_tree_generate_training_patterns_indices+0x19>
pop    %rbp
ret

x86 assembly (clang, -O2):
<kd_tree_generate_training_patterns_indices>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %ecx,-0x64(%rsp)
mov    %rsi,-0x40(%rsp)
mov    %rdi,-0x58(%rsp)
test   %edx,%edx
jle    13b4 <kd_tree_generate_training_patterns_indices+0x2b4>
movslq -0x64(%rsp),%rax
lea    0x0(,%rax,4),%r13
lea    0x4(,%rax,4),%rcx
mov    %edx,%edi
mov    %rax,-0x8(%rsp)
mov    %eax,%r9d
lea    0x0(,%r9,4),%rax
mov    %rax,-0x10(%rsp)
mov    %r9d,%eax
and    $0xfffffff8,%eax
mov    %rax,-0x18(%rsp)
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x20(%rsp)
shr    $0x3,%rax
add    $0x1,%rax
mov    %eax,%r12d
and    $0x3,%r12d
and    $0xfffffffffffffffc,%rax
mov    %rax,-0x30(%rsp)
mov    %r9d,%ebx
and    $0x3,%ebx
mov    -0x40(%rsp),%rsi
lea    0x70(%rsi),%rbp
mov    -0x58(%rsp),%r8
lea    0x70(%r8),%r14
lea    0x10(%rsi),%r11
mov    %r12,-0x28(%rsp)
shl    $0x5,%r12
xor    %r15d,%r15d
mov    %rbx,-0x60(%rsp)
mov    %rcx,-0x48(%rsp)
mov    %rdi,-0x50(%rsp)
jmp    11e5 <kd_tree_generate_training_patterns_indices+0xe5>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    -0x38(%rsp),%rax
mov    %r15d,(%rax,%r13,1)
add    $0x1,%r15
add    %r13,%rbp
add    %rcx,%r14
add    %rcx,%r8
add    %r13,%r11
add    %r13,%rsi
cmp    %rdi,%r15
je     13b4 <kd_tree_generate_training_patterns_indices+0x2b4>
mov    %rcx,%rax
imul   %r15,%rax
mov    -0x58(%rsp),%rdx
add    %rax,%rdx
mov    %rdx,-0x38(%rsp)
cmpl   $0x0,-0x64(%rsp)
jle    11c0 <kd_tree_generate_training_patterns_indices+0xc0>
cmpl   $0x8,-0x64(%rsp)
jae    1210 <kd_tree_generate_training_patterns_indices+0x110>
xor    %r10d,%r10d
jmp    1330 <kd_tree_generate_training_patterns_indices+0x230>
nop
mov    -0x58(%rsp),%rdi
mov    %r15,%rdx
imul   -0x8(%rsp),%rdx
lea    (%rdx,%r9,1),%rbx
mov    -0x40(%rsp),%rcx
lea    (%rcx,%rbx,4),%rbx
cmp    %rbx,-0x38(%rsp)
jae    125a <kd_tree_generate_training_patterns_indices+0x15a>
add    -0x10(%rsp),%rax
add    %rdi,%rax
lea    (%rcx,%rdx,4),%rdx
cmp    %rdx,%rax
jbe    125a <kd_tree_generate_training_patterns_indices+0x15a>
xor    %r10d,%r10d
mov    -0x48(%rsp),%rcx
mov    -0x50(%rsp),%rdi
mov    -0x60(%rsp),%rbx
jmp    1330 <kd_tree_generate_training_patterns_indices+0x230>
cmpq   $0x18,-0x20(%rsp)
jae    1266 <kd_tree_generate_training_patterns_indices+0x166>
xor    %ebx,%ebx
jmp    12d1 <kd_tree_generate_training_patterns_indices+0x1d1>
mov    -0x30(%rsp),%rax
xor    %ebx,%ebx
nopl   (%rax)
movups -0x70(%rbp,%rbx,4),%xmm0
movups -0x60(%rbp,%rbx,4),%xmm1
movups %xmm0,-0x70(%r14,%rbx,4)
movups %xmm1,-0x60(%r14,%rbx,4)
movups -0x50(%rbp,%rbx,4),%xmm0
movups -0x40(%rbp,%rbx,4),%xmm1
movups %xmm0,-0x50(%r14,%rbx,4)
movups %xmm1,-0x40(%r14,%rbx,4)
movups -0x30(%rbp,%rbx,4),%xmm0
movups -0x20(%rbp,%rbx,4),%xmm1
movups %xmm0,-0x30(%r14,%rbx,4)
movups %xmm1,-0x20(%r14,%rbx,4)
movups -0x10(%rbp,%rbx,4),%xmm0
movups 0x0(%rbp,%rbx,4),%xmm1
movups %xmm0,-0x10(%r14,%rbx,4)
movups %xmm1,(%r14,%rbx,4)
add    $0x20,%rbx
add    $0xfffffffffffffffc,%rax
jne    1270 <kd_tree_generate_training_patterns_indices+0x170>
cmpq   $0x0,-0x28(%rsp)
mov    -0x48(%rsp),%rcx
je     130b <kd_tree_generate_training_patterns_indices+0x20b>
lea    (%r8,%rbx,4),%rax
lea    (%r11,%rbx,4),%rbx
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
movups -0x10(%rbx,%rdx,1),%xmm0
movups (%rbx,%rdx,1),%xmm1
movups %xmm0,(%rax,%rdx,1)
movups %xmm1,0x10(%rax,%rdx,1)
add    $0x20,%rdx
cmp    %rdx,%r12
jne    12f0 <kd_tree_generate_training_patterns_indices+0x1f0>
mov    -0x18(%rsp),%rax
mov    %rax,%r10
cmp    %r9,%rax
mov    -0x50(%rsp),%rdi
mov    -0x60(%rsp),%rbx
je     11c0 <kd_tree_generate_training_patterns_indices+0xc0>
cs nopw 0x0(%rax,%rax,1)
mov    %r10,%rax
not    %rax
add    %r9,%rax
test   %rbx,%rbx
je     1356 <kd_tree_generate_training_patterns_indices+0x256>
xchg   %ax,%ax
movss  (%rsi,%r10,4),%xmm0
movss  %xmm0,(%r8,%r10,4)
add    $0x1,%r10
add    $0xffffffffffffffff,%rbx
jne    1340 <kd_tree_generate_training_patterns_indices+0x240>
cmp    $0x3,%rax
mov    -0x60(%rsp),%rbx
jb     11c0 <kd_tree_generate_training_patterns_indices+0xc0>
cs nopw 0x0(%rax,%rax,1)
nop
movss  (%rsi,%r10,4),%xmm0
movss  %xmm0,(%r8,%r10,4)
movss  0x4(%rsi,%r10,4),%xmm0
movss  %xmm0,0x4(%r8,%r10,4)
movss  0x8(%rsi,%r10,4),%xmm0
movss  %xmm0,0x8(%r8,%r10,4)
movss  0xc(%rsi,%r10,4),%xmm0
movss  %xmm0,0xc(%r8,%r10,4)
add    $0x4,%r10
cmp    %r10,%r9
jne    1370 <kd_tree_generate_training_patterns_indices+0x270>
jmp    11c0 <kd_tree_generate_training_patterns_indices+0xc0>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define void @kd_tree_generate_training_patterns_indices(i8* nocapture writeonly %0, float* nocapture %1, i32 %2, i32 %3) {
%5 = icmp sgt i32 %2, 0
br i1 %5, label %6, label %168
6: ; preds = %4
%7 = sext i32 %3 to i64
%8 = shl nsw i64 %7, 2
%9 = add nsw i64 %8, 4
%10 = icmp sgt i32 %3, 0
%11 = zext i32 %2 to i64
%12 = zext i32 %3 to i64
%13 = shl nuw nsw i64 %12, 2
%14 = and i64 %12, 4294967288
%15 = add nsw i64 %14, -8
%16 = lshr exact i64 %15, 3
%17 = add nuw nsw i64 %16, 1
%18 = icmp ult i32 %3, 8
%19 = and i64 %12, 4294967288
%20 = and i64 %17, 3
%21 = icmp ult i64 %15, 24
%22 = and i64 %17, 4611686018427387900
%23 = icmp eq i64 %20, 0
%24 = icmp eq i64 %19, %12
%25 = and i64 %12, 3
%26 = icmp eq i64 %25, 0
br label %27
27: ; preds = %6, %162
%28 = phi i64 [ 0, %6 ], [ %166, %162 ]
%29 = mul i64 %9, %28
%30 = getelementptr i8, i8* %0, i64 %29
%31 = add i64 %13, %29
%32 = getelementptr i8, i8* %0, i64 %31
%33 = mul i64 %28, %7
%34 = getelementptr float, float* %1, i64 %33
%35 = bitcast float* %34 to i8*
%36 = add i64 %33, %12
%37 = getelementptr float, float* %1, i64 %36
%38 = bitcast float* %37 to i8*
%39 = mul i64 %9, %28
%40 = getelementptr i8, i8* %0, i64 %39
%41 = bitcast i8* %40 to float*
br i1 %10, label %42, label %162
42: ; preds = %27
%43 = mul nsw i64 %28, %7
br i1 %18, label %122, label %44
44: ; preds = %42
%45 = icmp ult i8* %30, %38
%46 = icmp ugt i8* %32, %35
%47 = and i1 %45, %46
br i1 %47, label %122, label %48
48: ; preds = %44
br i1 %21, label %102, label %49
49: ; preds = %48, %49
%50 = phi i64 [ %99, %49 ], [ 0, %48 ]
%51 = phi i64 [ %100, %49 ], [ 0, %48 ]
%52 = add nsw i64 %50, %43
%53 = getelementptr inbounds float, float* %1, i64 %52
%54 = bitcast float* %53 to <4 x float>*
%55 = load <4 x float>, <4 x float>* %54
%56 = getelementptr inbounds float, float* %53, i64 4
%57 = bitcast float* %56 to <4 x float>*
%58 = load <4 x float>, <4 x float>* %57
%59 = getelementptr inbounds float, float* %41, i64 %50
%60 = bitcast float* %59 to <4 x float>*
store <4 x float> %55, <4 x float>* %60
%61 = getelementptr inbounds float, float* %59, i64 4
%62 = bitcast float* %61 to <4 x float>*
store <4 x float> %58, <4 x float>* %62
%63 = or i64 %50, 8
%64 = add nsw i64 %63, %43
%65 = getelementptr inbounds float, float* %1, i64 %64
%66 = bitcast float* %65 to <4 x float>*
%67 = load <4 x float>, <4 x float>* %66
%68 = getelementptr inbounds float, float* %65, i64 4
%69 = bitcast float* %68 to <4 x float>*
%70 = load <4 x float>, <4 x float>* %69
%71 = getelementptr inbounds float, float* %41, i64 %63
%72 = bitcast float* %71 to <4 x float>*
store <4 x float> %67, <4 x float>* %72
%73 = getelementptr inbounds float, float* %71, i64 4
%74 = bitcast float* %73 to <4 x float>*
store <4 x float> %70, <4 x float>* %74
%75 = or i64 %50, 16
%76 = add nsw i64 %75, %43
%77 = getelementptr inbounds float, float* %1, i64 %76
%78 = bitcast float* %77 to <4 x float>*
%79 = load <4 x float>, <4 x float>* %78
%80 = getelementptr inbounds float, float* %77, i64 4
%81 = bitcast float* %80 to <4 x float>*
%82 = load <4 x float>, <4 x float>* %81
%83 = getelementptr inbounds float, float* %41, i64 %75
%84 = bitcast float* %83 to <4 x float>*
store <4 x float> %79, <4 x float>* %84
%85 = getelementptr inbounds float, float* %83, i64 4
%86 = bitcast float* %85 to <4 x float>*
store <4 x float> %82, <4 x float>* %86
%87 = or i64 %50, 24
%88 = add nsw i64 %87, %43
%89 = getelementptr inbounds float, float* %1, i64 %88
%90 = bitcast float* %89 to <4 x float>*
%91 = load <4 x float>, <4 x float>* %90
%92 = getelementptr inbounds float, float* %89, i64 4
%93 = bitcast float* %92 to <4 x float>*
%94 = load <4 x float>, <4 x float>* %93
%95 = getelementptr inbounds float, float* %41, i64 %87
%96 = bitcast float* %95 to <4 x float>*
store <4 x float> %91, <4 x float>* %96
%97 = getelementptr inbounds float, float* %95, i64 4
%98 = bitcast float* %97 to <4 x float>*
store <4 x float> %94, <4 x float>* %98
%99 = add nuw i64 %50, 32
%100 = add i64 %51, 4
%101 = icmp eq i64 %100, %22
br i1 %101, label %102, label %49
102: ; preds = %49, %48
%103 = phi i64 [ 0, %48 ], [ %99, %49 ]
br i1 %23, label %121, label %104
104: ; preds = %102, %104
%105 = phi i64 [ %118, %104 ], [ %103, %102 ]
%106 = phi i64 [ %119, %104 ], [ 0, %102 ]
%107 = add nsw i64 %105, %43
%108 = getelementptr inbounds float, float* %1, i64 %107
%109 = bitcast float* %108 to <4 x float>*
%110 = load <4 x float>, <4 x float>* %109
%111 = getelementptr inbounds float, float* %108, i64 4
%112 = bitcast float* %111 to <4 x float>*
%113 = load <4 x float>, <4 x float>* %112
%114 = getelementptr inbounds float, float* %41, i64 %105
%115 = bitcast float* %114 to <4 x float>*
store <4 x float> %110, <4 x float>* %115
%116 = getelementptr inbounds float, float* %114, i64 4
%117 = bitcast float* %116 to <4 x float>*
store <4 x float> %113, <4 x float>* %117
%118 = add nuw i64 %105, 8
%119 = add i64 %106, 1
%120 = icmp eq i64 %119, %20
br i1 %120, label %121, label %104
121: ; preds = %104, %102
br i1 %24, label %162, label %122
122: ; preds = %44, %42, %121
%123 = phi i64 [ 0, %44 ], [ 0, %42 ], [ %19, %121 ]
%124 = xor i64 %123, -1
%125 = add nsw i64 %124, %12
br i1 %26, label %136, label %126
126: ; preds = %122, %126
%127 = phi i64 [ %133, %126 ], [ %123, %122 ]
%128 = phi i64 [ %134, %126 ], [ 0, %122 ]
%129 = add nsw i64 %127, %43
%130 = getelementptr inbounds float, float* %1, i64 %129
%131 = load float, float* %130
%132 = getelementptr inbounds float, float* %41, i64 %127
store float %131, float* %132
%133 = add nuw nsw i64 %127, 1
%134 = add i64 %128, 1
%135 = icmp eq i64 %134, %25
br i1 %135, label %136, label %126
136: ; preds = %126, %122
%137 = phi i64 [ %123, %122 ], [ %133, %126 ]
%138 = icmp ult i64 %125, 3
br i1 %138, label %162, label %139
139: ; preds = %136, %139
%140 = phi i64 [ %160, %139 ], [ %137, %136 ]
%141 = add nsw i64 %140, %43
%142 = getelementptr inbounds float, float* %1, i64 %141
%143 = load float, float* %142
%144 = getelementptr inbounds float, float* %41, i64 %140
store float %143, float* %144
%145 = add nuw nsw i64 %140, 1
%146 = add nsw i64 %145, %43
%147 = getelementptr inbounds float, float* %1, i64 %146
%148 = load float, float* %147
%149 = getelementptr inbounds float, float* %41, i64 %145
store float %148, float* %149
%150 = add nuw nsw i64 %140, 2
%151 = add nsw i64 %150, %43
%152 = getelementptr inbounds float, float* %1, i64 %151
%153 = load float, float* %152
%154 = getelementptr inbounds float, float* %41, i64 %150
store float %153, float* %154
%155 = add nuw nsw i64 %140, 3
%156 = add nsw i64 %155, %43
%157 = getelementptr inbounds float, float* %1, i64 %156
%158 = load float, float* %157
%159 = getelementptr inbounds float, float* %41, i64 %155
store float %158, float* %159
%160 = add nuw nsw i64 %140, 4
%161 = icmp eq i64 %160, %12
br i1 %161, label %162, label %139
162: ; preds = %136, %139, %121, %27
%163 = getelementptr i8, i8* %40, i64 %8
%164 = bitcast i8* %163 to i32*
%165 = trunc i64 %28 to i32
store i32 %165, i32* %164
%166 = add nuw nsw i64 %28, 1
%167 = icmp eq i64 %166, %11
br i1 %167, label %168, label %27
168: ; preds = %162, %4
ret void
}