#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 uint8_t;
typedef int int8_t;

/* Variables and functions */
scalar_t__ isdigit(unsigned char const);
int strverscmp(const char *s1, const char *s2) {
  const unsigned char *p1 = (const unsigned char *)s1;
  const unsigned char *p2 = (const unsigned char *)s2;
  static const uint8_t next_state[] = {0x0, 0x3, 0x9, 0x0, 0x3, 0x3,
                                       0x0, 0x6, 0x6, 0x0, 0x6, 0x9};
  static const int8_t result_type[] = {
      2, 2, 2, 2, 3, 2, 2, 2, 2, 2, -1, -1, +1, 3, 3, +1, 3, 3,
      2, 2, 2, 2, 2, 2, 2, 2, 2, 2, +1, +1, -1, 2, 2, -1, 2, 2};
  if (p1 == p2)
    return 0;
  unsigned char c1 = *p1++;
  unsigned char c2 = *p2++;
  int state = 0x0 + ((c1 == '0') + (isdigit(c1) != 0));
  int diff;
  while ((diff = c1 - c2) == 0) {
    if (c1 == '\0')
      return diff;
    state = next_state[state];
    c1 = *p1++;
    c2 = *p2++;
    state += (c1 == '0') + (isdigit(c1) != 0);
  }
  state = result_type[state * 3 + (((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    1350 <strverscmp+0x240>
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    %rax,%rcx
mov    -0x38(%rbp),%eax
cmp    $0x0,%rcx
setne  %cl
and    $0x1,%cl
movzbl %cl,%ecx
add    %ecx,%eax
add    $0x0,%eax
mov    %eax,-0x30(%rbp)
movzbl -0x29(%rbp),%eax
movzbl -0x2a(%rbp),%ecx
sub    %ecx,%eax
mov    %eax,-0x34(%rbp)
cmp    $0x0,%eax
jne    124a <strverscmp+0x13a>
movzbl -0x29(%rbp),%eax
cmp    $0x0,%eax
jne    11d6 <strverscmp+0xc6>
mov    -0x34(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1350 <strverscmp+0x240>
movslq -0x30(%rbp),%rcx
lea    0xe1f(%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,-0x3c(%rbp)
movzbl -0x29(%rbp),%edi
call   1030 <isdigit@plt>
mov    %rax,%rcx
mov    -0x3c(%rbp),%eax
cmp    $0x0,%rcx
setne  %cl
and    $0x1,%cl
movzbl %cl,%ecx
add    %ecx,%eax
add    -0x30(%rbp),%eax
mov    %eax,-0x30(%rbp)
jmp    11a8 <strverscmp+0x98>
mov    -0x30(%rbp),%ecx
mov    %ecx,%eax
lea    (%rax,%rax,2),%eax
mov    %eax,-0x44(%rbp)
movzbl -0x2a(%rbp),%edi
mov    %edi,%eax
sub    $0x30,%eax
sete   %al
movzbl %al,%eax
mov    %eax,-0x48(%rbp)
call   1030 <isdigit@plt>
mov    -0x48(%rbp),%ecx
mov    %rax,%rdx
mov    -0x44(%rbp),%eax
sub    $0x1,%rdx
sbb    $0xffffffff,%ecx
add    %ecx,%eax
movslq %eax,%rcx
lea    0xda8(%rip),%rax
mov    (%rax,%rcx,4),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    %eax,-0x40(%rbp)
sub    $0x2,%eax
je     12b3 <strverscmp+0x1a3>
jmp    12a2 <strverscmp+0x192>
mov    -0x40(%rbp),%eax
sub    $0x3,%eax
je     12be <strverscmp+0x1ae>
jmp    134a <strverscmp+0x23a>
mov    -0x34(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1350 <strverscmp+0x240>
jmp    12c3 <strverscmp+0x1b3>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
movzbl (%rax),%edi
call   1030 <isdigit@plt>
cmp    $0x0,%rax
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,%rax
jne    1311 <strverscmp+0x201>
movl   $0x1,-0x4(%rbp)
jmp    1350 <strverscmp+0x240>
jmp    12c3 <strverscmp+0x1b3>
mov    -0x28(%rbp),%rax
movzbl (%rax),%edi
call   1030 <isdigit@plt>
cmp    $0x0,%rax
je     1339 <strverscmp+0x229>
mov    $0xffffffff,%eax
mov    %eax,-0x4c(%rbp)
jmp    133f <strverscmp+0x22f>
mov    -0x34(%rbp),%eax
mov    %eax,-0x4c(%rbp)
mov    -0x4c(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    1350 <strverscmp+0x240>
mov    -0x30(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strverscmp>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
push   %rax
xor    %eax,%eax
cmp    %rsi,%rdi
je     1214 <strverscmp+0x104>
mov    %rsi,%r14
mov    %rdi,%r12
movzbl (%rdi),%ebp
xor    %r13d,%r13d
cmp    $0x30,%ebp
sete   %r13b
movzbl (%rsi),%r15d
mov    %ebp,%edi
call   1030 <isdigit@plt>
xor    %ebx,%ebx
test   %rax,%rax
setne  %bl
add    %r13d,%ebx
nop
add    $0x1,%r14
add    $0x1,%r12
mov    %ebp,%r13d
sub    %r15d,%r13d
jne    1198 <strverscmp+0x88>
test   %bpl,%bpl
je     11fe <strverscmp+0xee>
movslq %ebx,%r13
movzbl (%r12),%ebp
xor    %ebx,%ebx
cmp    $0x30,%ebp
sete   %bl
movzbl (%r14),%r15d
mov    %ebp,%edi
call   1030 <isdigit@plt>
lea    0xe75(%rip),%rcx
add    (%rcx,%r13,4),%ebx
cmp    $0x1,%rax
sbb    $0xffffffff,%ebx
jmp    1150 <strverscmp+0x40>
lea    (%rbx,%rbx,2),%eax
xor    %ebx,%ebx
cmp    $0x30,%r15b
sete   %bl
add    %eax,%ebx
movzbl %r15b,%edi
call   1030 <isdigit@plt>
cmp    $0x1,%rax
sbb    $0xffffffff,%ebx
movslq %ebx,%rax
lea    0xe70(%rip),%rcx
mov    (%rcx,%rax,4),%eax
cmp    $0x2,%eax
je     11f9 <strverscmp+0xe9>
cmp    $0x3,%eax
jne    1214 <strverscmp+0x104>
xor    %ebx,%ebx
nop
movzbl (%r12,%rbx,1),%edi
call   1030 <isdigit@plt>
test   %rax,%rax
je     1202 <strverscmp+0xf2>
movzbl (%r14,%rbx,1),%edi
call   1030 <isdigit@plt>
add    $0x1,%rbx
test   %rax,%rax
jne    11d0 <strverscmp+0xc0>
mov    $0x1,%eax
jmp    1214 <strverscmp+0x104>
mov    %r13d,%eax
jmp    1214 <strverscmp+0x104>
xor    %eax,%eax
jmp    1214 <strverscmp+0x104>
movzbl (%r14,%rbx,1),%edi
call   1030 <isdigit@plt>
neg    %rax
sbb    %eax,%eax
or     %r13d,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

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