void sh2fl_alt(n, ix, y, mask) long n;
short *ix, mask;
float *y;
{
  register long k;
  register float factor;
  for (k = 0, factor = (1. / 32768.); k < n; k++)
    *y++ = factor * ((*ix++) & mask);
}


x86 assembly (clang, -O0):
<sh2fl_alt>:
push   %rbp
mov    %rsp,%rbp
mov    %cx,%ax
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ax,-0x1a(%rbp)
movq   $0x0,-0x28(%rbp)
movss  0xed9(%rip),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x8(%rbp),%rax
jge    1183 <sh2fl_alt+0x83>
movss  -0x2c(%rbp),%xmm0
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x2,%rcx
mov    %rcx,-0x10(%rbp)
movswl (%rax),%eax
movswl -0x1a(%rbp),%ecx
and    %ecx,%eax
cvtsi2ss %eax,%xmm1
mulss  %xmm1,%xmm0
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x18(%rbp)
movss  %xmm0,(%rax)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    112c <sh2fl_alt+0x2c>
pop    %rbp
ret

x86 assembly (clang, -O2):
<sh2fl_alt>:
test   %rdi,%rdi
jle    1270 <sh2fl_alt+0x170>
movswl %cx,%r10d
cmp    $0x8,%rdi
jae    111b <sh2fl_alt+0x1b>
xor    %r8d,%r8d
jmp    1234 <sh2fl_alt+0x134>
mov    %rdi,%r8
and    $0xfffffffffffffff8,%r8
movd   %r10d,%xmm0
pshufd $0x0,%xmm0,%xmm0
lea    -0x8(%r8),%rax
mov    %rax,%r9
shr    $0x3,%r9
add    $0x1,%r9
test   %rax,%rax
je     1271 <sh2fl_alt+0x171>
mov    %r9,%rax
and    $0xfffffffffffffffe,%rax
xor    %ecx,%ecx
movaps 0xeac(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movq   (%rsi,%rcx,2),%xmm2
punpcklwd %xmm2,%xmm2
movq   0x8(%rsi,%rcx,2),%xmm3
punpcklwd %xmm3,%xmm3
psrad  $0x10,%xmm2
psrad  $0x10,%xmm3
pand   %xmm0,%xmm2
pand   %xmm0,%xmm3
cvtdq2ps %xmm2,%xmm2
cvtdq2ps %xmm3,%xmm3
mulps  %xmm1,%xmm2
mulps  %xmm1,%xmm3
movups %xmm2,(%rdx,%rcx,4)
movups %xmm3,0x10(%rdx,%rcx,4)
movq   0x10(%rsi,%rcx,2),%xmm2
punpcklwd %xmm2,%xmm2
movq   0x18(%rsi,%rcx,2),%xmm3
punpcklwd %xmm3,%xmm3
psrad  $0x10,%xmm2
psrad  $0x10,%xmm3
pand   %xmm0,%xmm2
pand   %xmm0,%xmm3
cvtdq2ps %xmm2,%xmm2
cvtdq2ps %xmm3,%xmm3
mulps  %xmm1,%xmm2
mulps  %xmm1,%xmm3
movups %xmm2,0x20(%rdx,%rcx,4)
movups %xmm3,0x30(%rdx,%rcx,4)
add    $0x10,%rcx
add    $0xfffffffffffffffe,%rax
jne    1160 <sh2fl_alt+0x60>
test   $0x1,%r9b
je     1227 <sh2fl_alt+0x127>
movq   (%rsi,%rcx,2),%xmm1
movq   0x8(%rsi,%rcx,2),%xmm2
punpcklwd %xmm1,%xmm1
psrad  $0x10,%xmm1
punpcklwd %xmm2,%xmm2
psrad  $0x10,%xmm2
pand   %xmm0,%xmm1
pand   %xmm0,%xmm2
cvtdq2ps %xmm1,%xmm0
cvtdq2ps %xmm2,%xmm1
movaps 0xde8(%rip),%xmm2
mulps  %xmm2,%xmm0
mulps  %xmm2,%xmm1
movups %xmm0,(%rdx,%rcx,4)
movups %xmm1,0x10(%rdx,%rcx,4)
cmp    %rdi,%r8
je     1270 <sh2fl_alt+0x170>
lea    (%rsi,%r8,2),%rsi
lea    (%rdx,%r8,4),%rdx
sub    %r8,%rdi
xor    %eax,%eax
movss  0xdcf(%rip),%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movswl (%rsi,%rax,2),%ecx
and    %r10d,%ecx
xorps  %xmm1,%xmm1
cvtsi2ss %ecx,%xmm1
mulss  %xmm0,%xmm1
movss  %xmm1,(%rdx,%rax,4)
add    $0x1,%rax
cmp    %rax,%rdi
jne    1250 <sh2fl_alt+0x150>
ret
xor    %ecx,%ecx
test   $0x1,%r9b
jne    11e6 <sh2fl_alt+0xe6>
jmp    1227 <sh2fl_alt+0x127>

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

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