int redislite_stringmatchlen(const char *pattern, int patternLen,
                             const char *string, int stringLen, int nocase) {
  while (patternLen) {
    switch (pattern[0]) {
    case '*':
      while (pattern[1] == '*') {
        pattern++;
        patternLen--;
      }
      if (patternLen == 1) {
        return 1;
      }
      while (stringLen) {
        if (redislite_stringmatchlen(pattern + 1, patternLen - 1, string,
                                     stringLen, nocase)) {
          return 1;
        }
        string++;
        stringLen--;
      }
      return 0;
      break;
    case '?':
      if (stringLen == 0) {
        return 0;
      }
      string++;
      stringLen--;
      break;
    case '[': {
      int not, match;
      pattern++;
      patternLen--;
      not = pattern[0] == '^';
      if (not ) {
        pattern++;
        patternLen--;
      }
      match = 0;
      while (1) {
        if (pattern[0] == '\\') {
          pattern++;
          patternLen--;
          if (pattern[0] == string[0]) {
            match = 1;
          }
        } else if (pattern[0] == ']') {
          break;
        } else if (patternLen == 0) {
          pattern--;
          patternLen++;
          break;
        } else if (pattern[1] == '-' && patternLen >= 3) {
          int start = pattern[0];
          int end = pattern[2];
          int c = string[0];
          if (start > end) {
            int t = start;
            start = end;
            end = t;
          }
          if (nocase) {
            start = tolower(start);
            end = tolower(end);
            c = tolower(c);
          }
          pattern += 2;
          patternLen -= 2;
          if (c >= start && c <= end) {
            match = 1;
          }
        } else {
          if (!nocase) {
            if (pattern[0] == string[0]) {
              match = 1;
            }
          } else {
            if (tolower((int)pattern[0]) == tolower((int)string[0])) {
              match = 1;
            }
          }
        }
        pattern++;
        patternLen--;
      }
      if (not ) {
        match = !match;
      }
      if (!match) {
        return 0;
      }
      string++;
      stringLen--;
      break;
    }
    case '\\':
      if (patternLen >= 2) {
        pattern++;
        patternLen--;
      }
    default:
      if (!nocase) {
        if (pattern[0] != string[0]) {
          return 0;
        }
      } else {
        if (tolower((int)pattern[0]) != tolower((int)string[0])) {
          return 0;
        }
      }
      string++;
      stringLen--;
      break;
    }
    pattern++;
    patternLen--;
    if (stringLen == 0) {
      while (*pattern == '*') {
        pattern++;
        patternLen--;
      }
      break;
    }
  }
  if (patternLen == 0 && stringLen == 0) {
    return 1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<redislite_stringmatchlen>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %ecx,-0x24(%rbp)
mov    %r8d,-0x28(%rbp)
cmpl   $0x0,-0x14(%rbp)
je     15cd <redislite_stringmatchlen+0x4ad>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x44(%rbp)
sub    $0x2a,%eax
je     118f <redislite_stringmatchlen+0x6f>
jmp    115c <redislite_stringmatchlen+0x3c>
mov    -0x44(%rbp),%eax
sub    $0x3f,%eax
je     123d <redislite_stringmatchlen+0x11d>
jmp    116d <redislite_stringmatchlen+0x4d>
mov    -0x44(%rbp),%eax
sub    $0x5b,%eax
je     126d <redislite_stringmatchlen+0x14d>
jmp    117e <redislite_stringmatchlen+0x5e>
mov    -0x44(%rbp),%eax
sub    $0x5c,%eax
je     14d2 <redislite_stringmatchlen+0x3b2>
jmp    14f6 <redislite_stringmatchlen+0x3d6>
jmp    1194 <redislite_stringmatchlen+0x74>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x2a,%eax
jne    11bf <redislite_stringmatchlen+0x9f>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1194 <redislite_stringmatchlen+0x74>
cmpl   $0x1,-0x14(%rbp)
jne    11d5 <redislite_stringmatchlen+0xb5>
movl   $0x1,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
jmp    11da <redislite_stringmatchlen+0xba>
cmpl   $0x0,-0x24(%rbp)
je     1231 <redislite_stringmatchlen+0x111>
mov    -0x10(%rbp),%rdi
add    $0x1,%rdi
mov    -0x14(%rbp),%esi
sub    $0x1,%esi
mov    -0x20(%rbp),%rdx
mov    -0x24(%rbp),%ecx
mov    -0x28(%rbp),%r8d
call   1030 <redislite_stringmatchlen@plt>
cmp    $0x0,%eax
je     1217 <redislite_stringmatchlen+0xf7>
movl   $0x1,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    11da <redislite_stringmatchlen+0xba>
movl   $0x0,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
cmpl   $0x0,-0x24(%rbp)
jne    1253 <redislite_stringmatchlen+0x133>
movl   $0x0,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    1575 <redislite_stringmatchlen+0x455>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5e,%eax
sete   %al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x2c(%rbp)
cmpl   $0x0,-0x2c(%rbp)
je     12b6 <redislite_stringmatchlen+0x196>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
movl   $0x0,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5c,%eax
jne    1304 <redislite_stringmatchlen+0x1e4>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
mov    -0x20(%rbp),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
jne    12ff <redislite_stringmatchlen+0x1df>
movl   $0x1,-0x30(%rbp)
jmp    146d <redislite_stringmatchlen+0x34d>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x5d,%eax
jne    1319 <redislite_stringmatchlen+0x1f9>
jmp    1487 <redislite_stringmatchlen+0x367>
cmpl   $0x0,-0x14(%rbp)
jne    133d <redislite_stringmatchlen+0x21d>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x14(%rbp)
jmp    1487 <redislite_stringmatchlen+0x367>
mov    -0x10(%rbp),%rax
movsbl 0x1(%rax),%eax
cmp    $0x2d,%eax
jne    13f9 <redislite_stringmatchlen+0x2d9>
cmpl   $0x3,-0x14(%rbp)
jl     13f9 <redislite_stringmatchlen+0x2d9>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x34(%rbp)
mov    -0x10(%rbp),%rax
movsbl 0x2(%rax),%eax
mov    %eax,-0x38(%rbp)
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x3c(%rbp)
mov    -0x34(%rbp),%eax
cmp    -0x38(%rbp),%eax
jle    1395 <redislite_stringmatchlen+0x275>
mov    -0x34(%rbp),%eax
mov    %eax,-0x40(%rbp)
mov    -0x38(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x40(%rbp),%eax
mov    %eax,-0x38(%rbp)
cmpl   $0x0,-0x28(%rbp)
je     13c0 <redislite_stringmatchlen+0x2a0>
mov    -0x34(%rbp),%edi
call   1040 <tolower@plt>
mov    %eax,-0x34(%rbp)
mov    -0x38(%rbp),%edi
call   1040 <tolower@plt>
mov    %eax,-0x38(%rbp)
mov    -0x3c(%rbp),%edi
call   1040 <tolower@plt>
mov    %eax,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0x14(%rbp)
mov    -0x3c(%rbp),%eax
cmp    -0x34(%rbp),%eax
jl     13f4 <redislite_stringmatchlen+0x2d4>
mov    -0x3c(%rbp),%eax
cmp    -0x38(%rbp),%eax
jg     13f4 <redislite_stringmatchlen+0x2d4>
movl   $0x1,-0x30(%rbp)
jmp    145e <redislite_stringmatchlen+0x33e>
cmpl   $0x0,-0x28(%rbp)
jne    1425 <redislite_stringmatchlen+0x305>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
mov    -0x20(%rbp),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
jne    1420 <redislite_stringmatchlen+0x300>
movl   $0x1,-0x30(%rbp)
jmp    1459 <redislite_stringmatchlen+0x339>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1040 <tolower@plt>
mov    %eax,-0x48(%rbp)
mov    -0x20(%rbp),%rax
movsbl (%rax),%edi
call   1040 <tolower@plt>
mov    %eax,%ecx
mov    -0x48(%rbp),%eax
cmp    %ecx,%eax
jne    1454 <redislite_stringmatchlen+0x334>
movl   $0x1,-0x30(%rbp)
jmp    1459 <redislite_stringmatchlen+0x339>
jmp    145e <redislite_stringmatchlen+0x33e>
jmp    1463 <redislite_stringmatchlen+0x343>
jmp    1468 <redislite_stringmatchlen+0x348>
jmp    146d <redislite_stringmatchlen+0x34d>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    12bd <redislite_stringmatchlen+0x19d>
cmpl   $0x0,-0x2c(%rbp)
je     14a2 <redislite_stringmatchlen+0x382>
cmpl   $0x0,-0x30(%rbp)
setne  %al
xor    $0xff,%al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x30(%rbp)
cmpl   $0x0,-0x30(%rbp)
jne    14b8 <redislite_stringmatchlen+0x398>
movl   $0x0,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
jmp    1575 <redislite_stringmatchlen+0x455>
cmpl   $0x2,-0x14(%rbp)
jl     14f1 <redislite_stringmatchlen+0x3d1>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    14f6 <redislite_stringmatchlen+0x3d6>
cmpl   $0x0,-0x28(%rbp)
jne    1527 <redislite_stringmatchlen+0x407>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
mov    -0x20(%rbp),%rcx
movsbl (%rcx),%ecx
cmp    %ecx,%eax
je     1522 <redislite_stringmatchlen+0x402>
movl   $0x0,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
jmp    1560 <redislite_stringmatchlen+0x440>
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1040 <tolower@plt>
mov    %eax,-0x4c(%rbp)
mov    -0x20(%rbp),%rax
movsbl (%rax),%edi
call   1040 <tolower@plt>
mov    %eax,%ecx
mov    -0x4c(%rbp),%eax
cmp    %ecx,%eax
je     155b <redislite_stringmatchlen+0x43b>
movl   $0x0,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
jmp    1560 <redislite_stringmatchlen+0x440>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x24(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x24(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x24(%rbp)
jne    15c8 <redislite_stringmatchlen+0x4a8>
jmp    1599 <redislite_stringmatchlen+0x479>
mov    -0x10(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2a,%eax
jne    15c3 <redislite_stringmatchlen+0x4a3>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    1599 <redislite_stringmatchlen+0x479>
jmp    15cd <redislite_stringmatchlen+0x4ad>
jmp    113a <redislite_stringmatchlen+0x1a>
cmpl   $0x0,-0x14(%rbp)
jne    15ed <redislite_stringmatchlen+0x4cd>
cmpl   $0x0,-0x24(%rbp)
jne    15ed <redislite_stringmatchlen+0x4cd>
movl   $0x1,-0x4(%rbp)
jmp    15f4 <redislite_stringmatchlen+0x4d4>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<redislite_stringmatchlen>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
mov    %r8d,0x4(%rsp)
mov    %ecx,%r15d
mov    %rdx,0x8(%rsp)
mov    %esi,%r13d
mov    %rdi,%r14
jmp    116b <redislite_stringmatchlen+0x4b>
cmp    0x0(%r13),%dil
jne    134f <redislite_stringmatchlen+0x22f>
nopl   (%rax)
add    $0x1,%r13
mov    %r13,0x8(%rsp)
lea    0x1(%rbp),%r14
lea    -0x1(%rbx),%r13d
add    $0xffffffff,%r15d
je     13bb <redislite_stringmatchlen+0x29b>
test   %r13d,%r13d
je     13b6 <redislite_stringmatchlen+0x296>
movsbl (%r14),%eax
cmp    $0x5a,%eax
jle    11b0 <redislite_stringmatchlen+0x90>
cmp    $0x5b,%eax
je     11d0 <redislite_stringmatchlen+0xb0>
cmp    $0x5c,%eax
jne    12ef <redislite_stringmatchlen+0x1cf>
cmp    $0x2,%r13d
jl     12ef <redislite_stringmatchlen+0x1cf>
add    $0x1,%r14
add    $0xffffffff,%r13d
jmp    12ef <redislite_stringmatchlen+0x1cf>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
cmp    $0x3f,%eax
jne    12ea <redislite_stringmatchlen+0x1ca>
mov    %r13d,%ebx
mov    %r14,%rbp
test   %r15d,%r15d
mov    0x8(%rsp),%r13
jne    1150 <redislite_stringmatchlen+0x30>
jmp    134f <redislite_stringmatchlen+0x22f>
xchg   %ax,%ax
mov    %r15d,0x14(%rsp)
lea    0x1(%r14),%rax
mov    0x1(%r14),%cl
add    $0x2,%r14
xor    %ebx,%ebx
mov    %cl,0x3(%rsp)
cmp    $0x5e,%cl
sete   %bl
not    %ebx
cmovne %rax,%r14
add    %r13d,%ebx
xor    %r12d,%r12d
mov    %r14,%rbp
mov    0x8(%rsp),%r13
mov    $0x1,%r15d
jmp    122a <redislite_stringmatchlen+0x10a>
nopl   0x0(%rax)
add    $0xffffffff,%ebx
movzbl 0x1(%rbp),%eax
add    $0x1,%rbp
cmp    0x0(%r13),%al
cmove  %r15d,%r12d
add    $0x1,%rbp
add    $0xffffffff,%ebx
movsbl 0x0(%rbp),%edi
cmp    $0x5c,%edi
je     1210 <redislite_stringmatchlen+0xf0>
cmp    $0x5d,%dil
je     132f <redislite_stringmatchlen+0x20f>
test   %ebx,%ebx
je     1326 <redislite_stringmatchlen+0x206>
cmpb   $0x2d,0x1(%rbp)
jne    12c0 <redislite_stringmatchlen+0x1a0>
cmp    $0x3,%ebx
jl     12c0 <redislite_stringmatchlen+0x1a0>
movzbl 0x2(%rbp),%eax
cmp    %al,%dil
mov    %eax,%ecx
cmovl  %edi,%ecx
cmovg  %edi,%eax
movsbl 0x0(%r13),%r14d
movsbl %cl,%r13d
movsbl %al,%r15d
cmpl   $0x0,0x4(%rsp)
je     1294 <redislite_stringmatchlen+0x174>
mov    %r13d,%edi
call   1040 <tolower@plt>
mov    %eax,%r13d
mov    %r15d,%edi
call   1040 <tolower@plt>
mov    %eax,%r15d
mov    %r14d,%edi
call   1040 <tolower@plt>
mov    %eax,%r14d
mov    %r12d,%eax
cmp    %r15d,%r14d
jg     12a1 <redislite_stringmatchlen+0x181>
mov    $0x1,%eax
add    $0x2,%rbp
add    $0xfffffffe,%ebx
cmp    %r13d,%r14d
cmovge %eax,%r12d
mov    0x8(%rsp),%r13
mov    $0x1,%r15d
jmp    1223 <redislite_stringmatchlen+0x103>
nop
cmpl   $0x0,0x4(%rsp)
je     12e1 <redislite_stringmatchlen+0x1c1>
call   1040 <tolower@plt>
mov    %eax,%r14d
movsbl 0x0(%r13),%edi
call   1040 <tolower@plt>
cmp    %eax,%r14d
jmp    121f <redislite_stringmatchlen+0xff>
cmp    0x0(%r13),%dil
jmp    121f <redislite_stringmatchlen+0xff>
cmp    $0x2a,%eax
je     1360 <redislite_stringmatchlen+0x240>
mov    %r13d,%ebx
mov    %r14,%rbp
movsbl (%r14),%edi
cmpl   $0x0,0x4(%rsp)
mov    0x8(%rsp),%r13
je     1143 <redislite_stringmatchlen+0x23>
call   1040 <tolower@plt>
mov    %eax,%r14d
movsbl 0x0(%r13),%edi
call   1040 <tolower@plt>
cmp    %eax,%r14d
je     1150 <redislite_stringmatchlen+0x30>
jmp    134f <redislite_stringmatchlen+0x22f>
add    $0xffffffffffffffff,%rbp
mov    $0x1,%ebx
mov    0x3(%rsp),%cl
xor    %eax,%eax
test   %r12d,%r12d
sete   %al
cmp    $0x5e,%cl
cmovne %r12d,%eax
test   %eax,%eax
mov    0x14(%rsp),%r15d
jne    1150 <redislite_stringmatchlen+0x30>
xor    %ebx,%ebx
jmp    13ed <redislite_stringmatchlen+0x2cd>
cs nopw 0x0(%rax,%rax,1)
add    $0xffffffff,%r13d
cmpb   $0x2a,0x1(%r14)
lea    0x1(%r14),%r14
je     1360 <redislite_stringmatchlen+0x240>
mov    $0x1,%ebx
test   %r13d,%r13d
je     13ed <redislite_stringmatchlen+0x2cd>
test   %r15d,%r15d
je     134f <redislite_stringmatchlen+0x22f>
mov    0x8(%rsp),%rbp
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    %r14,%rdi
mov    %r13d,%esi
mov    %rbp,%rdx
mov    %r15d,%ecx
mov    0x4(%rsp),%r8d
call   1030 <redislite_stringmatchlen@plt>
test   %eax,%eax
jne    13ed <redislite_stringmatchlen+0x2cd>
add    $0x1,%rbp
add    $0xffffffff,%r15d
jne    1390 <redislite_stringmatchlen+0x270>
jmp    134f <redislite_stringmatchlen+0x22f>
xor    %r13d,%r13d
jmp    13e5 <redislite_stringmatchlen+0x2c5>
xor    %r15d,%r15d
cmpb   $0x2a,(%r14)
jne    13e5 <redislite_stringmatchlen+0x2c5>
xor    %r13d,%r13d
nopw   0x0(%rax,%rax,1)
cmpb   $0x2a,0x2(%rbp,%r13,1)
lea    0x1(%r13),%r13
je     13d0 <redislite_stringmatchlen+0x2b0>
not    %r13d
add    %ebx,%r13d
xor    %r15d,%r15d
xor    %ebx,%ebx
or     %r13d,%r15d
sete   %bl
mov    %ebx,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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