int ti_dx(int size, double const *const *inputs, double const *options,
          double *const *outputs) {
  const double *high = inputs[0];
  const double *low = inputs[1];
  const double *close = inputs[2];
  const int period = (int)options[0];
  double *output = outputs[0];
  if (period < 1)
    return 1;
  if (size <= ti_dx_start(options))
    return 0;
  const double per = ((double)period - 1) / ((double)period);
  double atr = 0;
  double dmup = 0;
  double dmdown = 0;
  int i;
  for (i = 1; i < period; ++i) {
    double truerange;
    do {
      const double l = low[i];
      const double h = high[i];
      const double c = close[i - 1];
      const double ych = fabs(h - c);
      const double ycl = fabs(l - c);
      double v = h - l;
      if (ych > v)
        v = ych;
      if (ycl > v)
        v = ycl;
      truerange = v;
    } while (0);
    atr += truerange;
    double dp, dm;
    do {
      dp = high[i] - high[i - 1];
      dm = low[i - 1] - low[i];
      if (dp < 0)
        dp = 0;
      else if (dp > dm)
        dm = 0;
      if (dm < 0)
        dm = 0;
      else if (dm > dp)
        dp = 0;
    } while (0);
    dmup += dp;
    dmdown += dm;
  }
  {
    double di_up = dmup / atr;
    double di_down = dmdown / atr;
    double dm_diff = fabs(di_up - di_down);
    double dm_sum = di_up + di_down;
    double dx = dm_diff / dm_sum * 100;
    *output++ = dx;
  }
  for (i = period; i < size; ++i) {
    double truerange;
    do {
      const double l = low[i];
      const double h = high[i];
      const double c = close[i - 1];
      const double ych = fabs(h - c);
      const double ycl = fabs(l - c);
      double v = h - l;
      if (ych > v)
        v = ych;
      if (ycl > v)
        v = ycl;
      truerange = v;
    } while (0);
    atr = atr * per + truerange;
    double dp, dm;
    do {
      dp = high[i] - high[i - 1];
      dm = low[i - 1] - low[i];
      if (dp < 0)
        dp = 0;
      else if (dp > dm)
        dm = 0;
      if (dm < 0)
        dm = 0;
      else if (dm > dp)
        dp = 0;
    } while (0);
    dmup = dmup * per + dp;
    dmdown = dmdown * per + dm;
    double di_up = dmup / atr;
    double di_down = dmdown / atr;
    double dm_diff = fabs(di_up - di_down);
    double dm_sum = di_up + di_down;
    double dx = dm_diff / dm_sum * 100;
    *output++ = dx;
  }
  assert(output - outputs[0] == size - ti_dx_start(options));
  return 0;
}


x86 assembly (clang, -O0):
<ti_dx>:
push   %rbp
mov    %rsp,%rbp
sub    $0x170,%rsp
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rax
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rax
mov    %rax,-0x38(%rbp)
mov    -0x18(%rbp),%rax
cvttsd2si (%rax),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x48(%rbp)
cmpl   $0x1,-0x3c(%rbp)
jge    1189 <ti_dx+0x69>
movl   $0x1,-0x4(%rbp)
jmp    1813 <ti_dx+0x6f3>
mov    -0x8(%rbp),%eax
mov    %eax,-0x154(%rbp)
mov    -0x18(%rbp),%rdi
mov    $0x0,%al
call   1040 <ti_dx_start@plt>
mov    %eax,%ecx
mov    -0x154(%rbp),%eax
cmp    %ecx,%eax
jg     11b9 <ti_dx+0x99>
movl   $0x0,-0x4(%rbp)
jmp    1813 <ti_dx+0x6f3>
cvtsi2sdl -0x3c(%rbp),%xmm0
movsd  0xe3a(%rip),%xmm1
subsd  %xmm1,%xmm0
cvtsi2sdl -0x3c(%rbp),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x58(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x60(%rbp)
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x68(%rbp)
movl   $0x1,-0x6c(%rbp)
mov    -0x6c(%rbp),%eax
cmp    -0x3c(%rbp),%eax
jge    141c <ti_dx+0x2fc>
jmp    1208 <ti_dx+0xe8>
mov    -0x30(%rbp),%rax
movslq -0x6c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x80(%rbp)
mov    -0x28(%rbp),%rax
movslq -0x6c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x88(%rbp)
ff
mov    -0x38(%rbp),%rax
mov    -0x6c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x90(%rbp)
ff
movsd  -0x88(%rbp),%xmm0
ff
subsd  -0x90(%rbp),%xmm0
ff
movaps 0xdb0(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x98(%rbp)
ff
movsd  -0x80(%rbp),%xmm0
subsd  -0x90(%rbp),%xmm0
ff
movaps 0xd90(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0xa0(%rbp)
ff
movsd  -0x88(%rbp),%xmm0
ff
subsd  -0x80(%rbp),%xmm0
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0x98(%rbp),%xmm0
ff
ucomisd -0xa8(%rbp),%xmm0
ff
jbe    12c7 <ti_dx+0x1a7>
movsd  -0x98(%rbp),%xmm0
ff
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0xa0(%rbp),%xmm0
ff
ucomisd -0xa8(%rbp),%xmm0
ff
jbe    12ed <ti_dx+0x1cd>
movsd  -0xa0(%rbp),%xmm0
ff
movsd  %xmm0,-0xa8(%rbp)
ff
movsd  -0xa8(%rbp),%xmm0
ff
movsd  %xmm0,-0x78(%rbp)
movsd  -0x78(%rbp),%xmm0
addsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x28(%rbp),%rax
movslq -0x6c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x6c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
mov    -0x30(%rbp),%rax
mov    -0x6c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x6c(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
xorps  %xmm0,%xmm0
ucomisd -0xb0(%rbp),%xmm0
ff
jbe    1378 <ti_dx+0x258>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
jmp    139e <ti_dx+0x27e>
movsd  -0xb0(%rbp),%xmm0
ff
ucomisd -0xb8(%rbp),%xmm0
ff
jbe    1399 <ti_dx+0x279>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
jmp    139e <ti_dx+0x27e>
xorps  %xmm0,%xmm0
ucomisd -0xb8(%rbp),%xmm0
ff
jbe    13bf <ti_dx+0x29f>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0xb8(%rbp)
ff
jmp    13e5 <ti_dx+0x2c5>
movsd  -0xb8(%rbp),%xmm0
ff
ucomisd -0xb0(%rbp),%xmm0
ff
jbe    13e0 <ti_dx+0x2c0>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0xb0(%rbp)
ff
jmp    13e5 <ti_dx+0x2c5>
jmp    13ea <ti_dx+0x2ca>
movsd  -0xb0(%rbp),%xmm0
ff
addsd  -0x60(%rbp),%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0xb8(%rbp),%xmm0
ff
addsd  -0x68(%rbp),%xmm0
movsd  %xmm0,-0x68(%rbp)
mov    -0x6c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x6c(%rbp)
jmp    11f7 <ti_dx+0xd7>
movsd  -0x60(%rbp),%xmm0
divsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0xc0(%rbp)
ff
movsd  -0x68(%rbp),%xmm0
divsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0xc8(%rbp)
ff
movsd  -0xc0(%rbp),%xmm0
ff
subsd  -0xc8(%rbp),%xmm0
ff
movaps 0xbb9(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0xd0(%rbp)
ff
movsd  -0xc0(%rbp),%xmm0
ff
addsd  -0xc8(%rbp),%xmm0
ff
movsd  %xmm0,-0xd8(%rbp)
ff
movsd  -0xd0(%rbp),%xmm0
ff
divsd  -0xd8(%rbp),%xmm0
ff
movsd  0xb75(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0xe0(%rbp)
ff
movsd  -0xe0(%rbp),%xmm0
ff
mov    -0x48(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x48(%rbp)
movsd  %xmm0,(%rax)
mov    -0x3c(%rbp),%eax
mov    %eax,-0x6c(%rbp)
mov    -0x6c(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    17b9 <ti_dx+0x699>
jmp    14d1 <ti_dx+0x3b1>
mov    -0x30(%rbp),%rax
movslq -0x6c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xf0(%rbp)
ff
mov    -0x28(%rbp),%rax
movslq -0x6c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0xf8(%rbp)
ff
mov    -0x38(%rbp),%rax
mov    -0x6c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x100(%rbp)
ff
movsd  -0xf8(%rbp),%xmm0
ff
subsd  -0x100(%rbp),%xmm0
ff
movaps 0xae4(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x108(%rbp)
ff
movsd  -0xf0(%rbp),%xmm0
ff
subsd  -0x100(%rbp),%xmm0
ff
movaps 0xac1(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x110(%rbp)
ff
movsd  -0xf8(%rbp),%xmm0
ff
subsd  -0xf0(%rbp),%xmm0
ff
movsd  %xmm0,-0x118(%rbp)
ff
movsd  -0x108(%rbp),%xmm0
ff
ucomisd -0x118(%rbp),%xmm0
ff
jbe    1599 <ti_dx+0x479>
movsd  -0x108(%rbp),%xmm0
ff
movsd  %xmm0,-0x118(%rbp)
ff
movsd  -0x110(%rbp),%xmm0
ff
ucomisd -0x118(%rbp),%xmm0
ff
jbe    15bf <ti_dx+0x49f>
movsd  -0x110(%rbp),%xmm0
ff
movsd  %xmm0,-0x118(%rbp)
ff
movsd  -0x118(%rbp),%xmm0
ff
movsd  %xmm0,-0xe8(%rbp)
ff
movsd  -0x58(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0xe8(%rbp),%xmm1
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
mov    -0x28(%rbp),%rax
movslq -0x6c(%rbp),%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x28(%rbp),%rax
mov    -0x6c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x120(%rbp)
ff
mov    -0x30(%rbp),%rax
mov    -0x6c(%rbp),%ecx
sub    $0x1,%ecx
movslq %ecx,%rcx
movsd  (%rax,%rcx,8),%xmm0
mov    -0x30(%rbp),%rax
movslq -0x6c(%rbp),%rcx
subsd  (%rax,%rcx,8),%xmm0
movsd  %xmm0,-0x128(%rbp)
ff
xorps  %xmm0,%xmm0
ucomisd -0x120(%rbp),%xmm0
ff
jbe    165d <ti_dx+0x53d>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x120(%rbp)
ff
jmp    1683 <ti_dx+0x563>
movsd  -0x120(%rbp),%xmm0
ff
ucomisd -0x128(%rbp),%xmm0
ff
jbe    167e <ti_dx+0x55e>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x128(%rbp)
ff
jmp    1683 <ti_dx+0x563>
xorps  %xmm0,%xmm0
ucomisd -0x128(%rbp),%xmm0
ff
jbe    16a4 <ti_dx+0x584>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x128(%rbp)
ff
jmp    16ca <ti_dx+0x5aa>
movsd  -0x128(%rbp),%xmm0
ff
ucomisd -0x120(%rbp),%xmm0
ff
jbe    16c5 <ti_dx+0x5a5>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x120(%rbp)
ff
jmp    16ca <ti_dx+0x5aa>
jmp    16cf <ti_dx+0x5af>
movsd  -0x60(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x120(%rbp),%xmm1
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x60(%rbp)
movsd  -0x68(%rbp),%xmm0
movsd  -0x50(%rbp),%xmm2
movsd  -0x128(%rbp),%xmm1
ff
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x68(%rbp)
movsd  -0x60(%rbp),%xmm0
divsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x130(%rbp)
ff
movsd  -0x68(%rbp),%xmm0
divsd  -0x58(%rbp),%xmm0
movsd  %xmm0,-0x138(%rbp)
ff
movsd  -0x130(%rbp),%xmm0
ff
subsd  -0x138(%rbp),%xmm0
ff
movaps 0x8c8(%rip),%xmm1
pand   %xmm1,%xmm0
movsd  %xmm0,-0x140(%rbp)
ff
movsd  -0x130(%rbp),%xmm0
ff
addsd  -0x138(%rbp),%xmm0
ff
movsd  %xmm0,-0x148(%rbp)
ff
movsd  -0x140(%rbp),%xmm0
ff
divsd  -0x148(%rbp),%xmm0
ff
movsd  0x884(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x150(%rbp)
ff
movsd  -0x150(%rbp),%xmm0
ff
mov    -0x48(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x48(%rbp)
movsd  %xmm0,(%rax)
mov    -0x6c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x6c(%rbp)
jmp    14c0 <ti_dx+0x3a0>
mov    -0x48(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rcx),%rcx
sub    %rcx,%rax
sar    $0x3,%rax
mov    %rax,-0x160(%rbp)
mov    -0x8(%rbp),%eax
mov    %eax,-0x164(%rbp)
mov    -0x18(%rbp),%rdi
mov    $0x0,%al
call   1040 <ti_dx_start@plt>
mov    -0x164(%rbp),%ecx
mov    %eax,%edx
mov    -0x160(%rbp),%rax
sub    %edx,%ecx
movslq %ecx,%rcx
cmp    %rcx,%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <assert@plt>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x170,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ti_dx>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
cvttsd2si (%rdx),%eax
test   %eax,%eax
jle    1275 <ti_dx+0x155>
mov    %edi,%ebx
mov    %eax,0x4(%rsp)
mov    (%rsi),%r15
mov    0x8(%rsi),%r12
mov    0x10(%rsi),%r14
mov    %rcx,0x8(%rsp)
mov    (%rcx),%r13
xor    %ebp,%ebp
mov    %rdx,0x10(%rsp)
mov    %rdx,%rdi
xor    %eax,%eax
mov    %ebx,(%rsp)
call   1040 <ti_dx_start@plt>
mov    (%rsp),%edx
cmp    %edx,%eax
jge    143d <ti_dx+0x31d>
xorpd  %xmm0,%xmm0
xorpd  %xmm1,%xmm1
xorpd  %xmm2,%xmm2
mov    0x4(%rsp),%esi
cmp    $0x2,%esi
jb     127f <ti_dx+0x15f>
mov    %esi,%eax
movsd  (%r15),%xmm11
movsd  (%r12),%xmm10
add    $0xffffffffffffffff,%rax
xorpd  %xmm8,%xmm8
xor    %ecx,%ecx
movapd 0xe64(%rip),%xmm9
xorpd  %xmm2,%xmm2
xorpd  %xmm1,%xmm1
xorpd  %xmm0,%xmm0
jmp    120d <ti_dx+0xed>
nopw   0x0(%rax,%rax,1)
movapd %xmm4,%xmm6
addsd  %xmm6,%xmm0
addsd  %xmm7,%xmm1
movsd  (%r14,%rcx,8),%xmm3
movapd %xmm11,%xmm4
subsd  %xmm3,%xmm4
andpd  %xmm9,%xmm4
movapd %xmm10,%xmm5
subsd  %xmm3,%xmm5
andpd  %xmm9,%xmm5
movapd %xmm11,%xmm3
subsd  %xmm10,%xmm3
maxsd  %xmm3,%xmm4
maxsd  %xmm4,%xmm5
addsd  %xmm5,%xmm2
add    $0x1,%rcx
cmp    %rcx,%rax
je     127f <ti_dx+0x15f>
movapd %xmm11,%xmm4
movapd %xmm10,%xmm3
movsd  0x8(%r12,%rcx,8),%xmm10
movsd  0x8(%r15,%rcx,8),%xmm11
movapd %xmm11,%xmm7
subsd  %xmm4,%xmm7
subsd  %xmm10,%xmm3
ucomisd %xmm7,%xmm8
xorpd  %xmm5,%xmm5
ja     124c <ti_dx+0x12c>
xorpd  %xmm4,%xmm4
ucomisd %xmm3,%xmm7
movapd %xmm7,%xmm5
ja     1262 <ti_dx+0x142>
xorpd  %xmm6,%xmm6
ucomisd %xmm3,%xmm6
movapd %xmm5,%xmm7
movapd %xmm3,%xmm4
ja     11c4 <ti_dx+0xa4>
ucomisd %xmm7,%xmm4
jbe    11c0 <ti_dx+0xa0>
xorpd  %xmm7,%xmm7
jmp    11c0 <ti_dx+0xa0>
mov    $0x1,%ebp
jmp    143d <ti_dx+0x31d>
movapd %xmm1,%xmm3
divsd  %xmm2,%xmm3
movapd %xmm0,%xmm4
divsd  %xmm2,%xmm4
movapd %xmm3,%xmm5
subsd  %xmm4,%xmm5
andpd  0xd71(%rip),%xmm5
addsd  %xmm3,%xmm4
divsd  %xmm4,%xmm5
mulsd  0xd59(%rip),%xmm5
movsd  %xmm5,0x0(%r13)
add    $0x8,%r13
cmp    %edx,%esi
jge    140b <ti_dx+0x2eb>
xorps  %xmm3,%xmm3
cvtsi2sd %esi,%xmm3
movsd  0xd2f(%rip),%xmm11
addsd  %xmm3,%xmm11
divsd  %xmm3,%xmm11
movslq %esi,%rdi
movslq %edx,%rax
lea    (%r12,%rdi,8),%rcx
lea    (%r15,%rdi,8),%rdx
lea    (%r14,%rdi,8),%rsi
add    $0xfffffffffffffff8,%rsi
sub    %rdi,%rax
xor    %edi,%edi
movapd 0xd11(%rip),%xmm10
movapd 0xd08(%rip),%xmm8
movsd  0xcf7(%rip),%xmm9
jmp    13a3 <ti_dx+0x283>
cs nopw 0x0(%rax,%rax,1)
movapd %xmm12,%xmm13
movsd  (%rsi,%rdi,1),%xmm3
movapd %xmm6,%xmm4
subsd  %xmm3,%xmm4
andpd  %xmm10,%xmm4
subsd  %xmm7,%xmm6
subsd  %xmm3,%xmm7
andpd  %xmm10,%xmm7
maxsd  %xmm6,%xmm4
maxsd  %xmm4,%xmm7
mulsd  %xmm11,%xmm2
addsd  %xmm7,%xmm2
mulsd  %xmm11,%xmm1
addsd  %xmm5,%xmm1
mulsd  %xmm11,%xmm0
addsd  %xmm13,%xmm0
movapd %xmm1,%xmm3
divsd  %xmm2,%xmm3
movapd %xmm0,%xmm4
divsd  %xmm2,%xmm4
movapd %xmm3,%xmm5
subsd  %xmm4,%xmm5
andpd  %xmm8,%xmm5
addsd  %xmm3,%xmm4
divsd  %xmm4,%xmm5
mulsd  %xmm9,%xmm5
movsd  %xmm5,0x0(%r13,%rdi,1)
add    $0x8,%rdi
add    $0xffffffffffffffff,%rax
je     1408 <ti_dx+0x2e8>
movsd  -0x8(%rcx,%rdi,1),%xmm3
movsd  (%rcx,%rdi,1),%xmm7
movsd  (%rdx,%rdi,1),%xmm6
movapd %xmm6,%xmm5
subsd  -0x8(%rdx,%rdi,1),%xmm5
subsd  %xmm7,%xmm3
xorpd  %xmm13,%xmm13
ucomisd %xmm5,%xmm13
xorpd  %xmm4,%xmm4
ja     13e0 <ti_dx+0x2c0>
xorpd  %xmm12,%xmm12
ucomisd %xmm3,%xmm5
movapd %xmm5,%xmm4
ja     13f4 <ti_dx+0x2d4>
ucomisd %xmm3,%xmm13
movapd %xmm3,%xmm12
movapd %xmm4,%xmm5
ja     1325 <ti_dx+0x205>
ucomisd %xmm5,%xmm12
jbe    1320 <ti_dx+0x200>
xorpd  %xmm5,%xmm5
jmp    1320 <ti_dx+0x200>
add    %rdi,%r13
mov    0x8(%rsp),%rax
sub    (%rax),%r13
sar    $0x3,%r13
xor    %ebp,%ebp
mov    0x10(%rsp),%rdi
xor    %eax,%eax
call   1040 <ti_dx_start@plt>
mov    (%rsp),%ecx
sub    %eax,%ecx
movslq %ecx,%rax
xor    %edi,%edi
cmp    %rax,%r13
sete   %dil
xor    %eax,%eax
call   1030 <assert@plt>
mov    %ebp,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @ti_dx(i32 %0, double** %1, double* %2, double** %3) {
%5 = alloca i32
%6 = alloca i32
%7 = alloca double**
%8 = alloca double*
%9 = alloca double**
%10 = alloca double*
%11 = alloca double*
%12 = alloca double*
%13 = alloca i32
%14 = alloca double*
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca i32
%20 = alloca double
%21 = alloca double
%22 = alloca double
%23 = alloca double
%24 = alloca double
%25 = alloca double
%26 = alloca double
%27 = alloca double
%28 = alloca double
%29 = alloca double
%30 = alloca double
%31 = alloca double
%32 = alloca double
%33 = alloca double
%34 = alloca double
%35 = alloca double
%36 = alloca double
%37 = alloca double
%38 = alloca double
%39 = alloca double
%40 = alloca double
%41 = alloca double
%42 = alloca double
%43 = alloca double
%44 = alloca double
%45 = alloca double
%46 = alloca double
%47 = alloca double
store i32 %0, i32* %6
store double** %1, double*** %7
store double* %2, double** %8
store double** %3, double*** %9
%48 = load double**, double*** %7
%49 = getelementptr inbounds double*, double** %48, i64 0
%50 = load double*, double** %49
store double* %50, double** %10
%51 = load double**, double*** %7
%52 = getelementptr inbounds double*, double** %51, i64 1
%53 = load double*, double** %52
store double* %53, double** %11
%54 = load double**, double*** %7
%55 = getelementptr inbounds double*, double** %54, i64 2
%56 = load double*, double** %55
store double* %56, double** %12
%57 = load double*, double** %8
%58 = getelementptr inbounds double, double* %57, i64 0
%59 = load double, double* %58
%60 = fptosi double %59 to i32
store i32 %60, i32* %13
%61 = load double**, double*** %9
%62 = getelementptr inbounds double*, double** %61, i64 0
%63 = load double*, double** %62
store double* %63, double** %14
%64 = load i32, i32* %13
%65 = icmp slt i32 %64, 1
br i1 %65, label %66, label %67
66: ; preds = %4
store i32 1, i32* %5
br label %352
67: ; preds = %4
%68 = load i32, i32* %6
%69 = load double*, double** %8
%70 = call i32 (double*, ...) bitcast (i32 (...)* @ti_dx_start to i32 (double*, ...)*)(double* %69)
%71 = icmp sle i32 %68, %70
br i1 %71, label %72, label %73
72: ; preds = %67
store i32 0, i32* %5
br label %352
73: ; preds = %67
%74 = load i32, i32* %13
%75 = sitofp i32 %74 to double
%76 = fsub double %75, 1.000000e+00
%77 = load i32, i32* %13
%78 = sitofp i32 %77 to double
%79 = fdiv double %76, %78
store double %79, double* %15
store double 0.000000e+00, double* %16
store double 0.000000e+00, double* %17
store double 0.000000e+00, double* %18
store i32 1, i32* %19
br label %80
80: ; preds = %182, %73
%81 = load i32, i32* %19
%82 = load i32, i32* %13
%83 = icmp slt i32 %81, %82
br i1 %83, label %84, label %185
84: ; preds = %80
br label %85
85: ; preds = %84
%86 = load double*, double** %11
%87 = load i32, i32* %19
%88 = sext i32 %87 to i64
%89 = getelementptr inbounds double, double* %86, i64 %88
%90 = load double, double* %89
store double %90, double* %21
%91 = load double*, double** %10
%92 = load i32, i32* %19
%93 = sext i32 %92 to i64
%94 = getelementptr inbounds double, double* %91, i64 %93
%95 = load double, double* %94
store double %95, double* %22
%96 = load double*, double** %12
%97 = load i32, i32* %19
%98 = sub nsw i32 %97, 1
%99 = sext i32 %98 to i64
%100 = getelementptr inbounds double, double* %96, i64 %99
%101 = load double, double* %100
store double %101, double* %23
%102 = load double, double* %22
%103 = load double, double* %23
%104 = fsub double %102, %103
%105 = call double @llvm.fabs.f64(double %104)
store double %105, double* %24
%106 = load double, double* %21
%107 = load double, double* %23
%108 = fsub double %106, %107
%109 = call double @llvm.fabs.f64(double %108)
store double %109, double* %25
%110 = load double, double* %22
%111 = load double, double* %21
%112 = fsub double %110, %111
store double %112, double* %26
%113 = load double, double* %24
%114 = load double, double* %26
%115 = fcmp ogt double %113, %114
br i1 %115, label %116, label %118
116: ; preds = %85
%117 = load double, double* %24
store double %117, double* %26
br label %118
118: ; preds = %116, %85
%119 = load double, double* %25
%120 = load double, double* %26
%121 = fcmp ogt double %119, %120
br i1 %121, label %122, label %124
122: ; preds = %118
%123 = load double, double* %25
store double %123, double* %26
br label %124
124: ; preds = %122, %118
%125 = load double, double* %26
store double %125, double* %20
br label %126
126: ; preds = %124
%127 = load double, double* %20
%128 = load double, double* %16
%129 = fadd double %128, %127
store double %129, double* %16
br label %130
130: ; preds = %126
%131 = load double*, double** %10
%132 = load i32, i32* %19
%133 = sext i32 %132 to i64
%134 = getelementptr inbounds double, double* %131, i64 %133
%135 = load double, double* %134
%136 = load double*, double** %10
%137 = load i32, i32* %19
%138 = sub nsw i32 %137, 1
%139 = sext i32 %138 to i64
%140 = getelementptr inbounds double, double* %136, i64 %139
%141 = load double, double* %140
%142 = fsub double %135, %141
store double %142, double* %27
%143 = load double*, double** %11
%144 = load i32, i32* %19
%145 = sub nsw i32 %144, 1
%146 = sext i32 %145 to i64
%147 = getelementptr inbounds double, double* %143, i64 %146
%148 = load double, double* %147
%149 = load double*, double** %11
%150 = load i32, i32* %19
%151 = sext i32 %150 to i64
%152 = getelementptr inbounds double, double* %149, i64 %151
%153 = load double, double* %152
%154 = fsub double %148, %153
store double %154, double* %28
%155 = load double, double* %27
%156 = fcmp olt double %155, 0.000000e+00
br i1 %156, label %157, label %158
157: ; preds = %130
store double 0.000000e+00, double* %27
br label %164
158: ; preds = %130
%159 = load double, double* %27
%160 = load double, double* %28
%161 = fcmp ogt double %159, %160
br i1 %161, label %162, label %163
162: ; preds = %158
store double 0.000000e+00, double* %28
br label %163
163: ; preds = %162, %158
br label %164
164: ; preds = %163, %157
%165 = load double, double* %28
%166 = fcmp olt double %165, 0.000000e+00
br i1 %166, label %167, label %168
167: ; preds = %164
store double 0.000000e+00, double* %28
br label %174
168: ; preds = %164
%169 = load double, double* %28
%170 = load double, double* %27
%171 = fcmp ogt double %169, %170
br i1 %171, label %172, label %173
172: ; preds = %168
store double 0.000000e+00, double* %27
br label %173
173: ; preds = %172, %168
br label %174
174: ; preds = %173, %167
br label %175
175: ; preds = %174
%176 = load double, double* %27
%177 = load double, double* %17
%178 = fadd double %177, %176
store double %178, double* %17
%179 = load double, double* %28
%180 = load double, double* %18
%181 = fadd double %180, %179
store double %181, double* %18
br label %182
182: ; preds = %175
%183 = load i32, i32* %19
%184 = add nsw i32 %183, 1
store i32 %184, i32* %19
br label %80
185: ; preds = %80
%186 = load double, double* %17
%187 = load double, double* %16
%188 = fdiv double %186, %187
store double %188, double* %29
%189 = load double, double* %18
%190 = load double, double* %16
%191 = fdiv double %189, %190
store double %191, double* %30
%192 = load double, double* %29
%193 = load double, double* %30
%194 = fsub double %192, %193
%195 = call double @llvm.fabs.f64(double %194)
store double %195, double* %31
%196 = load double, double* %29
%197 = load double, double* %30
%198 = fadd double %196, %197
store double %198, double* %32
%199 = load double, double* %31
%200 = load double, double* %32
%201 = fdiv double %199, %200
%202 = fmul double %201, 1.000000e+02
store double %202, double* %33
%203 = load double, double* %33
%204 = load double*, double** %14
%205 = getelementptr inbounds double, double* %204, i32 1
store double* %205, double** %14
store double %203, double* %204
%206 = load i32, i32* %13
store i32 %206, i32* %19
br label %207
207: ; preds = %332, %185
%208 = load i32, i32* %19
%209 = load i32, i32* %6
%210 = icmp slt i32 %208, %209
br i1 %210, label %211, label %335
211: ; preds = %207
br label %212
212: ; preds = %211
%213 = load double*, double** %11
%214 = load i32, i32* %19
%215 = sext i32 %214 to i64
%216 = getelementptr inbounds double, double* %213, i64 %215
%217 = load double, double* %216
store double %217, double* %35
%218 = load double*, double** %10
%219 = load i32, i32* %19
%220 = sext i32 %219 to i64
%221 = getelementptr inbounds double, double* %218, i64 %220
%222 = load double, double* %221
store double %222, double* %36
%223 = load double*, double** %12
%224 = load i32, i32* %19
%225 = sub nsw i32 %224, 1
%226 = sext i32 %225 to i64
%227 = getelementptr inbounds double, double* %223, i64 %226
%228 = load double, double* %227
store double %228, double* %37
%229 = load double, double* %36
%230 = load double, double* %37
%231 = fsub double %229, %230
%232 = call double @llvm.fabs.f64(double %231)
store double %232, double* %38
%233 = load double, double* %35
%234 = load double, double* %37
%235 = fsub double %233, %234
%236 = call double @llvm.fabs.f64(double %235)
store double %236, double* %39
%237 = load double, double* %36
%238 = load double, double* %35
%239 = fsub double %237, %238
store double %239, double* %40
%240 = load double, double* %38
%241 = load double, double* %40
%242 = fcmp ogt double %240, %241
br i1 %242, label %243, label %245
243: ; preds = %212
%244 = load double, double* %38
store double %244, double* %40
br label %245
245: ; preds = %243, %212
%246 = load double, double* %39
%247 = load double, double* %40
%248 = fcmp ogt double %246, %247
br i1 %248, label %249, label %251
249: ; preds = %245
%250 = load double, double* %39
store double %250, double* %40
br label %251
251: ; preds = %249, %245
%252 = load double, double* %40
store double %252, double* %34
br label %253
253: ; preds = %251
%254 = load double, double* %16
%255 = load double, double* %15
%256 = load double, double* %34
%257 = call double @llvm.fmuladd.f64(double %254, double %255, double %256)
store double %257, double* %16
br label %258
258: ; preds = %253
%259 = load double*, double** %10
%260 = load i32, i32* %19
%261 = sext i32 %260 to i64
%262 = getelementptr inbounds double, double* %259, i64 %261
%263 = load double, double* %262
%264 = load double*, double** %10
%265 = load i32, i32* %19
%266 = sub nsw i32 %265, 1
%267 = sext i32 %266 to i64
%268 = getelementptr inbounds double, double* %264, i64 %267
%269 = load double, double* %268
%270 = fsub double %263, %269
store double %270, double* %41
%271 = load double*, double** %11
%272 = load i32, i32* %19
%273 = sub nsw i32 %272, 1
%274 = sext i32 %273 to i64
%275 = getelementptr inbounds double, double* %271, i64 %274
%276 = load double, double* %275
%277 = load double*, double** %11
%278 = load i32, i32* %19
%279 = sext i32 %278 to i64
%280 = getelementptr inbounds double, double* %277, i64 %279
%281 = load double, double* %280
%282 = fsub double %276, %281
store double %282, double* %42
%283 = load double, double* %41
%284 = fcmp olt double %283, 0.000000e+00
br i1 %284, label %285, label %286
285: ; preds = %258
store double 0.000000e+00, double* %41
br label %292
286: ; preds = %258
%287 = load double, double* %41
%288 = load double, double* %42
%289 = fcmp ogt double %287, %288
br i1 %289, label %290, label %291
290: ; preds = %286
store double 0.000000e+00, double* %42
br label %291
291: ; preds = %290, %286
br label %292
292: ; preds = %291, %285
%293 = load double, double* %42
%294 = fcmp olt double %293, 0.000000e+00
br i1 %294, label %295, label %296
295: ; preds = %292
store double 0.000000e+00, double* %42
br label %302
296: ; preds = %292
%297 = load double, double* %42
%298 = load double, double* %41
%299 = fcmp ogt double %297, %298
br i1 %299, label %300, label %301
300: ; preds = %296
store double 0.000000e+00, double* %41
br label %301
301: ; preds = %300, %296
br label %302
302: ; preds = %301, %295
br label %303
303: ; preds = %302
%304 = load double, double* %17
%305 = load double, double* %15
%306 = load double, double* %41
%307 = call double @llvm.fmuladd.f64(double %304, double %305, double %306)
store double %307, double* %17
%308 = load double, double* %18
%309 = load double, double* %15
%310 = load double, double* %42
%311 = call double @llvm.fmuladd.f64(double %308, double %309, double %310)
store double %311, double* %18
%312 = load double, double* %17
%313 = load double, double* %16
%314 = fdiv double %312, %313
store double %314, double* %43
%315 = load double, double* %18
%316 = load double, double* %16
%317 = fdiv double %315, %316
store double %317, double* %44
%318 = load double, double* %43
%319 = load double, double* %44
%320 = fsub double %318, %319
%321 = call double @llvm.fabs.f64(double %320)
store double %321, double* %45
%322 = load double, double* %43
%323 = load double, double* %44
%324 = fadd double %322, %323
store double %324, double* %46
%325 = load double, double* %45
%326 = load double, double* %46
%327 = fdiv double %325, %326
%328 = fmul double %327, 1.000000e+02
store double %328, double* %47
%329 = load double, double* %47
%330 = load double*, double** %14
%331 = getelementptr inbounds double, double* %330, i32 1
store double* %331, double** %14
store double %329, double* %330
br label %332
332: ; preds = %303
%333 = load i32, i32* %19
%334 = add nsw i32 %333, 1
store i32 %334, i32* %19
br label %207
335: ; preds = %207
%336 = load double*, double** %14
%337 = load double**, double*** %9
%338 = getelementptr inbounds double*, double** %337, i64 0
%339 = load double*, double** %338
%340 = ptrtoint double* %336 to i64
%341 = ptrtoint double* %339 to i64
%342 = sub i64 %340, %341
%343 = sdiv exact i64 %342, 8
%344 = load i32, i32* %6
%345 = load double*, double** %8
%346 = call i32 (double*, ...) bitcast (i32 (...)* @ti_dx_start to i32 (double*, ...)*)(double* %345)
%347 = sub nsw i32 %344, %346
%348 = sext i32 %347 to i64
%349 = icmp eq i64 %343, %348
%350 = zext i1 %349 to i32
%351 = call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %350)
store i32 0, i32* %5
br label %352
352: ; preds = %335, %72, %66
%353 = load i32, i32* %5
ret i32 %353
}

LLVM IR (-O2):
define i32 @ti_dx(i32 %0, double** nocapture %1, double* %2, double** nocapture %3) {
%5 = load double*, double** %1
%6 = getelementptr inbounds double*, double** %1, i64 1
%7 = load double*, double** %6
%8 = getelementptr inbounds double*, double** %1, i64 2
%9 = load double*, double** %8
%10 = load double, double* %2
%11 = fptosi double %10 to i32
%12 = load double*, double** %3
%13 = icmp slt i32 %11, 1
br i1 %13, label %154, label %14
14: ; preds = %4
%15 = tail call i32 (double*, ...) bitcast (i32 (...)* @ti_dx_start to i32 (double*, ...)*)(double* %2)
%16 = icmp slt i32 %15, %0
br i1 %16, label %17, label %154
17: ; preds = %14
%18 = sitofp i32 %11 to double
%19 = fadd double %18, -1.000000e+00
%20 = fdiv double %19, %18
%21 = icmp ugt i32 %11, 1
br i1 %21, label %22, label %70
22: ; preds = %17
%23 = zext i32 %11 to i64
%24 = load double, double* %5
%25 = load double, double* %7
br label %26
26: ; preds = %22, %63
%27 = phi double [ %25, %22 ], [ %34, %63 ]
%28 = phi double [ %24, %22 ], [ %36, %63 ]
%29 = phi i64 [ 1, %22 ], [ %68, %63 ]
%30 = phi double [ 0.000000e+00, %22 ], [ %49, %63 ]
%31 = phi double [ 0.000000e+00, %22 ], [ %66, %63 ]
%32 = phi double [ 0.000000e+00, %22 ], [ %67, %63 ]
%33 = getelementptr inbounds double, double* %7, i64 %29
%34 = load double, double* %33
%35 = getelementptr inbounds double, double* %5, i64 %29
%36 = load double, double* %35
%37 = add nsw i64 %29, -1
%38 = getelementptr inbounds double, double* %9, i64 %37
%39 = load double, double* %38
%40 = fsub double %36, %39
%41 = tail call double @llvm.fabs.f64(double %40)
%42 = fsub double %34, %39
%43 = tail call double @llvm.fabs.f64(double %42)
%44 = fsub double %36, %34
%45 = fcmp ogt double %41, %44
%46 = select i1 %45, double %41, double %44
%47 = fcmp ogt double %43, %46
%48 = select i1 %47, double %43, double %46
%49 = fadd double %30, %48
%50 = fsub double %36, %28
%51 = fsub double %27, %34
%52 = fcmp olt double %50, 0.000000e+00
br i1 %52, label %55, label %53
53: ; preds = %26
%54 = fcmp ogt double %50, %51
br i1 %54, label %58, label %55
55: ; preds = %26, %53
%56 = phi double [ %50, %53 ], [ 0.000000e+00, %26 ]
%57 = fcmp olt double %51, 0.000000e+00
br i1 %57, label %63, label %58
58: ; preds = %53, %55
%59 = phi double [ %56, %55 ], [ %50, %53 ]
%60 = phi double [ %51, %55 ], [ 0.000000e+00, %53 ]
%61 = fcmp ogt double %60, %59
br i1 %61, label %62, label %63
62: ; preds = %58
br label %63
63: ; preds = %55, %58, %62
%64 = phi double [ %60, %62 ], [ %60, %58 ], [ 0.000000e+00, %55 ]
%65 = phi double [ 0.000000e+00, %62 ], [ %59, %58 ], [ %56, %55 ]
%66 = fadd double %31, %65
%67 = fadd double %32, %64
%68 = add nuw nsw i64 %29, 1
%69 = icmp eq i64 %68, %23
br i1 %69, label %70, label %26
70: ; preds = %63, %17
%71 = phi double [ 0.000000e+00, %17 ], [ %67, %63 ]
%72 = phi double [ 0.000000e+00, %17 ], [ %66, %63 ]
%73 = phi double [ 0.000000e+00, %17 ], [ %49, %63 ]
%74 = fdiv double %72, %73
%75 = fdiv double %71, %73
%76 = fsub double %74, %75
%77 = tail call double @llvm.fabs.f64(double %76)
%78 = fadd double %74, %75
%79 = fdiv double %77, %78
%80 = fmul double %79, 1.000000e+02
store double %80, double* %12
%81 = getelementptr inbounds double, double* %12, i64 1
%82 = icmp slt i32 %11, %0
br i1 %82, label %83, label %141
83: ; preds = %70
%84 = sext i32 %11 to i64
%85 = sext i32 %0 to i64
br label %86
86: ; preds = %83, %126
%87 = phi i64 [ %84, %83 ], [ %138, %126 ]
%88 = phi double* [ %81, %83 ], [ %139, %126 ]
%89 = phi double [ %73, %83 ], [ %108, %126 ]
%90 = phi double [ %72, %83 ], [ %129, %126 ]
%91 = phi double [ %71, %83 ], [ %130, %126 ]
%92 = getelementptr inbounds double, double* %7, i64 %87
%93 = load double, double* %92
%94 = getelementptr inbounds double, double* %5, i64 %87
%95 = load double, double* %94
%96 = add nsw i64 %87, -1
%97 = getelementptr inbounds double, double* %9, i64 %96
%98 = load double, double* %97
%99 = fsub double %95, %98
%100 = tail call double @llvm.fabs.f64(double %99)
%101 = fsub double %93, %98
%102 = tail call double @llvm.fabs.f64(double %101)
%103 = fsub double %95, %93
%104 = fcmp ogt double %100, %103
%105 = select i1 %104, double %100, double %103
%106 = fcmp ogt double %102, %105
%107 = select i1 %106, double %102, double %105
%108 = tail call double @llvm.fmuladd.f64(double %89, double %20, double %107)
%109 = getelementptr inbounds double, double* %5, i64 %96
%110 = load double, double* %109
%111 = fsub double %95, %110
%112 = getelementptr inbounds double, double* %7, i64 %96
%113 = load double, double* %112
%114 = fsub double %113, %93
%115 = fcmp olt double %111, 0.000000e+00
br i1 %115, label %118, label %116
116: ; preds = %86
%117 = fcmp ogt double %111, %114
br i1 %117, label %121, label %118
118: ; preds = %86, %116
%119 = phi double [ %111, %116 ], [ 0.000000e+00, %86 ]
%120 = fcmp olt double %114, 0.000000e+00
br i1 %120, label %126, label %121
121: ; preds = %116, %118
%122 = phi double [ %114, %118 ], [ 0.000000e+00, %116 ]
%123 = phi double [ %119, %118 ], [ %111, %116 ]
%124 = fcmp ogt double %122, %123
br i1 %124, label %125, label %126
125: ; preds = %121
br label %126
126: ; preds = %118, %121, %125
%127 = phi double [ 0.000000e+00, %125 ], [ %123, %121 ], [ %119, %118 ]
%128 = phi double [ %122, %125 ], [ %122, %121 ], [ 0.000000e+00, %118 ]
%129 = tail call double @llvm.fmuladd.f64(double %90, double %20, double %127)
%130 = tail call double @llvm.fmuladd.f64(double %91, double %20, double %128)
%131 = fdiv double %129, %108
%132 = fdiv double %130, %108
%133 = fsub double %131, %132
%134 = tail call double @llvm.fabs.f64(double %133)
%135 = fadd double %131, %132
%136 = fdiv double %134, %135
%137 = fmul double %136, 1.000000e+02
store double %137, double* %88
%138 = add nsw i64 %87, 1
%139 = getelementptr inbounds double, double* %88, i64 1
%140 = icmp eq i64 %138, %85
br i1 %140, label %141, label %86
141: ; preds = %126, %70
%142 = phi double* [ %81, %70 ], [ %139, %126 ]
%143 = load double*, double** %3
%144 = ptrtoint double* %142 to i64
%145 = ptrtoint double* %143 to i64
%146 = sub i64 %144, %145
%147 = ashr exact i64 %146, 3
%148 = tail call i32 (double*, ...) bitcast (i32 (...)* @ti_dx_start to i32 (double*, ...)*)(double* %2)
%149 = sub nsw i32 %0, %148
%150 = sext i32 %149 to i64
%151 = icmp eq i64 %147, %150
%152 = zext i1 %151 to i32
%153 = tail call i32 (i32, ...) bitcast (i32 (...)* @assert to i32 (i32, ...)*)(i32 %152)
br label %154
154: ; preds = %14, %4, %141
%155 = phi i32 [ 0, %141 ], [ 1, %4 ], [ 0, %14 ]
ret i32 %155
}