void threshold_vector(float *vec, int n, double T) {
  float *end = vec + n;
  for (; vec < end; vec++)
    *vec = *vec > T;
}


x86 assembly (clang, -O0):
<threshold_vector>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movsd  %xmm0,-0x18(%rbp)
mov    -0x8(%rbp),%rax
movslq -0xc(%rbp),%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x20(%rbp)
mov    -0x8(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    1167 <threshold_vector+0x67>
mov    -0x8(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
seta   %al
and    $0x1,%al
movzbl %al,%eax
cvtsi2ss %eax,%xmm0
mov    -0x8(%rbp),%rax
movss  %xmm0,(%rax)
mov    -0x8(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x8(%rbp)
jmp    1123 <threshold_vector+0x23>
pop    %rbp
ret

x86 assembly (clang, -O2):
<threshold_vector>:
test   %esi,%esi
jle    1285 <threshold_vector+0x185>
movslq %esi,%rax
lea    (%rdi,%rax,4),%rax
lea    0x4(%rdi),%rdx
cmp    %rdx,%rax
cmova  %rax,%rdx
mov    %rdi,%rcx
not    %rcx
add    %rdx,%rcx
cmp    $0x1c,%rcx
jb     128a <threshold_vector+0x18a>
shr    $0x2,%rcx
add    $0x1,%rcx
mov    %rcx,%r8
and    $0xfffffffffffffff8,%r8
movapd %xmm0,%xmm1
unpcklpd %xmm0,%xmm1
lea    -0x8(%r8),%rdx
mov    %rdx,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rdx,%rdx
je     12c5 <threshold_vector+0x1c5>
mov    %r9,%rdx
and    $0xfffffffffffffffe,%rdx
xor    %esi,%esi
movdqa 0xe93(%rip),%xmm2
nopl   (%rax)
cvtps2pd (%rdi,%rsi,4),%xmm3
cvtps2pd 0x8(%rdi,%rsi,4),%xmm4
cvtps2pd 0x10(%rdi,%rsi,4),%xmm5
cvtps2pd 0x18(%rdi,%rsi,4),%xmm6
movapd %xmm1,%xmm7
cmpltpd %xmm4,%xmm7
movapd %xmm1,%xmm4
cmpltpd %xmm3,%xmm4
packssdw %xmm7,%xmm4
pand   %xmm2,%xmm4
movapd %xmm1,%xmm3
cmpltpd %xmm6,%xmm3
movapd %xmm1,%xmm6
cmpltpd %xmm5,%xmm6
packssdw %xmm3,%xmm6
pand   %xmm2,%xmm6
movdqu %xmm4,(%rdi,%rsi,4)
movdqu %xmm6,0x10(%rdi,%rsi,4)
cvtps2pd 0x20(%rdi,%rsi,4),%xmm3
cvtps2pd 0x28(%rdi,%rsi,4),%xmm4
cvtps2pd 0x30(%rdi,%rsi,4),%xmm5
cvtps2pd 0x38(%rdi,%rsi,4),%xmm6
movapd %xmm1,%xmm7
cmpltpd %xmm4,%xmm7
movapd %xmm1,%xmm4
cmpltpd %xmm3,%xmm4
packssdw %xmm7,%xmm4
pand   %xmm2,%xmm4
movapd %xmm1,%xmm3
cmpltpd %xmm6,%xmm3
movapd %xmm1,%xmm6
cmpltpd %xmm5,%xmm6
packssdw %xmm3,%xmm6
pand   %xmm2,%xmm6
movdqu %xmm4,0x20(%rdi,%rsi,4)
movdqu %xmm6,0x30(%rdi,%rsi,4)
add    $0x10,%rsi
add    $0xfffffffffffffffe,%rdx
jne    1170 <threshold_vector+0x70>
test   $0x1,%r9b
je     1280 <threshold_vector+0x180>
cvtps2pd (%rdi,%rsi,4),%xmm2
cvtps2pd 0x8(%rdi,%rsi,4),%xmm3
cvtps2pd 0x10(%rdi,%rsi,4),%xmm4
cvtps2pd 0x18(%rdi,%rsi,4),%xmm5
movapd %xmm1,%xmm6
cmpltpd %xmm3,%xmm6
movapd %xmm1,%xmm3
cmpltpd %xmm2,%xmm3
packssdw %xmm6,%xmm3
movdqa 0xda5(%rip),%xmm2
pand   %xmm2,%xmm3
movapd %xmm1,%xmm6
cmpltpd %xmm5,%xmm6
cmpltpd %xmm4,%xmm1
packssdw %xmm6,%xmm1
pand   %xmm2,%xmm1
movdqu %xmm3,(%rdi,%rsi,4)
movdqu %xmm1,0x10(%rdi,%rsi,4)
cmp    %r8,%rcx
jne    1286 <threshold_vector+0x186>
ret
lea    (%rdi,%r8,4),%rdi
movd   0xd7e(%rip),%xmm1
jmp    12ad <threshold_vector+0x1ad>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movd   %xmm2,(%rdi)
add    $0x4,%rdi
cmp    %rax,%rdi
jae    1285 <threshold_vector+0x185>
movss  (%rdi),%xmm2
cvtss2sd %xmm2,%xmm2
ucomisd %xmm0,%xmm2
movdqa %xmm1,%xmm2
ja     12a0 <threshold_vector+0x1a0>
pxor   %xmm2,%xmm2
jmp    12a0 <threshold_vector+0x1a0>
xor    %esi,%esi
test   $0x1,%r9b
jne    122a <threshold_vector+0x12a>
jmp    1280 <threshold_vector+0x180>

LLVM IR (-O0):
define void @threshold_vector(float* %0, i32 %1, double %2) {
%4 = alloca float*
%5 = alloca i32
%6 = alloca double
%7 = alloca float*
store float* %0, float** %4
store i32 %1, i32* %5
store double %2, double* %6
%8 = load float*, float** %4
%9 = load i32, i32* %5
%10 = sext i32 %9 to i64
%11 = getelementptr inbounds float, float* %8, i64 %10
store float* %11, float** %7
br label %12
12: ; preds = %25, %3
%13 = load float*, float** %4
%14 = load float*, float** %7
%15 = icmp ult float* %13, %14
br i1 %15, label %16, label %28
16: ; preds = %12
%17 = load float*, float** %4
%18 = load float, float* %17
%19 = fpext float %18 to double
%20 = load double, double* %6
%21 = fcmp ogt double %19, %20
%22 = zext i1 %21 to i32
%23 = sitofp i32 %22 to float
%24 = load float*, float** %4
store float %23, float* %24
br label %25
25: ; preds = %16
%26 = load float*, float** %4
%27 = getelementptr inbounds float, float* %26, i32 1
store float* %27, float** %4
br label %12
28: ; preds = %12
ret void
}

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