const char *minimum_size_type(int lwr, int upr) {
  if (lwr >= 0) {
    if (upr <= 255) {
      return "unsigned char";
    } else if (upr < 65535) {
      return "unsigned short int";
    } else {
      return "unsigned int";
    }
  } else if (lwr >= -127 && upr <= 127) {
    return "signed char";
  } else if (lwr >= -32767 && upr < 32767) {
    return "short";
  } else {
    return "int";
  }
}


x86 assembly (clang, -O0):
<minimum_size_type>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0xc(%rbp)
mov    %esi,-0x10(%rbp)
cmpl   $0x0,-0xc(%rbp)
jl     115e <minimum_size_type+0x5e>
cmpl   $0xff,-0x10(%rbp)
jg     1131 <minimum_size_type+0x31>
lea    0xed8(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    11b7 <minimum_size_type+0xb7>
cmpl   $0xffff,-0x10(%rbp)
jge    114e <minimum_size_type+0x4e>
lea    0xec9(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    11b7 <minimum_size_type+0xb7>
lea    0xecc(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    11b7 <minimum_size_type+0xb7>
cmpl   $0xffffff81,-0xc(%rbp)
jl     1182 <minimum_size_type+0x82>
cmpl   $0x7f,-0x10(%rbp)
jg     1182 <minimum_size_type+0x82>
lea    0xe89(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    11b7 <minimum_size_type+0xb7>
cmpl   $0xffff8001,-0xc(%rbp)
jl     11ac <minimum_size_type+0xac>
cmpl   $0x7fff,-0x10(%rbp)
jge    11ac <minimum_size_type+0xac>
lea    0xe8b(%rip),%rax
mov    %rax,-0x8(%rbp)
jmp    11b7 <minimum_size_type+0xb7>
lea    0xe77(%rip),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<minimum_size_type>:
test   %edi,%edi
js     1114 <minimum_size_type+0x14>
cmp    $0x100,%esi
jge    1129 <minimum_size_type+0x29>
lea    0xeed(%rip),%rax
ret
cmp    $0xffffff81,%edi
jb     1142 <minimum_size_type+0x42>
cmp    $0x80,%esi
jge    1142 <minimum_size_type+0x42>
lea    0xeda(%rip),%rax
ret
cmp    $0xffff,%esi
lea    0xed8(%rip),%rcx
lea    0xee4(%rip),%rax
cmovb  %rcx,%rax
ret
cmp    $0x7fff,%esi
lea    0xedf(%rip),%rax
lea    0xed4(%rip),%rcx
cmovge %rcx,%rax
cmp    $0xffff8001,%edi
cmovb  %rcx,%rax
ret

LLVM IR (-O0):
@.str = [14 x i8] c"unsigned char\00"
@.str.1 = [19 x i8] c"unsigned short int\00"
@.str.2 = [13 x i8] c"unsigned int\00"
@.str.3 = [12 x i8] c"signed char\00"
@.str.4 = [6 x i8] c"short\00"
@.str.5 = [4 x i8] c"int\00"
define i8* @minimum_size_type(i32 %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i32
store i32 %0, i32* %4
store i32 %1, i32* %5
%6 = load i32, i32* %4
%7 = icmp sge i32 %6, 0
br i1 %7, label %8, label %17
8: ; preds = %2
%9 = load i32, i32* %5
%10 = icmp sle i32 %9, 255
br i1 %10, label %11, label %12
11: ; preds = %8
store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0), i8** %3
br label %32
12: ; preds = %8
%13 = load i32, i32* %5
%14 = icmp slt i32 %13, 65535
br i1 %14, label %15, label %16
15: ; preds = %12
store i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.1, i64 0, i64 0), i8** %3
br label %32
16: ; preds = %12
store i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0), i8** %3
br label %32
17: ; preds = %2
%18 = load i32, i32* %4
%19 = icmp sge i32 %18, -127
br i1 %19, label %20, label %24
20: ; preds = %17
%21 = load i32, i32* %5
%22 = icmp sle i32 %21, 127
br i1 %22, label %23, label %24
23: ; preds = %20
store i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str.3, i64 0, i64 0), i8** %3
br label %32
24: ; preds = %20, %17
%25 = load i32, i32* %4
%26 = icmp sge i32 %25, -32767
br i1 %26, label %27, label %31
27: ; preds = %24
%28 = load i32, i32* %5
%29 = icmp slt i32 %28, 32767
br i1 %29, label %30, label %31
30: ; preds = %27
store i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.4, i64 0, i64 0), i8** %3
br label %32
31: ; preds = %27, %24
store i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.5, i64 0, i64 0), i8** %3
br label %32
32: ; preds = %31, %30, %23, %16, %15, %11
%33 = load i8*, i8** %3
ret i8* %33
}

LLVM IR (-O2):
@.str = [14 x i8] c"unsigned char\00"
@.str.1 = [19 x i8] c"unsigned short int\00"
@.str.2 = [13 x i8] c"unsigned int\00"
@.str.3 = [12 x i8] c"signed char\00"
@.str.4 = [6 x i8] c"short\00"
@.str.5 = [4 x i8] c"int\00"
define i8* @minimum_size_type(i32 %0, i32 %1) {
%3 = icmp sgt i32 %0, -1
br i1 %3, label %4, label %9
4: ; preds = %2
%5 = icmp slt i32 %1, 256
br i1 %5, label %18, label %6
6: ; preds = %4
%7 = icmp ult i32 %1, 65535
%8 = select i1 %7, i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str.1, i64 0, i64 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i64 0, i64 0)
br label %18
9: ; preds = %2
%10 = icmp ugt i32 %0, -128
%11 = icmp slt i32 %1, 128
%12 = and i1 %10, %11
br i1 %12, label %18, label %13
13: ; preds = %9
%14 = icmp ugt i32 %0, -32768
%15 = icmp slt i32 %1, 32767
%16 = and i1 %14, %15
%17 = select i1 %16, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.5, i64 0, i64 0)
br label %18
18: ; preds = %13, %9, %6, %4
%19 = phi i8* [ getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0), %4 ], [ %8, %6 ], [ getelementptr inbounds ([12 x i8], [12 x i8]* @.str.3, i64 0, i64 0), %9 ], [ %17, %13 ]
ret i8* %19
}