#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 */
size_t SIZE_MAX;
scalar_t__ isupper(unsigned char const);
unsigned char const tolower(unsigned char const);
size_t critical_factorization(const unsigned char *needle, size_t needle_len,
                              size_t *period) {
  size_t max_suffix, max_suffix_rev;
  size_t j;
  size_t k;
  size_t p;
  unsigned char a, b;
  if (needle_len < 3) {
    *period = 1;
    return needle_len - 1;
  }
  max_suffix = SIZE_MAX;
  j = 0;
  k = p = 1;
  while (j + k < needle_len) {
    a = (isupper(needle[j + k]) ? tolower(needle[j + k]) : (needle[j + k]));
    b = (isupper(needle[max_suffix + k]) ? tolower(needle[max_suffix + k])
                                         : (needle[max_suffix + k]));
    if (a < b) {
      j += k;
      k = 1;
      p = j - max_suffix;
    } else if (a == b) {
      if (k != p)
        ++k;
      else {
        j += p;
        k = 1;
      }
    } else {
      max_suffix = j++;
      k = p = 1;
    }
  }
  *period = p;
  max_suffix_rev = SIZE_MAX;
  j = 0;
  k = p = 1;
  while (j + k < needle_len) {
    a = (isupper(needle[j + k]) ? tolower(needle[j + k]) : (needle[j + k]));
    b = (isupper(needle[max_suffix_rev + k])
             ? tolower(needle[max_suffix_rev + k])
             : (needle[max_suffix_rev + k]));
    if (b < a) {
      j += k;
      k = 1;
      p = j - max_suffix_rev;
    } else if (a == b) {
      if (k != p)
        ++k;
      else {
        j += p;
        k = 1;
      }
    } else {
      max_suffix_rev = j++;
      k = p = 1;
    }
  }
  if (max_suffix_rev + 1 < max_suffix + 1)
    return max_suffix + 1;
  *period = p;
  return max_suffix_rev + 1;
}


x86 assembly (clang, -O0):
<critical_factorization>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0x3,-0x18(%rbp)
jae    115b <critical_factorization+0x3b>
mov    -0x20(%rbp),%rax
movq   $0x1,(%rax)
mov    -0x18(%rbp),%rax
sub    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    14cb <critical_factorization+0x3ab>
mov    0x2e76(%rip),%rax
mov    (%rax),%rax
mov    %rax,-0x28(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x1,-0x48(%rbp)
movq   $0x1,-0x40(%rbp)
mov    -0x38(%rbp),%rax
add    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    12ed <critical_factorization+0x1cd>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1040 <isupper@plt>
cmp    $0x0,%rax
je     11d2 <critical_factorization+0xb2>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1030 <tolower@plt>
movzbl %al,%eax
mov    %eax,-0x50(%rbp)
jmp    11e5 <critical_factorization+0xc5>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    %al,-0x49(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1040 <isupper@plt>
cmp    $0x0,%rax
je     122a <critical_factorization+0x10a>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1030 <tolower@plt>
movzbl %al,%eax
mov    %eax,-0x54(%rbp)
jmp    123d <critical_factorization+0x11d>
mov    -0x10(%rbp),%rax
mov    -0x28(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x54(%rbp)
mov    -0x54(%rbp),%eax
mov    %al,-0x4a(%rbp)
movzbl -0x49(%rbp),%eax
movzbl -0x4a(%rbp),%ecx
cmp    %ecx,%eax
jge    1278 <critical_factorization+0x158>
mov    -0x40(%rbp),%rax
add    -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x1,-0x40(%rbp)
mov    -0x38(%rbp),%rax
sub    -0x28(%rbp),%rax
mov    %rax,-0x48(%rbp)
jmp    12e8 <critical_factorization+0x1c8>
movzbl -0x49(%rbp),%eax
movzbl -0x4a(%rbp),%ecx
cmp    %ecx,%eax
jne    12c0 <critical_factorization+0x1a0>
mov    -0x40(%rbp),%rax
cmp    -0x48(%rbp),%rax
je     12a7 <critical_factorization+0x187>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    12bb <critical_factorization+0x19b>
mov    -0x48(%rbp),%rax
add    -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x1,-0x40(%rbp)
jmp    12e3 <critical_factorization+0x1c3>
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    %rax,-0x28(%rbp)
movq   $0x1,-0x48(%rbp)
movq   $0x1,-0x40(%rbp)
jmp    12e8 <critical_factorization+0x1c8>
jmp    1181 <critical_factorization+0x61>
mov    -0x48(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    0x2cd9(%rip),%rax
mov    (%rax),%rax
mov    %rax,-0x30(%rbp)
movq   $0x0,-0x38(%rbp)
movq   $0x1,-0x48(%rbp)
movq   $0x1,-0x40(%rbp)
mov    -0x38(%rbp),%rax
add    -0x40(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    148a <critical_factorization+0x36a>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1040 <isupper@plt>
cmp    $0x0,%rax
je     136f <critical_factorization+0x24f>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1030 <tolower@plt>
movzbl %al,%eax
mov    %eax,-0x58(%rbp)
jmp    1382 <critical_factorization+0x262>
mov    -0x10(%rbp),%rax
mov    -0x38(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x58(%rbp)
mov    -0x58(%rbp),%eax
mov    %al,-0x49(%rbp)
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1040 <isupper@plt>
cmp    $0x0,%rax
je     13c7 <critical_factorization+0x2a7>
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%edi
call   1030 <tolower@plt>
movzbl %al,%eax
mov    %eax,-0x5c(%rbp)
jmp    13da <critical_factorization+0x2ba>
mov    -0x10(%rbp),%rax
mov    -0x30(%rbp),%rcx
add    -0x40(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x5c(%rbp)
mov    -0x5c(%rbp),%eax
mov    %al,-0x4a(%rbp)
movzbl -0x4a(%rbp),%eax
movzbl -0x49(%rbp),%ecx
cmp    %ecx,%eax
jge    1415 <critical_factorization+0x2f5>
mov    -0x40(%rbp),%rax
add    -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x1,-0x40(%rbp)
mov    -0x38(%rbp),%rax
sub    -0x30(%rbp),%rax
mov    %rax,-0x48(%rbp)
jmp    1485 <critical_factorization+0x365>
movzbl -0x49(%rbp),%eax
movzbl -0x4a(%rbp),%ecx
cmp    %ecx,%eax
jne    145d <critical_factorization+0x33d>
mov    -0x40(%rbp),%rax
cmp    -0x48(%rbp),%rax
je     1444 <critical_factorization+0x324>
mov    -0x40(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x40(%rbp)
jmp    1458 <critical_factorization+0x338>
mov    -0x48(%rbp),%rax
add    -0x38(%rbp),%rax
mov    %rax,-0x38(%rbp)
movq   $0x1,-0x40(%rbp)
jmp    1480 <critical_factorization+0x360>
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x38(%rbp)
mov    %rax,-0x30(%rbp)
movq   $0x1,-0x48(%rbp)
movq   $0x1,-0x40(%rbp)
jmp    1485 <critical_factorization+0x365>
jmp    131e <critical_factorization+0x1fe>
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    -0x28(%rbp),%rcx
add    $0x1,%rcx
cmp    %rcx,%rax
jae    14b4 <critical_factorization+0x394>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
jmp    14cb <critical_factorization+0x3ab>
mov    -0x48(%rbp),%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<critical_factorization>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x38,%rsp
mov    %rdi,0x18(%rsp)
cmp    $0x2,%rsi
ja     114c <critical_factorization+0x2c>
movq   $0x1,(%rdx)
add    $0xffffffffffffffff,%rsi
mov    %rsi,%r15
jmp    137b <critical_factorization+0x25b>
mov    %rdx,0x28(%rsp)
mov    0x2e80(%rip),%rax
mov    (%rax),%r15
mov    $0x1,%ebp
xor    %eax,%eax
mov    $0x1,%edx
mov    $0x1,%r14d
mov    %rsi,0x10(%rsp)
jmp    11a3 <critical_factorization+0x83>
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
mov    0x8(%rsp),%r15
lea    0x1(%r15),%rbp
mov    $0x1,%r14d
mov    $0x1,%edx
mov    %rbp,%rax
add    %r14,%rbp
cmp    %rcx,%rbp
jae    1248 <critical_factorization+0x128>
mov    %rax,0x8(%rsp)
mov    %rdx,0x20(%rsp)
mov    0x18(%rsp),%rbx
movzbl (%rbx,%rbp,1),%edi
call   1040 <isupper@plt>
movzbl (%rbx,%rbp,1),%ebx
test   %rax,%rax
je     11ce <critical_factorization+0xae>
movzbl %bl,%edi
call   1030 <tolower@plt>
mov    %eax,%ebx
mov    %r15,%r13
mov    %r14,%r12
add    %r14,%r15
mov    0x18(%rsp),%r14
movzbl (%r14,%r15,1),%edi
call   1040 <isupper@plt>
mov    %rax,%rcx
movzbl (%r14,%r15,1),%eax
test   %rcx,%rcx
je     11fb <critical_factorization+0xdb>
movzbl %al,%edi
call   1030 <tolower@plt>
mov    %r13,%r15
mov    0x10(%rsp),%rcx
mov    %r12,%r14
cmp    %al,%bl
jae    1220 <critical_factorization+0x100>
mov    %rbp,%rdx
sub    %r15,%rdx
mov    $0x1,%r14d
jmp    1194 <critical_factorization+0x74>
nopl   0x0(%rax,%rax,1)
jne    1180 <critical_factorization+0x60>
mov    0x20(%rsp),%rdx
cmp    %rdx,%r14
jne    123a <critical_factorization+0x11a>
mov    0x8(%rsp),%rbp
add    %rdx,%rbp
jmp    1210 <critical_factorization+0xf0>
add    $0x1,%r14
mov    0x8(%rsp),%rbp
jmp    1194 <critical_factorization+0x74>
mov    0x28(%rsp),%rax
mov    %rdx,(%rax)
mov    0x2d81(%rip),%rax
mov    (%rax),%r13
mov    $0x1,%edx
cmp    $0x2,%rcx
jb     1363 <critical_factorization+0x243>
mov    $0x1,%r14d
xor    %r12d,%r12d
mov    $0x1,%edx
mov    $0x1,%eax
mov    %r15,0x30(%rsp)
jmp    12aa <critical_factorization+0x18a>
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %r14,%rdx
sub    %r13,%rdx
mov    $0x1,%eax
mov    %r14,%r12
add    %rax,%r14
cmp    %rcx,%r14
jae    1363 <critical_factorization+0x243>
mov    %rax,0x8(%rsp)
mov    %rdx,0x20(%rsp)
mov    0x18(%rsp),%rbx
movzbl (%rbx,%r14,1),%edi
call   1040 <isupper@plt>
movzbl (%rbx,%r14,1),%ebx
test   %rax,%rax
je     12d7 <critical_factorization+0x1b7>
movzbl %bl,%edi
call   1030 <tolower@plt>
mov    %eax,%ebx
mov    0x8(%rsp),%rax
mov    %r13,%rbp
lea    (%rax,%r13,1),%r15
mov    0x18(%rsp),%r13
movzbl 0x0(%r13,%r15,1),%edi
call   1040 <isupper@plt>
mov    %rax,%rcx
movzbl 0x0(%r13,%r15,1),%eax
test   %rcx,%rcx
je     1309 <critical_factorization+0x1e9>
movzbl %al,%edi
call   1030 <tolower@plt>
mov    0x30(%rsp),%r15
mov    0x10(%rsp),%rcx
mov    %rbp,%r13
cmp    %bl,%al
jb     1290 <critical_factorization+0x170>
jne    1340 <critical_factorization+0x220>
mov    0x20(%rsp),%rdx
mov    0x8(%rsp),%rax
cmp    %rdx,%rax
jne    1357 <critical_factorization+0x237>
add    %rdx,%r12
mov    $0x1,%eax
mov    %r12,%r14
jmp    129b <critical_factorization+0x17b>
nop
lea    0x1(%r12),%r14
mov    $0x1,%eax
mov    %r12,%r13
mov    $0x1,%edx
jmp    129b <critical_factorization+0x17b>
add    $0x1,%rax
mov    %r12,%r14
jmp    129b <critical_factorization+0x17b>
add    $0x1,%r13
add    $0x1,%r15
cmp    %r15,%r13
jb     137b <critical_factorization+0x25b>
mov    0x28(%rsp),%rax
mov    %rdx,(%rax)
mov    %r13,%r15
mov    %r15,%rax
add    $0x38,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
@SIZE_MAX = global i64 0
define i64 @critical_factorization(i8* nocapture %0, i64 %1, i64* nocapture writeonly %2) {
%4 = icmp ult i64 %1, 3
br i1 %4, label %5, label %7
5: ; preds = %3
store i64 1, i64* %2
%6 = add nsw i64 %1, -1
br label %109
7: ; preds = %3
%8 = load i64, i64* @SIZE_MAX
br label %9
9: ; preds = %7, %47
%10 = phi i64 [ %52, %47 ], [ 1, %7 ]
%11 = phi i64 [ %51, %47 ], [ 1, %7 ]
%12 = phi i64 [ %50, %47 ], [ 1, %7 ]
%13 = phi i64 [ %49, %47 ], [ 0, %7 ]
%14 = phi i64 [ %48, %47 ], [ %8, %7 ]
%15 = getelementptr inbounds i8, i8* %0, i64 %10
%16 = load i8, i8* %15
%17 = tail call i64 @isupper(i8 zeroext %16)
%18 = icmp eq i64 %17, 0
%19 = load i8, i8* %15
br i1 %18, label %22, label %20
20: ; preds = %9
%21 = tail call zeroext i8 @tolower(i8 zeroext %19)
br label %22
22: ; preds = %9, %20
%23 = phi i8 [ %21, %20 ], [ %19, %9 ]
%24 = add i64 %12, %14
%25 = getelementptr inbounds i8, i8* %0, i64 %24
%26 = load i8, i8* %25
%27 = tail call i64 @isupper(i8 zeroext %26)
%28 = icmp eq i64 %27, 0
%29 = load i8, i8* %25
br i1 %28, label %32, label %30
30: ; preds = %22
%31 = tail call zeroext i8 @tolower(i8 zeroext %29)
br label %32
32: ; preds = %22, %30
%33 = phi i8 [ %31, %30 ], [ %29, %22 ]
%34 = icmp ult i8 %23, %33
br i1 %34, label %35, label %37
35: ; preds = %32
%36 = sub i64 %10, %14
br label %47
37: ; preds = %32
%38 = icmp eq i8 %23, %33
br i1 %38, label %39, label %45
39: ; preds = %37
%40 = icmp eq i64 %12, %11
br i1 %40, label %43, label %41
41: ; preds = %39
%42 = add i64 %12, 1
br label %47
43: ; preds = %39
%44 = add i64 %11, %13
br label %47
45: ; preds = %37
%46 = add i64 %13, 1
br label %47
47: ; preds = %45, %43, %41, %35
%48 = phi i64 [ %14, %35 ], [ %14, %41 ], [ %14, %43 ], [ %13, %45 ]
%49 = phi i64 [ %10, %35 ], [ %13, %41 ], [ %44, %43 ], [ %46, %45 ]
%50 = phi i64 [ 1, %35 ], [ %42, %41 ], [ 1, %43 ], [ 1, %45 ]
%51 = phi i64 [ %36, %35 ], [ %11, %41 ], [ %11, %43 ], [ 1, %45 ]
%52 = add i64 %50, %49
%53 = icmp ult i64 %52, %1
br i1 %53, label %9, label %54
54: ; preds = %47
store i64 %51, i64* %2
%55 = load i64, i64* @SIZE_MAX
%56 = icmp ugt i64 %1, 1
br i1 %56, label %57, label %102
57: ; preds = %54, %95
%58 = phi i64 [ %100, %95 ], [ 1, %54 ]
%59 = phi i64 [ %99, %95 ], [ 1, %54 ]
%60 = phi i64 [ %98, %95 ], [ 1, %54 ]
%61 = phi i64 [ %97, %95 ], [ 0, %54 ]
%62 = phi i64 [ %96, %95 ], [ %55, %54 ]
%63 = getelementptr inbounds i8, i8* %0, i64 %58
%64 = load i8, i8* %63
%65 = tail call i64 @isupper(i8 zeroext %64)
%66 = icmp eq i64 %65, 0
%67 = load i8, i8* %63
br i1 %66, label %70, label %68
68: ; preds = %57
%69 = tail call zeroext i8 @tolower(i8 zeroext %67)
br label %70
70: ; preds = %57, %68
%71 = phi i8 [ %69, %68 ], [ %67, %57 ]
%72 = add i64 %60, %62
%73 = getelementptr inbounds i8, i8* %0, i64 %72
%74 = load i8, i8* %73
%75 = tail call i64 @isupper(i8 zeroext %74)
%76 = icmp eq i64 %75, 0
%77 = load i8, i8* %73
br i1 %76, label %80, label %78
78: ; preds = %70
%79 = tail call zeroext i8 @tolower(i8 zeroext %77)
br label %80
80: ; preds = %70, %78
%81 = phi i8 [ %79, %78 ], [ %77, %70 ]
%82 = icmp ult i8 %81, %71
br i1 %82, label %83, label %85
83: ; preds = %80
%84 = sub i64 %58, %62
br label %95
85: ; preds = %80
%86 = icmp eq i8 %71, %81
br i1 %86, label %87, label %93
87: ; preds = %85
%88 = icmp eq i64 %60, %59
br i1 %88, label %91, label %89
89: ; preds = %87
%90 = add i64 %60, 1
br label %95
91: ; preds = %87
%92 = add i64 %59, %61
br label %95
93: ; preds = %85
%94 = add i64 %61, 1
br label %95
95: ; preds = %93, %91, %89, %83
%96 = phi i64 [ %62, %83 ], [ %62, %89 ], [ %62, %91 ], [ %61, %93 ]
%97 = phi i64 [ %58, %83 ], [ %61, %89 ], [ %92, %91 ], [ %94, %93 ]
%98 = phi i64 [ 1, %83 ], [ %90, %89 ], [ 1, %91 ], [ 1, %93 ]
%99 = phi i64 [ %84, %83 ], [ %59, %89 ], [ %59, %91 ], [ 1, %93 ]
%100 = add i64 %98, %97
%101 = icmp ult i64 %100, %1
br i1 %101, label %57, label %102
102: ; preds = %95, %54
%103 = phi i64 [ %55, %54 ], [ %96, %95 ]
%104 = phi i64 [ 1, %54 ], [ %99, %95 ]
%105 = add i64 %103, 1
%106 = add i64 %48, 1
%107 = icmp ult i64 %105, %106
br i1 %107, label %109, label %108
108: ; preds = %102
store i64 %104, i64* %2
br label %109
109: ; preds = %102, %108, %5
%110 = phi i64 [ %6, %5 ], [ %105, %108 ], [ %106, %102 ]
ret i64 %110
}