#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 utf8_check(const char *s, size_t length) {
  size_t i = 0;
  while (i < length) {
    if (s[i] < 0x80)
      i++;
    else if ((s[i] & 0xe0) == 0xc0) {
      if (i + 1 >= length)
        return 0;
      if ((s[i + 1] & 0xc0) != 0x80 || (s[i] & 0xfe) == 0xc0)
        return 0;
      else
        i += 2;
    } else if ((s[i] & 0xf0) == 0xe0) {
      if (i + 2 >= length)
        return 0;
      if ((s[i + 1] & 0xc0) != 0x80 || (s[i + 2] & 0xc0) != 0x80 ||
          (s[i] == 0xe0 && (s[i + 1] & 0xe0) == 0x80) ||
          (s[i] == 0xed && (s[i + 1] & 0xe0) == 0xa0) ||
          (s[i] == 0xef && s[i + 1] == 0xbf && (s[i + 2] & 0xfe) == 0xbe))
        return 0;
      else
        i += 3;
    } else if ((s[i] & 0xf8) == 0xf0) {
      if (i + 3 >= length)
        return 0;
      if ((s[i + 1] & 0xc0) != 0x80 || (s[i + 2] & 0xc0) != 0x80 ||
          (s[i + 3] & 0xc0) != 0x80 ||
          (s[i] == 0xf0 && (s[i + 1] & 0xf0) == 0x80) ||
          (s[i] == 0xf4 && s[i + 1] > 0x8f) || s[i] > 0xf4)
        return 0;
      else
        i += 4;
    } else
      return 0;
  }
  return 1;
}


x86 assembly (clang, -O0):
<utf8_check>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1467 <utf8_check+0x367>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x80,%eax
jge    114a <utf8_check+0x4a>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1462 <utf8_check+0x362>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xe0,%eax
cmp    $0xc0,%eax
jne    11da <utf8_check+0xda>
mov    -0x20(%rbp),%rax
add    $0x1,%rax
cmp    -0x18(%rbp),%rax
jb     1184 <utf8_check+0x84>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    11bd <utf8_check+0xbd>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xfe,%eax
cmp    $0xc0,%eax
jne    11c9 <utf8_check+0xc9>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
mov    -0x20(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x20(%rbp)
jmp    145d <utf8_check+0x35d>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xf0,%eax
cmp    $0xe0,%eax
jne    131f <utf8_check+0x21f>
mov    -0x20(%rbp),%rax
add    $0x2,%rax
cmp    -0x18(%rbp),%rax
jb     1214 <utf8_check+0x114>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1302 <utf8_check+0x202>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x2(%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    1302 <utf8_check+0x202>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xe0,%eax
jne    1282 <utf8_check+0x182>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xe0,%eax
cmp    $0x80,%eax
je     1302 <utf8_check+0x202>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xed,%eax
jne    12b6 <utf8_check+0x1b6>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xe0,%eax
cmp    $0xa0,%eax
je     1302 <utf8_check+0x202>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xef,%eax
jne    130e <utf8_check+0x20e>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
cmp    $0xbf,%eax
jne    130e <utf8_check+0x20e>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x2(%rax,%rcx,1),%eax
and    $0xfe,%eax
cmp    $0xbe,%eax
jne    130e <utf8_check+0x20e>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
mov    -0x20(%rbp),%rax
add    $0x3,%rax
mov    %rax,-0x20(%rbp)
jmp    1458 <utf8_check+0x358>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
and    $0xf8,%eax
cmp    $0xf0,%eax
jne    1447 <utf8_check+0x347>
mov    -0x20(%rbp),%rax
add    $0x3,%rax
cmp    -0x18(%rbp),%rax
jb     1359 <utf8_check+0x259>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    142a <utf8_check+0x32a>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x2(%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    142a <utf8_check+0x32a>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x3(%rax,%rcx,1),%eax
and    $0xc0,%eax
cmp    $0x80,%eax
jne    142a <utf8_check+0x32a>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xf0,%eax
jne    13e4 <utf8_check+0x2e4>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
and    $0xf0,%eax
cmp    $0x80,%eax
je     142a <utf8_check+0x32a>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xf4,%eax
jne    1413 <utf8_check+0x313>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl 0x1(%rax,%rcx,1),%eax
cmp    $0x8f,%eax
jg     142a <utf8_check+0x32a>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0xf4,%eax
jle    1436 <utf8_check+0x336>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
mov    -0x20(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x20(%rbp)
jmp    1453 <utf8_check+0x353>
movl   $0x0,-0x4(%rbp)
jmp    146e <utf8_check+0x36e>
jmp    1458 <utf8_check+0x358>
jmp    145d <utf8_check+0x35d>
jmp    1462 <utf8_check+0x362>
jmp    1114 <utf8_check+0x14>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<utf8_check>:
mov    $0x1,%eax
ret

LLVM IR (-O0):
define i32 @utf8_check(i8* %0, i64 %1) {
%3 = alloca i32
%4 = alloca i8*
%5 = alloca i64
%6 = alloca i64
store i8* %0, i8** %4
store i64 %1, i64* %5
store i64 0, i64* %6
br label %7
7: ; preds = %238, %2
%8 = load i64, i64* %6
%9 = load i64, i64* %5
%10 = icmp ult i64 %8, %9
br i1 %10, label %11, label %239
11: ; preds = %7
%12 = load i8*, i8** %4
%13 = load i64, i64* %6
%14 = getelementptr inbounds i8, i8* %12, i64 %13
%15 = load i8, i8* %14
%16 = sext i8 %15 to i32
%17 = icmp slt i32 %16, 128
br i1 %17, label %18, label %21
18: ; preds = %11
%19 = load i64, i64* %6
%20 = add i64 %19, 1
store i64 %20, i64* %6
br label %238
21: ; preds = %11
%22 = load i8*, i8** %4
%23 = load i64, i64* %6
%24 = getelementptr inbounds i8, i8* %22, i64 %23
%25 = load i8, i8* %24
%26 = sext i8 %25 to i32
%27 = and i32 %26, 224
%28 = icmp eq i32 %27, 192
br i1 %28, label %29, label %57
29: ; preds = %21
%30 = load i64, i64* %6
%31 = add i64 %30, 1
%32 = load i64, i64* %5
%33 = icmp uge i64 %31, %32
br i1 %33, label %34, label %35
34: ; preds = %29
store i32 0, i32* %3
br label %240
35: ; preds = %29
%36 = load i8*, i8** %4
%37 = load i64, i64* %6
%38 = add i64 %37, 1
%39 = getelementptr inbounds i8, i8* %36, i64 %38
%40 = load i8, i8* %39
%41 = sext i8 %40 to i32
%42 = and i32 %41, 192
%43 = icmp ne i32 %42, 128
br i1 %43, label %52, label %44
44: ; preds = %35
%45 = load i8*, i8** %4
%46 = load i64, i64* %6
%47 = getelementptr inbounds i8, i8* %45, i64 %46
%48 = load i8, i8* %47
%49 = sext i8 %48 to i32
%50 = and i32 %49, 254
%51 = icmp eq i32 %50, 192
br i1 %51, label %52, label %53
52: ; preds = %44, %35
store i32 0, i32* %3
br label %240
53: ; preds = %44
%54 = load i64, i64* %6
%55 = add i64 %54, 2
store i64 %55, i64* %6
br label %56
56: ; preds = %53
br label %237
57: ; preds = %21
%58 = load i8*, i8** %4
%59 = load i64, i64* %6
%60 = getelementptr inbounds i8, i8* %58, i64 %59
%61 = load i8, i8* %60
%62 = sext i8 %61 to i32
%63 = and i32 %62, 240
%64 = icmp eq i32 %63, 224
br i1 %64, label %65, label %150
65: ; preds = %57
%66 = load i64, i64* %6
%67 = add i64 %66, 2
%68 = load i64, i64* %5
%69 = icmp uge i64 %67, %68
br i1 %69, label %70, label %71
70: ; preds = %65
store i32 0, i32* %3
br label %240
71: ; preds = %65
%72 = load i8*, i8** %4
%73 = load i64, i64* %6
%74 = add i64 %73, 1
%75 = getelementptr inbounds i8, i8* %72, i64 %74
%76 = load i8, i8* %75
%77 = sext i8 %76 to i32
%78 = and i32 %77, 192
%79 = icmp ne i32 %78, 128
br i1 %79, label %145, label %80
80: ; preds = %71
%81 = load i8*, i8** %4
%82 = load i64, i64* %6
%83 = add i64 %82, 2
%84 = getelementptr inbounds i8, i8* %81, i64 %83
%85 = load i8, i8* %84
%86 = sext i8 %85 to i32
%87 = and i32 %86, 192
%88 = icmp ne i32 %87, 128
br i1 %88, label %145, label %89
89: ; preds = %80
%90 = load i8*, i8** %4
%91 = load i64, i64* %6
%92 = getelementptr inbounds i8, i8* %90, i64 %91
%93 = load i8, i8* %92
%94 = sext i8 %93 to i32
%95 = icmp eq i32 %94, 224
br i1 %95, label %96, label %105
96: ; preds = %89
%97 = load i8*, i8** %4
%98 = load i64, i64* %6
%99 = add i64 %98, 1
%100 = getelementptr inbounds i8, i8* %97, i64 %99
%101 = load i8, i8* %100
%102 = sext i8 %101 to i32
%103 = and i32 %102, 224
%104 = icmp eq i32 %103, 128
br i1 %104, label %145, label %105
105: ; preds = %96, %89
%106 = load i8*, i8** %4
%107 = load i64, i64* %6
%108 = getelementptr inbounds i8, i8* %106, i64 %107
%109 = load i8, i8* %108
%110 = sext i8 %109 to i32
%111 = icmp eq i32 %110, 237
br i1 %111, label %112, label %121
112: ; preds = %105
%113 = load i8*, i8** %4
%114 = load i64, i64* %6
%115 = add i64 %114, 1
%116 = getelementptr inbounds i8, i8* %113, i64 %115
%117 = load i8, i8* %116
%118 = sext i8 %117 to i32
%119 = and i32 %118, 224
%120 = icmp eq i32 %119, 160
br i1 %120, label %145, label %121
121: ; preds = %112, %105
%122 = load i8*, i8** %4
%123 = load i64, i64* %6
%124 = getelementptr inbounds i8, i8* %122, i64 %123
%125 = load i8, i8* %124
%126 = sext i8 %125 to i32
%127 = icmp eq i32 %126, 239
br i1 %127, label %128, label %146
128: ; preds = %121
%129 = load i8*, i8** %4
%130 = load i64, i64* %6
%131 = add i64 %130, 1
%132 = getelementptr inbounds i8, i8* %129, i64 %131
%133 = load i8, i8* %132
%134 = sext i8 %133 to i32
%135 = icmp eq i32 %134, 191
br i1 %135, label %136, label %146
136: ; preds = %128
%137 = load i8*, i8** %4
%138 = load i64, i64* %6
%139 = add i64 %138, 2
%140 = getelementptr inbounds i8, i8* %137, i64 %139
%141 = load i8, i8* %140
%142 = sext i8 %141 to i32
%143 = and i32 %142, 254
%144 = icmp eq i32 %143, 190
br i1 %144, label %145, label %146
145: ; preds = %136, %112, %96, %80, %71
store i32 0, i32* %3
br label %240
146: ; preds = %136, %128, %121
%147 = load i64, i64* %6
%148 = add i64 %147, 3
store i64 %148, i64* %6
br label %149
149: ; preds = %146
br label %236
150: ; preds = %57
%151 = load i8*, i8** %4
%152 = load i64, i64* %6
%153 = getelementptr inbounds i8, i8* %151, i64 %152
%154 = load i8, i8* %153
%155 = sext i8 %154 to i32
%156 = and i32 %155, 248
%157 = icmp eq i32 %156, 240
br i1 %157, label %158, label %234
158: ; preds = %150
%159 = load i64, i64* %6
%160 = add i64 %159, 3
%161 = load i64, i64* %5
%162 = icmp uge i64 %160, %161
br i1 %162, label %163, label %164
163: ; preds = %158
store i32 0, i32* %3
br label %240
164: ; preds = %158
%165 = load i8*, i8** %4
%166 = load i64, i64* %6
%167 = add i64 %166, 1
%168 = getelementptr inbounds i8, i8* %165, i64 %167
%169 = load i8, i8* %168
%170 = sext i8 %169 to i32
%171 = and i32 %170, 192
%172 = icmp ne i32 %171, 128
br i1 %172, label %229, label %173
173: ; preds = %164
%174 = load i8*, i8** %4
%175 = load i64, i64* %6
%176 = add i64 %175, 2
%177 = getelementptr inbounds i8, i8* %174, i64 %176
%178 = load i8, i8* %177
%179 = sext i8 %178 to i32
%180 = and i32 %179, 192
%181 = icmp ne i32 %180, 128
br i1 %181, label %229, label %182
182: ; preds = %173
%183 = load i8*, i8** %4
%184 = load i64, i64* %6
%185 = add i64 %184, 3
%186 = getelementptr inbounds i8, i8* %183, i64 %185
%187 = load i8, i8* %186
%188 = sext i8 %187 to i32
%189 = and i32 %188, 192
%190 = icmp ne i32 %189, 128
br i1 %190, label %229, label %191
191: ; preds = %182
%192 = load i8*, i8** %4
%193 = load i64, i64* %6
%194 = getelementptr inbounds i8, i8* %192, i64 %193
%195 = load i8, i8* %194
%196 = sext i8 %195 to i32
%197 = icmp eq i32 %196, 240
br i1 %197, label %198, label %207
198: ; preds = %191
%199 = load i8*, i8** %4
%200 = load i64, i64* %6
%201 = add i64 %200, 1
%202 = getelementptr inbounds i8, i8* %199, i64 %201
%203 = load i8, i8* %202
%204 = sext i8 %203 to i32
%205 = and i32 %204, 240
%206 = icmp eq i32 %205, 128
br i1 %206, label %229, label %207
207: ; preds = %198, %191
%208 = load i8*, i8** %4
%209 = load i64, i64* %6
%210 = getelementptr inbounds i8, i8* %208, i64 %209
%211 = load i8, i8* %210
%212 = sext i8 %211 to i32
%213 = icmp eq i32 %212, 244
br i1 %213, label %214, label %222
214: ; preds = %207
%215 = load i8*, i8** %4
%216 = load i64, i64* %6
%217 = add i64 %216, 1
%218 = getelementptr inbounds i8, i8* %215, i64 %217
%219 = load i8, i8* %218
%220 = sext i8 %219 to i32
%221 = icmp sgt i32 %220, 143
br i1 %221, label %229, label %222
222: ; preds = %214, %207
%223 = load i8*, i8** %4
%224 = load i64, i64* %6
%225 = getelementptr inbounds i8, i8* %223, i64 %224
%226 = load i8, i8* %225
%227 = sext i8 %226 to i32
%228 = icmp sgt i32 %227, 244
br i1 %228, label %229, label %230
229: ; preds = %222, %214, %198, %182, %173, %164
store i32 0, i32* %3
br label %240
230: ; preds = %222
%231 = load i64, i64* %6
%232 = add i64 %231, 4
store i64 %232, i64* %6
br label %233
233: ; preds = %230
br label %235
234: ; preds = %150
store i32 0, i32* %3
br label %240
235: ; preds = %233
br label %236
236: ; preds = %235, %149
br label %237
237: ; preds = %236, %56
br label %238
238: ; preds = %237, %18
br label %7
239: ; preds = %7
store i32 1, i32* %3
br label %240
240: ; preds = %239, %234, %229, %163, %145, %70, %52, %34
%241 = load i32, i32* %3
ret i32 %241
}

LLVM IR (-O2):
define i32 @utf8_check(i8* nocapture readnone %0, i64 %1) {
ret i32 1
}