#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 */
scalar_t__ isupper(char const);
char const tolower(char const);
int stricmp(const char *s1, const char *s2) {
  register const char *scan1;
  register const char *scan2;
  register char chr1, chr2;
  scan1 = s1;
  scan2 = s2;
  do {
    chr1 = isupper(*scan1) ? tolower(*scan1) : *scan1;
    chr2 = isupper(*scan2) ? tolower(*scan2) : *scan2;
    scan1++;
    scan2++;
  } while (chr1 && chr1 == chr2);
  if (chr1 == '\0' && chr2 == '\0')
    return 0;
  else if (chr1 == '\0')
    return -1;
  else if (chr2 == '\0')
    return 1;
  else
    return chr1 - chr2;
}


x86 assembly (clang, -O0):
<stricmp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x18(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
movsbl (%rax),%edi
call   1040 <isupper@plt>
cmp    $0x0,%rax
je     116d <stricmp+0x4d>
mov    -0x20(%rbp),%rax
movsbl (%rax),%edi
call   1030 <tolower@plt>
movsbl %al,%eax
mov    %eax,-0x30(%rbp)
jmp    1177 <stricmp+0x57>
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x30(%rbp)
mov    -0x30(%rbp),%eax
mov    %al,-0x29(%rbp)
mov    -0x28(%rbp),%rax
movsbl (%rax),%edi
call   1040 <isupper@plt>
cmp    $0x0,%rax
je     11aa <stricmp+0x8a>
mov    -0x28(%rbp),%rax
movsbl (%rax),%edi
call   1030 <tolower@plt>
movsbl %al,%eax
mov    %eax,-0x34(%rbp)
jmp    11b4 <stricmp+0x94>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x34(%rbp)
mov    -0x34(%rbp),%eax
mov    %al,-0x2a(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
movsbl -0x29(%rbp),%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x35(%rbp)
je     11f4 <stricmp+0xd4>
movsbl -0x29(%rbp),%eax
movsbl -0x2a(%rbp),%ecx
cmp    %ecx,%eax
sete   %al
mov    %al,-0x35(%rbp)
mov    -0x35(%rbp),%al
test   $0x1,%al
jne    1140 <stricmp+0x20>
movsbl -0x29(%rbp),%eax
cmp    $0x0,%eax
jne    1225 <stricmp+0x105>
movsbl -0x2a(%rbp),%eax
cmp    $0x0,%eax
jne    1225 <stricmp+0x105>
movl   $0x0,-0x4(%rbp)
jmp    1264 <stricmp+0x144>
movsbl -0x29(%rbp),%eax
cmp    $0x0,%eax
jne    123e <stricmp+0x11e>
movl   $0xffffffff,-0x4(%rbp)
jmp    1264 <stricmp+0x144>
movsbl -0x2a(%rbp),%eax
cmp    $0x0,%eax
jne    1257 <stricmp+0x137>
movl   $0x1,-0x4(%rbp)
jmp    1264 <stricmp+0x144>
movsbl -0x29(%rbp),%eax
movsbl -0x2a(%rbp),%ecx
sub    %ecx,%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<stricmp>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %rsi,%r14
mov    %rdi,%r15
xor    %ebx,%ebx
nop
movsbl (%r15,%rbx,1),%edi
call   1040 <isupper@plt>
movzbl (%r15,%rbx,1),%ebp
test   %rax,%rax
je     114f <stricmp+0x2f>
movsbl %bpl,%edi
call   1030 <tolower@plt>
mov    %eax,%ebp
movsbl (%r14,%rbx,1),%edi
call   1040 <isupper@plt>
mov    %rax,%rcx
movzbl (%r14,%rbx,1),%eax
test   %rcx,%rcx
je     116e <stricmp+0x4e>
movsbl %al,%edi
call   1030 <tolower@plt>
test   %bpl,%bpl
je     117c <stricmp+0x5c>
add    $0x1,%rbx
cmp    %al,%bpl
je     1130 <stricmp+0x10>
movsbl %al,%ecx
movsbl %bpl,%edx
xor    %esi,%esi
mov    %ebp,%ebx
or     %al,%bl
sete   %sil
add    $0xffffffff,%esi
sub    %ecx,%edx
test   %al,%al
mov    $0x1,%eax
cmovne %edx,%eax
test   %bpl,%bpl
cmove  %esi,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define i32 @stricmp(i8* %0, i8* %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i8
%9 = alloca i8
store i8* %0, i8** %4
store i8* %1, i8** %5
%10 = load i8*, i8** %4
store i8* %10, i8** %6
%11 = load i8*, i8** %5
store i8* %11, i8** %7
br label %12
12: ; preds = %59, %2
%13 = load i8*, i8** %6
%14 = load i8, i8* %13
%15 = call i64 @isupper(i8 signext %14)
%16 = icmp ne i64 %15, 0
br i1 %16, label %17, label %22
17: ; preds = %12
%18 = load i8*, i8** %6
%19 = load i8, i8* %18
%20 = call signext i8 @tolower(i8 signext %19)
%21 = sext i8 %20 to i32
br label %26
22: ; preds = %12
%23 = load i8*, i8** %6
%24 = load i8, i8* %23
%25 = sext i8 %24 to i32
br label %26
26: ; preds = %22, %17
%27 = phi i32 [ %21, %17 ], [ %25, %22 ]
%28 = trunc i32 %27 to i8
store i8 %28, i8* %8
%29 = load i8*, i8** %7
%30 = load i8, i8* %29
%31 = call i64 @isupper(i8 signext %30)
%32 = icmp ne i64 %31, 0
br i1 %32, label %33, label %38
33: ; preds = %26
%34 = load i8*, i8** %7
%35 = load i8, i8* %34
%36 = call signext i8 @tolower(i8 signext %35)
%37 = sext i8 %36 to i32
br label %42
38: ; preds = %26
%39 = load i8*, i8** %7
%40 = load i8, i8* %39
%41 = sext i8 %40 to i32
br label %42
42: ; preds = %38, %33
%43 = phi i32 [ %37, %33 ], [ %41, %38 ]
%44 = trunc i32 %43 to i8
store i8 %44, i8* %9
%45 = load i8*, i8** %6
%46 = getelementptr inbounds i8, i8* %45, i32 1
store i8* %46, i8** %6
%47 = load i8*, i8** %7
%48 = getelementptr inbounds i8, i8* %47, i32 1
store i8* %48, i8** %7
br label %49
49: ; preds = %42
%50 = load i8, i8* %8
%51 = sext i8 %50 to i32
%52 = icmp ne i32 %51, 0
br i1 %52, label %53, label %59
53: ; preds = %49
%54 = load i8, i8* %8
%55 = sext i8 %54 to i32
%56 = load i8, i8* %9
%57 = sext i8 %56 to i32
%58 = icmp eq i32 %55, %57
br label %59
59: ; preds = %53, %49
%60 = phi i1 [ false, %49 ], [ %58, %53 ]
br i1 %60, label %12, label %61
61: ; preds = %59
%62 = load i8, i8* %8
%63 = sext i8 %62 to i32
%64 = icmp eq i32 %63, 0
br i1 %64, label %65, label %70
65: ; preds = %61
%66 = load i8, i8* %9
%67 = sext i8 %66 to i32
%68 = icmp eq i32 %67, 0
br i1 %68, label %69, label %70
69: ; preds = %65
store i32 0, i32* %3
br label %86
70: ; preds = %65, %61
%71 = load i8, i8* %8
%72 = sext i8 %71 to i32
%73 = icmp eq i32 %72, 0
br i1 %73, label %74, label %75
74: ; preds = %70
store i32 -1, i32* %3
br label %86
75: ; preds = %70
%76 = load i8, i8* %9
%77 = sext i8 %76 to i32
%78 = icmp eq i32 %77, 0
br i1 %78, label %79, label %80
79: ; preds = %75
store i32 1, i32* %3
br label %86
80: ; preds = %75
%81 = load i8, i8* %8
%82 = sext i8 %81 to i32
%83 = load i8, i8* %9
%84 = sext i8 %83 to i32
%85 = sub nsw i32 %82, %84
store i32 %85, i32* %3
br label %86
86: ; preds = %80, %79, %74, %69
%87 = load i32, i32* %3
ret i32 %87
}

LLVM IR (-O2):
define i32 @stricmp(i8* nocapture %0, i8* nocapture %1) {
br label %3
3: ; preds = %20, %2
%4 = phi i8* [ %1, %2 ], [ %23, %20 ]
%5 = phi i8* [ %0, %2 ], [ %22, %20 ]
%6 = load i8, i8* %5
%7 = tail call i64 @isupper(i8 signext %6)
%8 = icmp eq i64 %7, 0
%9 = load i8, i8* %5
br i1 %8, label %12, label %10
10: ; preds = %3
%11 = tail call signext i8 @tolower(i8 signext %9)
br label %12
12: ; preds = %3, %10
%13 = phi i8 [ %11, %10 ], [ %9, %3 ]
%14 = load i8, i8* %4
%15 = tail call i64 @isupper(i8 signext %14)
%16 = icmp eq i64 %15, 0
%17 = load i8, i8* %4
br i1 %16, label %20, label %18
18: ; preds = %12
%19 = tail call signext i8 @tolower(i8 signext %17)
br label %20
20: ; preds = %12, %18
%21 = phi i8 [ %19, %18 ], [ %17, %12 ]
%22 = getelementptr inbounds i8, i8* %5, i64 1
%23 = getelementptr inbounds i8, i8* %4, i64 1
%24 = icmp ne i8 %13, 0
%25 = icmp eq i8 %13, %21
%26 = select i1 %24, i1 %25, i1 false
br i1 %26, label %3, label %27
27: ; preds = %20
%28 = sext i8 %21 to i32
%29 = sext i8 %13 to i32
%30 = icmp eq i8 %13, 0
%31 = icmp eq i8 %21, 0
%32 = select i1 %30, i1 %31, i1 false
%33 = xor i1 %32, true
%34 = sext i1 %33 to i32
%35 = sub nsw i32 %29, %28
%36 = select i1 %31, i32 1, i32 %35
%37 = select i1 %30, i32 %34, i32 %36
ret i32 %37
}