#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 tm {
  int tm_year;
  int tm_mon;
  int tm_mday;
  int tm_isdst;
  scalar_t__ tm_sec;
  scalar_t__ tm_min;
  scalar_t__ tm_hour;
};

/* Variables and functions */
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ mktime(struct tm *);
void irix_6_4_bug(void) {
  struct tm tm;
  tm.tm_year = 96;
  tm.tm_mon = 3;
  tm.tm_mday = 0;
  tm.tm_hour = 0;
  tm.tm_min = 0;
  tm.tm_sec = 0;
  tm.tm_isdst = -1;
  mktime(&tm);
  if (tm.tm_mon != 2 || tm.tm_mday != 31)
    exit(3);
}


x86 assembly (clang, -O0):
<irix_6_4_bug>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movl   $0x60,-0x28(%rbp)
movl   $0x3,-0x24(%rbp)
movl   $0x0,-0x20(%rbp)
movq   $0x0,-0x8(%rbp)
movq   $0x0,-0x10(%rbp)
movq   $0x0,-0x18(%rbp)
movl   $0xffffffff,-0x1c(%rbp)
lea    -0x28(%rbp),%rdi
call   1030 <mktime@plt>
cmpl   $0x2,-0x24(%rbp)
jne    1179 <irix_6_4_bug+0x59>
cmpl   $0x1f,-0x20(%rbp)
je     1183 <irix_6_4_bug+0x63>
mov    $0x3,%edi
call   1040 <exit@plt>
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<irix_6_4_bug>:
sub    $0x28,%rsp
xorps  %xmm0,%xmm0
movaps %xmm0,0x10(%rsp)
movq   $0x0,0x20(%rsp)
movaps 0xec4(%rip),%xmm0
movaps %xmm0,(%rsp)
mov    %rsp,%rdi
call   1030 <mktime@plt>
cmpl   $0x2,0x4(%rsp)
jne    115b <irix_6_4_bug+0x3b>
cmpl   $0x1f,0x8(%rsp)
jne    115b <irix_6_4_bug+0x3b>
add    $0x28,%rsp
ret
mov    $0x3,%edi
call   1040 <exit@plt>

LLVM IR (-O0):
%struct.tm = type { i32, i32, i32, i32, i64, i64, i64 }
define void @irix_6_4_bug() {
%1 = alloca %struct.tm
%2 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 0
store i32 96, i32* %2
%3 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 1
store i32 3, i32* %3
%4 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 2
store i32 0, i32* %4
%5 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 6
store i64 0, i64* %5
%6 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 5
store i64 0, i64* %6
%7 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 4
store i64 0, i64* %7
%8 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 3
store i32 -1, i32* %8
%9 = call i32 @mktime(%struct.tm* %1)
%10 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 1
%11 = load i32, i32* %10
%12 = icmp ne i32 %11, 2
br i1 %12, label %17, label %13
13: ; preds = %0
%14 = getelementptr inbounds %struct.tm, %struct.tm* %1, i32 0, i32 2
%15 = load i32, i32* %14
%16 = icmp ne i32 %15, 31
br i1 %16, label %17, label %19
17: ; preds = %13, %0
%18 = call i32 @exit(i32 3)
unreachable
19: ; preds = %13
ret void
}

LLVM IR (-O2):
%struct.tm = type { i32, i32, i32, i32, i64, i64, i64 }
define void @irix_6_4_bug() {
%1 = alloca %struct.tm
%2 = bitcast %struct.tm* %1 to i8*
%3 = getelementptr inbounds %struct.tm, %struct.tm* %1, i64 0, i32 1
%4 = getelementptr inbounds %struct.tm, %struct.tm* %1, i64 0, i32 2
%5 = getelementptr inbounds %struct.tm, %struct.tm* %1, i64 0, i32 4
%6 = bitcast i64* %5 to i8*
%7 = bitcast %struct.tm* %1 to <4 x i32>*
store <4 x i32> <i32 96, i32 3, i32 0, i32 -1>, <4 x i32>* %7
%8 = call i32 @mktime(%struct.tm* %1)
%9 = load i32, i32* %3
%10 = icmp ne i32 %9, 2
%11 = load i32, i32* %4
%12 = icmp ne i32 %11, 31
%13 = select i1 %10, i1 true, i1 %12
br i1 %13, label %14, label %16
14: ; preds = %0
%15 = tail call i32 @exit(i32 3)
unreachable
16: ; preds = %0
ret void
}