#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 */
struct keyval {
  int dummy;
};

/* Variables and functions */
char *keyvals_get_val(struct keyval const *, char const *);
int strtol(char const *, char **, int);
int comments_get_date(const struct keyval *comments, const char *key) {
  const char *val;
  char *endptr;
  int year, month, day;
  long int ival;
  val = keyvals_get_val(comments, key);
  if (val == NULL)
    return -1;
  year = strtol(val, &endptr, 10);
  if (year < 1000 || year > 9999)
    return -1;
  ival = year * 10000;
  if (*endptr == '-' || *endptr == ' ' || *endptr == '/') {
    month = strtol(endptr + 1, &endptr, 10);
    if (month < 1 || month > 12)
      return ival;
    ival += month * 100;
  }
  if (*endptr == '-' || *endptr == ' ' || *endptr == '/') {
    day = strtol(endptr + 1, &endptr, 10);
    if (day < 1 || day > 31)
      return ival;
    ival += day;
  }
  return ival;
}


x86 assembly (clang, -O0):
<comments_get_date>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
call   1040 <keyvals_get_val@plt>
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
jne    1158 <comments_get_date+0x38>
movl   $0xffffffff,-0x4(%rbp)
jmp    1293 <comments_get_date+0x173>
mov    -0x20(%rbp),%rdi
lea    -0x28(%rbp),%rsi
mov    $0xa,%edx
call   1030 <strtol@plt>
mov    %eax,-0x2c(%rbp)
cmpl   $0x3e8,-0x2c(%rbp)
jl     1187 <comments_get_date+0x67>
cmpl   $0x270f,-0x2c(%rbp)
jle    1193 <comments_get_date+0x73>
movl   $0xffffffff,-0x4(%rbp)
jmp    1293 <comments_get_date+0x173>
imul   $0x2710,-0x2c(%rbp),%eax
cltq
mov    %rax,-0x40(%rbp)
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
je     11d0 <comments_get_date+0xb0>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x20,%eax
je     11d0 <comments_get_date+0xb0>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
jne    1217 <comments_get_date+0xf7>
mov    -0x28(%rbp),%rdi
add    $0x1,%rdi
lea    -0x28(%rbp),%rsi
mov    $0xa,%edx
call   1030 <strtol@plt>
mov    %eax,-0x30(%rbp)
cmpl   $0x1,-0x30(%rbp)
jl     11fd <comments_get_date+0xdd>
cmpl   $0xc,-0x30(%rbp)
jle    1209 <comments_get_date+0xe9>
mov    -0x40(%rbp),%rax
mov    %eax,-0x4(%rbp)
jmp    1293 <comments_get_date+0x173>
imul   $0x64,-0x30(%rbp),%eax
cltq
add    -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2d,%eax
je     1247 <comments_get_date+0x127>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x20,%eax
je     1247 <comments_get_date+0x127>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x2f,%eax
jne    128c <comments_get_date+0x16c>
mov    -0x28(%rbp),%rdi
add    $0x1,%rdi
lea    -0x28(%rbp),%rsi
mov    $0xa,%edx
call   1030 <strtol@plt>
mov    %eax,-0x34(%rbp)
cmpl   $0x1,-0x34(%rbp)
jl     1274 <comments_get_date+0x154>
cmpl   $0x1f,-0x34(%rbp)
jle    1280 <comments_get_date+0x160>
mov    -0x40(%rbp),%rax
mov    %eax,-0x4(%rbp)
jmp    1293 <comments_get_date+0x173>
movslq -0x34(%rbp),%rax
add    -0x40(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<comments_get_date>:
push   %r14
push   %rbx
push   %rax
call   1040 <keyvals_get_val@plt>
mov    $0xffffffff,%ebx
test   %rax,%rax
je     11c8 <comments_get_date+0xa8>
mov    %rsp,%rsi
mov    %rax,%rdi
mov    $0xa,%edx
call   1030 <strtol@plt>
lea    -0x2710(%rax),%ecx
cmp    $0xffffdcd8,%ecx
jb     11c8 <comments_get_date+0xa8>
imul   $0x2710,%eax,%ebx
mov    (%rsp),%rdi
movzbl (%rdi),%eax
movabs $0xa00100000000,%r14
cmp    $0x2f,%rax
ja     119d <comments_get_date+0x7d>
bt     %rax,%r14
jae    119d <comments_get_date+0x7d>
add    $0x1,%rdi
mov    %rsp,%rsi
mov    $0xa,%edx
call   1030 <strtol@plt>
lea    -0xd(%rax),%ecx
cmp    $0xfffffff4,%ecx
jb     11c8 <comments_get_date+0xa8>
imul   $0x64,%eax,%eax
add    %rax,%rbx
mov    (%rsp),%rdi
mov    (%rdi),%al
cmp    $0x2f,%al
ja     11c8 <comments_get_date+0xa8>
movzbl %al,%eax
bt     %rax,%r14
jae    11c8 <comments_get_date+0xa8>
add    $0x1,%rdi
mov    %rsp,%rsi
mov    $0xa,%edx
call   1030 <strtol@plt>
lea    -0x20(%rax),%ecx
cmp    $0xffffffe0,%ecx
jbe    11c8 <comments_get_date+0xa8>
mov    %eax,%eax
add    %rax,%rbx
mov    %ebx,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
%struct.keyval = type { i32 }
define i32 @comments_get_date(%struct.keyval* %0, i8* %1) {
%3 = alloca i32
%4 = alloca %struct.keyval*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i64
store %struct.keyval* %0, %struct.keyval** %4
store i8* %1, i8** %5
%12 = load %struct.keyval*, %struct.keyval** %4
%13 = load i8*, i8** %5
%14 = call i8* @keyvals_get_val(%struct.keyval* %12, i8* %13)
store i8* %14, i8** %6
%15 = load i8*, i8** %6
%16 = icmp eq i8* %15, null
br i1 %16, label %17, label %18
17: ; preds = %2
store i32 -1, i32* %3
br label %98
18: ; preds = %2
%19 = load i8*, i8** %6
%20 = call i32 @strtol(i8* %19, i8** %7, i32 10)
store i32 %20, i32* %8
%21 = load i32, i32* %8
%22 = icmp slt i32 %21, 1000
br i1 %22, label %26, label %23
23: ; preds = %18
%24 = load i32, i32* %8
%25 = icmp sgt i32 %24, 9999
br i1 %25, label %26, label %27
26: ; preds = %23, %18
store i32 -1, i32* %3
br label %98
27: ; preds = %23
%28 = load i32, i32* %8
%29 = mul nsw i32 %28, 10000
%30 = sext i32 %29 to i64
store i64 %30, i64* %11
%31 = load i8*, i8** %7
%32 = load i8, i8* %31
%33 = sext i8 %32 to i32
%34 = icmp eq i32 %33, 45
br i1 %34, label %45, label %35
35: ; preds = %27
%36 = load i8*, i8** %7
%37 = load i8, i8* %36
%38 = sext i8 %37 to i32
%39 = icmp eq i32 %38, 32
br i1 %39, label %45, label %40
40: ; preds = %35
%41 = load i8*, i8** %7
%42 = load i8, i8* %41
%43 = sext i8 %42 to i32
%44 = icmp eq i32 %43, 47
br i1 %44, label %45, label %63
45: ; preds = %40, %35, %27
%46 = load i8*, i8** %7
%47 = getelementptr inbounds i8, i8* %46, i64 1
%48 = call i32 @strtol(i8* %47, i8** %7, i32 10)
store i32 %48, i32* %9
%49 = load i32, i32* %9
%50 = icmp slt i32 %49, 1
br i1 %50, label %54, label %51
51: ; preds = %45
%52 = load i32, i32* %9
%53 = icmp sgt i32 %52, 12
br i1 %53, label %54, label %57
54: ; preds = %51, %45
%55 = load i64, i64* %11
%56 = trunc i64 %55 to i32
store i32 %56, i32* %3
br label %98
57: ; preds = %51
%58 = load i32, i32* %9
%59 = mul nsw i32 %58, 100
%60 = sext i32 %59 to i64
%61 = load i64, i64* %11
%62 = add nsw i64 %61, %60
store i64 %62, i64* %11
br label %63
63: ; preds = %57, %40
%64 = load i8*, i8** %7
%65 = load i8, i8* %64
%66 = sext i8 %65 to i32
%67 = icmp eq i32 %66, 45
br i1 %67, label %78, label %68
68: ; preds = %63
%69 = load i8*, i8** %7
%70 = load i8, i8* %69
%71 = sext i8 %70 to i32
%72 = icmp eq i32 %71, 32
br i1 %72, label %78, label %73
73: ; preds = %68
%74 = load i8*, i8** %7
%75 = load i8, i8* %74
%76 = sext i8 %75 to i32
%77 = icmp eq i32 %76, 47
br i1 %77, label %78, label %95
78: ; preds = %73, %68, %63
%79 = load i8*, i8** %7
%80 = getelementptr inbounds i8, i8* %79, i64 1
%81 = call i32 @strtol(i8* %80, i8** %7, i32 10)
store i32 %81, i32* %10
%82 = load i32, i32* %10
%83 = icmp slt i32 %82, 1
br i1 %83, label %87, label %84
84: ; preds = %78
%85 = load i32, i32* %10
%86 = icmp sgt i32 %85, 31
br i1 %86, label %87, label %90
87: ; preds = %84, %78
%88 = load i64, i64* %11
%89 = trunc i64 %88 to i32
store i32 %89, i32* %3
br label %98
90: ; preds = %84
%91 = load i32, i32* %10
%92 = sext i32 %91 to i64
%93 = load i64, i64* %11
%94 = add nsw i64 %93, %92
store i64 %94, i64* %11
br label %95
95: ; preds = %90, %73
%96 = load i64, i64* %11
%97 = trunc i64 %96 to i32
store i32 %97, i32* %3
br label %98
98: ; preds = %95, %87, %54, %26, %17
%99 = load i32, i32* %3
ret i32 %99
}

LLVM IR (-O2):
%struct.keyval = type { i32 }
define i32 @comments_get_date(%struct.keyval* %0, i8* %1) {
%3 = alloca i8*
%4 = bitcast i8** %3 to i8*
%5 = tail call i8* @keyvals_get_val(%struct.keyval* %0, i8* %1)
%6 = icmp eq i8* %5, null
br i1 %6, label %44, label %7
7: ; preds = %2
%8 = call i32 @strtol(i8* %5, i8** %3, i32 10)
%9 = add i32 %8, -10000
%10 = icmp ult i32 %9, -9000
br i1 %10, label %44, label %11
11: ; preds = %7
%12 = mul nuw nsw i32 %8, 10000
%13 = zext i32 %12 to i64
%14 = load i8*, i8** %3
%15 = load i8, i8* %14
switch i8 %15, label %27 [
i8 45, label %16
i8 32, label %16
i8 47, label %16
]
16: ; preds = %11, %11, %11
%17 = getelementptr inbounds i8, i8* %14, i64 1
%18 = call i32 @strtol(i8* %17, i8** %3, i32 10)
%19 = add i32 %18, -13
%20 = icmp ult i32 %19, -12
br i1 %20, label %44, label %21
21: ; preds = %16
%22 = mul nuw nsw i32 %18, 100
%23 = zext i32 %22 to i64
%24 = add nuw nsw i64 %23, %13
%25 = load i8*, i8** %3
%26 = load i8, i8* %25
br label %27
27: ; preds = %11, %21
%28 = phi i8 [ %26, %21 ], [ %15, %11 ]
%29 = phi i8* [ %25, %21 ], [ %14, %11 ]
%30 = phi i64 [ %24, %21 ], [ %13, %11 ]
switch i8 %28, label %41 [
i8 45, label %31
i8 32, label %31
i8 47, label %31
]
31: ; preds = %27, %27, %27
%32 = getelementptr inbounds i8, i8* %29, i64 1
%33 = call i32 @strtol(i8* %32, i8** %3, i32 10)
%34 = add i32 %33, -32
%35 = icmp ult i32 %34, -31
br i1 %35, label %36, label %38
36: ; preds = %31
%37 = trunc i64 %30 to i32
br label %44
38: ; preds = %31
%39 = zext i32 %33 to i64
%40 = add nuw nsw i64 %30, %39
br label %41
41: ; preds = %27, %38
%42 = phi i64 [ %40, %38 ], [ %30, %27 ]
%43 = trunc i64 %42 to i32
br label %44
44: ; preds = %16, %7, %2, %41, %36
%45 = phi i32 [ %37, %36 ], [ %43, %41 ], [ -1, %2 ], [ -1, %7 ], [ %12, %16 ]
ret i32 %45
}