#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 /*<<< orphan*/ subres;
typedef int /*<<< orphan*/ diversion;
typedef int /*<<< orphan*/ a;

/* Variables and functions */
int /*<<< orphan*/ bcopy(unsigned char *, unsigned char *, int);
int /*<<< orphan*/ bzero(unsigned char *, int);
int subtraction(unsigned char *a, int a_len, unsigned char *b, int b_len,
                unsigned char *subres) {
  int i, j, k;
  unsigned char diversion[20];
  bzero(diversion, sizeof(diversion));
  bzero(subres, sizeof(subres));
  if (a_len != b_len) {
    for (i = a_len, j = b_len; j >= 0; i--, j--) {
      b[i] = b[j];
      b[j] = 0;
    }
  }
  bcopy(a, diversion, sizeof(a));
  for (i = a_len; i >= 0; i--) {
    if (diversion[i] >= b[i])
      subres[i] = diversion[i] - b[i];
    else {
      j = i - 1;
      while (1) {
        if (diversion[j] > 0) {
          diversion[j]--;
          subres[i] = 256 - b[i] + diversion[i];
          break;
        } else
          diversion[j] = 255;
        j--;
      }
    }
  }
  if (a_len != b_len) {
    b_len = a_len;
    for (i = 0; i <= b_len; i++) {
      if (b[i] > 0)
        break;
      else {
        for (j = 0, k = 1; k <= b_len; j++, k++)
          b[j] = b[k];
        b[b_len] = 0;
        b_len--;
      }
    }
  }
  for (i = 0; i <= a_len; i++) {
    if (subres[i] > 0)
      break;
    else {
      for (j = 0, k = 1; k <= a_len; j++, k++)
        subres[j] = subres[k];
      subres[a_len] = 0;
      a_len--;
    }
  }
  return a_len;
}


x86 assembly (clang, -O0):
<subtraction>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
mov    %ecx,-0x1c(%rbp)
mov    %r8,-0x28(%rbp)
lea    -0x50(%rbp),%rdi
mov    $0x14,%esi
call   1040 <bzero@plt>
mov    -0x28(%rbp),%rdi
mov    $0x8,%esi
call   1040 <bzero@plt>
mov    -0xc(%rbp),%eax
cmp    -0x1c(%rbp),%eax
je     11b6 <subtraction+0x96>
mov    -0xc(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x1c(%rbp),%eax
mov    %eax,-0x30(%rbp)
cmpl   $0x0,-0x30(%rbp)
jl     11b1 <subtraction+0x91>
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x30(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x30(%rbp)
jmp    116e <subtraction+0x4e>
jmp    11b6 <subtraction+0x96>
mov    -0x8(%rbp),%rdi
lea    -0x50(%rbp),%rsi
mov    $0x8,%edx
call   1030 <bcopy@plt>
mov    -0xc(%rbp),%eax
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x2c(%rbp)
jl     12a7 <subtraction+0x187>
movslq -0x2c(%rbp),%rax
movzbl -0x50(%rbp,%rax,1),%eax
mov    -0x18(%rbp),%rcx
movslq -0x2c(%rbp),%rdx
movzbl (%rcx,%rdx,1),%ecx
cmp    %ecx,%eax
jl     121e <subtraction+0xfe>
movslq -0x2c(%rbp),%rax
movzbl -0x50(%rbp,%rax,1),%eax
mov    -0x18(%rbp),%rcx
movslq -0x2c(%rbp),%rdx
movzbl (%rcx,%rdx,1),%ecx
sub    %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    1294 <subtraction+0x174>
mov    -0x2c(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x30(%rbp)
movslq -0x30(%rbp),%rax
movzbl -0x50(%rbp,%rax,1),%eax
cmp    $0x0,%eax
jle    1278 <subtraction+0x158>
movslq -0x30(%rbp),%rax
mov    -0x50(%rbp,%rax,1),%cl
add    $0xff,%cl
mov    %cl,-0x50(%rbp,%rax,1)
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movzbl (%rax,%rcx,1),%ecx
mov    $0x100,%eax
sub    %ecx,%eax
movslq -0x2c(%rbp),%rcx
movzbl -0x50(%rbp,%rcx,1),%ecx
add    %ecx,%eax
mov    %al,%dl
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
jmp    128f <subtraction+0x16f>
movslq -0x30(%rbp),%rax
movb   $0xff,-0x50(%rbp,%rax,1)
mov    -0x30(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x30(%rbp)
jmp    1227 <subtraction+0x107>
jmp    1294 <subtraction+0x174>
jmp    1299 <subtraction+0x179>
mov    -0x2c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x2c(%rbp)
jmp    11ce <subtraction+0xae>
mov    -0xc(%rbp),%eax
cmp    -0x1c(%rbp),%eax
je     135a <subtraction+0x23a>
mov    -0xc(%rbp),%eax
mov    %eax,-0x1c(%rbp)
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jg     1355 <subtraction+0x235>
mov    -0x18(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
jle    12e6 <subtraction+0x1c6>
jmp    1355 <subtraction+0x235>
movl   $0x0,-0x30(%rbp)
movl   $0x1,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x1c(%rbp),%eax
jg     132d <subtraction+0x20d>
mov    -0x18(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x18(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    12f4 <subtraction+0x1d4>
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    1347 <subtraction+0x227>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    12c0 <subtraction+0x1a0>
jmp    135a <subtraction+0x23a>
movl   $0x0,-0x2c(%rbp)
mov    -0x2c(%rbp),%eax
cmp    -0xc(%rbp),%eax
jg     13f6 <subtraction+0x2d6>
mov    -0x28(%rbp),%rax
movslq -0x2c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
jle    1387 <subtraction+0x267>
jmp    13f6 <subtraction+0x2d6>
movl   $0x0,-0x30(%rbp)
movl   $0x1,-0x34(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0xc(%rbp),%eax
jg     13ce <subtraction+0x2ae>
mov    -0x28(%rbp),%rax
movslq -0x34(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x28(%rbp),%rax
movslq -0x30(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x30(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x30(%rbp)
mov    -0x34(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    1395 <subtraction+0x275>
mov    -0x28(%rbp),%rax
movslq -0xc(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
jmp    13e8 <subtraction+0x2c8>
mov    -0x2c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x2c(%rbp)
jmp    1361 <subtraction+0x241>
mov    -0xc(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<subtraction>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %r8,%r14
mov    %ecx,%r13d
mov    %rdx,%r15
mov    %esi,%r12d
mov    %rdi,0x8(%rsp)
lea    0x10(%rsp),%rbp
mov    %rbp,%rdi
mov    $0x14,%esi
call   1040 <bzero@plt>
mov    %r14,%rdi
mov    $0x8,%esi
call   1040 <bzero@plt>
cmp    %r13d,%r12d
je     1242 <subtraction+0x122>
test   %r13d,%r13d
js     1242 <subtraction+0x122>
mov    %r13d,%r11d
movslq %r12d,%rax
cmp    $0x3,%r13d
jae    11a1 <subtraction+0x81>
test   $0x1,%r11b
jne    11fe <subtraction+0xde>
mov    (%r15,%r11,1),%cl
mov    %cl,(%r15,%rax,1)
movb   $0x0,(%r15,%r11,1)
add    $0xffffffffffffffff,%rax
lea    -0x1(%r11),%rdx
test   %r11,%r11
jne    1206 <subtraction+0xe6>
jmp    1242 <subtraction+0x122>
lea    (%r15,%rax,1),%rcx
mov    %rcx,%rdx
sub    %r11,%rdx
cmp    %rcx,%rdx
ja     117c <subtraction+0x5c>
lea    (%r15,%r11,1),%rcx
cmp    %r15,%rcx
jb     117c <subtraction+0x5c>
mov    %rax,%rcx
sub    %r11,%rcx
add    %r15,%rcx
lea    (%r11,%r15,1),%rdx
add    $0x1,%rdx
cmp    %rdx,%rcx
jae    11dc <subtraction+0xbc>
lea    (%rax,%r15,1),%rcx
add    $0x1,%rcx
cmp    %r15,%rcx
ja     117c <subtraction+0x5c>
lea    0x1(%r11),%r8
movabs $0x1fffffff0,%r9
mov    %rbp,%rbx
cmp    $0xf,%r13d
jae    1393 <subtraction+0x273>
xor    %edi,%edi
jmp    147a <subtraction+0x35a>
mov    %r11,%rdx
test   %r11,%r11
je     1242 <subtraction+0x122>
add    %r15,%rax
lea    (%r15,%rdx,1),%rcx
not    %rdx
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movzbl (%rcx,%rsi,1),%ebx
mov    %bl,(%rax,%rsi,1)
movb   $0x0,(%rcx,%rsi,1)
movzbl -0x1(%rcx,%rsi,1),%ebx
mov    %bl,-0x1(%rax,%rsi,1)
movb   $0x0,-0x1(%rcx,%rsi,1)
add    $0xfffffffffffffffe,%rsi
cmp    %rsi,%rdx
jne    1220 <subtraction+0x100>
mov    0x8(%rsp),%rax
mov    (%rax),%rax
mov    %rax,0x10(%rsp)
test   %r12d,%r12d
js     1381 <subtraction+0x261>
mov    %r12d,%ecx
lea    (%rcx,%rbp,1),%rax
add    $0xfffffffffffffffe,%rax
mov    %rcx,0x8(%rsp)
jmp    1284 <subtraction+0x164>
nopw   0x0(%rax,%rax,1)
mov    %bl,(%r14,%rcx,1)
lea    -0x1(%rcx),%rdi
add    $0xffffffffffffffff,%rax
test   %rcx,%rcx
mov    %rdi,%rcx
jle    12dd <subtraction+0x1bd>
mov    0x10(%rsp,%rcx,1),%bl
mov    (%r15,%rcx,1),%dl
sub    %dl,%bl
jae    1270 <subtraction+0x150>
lea    (%rsp,%rcx,1),%rsi
add    $0xf,%rsi
mov    0xf(%rsp,%rcx,1),%bl
mov    %rax,%rdi
test   %bl,%bl
jne    12c8 <subtraction+0x1a8>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movb   $0xff,(%rsi)
mov    %rdi,%rsi
movzbl (%rdi),%ebx
add    $0xffffffffffffffff,%rdi
test   %bl,%bl
je     12b0 <subtraction+0x190>
add    $0x1,%rdi
mov    %rdi,%rsi
lea    -0x1(%rcx),%rdi
add    $0xff,%bl
mov    %bl,(%rsi)
mov    0x10(%rsp,%rcx,1),%bl
sub    %dl,%bl
mov    %bl,(%r14,%rcx,1)
jmp    1278 <subtraction+0x158>
cmp    %r13d,%r12d
je     1331 <subtraction+0x211>
test   %r12d,%r12d
js     1331 <subtraction+0x211>
lea    0x1(%r15),%rbx
xor    %r13d,%r13d
mov    0x8(%rsp),%rbp
jmp    1315 <subtraction+0x1f5>
cs nopw 0x0(%rax,%rax,1)
nop
movb   $0x0,(%r15,%rbp,1)
add    $0xffffffffffffffff,%rbp
lea    0x1(%r13),%rax
cmp    %rbp,%r13
mov    %rax,%r13
jge    1331 <subtraction+0x211>
cmpb   $0x0,(%r15,%r13,1)
jne    1331 <subtraction+0x211>
test   %rbp,%rbp
jle    1300 <subtraction+0x1e0>
mov    %r15,%rdi
mov    %rbx,%rsi
mov    %rbp,%rdx
call   1030 <memmove@plt>
jmp    1300 <subtraction+0x1e0>
test   %r12d,%r12d
js     1381 <subtraction+0x261>
lea    0x1(%r14),%r15
xor    %ebp,%ebp
mov    0x8(%rsp),%r12
jmp    1365 <subtraction+0x245>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movb   $0x0,(%r14,%r12,1)
add    $0xffffffffffffffff,%r12
lea    0x1(%rbp),%rax
cmp    %r12,%rbp
mov    %rax,%rbp
jge    1381 <subtraction+0x261>
cmpb   $0x0,(%r14,%rbp,1)
jne    1381 <subtraction+0x261>
test   %r12,%r12
jle    1350 <subtraction+0x230>
mov    %r14,%rdi
mov    %r15,%rsi
mov    %r12,%rdx
call   1030 <memmove@plt>
jmp    1350 <subtraction+0x230>
mov    %r12d,%eax
add    $0x28,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret
mov    %r8,%rdi
and    %r9,%rdi
lea    -0x10(%rdi),%rcx
mov    %rcx,%rdx
shr    $0x4,%rdx
add    $0x1,%rdx
mov    %edx,%r10d
and    $0x3,%r10d
cmp    $0x30,%rcx
jae    13b9 <subtraction+0x299>
xor    %esi,%esi
jmp    1427 <subtraction+0x307>
and    $0xfffffffffffffffc,%rdx
lea    (%rax,%r15,1),%rbp
add    $0xfffffffffffffff1,%rbp
lea    (%r11,%r15,1),%rcx
add    $0xfffffffffffffff1,%rcx
xor    %esi,%esi
xorps  %xmm0,%xmm0
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movups (%rcx,%rsi,1),%xmm1
movups %xmm1,0x0(%rbp,%rsi,1)
movups %xmm0,(%rcx,%rsi,1)
movups -0x10(%rcx,%rsi,1),%xmm1
movups %xmm1,-0x10(%rbp,%rsi,1)
movups %xmm0,-0x10(%rcx,%rsi,1)
movups -0x20(%rcx,%rsi,1),%xmm1
movups %xmm1,-0x20(%rbp,%rsi,1)
movups %xmm0,-0x20(%rcx,%rsi,1)
movups -0x30(%rcx,%rsi,1),%xmm1
movups %xmm1,-0x30(%rbp,%rsi,1)
movups %xmm0,-0x30(%rcx,%rsi,1)
add    $0xffffffffffffffc0,%rsi
add    $0xfffffffffffffffc,%rdx
jne    13e0 <subtraction+0x2c0>
neg    %rsi
test   %r10,%r10
je     1468 <subtraction+0x348>
mov    %r11,%rcx
sub    %rsi,%rcx
add    %r15,%rcx
add    $0xfffffffffffffff1,%rcx
mov    %rax,%rdx
sub    %rsi,%rdx
add    %r15,%rdx
add    $0xfffffffffffffff1,%rdx
shl    $0x4,%r10
xor    %esi,%esi
xorps  %xmm0,%xmm0
nop
movups (%rcx,%rsi,1),%xmm1
movups %xmm1,(%rdx,%rsi,1)
movups %xmm0,(%rcx,%rsi,1)
add    $0xfffffffffffffff0,%rsi
mov    %r10,%rbp
add    %rsi,%rbp
jne    1450 <subtraction+0x330>
cmp    %rdi,%r8
mov    %rbx,%rbp
je     1242 <subtraction+0x122>
test   $0xc,%r8b
je     14d7 <subtraction+0x3b7>
add    $0xc,%r9
and    %r8,%r9
mov    %r8,%rcx
and    $0xfffffffffffffffc,%rcx
neg    %rcx
neg    %rdi
lea    (%r11,%r15,1),%rdx
add    $0xfffffffffffffffd,%rdx
sub    %r9,%r11
lea    (%rax,%r15,1),%rsi
add    $0xfffffffffffffffd,%rsi
sub    %r9,%rax
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    (%rdx,%rdi,1),%ebp
mov    %ebp,(%rsi,%rdi,1)
movl   $0x0,(%rdx,%rdi,1)
add    $0xfffffffffffffffc,%rdi
cmp    %rdi,%rcx
jne    14b0 <subtraction+0x390>
cmp    %r9,%r8
mov    %rbx,%rbp
jne    117c <subtraction+0x5c>
jmp    1242 <subtraction+0x122>
sub    %rdi,%r11
sub    %rdi,%rax
jmp    117c <subtraction+0x5c>

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

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