#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 int32_t;
typedef long int16_t;

/* Variables and functions */
int random();
uint32_t get_one_value(int16_t *dist_table, size_t dist_size, uint32_t mu,
                       uint32_t sigma) {
  long x;
  long t;
  int32_t rnd;
  if (sigma == 0)
    return mu;
  if (dist_table == NULL) {
    return (rnd % (2 * sigma)) - sigma + mu;
  }
  rnd = random();
  t = dist_table[rnd % dist_size];
  x = t * (sigma % 8192);
  if (x >= 0)
    x += 8192 / 2;
  else
    x -= 8192 / 2;
  return x / 8192 + (sigma / 8192) * t + mu;
}


x86 assembly (clang, -O0):
<get_one_value>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %ecx,-0x20(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    113b <get_one_value+0x2b>
mov    -0x1c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1212 <get_one_value+0x102>
cmpq   $0x0,-0x10(%rbp)
jne    1162 <get_one_value+0x52>
mov    -0x34(%rbp),%eax
mov    -0x20(%rbp),%ecx
shl    $0x1,%ecx
cltd
idiv   %ecx
mov    %edx,%eax
sub    -0x20(%rbp),%eax
add    -0x1c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1212 <get_one_value+0x102>
mov    $0x0,%al
call   1030 <random@plt>
mov    %eax,-0x34(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x48(%rbp)
movslq -0x34(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x18(%rbp)
mov    -0x48(%rbp),%rax
mov    (%rax,%rdx,8),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x20(%rbp),%eax
mov    $0x2000,%ecx
cltd
idiv   %ecx
mov    -0x40(%rbp),%rax
movslq %edx,%rcx
imul   %rcx,%rax
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
jl     11cc <get_one_value+0xbc>
mov    -0x28(%rbp),%rax
add    $0x1000,%rax
mov    %rax,-0x28(%rbp)
jmp    11da <get_one_value+0xca>
mov    -0x28(%rbp),%rax
sub    $0x1000,%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
mov    $0x2000,%ecx
cqto
idiv   %rcx
mov    %rax,-0x50(%rbp)
mov    -0x20(%rbp),%eax
mov    $0x2000,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x50(%rbp),%rax
movslq %ecx,%rcx
imul   -0x30(%rbp),%rcx
add    %rcx,%rax
movslq -0x1c(%rbp),%rcx
add    %rcx,%rax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_one_value>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %edx,%r14d
test   %ecx,%ecx
je     11b6 <get_one_value+0xa6>
mov    %ecx,%ebx
mov    %rdi,%r15
test   %rdi,%rdi
je     114f <get_one_value+0x3f>
mov    %rsi,%rbp
xor    %eax,%eax
call   1030 <random@plt>
movslq %eax,%rcx
mov    %rcx,%rdx
or     %rbp,%rdx
shr    $0x20,%rdx
je     1154 <get_one_value+0x44>
mov    %rcx,%rax
xor    %edx,%edx
div    %rbp
jmp    1158 <get_one_value+0x48>
sub    %ebx,%r14d
jmp    11b6 <get_one_value+0xa6>
xor    %edx,%edx
div    %ebp
mov    (%r15,%rdx,8),%rax
lea    0x1fff(%rbx),%ecx
test   %ebx,%ebx
cmovns %ebx,%ecx
mov    %ecx,%edx
and    $0xffffe000,%edx
sub    %edx,%ebx
movslq %ebx,%rdx
imul   %rax,%rdx
mov    %rdx,%rsi
not    %rsi
shr    $0x32,%rsi
and    $0x2000,%esi
lea    (%rsi,%rdx,1),%rdi
add    $0xfffffffffffff000,%rdi
add    %rsi,%rdx
add    $0xfff,%rdx
test   %rdi,%rdi
cmovns %rdi,%rdx
shr    $0xd,%rdx
sar    $0xd,%ecx
imul   %ecx,%eax
add    %eax,%edx
add    %r14d,%edx
mov    %edx,%r14d
mov    %r14d,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @get_one_value(i64* %0, i64 %1, i32 %2, i32 %3) {
%5 = alloca i32
%6 = alloca i64*
%7 = alloca i64
%8 = alloca i32
%9 = alloca i32
%10 = alloca i64
%11 = alloca i64
%12 = alloca i32
store i64* %0, i64** %6
store i64 %1, i64* %7
store i32 %2, i32* %8
store i32 %3, i32* %9
%13 = load i32, i32* %9
%14 = icmp eq i32 %13, 0
br i1 %14, label %15, label %17
15: ; preds = %4
%16 = load i32, i32* %8
store i32 %16, i32* %5
br label %64
17: ; preds = %4
%18 = load i64*, i64** %6
%19 = icmp eq i64* %18, null
br i1 %19, label %20, label %29
20: ; preds = %17
%21 = load i32, i32* %12
%22 = load i32, i32* %9
%23 = mul nsw i32 2, %22
%24 = srem i32 %21, %23
%25 = load i32, i32* %9
%26 = sub nsw i32 %24, %25
%27 = load i32, i32* %8
%28 = add nsw i32 %26, %27
store i32 %28, i32* %5
br label %64
29: ; preds = %17
%30 = call i32 (...) @random()
store i32 %30, i32* %12
%31 = load i64*, i64** %6
%32 = load i32, i32* %12
%33 = sext i32 %32 to i64
%34 = load i64, i64* %7
%35 = urem i64 %33, %34
%36 = getelementptr inbounds i64, i64* %31, i64 %35
%37 = load i64, i64* %36
store i64 %37, i64* %11
%38 = load i64, i64* %11
%39 = load i32, i32* %9
%40 = srem i32 %39, 8192
%41 = sext i32 %40 to i64
%42 = mul nsw i64 %38, %41
store i64 %42, i64* %10
%43 = load i64, i64* %10
%44 = icmp sge i64 %43, 0
br i1 %44, label %45, label %48
45: ; preds = %29
%46 = load i64, i64* %10
%47 = add nsw i64 %46, 4096
store i64 %47, i64* %10
br label %51
48: ; preds = %29
%49 = load i64, i64* %10
%50 = sub nsw i64 %49, 4096
store i64 %50, i64* %10
br label %51
51: ; preds = %48, %45
%52 = load i64, i64* %10
%53 = sdiv i64 %52, 8192
%54 = load i32, i32* %9
%55 = sdiv i32 %54, 8192
%56 = sext i32 %55 to i64
%57 = load i64, i64* %11
%58 = mul nsw i64 %56, %57
%59 = add nsw i64 %53, %58
%60 = load i32, i32* %8
%61 = sext i32 %60 to i64
%62 = add nsw i64 %59, %61
%63 = trunc i64 %62 to i32
store i32 %63, i32* %5
br label %64
64: ; preds = %51, %20, %15
%65 = load i32, i32* %5
ret i32 %65
}

LLVM IR (-O2):
define i32 @get_one_value(i64* %0, i64 %1, i32 %2, i32 %3) {
%5 = icmp eq i32 %3, 0
br i1 %5, label %29, label %6
6: ; preds = %4
%7 = icmp eq i64* %0, null
br i1 %7, label %8, label %10
8: ; preds = %6
%9 = sub i32 %2, %3
br label %29
10: ; preds = %6
%11 = tail call i32 (...) @random()
%12 = sext i32 %11 to i64
%13 = urem i64 %12, %1
%14 = getelementptr inbounds i64, i64* %0, i64 %13
%15 = load i64, i64* %14
%16 = srem i32 %3, 8192
%17 = sext i32 %16 to i64
%18 = mul nsw i64 %15, %17
%19 = icmp sgt i64 %18, -1
%20 = select i1 %19, i64 4096, i64 -4096
%21 = add nsw i64 %20, %18
%22 = sdiv i64 %21, 8192
%23 = sdiv i32 %3, 8192
%24 = zext i32 %23 to i64
%25 = mul i64 %15, %24
%26 = add i64 %22, %25
%27 = trunc i64 %26 to i32
%28 = add i32 %27, %2
br label %29
29: ; preds = %4, %10, %8
%30 = phi i32 [ %9, %8 ], [ %28, %10 ], [ %2, %4 ]
ret i32 %30
}