#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 */

/* Variables and functions */
size_t strlen(char const *);
int get_string_length(const char *string_value) {
  size_t length;
  length = strlen(string_value);
  if (length > 0xFFFF) {
    return 2048;
  } else if (length > 0xFF) {
    return length + 4;
  } else if (length > 0x7F) {
    return length + 3;
  } else {
    return length + 2;
  }
}


x86 assembly (clang, -O0):
<get_string_length>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %rax,-0x18(%rbp)
cmpq   $0xffff,-0x18(%rbp)
jbe    1143 <get_string_length+0x33>
movl   $0x800,-0x4(%rbp)
jmp    1187 <get_string_length+0x77>
cmpq   $0xff,-0x18(%rbp)
jbe    1161 <get_string_length+0x51>
mov    -0x18(%rbp),%rax
add    $0x4,%rax
mov    %eax,-0x4(%rbp)
jmp    1187 <get_string_length+0x77>
cmpq   $0x7f,-0x18(%rbp)
jbe    117c <get_string_length+0x6c>
mov    -0x18(%rbp),%rax
add    $0x3,%rax
mov    %eax,-0x4(%rbp)
jmp    1187 <get_string_length+0x77>
mov    -0x18(%rbp),%rax
add    $0x2,%rax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<get_string_length>:
push   %rax
call   1030 <strlen@plt>
mov    $0x800,%ecx
cmp    $0xffff,%rax
ja     1140 <get_string_length+0x30>
cmp    $0x100,%rax
jb     1130 <get_string_length+0x20>
lea    0x4(%rax),%ecx
jmp    1140 <get_string_length+0x30>
cmp    $0x80,%rax
jb     113d <get_string_length+0x2d>
lea    0x3(%rax),%ecx
jmp    1140 <get_string_length+0x30>
lea    0x2(%rax),%ecx
mov    %ecx,%eax
pop    %rcx
ret

LLVM IR (-O0):
define i32 @get_string_length(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i64
store i8* %0, i8** %3
%5 = load i8*, i8** %3
%6 = call i64 @strlen(i8* %5)
store i64 %6, i64* %4
%7 = load i64, i64* %4
%8 = icmp ugt i64 %7, 65535
br i1 %8, label %9, label %10
9: ; preds = %1
store i32 2048, i32* %2
br label %28
10: ; preds = %1
%11 = load i64, i64* %4
%12 = icmp ugt i64 %11, 255
br i1 %12, label %13, label %17
13: ; preds = %10
%14 = load i64, i64* %4
%15 = add i64 %14, 4
%16 = trunc i64 %15 to i32
store i32 %16, i32* %2
br label %28
17: ; preds = %10
%18 = load i64, i64* %4
%19 = icmp ugt i64 %18, 127
br i1 %19, label %20, label %24
20: ; preds = %17
%21 = load i64, i64* %4
%22 = add i64 %21, 3
%23 = trunc i64 %22 to i32
store i32 %23, i32* %2
br label %28
24: ; preds = %17
%25 = load i64, i64* %4
%26 = add i64 %25, 2
%27 = trunc i64 %26 to i32
store i32 %27, i32* %2
br label %28
28: ; preds = %24, %20, %13, %9
%29 = load i32, i32* %2
ret i32 %29
}

LLVM IR (-O2):
define i32 @get_string_length(i8* nocapture %0) {
%2 = tail call i64 @strlen(i8* dereferenceable(1) %0)
%3 = icmp ugt i64 %2, 65535
br i1 %3, label %16, label %4
4: ; preds = %1
%5 = icmp ugt i64 %2, 255
br i1 %5, label %6, label %9
6: ; preds = %4
%7 = trunc i64 %2 to i32
%8 = add nuw nsw i32 %7, 4
br label %16
9: ; preds = %4
%10 = icmp ugt i64 %2, 127
%11 = trunc i64 %2 to i32
br i1 %10, label %12, label %14
12: ; preds = %9
%13 = add nuw nsw i32 %11, 3
br label %16
14: ; preds = %9
%15 = add nuw nsw i32 %11, 2
br label %16
16: ; preds = %1, %14, %12, %6
%17 = phi i32 [ %8, %6 ], [ %13, %12 ], [ %15, %14 ], [ 2048, %1 ]
ret i32 %17
}