int __strverscmp(s1, s2) const char *s1;
const char *s2;
{
  const unsigned char *p1 = (const unsigned char *)s1;
  const unsigned char *p2 = (const unsigned char *)s2;
  unsigned char c1, c2;
  int state;
  int diff;
  static const unsigned int next_state[] = {0x0, 0x4, 0xC, 0x0, 0x0, 0x4,
                                            0x4, 0x4, 0x0, 0x8, 0x8, 0x8,
                                            0x0, 0x8, 0xC, 0xC};
  static const int result_type[] = {
      2,  2, 2, 2, 2,  3, 2, 2, 2, 2,  2,  2, 2,  2, 2, 2, 2,  -1, -1, 2,
      +1, 3, 3, 2, +1, 3, 3, 2, 2, 2,  2,  2, 2,  2, 2, 2, 2,  3,  2,  2,
      2,  2, 2, 2, 2,  2, 2, 2, 2, +1, +1, 2, -1, 2, 2, 2, -1, 2,  2,  2};
  if (p1 == p2)
    return 0;
  c1 = *p1++;
  c2 = *p2++;
  state = 0x0 | ((c1 == '0') + (isdigit(c1) != 0));
  while ((diff = c1 - c2) == 0 && c1 != '\0') {
    state = next_state[state];
    c1 = *p1++;
    c2 = *p2++;
    state |= (c1 == '0') + (isdigit(c1) != 0);
  }
  state = result_type[state << 2 | (((c2 == '0') + (isdigit(c2) != 0)))];
  switch (state) {
  case 2:
    return diff;
  case 3:
    while (isdigit(*p1++))
      if (!isdigit(*p2++))
        return 1;
    return isdigit(*p2) ? -1 : diff;
  default:
    return state;
  }
}


x86 assembly (clang, -O0):
<__strverscmp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x28(%rbp),%rax
jne    114a <__strverscmp+0x3a>
movl   $0x0,-0x4(%rbp)
jmp    134f <__strverscmp+0x23f>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
mov    (%rax),%al
mov    %al,-0x29(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
mov    (%rax),%al
mov    %al,-0x2a(%rbp)
movzbl -0x29(%rbp),%eax
cmp    $0x30,%eax
sete   %al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x38(%rbp)
movzbl -0x29(%rbp),%edi
call   1030 <isdigit@plt>
mov    %eax,%ecx
mov    -0x38(%rbp),%eax
cmp    $0x0,%ecx
setne  %cl
and    $0x1,%cl
movzbl %cl,%ecx
add    %ecx,%eax
or     $0x0,%eax
mov    %eax,-0x30(%rbp)
movzbl -0x29(%rbp),%ecx
movzbl -0x2a(%rbp),%eax
sub    %eax,%ecx
mov    %ecx,-0x34(%rbp)
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x39(%rbp)
jne    11ce <__strverscmp+0xbe>
movzbl -0x29(%rbp),%eax
cmp    $0x0,%eax
setne  %al
mov    %al,-0x39(%rbp)
mov    -0x39(%rbp),%al
test   $0x1,%al
jne    11de <__strverscmp+0xce>
jmp    1250 <__strverscmp+0x140>
movslq -0x30(%rbp),%rcx
lea    0xe17(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x30(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
mov    (%rax),%al
mov    %al,-0x29(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
mov    (%rax),%al
mov    %al,-0x2a(%rbp)
movzbl -0x29(%rbp),%eax
cmp    $0x30,%eax
sete   %al
and    $0x1,%al
movzbl %al,%eax
mov    %eax,-0x40(%rbp)
movzbl -0x29(%rbp),%edi
call   1030 <isdigit@plt>
mov    %eax,%ecx
mov    -0x40(%rbp),%eax
cmp    $0x0,%ecx
setne  %cl
and    $0x1,%cl
movzbl %cl,%ecx
add    %ecx,%eax
or     -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
jmp    11a6 <__strverscmp+0x96>
mov    -0x30(%rbp),%eax
shl    $0x2,%eax
mov    %eax,-0x48(%rbp)
movzbl -0x2a(%rbp),%edi
mov    %edi,%eax
sub    $0x30,%eax
sete   %al
movzbl %al,%eax
mov    %eax,-0x4c(%rbp)
call   1030 <isdigit@plt>
mov    -0x4c(%rbp),%ecx
mov    %eax,%edx
mov    -0x48(%rbp),%eax
sub    $0x1,%edx
sbb    $0xffffffff,%ecx
or     %ecx,%eax
movslq %eax,%rcx
lea    0xdb6(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,-0x44(%rbp)
sub    $0x2,%eax
je     12b5 <__strverscmp+0x1a5>
jmp    12a4 <__strverscmp+0x194>
mov    -0x44(%rbp),%eax
sub    $0x3,%eax
je     12c0 <__strverscmp+0x1b0>
jmp    1349 <__strverscmp+0x239>
mov    -0x34(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    134f <__strverscmp+0x23f>
jmp    12c5 <__strverscmp+0x1b5>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
movzbl (%rax),%edi
call   1030 <isdigit@plt>
cmp    $0x0,%eax
je     1316 <__strverscmp+0x206>
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
movzbl (%rax),%edi
call   1030 <isdigit@plt>
cmp    $0x0,%eax
jne    1311 <__strverscmp+0x201>
movl   $0x1,-0x4(%rbp)
jmp    134f <__strverscmp+0x23f>
jmp    12c5 <__strverscmp+0x1b5>
mov    -0x28(%rbp),%rax
movzbl (%rax),%edi
call   1030 <isdigit@plt>
cmp    $0x0,%eax
je     1338 <__strverscmp+0x228>
mov    $0xffffffff,%eax
mov    %eax,-0x50(%rbp)
jmp    133e <__strverscmp+0x22e>
mov    -0x34(%rbp),%eax
mov    %eax,-0x50(%rbp)
mov    -0x50(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    134f <__strverscmp+0x23f>
mov    -0x30(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<__strverscmp>:
cmp    %rsi,%rdi
je     11f2 <__strverscmp+0xf2>
movzbl (%rdi),%edx
xor    %ecx,%ecx
cmp    $0x30,%edx
sete   %cl
lea    -0x30(%rdx),%r8d
xor    %eax,%eax
cmp    $0xa,%r8d
setb   %al
add    %ecx,%eax
add    $0x1,%rdi
mov    (%rsi),%r8b
add    $0x1,%rsi
movzbl %r8b,%r10d
mov    %edx,%ecx
sub    %r10d,%ecx
jne    118c <__strverscmp+0x8c>
test   %dl,%dl
je     118c <__strverscmp+0x8c>
lea    0xebc(%rip),%r9
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movslq %eax,%r8
movzbl (%rdi),%edx
xor    %ecx,%ecx
cmp    $0x30,%edx
sete   %cl
lea    -0x30(%rdx),%r10d
xor    %eax,%eax
cmp    $0xa,%r10d
setb   %al
add    %ecx,%eax
or     (%r9,%r8,4),%eax
add    $0x1,%rdi
movzbl (%rsi),%r8d
add    $0x1,%rsi
movzbl %r8b,%r10d
mov    %edx,%ecx
sub    %r10d,%ecx
jne    118c <__strverscmp+0x8c>
test   %dl,%dl
jne    1150 <__strverscmp+0x50>
xor    %r9d,%r9d
cmp    $0x30,%r8b
sete   %r9b
add    $0xffffffd0,%r10d
xor    %edx,%edx
cmp    $0xa,%r10d
setb   %dl
add    %r9d,%edx
lea    (%rdx,%rax,4),%eax
cltq
lea    0xe8d(%rip),%rdx
mov    (%rdx,%rax,4),%eax
cmp    $0x2,%eax
je     1207 <__strverscmp+0x107>
cmp    $0x3,%eax
jne    1209 <__strverscmp+0x109>
xor    %eax,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movzbl (%rdi,%rax,1),%edx
add    $0xffffffd0,%edx
cmp    $0x9,%edx
ja     11f5 <__strverscmp+0xf5>
movzbl (%rsi,%rax,1),%edx
add    $0xffffffd0,%edx
add    $0x1,%rax
cmp    $0xa,%edx
jb     11d0 <__strverscmp+0xd0>
mov    $0x1,%eax
ret
xor    %eax,%eax
ret
movzbl (%rsi,%rax,1),%eax
add    $0xffffffd0,%eax
cmp    $0xa,%eax
mov    $0xffffffff,%eax
cmovb  %eax,%ecx
mov    %ecx,%eax
ret

LLVM IR (-O0):
@__strverscmp.next_state = internal constant [16 x i32] [i32 0, i32 4, i32 12, i32 0, i32 0, i32 4, i32 4, i32 4, i32 0, i32 8, i32 8, i32 8, i32 0, i32 8, i32 12, i32 12]
@__strverscmp.result_type = internal constant [60 x i32] [i32 2, i32 2, i32 2, i32 2, i32 2, i32 3, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 -1, i32 -1, i32 2, i32 1, i32 3, i32 3, i32 2, i32 1, i32 3, i32 3, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 3, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1, i32 2, i32 -1, i32 2, i32 2, i32 2, i32 -1, i32 2, i32 2, i32 2]
define i32 @__strverscmp(i8* %0, i8* %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i8
%9 = alloca i8
%10 = alloca i32
%11 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
%12 = load i8*, i8** %4
store i8* %12, i8** %6
%13 = load i8*, i8** %5
store i8* %13, i8** %7
%14 = load i8*, i8** %6
%15 = load i8*, i8** %7
%16 = icmp eq i8* %14, %15
br i1 %16, label %17, label %18
17: ; preds = %2
store i32 0, i32* %3
br label %122
18: ; preds = %2
%19 = load i8*, i8** %6
%20 = getelementptr inbounds i8, i8* %19, i32 1
store i8* %20, i8** %6
%21 = load i8, i8* %19
store i8 %21, i8* %8
%22 = load i8*, i8** %7
%23 = getelementptr inbounds i8, i8* %22, i32 1
store i8* %23, i8** %7
%24 = load i8, i8* %22
store i8 %24, i8* %9
%25 = load i8, i8* %8
%26 = zext i8 %25 to i32
%27 = icmp eq i32 %26, 48
%28 = zext i1 %27 to i32
%29 = load i8, i8* %8
%30 = zext i8 %29 to i32
%31 = call i32 @isdigit(i32 %30)
%32 = icmp ne i32 %31, 0
%33 = zext i1 %32 to i32
%34 = add nsw i32 %28, %33
%35 = or i32 0, %34
store i32 %35, i32* %10
br label %36
36: ; preds = %49, %18
%37 = load i8, i8* %8
%38 = zext i8 %37 to i32
%39 = load i8, i8* %9
%40 = zext i8 %39 to i32
%41 = sub nsw i32 %38, %40
store i32 %41, i32* %11
%42 = icmp eq i32 %41, 0
br i1 %42, label %43, label %47
43: ; preds = %36
%44 = load i8, i8* %8
%45 = zext i8 %44 to i32
%46 = icmp ne i32 %45, 0
br label %47
47: ; preds = %43, %36
%48 = phi i1 [ false, %36 ], [ %46, %43 ]
br i1 %48, label %49, label %72
49: ; preds = %47
%50 = load i32, i32* %10
%51 = sext i32 %50 to i64
%52 = getelementptr inbounds [16 x i32], [16 x i32]* @__strverscmp.next_state, i64 0, i64 %51
%53 = load i32, i32* %52
store i32 %53, i32* %10
%54 = load i8*, i8** %6
%55 = getelementptr inbounds i8, i8* %54, i32 1
store i8* %55, i8** %6
%56 = load i8, i8* %54
store i8 %56, i8* %8
%57 = load i8*, i8** %7
%58 = getelementptr inbounds i8, i8* %57, i32 1
store i8* %58, i8** %7
%59 = load i8, i8* %57
store i8 %59, i8* %9
%60 = load i8, i8* %8
%61 = zext i8 %60 to i32
%62 = icmp eq i32 %61, 48
%63 = zext i1 %62 to i32
%64 = load i8, i8* %8
%65 = zext i8 %64 to i32
%66 = call i32 @isdigit(i32 %65)
%67 = icmp ne i32 %66, 0
%68 = zext i1 %67 to i32
%69 = add nsw i32 %63, %68
%70 = load i32, i32* %10
%71 = or i32 %70, %69
store i32 %71, i32* %10
br label %36
72: ; preds = %47
%73 = load i32, i32* %10
%74 = shl i32 %73, 2
%75 = load i8, i8* %9
%76 = zext i8 %75 to i32
%77 = icmp eq i32 %76, 48
%78 = zext i1 %77 to i32
%79 = load i8, i8* %9
%80 = zext i8 %79 to i32
%81 = call i32 @isdigit(i32 %80)
%82 = icmp ne i32 %81, 0
%83 = zext i1 %82 to i32
%84 = add nsw i32 %78, %83
%85 = or i32 %74, %84
%86 = sext i32 %85 to i64
%87 = getelementptr inbounds [60 x i32], [60 x i32]* @__strverscmp.result_type, i64 0, i64 %86
%88 = load i32, i32* %87
store i32 %88, i32* %10
%89 = load i32, i32* %10
switch i32 %89, label %120 [
i32 2, label %90
i32 3, label %92
]
90: ; preds = %72
%91 = load i32, i32* %11
store i32 %91, i32* %3
br label %122
92: ; preds = %72
br label %93
93: ; preds = %108, %92
%94 = load i8*, i8** %6
%95 = getelementptr inbounds i8, i8* %94, i32 1
store i8* %95, i8** %6
%96 = load i8, i8* %94
%97 = zext i8 %96 to i32
%98 = call i32 @isdigit(i32 %97)
%99 = icmp ne i32 %98, 0
br i1 %99, label %100, label %109
100: ; preds = %93
%101 = load i8*, i8** %7
%102 = getelementptr inbounds i8, i8* %101, i32 1
store i8* %102, i8** %7
%103 = load i8, i8* %101
%104 = zext i8 %103 to i32
%105 = call i32 @isdigit(i32 %104)
%106 = icmp ne i32 %105, 0
br i1 %106, label %108, label %107
107: ; preds = %100
store i32 1, i32* %3
br label %122
108: ; preds = %100
br label %93
109: ; preds = %93
%110 = load i8*, i8** %7
%111 = load i8, i8* %110
%112 = zext i8 %111 to i32
%113 = call i32 @isdigit(i32 %112)
%114 = icmp ne i32 %113, 0
br i1 %114, label %115, label %116
115: ; preds = %109
br label %118
116: ; preds = %109
%117 = load i32, i32* %11
br label %118
118: ; preds = %116, %115
%119 = phi i32 [ -1, %115 ], [ %117, %116 ]
store i32 %119, i32* %3
br label %122
120: ; preds = %72
%121 = load i32, i32* %10
store i32 %121, i32* %3
br label %122
122: ; preds = %120, %118, %107, %90, %17
%123 = load i32, i32* %3
ret i32 %123
}

LLVM IR (-O2):
@__strverscmp.next_state = internal unnamed_addr constant [16 x i32] [i32 0, i32 4, i32 12, i32 0, i32 0, i32 4, i32 4, i32 4, i32 0, i32 8, i32 8, i32 8, i32 0, i32 8, i32 12, i32 12]
@__strverscmp.result_type = internal unnamed_addr constant [60 x i32] [i32 2, i32 2, i32 2, i32 2, i32 2, i32 3, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 -1, i32 -1, i32 2, i32 1, i32 3, i32 3, i32 2, i32 1, i32 3, i32 3, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 3, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 1, i32 1, i32 2, i32 -1, i32 2, i32 2, i32 2, i32 -1, i32 2, i32 2, i32 2]
define i32 @__strverscmp(i8* %0, i8* %1) {
%3 = icmp eq i8* %0, %1
br i1 %3, label %86, label %4
4: ; preds = %2
%5 = load i8, i8* %0
%6 = zext i8 %5 to i32
%7 = icmp eq i8 %5, 48
%8 = zext i1 %7 to i32
%9 = add nsw i32 %6, -48
%10 = icmp ult i32 %9, 10
%11 = zext i1 %10 to i32
%12 = add nuw nsw i32 %11, %8
%13 = getelementptr inbounds i8, i8* %1, i64 1
%14 = getelementptr inbounds i8, i8* %0, i64 1
%15 = load i8, i8* %1
%16 = zext i8 %15 to i32
%17 = sub nsw i32 %6, %16
%18 = icmp eq i32 %17, 0
%19 = icmp ne i8 %5, 0
%20 = select i1 %18, i1 %19, i1 false
br i1 %20, label %21, label %47
21: ; preds = %4, %21
%22 = phi i8* [ %38, %21 ], [ %14, %4 ]
%23 = phi i8* [ %37, %21 ], [ %13, %4 ]
%24 = phi i32 [ %36, %21 ], [ %12, %4 ]
%25 = sext i32 %24 to i64
%26 = getelementptr inbounds [16 x i32], [16 x i32]* @__strverscmp.next_state, i64 0, i64 %25
%27 = load i32, i32* %26
%28 = load i8, i8* %22
%29 = zext i8 %28 to i32
%30 = icmp eq i8 %28, 48
%31 = zext i1 %30 to i32
%32 = add nsw i32 %29, -48
%33 = icmp ult i32 %32, 10
%34 = zext i1 %33 to i32
%35 = add nuw nsw i32 %34, %31
%36 = or i32 %35, %27
%37 = getelementptr inbounds i8, i8* %23, i64 1
%38 = getelementptr inbounds i8, i8* %22, i64 1
%39 = load i8, i8* %23
%40 = zext i8 %39 to i32
%41 = sub nsw i32 %29, %40
%42 = icmp eq i32 %41, 0
%43 = icmp ne i8 %28, 0
%44 = select i1 %42, i1 %43, i1 false
br i1 %44, label %21, label %45
45: ; preds = %21
%46 = zext i8 %39 to i32
br label %47
47: ; preds = %45, %4
%48 = phi i32 [ %16, %4 ], [ %46, %45 ]
%49 = phi i8 [ %15, %4 ], [ %39, %45 ]
%50 = phi i32 [ %12, %4 ], [ %36, %45 ]
%51 = phi i8* [ %13, %4 ], [ %37, %45 ]
%52 = phi i8* [ %14, %4 ], [ %38, %45 ]
%53 = phi i32 [ %17, %4 ], [ %41, %45 ]
%54 = shl i32 %50, 2
%55 = icmp eq i8 %49, 48
%56 = zext i1 %55 to i32
%57 = add nsw i32 %48, -48
%58 = icmp ult i32 %57, 10
%59 = zext i1 %58 to i32
%60 = add nuw nsw i32 %59, %56
%61 = or i32 %60, %54
%62 = sext i32 %61 to i64
%63 = getelementptr inbounds [60 x i32], [60 x i32]* @__strverscmp.result_type, i64 0, i64 %62
%64 = load i32, i32* %63
switch i32 %64, label %85 [
i32 2, label %86
i32 3, label %65
]
65: ; preds = %47, %72
%66 = phi i8* [ %73, %72 ], [ %52, %47 ]
%67 = phi i8* [ %74, %72 ], [ %51, %47 ]
%68 = load i8, i8* %66
%69 = zext i8 %68 to i32
%70 = add nsw i32 %69, -48
%71 = icmp ult i32 %70, 10
br i1 %71, label %72, label %79
72: ; preds = %65
%73 = getelementptr inbounds i8, i8* %66, i64 1
%74 = getelementptr inbounds i8, i8* %67, i64 1
%75 = load i8, i8* %67
%76 = zext i8 %75 to i32
%77 = add nsw i32 %76, -48
%78 = icmp ult i32 %77, 10
br i1 %78, label %65, label %86
79: ; preds = %65
%80 = load i8, i8* %67
%81 = zext i8 %80 to i32
%82 = add nsw i32 %81, -48
%83 = icmp ult i32 %82, 10
%84 = select i1 %83, i32 -1, i32 %53
br label %86
85: ; preds = %47
br label %86
86: ; preds = %72, %47, %2, %85, %79
%87 = phi i32 [ %64, %85 ], [ %84, %79 ], [ 0, %2 ], [ %53, %47 ], [ 1, %72 ]
ret i32 %87
}