#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 str_is_utf8(const char *text) {
  size_t i, mb_len, expecting_bytes = 0;
  const unsigned char *utf8;
  unsigned int utf32;
  while ('\0' != *text) {
    if (0 == (*text & 0x80)) {
      text++;
      continue;
    }
    if (0x80 == (*text & 0xc0) || 0xfe == (*text & 0xfe))
      return -1;
    utf8 = (const unsigned char *)text;
    if (0xc0 == (*text & 0xe0))
      expecting_bytes = 1;
    else if (0xe0 == (*text & 0xf0))
      expecting_bytes = 2;
    else if (0xf0 == (*text & 0xf8))
      expecting_bytes = 3;
    else if (0xf8 == (*text & 0xfc))
      expecting_bytes = 4;
    else if (0xfc == (*text & 0xfe))
      expecting_bytes = 5;
    mb_len = expecting_bytes + 1;
    text++;
    for (; 0 != expecting_bytes; expecting_bytes--) {
      if (0x80 != (*text++ & 0xc0))
        return -1;
    }
    if (0xc0 == (utf8[0] & 0xfe) ||
        (0xe0 == utf8[0] && 0x00 == (utf8[1] & 0x20)) ||
        (0xf0 == utf8[0] && 0x00 == (utf8[1] & 0x30)) ||
        (0xf8 == utf8[0] && 0x00 == (utf8[1] & 0x38)) ||
        (0xfc == utf8[0] && 0x00 == (utf8[1] & 0x3c))) {
      return -1;
    }
    utf32 = 0;
    if (0xc0 == (utf8[0] & 0xe0))
      utf32 = utf8[0] & 0x1f;
    else if (0xe0 == (utf8[0] & 0xf0))
      utf32 = utf8[0] & 0x0f;
    else if (0xf0 == (utf8[0] & 0xf8))
      utf32 = utf8[0] & 0x07;
    else if (0xf8 == (utf8[0] & 0xfc))
      utf32 = utf8[0] & 0x03;
    else if (0xfc == (utf8[0] & 0xfe))
      utf32 = utf8[0] & 0x01;
    for (i = 1; i < mb_len; i++) {
      utf32 <<= 6;
      utf32 += utf8[i] & 0x3f;
    }
    if (utf32 > 0x10ffff || 0xd800 == (utf32 & 0xf800))
      return -1;
  }
  return 0;
}


x86 assembly (clang, -O0):
<str_is_utf8>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
xor    %eax,%eax
cmp    %ecx,%eax
je     1503 <str_is_utf8+0x403>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0x80,%ecx
xor    %eax,%eax
cmp    %ecx,%eax
jne    1149 <str_is_utf8+0x49>
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
jmp    1110 <str_is_utf8+0x10>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xc0,%ecx
mov    $0x80,%eax
cmp    %ecx,%eax
je     117d <str_is_utf8+0x7d>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xfe,%ecx
mov    $0xfe,%eax
cmp    %ecx,%eax
jne    1189 <str_is_utf8+0x89>
movl   $0xffffffff,-0x4(%rbp)
jmp    150a <str_is_utf8+0x40a>
mov    -0x10(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xe0,%ecx
mov    $0xc0,%eax
cmp    %ecx,%eax
jne    11b8 <str_is_utf8+0xb8>
movq   $0x1,-0x28(%rbp)
jmp    1263 <str_is_utf8+0x163>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xf0,%ecx
mov    $0xe0,%eax
cmp    %ecx,%eax
jne    11df <str_is_utf8+0xdf>
movq   $0x2,-0x28(%rbp)
jmp    125e <str_is_utf8+0x15e>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xf8,%ecx
mov    $0xf0,%eax
cmp    %ecx,%eax
jne    1206 <str_is_utf8+0x106>
movq   $0x3,-0x28(%rbp)
jmp    1259 <str_is_utf8+0x159>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xfc,%ecx
mov    $0xf8,%eax
cmp    %ecx,%eax
jne    122d <str_is_utf8+0x12d>
movq   $0x4,-0x28(%rbp)
jmp    1254 <str_is_utf8+0x154>
mov    -0x10(%rbp),%rax
movsbl (%rax),%ecx
and    $0xfe,%ecx
mov    $0xfc,%eax
cmp    %ecx,%eax
jne    124f <str_is_utf8+0x14f>
movq   $0x5,-0x28(%rbp)
jmp    1254 <str_is_utf8+0x154>
jmp    1259 <str_is_utf8+0x159>
jmp    125e <str_is_utf8+0x15e>
jmp    1263 <str_is_utf8+0x163>
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
xor    %eax,%eax
cmp    -0x28(%rbp),%rax
je     12ce <str_is_utf8+0x1ce>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
movsbl (%rax),%ecx
and    $0xc0,%ecx
mov    $0x80,%eax
cmp    %ecx,%eax
je     12b8 <str_is_utf8+0x1b8>
movl   $0xffffffff,-0x4(%rbp)
jmp    150a <str_is_utf8+0x40a>
jmp    12bd <str_is_utf8+0x1bd>
mov    -0x28(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x28(%rbp)
jmp    127b <str_is_utf8+0x17b>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
and    $0xfe,%ecx
mov    $0xc0,%eax
cmp    %ecx,%eax
je     138c <str_is_utf8+0x28c>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
mov    $0xe0,%eax
cmp    %ecx,%eax
jne    1311 <str_is_utf8+0x211>
mov    -0x30(%rbp),%rax
movzbl 0x1(%rax),%ecx
and    $0x20,%ecx
xor    %eax,%eax
cmp    %ecx,%eax
je     138c <str_is_utf8+0x28c>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
mov    $0xf0,%eax
cmp    %ecx,%eax
jne    133a <str_is_utf8+0x23a>
mov    -0x30(%rbp),%rax
movzbl 0x1(%rax),%ecx
and    $0x30,%ecx
xor    %eax,%eax
cmp    %ecx,%eax
je     138c <str_is_utf8+0x28c>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
mov    $0xf8,%eax
cmp    %ecx,%eax
jne    1363 <str_is_utf8+0x263>
mov    -0x30(%rbp),%rax
movzbl 0x1(%rax),%ecx
and    $0x38,%ecx
xor    %eax,%eax
cmp    %ecx,%eax
je     138c <str_is_utf8+0x28c>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
mov    $0xfc,%eax
cmp    %ecx,%eax
jne    1398 <str_is_utf8+0x298>
mov    -0x30(%rbp),%rax
movzbl 0x1(%rax),%ecx
and    $0x3c,%ecx
xor    %eax,%eax
cmp    %ecx,%eax
jne    1398 <str_is_utf8+0x298>
movl   $0xffffffff,-0x4(%rbp)
jmp    150a <str_is_utf8+0x40a>
movl   $0x0,-0x34(%rbp)
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
and    $0xe0,%ecx
mov    $0xc0,%eax
cmp    %ecx,%eax
jne    13cb <str_is_utf8+0x2cb>
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
and    $0x1f,%eax
mov    %eax,-0x34(%rbp)
jmp    148a <str_is_utf8+0x38a>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
and    $0xf0,%ecx
mov    $0xe0,%eax
cmp    %ecx,%eax
jne    13f7 <str_is_utf8+0x2f7>
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
and    $0xf,%eax
mov    %eax,-0x34(%rbp)
jmp    1485 <str_is_utf8+0x385>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
and    $0xf8,%ecx
mov    $0xf0,%eax
cmp    %ecx,%eax
jne    1423 <str_is_utf8+0x323>
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
and    $0x7,%eax
mov    %eax,-0x34(%rbp)
jmp    1480 <str_is_utf8+0x380>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
and    $0xfc,%ecx
mov    $0xf8,%eax
cmp    %ecx,%eax
jne    144f <str_is_utf8+0x34f>
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
and    $0x3,%eax
mov    %eax,-0x34(%rbp)
jmp    147b <str_is_utf8+0x37b>
mov    -0x30(%rbp),%rax
movzbl (%rax),%ecx
and    $0xfe,%ecx
mov    $0xfc,%eax
cmp    %ecx,%eax
jne    1476 <str_is_utf8+0x376>
mov    -0x30(%rbp),%rax
movzbl (%rax),%eax
and    $0x1,%eax
mov    %eax,-0x34(%rbp)
jmp    147b <str_is_utf8+0x37b>
jmp    1480 <str_is_utf8+0x380>
jmp    1485 <str_is_utf8+0x385>
jmp    148a <str_is_utf8+0x38a>
movq   $0x1,-0x18(%rbp)
mov    -0x18(%rbp),%rax
cmp    -0x20(%rbp),%rax
jae    14cf <str_is_utf8+0x3cf>
mov    -0x34(%rbp),%eax
shl    $0x6,%eax
mov    %eax,-0x34(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x18(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
and    $0x3f,%eax
add    -0x34(%rbp),%eax
mov    %eax,-0x34(%rbp)
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    1492 <str_is_utf8+0x392>
cmpl   $0x10ffff,-0x34(%rbp)
ja     14f2 <str_is_utf8+0x3f2>
mov    -0x34(%rbp),%ecx
and    $0xf800,%ecx
mov    $0xd800,%eax
cmp    %ecx,%eax
jne    14fe <str_is_utf8+0x3fe>
movl   $0xffffffff,-0x4(%rbp)
jmp    150a <str_is_utf8+0x40a>
jmp    1110 <str_is_utf8+0x10>
movl   $0x0,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<str_is_utf8>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
mov    (%rdi),%cl
test   %cl,%cl
je     13e0 <str_is_utf8+0x2e0>
xor    %r8d,%r8d
lea    0xee2(%rip),%r9
mov    $0xffffffff,%eax
jmp    1145 <str_is_utf8+0x45>
cs nopw 0x0(%rax,%rax,1)
nop
add    $0x1,%rdi
mov    %rdi,%r10
mov    (%r10),%cl
mov    %r10,%rdi
test   %cl,%cl
je     13e0 <str_is_utf8+0x2e0>
test   $0x80,%cl
je     1130 <str_is_utf8+0x30>
movzbl %cl,%ebx
mov    %ebx,%edx
and    $0xffffffc0,%edx
cmp    $0x80,%edx
je     13e2 <str_is_utf8+0x2e2>
mov    %ebx,%edx
and    $0xfffffffe,%edx
cmp    $0xfe,%edx
je     13e2 <str_is_utf8+0x2e2>
mov    %ebx,%r11d
and    $0xffffffe0,%r11d
cmp    $0xc0,%r11d
jne    1190 <str_is_utf8+0x90>
mov    $0x1,%esi
mov    $0x1,%bpl
xor    %r14d,%r14d
xor    %r13d,%r13d
jmp    11ae <str_is_utf8+0xae>
nop
mov    %ebx,%esi
and    $0xfffffff0,%esi
cmp    $0xe0,%esi
jne    1252 <str_is_utf8+0x152>
mov    $0x2,%esi
mov    $0x1,%r13b
xor    %r14d,%r14d
xor    %ebp,%ebp
xor    %r12d,%r12d
mov    0x1(%rdi),%dl
and    $0xc0,%dl
cmp    $0x80,%dl
jne    13e2 <str_is_utf8+0x2e2>
lea    0x1(%rdi),%r15
lea    (%rdi,%rsi,1),%r10
add    $0x1,%r10
test   %bpl,%bpl
jne    1220 <str_is_utf8+0x120>
mov    0x2(%rdi),%dl
and    $0xc0,%dl
cmp    $0x80,%dl
jne    13e2 <str_is_utf8+0x2e2>
test   %r13b,%r13b
jne    1220 <str_is_utf8+0x120>
mov    0x3(%rdi),%dl
and    $0xc0,%dl
cmp    $0x80,%dl
jne    13e2 <str_is_utf8+0x2e2>
test   %r12b,%r12b
jne    1220 <str_is_utf8+0x120>
mov    0x4(%rdi),%dl
and    $0xc0,%dl
cmp    $0x80,%dl
jne    13e2 <str_is_utf8+0x2e2>
test   %r14b,%r14b
jne    1220 <str_is_utf8+0x120>
mov    0x5(%rdi),%dl
and    $0xc0,%dl
cmp    $0x80,%dl
jne    13e2 <str_is_utf8+0x2e2>
nopl   0x0(%rax)
xor    %ebp,%ebp
mov    %ecx,%edx
and    $0xfe,%dl
cmp    $0xc0,%dl
je     13e2 <str_is_utf8+0x2e2>
add    $0x20,%cl
rol    $0x6,%cl
cmp    $0x7,%cl
ja     1278 <str_is_utf8+0x178>
movzbl %cl,%ecx
movslq (%r9,%rcx,4),%rcx
add    %r9,%rcx
jmp    *%rcx
testb  $0x20,(%r15)
jne    129b <str_is_utf8+0x19b>
jmp    13e2 <str_is_utf8+0x2e2>
mov    %ebx,%esi
and    $0xfffffff8,%esi
cmp    $0xf0,%esi
jne    13a1 <str_is_utf8+0x2a1>
mov    $0x3,%esi
mov    $0x1,%r12b
xor    %r14d,%r14d
xor    %ebp,%ebp
xor    %r13d,%r13d
jmp    11b1 <str_is_utf8+0xb1>
cmp    $0xc0,%r11d
jne    129b <str_is_utf8+0x19b>
and    $0x1f,%ebx
jmp    12f3 <str_is_utf8+0x1f3>
testb  $0x30,(%r15)
jne    129b <str_is_utf8+0x19b>
jmp    13e2 <str_is_utf8+0x2e2>
testb  $0x38,(%r15)
je     13e2 <str_is_utf8+0x2e2>
mov    %ebx,%ecx
and    $0xfffffff0,%ecx
cmp    $0xe0,%ecx
jne    12ad <str_is_utf8+0x1ad>
and    $0xf,%ebx
jmp    12f3 <str_is_utf8+0x1f3>
mov    %ebx,%ecx
and    $0xfffffff8,%ecx
cmp    $0xf0,%ecx
jne    12cf <str_is_utf8+0x1cf>
and    $0x7,%ebx
jmp    12f3 <str_is_utf8+0x1f3>
mov    $0xfc,%ebx
testb  $0x3c,(%r15)
jne    12e1 <str_is_utf8+0x1e1>
jmp    13e2 <str_is_utf8+0x2e2>
mov    %ebx,%ecx
and    $0xfffffffc,%ecx
cmp    $0xf8,%ecx
jne    12e1 <str_is_utf8+0x1e1>
and    $0x3,%ebx
jmp    12f3 <str_is_utf8+0x1f3>
mov    %ebx,%ecx
and    $0xfffffffe,%ecx
and    $0x1,%ebx
cmp    $0xfc,%ecx
cmovne %r8d,%ebx
test   %bpl,%bpl
jne    1385 <str_is_utf8+0x285>
lea    -0x1(%rsi),%rdx
mov    %esi,%ecx
and    $0x3,%ecx
mov    $0x1,%ebp
cmp    $0x3,%rdx
jb     1361 <str_is_utf8+0x261>
and    $0xfffffffc,%esi
xor    %ebp,%ebp
cs nopw 0x0(%rax,%rax,1)
nop
movzbl 0x1(%rdi,%rbp,1),%edx
and    $0x3f,%edx
shl    $0xc,%ebx
shl    $0x6,%edx
or     %ebx,%edx
movzbl 0x2(%rdi,%rbp,1),%ebx
and    $0x3f,%ebx
or     %edx,%ebx
movzbl 0x3(%rdi,%rbp,1),%edx
and    $0x3f,%edx
shl    $0xc,%ebx
shl    $0x6,%edx
or     %ebx,%edx
movzbl 0x4(%rdi,%rbp,1),%ebx
and    $0x3f,%ebx
or     %edx,%ebx
add    $0x4,%rbp
cmp    %rbp,%rsi
jne    1320 <str_is_utf8+0x220>
add    $0x1,%rbp
test   %rcx,%rcx
je     1385 <str_is_utf8+0x285>
add    %rbp,%rdi
xor    %edx,%edx
nopl   0x0(%rax,%rax,1)
shl    $0x6,%ebx
movzbl (%rdi,%rdx,1),%esi
and    $0x3f,%esi
or     %esi,%ebx
add    $0x1,%rdx
cmp    %rdx,%rcx
jne    1370 <str_is_utf8+0x270>
cmp    $0x10ffff,%ebx
ja     13e2 <str_is_utf8+0x2e2>
and    $0xf800,%ebx
cmp    $0xd800,%ebx
jne    1137 <str_is_utf8+0x37>
jmp    13e2 <str_is_utf8+0x2e2>
mov    %ebx,%esi
and    $0xfffffffc,%esi
cmp    $0xf8,%esi
jne    13b8 <str_is_utf8+0x2b8>
mov    $0x4,%esi
mov    $0x1,%r14b
jmp    13c8 <str_is_utf8+0x2c8>
cmp    $0xfc,%edx
jne    13cf <str_is_utf8+0x2cf>
mov    $0x5,%esi
xor    %r14d,%r14d
xor    %ebp,%ebp
jmp    118a <str_is_utf8+0x8a>
lea    0x1(%rdi),%r15
mov    $0x1,%bpl
xor    %esi,%esi
mov    %r15,%r10
jmp    1222 <str_is_utf8+0x122>
xor    %eax,%eax
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

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

LLVM IR (-O2):
define i32 @str_is_utf8(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 0
br i1 %3, label %195, label %4
4: ; preds = %1, %12
%5 = phi i8 [ %14, %12 ], [ %2, %1 ]
%6 = phi i8* [ %13, %12 ], [ %0, %1 ]
%7 = zext i8 %5 to i32
%8 = and i32 %7, 128
%9 = icmp eq i32 %8, 0
br i1 %9, label %10, label %16
10: ; preds = %4
%11 = getelementptr inbounds i8, i8* %6, i64 1
br label %12
12: ; preds = %10, %189
%13 = phi i8* [ %11, %10 ], [ %77, %189 ]
%14 = load i8, i8* %13
%15 = icmp eq i8 %14, 0
br i1 %15, label %195, label %4
16: ; preds = %4
%17 = and i32 %7, 192
%18 = icmp eq i32 %17, 128
br i1 %18, label %195, label %19
19: ; preds = %16
%20 = and i32 %7, 254
%21 = icmp eq i32 %20, 254
br i1 %21, label %195, label %22
22: ; preds = %19
%23 = and i32 %7, 224
%24 = icmp eq i32 %23, 192
br i1 %24, label %38, label %25
25: ; preds = %22
%26 = and i32 %7, 240
%27 = icmp eq i32 %26, 224
br i1 %27, label %38, label %28
28: ; preds = %25
%29 = and i32 %7, 248
%30 = icmp eq i32 %29, 240
br i1 %30, label %38, label %31
31: ; preds = %28
%32 = and i32 %7, 252
%33 = icmp eq i32 %32, 248
br i1 %33, label %38, label %34
34: ; preds = %31
%35 = icmp eq i32 %20, 252
br i1 %35, label %38, label %36
36: ; preds = %34
%37 = getelementptr i8, i8* %6, i64 1
br label %73
38: ; preds = %34, %22, %25, %28, %31
%39 = phi i1 [ false, %34 ], [ false, %22 ], [ false, %25 ], [ false, %28 ], [ true, %31 ]
%40 = phi i1 [ false, %34 ], [ true, %22 ], [ false, %25 ], [ false, %28 ], [ false, %31 ]
%41 = phi i1 [ false, %34 ], [ false, %22 ], [ true, %25 ], [ false, %28 ], [ false, %31 ]
%42 = phi i1 [ false, %34 ], [ false, %22 ], [ false, %25 ], [ true, %28 ], [ false, %31 ]
%43 = phi i64 [ 5, %34 ], [ 1, %22 ], [ 2, %25 ], [ 3, %28 ], [ 4, %31 ]
%44 = getelementptr i8, i8* %6, i64 1
%45 = getelementptr i8, i8* %44, i64 %43
%46 = load i8, i8* %44
%47 = and i8 %46, -64
%48 = icmp eq i8 %47, -128
br i1 %48, label %49, label %195
49: ; preds = %38
br i1 %40, label %73, label %50
50: ; preds = %49
%51 = getelementptr i8, i8* %6, i64 2
%52 = load i8, i8* %51
%53 = and i8 %52, -64
%54 = icmp eq i8 %53, -128
br i1 %54, label %55, label %195
55: ; preds = %50
br i1 %41, label %73, label %56
56: ; preds = %55
%57 = getelementptr i8, i8* %6, i64 3
%58 = load i8, i8* %57
%59 = and i8 %58, -64
%60 = icmp eq i8 %59, -128
br i1 %60, label %61, label %195
61: ; preds = %56
br i1 %42, label %73, label %62
62: ; preds = %61
%63 = getelementptr i8, i8* %6, i64 4
%64 = load i8, i8* %63
%65 = and i8 %64, -64
%66 = icmp eq i8 %65, -128
br i1 %66, label %67, label %195
67: ; preds = %62
br i1 %39, label %73, label %68
68: ; preds = %67
%69 = getelementptr i8, i8* %6, i64 5
%70 = load i8, i8* %69
%71 = and i8 %70, -64
%72 = icmp eq i8 %71, -128
br i1 %72, label %73, label %195
73: ; preds = %49, %55, %61, %67, %68, %36
%74 = phi i1 [ true, %36 ], [ false, %68 ], [ false, %67 ], [ false, %61 ], [ false, %55 ], [ false, %49 ]
%75 = phi i8* [ %37, %36 ], [ %44, %68 ], [ %44, %67 ], [ %44, %61 ], [ %44, %55 ], [ %44, %49 ]
%76 = phi i64 [ 0, %36 ], [ %43, %68 ], [ %43, %67 ], [ %43, %61 ], [ %43, %55 ], [ %43, %49 ]
%77 = phi i8* [ %37, %36 ], [ %45, %68 ], [ %45, %67 ], [ %45, %61 ], [ %45, %55 ], [ %45, %49 ]
%78 = and i8 %5, -2
%79 = icmp eq i8 %78, -64
br i1 %79, label %195, label %80
80: ; preds = %73
%81 = add i8 %5, 32
%82 = tail call i8 @llvm.fshl.i8(i8 %81, i8 %81, i8 6)
switch i8 %82, label %101 [
i8 0, label %83
i8 4, label %87
i8 6, label %91
i8 7, label %95
]
83: ; preds = %80
%84 = load i8, i8* %75
%85 = and i8 %84, 32
%86 = icmp eq i8 %85, 0
br i1 %86, label %195, label %99
87: ; preds = %80
%88 = load i8, i8* %75
%89 = and i8 %88, 48
%90 = icmp eq i8 %89, 0
br i1 %90, label %195, label %99
91: ; preds = %80
%92 = load i8, i8* %75
%93 = and i8 %92, 56
%94 = icmp eq i8 %93, 0
br i1 %94, label %195, label %99
95: ; preds = %80
%96 = load i8, i8* %75
%97 = and i8 %96, 60
%98 = icmp eq i8 %97, 0
br i1 %98, label %195, label %123
99: ; preds = %83, %87, %91
%100 = zext i8 %5 to i32
br label %107
101: ; preds = %80
%102 = zext i8 %5 to i32
%103 = and i32 %102, 224
%104 = icmp eq i32 %103, 192
br i1 %104, label %105, label %107
105: ; preds = %101
%106 = and i32 %102, 31
br label %129
107: ; preds = %99, %101
%108 = phi i32 [ %102, %101 ], [ %100, %99 ]
%109 = and i32 %108, 240
%110 = icmp eq i32 %109, 224
br i1 %110, label %111, label %113
111: ; preds = %107
%112 = and i32 %108, 15
br label %129
113: ; preds = %107
%114 = and i32 %108, 248
%115 = icmp eq i32 %114, 240
br i1 %115, label %116, label %118
116: ; preds = %113
%117 = and i32 %108, 7
br label %129
118: ; preds = %113
%119 = and i32 %108, 252
%120 = icmp eq i32 %119, 248
br i1 %120, label %121, label %123
121: ; preds = %118
%122 = and i32 %108, 3
br label %129
123: ; preds = %95, %118
%124 = phi i32 [ %108, %118 ], [ 252, %95 ]
%125 = and i32 %124, 254
%126 = icmp eq i32 %125, 252
%127 = and i32 %124, 1
%128 = select i1 %126, i32 %127, i32 0
br label %129
129: ; preds = %123, %111, %121, %116, %105
%130 = phi i32 [ %106, %105 ], [ %112, %111 ], [ %117, %116 ], [ %122, %121 ], [ %128, %123 ]
br i1 %74, label %189, label %131
131: ; preds = %129
%132 = add nsw i64 %76, -1
%133 = and i64 %76, 3
%134 = icmp ult i64 %132, 3
br i1 %134, label %171, label %135
135: ; preds = %131
%136 = and i64 %76, -4
br label %137
137: ; preds = %137, %135
%138 = phi i32 [ %130, %135 ], [ %167, %137 ]
%139 = phi i64 [ 1, %135 ], [ %168, %137 ]
%140 = phi i64 [ 0, %135 ], [ %169, %137 ]
%141 = getelementptr inbounds i8, i8* %6, i64 %139
%142 = load i8, i8* %141
%143 = and i8 %142, 63
%144 = zext i8 %143 to i32
%145 = add nuw nsw i64 %139, 1
%146 = shl i32 %138, 12
%147 = shl nuw nsw i32 %144, 6
%148 = or i32 %146, %147
%149 = getelementptr inbounds i8, i8* %6, i64 %145
%150 = load i8, i8* %149
%151 = and i8 %150, 63
%152 = zext i8 %151 to i32
%153 = or i32 %148, %152
%154 = add nuw nsw i64 %139, 2
%155 = getelementptr inbounds i8, i8* %6, i64 %154
%156 = load i8, i8* %155
%157 = and i8 %156, 63
%158 = zext i8 %157 to i32
%159 = add nuw nsw i64 %139, 3
%160 = shl i32 %153, 12
%161 = shl nuw nsw i32 %158, 6
%162 = or i32 %160, %161
%163 = getelementptr inbounds i8, i8* %6, i64 %159
%164 = load i8, i8* %163
%165 = and i8 %164, 63
%166 = zext i8 %165 to i32
%167 = or i32 %162, %166
%168 = add nuw nsw i64 %139, 4
%169 = add i64 %140, 4
%170 = icmp eq i64 %169, %136
br i1 %170, label %171, label %137
171: ; preds = %137, %131
%172 = phi i32 [ undef, %131 ], [ %167, %137 ]
%173 = phi i32 [ %130, %131 ], [ %167, %137 ]
%174 = phi i64 [ 1, %131 ], [ %168, %137 ]
%175 = icmp eq i64 %133, 0
br i1 %175, label %189, label %176
176: ; preds = %171, %176
%177 = phi i32 [ %185, %176 ], [ %173, %171 ]
%178 = phi i64 [ %186, %176 ], [ %174, %171 ]
%179 = phi i64 [ %187, %176 ], [ 0, %171 ]
%180 = shl i32 %177, 6
%181 = getelementptr inbounds i8, i8* %6, i64 %178
%182 = load i8, i8* %181
%183 = and i8 %182, 63
%184 = zext i8 %183 to i32
%185 = or i32 %180, %184
%186 = add nuw nsw i64 %178, 1
%187 = add i64 %179, 1
%188 = icmp eq i64 %187, %133
br i1 %188, label %189, label %176
189: ; preds = %171, %176, %129
%190 = phi i32 [ %130, %129 ], [ %172, %171 ], [ %185, %176 ]
%191 = icmp ugt i32 %190, 1114111
%192 = and i32 %190, 63488
%193 = icmp eq i32 %192, 55296
%194 = or i1 %191, %193
br i1 %194, label %195, label %12
195: ; preds = %19, %16, %95, %91, %87, %83, %73, %189, %12, %38, %50, %56, %62, %68, %1
%196 = phi i32 [ 0, %1 ], [ -1, %68 ], [ -1, %62 ], [ -1, %56 ], [ -1, %50 ], [ -1, %38 ], [ -1, %19 ], [ -1, %16 ], [ -1, %95 ], [ -1, %91 ], [ -1, %87 ], [ -1, %83 ], [ -1, %73 ], [ -1, %189 ], [ 0, %12 ]
ret i32 %196
}