int upper_strneq(char *s1, char *s2, int n) {
  int i;
  char c1, c2;
  for (i = 1; i < n; i++) {
    c1 = s1[i];
    c2 = s2[i];
    if (c1 >= 'a' && c1 <= 'z') {
      c1 += ('A' - 'a');
    } else if (c1 == '\n') {
      c1 = '\0';
    }
    if (c2 >= 'a' && c2 <= 'z') {
      c2 += ('A' - 'a');
    } else if (c2 == '\n') {
      c2 = '\0';
    }
    if ((c1 - c2) || !c1 || !c2) {
      break;
    }
  }
  return (int)!(c1 - c2);
}


x86 assembly (clang, -O0):
<upper_strneq>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x1,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11fb <upper_strneq+0xfb>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x19(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x1a(%rbp)
movsbl -0x19(%rbp),%eax
cmp    $0x61,%eax
jl     1167 <upper_strneq+0x67>
movsbl -0x19(%rbp),%eax
cmp    $0x7a,%eax
jg     1167 <upper_strneq+0x67>
movsbl -0x19(%rbp),%eax
add    $0xffffffe0,%eax
mov    %al,-0x19(%rbp)
jmp    117d <upper_strneq+0x7d>
movsbl -0x19(%rbp),%eax
cmp    $0xa,%eax
jne    1178 <upper_strneq+0x78>
movb   $0x0,-0x19(%rbp)
jmp    117d <upper_strneq+0x7d>
movsbl -0x1a(%rbp),%eax
cmp    $0x61,%eax
jl     11a6 <upper_strneq+0xa6>
movsbl -0x1a(%rbp),%eax
cmp    $0x7a,%eax
jg     11a6 <upper_strneq+0xa6>
movsbl -0x1a(%rbp),%eax
add    $0xffffffe0,%eax
mov    %al,-0x1a(%rbp)
jmp    11bc <upper_strneq+0xbc>
movsbl -0x1a(%rbp),%eax
cmp    $0xa,%eax
jne    11b7 <upper_strneq+0xb7>
movb   $0x0,-0x1a(%rbp)
jmp    11bc <upper_strneq+0xbc>
movsbl -0x19(%rbp),%eax
movsbl -0x1a(%rbp),%ecx
sub    %ecx,%eax
cmp    $0x0,%eax
jne    11e3 <upper_strneq+0xe3>
cmpb   $0x0,-0x19(%rbp)
je     11e3 <upper_strneq+0xe3>
cmpb   $0x0,-0x1a(%rbp)
jne    11e8 <upper_strneq+0xe8>
jmp    11fb <upper_strneq+0xfb>
jmp    11ed <upper_strneq+0xed>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    1116 <upper_strneq+0x16>
movsbl -0x19(%rbp),%eax
movsbl -0x1a(%rbp),%ecx
sub    %ecx,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
and    $0x1,%al
movzbl %al,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<upper_strneq>:
cmp    $0x2,%edx
jl     1167 <upper_strneq+0x67>
mov    %edx,%r8d
mov    $0x2,%eax
xor    %r10d,%r10d
movzbl -0x1(%rdi,%rax,1),%ecx
movzbl -0x1(%rsi,%rax,1),%edx
lea    -0x61(%rcx),%r9d
lea    -0x20(%rcx),%r11d
cmp    $0xa,%cl
cmove  %r10d,%ecx
cmp    $0x1a,%r9b
movzbl %r11b,%r9d
cmovae %ecx,%r9d
lea    -0x61(%rdx),%r11d
lea    -0x20(%rdx),%ecx
cmp    $0xa,%dl
cmove  %r10d,%edx
cmp    $0x1a,%r11b
movzbl %cl,%ecx
cmovae %edx,%ecx
test   %cl,%cl
je     1167 <upper_strneq+0x67>
test   %r9b,%r9b
je     1167 <upper_strneq+0x67>
cmp    %cl,%r9b
jne    1167 <upper_strneq+0x67>
lea    0x1(%rax),%rdx
cmp    %r8,%rax
mov    %rdx,%rax
jb     1110 <upper_strneq+0x10>
xor    %eax,%eax
cmp    %cl,%r9b
sete   %al
ret

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

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