void interpolate2D_weights(float rx, float ry, float w[2][2]) {
  int ix, iy;
  float x, y;
  iy = (int)floor(ry);
  ix = (int)floor(rx);
  y = ry - (float)iy;
  x = rx - (float)ix;
  w[0][0] = (1 - x) * (1 - y);
  w[1][0] = (x) * (1 - y);
  w[0][1] = (1 - x) * (y);
  w[1][1] = (x) * (y);
}


x86 assembly (clang, -O0):
<interpolate2D_weights>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
movss  %xmm0,-0x4(%rbp)
movss  %xmm1,-0x8(%rbp)
mov    %rdi,-0x10(%rbp)
movss  -0x8(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
call   1030 <floor@plt>
cvttsd2si %xmm0,%eax
mov    %eax,-0x18(%rbp)
movss  -0x4(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
call   1030 <floor@plt>
cvttsd2si %xmm0,%eax
mov    %eax,-0x14(%rbp)
movss  -0x8(%rbp),%xmm0
cvtsi2ssl -0x18(%rbp),%xmm1
subss  %xmm1,%xmm0
movss  %xmm0,-0x20(%rbp)
movss  -0x4(%rbp),%xmm0
cvtsi2ssl -0x14(%rbp),%xmm1
subss  %xmm1,%xmm0
movss  %xmm0,-0x1c(%rbp)
movss  0xe82(%rip),%xmm0
subss  -0x1c(%rbp),%xmm0
movss  0xe75(%rip),%xmm1
subss  -0x20(%rbp),%xmm1
mulss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,(%rax)
movss  -0x1c(%rbp),%xmm0
movss  0xe57(%rip),%xmm1
subss  -0x20(%rbp),%xmm1
mulss  %xmm1,%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,0x8(%rax)
movss  0xe3d(%rip),%xmm0
subss  -0x1c(%rbp),%xmm0
mulss  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,0x4(%rax)
movss  -0x1c(%rbp),%xmm0
mulss  -0x20(%rbp),%xmm0
mov    -0x10(%rbp),%rax
movss  %xmm0,0xc(%rax)
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<interpolate2D_weights>:
push   %rbx
sub    $0x30,%rsp
mov    %rdi,%rbx
movaps %xmm1,0x20(%rsp)
movaps %xmm0,(%rsp)
movaps %xmm1,%xmm0
call   1030 <floorf@plt>
movaps %xmm0,0x10(%rsp)
movaps (%rsp),%xmm0
call   1030 <floorf@plt>
cvttps2dq 0x10(%rsp),%xmm1
cvtdq2ps %xmm1,%xmm1
movaps 0x20(%rsp),%xmm2
subss  %xmm1,%xmm2
cvttps2dq %xmm0,%xmm0
cvtdq2ps %xmm0,%xmm0
movaps (%rsp),%xmm3
subss  %xmm0,%xmm3
movss  0xea0(%rip),%xmm0
movaps %xmm0,%xmm1
subss  %xmm3,%xmm1
subss  %xmm2,%xmm0
shufps $0x0,%xmm3,%xmm1
unpcklps %xmm2,%xmm0
movlhps %xmm0,%xmm0
mulps  %xmm1,%xmm0
movups %xmm0,(%rbx)
add    $0x30,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define void @interpolate2D_weights(float %0, float %1, [2 x float]* %2) {
%4 = alloca float
%5 = alloca float
%6 = alloca [2 x float]*
%7 = alloca i32
%8 = alloca i32
%9 = alloca float
%10 = alloca float
store float %0, float* %4
store float %1, float* %5
store [2 x float]* %2, [2 x float]** %6
%11 = load float, float* %5
%12 = fpext float %11 to double
%13 = call double @llvm.floor.f64(double %12)
%14 = fptosi double %13 to i32
store i32 %14, i32* %8
%15 = load float, float* %4
%16 = fpext float %15 to double
%17 = call double @llvm.floor.f64(double %16)
%18 = fptosi double %17 to i32
store i32 %18, i32* %7
%19 = load float, float* %5
%20 = load i32, i32* %8
%21 = sitofp i32 %20 to float
%22 = fsub float %19, %21
store float %22, float* %10
%23 = load float, float* %4
%24 = load i32, i32* %7
%25 = sitofp i32 %24 to float
%26 = fsub float %23, %25
store float %26, float* %9
%27 = load float, float* %9
%28 = fsub float 1.000000e+00, %27
%29 = load float, float* %10
%30 = fsub float 1.000000e+00, %29
%31 = fmul float %28, %30
%32 = load [2 x float]*, [2 x float]** %6
%33 = getelementptr inbounds [2 x float], [2 x float]* %32, i64 0
%34 = getelementptr inbounds [2 x float], [2 x float]* %33, i64 0, i64 0
store float %31, float* %34
%35 = load float, float* %9
%36 = load float, float* %10
%37 = fsub float 1.000000e+00, %36
%38 = fmul float %35, %37
%39 = load [2 x float]*, [2 x float]** %6
%40 = getelementptr inbounds [2 x float], [2 x float]* %39, i64 1
%41 = getelementptr inbounds [2 x float], [2 x float]* %40, i64 0, i64 0
store float %38, float* %41
%42 = load float, float* %9
%43 = fsub float 1.000000e+00, %42
%44 = load float, float* %10
%45 = fmul float %43, %44
%46 = load [2 x float]*, [2 x float]** %6
%47 = getelementptr inbounds [2 x float], [2 x float]* %46, i64 0
%48 = getelementptr inbounds [2 x float], [2 x float]* %47, i64 0, i64 1
store float %45, float* %48
%49 = load float, float* %9
%50 = load float, float* %10
%51 = fmul float %49, %50
%52 = load [2 x float]*, [2 x float]** %6
%53 = getelementptr inbounds [2 x float], [2 x float]* %52, i64 1
%54 = getelementptr inbounds [2 x float], [2 x float]* %53, i64 0, i64 1
store float %51, float* %54
ret void
}

LLVM IR (-O2):
define void @interpolate2D_weights(float %0, float %1, [2 x float]* nocapture writeonly %2) {
%4 = tail call float @llvm.floor.f32(float %1)
%5 = fptosi float %4 to i32
%6 = tail call float @llvm.floor.f32(float %0)
%7 = fptosi float %6 to i32
%8 = sitofp i32 %5 to float
%9 = fsub float %1, %8
%10 = sitofp i32 %7 to float
%11 = fsub float %0, %10
%12 = fsub float 1.000000e+00, %11
%13 = fsub float 1.000000e+00, %9
%14 = insertelement <4 x float> poison, float %12, i64 0
%15 = insertelement <4 x float> %14, float %11, i64 1
%16 = shufflevector <4 x float> %15, <4 x float> poison, <4 x i32> <i32 0, i32 0, i32 1, i32 1>
%17 = insertelement <4 x float> poison, float %13, i64 0
%18 = insertelement <4 x float> %17, float %9, i64 1
%19 = shufflevector <4 x float> %18, <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
%20 = fmul <4 x float> %16, %19
%21 = bitcast [2 x float]* %2 to <4 x float>*
store <4 x float> %20, <4 x float>* %21
ret void
}