#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 */
int /*<<< orphan*/ abort();
unsigned char divide(unsigned char, unsigned char);
int /*<<< orphan*/ free(unsigned char *);
int /*<<< orphan*/ gen_conv_matrix(unsigned char *, unsigned char *, size_t,
                                   size_t);
int /*<<< orphan*/ inner_product_set(unsigned char *, unsigned char *,
                                     unsigned char *, size_t, size_t);
unsigned char *malloc(size_t);
int /*<<< orphan*/ memset(unsigned char *, int /*<<< orphan*/, size_t);
unsigned char sum(unsigned char, unsigned char);
void divide_polynomial(unsigned char *dividend, unsigned char *divisor,
                       unsigned char *quotient, unsigned char *remainder,
                       size_t dividend_len, size_t divisor_len) {
  if (divisor_len > dividend_len) {
    for (int i = 0; i < dividend_len; i++) {
      remainder[i] = dividend[i];
    }
    return;
  }
  unsigned char *quotient_divisor_product = malloc(dividend_len);
  if (!quotient_divisor_product)
    abort();
  unsigned char *product_dividend_difference = malloc(dividend_len);
  if (!product_dividend_difference)
    abort();
  unsigned char *divisor_conv =
      malloc(dividend_len * (dividend_len + divisor_len - 1));
  if (!divisor_conv)
    abort();
  size_t quotient_len = dividend_len - (divisor_len - 1);
  memset(quotient, 0, quotient_len);
  gen_conv_matrix(divisor, divisor_conv, divisor_len - 1, dividend_len - 1);
  for (;;) {
    inner_product_set(quotient_divisor_product, divisor_conv, quotient,
                      quotient_len, dividend_len);
    for (int i = 0; i < dividend_len; i++) {
      product_dividend_difference[i] =
          sum(dividend[i], quotient_divisor_product[i]);
    }
    int diff_greatest_nonzero = dividend_len;
    for (;;) {
      diff_greatest_nonzero--;
      if (diff_greatest_nonzero == -1)
        break;
      if (product_dividend_difference[diff_greatest_nonzero])
        break;
    }
    if (diff_greatest_nonzero < (int)divisor_len - 1) {
      for (int i = 0; i <= diff_greatest_nonzero; i++) {
        remainder[i] = product_dividend_difference[i];
      }
      free(quotient_divisor_product);
      free(product_dividend_difference);
      free(divisor_conv);
      return;
    }
    unsigned char factor =
        divide(product_dividend_difference[diff_greatest_nonzero],
               divisor[divisor_len - 1]);
    quotient[diff_greatest_nonzero - (divisor_len - 1)] = factor;
  }
}


x86 assembly (clang, -O0):
<divide_polynomial>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
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    -0x30(%rbp),%rax
cmp    -0x28(%rbp),%rax
jbe    11ec <divide_polynomial+0x6c>
movl   $0x0,-0x34(%rbp)
movslq -0x34(%rbp),%rax
cmp    -0x28(%rbp),%rax
jae    11e7 <divide_polynomial+0x67>
mov    -0x8(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x20(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    11b5 <divide_polynomial+0x35>
jmp    13e8 <divide_polynomial+0x268>
mov    -0x28(%rbp),%rdi
call   10a0 <malloc@plt>
mov    %rax,-0x40(%rbp)
cmpq   $0x0,-0x40(%rbp)
jne    120b <divide_polynomial+0x8b>
mov    $0x0,%al
call   1040 <abort@plt>
mov    -0x28(%rbp),%rdi
call   10a0 <malloc@plt>
mov    %rax,-0x48(%rbp)
cmpq   $0x0,-0x48(%rbp)
jne    122a <divide_polynomial+0xaa>
mov    $0x0,%al
call   1040 <abort@plt>
mov    -0x28(%rbp),%rdi
mov    -0x28(%rbp),%rax
add    -0x30(%rbp),%rax
sub    $0x1,%rax
imul   %rax,%rdi
call   10a0 <malloc@plt>
mov    %rax,-0x50(%rbp)
cmpq   $0x0,-0x50(%rbp)
jne    1259 <divide_polynomial+0xd9>
mov    $0x0,%al
call   1040 <abort@plt>
mov    -0x28(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
sub    %rcx,%rax
mov    %rax,-0x58(%rbp)
mov    -0x18(%rbp),%rdi
mov    -0x58(%rbp),%rdx
xor    %esi,%esi
call   1060 <memset@plt>
mov    -0x10(%rbp),%rdi
mov    -0x50(%rbp),%rsi
mov    -0x30(%rbp),%rdx
sub    $0x1,%rdx
mov    -0x28(%rbp),%rcx
sub    $0x1,%rcx
call   1080 <gen_conv_matrix@plt>
mov    -0x40(%rbp),%rdi
mov    -0x50(%rbp),%rsi
mov    -0x18(%rbp),%rdx
mov    -0x58(%rbp),%rcx
mov    -0x28(%rbp),%r8
call   1070 <inner_product_set@plt>
movl   $0x0,-0x5c(%rbp)
movslq -0x5c(%rbp),%rax
cmp    -0x28(%rbp),%rax
jae    1300 <divide_polynomial+0x180>
mov    -0x8(%rbp),%rax
movslq -0x5c(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x40(%rbp),%rax
movslq -0x5c(%rbp),%rcx
movzbl %dl,%edi
movzbl (%rax,%rcx,1),%esi
call   1090 <sum@plt>
mov    %al,%dl
mov    -0x48(%rbp),%rax
movslq -0x5c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x5c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x5c(%rbp)
jmp    12b8 <divide_polynomial+0x138>
mov    -0x28(%rbp),%rax
mov    %eax,-0x60(%rbp)
mov    -0x60(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x60(%rbp)
cmpl   $0xffffffff,-0x60(%rbp)
jne    131f <divide_polynomial+0x19f>
jmp    133b <divide_polynomial+0x1bb>
mov    -0x48(%rbp),%rax
movslq -0x60(%rbp),%rcx
cmpb   $0x0,(%rax,%rcx,1)
je     1336 <divide_polynomial+0x1b6>
jmp    133b <divide_polynomial+0x1bb>
jmp    1307 <divide_polynomial+0x187>
mov    -0x60(%rbp),%eax
mov    -0x30(%rbp),%rcx
sub    $0x1,%ecx
cmp    %ecx,%eax
jge    13a4 <divide_polynomial+0x224>
movl   $0x0,-0x64(%rbp)
mov    -0x64(%rbp),%eax
cmp    -0x60(%rbp),%eax
jg     1384 <divide_polynomial+0x204>
mov    -0x48(%rbp),%rax
movslq -0x64(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x20(%rbp),%rax
movslq -0x64(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x64(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x64(%rbp)
jmp    1354 <divide_polynomial+0x1d4>
mov    -0x40(%rbp),%rdi
call   1030 <free@plt>
mov    -0x48(%rbp),%rdi
call   1030 <free@plt>
mov    -0x50(%rbp),%rdi
call   1030 <free@plt>
jmp    13e8 <divide_polynomial+0x268>
mov    -0x48(%rbp),%rax
movslq -0x60(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%rcx
sub    $0x1,%rcx
movzbl %dl,%edi
movzbl (%rax,%rcx,1),%esi
call   1050 <divide@plt>
mov    %al,-0x65(%rbp)
mov    -0x65(%rbp),%dl
mov    -0x18(%rbp),%rax
movslq -0x60(%rbp),%rcx
mov    -0x30(%rbp),%rsi
sub    $0x1,%rsi
sub    %rsi,%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1298 <divide_polynomial+0x118>
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<divide_polynomial>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x48,%rsp
mov    %r8,%r12
mov    %rsi,0x20(%rsp)
mov    %rdi,%r15
cmp    %r8,%r9
jbe    124e <divide_polynomial+0xbe>
test   %r12,%r12
je     123f <divide_polynomial+0xaf>
cmp    $0x8,%r12
jb     11db <divide_polynomial+0x4b>
lea    (%r15,%r12,1),%rax
cmp    %rcx,%rax
jbe    13f0 <divide_polynomial+0x260>
lea    (%rcx,%r12,1),%rax
cmp    %r15,%rax
jbe    13f0 <divide_polynomial+0x260>
xor    %eax,%eax
mov    %rax,%rsi
not    %rsi
add    %r12,%rsi
mov    %r12,%rdx
and    $0x3,%rdx
je     1202 <divide_polynomial+0x72>
nop
movzbl (%r15,%rax,1),%ebx
mov    %bl,(%rcx,%rax,1)
add    $0x1,%rax
add    $0xffffffffffffffff,%rdx
jne    11f0 <divide_polynomial+0x60>
cmp    $0x3,%rsi
jb     123f <divide_polynomial+0xaf>
nopl   0x0(%rax,%rax,1)
movzbl (%r15,%rax,1),%edx
mov    %dl,(%rcx,%rax,1)
movzbl 0x1(%r15,%rax,1),%edx
mov    %dl,0x1(%rcx,%rax,1)
movzbl 0x2(%r15,%rax,1),%edx
mov    %dl,0x2(%rcx,%rax,1)
movzbl 0x3(%r15,%rax,1),%edx
mov    %dl,0x3(%rcx,%rax,1)
add    $0x4,%rax
cmp    %rax,%r12
jne    1210 <divide_polynomial+0x80>
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %r9,%rbx
mov    %rdx,0x10(%rsp)
mov    %rcx,0x28(%rsp)
mov    %r12,%rdi
call   10b0 <malloc@plt>
test   %rax,%rax
je     150f <divide_polynomial+0x37f>
mov    %rax,%r13
mov    %r12,%rdi
call   10b0 <malloc@plt>
test   %rax,%rax
je     150f <divide_polynomial+0x37f>
mov    %rax,%rbp
lea    (%r12,%rbx,1),%rdi
add    $0xffffffffffffffff,%rdi
imul   %r12,%rdi
call   10b0 <malloc@plt>
mov    %rax,0x18(%rsp)
test   %rax,%rax
je     150f <divide_polynomial+0x37f>
lea    -0x1(%r12),%rax
mov    %rax,0x8(%rsp)
lea    -0x1(%rbx),%r14
mov    %r12,%rdx
sub    %r14,%rdx
mov    0x10(%rsp),%rdi
xor    %esi,%esi
mov    %rdx,0x40(%rsp)
call   1060 <memset@plt>
mov    0x20(%rsp),%rdi
mov    0x18(%rsp),%rsi
mov    %r14,0x38(%rsp)
mov    %r14,%rdx
mov    0x8(%rsp),%rcx
call   1080 <gen_conv_matrix@plt>
mov    0x10(%rsp),%rdx
movslq %r12d,%rax
add    $0x1,%rax
mov    %rax,0x8(%rsp)
mov    %rbx,0x30(%rsp)
jmp    133b <divide_polynomial+0x1ab>
nopl   0x0(%rax,%rax,1)
mov    $0xffffffffffffffff,%rax
test   %ebx,%ebx
jg     13c8 <divide_polynomial+0x238>
movslq %eax,%rbx
movzbl 0x0(%rbp,%rbx,1),%edi
mov    0x20(%rsp),%rax
mov    0x38(%rsp),%r14
movzbl (%rax,%r14,1),%esi
call   1050 <divide@plt>
sub    %r14,%rbx
mov    0x10(%rsp),%rdx
mov    %al,(%rdx,%rbx,1)
mov    0x30(%rsp),%rbx
mov    %r13,%rdi
mov    0x18(%rsp),%rsi
mov    0x40(%rsp),%rcx
mov    %r12,%r8
call   1070 <inner_product_set@plt>
test   %r12,%r12
je     137e <divide_polynomial+0x1ee>
xor    %r14d,%r14d
nopl   0x0(%rax,%rax,1)
movzbl (%r15,%r14,1),%edi
movzbl 0x0(%r13,%r14,1),%esi
call   10a0 <sum@plt>
mov    %al,0x0(%rbp,%r14,1)
add    $0x1,%r14
cmp    %r14,%r12
jne    1360 <divide_polynomial+0x1d0>
mov    0x8(%rsp),%rcx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
cmp    $0x1,%rcx
je     1300 <divide_polynomial+0x170>
lea    -0x1(%rcx),%rax
cmpb   $0x0,-0x2(%rbp,%rcx,1)
mov    %rax,%rcx
je     1390 <divide_polynomial+0x200>
cmp    %ebx,%eax
jl     13b5 <divide_polynomial+0x225>
add    $0xffffffffffffffff,%rax
jmp    130f <divide_polynomial+0x17f>
test   %eax,%eax
jle    13c8 <divide_polynomial+0x238>
mov    %eax,%edx
mov    0x28(%rsp),%rdi
mov    %rbp,%rsi
call   1090 <memcpy@plt>
mov    %r13,%rdi
call   1030 <free@plt>
mov    %rbp,%rdi
call   1030 <free@plt>
mov    0x18(%rsp),%rdi
add    $0x48,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
jmp    1030 <free@plt>
cmp    $0x20,%r12
jae    13fd <divide_polynomial+0x26d>
xor    %eax,%eax
jmp    14de <divide_polynomial+0x34e>
mov    %r12,%rax
and    $0xffffffffffffffe0,%rax
lea    -0x20(%rax),%rsi
mov    %rsi,%rdx
shr    $0x5,%rdx
add    $0x1,%rdx
mov    %edx,%ebp
and    $0x3,%ebp
cmp    $0x60,%rsi
jae    1422 <divide_polynomial+0x292>
xor    %esi,%esi
jmp    1490 <divide_polynomial+0x300>
and    $0xfffffffffffffffc,%rdx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movups (%r15,%rsi,1),%xmm0
movups 0x10(%r15,%rsi,1),%xmm1
movups %xmm0,(%rcx,%rsi,1)
movups %xmm1,0x10(%rcx,%rsi,1)
movups 0x20(%r15,%rsi,1),%xmm0
movups 0x30(%r15,%rsi,1),%xmm1
movups %xmm0,0x20(%rcx,%rsi,1)
movups %xmm1,0x30(%rcx,%rsi,1)
movups 0x40(%r15,%rsi,1),%xmm0
movups 0x50(%r15,%rsi,1),%xmm1
movups %xmm0,0x40(%rcx,%rsi,1)
movups %xmm1,0x50(%rcx,%rsi,1)
movups 0x60(%r15,%rsi,1),%xmm0
movups 0x70(%r15,%rsi,1),%xmm1
movups %xmm0,0x60(%rcx,%rsi,1)
movups %xmm1,0x70(%rcx,%rsi,1)
sub    $0xffffffffffffff80,%rsi
add    $0xfffffffffffffffc,%rdx
jne    1430 <divide_polynomial+0x2a0>
test   %rbp,%rbp
je     14cb <divide_polynomial+0x33b>
lea    (%rcx,%rsi,1),%rdx
add    $0x10,%rdx
add    %r15,%rsi
add    $0x10,%rsi
shl    $0x5,%rbp
xor    %edi,%edi
nopw   0x0(%rax,%rax,1)
movups -0x10(%rsi,%rdi,1),%xmm0
movups (%rsi,%rdi,1),%xmm1
movups %xmm0,-0x10(%rdx,%rdi,1)
movups %xmm1,(%rdx,%rdi,1)
add    $0x20,%rdi
cmp    %rdi,%rbp
jne    14b0 <divide_polynomial+0x320>
cmp    %r12,%rax
je     123f <divide_polynomial+0xaf>
test   $0x18,%r12b
je     11dd <divide_polynomial+0x4d>
mov    %rax,%rsi
mov    %r12,%rax
and    $0xfffffffffffffff8,%rax
nopl   0x0(%rax,%rax,1)
mov    (%r15,%rsi,1),%rdx
mov    %rdx,(%rcx,%rsi,1)
add    $0x8,%rsi
cmp    %rsi,%rax
jne    14f0 <divide_polynomial+0x360>
cmp    %r12,%rax
je     123f <divide_polynomial+0xaf>
jmp    11dd <divide_polynomial+0x4d>
xor    %eax,%eax
call   1040 <abort@plt>

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

LLVM IR (-O2):
define void @divide_polynomial(i8* nocapture %0, i8* %1, i8* %2, i8* nocapture writeonly %3, i64 %4, i64 %5) {
%7 = icmp ugt i64 %5, %4
br i1 %7, label %8, label %153
8: ; preds = %6
%9 = icmp eq i64 %4, 0
br i1 %9, label %226, label %10
10: ; preds = %8
%11 = icmp ult i64 %4, 8
br i1 %11, label %116, label %12
12: ; preds = %10
%13 = getelementptr i8, i8* %3, i64 %4
%14 = getelementptr i8, i8* %0, i64 %4
%15 = icmp ugt i8* %14, %3
%16 = icmp ugt i8* %13, %0
%17 = and i1 %15, %16
br i1 %17, label %116, label %18
18: ; preds = %12
%19 = icmp ult i64 %4, 32
br i1 %19, label %102, label %20
20: ; preds = %18
%21 = and i64 %4, -32
%22 = add i64 %21, -32
%23 = lshr exact i64 %22, 5
%24 = add nuw nsw i64 %23, 1
%25 = and i64 %24, 3
%26 = icmp ult i64 %22, 96
br i1 %26, label %78, label %27
27: ; preds = %20
%28 = and i64 %24, 1152921504606846972
br label %29
29: ; preds = %29, %27
%30 = phi i64 [ 0, %27 ], [ %75, %29 ]
%31 = phi i64 [ 0, %27 ], [ %76, %29 ]
%32 = getelementptr inbounds i8, i8* %0, i64 %30
%33 = bitcast i8* %32 to <16 x i8>*
%34 = load <16 x i8>, <16 x i8>* %33
%35 = getelementptr inbounds i8, i8* %32, i64 16
%36 = bitcast i8* %35 to <16 x i8>*
%37 = load <16 x i8>, <16 x i8>* %36
%38 = getelementptr inbounds i8, i8* %3, i64 %30
%39 = bitcast i8* %38 to <16 x i8>*
store <16 x i8> %34, <16 x i8>* %39
%40 = getelementptr inbounds i8, i8* %38, i64 16
%41 = bitcast i8* %40 to <16 x i8>*
store <16 x i8> %37, <16 x i8>* %41
%42 = or i64 %30, 32
%43 = getelementptr inbounds i8, i8* %0, i64 %42
%44 = bitcast i8* %43 to <16 x i8>*
%45 = load <16 x i8>, <16 x i8>* %44
%46 = getelementptr inbounds i8, i8* %43, i64 16
%47 = bitcast i8* %46 to <16 x i8>*
%48 = load <16 x i8>, <16 x i8>* %47
%49 = getelementptr inbounds i8, i8* %3, i64 %42
%50 = bitcast i8* %49 to <16 x i8>*
store <16 x i8> %45, <16 x i8>* %50
%51 = getelementptr inbounds i8, i8* %49, i64 16
%52 = bitcast i8* %51 to <16 x i8>*
store <16 x i8> %48, <16 x i8>* %52
%53 = or i64 %30, 64
%54 = getelementptr inbounds i8, i8* %0, i64 %53
%55 = bitcast i8* %54 to <16 x i8>*
%56 = load <16 x i8>, <16 x i8>* %55
%57 = getelementptr inbounds i8, i8* %54, i64 16
%58 = bitcast i8* %57 to <16 x i8>*
%59 = load <16 x i8>, <16 x i8>* %58
%60 = getelementptr inbounds i8, i8* %3, i64 %53
%61 = bitcast i8* %60 to <16 x i8>*
store <16 x i8> %56, <16 x i8>* %61
%62 = getelementptr inbounds i8, i8* %60, i64 16
%63 = bitcast i8* %62 to <16 x i8>*
store <16 x i8> %59, <16 x i8>* %63
%64 = or i64 %30, 96
%65 = getelementptr inbounds i8, i8* %0, i64 %64
%66 = bitcast i8* %65 to <16 x i8>*
%67 = load <16 x i8>, <16 x i8>* %66
%68 = getelementptr inbounds i8, i8* %65, i64 16
%69 = bitcast i8* %68 to <16 x i8>*
%70 = load <16 x i8>, <16 x i8>* %69
%71 = getelementptr inbounds i8, i8* %3, i64 %64
%72 = bitcast i8* %71 to <16 x i8>*
store <16 x i8> %67, <16 x i8>* %72
%73 = getelementptr inbounds i8, i8* %71, i64 16
%74 = bitcast i8* %73 to <16 x i8>*
store <16 x i8> %70, <16 x i8>* %74
%75 = add nuw i64 %30, 128
%76 = add i64 %31, 4
%77 = icmp eq i64 %76, %28
br i1 %77, label %78, label %29
78: ; preds = %29, %20
%79 = phi i64 [ 0, %20 ], [ %75, %29 ]
%80 = icmp eq i64 %25, 0
br i1 %80, label %97, label %81
81: ; preds = %78, %81
%82 = phi i64 [ %94, %81 ], [ %79, %78 ]
%83 = phi i64 [ %95, %81 ], [ 0, %78 ]
%84 = getelementptr inbounds i8, i8* %0, i64 %82
%85 = bitcast i8* %84 to <16 x i8>*
%86 = load <16 x i8>, <16 x i8>* %85
%87 = getelementptr inbounds i8, i8* %84, i64 16
%88 = bitcast i8* %87 to <16 x i8>*
%89 = load <16 x i8>, <16 x i8>* %88
%90 = getelementptr inbounds i8, i8* %3, i64 %82
%91 = bitcast i8* %90 to <16 x i8>*
store <16 x i8> %86, <16 x i8>* %91
%92 = getelementptr inbounds i8, i8* %90, i64 16
%93 = bitcast i8* %92 to <16 x i8>*
store <16 x i8> %89, <16 x i8>* %93
%94 = add nuw i64 %82, 32
%95 = add i64 %83, 1
%96 = icmp eq i64 %95, %25
br i1 %96, label %97, label %81
97: ; preds = %81, %78
%98 = icmp eq i64 %21, %4
br i1 %98, label %226, label %99
99: ; preds = %97
%100 = and i64 %4, 24
%101 = icmp eq i64 %100, 0
br i1 %101, label %116, label %102
102: ; preds = %18, %99
%103 = phi i64 [ %21, %99 ], [ 0, %18 ]
%104 = and i64 %4, -8
br label %105
105: ; preds = %105, %102
%106 = phi i64 [ %103, %102 ], [ %112, %105 ]
%107 = getelementptr inbounds i8, i8* %0, i64 %106
%108 = bitcast i8* %107 to <8 x i8>*
%109 = load <8 x i8>, <8 x i8>* %108
%110 = getelementptr inbounds i8, i8* %3, i64 %106
%111 = bitcast i8* %110 to <8 x i8>*
store <8 x i8> %109, <8 x i8>* %111
%112 = add nuw i64 %106, 8
%113 = icmp eq i64 %112, %104
br i1 %113, label %114, label %105
114: ; preds = %105
%115 = icmp eq i64 %104, %4
br i1 %115, label %226, label %116
116: ; preds = %12, %10, %99, %114
%117 = phi i64 [ 0, %10 ], [ 0, %12 ], [ %21, %99 ], [ %104, %114 ]
%118 = xor i64 %117, -1
%119 = add i64 %118, %4
%120 = and i64 %4, 3
%121 = icmp eq i64 %120, 0
br i1 %121, label %131, label %122
122: ; preds = %116, %122
%123 = phi i64 [ %128, %122 ], [ %117, %116 ]
%124 = phi i64 [ %129, %122 ], [ 0, %116 ]
%125 = getelementptr inbounds i8, i8* %0, i64 %123
%126 = load i8, i8* %125
%127 = getelementptr inbounds i8, i8* %3, i64 %123
store i8 %126, i8* %127
%128 = add nuw nsw i64 %123, 1
%129 = add i64 %124, 1
%130 = icmp eq i64 %129, %120
br i1 %130, label %131, label %122
131: ; preds = %122, %116
%132 = phi i64 [ %117, %116 ], [ %128, %122 ]
%133 = icmp ult i64 %119, 3
br i1 %133, label %226, label %134
134: ; preds = %131, %134
%135 = phi i64 [ %151, %134 ], [ %132, %131 ]
%136 = getelementptr inbounds i8, i8* %0, i64 %135
%137 = load i8, i8* %136
%138 = getelementptr inbounds i8, i8* %3, i64 %135
store i8 %137, i8* %138
%139 = add nuw nsw i64 %135, 1
%140 = getelementptr inbounds i8, i8* %0, i64 %139
%141 = load i8, i8* %140
%142 = getelementptr inbounds i8, i8* %3, i64 %139
store i8 %141, i8* %142
%143 = add nuw nsw i64 %135, 2
%144 = getelementptr inbounds i8, i8* %0, i64 %143
%145 = load i8, i8* %144
%146 = getelementptr inbounds i8, i8* %3, i64 %143
store i8 %145, i8* %146
%147 = add nuw nsw i64 %135, 3
%148 = getelementptr inbounds i8, i8* %0, i64 %147
%149 = load i8, i8* %148
%150 = getelementptr inbounds i8, i8* %3, i64 %147
store i8 %149, i8* %150
%151 = add nuw nsw i64 %135, 4
%152 = icmp eq i64 %151, %4
br i1 %152, label %226, label %134
153: ; preds = %6
%154 = tail call i8* @malloc(i64 %4)
%155 = icmp eq i8* %154, null
br i1 %155, label %156, label %158
156: ; preds = %153
%157 = tail call i32 (...) @abort()
unreachable
158: ; preds = %153
%159 = tail call i8* @malloc(i64 %4)
%160 = icmp eq i8* %159, null
br i1 %160, label %161, label %163
161: ; preds = %158
%162 = tail call i32 (...) @abort()
unreachable
163: ; preds = %158
%164 = add i64 %4, -1
%165 = add i64 %164, %5
%166 = mul i64 %165, %4
%167 = tail call i8* @malloc(i64 %166)
%168 = icmp eq i8* %167, null
br i1 %168, label %169, label %171
169: ; preds = %163
%170 = tail call i32 (...) @abort()
unreachable
171: ; preds = %163
%172 = add i64 %5, -1
%173 = sub i64 %4, %172
%174 = tail call i32 @memset(i8* %2, i32 0, i64 %173)
%175 = tail call i32 @gen_conv_matrix(i8* %1, i8* %167, i64 %172, i64 %164)
%176 = icmp eq i64 %4, 0
%177 = trunc i64 %5 to i32
%178 = getelementptr inbounds i8, i8* %1, i64 %172
%179 = shl i64 %4, 32
%180 = ashr exact i64 %179, 32
%181 = icmp sgt i32 %177, 0
br label %182
182: ; preds = %212, %171
%183 = tail call i32 @inner_product_set(i8* %154, i8* %167, i8* %2, i64 %173, i64 %4)
br i1 %176, label %194, label %184
184: ; preds = %182, %184
%185 = phi i64 [ %192, %184 ], [ 0, %182 ]
%186 = getelementptr inbounds i8, i8* %0, i64 %185
%187 = load i8, i8* %186
%188 = getelementptr inbounds i8, i8* %154, i64 %185
%189 = load i8, i8* %188
%190 = tail call zeroext i8 @sum(i8 zeroext %187, i8 zeroext %189)
%191 = getelementptr inbounds i8, i8* %159, i64 %185
store i8 %190, i8* %191
%192 = add nuw i64 %185, 1
%193 = icmp eq i64 %192, %4
br i1 %193, label %194, label %184
194: ; preds = %184, %182
br label %195
195: ; preds = %194, %199
%196 = phi i64 [ %197, %199 ], [ %180, %194 ]
%197 = add nsw i64 %196, -1
%198 = icmp eq i64 %196, 0
br i1 %198, label %206, label %199
199: ; preds = %195
%200 = getelementptr inbounds i8, i8* %159, i64 %197
%201 = load i8, i8* %200
%202 = icmp eq i8 %201, 0
br i1 %202, label %195, label %203
203: ; preds = %199
%204 = trunc i64 %196 to i32
%205 = icmp slt i32 %204, %177
br i1 %205, label %207, label %212
206: ; preds = %195
br i1 %181, label %222, label %212
207: ; preds = %203
%208 = trunc i64 %196 to i32
%209 = icmp sgt i32 %208, 0
br i1 %209, label %210, label %222
210: ; preds = %207
%211 = and i64 %196, 4294967295
br label %222
212: ; preds = %203, %206
%213 = phi i64 [ -1, %206 ], [ %197, %203 ]
%214 = shl i64 %213, 32
%215 = ashr exact i64 %214, 32
%216 = getelementptr inbounds i8, i8* %159, i64 %215
%217 = load i8, i8* %216
%218 = load i8, i8* %178
%219 = tail call zeroext i8 @divide(i8 zeroext %217, i8 zeroext %218)
%220 = sub i64 %215, %172
%221 = getelementptr inbounds i8, i8* %2, i64 %220
store i8 %219, i8* %221
br label %182
222: ; preds = %206, %207, %210
%223 = tail call i32 @free(i8* %154)
%224 = tail call i32 @free(i8* %159)
%225 = tail call i32 @free(i8* %167)
br label %226
226: ; preds = %131, %134, %97, %114, %222, %8
ret void
}