#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 */
float roundf(float);
void smquant(int n, float *y, float *x, float *res) {
  float _res;
  while (n--) {
    _res = res[n];
    y[n] = roundf(x[n] / _res) * _res;
  }
}


x86 assembly (clang, -O0):
<smquant>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,%ecx
add    $0xffffffff,%ecx
mov    %ecx,-0x4(%rbp)
cmp    $0x0,%eax
je     117b <smquant+0x6b>
mov    -0x20(%rbp),%rax
movslq -0x4(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
movss  %xmm0,-0x24(%rbp)
mov    -0x18(%rbp),%rax
movslq -0x4(%rbp),%rcx
movss  (%rax,%rcx,4),%xmm0
divss  -0x24(%rbp),%xmm0
call   1030 <roundf@plt>
mulss  -0x24(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movslq -0x4(%rbp),%rcx
movss  %xmm0,(%rax,%rcx,4)
jmp    1127 <smquant+0x17>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<smquant>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x88,%rsp
test   %edi,%edi
je     132b <smquant+0x21b>
mov    %rcx,%r14
mov    %rdx,%r15
mov    %rsi,%r12
movslq %edi,%rax
add    $0xffffffff,%edi
cmp    $0x3,%edi
jae    1183 <smquant+0x73>
mov    %rax,%rbx
test   $0x1,%bl
je     12c6 <smquant+0x1b6>
lea    -0x1(%rbx),%rbp
movss  -0x4(%r14,%rbx,4),%xmm1
movss  %xmm1,(%rsp)
movss  -0x4(%r15,%rbx,4),%xmm0
divss  %xmm1,%xmm0
call   1030 <roundf@plt>
mulss  (%rsp),%xmm0
movss  %xmm0,-0x4(%r12,%rbx,4)
cmp    $0x1,%ebx
jne    12d0 <smquant+0x1c0>
jmp    132b <smquant+0x21b>
mov    %rdi,%rcx
not    %rcx
add    %rax,%rcx
lea    (%r12,%rcx,4),%rdx
lea    (%r12,%rax,4),%rsi
lea    (%r14,%rcx,4),%rbx
lea    (%r14,%rax,4),%rbp
lea    (%r15,%rcx,4),%r8
lea    (%r15,%rax,4),%rcx
cmp    %rbp,%rdx
setb   %r9b
cmp    %rsi,%rbx
setb   %bl
cmp    %rcx,%rdx
setb   %cl
cmp    %rsi,%r8
setb   %dl
test   %bl,%r9b
jne    133d <smquant+0x22d>
and    %dl,%cl
jne    113d <smquant+0x2d>
add    $0x1,%rdi
mov    %rdi,0x28(%rsp)
mov    %rdi,%rbp
and    $0xfffffffffffffffc,%rbp
mov    %rax,%rcx
sub    %rbp,%rcx
mov    %rcx,0x20(%rsp)
lea    (%r12,%rax,4),%rcx
add    $0xfffffffffffffff0,%rcx
mov    %rcx,0x38(%rsp)
lea    -0x10(%r15,%rax,4),%rcx
mov    %rcx,0x30(%rsp)
lea    (%r14,%rax,4),%rbx
add    $0xfffffffffffffff0,%rbx
mov    %rbp,0x18(%rsp)
neg    %rbp
xor    %r13d,%r13d
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups (%rbx,%r13,4),%xmm0
movaps %xmm0,0x70(%rsp)
mov    0x30(%rsp),%rax
movups (%rax,%r13,4),%xmm1
divps  %xmm0,%xmm1
movaps %xmm1,(%rsp)
movaps %xmm1,%xmm0
shufps $0x1b,%xmm1,%xmm0
movaps %xmm0,0x50(%rsp)
movhlps %xmm0,%xmm0
call   1030 <roundf@plt>
movaps %xmm0,0x60(%rsp)
movaps (%rsp),%xmm0
call   1030 <roundf@plt>
movaps %xmm0,0x40(%rsp)
movaps (%rsp),%xmm0
movhlps %xmm0,%xmm0
call   1030 <roundf@plt>
movaps %xmm0,(%rsp)
movaps 0x50(%rsp),%xmm0
call   1030 <roundf@plt>
movaps (%rsp),%xmm1
unpcklps %xmm0,%xmm1
movaps 0x40(%rsp),%xmm0
unpcklps 0x60(%rsp),%xmm0
movlhps %xmm1,%xmm0
mulps  0x70(%rsp),%xmm0
mov    0x38(%rsp),%rax
movups %xmm0,(%rax,%r13,4)
add    $0xfffffffffffffffc,%r13
cmp    %r13,%rbp
jne    1220 <smquant+0x110>
mov    0x18(%rsp),%rax
cmp    %rax,0x28(%rsp)
mov    0x20(%rsp),%rbx
je     132b <smquant+0x21b>
test   $0x1,%bl
jne    1149 <smquant+0x39>
mov    %rbx,%rbp
cmp    $0x1,%ebx
je     132b <smquant+0x21b>
xchg   %ax,%ax
movss  -0x4(%r14,%rbp,4),%xmm1
movss  %xmm1,(%rsp)
movss  -0x4(%r15,%rbp,4),%xmm0
divss  %xmm1,%xmm0
call   1030 <roundf@plt>
mulss  (%rsp),%xmm0
movss  %xmm0,-0x4(%r12,%rbp,4)
lea    -0x2(%rbp),%rbx
movss  -0x8(%r14,%rbp,4),%xmm1
movss  %xmm1,(%rsp)
movss  -0x8(%r15,%rbp,4),%xmm0
divss  %xmm1,%xmm0
call   1030 <roundf@plt>
mulss  (%rsp),%xmm0
movss  %xmm0,-0x8(%r12,%rbp,4)
mov    %rbx,%rbp
test   %ebx,%ebx
jne    12d0 <smquant+0x1c0>
add    $0x88,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %rax,%rbx
test   $0x1,%bl
jne    1149 <smquant+0x39>
jmp    12c6 <smquant+0x1b6>

LLVM IR (-O0):
define void @smquant(i32 %0, float* %1, float* %2, float* %3) {
%5 = alloca i32
%6 = alloca float*
%7 = alloca float*
%8 = alloca float*
%9 = alloca float
store i32 %0, i32* %5
store float* %1, float** %6
store float* %2, float** %7
store float* %3, float** %8
br label %10
10: ; preds = %14, %4
%11 = load i32, i32* %5
%12 = add nsw i32 %11, -1
store i32 %12, i32* %5
%13 = icmp ne i32 %11, 0
br i1 %13, label %14, label %34
14: ; preds = %10
%15 = load float*, float** %8
%16 = load i32, i32* %5
%17 = sext i32 %16 to i64
%18 = getelementptr inbounds float, float* %15, i64 %17
%19 = load float, float* %18
store float %19, float* %9
%20 = load float*, float** %7
%21 = load i32, i32* %5
%22 = sext i32 %21 to i64
%23 = getelementptr inbounds float, float* %20, i64 %22
%24 = load float, float* %23
%25 = load float, float* %9
%26 = fdiv float %24, %25
%27 = call float @llvm.round.f32(float %26)
%28 = load float, float* %9
%29 = fmul float %27, %28
%30 = load float*, float** %6
%31 = load i32, i32* %5
%32 = sext i32 %31 to i64
%33 = getelementptr inbounds float, float* %30, i64 %32
store float %29, float* %33
br label %10
34: ; preds = %10
ret void
}

LLVM IR (-O2):
define void @smquant(i32 %0, float* nocapture writeonly %1, float* nocapture %2, float* nocapture %3) {
%5 = icmp eq i32 %0, 0
br i1 %5, label %98, label %6
6: ; preds = %4
%7 = sext i32 %0 to i64
%8 = add i32 %0, -1
%9 = zext i32 %8 to i64
%10 = add nuw nsw i64 %9, 1
%11 = icmp ult i32 %8, 3
br i1 %11, label %58, label %12
12: ; preds = %6
%13 = add i32 %0, -1
%14 = zext i32 %13 to i64
%15 = xor i64 %14, -1
%16 = add nsw i64 %15, %7
%17 = getelementptr float, float* %1, i64 %16
%18 = getelementptr float, float* %1, i64 %7
%19 = getelementptr float, float* %3, i64 %16
%20 = getelementptr float, float* %3, i64 %7
%21 = getelementptr float, float* %2, i64 %16
%22 = getelementptr float, float* %2, i64 %7
%23 = icmp ult float* %17, %20
%24 = icmp ult float* %19, %18
%25 = and i1 %23, %24
%26 = icmp ult float* %17, %22
%27 = icmp ult float* %21, %18
%28 = and i1 %26, %27
%29 = or i1 %25, %28
br i1 %29, label %58, label %30
30: ; preds = %12
%31 = and i64 %10, 8589934588
%32 = sub nsw i64 %7, %31
%33 = getelementptr inbounds float, float* %3, i64 -3
%34 = getelementptr inbounds float, float* %2, i64 -3
%35 = getelementptr inbounds float, float* %1, i64 -3
br label %36
36: ; preds = %36, %30
%37 = phi i64 [ 0, %30 ], [ %54, %36 ]
%38 = xor i64 %37, -1
%39 = add i64 %38, %7
%40 = getelementptr inbounds float, float* %33, i64 %39
%41 = bitcast float* %40 to <4 x float>*
%42 = load <4 x float>, <4 x float>* %41
%43 = shufflevector <4 x float> %42, <4 x float> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%44 = getelementptr inbounds float, float* %34, i64 %39
%45 = bitcast float* %44 to <4 x float>*
%46 = load <4 x float>, <4 x float>* %45
%47 = fdiv <4 x float> %46, %42
%48 = shufflevector <4 x float> %47, <4 x float> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%49 = call <4 x float> @llvm.round.v4f32(<4 x float> %48)
%50 = fmul <4 x float> %43, %49
%51 = shufflevector <4 x float> %50, <4 x float> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%52 = getelementptr inbounds float, float* %35, i64 %39
%53 = bitcast float* %52 to <4 x float>*
store <4 x float> %51, <4 x float>* %53
%54 = add nuw i64 %37, 4
%55 = icmp eq i64 %54, %31
br i1 %55, label %56, label %36
56: ; preds = %36
%57 = icmp eq i64 %10, %31
br i1 %57, label %98, label %58
58: ; preds = %12, %6, %56
%59 = phi i64 [ %7, %12 ], [ %7, %6 ], [ %32, %56 ]
%60 = trunc i64 %59 to i32
%61 = and i32 %60, 1
%62 = icmp eq i32 %61, 0
br i1 %62, label %73, label %63
63: ; preds = %58
%64 = add nsw i64 %59, -1
%65 = getelementptr inbounds float, float* %3, i64 %64
%66 = load float, float* %65
%67 = getelementptr inbounds float, float* %2, i64 %64
%68 = load float, float* %67
%69 = fdiv float %68, %66
%70 = tail call float @llvm.round.f32(float %69)
%71 = fmul float %66, %70
%72 = getelementptr inbounds float, float* %1, i64 %64
store float %71, float* %72
br label %73
73: ; preds = %63, %58
%74 = phi i64 [ %59, %58 ], [ %64, %63 ]
%75 = icmp eq i32 %60, 1
br i1 %75, label %98, label %76
76: ; preds = %73, %76
%77 = phi i64 [ %87, %76 ], [ %74, %73 ]
%78 = add nsw i64 %77, -1
%79 = getelementptr inbounds float, float* %3, i64 %78
%80 = load float, float* %79
%81 = getelementptr inbounds float, float* %2, i64 %78
%82 = load float, float* %81
%83 = fdiv float %82, %80
%84 = tail call float @llvm.round.f32(float %83)
%85 = fmul float %80, %84
%86 = getelementptr inbounds float, float* %1, i64 %78
store float %85, float* %86
%87 = add nsw i64 %77, -2
%88 = getelementptr inbounds float, float* %3, i64 %87
%89 = load float, float* %88
%90 = getelementptr inbounds float, float* %2, i64 %87
%91 = load float, float* %90
%92 = fdiv float %91, %89
%93 = tail call float @llvm.round.f32(float %92)
%94 = fmul float %89, %93
%95 = getelementptr inbounds float, float* %1, i64 %87
store float %94, float* %95
%96 = trunc i64 %87 to i32
%97 = icmp eq i32 %96, 0
br i1 %97, label %98, label %76
98: ; preds = %73, %76, %56, %4
ret void
}