#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
short SHRT_MAX;
short SHRT_MIN;
int /*<<< orphan*/ memcpy(short *, short *, long);
int ffi2fi2(short *input, long ntodo, double scale, double zero, short *output,
            int *status) {
  long ii;
  double dvalue;
  if (scale == 1. && zero == 0.) {
    memcpy(output, input, ntodo * sizeof(short));
  } else {
    for (ii = 0; ii < ntodo; ii++) {
      dvalue = (input[ii] - zero) / scale;
      if (dvalue < -32768.49) {
        *status = -11;
        output[ii] = SHRT_MIN;
      } else if (dvalue > 32767.49) {
        *status = -11;
        output[ii] = SHRT_MAX;
      } else {
        if (dvalue >= 0)
          output[ii] = (short)(dvalue + .5);
        else
          output[ii] = (short)(dvalue - .5);
      }
    }
  }
  return (*status);
}


x86 assembly (clang, -O0):
<ffi2fi2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
movsd  %xmm0,-0x18(%rbp)
movsd  %xmm1,-0x20(%rbp)
mov    %rdx,-0x28(%rbp)
mov    %rcx,-0x30(%rbp)
movsd  -0x18(%rbp),%xmm0
movsd  0xec1(%rip),%xmm1
ucomisd %xmm1,%xmm0
jne    1181 <ffi2fi2+0x71>
jp     1181 <ffi2fi2+0x71>
movsd  -0x20(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jne    1181 <ffi2fi2+0x71>
jp     1181 <ffi2fi2+0x71>
mov    -0x28(%rbp),%rdi
mov    -0x8(%rbp),%rsi
mov    -0x10(%rbp),%rdx
shl    $0x1,%rdx
call   1030 <memcpy@plt>
jmp    12ae <ffi2fi2+0x19e>
movq   $0x0,-0x38(%rbp)
mov    -0x38(%rbp),%rax
cmp    -0x10(%rbp),%rax
jge    12a9 <ffi2fi2+0x199>
mov    -0x8(%rbp),%rax
mov    -0x38(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
cvtsi2sd %eax,%xmm0
subsd  -0x20(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  0xe4a(%rip),%xmm0
ucomisd -0x40(%rbp),%xmm0
jbe    11ee <ffi2fi2+0xde>
mov    -0x30(%rbp),%rax
movl   $0xfffffff5,(%rax)
mov    0x2e06(%rip),%rax
mov    (%rax),%dx
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
jmp    1293 <ffi2fi2+0x183>
movsd  -0x40(%rbp),%xmm0
movsd  0xe15(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    122a <ffi2fi2+0x11a>
mov    -0x30(%rbp),%rax
movl   $0xfffffff5,(%rax)
mov    0x2dc2(%rip),%rax
mov    (%rax),%dx
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
jmp    128e <ffi2fi2+0x17e>
movsd  -0x40(%rbp),%xmm0
xorps  %xmm1,%xmm1
ucomisd %xmm1,%xmm0
jb     1265 <ffi2fi2+0x155>
movsd  -0x40(%rbp),%xmm0
movsd  0xdd7(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,%dx
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
jmp    1289 <ffi2fi2+0x179>
movsd  -0x40(%rbp),%xmm0
movsd  0xda6(%rip),%xmm1
addsd  %xmm1,%xmm0
cvttsd2si %xmm0,%eax
mov    %ax,%dx
mov    -0x28(%rbp),%rax
mov    -0x38(%rbp),%rcx
mov    %dx,(%rax,%rcx,2)
jmp    128e <ffi2fi2+0x17e>
jmp    1293 <ffi2fi2+0x183>
jmp    1298 <ffi2fi2+0x188>
mov    -0x38(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x38(%rbp)
jmp    1189 <ffi2fi2+0x79>
jmp    12ae <ffi2fi2+0x19e>
mov    -0x30(%rbp),%rax
mov    (%rax),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ffi2fi2>:
push   %rbx
mov    %rcx,%rbx
mov    %rsi,%rax
mov    %rdi,%rsi
ucomisd 0xede(%rip),%xmm0
jne    1145 <ffi2fi2+0x35>
jp     1145 <ffi2fi2+0x35>
xorpd  %xmm2,%xmm2
ucomisd %xmm2,%xmm1
jne    1145 <ffi2fi2+0x35>
jp     1145 <ffi2fi2+0x35>
add    %rax,%rax
mov    %rdx,%rdi
mov    %rax,%rdx
call   1030 <memcpy@plt>
jmp    11f6 <ffi2fi2+0xe6>
test   %rax,%rax
jle    11f6 <ffi2fi2+0xe6>
xor    %ecx,%ecx
movsd  0xeb0(%rip),%xmm2
mov    0x2e81(%rip),%r9
movsd  0xea9(%rip),%xmm3
mov    0x2e6a(%rip),%r8
xorpd  %xmm4,%xmm4
movsd  0xea6(%rip),%xmm5
movsd  0xe96(%rip),%xmm6
jmp    11a7 <ffi2fi2+0x97>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movl   $0xfffffff5,(%rbx)
movzwl (%r9),%edi
mov    %di,(%rdx,%rcx,2)
add    $0x1,%rcx
cmp    %rcx,%rax
je     11f6 <ffi2fi2+0xe6>
movswl (%rsi,%rcx,2),%edi
xorps  %xmm7,%xmm7
cvtsi2sd %edi,%xmm7
subsd  %xmm1,%xmm7
divsd  %xmm0,%xmm7
ucomisd %xmm7,%xmm2
ja     1190 <ffi2fi2+0x80>
ucomisd %xmm3,%xmm7
jbe    11e0 <ffi2fi2+0xd0>
movl   $0xfffffff5,(%rbx)
movzwl (%r8),%edi
jmp    119a <ffi2fi2+0x8a>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
ucomisd %xmm4,%xmm7
jae    11ec <ffi2fi2+0xdc>
addsd  %xmm5,%xmm7
jmp    11f0 <ffi2fi2+0xe0>
addsd  %xmm6,%xmm7
cvttsd2si %xmm7,%edi
jmp    119a <ffi2fi2+0x8a>
mov    (%rbx),%eax
pop    %rbx
ret

LLVM IR (-O0):
@SHRT_MIN = global i16 0
@SHRT_MAX = global i16 0
define i32 @ffi2fi2(i16* %0, i64 %1, double %2, double %3, i16* %4, i32* %5) {
%7 = alloca i16*
%8 = alloca i64
%9 = alloca double
%10 = alloca double
%11 = alloca i16*
%12 = alloca i32*
%13 = alloca i64
%14 = alloca double
store i16* %0, i16** %7
store i64 %1, i64* %8
store double %2, double* %9
store double %3, double* %10
store i16* %4, i16** %11
store i32* %5, i32** %12
%15 = load double, double* %9
%16 = fcmp oeq double %15, 1.000000e+00
br i1 %16, label %17, label %26
17: ; preds = %6
%18 = load double, double* %10
%19 = fcmp oeq double %18, 0.000000e+00
br i1 %19, label %20, label %26
20: ; preds = %17
%21 = load i16*, i16** %11
%22 = load i16*, i16** %7
%23 = load i64, i64* %8
%24 = mul i64 %23, 2
%25 = call i32 @memcpy(i16* %21, i16* %22, i64 %24)
br label %83
26: ; preds = %17, %6
store i64 0, i64* %13
br label %27
27: ; preds = %79, %26
%28 = load i64, i64* %13
%29 = load i64, i64* %8
%30 = icmp slt i64 %28, %29
br i1 %30, label %31, label %82
31: ; preds = %27
%32 = load i16*, i16** %7
%33 = load i64, i64* %13
%34 = getelementptr inbounds i16, i16* %32, i64 %33
%35 = load i16, i16* %34
%36 = sext i16 %35 to i32
%37 = sitofp i32 %36 to double
%38 = load double, double* %10
%39 = fsub double %37, %38
%40 = load double, double* %9
%41 = fdiv double %39, %40
store double %41, double* %14
%42 = load double, double* %14
%43 = fcmp olt double %42, 0xC0E0000FAE147AE1
br i1 %43, label %44, label %50
44: ; preds = %31
%45 = load i32*, i32** %12
store i32 -11, i32* %45
%46 = load i16, i16* @SHRT_MIN
%47 = load i16*, i16** %11
%48 = load i64, i64* %13
%49 = getelementptr inbounds i16, i16* %47, i64 %48
store i16 %46, i16* %49
br label %78
50: ; preds = %31
%51 = load double, double* %14
%52 = fcmp ogt double %51, 0x40DFFFDF5C28F5C3
br i1 %52, label %53, label %59
53: ; preds = %50
%54 = load i32*, i32** %12
store i32 -11, i32* %54
%55 = load i16, i16* @SHRT_MAX
%56 = load i16*, i16** %11
%57 = load i64, i64* %13
%58 = getelementptr inbounds i16, i16* %56, i64 %57
store i16 %55, i16* %58
br label %77
59: ; preds = %50
%60 = load double, double* %14
%61 = fcmp oge double %60, 0.000000e+00
br i1 %61, label %62, label %69
62: ; preds = %59
%63 = load double, double* %14
%64 = fadd double %63, 5.000000e-01
%65 = fptosi double %64 to i16
%66 = load i16*, i16** %11
%67 = load i64, i64* %13
%68 = getelementptr inbounds i16, i16* %66, i64 %67
store i16 %65, i16* %68
br label %76
69: ; preds = %59
%70 = load double, double* %14
%71 = fsub double %70, 5.000000e-01
%72 = fptosi double %71 to i16
%73 = load i16*, i16** %11
%74 = load i64, i64* %13
%75 = getelementptr inbounds i16, i16* %73, i64 %74
store i16 %72, i16* %75
br label %76
76: ; preds = %69, %62
br label %77
77: ; preds = %76, %53
br label %78
78: ; preds = %77, %44
br label %79
79: ; preds = %78
%80 = load i64, i64* %13
%81 = add nsw i64 %80, 1
store i64 %81, i64* %13
br label %27
82: ; preds = %27
br label %83
83: ; preds = %82, %20
%84 = load i32*, i32** %12
%85 = load i32, i32* %84
ret i32 %85
}

LLVM IR (-O2):
@SHRT_MIN = global i16 0
@SHRT_MAX = global i16 0
define i32 @ffi2fi2(i16* %0, i64 %1, double %2, double %3, i16* %4, i32* nocapture %5) {
%7 = fcmp oeq double %2, 1.000000e+00
%8 = fcmp oeq double %3, 0.000000e+00
%9 = and i1 %7, %8
br i1 %9, label %12, label %10
10: ; preds = %6
%11 = icmp sgt i64 %1, 0
br i1 %11, label %15, label %42
12: ; preds = %6
%13 = shl i64 %1, 1
%14 = tail call i32 @memcpy(i16* %4, i16* %0, i64 %13)
br label %42
15: ; preds = %10, %37
%16 = phi i64 [ %40, %37 ], [ 0, %10 ]
%17 = getelementptr inbounds i16, i16* %0, i64 %16
%18 = load i16, i16* %17
%19 = sitofp i16 %18 to double
%20 = fsub double %19, %3
%21 = fdiv double %20, %2
%22 = fcmp olt double %21, 0xC0E0000FAE147AE1
br i1 %22, label %23, label %25
23: ; preds = %15
store i32 -11, i32* %5
%24 = load i16, i16* @SHRT_MIN
br label %37
25: ; preds = %15
%26 = fcmp ogt double %21, 0x40DFFFDF5C28F5C3
br i1 %26, label %27, label %29
27: ; preds = %25
store i32 -11, i32* %5
%28 = load i16, i16* @SHRT_MAX
br label %37
29: ; preds = %25
%30 = fcmp ult double %21, 0.000000e+00
br i1 %30, label %34, label %31
31: ; preds = %29
%32 = fadd double %21, 5.000000e-01
%33 = fptosi double %32 to i16
br label %37
34: ; preds = %29
%35 = fadd double %21, -5.000000e-01
%36 = fptosi double %35 to i16
br label %37
37: ; preds = %23, %31, %34, %27
%38 = phi i16 [ %24, %23 ], [ %33, %31 ], [ %36, %34 ], [ %28, %27 ]
%39 = getelementptr inbounds i16, i16* %4, i64 %16
store i16 %38, i16* %39
%40 = add nuw nsw i64 %16, 1
%41 = icmp eq i64 %40, %1
br i1 %41, label %42, label %15
42: ; preds = %37, %10, %12
%43 = load i32, i32* %5
ret i32 %43
}