int solo5_app_main(const struct solo5_start_info *si __attribute__((unused))) {
  puts("\n**** Solo5 standalone test_fpu ****\n\n");
  float a, b, c[2];
  c[0] = 2.0;
  c[1] = 5.0;
  __asm__("movups %0,%%xmm1;"
          "mulps %%xmm1, %%xmm1;"
          "movups %%xmm1, %0"
          : "=m"(c)
          : "m"(c)
          : "xmm1");
  a = 1.5;
  b = 5.0;
  a *= b;
  if (a == 7.5 && c[0] == 4.0 && c[1] == 25.0)
    puts("SUCCESS\n");
  else
    return 1;
  return 0;
}


x86 assembly (clang, -O0):
<solo5_app_main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
lea    0xf01(%rip),%rdi
mov    $0x0,%al
call   1030 <puts@plt>
movss  0xeee(%rip),%xmm0
movss  %xmm0,-0x20(%rbp)
movss  0xed9(%rip),%xmm0
movss  %xmm0,-0x1c(%rbp)
movups -0x20(%rbp),%xmm1
mulps  %xmm1,%xmm1
movups %xmm1,-0x20(%rbp)
movss  0xec5(%rip),%xmm0
movss  %xmm0,-0x14(%rbp)
movss  0xeb4(%rip),%xmm0
movss  %xmm0,-0x18(%rbp)
movss  -0x18(%rbp),%xmm0
mulss  -0x14(%rbp),%xmm0
movss  %xmm0,-0x14(%rbp)
movss  -0x14(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe77(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    11ee <solo5_app_main+0xde>
jp     11ee <solo5_app_main+0xde>
movss  -0x20(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe5e(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    11ee <solo5_app_main+0xde>
jp     11ee <solo5_app_main+0xde>
movss  -0x1c(%rbp),%xmm0
cvtss2sd %xmm0,%xmm0
movsd  0xe45(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    11ee <solo5_app_main+0xde>
jp     11ee <solo5_app_main+0xde>
lea    0xe69(%rip),%rdi
mov    $0x0,%al
call   1030 <puts@plt>
jmp    11fa <solo5_app_main+0xea>
movl   $0x1,-0x4(%rbp)
jmp    1201 <solo5_app_main+0xf1>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<solo5_app_main>:
push   %rbx
sub    $0x10,%rsp
lea    0xeec(%rip),%rdi
xor    %eax,%eax
call   1030 <puts@plt>
movabs $0x40a0000040000000,%rax
mov    %rax,0x8(%rsp)
movups 0x8(%rsp),%xmm1
mulps  %xmm1,%xmm1
movups %xmm1,0x8(%rsp)
movss  0x8(%rsp),%xmm0
ucomiss 0xeb4(%rip),%xmm0
mov    $0x1,%ebx
jne    1176 <solo5_app_main+0x66>
jp     1176 <solo5_app_main+0x66>
movss  0xc(%rsp),%xmm0
ucomiss 0xea2(%rip),%xmm0
jne    1176 <solo5_app_main+0x66>
jp     1176 <solo5_app_main+0x66>
lea    0xec2(%rip),%rdi
xor    %ebx,%ebx
xor    %eax,%eax
call   1030 <puts@plt>
mov    %ebx,%eax
add    $0x10,%rsp
pop    %rbx
ret

LLVM IR (-O0):
%struct.solo5_start_info = type opaque
@.str = [39 x i8] c"\0A**** Solo5 standalone test_fpu ****\0A\0A\00"
@.str.1 = [9 x i8] c"SUCCESS\0A\00"
define i32 @solo5_app_main(%struct.solo5_start_info* %0) {
%2 = alloca i32
%3 = alloca %struct.solo5_start_info*
%4 = alloca float
%5 = alloca float
%6 = alloca [2 x float]
store %struct.solo5_start_info* %0, %struct.solo5_start_info** %3
%7 = call i32 (i8*, ...) bitcast (i32 (...)* @puts to i32 (i8*, ...)*)(i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str, i64 0, i64 0))
%8 = getelementptr inbounds [2 x float], [2 x float]* %6, i64 0, i64 0
store float 2.000000e+00, float* %8
%9 = getelementptr inbounds [2 x float], [2 x float]* %6, i64 0, i64 1
store float 5.000000e+00, float* %9
store float 1.500000e+00, float* %4
store float 5.000000e+00, float* %5
%10 = load float, float* %5
%11 = load float, float* %4
%12 = fmul float %11, %10
store float %12, float* %4
%13 = load float, float* %4
%14 = fpext float %13 to double
%15 = fcmp oeq double %14, 7.500000e+00
br i1 %15, label %16, label %28
16: ; preds = %1
%17 = getelementptr inbounds [2 x float], [2 x float]* %6, i64 0, i64 0
%18 = load float, float* %17
%19 = fpext float %18 to double
%20 = fcmp oeq double %19, 4.000000e+00
br i1 %20, label %21, label %28
21: ; preds = %16
%22 = getelementptr inbounds [2 x float], [2 x float]* %6, i64 0, i64 1
%23 = load float, float* %22
%24 = fpext float %23 to double
%25 = fcmp oeq double %24, 2.500000e+01
br i1 %25, label %26, label %28
26: ; preds = %21
%27 = call i32 (i8*, ...) bitcast (i32 (...)* @puts to i32 (i8*, ...)*)(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0))
br label %29
28: ; preds = %21, %16, %1
store i32 1, i32* %2
br label %30
29: ; preds = %26
store i32 0, i32* %2
br label %30
30: ; preds = %29, %28
%31 = load i32, i32* %2
ret i32 %31
}

LLVM IR (-O2):
%struct.solo5_start_info = type opaque
@.str = [39 x i8] c"\0A**** Solo5 standalone test_fpu ****\0A\0A\00"
@.str.1 = [9 x i8] c"SUCCESS\0A\00"
define i32 @solo5_app_main(%struct.solo5_start_info* nocapture readnone %0) {
%2 = alloca [2 x float]
%3 = tail call i32 (i8*, ...) bitcast (i32 (...)* @puts to i32 (i8*, ...)*)(i8* getelementptr inbounds ([39 x i8], [39 x i8]* @.str, i64 0, i64 0))
%4 = bitcast [2 x float]* %2 to i8*
%5 = getelementptr inbounds [2 x float], [2 x float]* %2, i64 0, i64 0
store float 2.000000e+00, float* %5
%6 = getelementptr inbounds [2 x float], [2 x float]* %2, i64 0, i64 1
store float 5.000000e+00, float* %6
%7 = load float, float* %5
%8 = fcmp oeq float %7, 4.000000e+00
%9 = load float, float* %6
%10 = fcmp oeq float %9, 2.500000e+01
%11 = select i1 %8, i1 %10, i1 false
br i1 %11, label %12, label %14
12: ; preds = %1
%13 = call i32 (i8*, ...) bitcast (i32 (...)* @puts to i32 (i8*, ...)*)(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.1, i64 0, i64 0))
br label %14
14: ; preds = %1, %12
%15 = phi i32 [ 0, %12 ], [ 1, %1 ]
ret i32 %15
}