float sphere_func(const float p[3], const float s[3], float smoothness) {
  float d = vec3_norm(p);
  float r;
  if (p[0] == 0 && p[1] == 0 && p[2] == 0)
    return max3(s[0], s[1], s[2]);
  r = s[0] * s[1] * s[2] /
      vec3_norm(((float[]){s[1] * s[2] * p[0] / d, s[0] * s[2] * p[1] / d,
                           s[0] * s[1] * p[2] / d}));
  return r - d;
}


x86 assembly (clang, -O0):
<sphere_func>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movss  %xmm0,-0x1c(%rbp)
mov    -0x10(%rbp),%rdi
mov    $0x0,%al
call   1040 <vec3_norm@plt>
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x20(%rbp)
mov    -0x10(%rbp),%rax
movss  (%rax),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    11d4 <sphere_func+0xb4>
jp     11d4 <sphere_func+0xb4>
mov    -0x10(%rbp),%rax
movss  0x4(%rax),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    11d4 <sphere_func+0xb4>
jp     11d4 <sphere_func+0xb4>
mov    -0x10(%rbp),%rax
movss  0x8(%rax),%xmm0
xorps  %xmm1,%xmm1
ucomiss %xmm1,%xmm0
jne    11d4 <sphere_func+0xb4>
jp     11d4 <sphere_func+0xb4>
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
cvtss2sd %xmm0,%xmm0
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm1
cvtss2sd %xmm1,%xmm1
mov    -0x18(%rbp),%rax
movss  0x8(%rax),%xmm2
cvtss2sd %xmm2,%xmm2
mov    $0x3,%al
call   1030 <max3@plt>
cvtsi2ss %eax,%xmm0
movss  %xmm0,-0x4(%rbp)
jmp    128b <sphere_func+0x16b>
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x8(%rax),%xmm0
movss  %xmm0,-0x34(%rbp)
mov    -0x18(%rbp),%rax
movss  0x4(%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  (%rax),%xmm0
divss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x30(%rbp)
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x8(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x4(%rax),%xmm0
divss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x2c(%rbp)
mov    -0x18(%rbp),%rax
movss  (%rax),%xmm0
mov    -0x18(%rbp),%rax
mulss  0x4(%rax),%xmm0
mov    -0x10(%rbp),%rax
mulss  0x8(%rax),%xmm0
divss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
lea    -0x30(%rbp),%rdi
mov    $0x0,%al
call   1040 <vec3_norm@plt>
movss  -0x34(%rbp),%xmm0
cvtsi2ss %eax,%xmm1
divss  %xmm1,%xmm0
movss  %xmm0,-0x24(%rbp)
movss  -0x24(%rbp),%xmm0
subss  -0x20(%rbp),%xmm0
movss  %xmm0,-0x4(%rbp)
movss  -0x4(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sphere_func>:
push   %r14
push   %rbx
sub    $0x18,%rsp
mov    %rsi,%r14
mov    %rdi,%rbx
xor    %eax,%eax
call   1040 <vec3_norm@plt>
movss  (%rbx),%xmm1
movss  0x4(%rbx),%xmm0
xorps  %xmm2,%xmm2
ucomiss %xmm2,%xmm1
jne    118d <sphere_func+0x6d>
jp     118d <sphere_func+0x6d>
ucomiss %xmm2,%xmm0
jne    118d <sphere_func+0x6d>
jp     118d <sphere_func+0x6d>
movss  0x8(%rbx),%xmm2
xorps  %xmm3,%xmm3
ucomiss %xmm3,%xmm2
jne    118d <sphere_func+0x6d>
jp     118d <sphere_func+0x6d>
movss  (%r14),%xmm0
movss  0x4(%r14),%xmm1
cvtss2sd %xmm0,%xmm0
cvtss2sd %xmm1,%xmm1
movss  0x8(%r14),%xmm2
cvtss2sd %xmm2,%xmm2
mov    $0x3,%al
call   1030 <max3@plt>
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
jmp    1215 <sphere_func+0xf5>
cvtsi2ss %eax,%xmm6
movss  (%r14),%xmm2
movss  0x4(%r14),%xmm3
movaps %xmm2,%xmm4
mulss  %xmm3,%xmm4
movss  0x8(%r14),%xmm5
movaps %xmm4,%xmm7
mulss  %xmm5,%xmm7
movss  %xmm7,0x8(%rsp)
mulss  %xmm5,%xmm3
mulss  %xmm3,%xmm1
movss  %xmm6,0x4(%rsp)
divss  %xmm6,%xmm1
movss  %xmm1,0xc(%rsp)
mulss  %xmm5,%xmm2
mulss  %xmm0,%xmm2
divss  %xmm6,%xmm2
movss  %xmm2,0x10(%rsp)
mulss  0x8(%rbx),%xmm4
divss  %xmm6,%xmm4
movss  %xmm4,0x14(%rsp)
lea    0xc(%rsp),%rdi
xor    %eax,%eax
call   1040 <vec3_norm@plt>
xorps  %xmm0,%xmm0
cvtsi2ss %eax,%xmm0
movss  0x8(%rsp),%xmm1
divss  %xmm0,%xmm1
movaps %xmm1,%xmm0
subss  0x4(%rsp),%xmm0
add    $0x18,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define float @sphere_func(float* %0, float* %1, float %2) {
%4 = alloca float
%5 = alloca float*
%6 = alloca float*
%7 = alloca float
%8 = alloca float
%9 = alloca float
%10 = alloca [3 x float]
store float* %0, float** %5
store float* %1, float** %6
store float %2, float* %7
%11 = load float*, float** %5
%12 = call i32 (float*, ...) bitcast (i32 (...)* @vec3_norm to i32 (float*, ...)*)(float* %11)
%13 = sitofp i32 %12 to float
store float %13, float* %8
%14 = load float*, float** %5
%15 = getelementptr inbounds float, float* %14, i64 0
%16 = load float, float* %15
%17 = fcmp oeq float %16, 0.000000e+00
br i1 %17, label %18, label %43
18: ; preds = %3
%19 = load float*, float** %5
%20 = getelementptr inbounds float, float* %19, i64 1
%21 = load float, float* %20
%22 = fcmp oeq float %21, 0.000000e+00
br i1 %22, label %23, label %43
23: ; preds = %18
%24 = load float*, float** %5
%25 = getelementptr inbounds float, float* %24, i64 2
%26 = load float, float* %25
%27 = fcmp oeq float %26, 0.000000e+00
br i1 %27, label %28, label %43
28: ; preds = %23
%29 = load float*, float** %6
%30 = getelementptr inbounds float, float* %29, i64 0
%31 = load float, float* %30
%32 = fpext float %31 to double
%33 = load float*, float** %6
%34 = getelementptr inbounds float, float* %33, i64 1
%35 = load float, float* %34
%36 = fpext float %35 to double
%37 = load float*, float** %6
%38 = getelementptr inbounds float, float* %37, i64 2
%39 = load float, float* %38
%40 = fpext float %39 to double
%41 = call i32 (double, double, double, ...) bitcast (i32 (...)* @max3 to i32 (double, double, double, ...)*)(double %32, double %36, double %40)
%42 = sitofp i32 %41 to float
store float %42, float* %4
br label %104
43: ; preds = %23, %18, %3
%44 = load float*, float** %6
%45 = getelementptr inbounds float, float* %44, i64 0
%46 = load float, float* %45
%47 = load float*, float** %6
%48 = getelementptr inbounds float, float* %47, i64 1
%49 = load float, float* %48
%50 = fmul float %46, %49
%51 = load float*, float** %6
%52 = getelementptr inbounds float, float* %51, i64 2
%53 = load float, float* %52
%54 = fmul float %50, %53
%55 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 0
%56 = load float*, float** %6
%57 = getelementptr inbounds float, float* %56, i64 1
%58 = load float, float* %57
%59 = load float*, float** %6
%60 = getelementptr inbounds float, float* %59, i64 2
%61 = load float, float* %60
%62 = fmul float %58, %61
%63 = load float*, float** %5
%64 = getelementptr inbounds float, float* %63, i64 0
%65 = load float, float* %64
%66 = fmul float %62, %65
%67 = load float, float* %8
%68 = fdiv float %66, %67
store float %68, float* %55
%69 = getelementptr inbounds float, float* %55, i64 1
%70 = load float*, float** %6
%71 = getelementptr inbounds float, float* %70, i64 0
%72 = load float, float* %71
%73 = load float*, float** %6
%74 = getelementptr inbounds float, float* %73, i64 2
%75 = load float, float* %74
%76 = fmul float %72, %75
%77 = load float*, float** %5
%78 = getelementptr inbounds float, float* %77, i64 1
%79 = load float, float* %78
%80 = fmul float %76, %79
%81 = load float, float* %8
%82 = fdiv float %80, %81
store float %82, float* %69
%83 = getelementptr inbounds float, float* %69, i64 1
%84 = load float*, float** %6
%85 = getelementptr inbounds float, float* %84, i64 0
%86 = load float, float* %85
%87 = load float*, float** %6
%88 = getelementptr inbounds float, float* %87, i64 1
%89 = load float, float* %88
%90 = fmul float %86, %89
%91 = load float*, float** %5
%92 = getelementptr inbounds float, float* %91, i64 2
%93 = load float, float* %92
%94 = fmul float %90, %93
%95 = load float, float* %8
%96 = fdiv float %94, %95
store float %96, float* %83
%97 = getelementptr inbounds [3 x float], [3 x float]* %10, i64 0, i64 0
%98 = call i32 (float*, ...) bitcast (i32 (...)* @vec3_norm to i32 (float*, ...)*)(float* %97)
%99 = sitofp i32 %98 to float
%100 = fdiv float %54, %99
store float %100, float* %9
%101 = load float, float* %9
%102 = load float, float* %8
%103 = fsub float %101, %102
store float %103, float* %4
br label %104
104: ; preds = %43, %28
%105 = load float, float* %4
ret float %105
}

LLVM IR (-O2):
define float @sphere_func(float* %0, float* nocapture %1, float %2) {
%4 = alloca [3 x float]
%5 = tail call i32 (float*, ...) bitcast (i32 (...)* @vec3_norm to i32 (float*, ...)*)(float* %0)
%6 = sitofp i32 %5 to float
%7 = load float, float* %0
%8 = fcmp oeq float %7, 0.000000e+00
%9 = getelementptr inbounds float, float* %0, i64 1
%10 = load float, float* %9
%11 = fcmp oeq float %10, 0.000000e+00
%12 = select i1 %8, i1 %11, i1 false
br i1 %12, label %13, label %28
13: ; preds = %3
%14 = getelementptr inbounds float, float* %0, i64 2
%15 = load float, float* %14
%16 = fcmp oeq float %15, 0.000000e+00
br i1 %16, label %17, label %28
17: ; preds = %13
%18 = load float, float* %1
%19 = fpext float %18 to double
%20 = getelementptr inbounds float, float* %1, i64 1
%21 = load float, float* %20
%22 = fpext float %21 to double
%23 = getelementptr inbounds float, float* %1, i64 2
%24 = load float, float* %23
%25 = fpext float %24 to double
%26 = tail call i32 (double, double, double, ...) bitcast (i32 (...)* @max3 to i32 (double, double, double, ...)*)(double %19, double %22, double %25)
%27 = sitofp i32 %26 to float
br label %53
28: ; preds = %3, %13
%29 = load float, float* %1
%30 = getelementptr inbounds float, float* %1, i64 1
%31 = load float, float* %30
%32 = fmul float %29, %31
%33 = getelementptr inbounds float, float* %1, i64 2
%34 = load float, float* %33
%35 = fmul float %32, %34
%36 = getelementptr inbounds [3 x float], [3 x float]* %4, i64 0, i64 0
%37 = fmul float %31, %34
%38 = fmul float %7, %37
%39 = fdiv float %38, %6
store float %39, float* %36
%40 = getelementptr inbounds [3 x float], [3 x float]* %4, i64 0, i64 1
%41 = fmul float %29, %34
%42 = fmul float %41, %10
%43 = fdiv float %42, %6
store float %43, float* %40
%44 = getelementptr inbounds [3 x float], [3 x float]* %4, i64 0, i64 2
%45 = getelementptr inbounds float, float* %0, i64 2
%46 = load float, float* %45
%47 = fmul float %32, %46
%48 = fdiv float %47, %6
store float %48, float* %44
%49 = call i32 (float*, ...) bitcast (i32 (...)* @vec3_norm to i32 (float*, ...)*)(float* %36)
%50 = sitofp i32 %49 to float
%51 = fdiv float %35, %50
%52 = fsub float %51, %6
br label %53
53: ; preds = %28, %17
%54 = phi float [ %27, %17 ], [ %52, %28 ]
ret float %54
}