int cstrmatch_char(char buf, char pattern) {
  switch (pattern) {
  case 'A':
    if (buf >= 'A' && buf <= 'Z')
      break;
    return 0;
  case 'a':
    if ((buf >= 'A' && buf <= 'Z') || (buf >= 'a' && buf <= 'z'))
      break;
    return 0;
  case 'd':
    if (buf >= '0' && buf <= '9')
      break;
    return 0;
  case '?':
    break;
  case ' ':
    if (buf == ' ' || buf == '\t')
      break;
    return 0;
  case '\n':
    if (buf == '\n' || buf == '\r')
      break;
    return 0;
  case '$':
    if (buf == ' ' || buf == '\t' || buf == '\r' || buf == '\n' ||
        (buf >= 'A' && buf <= 'Z') || (buf >= 'a' && buf <= 'z') ||
        (buf >= '0' && buf <= '9'))
      return 0;
    break;
  default:
    if (buf == pattern)
      break;
    return 0;
  }
  return 1;
}


x86 assembly (clang, -O0):
<cstrmatch_char>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %dil,%cl
mov    %cl,-0x5(%rbp)
mov    %al,-0x6(%rbp)
movsbl -0x6(%rbp),%eax
mov    %eax,-0xc(%rbp)
sub    $0xa,%eax
je     1256 <cstrmatch_char+0x156>
jmp    1125 <cstrmatch_char+0x25>
mov    -0xc(%rbp),%eax
sub    $0x20,%eax
je     122b <cstrmatch_char+0x12b>
jmp    1136 <cstrmatch_char+0x36>
mov    -0xc(%rbp),%eax
sub    $0x24,%eax
je     1281 <cstrmatch_char+0x181>
jmp    1147 <cstrmatch_char+0x47>
mov    -0xc(%rbp),%eax
sub    $0x3f,%eax
je     1226 <cstrmatch_char+0x126>
jmp    1158 <cstrmatch_char+0x58>
mov    -0xc(%rbp),%eax
sub    $0x41,%eax
je     118b <cstrmatch_char+0x8b>
jmp    1169 <cstrmatch_char+0x69>
mov    -0xc(%rbp),%eax
sub    $0x61,%eax
je     11b6 <cstrmatch_char+0xb6>
jmp    117a <cstrmatch_char+0x7a>
mov    -0xc(%rbp),%eax
sub    $0x64,%eax
je     11fb <cstrmatch_char+0xfb>
jmp    1314 <cstrmatch_char+0x214>
movsbl -0x5(%rbp),%eax
cmp    $0x41,%eax
jl     11aa <cstrmatch_char+0xaa>
movsbl -0x5(%rbp),%eax
cmp    $0x5a,%eax
jg     11aa <cstrmatch_char+0xaa>
jmp    1335 <cstrmatch_char+0x235>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
movsbl -0x5(%rbp),%eax
cmp    $0x41,%eax
jl     11d0 <cstrmatch_char+0xd0>
movsbl -0x5(%rbp),%eax
cmp    $0x5a,%eax
jle    11ea <cstrmatch_char+0xea>
movsbl -0x5(%rbp),%eax
cmp    $0x61,%eax
jl     11ef <cstrmatch_char+0xef>
movsbl -0x5(%rbp),%eax
cmp    $0x7a,%eax
jg     11ef <cstrmatch_char+0xef>
jmp    1335 <cstrmatch_char+0x235>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
movsbl -0x5(%rbp),%eax
cmp    $0x30,%eax
jl     121a <cstrmatch_char+0x11a>
movsbl -0x5(%rbp),%eax
cmp    $0x39,%eax
jg     121a <cstrmatch_char+0x11a>
jmp    1335 <cstrmatch_char+0x235>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
jmp    1335 <cstrmatch_char+0x235>
movsbl -0x5(%rbp),%eax
cmp    $0x20,%eax
je     1245 <cstrmatch_char+0x145>
movsbl -0x5(%rbp),%eax
cmp    $0x9,%eax
jne    124a <cstrmatch_char+0x14a>
jmp    1335 <cstrmatch_char+0x235>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
movsbl -0x5(%rbp),%eax
cmp    $0xa,%eax
je     1270 <cstrmatch_char+0x170>
movsbl -0x5(%rbp),%eax
cmp    $0xd,%eax
jne    1275 <cstrmatch_char+0x175>
jmp    1335 <cstrmatch_char+0x235>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
movsbl -0x5(%rbp),%eax
cmp    $0x20,%eax
je     1303 <cstrmatch_char+0x203>
movsbl -0x5(%rbp),%eax
cmp    $0x9,%eax
je     1303 <cstrmatch_char+0x203>
movsbl -0x5(%rbp),%eax
cmp    $0xd,%eax
je     1303 <cstrmatch_char+0x203>
movsbl -0x5(%rbp),%eax
cmp    $0xa,%eax
je     1303 <cstrmatch_char+0x203>
movsbl -0x5(%rbp),%eax
cmp    $0x41,%eax
jl     12cf <cstrmatch_char+0x1cf>
movsbl -0x5(%rbp),%eax
cmp    $0x5a,%eax
jle    1303 <cstrmatch_char+0x203>
movsbl -0x5(%rbp),%eax
cmp    $0x61,%eax
jl     12e9 <cstrmatch_char+0x1e9>
movsbl -0x5(%rbp),%eax
cmp    $0x7a,%eax
jle    1303 <cstrmatch_char+0x203>
movsbl -0x5(%rbp),%eax
cmp    $0x30,%eax
jl     130f <cstrmatch_char+0x20f>
movsbl -0x5(%rbp),%eax
cmp    $0x39,%eax
jg     130f <cstrmatch_char+0x20f>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
jmp    1335 <cstrmatch_char+0x235>
movsbl -0x5(%rbp),%eax
movsbl -0x6(%rbp),%ecx
cmp    %ecx,%eax
jne    1329 <cstrmatch_char+0x229>
jmp    1335 <cstrmatch_char+0x235>
movl   $0x0,-0x4(%rbp)
jmp    133c <cstrmatch_char+0x23c>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<cstrmatch_char>:
cmp    $0x3e,%esi
jle    1131 <cstrmatch_char+0x31>
lea    -0x3f(%rsi),%eax
cmp    $0x25,%eax
ja     11a1 <cstrmatch_char+0xa1>
lea    0xee8(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
and    $0xdf,%dil
add    $0xbf,%dil
cmp    $0x1a,%dil
jb     117a <cstrmatch_char+0x7a>
jmp    11a6 <cstrmatch_char+0xa6>
cmp    $0xa,%esi
je     1180 <cstrmatch_char+0x80>
cmp    $0x20,%esi
je     118d <cstrmatch_char+0x8d>
cmp    $0x24,%esi
jne    11a1 <cstrmatch_char+0xa1>
lea    -0x9(%rdi),%eax
cmp    $0x18,%al
jae    1154 <cstrmatch_char+0x54>
movzbl %al,%eax
mov    $0x800013,%ecx
bt     %eax,%ecx
jb     11a6 <cstrmatch_char+0xa6>
lea    -0x30(%rdi),%ecx
xor    %eax,%eax
cmp    $0xa,%cl
jb     116c <cstrmatch_char+0x6c>
and    $0xdf,%dil
add    $0xbf,%dil
cmp    $0x1a,%dil
jae    117a <cstrmatch_char+0x7a>
movzbl %al,%eax
ret
add    $0xd0,%dil
cmp    $0xa,%dil
jae    11a6 <cstrmatch_char+0xa6>
mov    $0x1,%al
movzbl %al,%eax
ret
cmp    $0xd,%dil
sete   %cl
cmp    $0xa,%dil
jmp    1198 <cstrmatch_char+0x98>
cmp    $0x20,%dil
sete   %cl
cmp    $0x9,%dil
sete   %al
or     %cl,%al
movzbl %al,%eax
ret
cmp    %sil,%dil
je     117a <cstrmatch_char+0x7a>
xor    %eax,%eax
movzbl %al,%eax
ret

LLVM IR (-O0):
define i32 @cstrmatch_char(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* %5
%7 = sext i8 %6 to i32
switch i32 %7, label %109 [
i32 65, label %8
i32 97, label %18
i32 100, label %36
i32 63, label %46
i32 32, label %47
i32 10, label %57
i32 36, label %67
]
8: ; preds = %2
%9 = load i8, i8* %4
%10 = sext i8 %9 to i32
%11 = icmp sge i32 %10, 65
br i1 %11, label %12, label %17
12: ; preds = %8
%13 = load i8, i8* %4
%14 = sext i8 %13 to i32
%15 = icmp sle i32 %14, 90
br i1 %15, label %16, label %17
16: ; preds = %12
br label %117
17: ; preds = %12, %8
store i32 0, i32* %3
br label %118
18: ; preds = %2
%19 = load i8, i8* %4
%20 = sext i8 %19 to i32
%21 = icmp sge i32 %20, 65
br i1 %21, label %22, label %26
22: ; preds = %18
%23 = load i8, i8* %4
%24 = sext i8 %23 to i32
%25 = icmp sle i32 %24, 90
br i1 %25, label %34, label %26
26: ; preds = %22, %18
%27 = load i8, i8* %4
%28 = sext i8 %27 to i32
%29 = icmp sge i32 %28, 97
br i1 %29, label %30, label %35
30: ; preds = %26
%31 = load i8, i8* %4
%32 = sext i8 %31 to i32
%33 = icmp sle i32 %32, 122
br i1 %33, label %34, label %35
34: ; preds = %30, %22
br label %117
35: ; preds = %30, %26
store i32 0, i32* %3
br label %118
36: ; preds = %2
%37 = load i8, i8* %4
%38 = sext i8 %37 to i32
%39 = icmp sge i32 %38, 48
br i1 %39, label %40, label %45
40: ; preds = %36
%41 = load i8, i8* %4
%42 = sext i8 %41 to i32
%43 = icmp sle i32 %42, 57
br i1 %43, label %44, label %45
44: ; preds = %40
br label %117
45: ; preds = %40, %36
store i32 0, i32* %3
br label %118
46: ; preds = %2
br label %117
47: ; preds = %2
%48 = load i8, i8* %4
%49 = sext i8 %48 to i32
%50 = icmp eq i32 %49, 32
br i1 %50, label %55, label %51
51: ; preds = %47
%52 = load i8, i8* %4
%53 = sext i8 %52 to i32
%54 = icmp eq i32 %53, 9
br i1 %54, label %55, label %56
55: ; preds = %51, %47
br label %117
56: ; preds = %51
store i32 0, i32* %3
br label %118
57: ; preds = %2
%58 = load i8, i8* %4
%59 = sext i8 %58 to i32
%60 = icmp eq i32 %59, 10
br i1 %60, label %65, label %61
61: ; preds = %57
%62 = load i8, i8* %4
%63 = sext i8 %62 to i32
%64 = icmp eq i32 %63, 13
br i1 %64, label %65, label %66
65: ; preds = %61, %57
br label %117
66: ; preds = %61
store i32 0, i32* %3
br label %118
67: ; preds = %2
%68 = load i8, i8* %4
%69 = sext i8 %68 to i32
%70 = icmp eq i32 %69, 32
br i1 %70, label %107, label %71
71: ; preds = %67
%72 = load i8, i8* %4
%73 = sext i8 %72 to i32
%74 = icmp eq i32 %73, 9
br i1 %74, label %107, label %75
75: ; preds = %71
%76 = load i8, i8* %4
%77 = sext i8 %76 to i32
%78 = icmp eq i32 %77, 13
br i1 %78, label %107, label %79
79: ; preds = %75
%80 = load i8, i8* %4
%81 = sext i8 %80 to i32
%82 = icmp eq i32 %81, 10
br i1 %82, label %107, label %83
83: ; preds = %79
%84 = load i8, i8* %4
%85 = sext i8 %84 to i32
%86 = icmp sge i32 %85, 65
br i1 %86, label %87, label %91
87: ; preds = %83
%88 = load i8, i8* %4
%89 = sext i8 %88 to i32
%90 = icmp sle i32 %89, 90
br i1 %90, label %107, label %91
91: ; preds = %87, %83
%92 = load i8, i8* %4
%93 = sext i8 %92 to i32
%94 = icmp sge i32 %93, 97
br i1 %94, label %95, label %99
95: ; preds = %91
%96 = load i8, i8* %4
%97 = sext i8 %96 to i32
%98 = icmp sle i32 %97, 122
br i1 %98, label %107, label %99
99: ; preds = %95, %91
%100 = load i8, i8* %4
%101 = sext i8 %100 to i32
%102 = icmp sge i32 %101, 48
br i1 %102, label %103, label %108
103: ; preds = %99
%104 = load i8, i8* %4
%105 = sext i8 %104 to i32
%106 = icmp sle i32 %105, 57
br i1 %106, label %107, label %108
107: ; preds = %103, %95, %87, %79, %75, %71, %67
store i32 0, i32* %3
br label %118
108: ; preds = %103, %99
br label %117
109: ; preds = %2
%110 = load i8, i8* %4
%111 = sext i8 %110 to i32
%112 = load i8, i8* %5
%113 = sext i8 %112 to i32
%114 = icmp eq i32 %111, %113
br i1 %114, label %115, label %116
115: ; preds = %109
br label %117
116: ; preds = %109
store i32 0, i32* %3
br label %118
117: ; preds = %115, %108, %65, %55, %46, %44, %34, %16
store i32 1, i32* %3
br label %118
118: ; preds = %117, %116, %107, %66, %56, %45, %35, %17
%119 = load i32, i32* %3
ret i32 %119
}

LLVM IR (-O2):
define i32 @cstrmatch_char(i8 signext %0, i8 signext %1) {
%3 = sext i8 %1 to i32
switch i32 %3, label %32 [
i32 65, label %4
i32 97, label %7
i32 100, label %11
i32 63, label %34
i32 32, label %14
i32 10, label %18
i32 36, label %22
]
4: ; preds = %2
%5 = add i8 %0, -65
%6 = icmp ult i8 %5, 26
br i1 %6, label %34, label %40
7: ; preds = %2
%8 = and i8 %0, -33
%9 = add i8 %8, -65
%10 = icmp ult i8 %9, 26
br i1 %10, label %34, label %40
11: ; preds = %2
%12 = add i8 %0, -48
%13 = icmp ult i8 %12, 10
br i1 %13, label %34, label %40
14: ; preds = %2
%15 = icmp eq i8 %0, 32
%16 = icmp eq i8 %0, 9
%17 = or i1 %15, %16
br label %40
18: ; preds = %2
%19 = icmp eq i8 %0, 13
%20 = icmp eq i8 %0, 10
%21 = or i1 %19, %20
br label %40
22: ; preds = %2
%23 = add i8 %0, -9
%24 = icmp ult i8 %23, 24
br i1 %24, label %35, label %25
25: ; preds = %35, %22
%26 = and i8 %0, -33
%27 = add i8 %26, -65
%28 = icmp ult i8 %27, 26
%29 = add i8 %0, -48
%30 = icmp ult i8 %29, 10
%31 = or i1 %30, %28
br i1 %31, label %40, label %34
32: ; preds = %2
%33 = icmp eq i8 %0, %1
br i1 %33, label %34, label %40
34: ; preds = %25, %32, %11, %7, %4, %2
br label %40
35: ; preds = %22
%36 = zext i8 %23 to i32
%37 = lshr i32 8388627, %36
%38 = and i32 %37, 1
%39 = icmp eq i32 %38, 0
br i1 %39, label %25, label %40
40: ; preds = %35, %18, %14, %32, %25, %11, %7, %4, %34
%41 = phi i1 [ true, %34 ], [ false, %4 ], [ false, %7 ], [ false, %11 ], [ false, %25 ], [ false, %32 ], [ %17, %14 ], [ %21, %18 ], [ false, %35 ]
%42 = zext i1 %41 to i32
ret i32 %42
}