int needs_encoding(char ch, char next) {
  if ((ch >= (unsigned int)0xD800 && ch <= (unsigned int)0xDBFF)) {
    if (!(next >= (unsigned int)0xDC00 && next <= (unsigned int)0xDFFF)) {
      return -1;
    }
  }
  if ((ch >= (unsigned int)0x0041 && ch <= (unsigned int)0x005A) ||
      (ch >= (unsigned int)0x061 && ch <= (unsigned int)0x007A)) {
    return 0;
  }
  if ((ch >= (unsigned int)0x0030 && ch <= (unsigned int)0x0039)) {
    return 0;
  }
  if ('-' == ch || '_' == ch || '.' == ch || '!' == ch || '~' == ch ||
      '*' == ch || '(' == ch || ')' == ch) {
    return 0;
  }
  return 1;
}


x86 assembly (clang, -O0):
<needs_encoding>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %dil,%cl
mov    %cl,-0x5(%rbp)
mov    %al,-0x6(%rbp)
movsbl -0x5(%rbp),%eax
cmp    $0xd800,%eax
jb     115d <needs_encoding+0x5d>
movsbl -0x5(%rbp),%eax
cmp    $0xdbff,%eax
ja     115d <needs_encoding+0x5d>
movsbl -0x6(%rbp),%eax
cmp    $0xdc00,%eax
jb     114c <needs_encoding+0x4c>
movsbl -0x6(%rbp),%eax
cmp    $0xdfff,%eax
jbe    1158 <needs_encoding+0x58>
movl   $0xffffffff,-0x4(%rbp)
jmp    125e <needs_encoding+0x15e>
jmp    115d <needs_encoding+0x5d>
movsbl -0x5(%rbp),%eax
cmp    $0x41,%eax
jb     1177 <needs_encoding+0x77>
movsbl -0x5(%rbp),%eax
cmp    $0x5a,%eax
jbe    1191 <needs_encoding+0x91>
movsbl -0x5(%rbp),%eax
cmp    $0x61,%eax
jb     119d <needs_encoding+0x9d>
movsbl -0x5(%rbp),%eax
cmp    $0x7a,%eax
ja     119d <needs_encoding+0x9d>
movl   $0x0,-0x4(%rbp)
jmp    125e <needs_encoding+0x15e>
movsbl -0x5(%rbp),%eax
cmp    $0x30,%eax
jb     11c3 <needs_encoding+0xc3>
movsbl -0x5(%rbp),%eax
cmp    $0x39,%eax
ja     11c3 <needs_encoding+0xc3>
movl   $0x0,-0x4(%rbp)
jmp    125e <needs_encoding+0x15e>
movsbl -0x5(%rbp),%ecx
mov    $0x2d,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x5f,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x2e,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x21,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x7e,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x2a,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x28,%eax
cmp    %ecx,%eax
je     124b <needs_encoding+0x14b>
movsbl -0x5(%rbp),%ecx
mov    $0x29,%eax
cmp    %ecx,%eax
jne    1257 <needs_encoding+0x157>
movl   $0x0,-0x4(%rbp)
jmp    125e <needs_encoding+0x15e>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<needs_encoding>:
lea    -0x30(%rdi),%ecx
xor    %eax,%eax
cmp    $0xa,%cl
jb     1132 <needs_encoding+0x32>
mov    %edi,%ecx
and    $0xdf,%cl
add    $0xbf,%cl
cmp    $0x1a,%cl
jb     1132 <needs_encoding+0x32>
lea    -0x21(%rdi),%ecx
cmp    $0x3e,%cl
ja     1133 <needs_encoding+0x33>
movzbl %cl,%ecx
movabs $0x4000000000003381,%rdx
bt     %rcx,%rdx
jae    1133 <needs_encoding+0x33>
ret
cmp    $0x7e,%dil
je     1132 <needs_encoding+0x32>
mov    $0x1,%eax
ret

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

LLVM IR (-O2):
define i32 @needs_encoding(i8 signext %0, i8 signext %1) {
%3 = and i8 %0, -33
%4 = add i8 %3, -65
%5 = icmp ult i8 %4, 26
%6 = add i8 %0, -48
%7 = icmp ult i8 %6, 10
%8 = or i1 %7, %5
br i1 %8, label %11, label %9
9: ; preds = %2
switch i8 %0, label %10 [
i8 126, label %11
i8 95, label %11
i8 46, label %11
i8 45, label %11
i8 42, label %11
i8 41, label %11
i8 40, label %11
i8 33, label %11
]
10: ; preds = %9
br label %11
11: ; preds = %9, %9, %9, %9, %9, %9, %9, %9, %2, %10
%12 = phi i32 [ 1, %10 ], [ 0, %2 ], [ 0, %9 ], [ 0, %9 ], [ 0, %9 ], [ 0, %9 ], [ 0, %9 ], [ 0, %9 ], [ 0, %9 ], [ 0, %9 ]
ret i32 %12
}