int validate_date(unsigned char day, unsigned char month, unsigned int year) {
  int days_in_february;
  switch (month) {
  case 0:
  case 2:
  case 4:
  case 6:
  case 7:
  case 9:
  case 11:
    if (day > 31)
      return -1;
    break;
  case 3:
  case 5:
  case 8:
  case 10:
    if (day > 30)
      return -1;
    break;
  case 1:
    days_in_february = 28;
    if (year % 4 == 0) {
      if (year % 100 != 0) {
        days_in_february = 29;
      } else if (year % 400 == 0) {
        days_in_february = 29;
      }
    }
    if (day > days_in_february)
      return -1;
    break;
  default:
    return -1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<validate_date>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %dil,%cl
mov    %cl,-0x5(%rbp)
mov    %al,-0x6(%rbp)
mov    %edx,-0xc(%rbp)
movzbl -0x6(%rbp),%eax
mov    %eax,-0x14(%rbp)
test   %eax,%eax
je     11d4 <validate_date+0xd4>
jmp    1127 <validate_date+0x27>
mov    -0x14(%rbp),%eax
sub    $0x1,%eax
je     1210 <validate_date+0x110>
jmp    1138 <validate_date+0x38>
mov    -0x14(%rbp),%eax
sub    $0x2,%eax
je     11d4 <validate_date+0xd4>
jmp    1149 <validate_date+0x49>
mov    -0x14(%rbp),%eax
sub    $0x3,%eax
je     11f2 <validate_date+0xf2>
jmp    115a <validate_date+0x5a>
mov    -0x14(%rbp),%eax
sub    $0x4,%eax
je     11d4 <validate_date+0xd4>
jmp    116b <validate_date+0x6b>
mov    -0x14(%rbp),%eax
sub    $0x5,%eax
je     11f2 <validate_date+0xf2>
jmp    117c <validate_date+0x7c>
mov    -0x14(%rbp),%eax
add    $0xfffffffa,%eax
sub    $0x2,%eax
jb     11d4 <validate_date+0xd4>
jmp    1190 <validate_date+0x90>
mov    -0x14(%rbp),%eax
sub    $0x8,%eax
je     11f2 <validate_date+0xf2>
jmp    11a1 <validate_date+0xa1>
mov    -0x14(%rbp),%eax
sub    $0x9,%eax
je     11d4 <validate_date+0xd4>
jmp    11b2 <validate_date+0xb2>
mov    -0x14(%rbp),%eax
sub    $0xa,%eax
je     11f2 <validate_date+0xf2>
jmp    11c3 <validate_date+0xc3>
mov    -0x14(%rbp),%eax
sub    $0xb,%eax
jne    128b <validate_date+0x18b>
jmp    11d4 <validate_date+0xd4>
movzbl -0x5(%rbp),%eax
cmp    $0x1f,%eax
jle    11ed <validate_date+0xed>
movl   $0xffffffff,-0x4(%rbp)
jmp    129e <validate_date+0x19e>
jmp    1297 <validate_date+0x197>
movzbl -0x5(%rbp),%eax
cmp    $0x1e,%eax
jle    120b <validate_date+0x10b>
movl   $0xffffffff,-0x4(%rbp)
jmp    129e <validate_date+0x19e>
jmp    1297 <validate_date+0x197>
movl   $0x1c,-0x10(%rbp)
mov    -0xc(%rbp),%eax
and    $0x3,%eax
cmp    $0x0,%eax
jne    126d <validate_date+0x16d>
mov    -0xc(%rbp),%eax
mov    $0x64,%ecx
xor    %edx,%edx
div    %ecx
cmp    $0x0,%edx
je     1247 <validate_date+0x147>
movl   $0x1d,-0x10(%rbp)
jmp    1268 <validate_date+0x168>
mov    -0xc(%rbp),%eax
mov    $0x190,%ecx
xor    %edx,%edx
div    %ecx
cmp    $0x0,%edx
jne    1263 <validate_date+0x163>
movl   $0x1d,-0x10(%rbp)
jmp    1268 <validate_date+0x168>
jmp    126d <validate_date+0x16d>
movzbl -0x5(%rbp),%eax
cmp    -0x10(%rbp),%eax
jle    1286 <validate_date+0x186>
movl   $0xffffffff,-0x4(%rbp)
jmp    129e <validate_date+0x19e>
jmp    1297 <validate_date+0x197>
movl   $0xffffffff,-0x4(%rbp)
jmp    129e <validate_date+0x19e>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<validate_date>:
mov    $0xffffffff,%eax
cmp    $0xb,%sil
ja     1120 <validate_date+0x20>
mov    %esi,%ecx
mov    $0xad5,%esi
bt     %rcx,%rsi
jae    1121 <validate_date+0x21>
cmp    $0x1f,%dil
ja     1120 <validate_date+0x20>
xor    %eax,%eax
ret
mov    $0x528,%esi
bt     %rcx,%rsi
jae    1134 <validate_date+0x34>
cmp    $0x1e,%dil
jbe    111e <validate_date+0x1e>
jmp    1120 <validate_date+0x20>
mov    $0x1c,%ecx
test   $0x3,%dl
jne    1167 <validate_date+0x67>
imul   $0xc28f5c29,%edx,%edx
mov    %edx,%esi
ror    $0x2,%esi
mov    $0x1d,%ecx
cmp    $0x28f5c28,%esi
ja     1167 <validate_date+0x67>
ror    $0x4,%edx
xor    %ecx,%ecx
cmp    $0xa3d70b,%edx
setb   %cl
or     $0x1c,%ecx
movzbl %dil,%edx
cmp    %edx,%ecx
jae    111e <validate_date+0x1e>
jmp    1120 <validate_date+0x20>

LLVM IR (-O0):
define i32 @validate_date(i8 zeroext %0, i8 zeroext %1, i32 %2) {
%4 = alloca i32
%5 = alloca i8
%6 = alloca i8
%7 = alloca i32
%8 = alloca i32
store i8 %0, i8* %5
store i8 %1, i8* %6
store i32 %2, i32* %7
%9 = load i8, i8* %6
%10 = zext i8 %9 to i32
switch i32 %10, label %46 [
i32 0, label %11
i32 2, label %11
i32 4, label %11
i32 6, label %11
i32 7, label %11
i32 9, label %11
i32 11, label %11
i32 3, label %17
i32 5, label %17
i32 8, label %17
i32 10, label %17
i32 1, label %23
]
11: ; preds = %3, %3, %3, %3, %3, %3, %3
%12 = load i8, i8* %5
%13 = zext i8 %12 to i32
%14 = icmp sgt i32 %13, 31
br i1 %14, label %15, label %16
15: ; preds = %11
store i32 -1, i32* %4
br label %48
16: ; preds = %11
br label %47
17: ; preds = %3, %3, %3, %3
%18 = load i8, i8* %5
%19 = zext i8 %18 to i32
%20 = icmp sgt i32 %19, 30
br i1 %20, label %21, label %22
21: ; preds = %17
store i32 -1, i32* %4
br label %48
22: ; preds = %17
br label %47
23: ; preds = %3
store i32 28, i32* %8
%24 = load i32, i32* %7
%25 = urem i32 %24, 4
%26 = icmp eq i32 %25, 0
br i1 %26, label %27, label %39
27: ; preds = %23
%28 = load i32, i32* %7
%29 = urem i32 %28, 100
%30 = icmp ne i32 %29, 0
br i1 %30, label %31, label %32
31: ; preds = %27
store i32 29, i32* %8
br label %38
32: ; preds = %27
%33 = load i32, i32* %7
%34 = urem i32 %33, 400
%35 = icmp eq i32 %34, 0
br i1 %35, label %36, label %37
36: ; preds = %32
store i32 29, i32* %8
br label %37
37: ; preds = %36, %32
br label %38
38: ; preds = %37, %31
br label %39
39: ; preds = %38, %23
%40 = load i8, i8* %5
%41 = zext i8 %40 to i32
%42 = load i32, i32* %8
%43 = icmp sgt i32 %41, %42
br i1 %43, label %44, label %45
44: ; preds = %39
store i32 -1, i32* %4
br label %48
45: ; preds = %39
br label %47
46: ; preds = %3
store i32 -1, i32* %4
br label %48
47: ; preds = %45, %22, %16
store i32 0, i32* %4
br label %48
48: ; preds = %47, %46, %44, %21, %15
%49 = load i32, i32* %4
ret i32 %49
}

LLVM IR (-O2):
define i32 @validate_date(i8 zeroext %0, i8 zeroext %1, i32 %2) {
switch i8 %1, label %23 [
i8 0, label %4
i8 2, label %4
i8 4, label %4
i8 6, label %4
i8 7, label %4
i8 9, label %4
i8 11, label %4
i8 3, label %6
i8 5, label %6
i8 8, label %6
i8 10, label %6
i8 1, label %8
]
4: ; preds = %3, %3, %3, %3, %3, %3, %3
%5 = icmp ugt i8 %0, 31
br i1 %5, label %23, label %22
6: ; preds = %3, %3, %3, %3
%7 = icmp ugt i8 %0, 30
br i1 %7, label %23, label %22
8: ; preds = %3
%9 = and i32 %2, 3
%10 = icmp eq i32 %9, 0
br i1 %10, label %11, label %18
11: ; preds = %8
%12 = urem i32 %2, 100
%13 = icmp eq i32 %12, 0
br i1 %13, label %14, label %18
14: ; preds = %11
%15 = urem i32 %2, 400
%16 = icmp eq i32 %15, 0
%17 = select i1 %16, i32 29, i32 28
br label %18
18: ; preds = %14, %11, %8
%19 = phi i32 [ 28, %8 ], [ 29, %11 ], [ %17, %14 ]
%20 = zext i8 %0 to i32
%21 = icmp ult i32 %19, %20
br i1 %21, label %23, label %22
22: ; preds = %18, %6, %4
br label %23
23: ; preds = %3, %18, %6, %4, %22
%24 = phi i32 [ 0, %22 ], [ -1, %4 ], [ -1, %6 ], [ -1, %18 ], [ -1, %3 ]
ret i32 %24
}