unsigned int byte_chr(const char *s, unsigned int n, int c) {
  char ch;
  const char *t;
  ch = (char)c;
  t = s;
  for (;;) {
    if (!n)
      break;
    if (*t == ch)
      break;
    ++t;
    --n;
    if (!n)
      break;
    if (*t == ch)
      break;
    ++t;
    --n;
    if (!n)
      break;
    if (*t == ch)
      break;
    ++t;
    --n;
    if (!n)
      break;
    if (*t == ch)
      break;
    ++t;
    --n;
  }
  return t - s;
}


x86 assembly (clang, -O0):
<byte_chr>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %edx,-0x10(%rbp)
mov    -0x10(%rbp),%eax
mov    %al,-0x11(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    112b <byte_chr+0x2b>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
movsbl -0x11(%rbp),%ecx
cmp    %ecx,%eax
jne    1143 <byte_chr+0x43>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    1167 <byte_chr+0x67>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
movsbl -0x11(%rbp),%ecx
cmp    %ecx,%eax
jne    117f <byte_chr+0x7f>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    11a3 <byte_chr+0xa3>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
movsbl -0x11(%rbp),%ecx
cmp    %ecx,%eax
jne    11bb <byte_chr+0xbb>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
cmpl   $0x0,-0xc(%rbp)
jne    11df <byte_chr+0xdf>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
movsbl -0x11(%rbp),%ecx
cmp    %ecx,%eax
jne    11f7 <byte_chr+0xf7>
jmp    1211 <byte_chr+0x111>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
jmp    111c <byte_chr+0x1c>
mov    -0x20(%rbp),%rax
mov    -0x8(%rbp),%rcx
sub    %rcx,%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<byte_chr>:
mov    %rdi,%rax
test   %esi,%esi
je     1163 <byte_chr+0x63>
movsbl %dl,%edx
mov    %esi,%r11d
lea    -0x1(%r11),%r8
lea    -0x2(%r11),%r9
lea    -0x3(%r11),%r10
xor    %ecx,%ecx
mov    %rdi,%rax
movsbl (%rdi,%rcx,1),%esi
cmp    %esi,%edx
je     115d <byte_chr+0x5d>
cmp    %ecx,%r8d
je     1166 <byte_chr+0x66>
movsbl 0x1(%rdi,%rcx,1),%esi
cmp    %esi,%edx
je     1171 <byte_chr+0x71>
cmp    %ecx,%r9d
je     1178 <byte_chr+0x78>
movsbl 0x2(%rdi,%rcx,1),%esi
cmp    %esi,%edx
je     117f <byte_chr+0x7f>
cmp    %ecx,%r10d
je     118a <byte_chr+0x8a>
movsbl 0x3(%rdi,%rcx,1),%esi
cmp    %esi,%edx
je     1195 <byte_chr+0x95>
add    $0x4,%rax
add    $0x4,%rcx
cmp    %ecx,%r11d
jne    111e <byte_chr+0x1e>
add    %rdi,%rcx
mov    %rcx,%rax
sub    %edi,%eax
ret
lea    (%rdi,%rcx,1),%rax
add    $0x1,%rax
sub    %edi,%eax
ret
add    $0x1,%rax
sub    %edi,%eax
ret
add    $0x2,%rax
sub    %edi,%eax
ret
lea    (%rdi,%rcx,1),%rax
add    $0x2,%rax
sub    %edi,%eax
ret
lea    (%rdi,%rcx,1),%rax
add    $0x3,%rax
sub    %edi,%eax
ret
add    $0x3,%rax
sub    %edi,%eax
ret

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

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