#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 */
typedef int uint32_t;
typedef int uint16_t;

/* Variables and functions */
uint16_t make_float16(float value) {
  union fp32 {
    uint32_t u;
    float f;
  };
  const union fp32 f32infty = {255U << 23};
  const union fp32 f16infty = {31U << 23};
  const union fp32 magic = {15U << 23};
  const uint32_t sign_mask = 0x80000000U;
  const uint32_t round_mask = ~0xFFFU;
  union fp32 in;
  uint16_t out = 0;
  in.f = value;
  uint32_t sign = in.u & sign_mask;
  in.u ^= sign;
  if (in.u >= f32infty.u) {
    out = (in.u > f32infty.u) ? 0x7FFFU : 0x7C00U;
  } else {
    in.u &= round_mask;
    in.f *= magic.f;
    in.u -= round_mask;
    if (in.u > f16infty.u) {
      in.u = f16infty.u;
    }
    out = (uint16_t)(in.u >> 13);
  }
  out |= (uint16_t)(sign >> 16);
  return out;
}


x86 assembly (clang, -O0):
<make_float16>:
push   %rbp
mov    %rsp,%rbp
movss  %xmm0,-0x4(%rbp)
mov    0xef1(%rip),%eax
mov    %eax,-0x8(%rbp)
mov    0xeec(%rip),%eax
mov    %eax,-0x10(%rbp)
mov    0xee7(%rip),%eax
mov    %eax,-0x18(%rbp)
movl   $0x80000000,-0x1c(%rbp)
movl   $0xfffff000,-0x20(%rbp)
movl   $0x0,-0x2c(%rbp)
movss  -0x4(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
and    $0x80000000,%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
xor    -0x28(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0x8(%rbp),%eax
jl     1180 <make_float16+0x80>
mov    -0x28(%rbp),%edx
mov    -0x8(%rbp),%esi
mov    $0x7c00,%eax
mov    $0x7fff,%ecx
cmp    %esi,%edx
cmovg  %ecx,%eax
mov    %eax,-0x2c(%rbp)
jmp    11c0 <make_float16+0xc0>
mov    -0x28(%rbp),%eax
and    $0xfffff000,%eax
mov    %eax,-0x28(%rbp)
movss  -0x18(%rbp),%xmm0
mulss  -0x28(%rbp),%xmm0
movss  %xmm0,-0x28(%rbp)
mov    -0x28(%rbp),%eax
sub    $0xfffff000,%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
cmp    -0x10(%rbp),%eax
jle    11b7 <make_float16+0xb7>
mov    -0x10(%rbp),%eax
mov    %eax,-0x28(%rbp)
mov    -0x28(%rbp),%eax
sar    $0xd,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x30(%rbp),%eax
sar    $0x10,%eax
or     -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<make_float16>:
movd   %xmm0,%eax
mov    %eax,%ecx
and    $0x7fffffff,%ecx
cmp    $0x7f800000,%ecx
jb     1123 <make_float16+0x23>
mov    $0x7c00,%edx
mov    $0x7fff,%ecx
cmove  %edx,%ecx
jmp    1152 <make_float16+0x52>
mov    %eax,%ecx
and    $0x7ffff000,%ecx
movd   %ecx,%xmm0
mulss  0xec9(%rip),%xmm0
movd   %xmm0,%ecx
lea    0x1000(%rcx),%edx
sar    $0xd,%edx
cmp    $0xf7ff001,%ecx
mov    $0x7c00,%ecx
cmovl  %edx,%ecx
sar    $0x10,%eax
and    $0xffff8000,%eax
or     %ecx,%eax
ret

LLVM IR (-O0):
%union.fp32 = type { i32 }
@__const.make_float16.f32infty = %union.fp32 { i32 2139095040 }
@__const.make_float16.f16infty = %union.fp32 { i32 260046848 }
@__const.make_float16.magic = %union.fp32 { i32 125829120 }
define i32 @make_float16(float %0) {
%2 = alloca float
%3 = alloca %union.fp32
%4 = alloca %union.fp32
%5 = alloca %union.fp32
%6 = alloca i32
%7 = alloca i32
%8 = alloca %union.fp32
%9 = alloca i32
%10 = alloca i32
store float %0, float* %2
%11 = bitcast %union.fp32* %3 to i8*
%12 = bitcast %union.fp32* %4 to i8*
%13 = bitcast %union.fp32* %5 to i8*
store i32 -2147483648, i32* %6
store i32 -4096, i32* %7
store i32 0, i32* %9
%14 = load float, float* %2
%15 = bitcast %union.fp32* %8 to float*
store float %14, float* %15
%16 = bitcast %union.fp32* %8 to i32*
%17 = load i32, i32* %16
%18 = and i32 %17, -2147483648
store i32 %18, i32* %10
%19 = load i32, i32* %10
%20 = bitcast %union.fp32* %8 to i32*
%21 = load i32, i32* %20
%22 = xor i32 %21, %19
store i32 %22, i32* %20
%23 = bitcast %union.fp32* %8 to i32*
%24 = load i32, i32* %23
%25 = bitcast %union.fp32* %3 to i32*
%26 = load i32, i32* %25
%27 = icmp sge i32 %24, %26
br i1 %27, label %28, label %36
28: ; preds = %1
%29 = bitcast %union.fp32* %8 to i32*
%30 = load i32, i32* %29
%31 = bitcast %union.fp32* %3 to i32*
%32 = load i32, i32* %31
%33 = icmp sgt i32 %30, %32
%34 = zext i1 %33 to i64
%35 = select i1 %33, i32 32767, i32 31744
store i32 %35, i32* %9
br label %61
36: ; preds = %1
%37 = bitcast %union.fp32* %8 to i32*
%38 = load i32, i32* %37
%39 = and i32 %38, -4096
store i32 %39, i32* %37
%40 = bitcast %union.fp32* %5 to float*
%41 = load float, float* %40
%42 = bitcast %union.fp32* %8 to float*
%43 = load float, float* %42
%44 = fmul float %43, %41
store float %44, float* %42
%45 = bitcast %union.fp32* %8 to i32*
%46 = load i32, i32* %45
%47 = sub nsw i32 %46, -4096
store i32 %47, i32* %45
%48 = bitcast %union.fp32* %8 to i32*
%49 = load i32, i32* %48
%50 = bitcast %union.fp32* %4 to i32*
%51 = load i32, i32* %50
%52 = icmp sgt i32 %49, %51
br i1 %52, label %53, label %57
53: ; preds = %36
%54 = bitcast %union.fp32* %4 to i32*
%55 = load i32, i32* %54
%56 = bitcast %union.fp32* %8 to i32*
store i32 %55, i32* %56
br label %57
57: ; preds = %53, %36
%58 = bitcast %union.fp32* %8 to i32*
%59 = load i32, i32* %58
%60 = ashr i32 %59, 13
store i32 %60, i32* %9
br label %61
61: ; preds = %57, %28
%62 = load i32, i32* %10
%63 = ashr i32 %62, 16
%64 = load i32, i32* %9
%65 = or i32 %64, %63
store i32 %65, i32* %9
%66 = load i32, i32* %9
ret i32 %66
}

LLVM IR (-O2):
define i32 @make_float16(float %0) {
%2 = bitcast float %0 to i32
%3 = and i32 %2, 2147483647
%4 = icmp ugt i32 %3, 2139095039
br i1 %4, label %5, label %8
5: ; preds = %1
%6 = icmp eq i32 %3, 2139095040
%7 = select i1 %6, i32 31744, i32 32767
br label %17
8: ; preds = %1
%9 = and i32 %2, 2147479552
%10 = bitcast i32 %9 to float
%11 = fmul float %10, 0x38F0000000000000
%12 = bitcast float %11 to i32
%13 = add nsw i32 %12, 4096
%14 = icmp sgt i32 %12, 260042752
%15 = ashr i32 %13, 13
%16 = select i1 %14, i32 31744, i32 %15
br label %17
17: ; preds = %8, %5
%18 = phi i32 [ %7, %5 ], [ %16, %8 ]
%19 = ashr i32 %2, 16
%20 = and i32 %19, -32768
%21 = or i32 %18, %20
ret i32 %21
}