#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 */
int /*<<< orphan*/ assert(int);
int /*<<< orphan*/ tolower(char);
size_t UrlGetProto(char *d, size_t sd, char const **ppurl) {
  char const *s;
  char *rd;
  char c;
  assert(d != NULL);
  assert(sd > 0);
  assert(ppurl != NULL);
  assert(*ppurl != NULL);
  rd = d;
  s = *ppurl;
  while (((c = *s++) != 0) && (--sd)) {
    if (c == ':')
      break;
    *d++ = tolower(c);
  }
  *d = '\0';
  *ppurl = s;
  return ((size_t)(d - rd));
}


x86 assembly (clang, -O0):
<UrlGetProto>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
cmpq   $0x0,-0x8(%rbp)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
cmpq   $0x0,-0x10(%rbp)
seta   %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
cmpq   $0x0,-0x18(%rbp)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
mov    -0x18(%rbp),%rax
cmpq   $0x0,(%rax)
setne  %al
and    $0x1,%al
movzbl %al,%edi
call   1030 <assert@plt>
mov    -0x8(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x18(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
mov    (%rax),%al
mov    %al,-0x29(%rbp)
movsbl %al,%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x2a(%rbp)
je     11cd <UrlGetProto+0xad>
mov    -0x10(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x10(%rbp)
cmp    $0x0,%rax
setne  %al
mov    %al,-0x2a(%rbp)
mov    -0x2a(%rbp),%al
test   $0x1,%al
jne    11dd <UrlGetProto+0xbd>
jmp    1210 <UrlGetProto+0xf0>
movsbl -0x29(%rbp),%eax
cmp    $0x3a,%eax
jne    11ef <UrlGetProto+0xcf>
jmp    1210 <UrlGetProto+0xf0>
movsbl -0x29(%rbp),%edi
call   1040 <tolower@plt>
mov    %al,%cl
mov    -0x8(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %cl,(%rax)
jmp    1192 <UrlGetProto+0x72>
mov    -0x8(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x20(%rbp),%rcx
mov    -0x18(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
mov    -0x28(%rbp),%rcx
sub    %rcx,%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<UrlGetProto>:
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    %rdx,%r15
mov    %rsi,%r12
mov    %rdi,%r14
xor    %edi,%edi
test   %r14,%r14
setne  %dil
call   1030 <assert@plt>
xor    %edi,%edi
test   %r12,%r12
setne  %dil
call   1030 <assert@plt>
xor    %edi,%edi
test   %r15,%r15
setne  %dil
call   1030 <assert@plt>
xor    %edi,%edi
cmpq   $0x0,(%r15)
setne  %dil
call   1030 <assert@plt>
mov    (%r15),%r13
mov    0x0(%r13),%al
add    $0x1,%r13
test   %al,%al
je     11b7 <UrlGetProto+0x97>
add    $0xffffffffffffffff,%r12
mov    %r14,%rbx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
sub    $0x1,%r12
jb     11ba <UrlGetProto+0x9a>
cmp    $0x3a,%al
je     11ba <UrlGetProto+0x9a>
movsbl %al,%edi
call   1040 <tolower@plt>
mov    %al,(%rbx)
add    $0x1,%rbx
movzbl 0x0(%r13),%eax
add    $0x1,%r13
test   %al,%al
jne    1190 <UrlGetProto+0x70>
jmp    11ba <UrlGetProto+0x9a>
mov    %r14,%rbx
movb   $0x0,(%rbx)
mov    %r13,(%r15)
sub    %r14,%rbx
mov    %rbx,%rax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i64 @UrlGetProto(i8* %0, i64 %1, i8** %2) {
%4 = alloca i8*
%5 = alloca i64
%6 = alloca i8**
%7 = alloca i8*
%8 = alloca i8*
%9 = alloca i8
store i8* %0, i8** %4
store i64 %1, i64* %5
store i8** %2, i8*** %6
%10 = load i8*, i8** %4
%11 = icmp ne i8* %10, null
%12 = zext i1 %11 to i32
%13 = call i32 @assert(i32 %12)
%14 = load i64, i64* %5
%15 = icmp ugt i64 %14, 0
%16 = zext i1 %15 to i32
%17 = call i32 @assert(i32 %16)
%18 = load i8**, i8*** %6
%19 = icmp ne i8** %18, null
%20 = zext i1 %19 to i32
%21 = call i32 @assert(i32 %20)
%22 = load i8**, i8*** %6
%23 = load i8*, i8** %22
%24 = icmp ne i8* %23, null
%25 = zext i1 %24 to i32
%26 = call i32 @assert(i32 %25)
%27 = load i8*, i8** %4
store i8* %27, i8** %8
%28 = load i8**, i8*** %6
%29 = load i8*, i8** %28
store i8* %29, i8** %7
br label %30
30: ; preds = %47, %3
%31 = load i8*, i8** %7
%32 = getelementptr inbounds i8, i8* %31, i32 1
store i8* %32, i8** %7
%33 = load i8, i8* %31
store i8 %33, i8* %9
%34 = sext i8 %33 to i32
%35 = icmp ne i32 %34, 0
br i1 %35, label %36, label %40
36: ; preds = %30
%37 = load i64, i64* %5
%38 = add i64 %37, -1
store i64 %38, i64* %5
%39 = icmp ne i64 %38, 0
br label %40
40: ; preds = %36, %30
%41 = phi i1 [ false, %30 ], [ %39, %36 ]
br i1 %41, label %42, label %53
42: ; preds = %40
%43 = load i8, i8* %9
%44 = sext i8 %43 to i32
%45 = icmp eq i32 %44, 58
br i1 %45, label %46, label %47
46: ; preds = %42
br label %53
47: ; preds = %42
%48 = load i8, i8* %9
%49 = call i32 @tolower(i8 signext %48)
%50 = trunc i32 %49 to i8
%51 = load i8*, i8** %4
%52 = getelementptr inbounds i8, i8* %51, i32 1
store i8* %52, i8** %4
store i8 %50, i8* %51
br label %30
53: ; preds = %46, %40
%54 = load i8*, i8** %4
store i8 0, i8* %54
%55 = load i8*, i8** %7
%56 = load i8**, i8*** %6
store i8* %55, i8** %56
%57 = load i8*, i8** %4
%58 = load i8*, i8** %8
%59 = ptrtoint i8* %57 to i64
%60 = ptrtoint i8* %58 to i64
%61 = sub i64 %59, %60
ret i64 %61
}

LLVM IR (-O2):
define i64 @UrlGetProto(i8* %0, i64 %1, i8** %2) {
%4 = icmp ne i8* %0, null
%5 = zext i1 %4 to i32
%6 = tail call i32 @assert(i32 %5)
%7 = icmp ne i64 %1, 0
%8 = zext i1 %7 to i32
%9 = tail call i32 @assert(i32 %8)
%10 = icmp ne i8** %2, null
%11 = zext i1 %10 to i32
%12 = tail call i32 @assert(i32 %11)
%13 = load i8*, i8** %2
%14 = icmp ne i8* %13, null
%15 = zext i1 %14 to i32
%16 = tail call i32 @assert(i32 %15)
%17 = load i8*, i8** %2
%18 = getelementptr inbounds i8, i8* %17, i64 1
%19 = load i8, i8* %17
%20 = icmp eq i8 %19, 0
br i1 %20, label %37, label %21
21: ; preds = %3, %30
%22 = phi i8 [ %35, %30 ], [ %19, %3 ]
%23 = phi i8* [ %34, %30 ], [ %18, %3 ]
%24 = phi i8* [ %33, %30 ], [ %0, %3 ]
%25 = phi i64 [ %26, %30 ], [ %1, %3 ]
%26 = add i64 %25, -1
%27 = icmp eq i64 %26, 0
%28 = icmp eq i8 %22, 58
%29 = select i1 %27, i1 true, i1 %28
br i1 %29, label %37, label %30
30: ; preds = %21
%31 = tail call i32 @tolower(i8 signext %22)
%32 = trunc i32 %31 to i8
%33 = getelementptr inbounds i8, i8* %24, i64 1
store i8 %32, i8* %24
%34 = getelementptr inbounds i8, i8* %23, i64 1
%35 = load i8, i8* %23
%36 = icmp eq i8 %35, 0
br i1 %36, label %37, label %21
37: ; preds = %21, %30, %3
%38 = phi i8* [ %0, %3 ], [ %33, %30 ], [ %24, %21 ]
%39 = phi i8* [ %18, %3 ], [ %34, %30 ], [ %23, %21 ]
store i8 0, i8* %38
store i8* %39, i8** %2
%40 = ptrtoint i8* %38 to i64
%41 = ptrtoint i8* %0 to i64
%42 = sub i64 %40, %41
ret i64 %42
}