#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 echo_est_q16;

/* Variables and functions */
void echo_cancel(const short *out_buf, const short *in, size_t block_size,
                 int *filter_q16, size_t num_taps, short *echo_cancelled_in) {
  const short *cur_out = &out_buf[block_size - 1];
  const short *cur_in = &in[block_size - 1];
  short *cur_in_ec = &echo_cancelled_in[block_size - 1];
  const short *out_p;
  int out_norm_sq_p16;
  out_norm_sq_p16 = 0;
  for (out_p = &out_buf[block_size + num_taps - 1];
       out_p != &out_buf[block_size - 1]; --out_p)
    out_norm_sq_p16 += ((((((int)*out_p) + ((1 << 8) / 2)) / (1 << 8))) *
                        (((((int)*out_p) + ((1 << 8) / 2)) / (1 << 8))));
  do {
    int *filter_q16_p;
    int echo_est_q16;
    short echo_est;
    echo_est_q16 = 0;
    for (out_p = &cur_out[num_taps - 1],
        filter_q16_p = &filter_q16[num_taps - 1];
         out_p != cur_out; --out_p, --filter_q16_p)
      echo_est_q16 += (int)(*out_p) * (*filter_q16_p);
    echo_est = (((echo_est_q16) + ((1 << 16) / 2)) / (1 << 16));
    *cur_in_ec = *cur_in - echo_est;
    out_norm_sq_p16 +=
        ((((((int)cur_out[0]) + ((1 << 8) / 2)) / (1 << 8))) *
         (((((int)cur_out[0]) + ((1 << 8) / 2)) / (1 << 8)))) -
        ((((((int)cur_out[num_taps]) + ((1 << 8) / 2)) / (1 << 8))) *
         (((((int)cur_out[num_taps]) + ((1 << 8) / 2)) / (1 << 8))));
    if (out_norm_sq_p16 != 0) {
      for (out_p = &cur_out[num_taps - 1],
          filter_q16_p = &filter_q16[num_taps - 1];
           out_p != cur_out; --out_p, --filter_q16_p)
        *filter_q16_p +=
            ((((int)*cur_in_ec * (int)*out_p) + ((out_norm_sq_p16) / 2)) /
             (out_norm_sq_p16));
    }
  } while (cur_out--, cur_in_ec--, cur_in-- != in);
}


x86 assembly (clang, -O0):
<echo_cancel>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %rcx,-0x20(%rbp)
mov    %r8,-0x28(%rbp)
mov    %r9,-0x30(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x38(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x40(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x18(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x48(%rbp)
movl   $0x0,-0x54(%rbp)
mov    -0x8(%rbp),%rax
mov    -0x18(%rbp),%rcx
add    -0x28(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
mov    -0x8(%rbp),%rcx
mov    -0x18(%rbp),%rdx
sub    $0x1,%rdx
shl    $0x1,%rdx
add    %rdx,%rcx
cmp    %rcx,%rax
je     11ed <echo_cancel+0xed>
mov    -0x50(%rbp),%rax
movswl (%rax),%eax
add    $0x80,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
mov    %eax,-0x6c(%rbp)
mov    -0x50(%rbp),%rax
movswl (%rax),%eax
add    $0x80,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x6c(%rbp),%eax
imul   %ecx,%eax
add    -0x54(%rbp),%eax
mov    %eax,-0x54(%rbp)
mov    -0x50(%rbp),%rax
add    $0xfffffffffffffffe,%rax
mov    %rax,-0x50(%rbp)
jmp    1183 <echo_cancel+0x83>
jmp    11f2 <echo_cancel+0xf2>
movl   $0x0,-0x64(%rbp)
mov    -0x38(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x60(%rbp)
mov    -0x50(%rbp),%rax
cmp    -0x38(%rbp),%rax
je     1266 <echo_cancel+0x166>
mov    -0x50(%rbp),%rax
movswl (%rax),%eax
mov    -0x60(%rbp),%rcx
imul   (%rcx),%eax
add    -0x64(%rbp),%eax
mov    %eax,-0x64(%rbp)
mov    -0x50(%rbp),%rax
add    $0xfffffffffffffffe,%rax
mov    %rax,-0x50(%rbp)
mov    -0x60(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x60(%rbp)
jmp    1227 <echo_cancel+0x127>
mov    -0x64(%rbp),%eax
add    $0x8000,%eax
mov    $0x10000,%ecx
cltd
idiv   %ecx
mov    %ax,-0x66(%rbp)
mov    -0x40(%rbp),%rax
movswl (%rax),%eax
movswl -0x66(%rbp),%ecx
sub    %ecx,%eax
mov    %ax,%cx
mov    -0x48(%rbp),%rax
mov    %cx,(%rax)
mov    -0x38(%rbp),%rax
movswl (%rax),%eax
add    $0x80,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
mov    %eax,-0x74(%rbp)
mov    -0x38(%rbp),%rax
movswl (%rax),%eax
add    $0x80,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x74(%rbp),%eax
imul   %ecx,%eax
mov    %eax,-0x70(%rbp)
mov    -0x38(%rbp),%rax
mov    -0x28(%rbp),%rcx
movswl (%rax,%rcx,2),%eax
add    $0x80,%eax
mov    $0x100,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x38(%rbp),%rax
mov    -0x28(%rbp),%rdx
movswl (%rax,%rdx,2),%eax
add    $0x80,%eax
mov    $0x100,%esi
cltd
idiv   %esi
mov    %eax,%edx
mov    -0x70(%rbp),%eax
imul   %edx,%ecx
sub    %ecx,%eax
add    -0x54(%rbp),%eax
mov    %eax,-0x54(%rbp)
cmpl   $0x0,-0x54(%rbp)
je     13a7 <echo_cancel+0x2a7>
mov    -0x38(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x1,%rcx
add    %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
shl    $0x2,%rcx
add    %rcx,%rax
mov    %rax,-0x60(%rbp)
mov    -0x50(%rbp),%rax
cmp    -0x38(%rbp),%rax
je     13a2 <echo_cancel+0x2a2>
mov    -0x48(%rbp),%rax
movswl (%rax),%eax
mov    -0x50(%rbp),%rcx
movswl (%rcx),%ecx
imul   %ecx,%eax
mov    %eax,-0x78(%rbp)
mov    -0x54(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %eax,%ecx
mov    -0x78(%rbp),%eax
add    %ecx,%eax
cltd
idivl  -0x54(%rbp)
mov    %eax,%ecx
mov    -0x60(%rbp),%rax
add    (%rax),%ecx
mov    %ecx,(%rax)
mov    -0x50(%rbp),%rax
add    $0xfffffffffffffffe,%rax
mov    %rax,-0x50(%rbp)
mov    -0x60(%rbp),%rax
add    $0xfffffffffffffffc,%rax
mov    %rax,-0x60(%rbp)
jmp    1343 <echo_cancel+0x243>
jmp    13a7 <echo_cancel+0x2a7>
jmp    13ac <echo_cancel+0x2ac>
mov    -0x38(%rbp),%rax
add    $0xfffffffffffffffe,%rax
mov    %rax,-0x38(%rbp)
mov    -0x48(%rbp),%rax
add    $0xfffffffffffffffe,%rax
mov    %rax,-0x48(%rbp)
mov    -0x40(%rbp),%rax
mov    %rax,%rcx
add    $0xfffffffffffffffe,%rcx
mov    %rcx,-0x40(%rbp)
cmp    -0x10(%rbp),%rax
jne    11f2 <echo_cancel+0xf2>
pop    %rbp
ret

x86 assembly (clang, -O2):
<echo_cancel>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %r8,%r11
mov    %rsi,-0x38(%rsp)
mov    %rdi,%r13
movabs $0x7fffffffffffffff,%r8
ff ff 7f
lea    (%rdi,%rdx,2),%r10
add    $0xfffffffffffffffe,%r10
test   %r11,%r11
je     12a6 <echo_cancel+0x1a6>
lea    -0x1(%rdx),%rax
add    %r11,%rax
lea    0x0(,%rax,2),%rbx
add    %r13,%rbx
lea    (%r11,%r8,1),%r15
and    %r8,%r15
xor    %esi,%esi
cmp    $0x7,%r15
jb     1280 <echo_cancel+0x180>
add    $0x1,%r15
mov    %r15,%r14
and    $0xfffffffffffffff8,%r14
mov    %r14,%rdi
neg    %rdi
sub    %r14,%rbx
sub    %r14,%rbx
lea    (%r11,%rdx,1),%rax
lea    -0x8(,%rax,2),%rax
ff
add    %r13,%rax
pxor   %xmm0,%xmm0
xor    %ebp,%ebp
movdqa 0xe77(%rip),%xmm2
pxor   %xmm1,%xmm1
nopl   (%rax)
movq   (%rax,%rbp,2),%xmm3
movq   -0x8(%rax,%rbp,2),%xmm4
pshufd $0xc4,%xmm3,%xmm3
pshuflw $0xac,%xmm3,%xmm3
pshufhw $0x24,%xmm3,%xmm3
psrad  $0x10,%xmm3
pshufd $0xc4,%xmm4,%xmm4
pshuflw $0xac,%xmm4,%xmm4
pshufhw $0x24,%xmm4,%xmm4
psrad  $0x10,%xmm4
paddd  %xmm2,%xmm3
paddd  %xmm2,%xmm4
movdqa %xmm3,%xmm5
psrld  $0x18,%xmm5
paddd  %xmm3,%xmm5
psrld  $0x8,%xmm5
movdqa %xmm4,%xmm3
psrld  $0x18,%xmm3
paddd  %xmm4,%xmm3
psrld  $0x8,%xmm3
movdqa %xmm5,%xmm4
pmulhw %xmm5,%xmm4
pshuflw $0xe8,%xmm4,%xmm4
pshufhw $0xe8,%xmm4,%xmm4
pshufd $0xe8,%xmm4,%xmm4
pmullw %xmm5,%xmm5
pshuflw $0xe8,%xmm5,%xmm5
pshufhw $0xe8,%xmm5,%xmm5
pshufd $0xe8,%xmm5,%xmm5
punpcklwd %xmm4,%xmm5
paddd  %xmm5,%xmm0
movdqa %xmm3,%xmm4
pmulhw %xmm3,%xmm4
pshuflw $0xe8,%xmm4,%xmm4
pshufhw $0xe8,%xmm4,%xmm4
pshufd $0xe8,%xmm4,%xmm4
pmullw %xmm3,%xmm3
pshuflw $0xe8,%xmm3,%xmm3
pshufhw $0xe8,%xmm3,%xmm3
pshufd $0xe8,%xmm3,%xmm3
punpcklwd %xmm4,%xmm3
paddd  %xmm3,%xmm1
add    $0xfffffffffffffff8,%rbp
cmp    %rbp,%rdi
jne    1190 <echo_cancel+0x90>
paddd  %xmm0,%xmm1
pshufd $0xee,%xmm1,%xmm0
paddd  %xmm1,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%esi
cmp    %r14,%r15
je     12a8 <echo_cancel+0x1a8>
nop
movswl (%rbx),%eax
lea    0x80(%rax),%edi
add    $0x17f,%eax
test   %edi,%edi
cmovns %edi,%eax
sar    $0x8,%eax
imul   %eax,%eax
add    %eax,%esi
add    $0xfffffffffffffffe,%rbx
cmp    %r10,%rbx
jne    1280 <echo_cancel+0x180>
jmp    12a8 <echo_cancel+0x1a8>
xor    %esi,%esi
mov    -0x38(%rsp),%rax
lea    (%rax,%rdx,2),%r14
add    $0xfffffffffffffffe,%r14
lea    -0x2(%r9,%rdx,2),%r9
lea    -0x1(%r11),%rax
mov    %rax,-0x40(%rsp)
lea    (%rcx,%r11,4),%r12
add    $0xfffffffffffffffc,%r12
lea    (%r8,%r11,1),%rax
add    $0xffffffffffffffff,%rax
and    %r8,%rax
mov    %rax,-0x10(%rsp)
add    $0x1,%rax
mov    %rax,-0x20(%rsp)
and    $0xfffffffffffffff8,%rax
mov    %rax,%r15
neg    %r15
mov    %rax,-0x28(%rsp)
lea    0x0(,%rax,4),%rax
mov    %r12,%rdi
sub    %rax,%rdi
mov    %rdi,-0x30(%rsp)
lea    (%r11,%rdx,1),%rax
lea    -0xa(,%rax,2),%rdi
ff
add    %r13,%rdi
lea    -0x4(%r13,%rdx,2),%r13
lea    (%r11,%r11,1),%rax
mov    %rax,-0x18(%rsp)
jmp    1357 <echo_cancel+0x257>
cs nopw 0x0(%rax,%rax,1)
nop
add    $0xfffffffffffffffe,%r10
add    $0xfffffffffffffffe,%r9
mov    -0x8(%rsp),%rdx
lea    -0x2(%rdx),%r14
add    $0xfffffffffffffffe,%rdi
add    $0xfffffffffffffffe,%r13
cmp    -0x38(%rsp),%rdx
mov    %r8,%r11
je     1533 <echo_cancel+0x433>
mov    $0x0,%edx
cmpq   $0x0,-0x40(%rsp)
je     1485 <echo_cancel+0x385>
mov    -0x40(%rsp),%rax
lea    (%r10,%rax,2),%rax
xor    %edx,%edx
cmpq   $0x7,-0x10(%rsp)
jae    1390 <echo_cancel+0x290>
mov    %r12,%rbx
jmp    1470 <echo_cancel+0x370>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
lea    (%rax,%r15,2),%rax
pxor   %xmm0,%xmm0
xor    %edx,%edx
pxor   %xmm1,%xmm1
xchg   %ax,%ax
movq   (%rdi,%rdx,2),%xmm2
movq   -0x8(%rdi,%rdx,2),%xmm3
pshufd $0xc4,%xmm2,%xmm2
pshuflw $0xac,%xmm2,%xmm2
pshufhw $0x24,%xmm2,%xmm2
psrad  $0x10,%xmm2
pshufd $0xc4,%xmm3,%xmm3
pshuflw $0xac,%xmm3,%xmm3
pshufhw $0x24,%xmm3,%xmm3
psrad  $0x10,%xmm3
movdqu -0x1c(%r12,%rdx,4),%xmm4
movdqu -0xc(%r12,%rdx,4),%xmm5
pshufd $0x1b,%xmm5,%xmm6
pshufd $0x1b,%xmm4,%xmm7
pmuludq %xmm2,%xmm6
pshufd $0xe8,%xmm6,%xmm6
pshufd $0x4e,%xmm5,%xmm5
pshufd $0xf5,%xmm2,%xmm2
pmuludq %xmm5,%xmm2
pshufd $0xe8,%xmm2,%xmm2
punpckldq %xmm2,%xmm6
paddd  %xmm6,%xmm0
pmuludq %xmm3,%xmm7
pshufd $0xe8,%xmm7,%xmm2
pshufd $0x4e,%xmm4,%xmm4
pshufd $0xf5,%xmm3,%xmm3
pmuludq %xmm4,%xmm3
pshufd $0xe8,%xmm3,%xmm3
punpckldq %xmm3,%xmm2
paddd  %xmm2,%xmm1
add    $0xfffffffffffffff8,%rdx
cmp    %rdx,%r15
jne    13a0 <echo_cancel+0x2a0>
paddd  %xmm0,%xmm1
pshufd $0xee,%xmm1,%xmm0
paddd  %xmm1,%xmm0
pshufd $0x55,%xmm0,%xmm1
paddd  %xmm0,%xmm1
movd   %xmm1,%edx
mov    -0x30(%rsp),%rbx
mov    -0x28(%rsp),%rbp
cmp    %rbp,-0x20(%rsp)
je     1485 <echo_cancel+0x385>
nopl   0x0(%rax,%rax,1)
movswl (%rax),%ebp
imul   (%rbx),%ebp
add    %ebp,%edx
add    $0xfffffffffffffffe,%rax
add    $0xfffffffffffffffc,%rbx
cmp    %r10,%rax
jne    1470 <echo_cancel+0x370>
lea    0x8000(%rdx),%eax
add    $0x17fff,%edx
test   %eax,%eax
cmovns %eax,%edx
shr    $0x10,%edx
mov    %r14,-0x8(%rsp)
movzwl (%r14),%eax
sub    %edx,%eax
mov    %ax,(%r9)
movswl (%r10),%edx
lea    0x80(%rdx),%ebp
add    $0x17f,%edx
test   %ebp,%ebp
cmovns %ebp,%edx
sar    $0x8,%edx
imul   %edx,%edx
mov    %r11,%r8
movswl (%r10,%r11,2),%ebp
lea    0x80(%rbp),%ebx
add    $0x17f,%ebp
test   %ebx,%ebx
cmovns %ebx,%ebp
sar    $0x8,%ebp
imul   %ebp,%ebp
sub    %ebp,%edx
add    %edx,%esi
je     1330 <echo_cancel+0x230>
cmpq   $0x0,-0x40(%rsp)
je     1330 <echo_cancel+0x230>
movswl %ax,%ebx
mov    %esi,%r11d
shr    $0x1f,%r11d
add    %esi,%r11d
sar    %r11d
mov    -0x18(%rsp),%r14
nopl   (%rax)
movswl 0x0(%r13,%r14,1),%eax
imul   %ebx,%eax
add    %r11d,%eax
cltd
idiv   %esi
add    %eax,-0x4(%rcx,%r14,2)
add    $0xfffffffffffffffe,%r14
cmp    $0x2,%r14
jne    1510 <echo_cancel+0x410>
jmp    1330 <echo_cancel+0x230>
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define void @echo_cancel(i16* %0, i16* %1, i64 %2, i32* %3, i64 %4, i16* %5) {
%7 = alloca i16*
%8 = alloca i16*
%9 = alloca i64
%10 = alloca i32*
%11 = alloca i64
%12 = alloca i16*
%13 = alloca i16*
%14 = alloca i16*
%15 = alloca i16*
%16 = alloca i16*
%17 = alloca i32
%18 = alloca i32*
%19 = alloca i32
%20 = alloca i16
store i16* %0, i16** %7
store i16* %1, i16** %8
store i64 %2, i64* %9
store i32* %3, i32** %10
store i64 %4, i64* %11
store i16* %5, i16** %12
%21 = load i16*, i16** %7
%22 = load i64, i64* %9
%23 = sub i64 %22, 1
%24 = getelementptr inbounds i16, i16* %21, i64 %23
store i16* %24, i16** %13
%25 = load i16*, i16** %8
%26 = load i64, i64* %9
%27 = sub i64 %26, 1
%28 = getelementptr inbounds i16, i16* %25, i64 %27
store i16* %28, i16** %14
%29 = load i16*, i16** %12
%30 = load i64, i64* %9
%31 = sub i64 %30, 1
%32 = getelementptr inbounds i16, i16* %29, i64 %31
store i16* %32, i16** %15
store i32 0, i32* %17
%33 = load i16*, i16** %7
%34 = load i64, i64* %9
%35 = load i64, i64* %11
%36 = add i64 %34, %35
%37 = sub i64 %36, 1
%38 = getelementptr inbounds i16, i16* %33, i64 %37
store i16* %38, i16** %16
br label %39
39: ; preds = %60, %6
%40 = load i16*, i16** %16
%41 = load i16*, i16** %7
%42 = load i64, i64* %9
%43 = sub i64 %42, 1
%44 = getelementptr inbounds i16, i16* %41, i64 %43
%45 = icmp ne i16* %40, %44
br i1 %45, label %46, label %63
46: ; preds = %39
%47 = load i16*, i16** %16
%48 = load i16, i16* %47
%49 = sext i16 %48 to i32
%50 = add nsw i32 %49, 128
%51 = sdiv i32 %50, 256
%52 = load i16*, i16** %16
%53 = load i16, i16* %52
%54 = sext i16 %53 to i32
%55 = add nsw i32 %54, 128
%56 = sdiv i32 %55, 256
%57 = mul nsw i32 %51, %56
%58 = load i32, i32* %17
%59 = add nsw i32 %58, %57
store i32 %59, i32* %17
br label %60
60: ; preds = %46
%61 = load i16*, i16** %16
%62 = getelementptr inbounds i16, i16* %61, i32 -1
store i16* %62, i16** %16
br label %39
63: ; preds = %39
br label %64
64: ; preds = %173, %63
store i32 0, i32* %19
%65 = load i16*, i16** %13
%66 = load i64, i64* %11
%67 = sub i64 %66, 1
%68 = getelementptr inbounds i16, i16* %65, i64 %67
store i16* %68, i16** %16
%69 = load i32*, i32** %10
%70 = load i64, i64* %11
%71 = sub i64 %70, 1
%72 = getelementptr inbounds i32, i32* %69, i64 %71
store i32* %72, i32** %18
br label %73
73: ; preds = %86, %64
%74 = load i16*, i16** %16
%75 = load i16*, i16** %13
%76 = icmp ne i16* %74, %75
br i1 %76, label %77, label %91
77: ; preds = %73
%78 = load i16*, i16** %16
%79 = load i16, i16* %78
%80 = sext i16 %79 to i32
%81 = load i32*, i32** %18
%82 = load i32, i32* %81
%83 = mul nsw i32 %80, %82
%84 = load i32, i32* %19
%85 = add nsw i32 %84, %83
store i32 %85, i32* %19
br label %86
86: ; preds = %77
%87 = load i16*, i16** %16
%88 = getelementptr inbounds i16, i16* %87, i32 -1
store i16* %88, i16** %16
%89 = load i32*, i32** %18
%90 = getelementptr inbounds i32, i32* %89, i32 -1
store i32* %90, i32** %18
br label %73
91: ; preds = %73
%92 = load i32, i32* %19
%93 = add nsw i32 %92, 32768
%94 = sdiv i32 %93, 65536
%95 = trunc i32 %94 to i16
store i16 %95, i16* %20
%96 = load i16*, i16** %14
%97 = load i16, i16* %96
%98 = sext i16 %97 to i32
%99 = load i16, i16* %20
%100 = sext i16 %99 to i32
%101 = sub nsw i32 %98, %100
%102 = trunc i32 %101 to i16
%103 = load i16*, i16** %15
store i16 %102, i16* %103
%104 = load i16*, i16** %13
%105 = getelementptr inbounds i16, i16* %104, i64 0
%106 = load i16, i16* %105
%107 = sext i16 %106 to i32
%108 = add nsw i32 %107, 128
%109 = sdiv i32 %108, 256
%110 = load i16*, i16** %13
%111 = getelementptr inbounds i16, i16* %110, i64 0
%112 = load i16, i16* %111
%113 = sext i16 %112 to i32
%114 = add nsw i32 %113, 128
%115 = sdiv i32 %114, 256
%116 = mul nsw i32 %109, %115
%117 = load i16*, i16** %13
%118 = load i64, i64* %11
%119 = getelementptr inbounds i16, i16* %117, i64 %118
%120 = load i16, i16* %119
%121 = sext i16 %120 to i32
%122 = add nsw i32 %121, 128
%123 = sdiv i32 %122, 256
%124 = load i16*, i16** %13
%125 = load i64, i64* %11
%126 = getelementptr inbounds i16, i16* %124, i64 %125
%127 = load i16, i16* %126
%128 = sext i16 %127 to i32
%129 = add nsw i32 %128, 128
%130 = sdiv i32 %129, 256
%131 = mul nsw i32 %123, %130
%132 = sub nsw i32 %116, %131
%133 = load i32, i32* %17
%134 = add nsw i32 %133, %132
store i32 %134, i32* %17
%135 = load i32, i32* %17
%136 = icmp ne i32 %135, 0
br i1 %136, label %137, label %172
137: ; preds = %91
%138 = load i16*, i16** %13
%139 = load i64, i64* %11
%140 = sub i64 %139, 1
%141 = getelementptr inbounds i16, i16* %138, i64 %140
store i16* %141, i16** %16
%142 = load i32*, i32** %10
%143 = load i64, i64* %11
%144 = sub i64 %143, 1
%145 = getelementptr inbounds i32, i32* %142, i64 %144
store i32* %145, i32** %18
br label %146
146: ; preds = %166, %137
%147 = load i16*, i16** %16
%148 = load i16*, i16** %13
%149 = icmp ne i16* %147, %148
br i1 %149, label %150, label %171
150: ; preds = %146
%151 = load i16*, i16** %15
%152 = load i16, i16* %151
%153 = sext i16 %152 to i32
%154 = load i16*, i16** %16
%155 = load i16, i16* %154
%156 = sext i16 %155 to i32
%157 = mul nsw i32 %153, %156
%158 = load i32, i32* %17
%159 = sdiv i32 %158, 2
%160 = add nsw i32 %157, %159
%161 = load i32, i32* %17
%162 = sdiv i32 %160, %161
%163 = load i32*, i32** %18
%164 = load i32, i32* %163
%165 = add nsw i32 %164, %162
store i32 %165, i32* %163
br label %166
166: ; preds = %150
%167 = load i16*, i16** %16
%168 = getelementptr inbounds i16, i16* %167, i32 -1
store i16* %168, i16** %16
%169 = load i32*, i32** %18
%170 = getelementptr inbounds i32, i32* %169, i32 -1
store i32* %170, i32** %18
br label %146
171: ; preds = %146
br label %172
172: ; preds = %171, %91
br label %173
173: ; preds = %172
%174 = load i16*, i16** %13
%175 = getelementptr inbounds i16, i16* %174, i32 -1
store i16* %175, i16** %13
%176 = load i16*, i16** %15
%177 = getelementptr inbounds i16, i16* %176, i32 -1
store i16* %177, i16** %15
%178 = load i16*, i16** %14
%179 = getelementptr inbounds i16, i16* %178, i32 -1
store i16* %179, i16** %14
%180 = load i16*, i16** %8
%181 = icmp ne i16* %178, %180
br i1 %181, label %64, label %182
182: ; preds = %173
ret void
}

LLVM IR (-O2):
define void @echo_cancel(i16* %0, i16* %1, i64 %2, i32* nocapture %3, i64 %4, i16* nocapture %5) {
%7 = add i64 %2, -1
%8 = getelementptr inbounds i16, i16* %0, i64 %7
%9 = getelementptr inbounds i16, i16* %1, i64 %7
%10 = getelementptr inbounds i16, i16* %5, i64 %7
%11 = icmp eq i64 %4, 0
br i1 %11, label %57, label %12
12: ; preds = %6
%13 = add i64 %7, %4
%14 = getelementptr inbounds i16, i16* %0, i64 %13
%15 = add i64 %4, 9223372036854775807
%16 = and i64 %15, 9223372036854775807
%17 = add nuw i64 %16, 1
%18 = icmp ult i64 %16, 7
br i1 %18, label %54, label %19
19: ; preds = %12
%20 = and i64 %17, -8
%21 = sub i64 0, %20
%22 = getelementptr i16, i16* %14, i64 %21
br label %23
23: ; preds = %23, %19
%24 = phi i64 [ 0, %19 ], [ %48, %23 ]
%25 = phi <4 x i32> [ zeroinitializer, %19 ], [ %46, %23 ]
%26 = phi <4 x i32> [ zeroinitializer, %19 ], [ %47, %23 ]
%27 = sub i64 0, %24
%28 = getelementptr i16, i16* %14, i64 %27
%29 = getelementptr i16, i16* %28, i64 -3
%30 = bitcast i16* %29 to <4 x i16>*
%31 = load <4 x i16>, <4 x i16>* %30
%32 = shufflevector <4 x i16> %31, <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%33 = getelementptr i16, i16* %28, i64 -4
%34 = getelementptr i16, i16* %33, i64 -3
%35 = bitcast i16* %34 to <4 x i16>*
%36 = load <4 x i16>, <4 x i16>* %35
%37 = shufflevector <4 x i16> %36, <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%38 = sext <4 x i16> %32 to <4 x i32>
%39 = sext <4 x i16> %37 to <4 x i32>
%40 = add nsw <4 x i32> %38, <i32 128, i32 128, i32 128, i32 128>
%41 = add nsw <4 x i32> %39, <i32 128, i32 128, i32 128, i32 128>
%42 = sdiv <4 x i32> %40, <i32 256, i32 256, i32 256, i32 256>
%43 = sdiv <4 x i32> %41, <i32 256, i32 256, i32 256, i32 256>
%44 = mul nsw <4 x i32> %42, %42
%45 = mul nsw <4 x i32> %43, %43
%46 = add <4 x i32> %44, %25
%47 = add <4 x i32> %45, %26
%48 = add nuw i64 %24, 8
%49 = icmp eq i64 %48, %20
br i1 %49, label %50, label %23
50: ; preds = %23
%51 = add <4 x i32> %47, %46
%52 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %51)
%53 = icmp eq i64 %17, %20
br i1 %53, label %57, label %54
54: ; preds = %12, %50
%55 = phi i32 [ 0, %12 ], [ %52, %50 ]
%56 = phi i16* [ %14, %12 ], [ %22, %50 ]
br label %71
57: ; preds = %71, %50, %6
%58 = phi i32 [ 0, %6 ], [ %52, %50 ], [ %79, %71 ]
%59 = add i64 %4, -1
%60 = getelementptr inbounds i32, i32* %3, i64 %59
%61 = icmp eq i64 %59, 0
%62 = add i64 %4, 9223372036854775806
%63 = and i64 %62, 9223372036854775807
%64 = add nuw i64 %63, 1
%65 = icmp ult i64 %63, 7
%66 = and i64 %64, -8
%67 = sub i64 0, %66
%68 = getelementptr i32, i32* %60, i64 %67
%69 = sub i64 0, %66
%70 = icmp eq i64 %64, %66
br label %82
71: ; preds = %54, %71
%72 = phi i32 [ %79, %71 ], [ %55, %54 ]
%73 = phi i16* [ %80, %71 ], [ %56, %54 ]
%74 = load i16, i16* %73
%75 = sext i16 %74 to i32
%76 = add nsw i32 %75, 128
%77 = sdiv i32 %76, 256
%78 = mul nsw i32 %77, %77
%79 = add nuw nsw i32 %78, %72
%80 = getelementptr inbounds i16, i16* %73, i64 -1
%81 = icmp eq i16* %80, %8
br i1 %81, label %57, label %71
82: ; preds = %57, %182
%83 = phi i16* [ %185, %182 ], [ %9, %57 ]
%84 = phi i16* [ %184, %182 ], [ %10, %57 ]
%85 = phi i32 [ %163, %182 ], [ %58, %57 ]
%86 = phi i16* [ %183, %182 ], [ %8, %57 ]
%87 = getelementptr inbounds i16, i16* %86, i64 %59
br i1 %61, label %144, label %88
88: ; preds = %82
br i1 %65, label %128, label %89
89: ; preds = %88
%90 = getelementptr i16, i16* %87, i64 %69
br label %91
91: ; preds = %91, %89
%92 = phi i64 [ 0, %89 ], [ %123, %91 ]
%93 = phi <4 x i32> [ zeroinitializer, %89 ], [ %121, %91 ]
%94 = phi <4 x i32> [ zeroinitializer, %89 ], [ %122, %91 ]
%95 = sub i64 0, %92
%96 = getelementptr i32, i32* %60, i64 %95
%97 = sub i64 0, %92
%98 = getelementptr i16, i16* %87, i64 %97
%99 = getelementptr i16, i16* %98, i64 -3
%100 = bitcast i16* %99 to <4 x i16>*
%101 = load <4 x i16>, <4 x i16>* %100
%102 = shufflevector <4 x i16> %101, <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%103 = getelementptr i16, i16* %98, i64 -4
%104 = getelementptr i16, i16* %103, i64 -3
%105 = bitcast i16* %104 to <4 x i16>*
%106 = load <4 x i16>, <4 x i16>* %105
%107 = shufflevector <4 x i16> %106, <4 x i16> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%108 = sext <4 x i16> %102 to <4 x i32>
%109 = sext <4 x i16> %107 to <4 x i32>
%110 = getelementptr i32, i32* %96, i64 -3
%111 = bitcast i32* %110 to <4 x i32>*
%112 = load <4 x i32>, <4 x i32>* %111
%113 = shufflevector <4 x i32> %112, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%114 = getelementptr i32, i32* %96, i64 -4
%115 = getelementptr i32, i32* %114, i64 -3
%116 = bitcast i32* %115 to <4 x i32>*
%117 = load <4 x i32>, <4 x i32>* %116
%118 = shufflevector <4 x i32> %117, <4 x i32> poison, <4 x i32> <i32 3, i32 2, i32 1, i32 0>
%119 = mul nsw <4 x i32> %113, %108
%120 = mul nsw <4 x i32> %118, %109
%121 = add <4 x i32> %119, %93
%122 = add <4 x i32> %120, %94
%123 = add nuw i64 %92, 8
%124 = icmp eq i64 %123, %66
br i1 %124, label %125, label %91
125: ; preds = %91
%126 = add <4 x i32> %122, %121
%127 = call i32 @llvm.vector.reduce.add.v4i32(<4 x i32> %126)
br i1 %70, label %144, label %128
128: ; preds = %88, %125
%129 = phi i32 [ 0, %88 ], [ %127, %125 ]
%130 = phi i32* [ %60, %88 ], [ %68, %125 ]
%131 = phi i16* [ %87, %88 ], [ %90, %125 ]
br label %132
132: ; preds = %128, %132
%133 = phi i32 [ %140, %132 ], [ %129, %128 ]
%134 = phi i32* [ %142, %132 ], [ %130, %128 ]
%135 = phi i16* [ %141, %132 ], [ %131, %128 ]
%136 = load i16, i16* %135
%137 = sext i16 %136 to i32
%138 = load i32, i32* %134
%139 = mul nsw i32 %138, %137
%140 = add nsw i32 %139, %133
%141 = getelementptr inbounds i16, i16* %135, i64 -1
%142 = getelementptr inbounds i32, i32* %134, i64 -1
%143 = icmp eq i16* %141, %86
br i1 %143, label %144, label %132
144: ; preds = %132, %125, %82
%145 = phi i32 [ 0, %82 ], [ %127, %125 ], [ %140, %132 ]
%146 = add nsw i32 %145, 32768
%147 = sdiv i32 %146, -65536
%148 = load i16, i16* %83
%149 = trunc i32 %147 to i16
%150 = add i16 %148, %149
store i16 %150, i16* %84
%151 = load i16, i16* %86
%152 = sext i16 %151 to i32
%153 = add nsw i32 %152, 128
%154 = sdiv i32 %153, 256
%155 = mul nsw i32 %154, %154
%156 = getelementptr inbounds i16, i16* %86, i64 %4
%157 = load i16, i16* %156
%158 = sext i16 %157 to i32
%159 = add nsw i32 %158, 128
%160 = sdiv i32 %159, 256
%161 = mul nsw i32 %160, %160
%162 = sub nsw i32 %155, %161
%163 = add nsw i32 %162, %85
%164 = icmp eq i32 %163, 0
%165 = or i1 %164, %61
br i1 %165, label %182, label %166
166: ; preds = %144
%167 = sext i16 %150 to i32
%168 = sdiv i32 %163, 2
br label %169
169: ; preds = %166, %169
%170 = phi i32* [ %60, %166 ], [ %180, %169 ]
%171 = phi i16* [ %87, %166 ], [ %179, %169 ]
%172 = load i16, i16* %171
%173 = sext i16 %172 to i32
%174 = mul nsw i32 %173, %167
%175 = add nsw i32 %174, %168
%176 = sdiv i32 %175, %163
%177 = load i32, i32* %170
%178 = add nsw i32 %177, %176
store i32 %178, i32* %170
%179 = getelementptr inbounds i16, i16* %171, i64 -1
%180 = getelementptr inbounds i32, i32* %170, i64 -1
%181 = icmp eq i16* %179, %86
br i1 %181, label %182, label %169
182: ; preds = %169, %144
%183 = getelementptr inbounds i16, i16* %86, i64 -1
%184 = getelementptr inbounds i16, i16* %84, i64 -1
%185 = getelementptr inbounds i16, i16* %83, i64 -1
%186 = icmp eq i16* %83, %1
br i1 %186, label %187, label %82
187: ; preds = %182
ret void
}