#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 stat {
  int st_mode;
};

/* Variables and functions */
#define S_IFBLK 134
#define S_IFCHR 133
#define S_IFDIR 132
#define S_IFIFO 131
#define S_IFLNK 130
int S_IFMT;
#define S_IFREG 129
#define S_IFSOCK 128
char filetype_character(const struct stat *statbuf) {
  switch (statbuf->st_mode & S_IFMT) {
  case S_IFBLK:
    return 'b';
  case S_IFCHR:
    return 'b';
  case S_IFDIR:
    return 'd';
  case S_IFIFO:
    return 'p';
  case S_IFLNK:
    return 'l';
  case S_IFSOCK:
    return 's';
  case S_IFREG:
  default:
    return '-';
  }
}


x86 assembly (clang, -O0):
<filetype_character>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    (%rax),%eax
mov    0x2ecb(%rip),%rcx
mov    (%rcx),%ecx
and    %ecx,%eax
add    $0xffffff80,%eax
mov    %eax,%ecx
mov    %rcx,-0x18(%rbp)
sub    $0x6,%eax
ja     117a <filetype_character+0x7a>
mov    -0x18(%rbp),%rax
lea    0xeca(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movb   $0x62,-0x1(%rbp)
jmp    117e <filetype_character+0x7e>
movb   $0x62,-0x1(%rbp)
jmp    117e <filetype_character+0x7e>
movb   $0x64,-0x1(%rbp)
jmp    117e <filetype_character+0x7e>
movb   $0x70,-0x1(%rbp)
jmp    117e <filetype_character+0x7e>
movb   $0x6c,-0x1(%rbp)
jmp    117e <filetype_character+0x7e>
movb   $0x73,-0x1(%rbp)
jmp    117e <filetype_character+0x7e>
jmp    117a <filetype_character+0x7a>
movb   $0x2d,-0x1(%rbp)
movsbl -0x1(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<filetype_character>:
mov    0x2ed9(%rip),%rax
mov    (%rax),%eax
and    (%rdi),%eax
lea    -0x400(,%rax,8),%ecx
add    $0xffffff80,%eax
movabs $0x626264706c2d73,%rdx
shr    %cl,%rdx
cmp    $0x7,%eax
mov    $0x2d,%eax
cmovb  %edx,%eax
ret

LLVM IR (-O0):
%struct.stat = type { i32 }
@S_IFMT = global i32 0
define signext i8 @filetype_character(%struct.stat* %0) {
%2 = alloca i8
%3 = alloca %struct.stat*
store %struct.stat* %0, %struct.stat** %3
%4 = load %struct.stat*, %struct.stat** %3
%5 = getelementptr inbounds %struct.stat, %struct.stat* %4, i32 0, i32 0
%6 = load i32, i32* %5
%7 = load i32, i32* @S_IFMT
%8 = and i32 %6, %7
switch i32 %8, label %16 [
i32 134, label %9
i32 133, label %10
i32 132, label %11
i32 131, label %12
i32 130, label %13
i32 128, label %14
i32 129, label %15
]
9: ; preds = %1
store i8 98, i8* %2
br label %17
10: ; preds = %1
store i8 98, i8* %2
br label %17
11: ; preds = %1
store i8 100, i8* %2
br label %17
12: ; preds = %1
store i8 112, i8* %2
br label %17
13: ; preds = %1
store i8 108, i8* %2
br label %17
14: ; preds = %1
store i8 115, i8* %2
br label %17
15: ; preds = %1
br label %16
16: ; preds = %1, %15
store i8 45, i8* %2
br label %17
17: ; preds = %16, %14, %13, %12, %11, %10, %9
%18 = load i8, i8* %2
ret i8 %18
}

LLVM IR (-O2):
%struct.stat = type { i32 }
@S_IFMT = global i32 0
define signext i8 @filetype_character(%struct.stat* nocapture %0) {
%2 = getelementptr inbounds %struct.stat, %struct.stat* %0, i64 0, i32 0
%3 = load i32, i32* %2
%4 = load i32, i32* @S_IFMT
%5 = and i32 %4, %3
%6 = add i32 %5, -128
%7 = icmp ult i32 %6, 7
%8 = zext i32 %6 to i56
%9 = shl nuw nsw i56 %8, 3
%10 = lshr i56 27692731240033651, %9
%11 = trunc i56 %10 to i8
%12 = select i1 %7, i8 %11, i8 45
ret i8 %12
}