#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 /*<<< orphan*/ tmpfname;
struct utsname {
  char *machine;
};
typedef long off_t;

/* Variables and functions */
scalar_t__ EOVERFLOW;
void *MAP_FAILED;
int /*<<< orphan*/ MAP_SHARED;
int O_CREAT;
int O_EXCL;
int O_RDWR;
int PROT_READ;
int PROT_WRITE;
int S_IRUSR;
int S_IWUSR;
int /*<<< orphan*/ _SC_PAGE_SIZE;
int /*<<< orphan*/ close(int);
scalar_t__ errno;
int getpid();
void *mmap(int /*<<< orphan*/ *, size_t, int, int /*<<< orphan*/, int, long);
int /*<<< orphan*/ munmap(void *, size_t);
int open(char *, int, int);
int /*<<< orphan*/ perror(char *);
int /*<<< orphan*/ printf(char *, ...);
int /*<<< orphan*/ snprintf(char *, int, char *, int);
char *strerror(scalar_t__);
scalar_t__ strstr(char *, char *);
long sysconf(int /*<<< orphan*/);
int /*<<< orphan*/ uname(struct utsname *);
int /*<<< orphan*/ unlink(char *);
int main(void) {
  char tmpfname[256];
  void *pa;
  size_t len;
  int fd;
  off_t off = 0;
  if (sizeof(void *) == 8) {
    printf("USUPPORTED: Cannot be tested on 64 bit architecture\n");
    return 4;
  }
  struct utsname buf;
  if (!uname(&buf) && strstr(buf.machine, "64")) {
    printf("UNSUPPORTED: Looks like we run on 64bit kernel (%s)\n",
           buf.machine);
    return 4;
  }
  long page_size = sysconf(_SC_PAGE_SIZE);
  snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_mmap_31_1_%d", getpid());
  unlink(tmpfname);
  fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR);
  if (fd == -1) {
    printf("Error at open(): %s\n", strerror(errno));
    return 2;
  }
  unlink(tmpfname);
  len = ~((size_t)0) & (~(page_size - 1));
  off = ((off_t) ~((size_t)0)) * page_size;
  off &= ~(page_size - 1);
  printf("off: %llx, len: %llx\n", (unsigned long long)off,
         (unsigned long long)len);
  pa = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, off);
  if (pa == MAP_FAILED && errno == EOVERFLOW) {
    printf("Got EOVERFLOW\n");
    printf("Test PASSED\n");
    return 0;
  }
  if (pa == MAP_FAILED)
    perror("Test FAILED: expect EOVERFLOW but get other error");
  else
    printf("Test FAILED: Expect EOVERFLOW but got no error\n");
  close(fd);
  munmap(pa, len);
  return 1;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x140,%rsp
movl   $0x0,-0x4(%rbp)
movq   $0x0,-0x130(%rbp)
lea    0xecc(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    $0x4,%eax
add    $0x140,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rax
lea    0xee8(%rip),%rdi
call   1030 <puts@plt>
mov    $0x4,%eax
pop    %rcx
ret

LLVM IR (-O0):
%struct.utsname = type { i8* }
@.str = [53 x i8] c"USUPPORTED: Cannot be tested on 64 bit architecture\0A\00"
@EOVERFLOW = global i64 0
@MAP_FAILED = global i8* null
@MAP_SHARED = global i32 0
@O_CREAT = global i32 0
@O_EXCL = global i32 0
@O_RDWR = global i32 0
@PROT_READ = global i32 0
@PROT_WRITE = global i32 0
@S_IRUSR = global i32 0
@S_IWUSR = global i32 0
@_SC_PAGE_SIZE = global i32 0
@errno = global i64 0
define i32 @main() {
%1 = alloca i32
%2 = alloca [256 x i8]
%3 = alloca i8*
%4 = alloca i64
%5 = alloca i32
%6 = alloca i64
%7 = alloca %struct.utsname
%8 = alloca i64
store i32 0, i32* %1
store i64 0, i64* %6
%9 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([53 x i8], [53 x i8]* @.str, i64 0, i64 0))
ret i32 4
}

LLVM IR (-O2):
@EOVERFLOW = global i64 0
@MAP_FAILED = global i8* null
@MAP_SHARED = global i32 0
@O_CREAT = global i32 0
@O_EXCL = global i32 0
@O_RDWR = global i32 0
@PROT_READ = global i32 0
@PROT_WRITE = global i32 0
@S_IRUSR = global i32 0
@S_IWUSR = global i32 0
@_SC_PAGE_SIZE = global i32 0
@errno = global i64 0
@str = [52 x i8] c"USUPPORTED: Cannot be tested on 64 bit architecture\00"
define i32 @main() {
%1 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([52 x i8], [52 x i8]* @str, i64 0, i64 0))
ret i32 4
}