#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 strlen(char *);
int convertUTF(unsigned char *in) {
  unsigned char c, *out = in, *end = in + strlen((char *)in) + 1;
  unsigned int x;
  do {
    if ((c = *in++) < 0x80)
      x = c;
    else {
      if (c < 0xC0)
        return 0;
      else if (c < 0xE0) {
        x = (c & 0x1F) << 6;
        if ((c = *in++) < 0x80 || c > 0xBF)
          return 0;
        else
          x |= (c & 0x3F);
      } else if (c < 0xF0) {
        x = (c & 0xF) << 12;
        if ((c = *in++) < 0x80 || c > 0xBF)
          return 0;
        else
          x |= (c & 0x3F) << 6;
        if ((c = *in++) < 0x80 || c > 0xBF)
          return 0;
        else
          x |= (c & 0x3F);
      } else
        return 0;
    }
    if (x > 127)
      x = '_';
    if (in > end)
      return 0;
  } while ((*out++ = (unsigned char)x));
  return 1;
}


x86 assembly (clang, -O0):
<convertUTF>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %rdi,-0x10(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x10(%rbp),%rdi
call   1030 <strlen@plt>
mov    %eax,%ecx
mov    -0x38(%rbp),%rax
movslq %ecx,%rcx
add    %rcx,%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%al
mov    %al,-0x11(%rbp)
movzbl %al,%eax
cmp    $0x80,%eax
jge    1177 <convertUTF+0x67>
movzbl -0x11(%rbp),%eax
mov    %eax,-0x2c(%rbp)
jmp    12d0 <convertUTF+0x1c0>
movzbl -0x11(%rbp),%eax
cmp    $0xc0,%eax
jge    1192 <convertUTF+0x82>
movl   $0x0,-0x4(%rbp)
jmp    1323 <convertUTF+0x213>
movzbl -0x11(%rbp),%eax
cmp    $0xe0,%eax
jge    11fd <convertUTF+0xed>
movzbl -0x11(%rbp),%eax
and    $0x1f,%eax
shl    $0x6,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%al
mov    %al,-0x11(%rbp)
movzbl %al,%eax
cmp    $0x80,%eax
jl     11df <convertUTF+0xcf>
movzbl -0x11(%rbp),%eax
cmp    $0xbf,%eax
jle    11eb <convertUTF+0xdb>
movl   $0x0,-0x4(%rbp)
jmp    1323 <convertUTF+0x213>
movzbl -0x11(%rbp),%eax
and    $0x3f,%eax
or     -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
jmp    12c6 <convertUTF+0x1b6>
movzbl -0x11(%rbp),%eax
cmp    $0xf0,%eax
jge    12b5 <convertUTF+0x1a5>
movzbl -0x11(%rbp),%eax
and    $0xf,%eax
shl    $0xc,%eax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%al
mov    %al,-0x11(%rbp)
movzbl %al,%eax
cmp    $0x80,%eax
jl     124a <convertUTF+0x13a>
movzbl -0x11(%rbp),%eax
cmp    $0xbf,%eax
jle    1256 <convertUTF+0x146>
movl   $0x0,-0x4(%rbp)
jmp    1323 <convertUTF+0x213>
movzbl -0x11(%rbp),%eax
and    $0x3f,%eax
shl    $0x6,%eax
or     -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%al
mov    %al,-0x11(%rbp)
movzbl %al,%eax
cmp    $0x80,%eax
jl     1297 <convertUTF+0x187>
movzbl -0x11(%rbp),%eax
cmp    $0xbf,%eax
jle    12a3 <convertUTF+0x193>
movl   $0x0,-0x4(%rbp)
jmp    1323 <convertUTF+0x213>
movzbl -0x11(%rbp),%eax
and    $0x3f,%eax
or     -0x2c(%rbp),%eax
mov    %eax,-0x2c(%rbp)
jmp    12c1 <convertUTF+0x1b1>
movl   $0x0,-0x4(%rbp)
jmp    1323 <convertUTF+0x213>
jmp    12c6 <convertUTF+0x1b6>
jmp    12cb <convertUTF+0x1bb>
jmp    12d0 <convertUTF+0x1c0>
cmpl   $0x7f,-0x2c(%rbp)
jbe    12e1 <convertUTF+0x1d1>
movl   $0x5f,-0x2c(%rbp)
mov    -0x10(%rbp),%rax
cmp    -0x28(%rbp),%rax
jbe    12fb <convertUTF+0x1eb>
movl   $0x0,-0x4(%rbp)
jmp    1323 <convertUTF+0x213>
jmp    1300 <convertUTF+0x1f0>
mov    -0x2c(%rbp),%eax
mov    -0x20(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x20(%rbp)
mov    %al,(%rcx)
cmp    $0x0,%al
jne    1149 <convertUTF+0x39>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<convertUTF>:
push   %rbx
mov    %rdi,%rbx
call   1030 <strlen@plt>
cltq
lea    (%rbx,%rax,1),%r9
add    $0x1,%r9
mov    $0x5f,%r8d
mov    %rbx,%rsi
nopl   0x0(%rax)
lea    0x1(%rbx),%rcx
movzbl (%rbx),%edi
test   %dil,%dil
js     1150 <convertUTF+0x40>
mov    %rcx,%rbx
cmp    %r9,%rbx
jbe    11c0 <convertUTF+0xb0>
jmp    11de <convertUTF+0xce>
nopl   0x0(%rax)
xor    %eax,%eax
cmp    $0xc0,%dil
jb     11dc <convertUTF+0xcc>
cmp    $0xdf,%dil
ja     1180 <convertUTF+0x70>
movzbl (%rcx),%ecx
cmp    $0xbf,%cl
jg     11dc <convertUTF+0xcc>
add    $0x2,%rbx
and    $0x1f,%edi
shl    $0x6,%edi
and    $0x3f,%ecx
or     %ecx,%edi
cmp    %r9,%rbx
jbe    11c0 <convertUTF+0xb0>
jmp    11de <convertUTF+0xce>
cmp    $0xef,%dil
ja     11dc <convertUTF+0xcc>
movzbl (%rcx),%edx
cmp    $0xbf,%dl
jg     11dc <convertUTF+0xcc>
movzbl 0x2(%rbx),%ecx
cmp    $0xbf,%cl
jg     11dc <convertUTF+0xcc>
add    $0x3,%rbx
shl    $0xc,%edi
movzwl %di,%eax
and    $0x3f,%edx
shl    $0x6,%edx
or     %eax,%edx
and    $0x3f,%ecx
or     %edx,%ecx
mov    %ecx,%edi
cmp    %r9,%rbx
ja     11de <convertUTF+0xce>
cs nopw 0x0(%rax,%rax,1)
nop
cmp    $0x7f,%edi
cmova  %r8d,%edi
mov    %dil,(%rsi)
add    $0x1,%rsi
test   %dil,%dil
jne    1130 <convertUTF+0x20>
mov    $0x1,%eax
pop    %rbx
ret
xor    %eax,%eax
pop    %rbx
ret

LLVM IR (-O0):
define i32 @convertUTF(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i8
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i32
store i8* %0, i8** %3
%8 = load i8*, i8** %3
store i8* %8, i8** %5
%9 = load i8*, i8** %3
%10 = load i8*, i8** %3
%11 = call i32 @strlen(i8* %10)
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds i8, i8* %9, i64 %12
%14 = getelementptr inbounds i8, i8* %13, i64 1
store i8* %14, i8** %6
br label %15
15: ; preds = %113, %1
%16 = load i8*, i8** %3
%17 = getelementptr inbounds i8, i8* %16, i32 1
store i8* %17, i8** %3
%18 = load i8, i8* %16
store i8 %18, i8* %4
%19 = zext i8 %18 to i32
%20 = icmp slt i32 %19, 128
br i1 %20, label %21, label %24
21: ; preds = %15
%22 = load i8, i8* %4
%23 = zext i8 %22 to i32
store i32 %23, i32* %7
br label %103
24: ; preds = %15
%25 = load i8, i8* %4
%26 = zext i8 %25 to i32
%27 = icmp slt i32 %26, 192
br i1 %27, label %28, label %29
28: ; preds = %24
store i32 0, i32* %2
br label %120
29: ; preds = %24
%30 = load i8, i8* %4
%31 = zext i8 %30 to i32
%32 = icmp slt i32 %31, 224
br i1 %32, label %33, label %55
33: ; preds = %29
%34 = load i8, i8* %4
%35 = zext i8 %34 to i32
%36 = and i32 %35, 31
%37 = shl i32 %36, 6
store i32 %37, i32* %7
%38 = load i8*, i8** %3
%39 = getelementptr inbounds i8, i8* %38, i32 1
store i8* %39, i8** %3
%40 = load i8, i8* %38
store i8 %40, i8* %4
%41 = zext i8 %40 to i32
%42 = icmp slt i32 %41, 128
br i1 %42, label %47, label %43
43: ; preds = %33
%44 = load i8, i8* %4
%45 = zext i8 %44 to i32
%46 = icmp sgt i32 %45, 191
br i1 %46, label %47, label %48
47: ; preds = %43, %33
store i32 0, i32* %2
br label %120
48: ; preds = %43
%49 = load i8, i8* %4
%50 = zext i8 %49 to i32
%51 = and i32 %50, 63
%52 = load i32, i32* %7
%53 = or i32 %52, %51
store i32 %53, i32* %7
br label %54
54: ; preds = %48
br label %101
55: ; preds = %29
%56 = load i8, i8* %4
%57 = zext i8 %56 to i32
%58 = icmp slt i32 %57, 240
br i1 %58, label %59, label %99
59: ; preds = %55
%60 = load i8, i8* %4
%61 = zext i8 %60 to i32
%62 = and i32 %61, 15
%63 = shl i32 %62, 12
store i32 %63, i32* %7
%64 = load i8*, i8** %3
%65 = getelementptr inbounds i8, i8* %64, i32 1
store i8* %65, i8** %3
%66 = load i8, i8* %64
store i8 %66, i8* %4
%67 = zext i8 %66 to i32
%68 = icmp slt i32 %67, 128
br i1 %68, label %73, label %69
69: ; preds = %59
%70 = load i8, i8* %4
%71 = zext i8 %70 to i32
%72 = icmp sgt i32 %71, 191
br i1 %72, label %73, label %74
73: ; preds = %69, %59
store i32 0, i32* %2
br label %120
74: ; preds = %69
%75 = load i8, i8* %4
%76 = zext i8 %75 to i32
%77 = and i32 %76, 63
%78 = shl i32 %77, 6
%79 = load i32, i32* %7
%80 = or i32 %79, %78
store i32 %80, i32* %7
br label %81
81: ; preds = %74
%82 = load i8*, i8** %3
%83 = getelementptr inbounds i8, i8* %82, i32 1
store i8* %83, i8** %3
%84 = load i8, i8* %82
store i8 %84, i8* %4
%85 = zext i8 %84 to i32
%86 = icmp slt i32 %85, 128
br i1 %86, label %91, label %87
87: ; preds = %81
%88 = load i8, i8* %4
%89 = zext i8 %88 to i32
%90 = icmp sgt i32 %89, 191
br i1 %90, label %91, label %92
91: ; preds = %87, %81
store i32 0, i32* %2
br label %120
92: ; preds = %87
%93 = load i8, i8* %4
%94 = zext i8 %93 to i32
%95 = and i32 %94, 63
%96 = load i32, i32* %7
%97 = or i32 %96, %95
store i32 %97, i32* %7
br label %98
98: ; preds = %92
br label %100
99: ; preds = %55
store i32 0, i32* %2
br label %120
100: ; preds = %98
br label %101
101: ; preds = %100, %54
br label %102
102: ; preds = %101
br label %103
103: ; preds = %102, %21
%104 = load i32, i32* %7
%105 = icmp ugt i32 %104, 127
br i1 %105, label %106, label %107
106: ; preds = %103
store i32 95, i32* %7
br label %107
107: ; preds = %106, %103
%108 = load i8*, i8** %3
%109 = load i8*, i8** %6
%110 = icmp ugt i8* %108, %109
br i1 %110, label %111, label %112
111: ; preds = %107
store i32 0, i32* %2
br label %120
112: ; preds = %107
br label %113
113: ; preds = %112
%114 = load i32, i32* %7
%115 = trunc i32 %114 to i8
%116 = load i8*, i8** %5
%117 = getelementptr inbounds i8, i8* %116, i32 1
store i8* %117, i8** %5
store i8 %115, i8* %116
%118 = icmp ne i8 %115, 0
br i1 %118, label %15, label %119
119: ; preds = %113
store i32 1, i32* %2
br label %120
120: ; preds = %119, %111, %99, %91, %73, %47, %28
%121 = load i32, i32* %2
ret i32 %121
}

LLVM IR (-O2):
define i32 @convertUTF(i8* %0) {
%2 = tail call i32 @strlen(i8* %0)
%3 = sext i32 %2 to i64
%4 = getelementptr inbounds i8, i8* %0, i64 %3
%5 = getelementptr inbounds i8, i8* %4, i64 1
br label %6
6: ; preds = %51, %1
%7 = phi i8* [ %0, %1 ], [ %48, %51 ]
%8 = phi i8* [ %0, %1 ], [ %55, %51 ]
%9 = getelementptr inbounds i8, i8* %7, i64 1
%10 = load i8, i8* %7
%11 = zext i8 %10 to i32
%12 = icmp sgt i8 %10, -1
br i1 %12, label %47, label %13
13: ; preds = %6
%14 = icmp ult i8 %10, -64
br i1 %14, label %57, label %15
15: ; preds = %13
%16 = icmp ult i8 %10, -32
br i1 %16, label %17, label %27
17: ; preds = %15
%18 = load i8, i8* %9
%19 = icmp sgt i8 %18, -65
br i1 %19, label %57, label %20
20: ; preds = %17
%21 = getelementptr inbounds i8, i8* %7, i64 2
%22 = shl nuw nsw i32 %11, 6
%23 = and i32 %22, 1984
%24 = and i8 %18, 63
%25 = zext i8 %24 to i32
%26 = or i32 %23, %25
br label %47
27: ; preds = %15
%28 = icmp ult i8 %10, -16
br i1 %28, label %29, label %57
29: ; preds = %27
%30 = load i8, i8* %9
%31 = icmp sgt i8 %30, -65
br i1 %31, label %57, label %32
32: ; preds = %29
%33 = getelementptr inbounds i8, i8* %7, i64 2
%34 = load i8, i8* %33
%35 = icmp sgt i8 %34, -65
br i1 %35, label %57, label %36
36: ; preds = %32
%37 = getelementptr inbounds i8, i8* %7, i64 3
%38 = shl nuw nsw i32 %11, 12
%39 = and i32 %38, 61440
%40 = and i8 %30, 63
%41 = zext i8 %40 to i32
%42 = shl nuw nsw i32 %41, 6
%43 = or i32 %42, %39
%44 = and i8 %34, 63
%45 = zext i8 %44 to i32
%46 = or i32 %43, %45
br label %47
47: ; preds = %6, %36, %20
%48 = phi i8* [ %21, %20 ], [ %37, %36 ], [ %9, %6 ]
%49 = phi i32 [ %26, %20 ], [ %46, %36 ], [ %11, %6 ]
%50 = icmp ugt i8* %48, %5
br i1 %50, label %57, label %51
51: ; preds = %47
%52 = icmp ugt i32 %49, 127
%53 = trunc i32 %49 to i8
%54 = select i1 %52, i8 95, i8 %53
%55 = getelementptr inbounds i8, i8* %8, i64 1
store i8 %54, i8* %8
%56 = icmp eq i8 %54, 0
br i1 %56, label %57, label %6
57: ; preds = %51, %47, %27, %32, %29, %17, %13
%58 = phi i32 [ 0, %13 ], [ 0, %17 ], [ 0, %29 ], [ 0, %32 ], [ 0, %27 ], [ 0, %47 ], [ 1, %51 ]
ret i32 %58
}