long double __attribute__((sysv_abi))
func_native(long double a, double b, float c, long d, int e, char f) {
  long double ret;
  ret = a + (long double)b + (long double)c;
  ret *= (long double)(d + (long)e);
  if (f > 0)
    ret += func_native(a, b, c, d, e, -f);
  return ret;
}


x86 assembly (clang, -O0):
<func_native>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %dl,%al
fldt   0x10(%rbp)
fstpt  -0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movss  %xmm1,-0x1c(%rbp)
mov    %rdi,-0x28(%rbp)
mov    %esi,-0x2c(%rbp)
mov    %al,-0x2d(%rbp)
fldt   -0x10(%rbp)
fldl   -0x18(%rbp)
faddp  %st,%st(1)
flds   -0x1c(%rbp)
faddp  %st,%st(1)
fstpt  -0x40(%rbp)
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
add    %rcx,%rax
mov    %rax,-0x48(%rbp)
fildll -0x48(%rbp)
fldt   -0x40(%rbp)
fmulp  %st,%st(1)
fstpt  -0x40(%rbp)
movsbl -0x2d(%rbp),%eax
cmp    $0x0,%eax
jle    119a <func_native+0x8a>
fldt   -0x10(%rbp)
movsd  -0x18(%rbp),%xmm0
movss  -0x1c(%rbp),%xmm1
mov    -0x28(%rbp),%rdi
mov    -0x2c(%rbp),%esi
movzbl -0x2d(%rbp),%eax
neg    %eax
mov    %rsp,%rcx
fstpt  (%rcx)
movsbl %al,%edx
call   1030 <func_native@plt>
fldt   -0x40(%rbp)
faddp  %st,%st(1)
fstpt  -0x40(%rbp)
fldt   -0x40(%rbp)
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<func_native>:
sub    $0x38,%rsp
fldt   0x40(%rsp)
movsd  %xmm0,0x18(%rsp)
fld    %st(0)
faddl  0x18(%rsp)
movss  %xmm1,0x14(%rsp)
fadds  0x14(%rsp)
movslq %esi,%rax
add    %rdi,%rax
mov    %rax,0x20(%rsp)
fildll 0x20(%rsp)
fmulp  %st,%st(1)
test   %dl,%dl
jle    1161 <func_native+0x51>
neg    %dl
fxch   %st(1)
fstpt  (%rsp)
movsbl %dl,%edx
fstpt  0x2c(%rsp)
call   1030 <func_native@plt>
fldt   0x2c(%rsp)
faddp  %st,%st(1)
add    $0x38,%rsp
ret
fstp   %st(1)
add    $0x38,%rsp
ret

LLVM IR (-O0):
define x86_fp80 @func_native(x86_fp80 %0, double %1, float %2, i64 %3, i32 %4, i8 signext %5) {
%7 = alloca x86_fp80
%8 = alloca double
%9 = alloca float
%10 = alloca i64
%11 = alloca i32
%12 = alloca i8
%13 = alloca x86_fp80
store x86_fp80 %0, x86_fp80* %7
store double %1, double* %8
store float %2, float* %9
store i64 %3, i64* %10
store i32 %4, i32* %11
store i8 %5, i8* %12
%14 = load x86_fp80, x86_fp80* %7
%15 = load double, double* %8
%16 = fpext double %15 to x86_fp80
%17 = fadd x86_fp80 %14, %16
%18 = load float, float* %9
%19 = fpext float %18 to x86_fp80
%20 = fadd x86_fp80 %17, %19
store x86_fp80 %20, x86_fp80* %13
%21 = load i64, i64* %10
%22 = load i32, i32* %11
%23 = sext i32 %22 to i64
%24 = add nsw i64 %21, %23
%25 = sitofp i64 %24 to x86_fp80
%26 = load x86_fp80, x86_fp80* %13
%27 = fmul x86_fp80 %26, %25
store x86_fp80 %27, x86_fp80* %13
%28 = load i8, i8* %12
%29 = sext i8 %28 to i32
%30 = icmp sgt i32 %29, 0
br i1 %30, label %31, label %44
31: ; preds = %6
%32 = load x86_fp80, x86_fp80* %7
%33 = load double, double* %8
%34 = load float, float* %9
%35 = load i64, i64* %10
%36 = load i32, i32* %11
%37 = load i8, i8* %12
%38 = sext i8 %37 to i32
%39 = sub nsw i32 0, %38
%40 = trunc i32 %39 to i8
%41 = call x86_fp80 @func_native(x86_fp80 %32, double %33, float %34, i64 %35, i32 %36, i8 signext %40)
%42 = load x86_fp80, x86_fp80* %13
%43 = fadd x86_fp80 %42, %41
store x86_fp80 %43, x86_fp80* %13
br label %44
44: ; preds = %31, %6
%45 = load x86_fp80, x86_fp80* %13
ret x86_fp80 %45
}

LLVM IR (-O2):
define x86_fp80 @func_native(x86_fp80 %0, double %1, float %2, i64 %3, i32 %4, i8 signext %5) {
%7 = fpext double %1 to x86_fp80
%8 = fadd x86_fp80 %7, %0
%9 = fpext float %2 to x86_fp80
%10 = fadd x86_fp80 %8, %9
%11 = sext i32 %4 to i64
%12 = add nsw i64 %11, %3
%13 = sitofp i64 %12 to x86_fp80
%14 = fmul x86_fp80 %10, %13
%15 = icmp sgt i8 %5, 0
br i1 %15, label %18, label %16
16: ; preds = %6, %18
%17 = phi x86_fp80 [ %21, %18 ], [ %14, %6 ]
ret x86_fp80 %17
18: ; preds = %6
%19 = sub nsw i8 0, %5
%20 = tail call x86_fp80 @func_native(x86_fp80 %0, double %1, float %2, i64 %3, i32 %4, i8 signext %19)
%21 = fadd x86_fp80 %14, %20
br label %16
}