int modifiedUtf8LengthOfUtf8(char *string, int length) {
  int new_length;
  int i;
  new_length = 0;
  for (i = 0; i < length; i++) {
    unsigned byte;
    byte = (unsigned char)string[i];
    if ((byte & 0x80) == 0) {
      new_length++;
      if (byte == 0) {
        new_length++;
      }
    } else if ((byte & 0xE0) == 0xC0) {
      if ((i + 1) >= length || (string[i + 1] & 0xC0) != 0x80) {
        break;
      }
      i++;
      new_length += 2;
    } else if ((byte & 0xF0) == 0xE0) {
      if ((i + 2) >= length || (string[i + 1] & 0xC0) != 0x80 ||
          (string[i + 2] & 0xC0) != 0x80) {
        break;
      }
      i += 2;
      new_length += 3;
    } else if ((byte & 0xF8) == 0xF0) {
      if ((i + 3) >= length || (string[i + 1] & 0xC0) != 0x80 ||
          (string[i + 2] & 0xC0) != 0x80 || (string[i + 3] & 0xC0) != 0x80) {
        break;
      }
      i += 3;
      new_length += 6;
    } else {
      break;
    }
  }
  if (i != length) {
    return length;
  }
  return new_length;
}


x86 assembly (clang, -O0):
<modifiedUtf8LengthOfUtf8>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    130d <modifiedUtf8LengthOfUtf8+0x20d>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    %eax,-0x20(%rbp)
mov    -0x20(%rbp),%eax
and    $0x80,%eax
cmp    $0x0,%eax
jne    1166 <modifiedUtf8LengthOfUtf8+0x66>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
cmpl   $0x0,-0x20(%rbp)
jne    1161 <modifiedUtf8LengthOfUtf8+0x61>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    12fa <modifiedUtf8LengthOfUtf8+0x1fa>
mov    -0x20(%rbp),%eax
and    $0xe0,%eax
cmp    $0xc0,%eax
jne    11c5 <modifiedUtf8LengthOfUtf8+0xc5>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
cmp    -0x14(%rbp),%eax
jge    11a9 <modifiedUtf8LengthOfUtf8+0xa9>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     11ae <modifiedUtf8LengthOfUtf8+0xae>
jmp    130d <modifiedUtf8LengthOfUtf8+0x20d>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x18(%rbp)
jmp    12f5 <modifiedUtf8LengthOfUtf8+0x1f5>
mov    -0x20(%rbp),%eax
and    $0xf0,%eax
cmp    $0xe0,%eax
jne    1245 <modifiedUtf8LengthOfUtf8+0x145>
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
cmp    -0x14(%rbp),%eax
jge    1229 <modifiedUtf8LengthOfUtf8+0x129>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1229 <modifiedUtf8LengthOfUtf8+0x129>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     122e <modifiedUtf8LengthOfUtf8+0x12e>
jmp    130d <modifiedUtf8LengthOfUtf8+0x20d>
mov    -0x1c(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x18(%rbp)
jmp    12f0 <modifiedUtf8LengthOfUtf8+0x1f0>
mov    -0x20(%rbp),%eax
and    $0xf8,%eax
cmp    $0xf0,%eax
jne    12e6 <modifiedUtf8LengthOfUtf8+0x1e6>
mov    -0x1c(%rbp),%eax
add    $0x3,%eax
cmp    -0x14(%rbp),%eax
jge    12ca <modifiedUtf8LengthOfUtf8+0x1ca>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x1,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    12ca <modifiedUtf8LengthOfUtf8+0x1ca>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x2,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    12ca <modifiedUtf8LengthOfUtf8+0x1ca>
mov    -0x10(%rbp),%rax
mov    -0x1c(%rbp),%ecx
add    $0x3,%ecx
movslq %ecx,%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
je     12cf <modifiedUtf8LengthOfUtf8+0x1cf>
jmp    130d <modifiedUtf8LengthOfUtf8+0x20d>
mov    -0x1c(%rbp),%eax
add    $0x3,%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%eax
add    $0x6,%eax
mov    %eax,-0x18(%rbp)
jmp    12eb <modifiedUtf8LengthOfUtf8+0x1eb>
jmp    130d <modifiedUtf8LengthOfUtf8+0x20d>
jmp    12f0 <modifiedUtf8LengthOfUtf8+0x1f0>
jmp    12f5 <modifiedUtf8LengthOfUtf8+0x1f5>
jmp    12fa <modifiedUtf8LengthOfUtf8+0x1fa>
jmp    12ff <modifiedUtf8LengthOfUtf8+0x1ff>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1119 <modifiedUtf8LengthOfUtf8+0x19>
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
je     1324 <modifiedUtf8LengthOfUtf8+0x224>
mov    -0x14(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    132a <modifiedUtf8LengthOfUtf8+0x22a>
mov    -0x18(%rbp),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<modifiedUtf8LengthOfUtf8>:
test   %esi,%esi
jle    11f2 <modifiedUtf8LengthOfUtf8+0xf2>
xor    %r9d,%r9d
xor    %eax,%eax
jmp    1126 <modifiedUtf8LengthOfUtf8+0x26>
nop
cmp    $0x1,%edx
adc    $0x0,%eax
add    $0x1,%eax
add    $0x1,%r9d
cmp    %esi,%r9d
jge    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movslq %r9d,%r10
movzbl (%rdi,%r10,1),%edx
test   $0x80,%dl
je     1110 <modifiedUtf8LengthOfUtf8+0x10>
mov    %edx,%ecx
and    $0xffffffe0,%ecx
cmp    $0xc0,%ecx
jne    1170 <modifiedUtf8LengthOfUtf8+0x70>
add    $0x1,%r10
cmp    %esi,%r10d
jge    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movzbl (%rdi,%r10,1),%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
add    $0x2,%eax
mov    %r10d,%r9d
jmp    1119 <modifiedUtf8LengthOfUtf8+0x19>
cs nopw 0x0(%rax,%rax,1)
mov    %edx,%ecx
and    $0xfffffff0,%ecx
cmp    $0xe0,%ecx
jne    11aa <modifiedUtf8LengthOfUtf8+0xaa>
lea    0x2(%r10),%rcx
cmp    %esi,%ecx
jge    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movzbl 0x1(%r10,%rdi,1),%edx
and    $0xc0,%dl
cmp    $0x80,%dl
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movzbl (%rdi,%rcx,1),%edx
and    $0xc0,%dl
cmp    $0x80,%dl
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
add    $0x3,%eax
mov    %ecx,%r9d
jmp    1119 <modifiedUtf8LengthOfUtf8+0x19>
and    $0xfffffff8,%edx
cmp    $0xf0,%edx
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
lea    0x3(%r10),%r8
cmp    %esi,%r8d
jge    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movzbl 0x1(%r10,%rdi,1),%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movzbl 0x2(%r10,%rdi,1),%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
movzbl (%rdi,%r8,1),%ecx
and    $0xc0,%cl
cmp    $0x80,%cl
jne    11f7 <modifiedUtf8LengthOfUtf8+0xf7>
add    $0x6,%eax
mov    %r8d,%r9d
jmp    1119 <modifiedUtf8LengthOfUtf8+0x19>
xor    %eax,%eax
xor    %r9d,%r9d
cmp    %esi,%r9d
cmovne %esi,%eax
ret

LLVM IR (-O0):
define i32 @modifiedUtf8LengthOfUtf8(i8* %0, i32 %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i32
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i8* %0, i8** %4
store i32 %1, i32* %5
store i32 0, i32* %6
store i32 0, i32* %7
br label %9
9: ; preds = %142, %2
%10 = load i32, i32* %7
%11 = load i32, i32* %5
%12 = icmp slt i32 %10, %11
br i1 %12, label %13, label %145
13: ; preds = %9
%14 = load i8*, i8** %4
%15 = load i32, i32* %7
%16 = sext i32 %15 to i64
%17 = getelementptr inbounds i8, i8* %14, i64 %16
%18 = load i8, i8* %17
%19 = zext i8 %18 to i32
store i32 %19, i32* %8
%20 = load i32, i32* %8
%21 = and i32 %20, 128
%22 = icmp eq i32 %21, 0
br i1 %22, label %23, label %32
23: ; preds = %13
%24 = load i32, i32* %6
%25 = add nsw i32 %24, 1
store i32 %25, i32* %6
%26 = load i32, i32* %8
%27 = icmp eq i32 %26, 0
br i1 %27, label %28, label %31
28: ; preds = %23
%29 = load i32, i32* %6
%30 = add nsw i32 %29, 1
store i32 %30, i32* %6
br label %31
31: ; preds = %28, %23
br label %141
32: ; preds = %13
%33 = load i32, i32* %8
%34 = and i32 %33, 224
%35 = icmp eq i32 %34, 192
br i1 %35, label %36, label %57
36: ; preds = %32
%37 = load i32, i32* %7
%38 = add nsw i32 %37, 1
%39 = load i32, i32* %5
%40 = icmp sge i32 %38, %39
br i1 %40, label %51, label %41
41: ; preds = %36
%42 = load i8*, i8** %4
%43 = load i32, i32* %7
%44 = add nsw i32 %43, 1
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds i8, i8* %42, i64 %45
%47 = load i8, i8* %46
%48 = sext i8 %47 to i32
%49 = and i32 %48, 192
%50 = icmp ne i32 %49, 128
br i1 %50, label %51, label %52
51: ; preds = %41, %36
br label %145
52: ; preds = %41
%53 = load i32, i32* %7
%54 = add nsw i32 %53, 1
store i32 %54, i32* %7
%55 = load i32, i32* %6
%56 = add nsw i32 %55, 2
store i32 %56, i32* %6
br label %140
57: ; preds = %32
%58 = load i32, i32* %8
%59 = and i32 %58, 240
%60 = icmp eq i32 %59, 224
br i1 %60, label %61, label %92
61: ; preds = %57
%62 = load i32, i32* %7
%63 = add nsw i32 %62, 2
%64 = load i32, i32* %5
%65 = icmp sge i32 %63, %64
br i1 %65, label %86, label %66
66: ; preds = %61
%67 = load i8*, i8** %4
%68 = load i32, i32* %7
%69 = add nsw i32 %68, 1
%70 = sext i32 %69 to i64
%71 = getelementptr inbounds i8, i8* %67, i64 %70
%72 = load i8, i8* %71
%73 = sext i8 %72 to i32
%74 = and i32 %73, 192
%75 = icmp ne i32 %74, 128
br i1 %75, label %86, label %76
76: ; preds = %66
%77 = load i8*, i8** %4
%78 = load i32, i32* %7
%79 = add nsw i32 %78, 2
%80 = sext i32 %79 to i64
%81 = getelementptr inbounds i8, i8* %77, i64 %80
%82 = load i8, i8* %81
%83 = sext i8 %82 to i32
%84 = and i32 %83, 192
%85 = icmp ne i32 %84, 128
br i1 %85, label %86, label %87
86: ; preds = %76, %66, %61
br label %145
87: ; preds = %76
%88 = load i32, i32* %7
%89 = add nsw i32 %88, 2
store i32 %89, i32* %7
%90 = load i32, i32* %6
%91 = add nsw i32 %90, 3
store i32 %91, i32* %6
br label %139
92: ; preds = %57
%93 = load i32, i32* %8
%94 = and i32 %93, 248
%95 = icmp eq i32 %94, 240
br i1 %95, label %96, label %137
96: ; preds = %92
%97 = load i32, i32* %7
%98 = add nsw i32 %97, 3
%99 = load i32, i32* %5
%100 = icmp sge i32 %98, %99
br i1 %100, label %131, label %101
101: ; preds = %96
%102 = load i8*, i8** %4
%103 = load i32, i32* %7
%104 = add nsw i32 %103, 1
%105 = sext i32 %104 to i64
%106 = getelementptr inbounds i8, i8* %102, i64 %105
%107 = load i8, i8* %106
%108 = sext i8 %107 to i32
%109 = and i32 %108, 192
%110 = icmp ne i32 %109, 128
br i1 %110, label %131, label %111
111: ; preds = %101
%112 = load i8*, i8** %4
%113 = load i32, i32* %7
%114 = add nsw i32 %113, 2
%115 = sext i32 %114 to i64
%116 = getelementptr inbounds i8, i8* %112, i64 %115
%117 = load i8, i8* %116
%118 = sext i8 %117 to i32
%119 = and i32 %118, 192
%120 = icmp ne i32 %119, 128
br i1 %120, label %131, label %121
121: ; preds = %111
%122 = load i8*, i8** %4
%123 = load i32, i32* %7
%124 = add nsw i32 %123, 3
%125 = sext i32 %124 to i64
%126 = getelementptr inbounds i8, i8* %122, i64 %125
%127 = load i8, i8* %126
%128 = sext i8 %127 to i32
%129 = and i32 %128, 192
%130 = icmp ne i32 %129, 128
br i1 %130, label %131, label %132
131: ; preds = %121, %111, %101, %96
br label %145
132: ; preds = %121
%133 = load i32, i32* %7
%134 = add nsw i32 %133, 3
store i32 %134, i32* %7
%135 = load i32, i32* %6
%136 = add nsw i32 %135, 6
store i32 %136, i32* %6
br label %138
137: ; preds = %92
br label %145
138: ; preds = %132
br label %139
139: ; preds = %138, %87
br label %140
140: ; preds = %139, %52
br label %141
141: ; preds = %140, %31
br label %142
142: ; preds = %141
%143 = load i32, i32* %7
%144 = add nsw i32 %143, 1
store i32 %144, i32* %7
br label %9
145: ; preds = %137, %131, %86, %51, %9
%146 = load i32, i32* %7
%147 = load i32, i32* %5
%148 = icmp ne i32 %146, %147
br i1 %148, label %149, label %151
149: ; preds = %145
%150 = load i32, i32* %5
store i32 %150, i32* %3
br label %153
151: ; preds = %145
%152 = load i32, i32* %6
store i32 %152, i32* %3
br label %153
153: ; preds = %151, %149
%154 = load i32, i32* %3
ret i32 %154
}

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