char dna_to_upper(s, ambiguity_code_ok)
char *s;
int ambiguity_code_ok;
{
  char *p = s;
  int unrecognized_base = '\0';
  while (*p) {
    switch (*p) {
    case 'a':
    case 'A':
      *p = 'A';
      break;
    case 'c':
    case 'C':
      *p = 'C';
      break;
    case 'g':
    case 'G':
      *p = 'G';
      break;
    case 't':
    case 'T':
      *p = 'T';
      break;
    case 'n':
    case 'N':
      *p = 'N';
      break;
    default:
      if (ambiguity_code_ok) {
        switch (*p) {
        case 'r':
        case 'R':
          *p = 'R';
          break;
        case 'y':
        case 'Y':
          *p = 'Y';
          break;
        case 'm':
        case 'M':
          *p = 'M';
          break;
        case 'w':
        case 'W':
          *p = 'W';
          break;
        case 's':
        case 'S':
          *p = 'S';
          break;
        case 'k':
        case 'K':
          *p = 'K';
          break;
        case 'd':
        case 'D':
          *p = 'D';
          break;
        case 'h':
        case 'H':
          *p = 'H';
          break;
        case 'v':
        case 'V':
          *p = 'V';
          break;
        case 'b':
        case 'B':
          *p = 'B';
          break;
        }
      } else {
        if (!unrecognized_base)
          unrecognized_base = *p;
        *p = 'N';
      }
      break;
    }
    p++;
  }
  return unrecognized_base;
}


x86 assembly (clang, -O0):
<dna_to_upper>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x18(%rbp),%rax
cmpb   $0x0,(%rax)
je     1270 <dna_to_upper+0x170>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
add    $0xffffffbf,%eax
mov    %eax,%ecx
mov    %rcx,-0x28(%rbp)
sub    $0x33,%eax
ja     1190 <dna_to_upper+0x90>
mov    -0x28(%rbp),%rax
lea    0xeb5(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x18(%rbp),%rax
movb   $0x41,(%rax)
jmp    125f <dna_to_upper+0x15f>
mov    -0x18(%rbp),%rax
movb   $0x43,(%rax)
jmp    125f <dna_to_upper+0x15f>
mov    -0x18(%rbp),%rax
movb   $0x47,(%rax)
jmp    125f <dna_to_upper+0x15f>
mov    -0x18(%rbp),%rax
movb   $0x54,(%rax)
jmp    125f <dna_to_upper+0x15f>
mov    -0x18(%rbp),%rax
movb   $0x4e,(%rax)
jmp    125f <dna_to_upper+0x15f>
cmpl   $0x0,-0xc(%rbp)
je     123f <dna_to_upper+0x13f>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
add    $0xffffffbe,%eax
mov    %eax,%ecx
mov    %rcx,-0x30(%rbp)
sub    $0x37,%eax
ja     123a <dna_to_upper+0x13a>
mov    -0x30(%rbp),%rax
lea    0xf12(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x18(%rbp),%rax
movb   $0x52,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x59,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x4d,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x57,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x53,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x4b,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x44,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x48,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x56,(%rax)
jmp    123a <dna_to_upper+0x13a>
mov    -0x18(%rbp),%rax
movb   $0x42,(%rax)
jmp    125a <dna_to_upper+0x15a>
cmpl   $0x0,-0x1c(%rbp)
jne    1253 <dna_to_upper+0x153>
mov    -0x18(%rbp),%rax
movsbl (%rax),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x18(%rbp),%rax
movb   $0x4e,(%rax)
jmp    125f <dna_to_upper+0x15f>
mov    -0x18(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x18(%rbp)
jmp    111a <dna_to_upper+0x1a>
mov    -0x1c(%rbp),%eax
movsbl %al,%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<dna_to_upper>:
mov    (%rdi),%cl
test   %cl,%cl
je     11b3 <dna_to_upper+0xb3>
add    $0x1,%rdi
xor    %eax,%eax
lea    0xfb9(%rip),%r8
lea    0xee2(%rip),%r9
xchg   %ax,%ax
movsbl %cl,%edx
lea    -0x41(%rdx),%ecx
cmp    $0x33,%ecx
ja     1161 <dna_to_upper+0x61>
mov    $0x41,%r10b
movslq (%r9,%rcx,4),%rcx
add    %r9,%rcx
jmp    *%rcx
mov    $0x43,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x47,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x4e,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x54,%r10b
nopl   0x0(%rax)
mov    %r10b,-0x1(%rdi)
movzbl (%rdi),%ecx
add    $0x1,%rdi
test   %cl,%cl
jne    1120 <dna_to_upper+0x20>
jmp    11b2 <dna_to_upper+0xb2>
test   %esi,%esi
je     117e <dna_to_upper+0x7e>
add    $0xffffffbe,%edx
cmp    $0x37,%edx
ja     1154 <dna_to_upper+0x54>
mov    $0x52,%r10b
movslq (%r8,%rdx,4),%rcx
add    %r8,%rcx
jmp    *%rcx
mov    $0x42,%r10b
jmp    1150 <dna_to_upper+0x50>
test   %eax,%eax
cmovne %eax,%edx
mov    $0x4e,%r10b
mov    %edx,%eax
jmp    1150 <dna_to_upper+0x50>
mov    $0x44,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x48,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x4b,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x4d,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x53,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x56,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x57,%r10b
jmp    1150 <dna_to_upper+0x50>
mov    $0x59,%r10b
jmp    1150 <dna_to_upper+0x50>
ret
xor    %eax,%eax
ret

LLVM IR (-O0):
define signext i8 @dna_to_upper(i8* %0, i32 %1) {
%3 = alloca i8*
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i32
store i8* %0, i8** %3
store i32 %1, i32* %4
%7 = load i8*, i8** %3
store i8* %7, i8** %5
store i32 0, i32* %6
br label %8
8: ; preds = %64, %2
%9 = load i8*, i8** %5
%10 = load i8, i8* %9
%11 = icmp ne i8 %10, 0
br i1 %11, label %12, label %67
12: ; preds = %8
%13 = load i8*, i8** %5
%14 = load i8, i8* %13
%15 = sext i8 %14 to i32
switch i32 %15, label %26 [
i32 97, label %16
i32 65, label %16
i32 99, label %18
i32 67, label %18
i32 103, label %20
i32 71, label %20
i32 116, label %22
i32 84, label %22
i32 110, label %24
i32 78, label %24
]
16: ; preds = %12, %12
%17 = load i8*, i8** %5
store i8 65, i8* %17
br label %64
18: ; preds = %12, %12
%19 = load i8*, i8** %5
store i8 67, i8* %19
br label %64
20: ; preds = %12, %12
%21 = load i8*, i8** %5
store i8 71, i8* %21
br label %64
22: ; preds = %12, %12
%23 = load i8*, i8** %5
store i8 84, i8* %23
br label %64
24: ; preds = %12, %12
%25 = load i8*, i8** %5
store i8 78, i8* %25
br label %64
26: ; preds = %12
%27 = load i32, i32* %4
%28 = icmp ne i32 %27, 0
br i1 %28, label %29, label %54
29: ; preds = %26
%30 = load i8*, i8** %5
%31 = load i8, i8* %30
%32 = sext i8 %31 to i32
switch i32 %32, label %53 [
i32 114, label %33
i32 82, label %33
i32 121, label %35
i32 89, label %35
i32 109, label %37
i32 77, label %37
i32 119, label %39
i32 87, label %39
i32 115, label %41
i32 83, label %41
i32 107, label %43
i32 75, label %43
i32 100, label %45
i32 68, label %45
i32 104, label %47
i32 72, label %47
i32 118, label %49
i32 86, label %49
i32 98, label %51
i32 66, label %51
]
33: ; preds = %29, %29
%34 = load i8*, i8** %5
store i8 82, i8* %34
br label %53
35: ; preds = %29, %29
%36 = load i8*, i8** %5
store i8 89, i8* %36
br label %53
37: ; preds = %29, %29
%38 = load i8*, i8** %5
store i8 77, i8* %38
br label %53
39: ; preds = %29, %29
%40 = load i8*, i8** %5
store i8 87, i8* %40
br label %53
41: ; preds = %29, %29
%42 = load i8*, i8** %5
store i8 83, i8* %42
br label %53
43: ; preds = %29, %29
%44 = load i8*, i8** %5
store i8 75, i8* %44
br label %53
45: ; preds = %29, %29
%46 = load i8*, i8** %5
store i8 68, i8* %46
br label %53
47: ; preds = %29, %29
%48 = load i8*, i8** %5
store i8 72, i8* %48
br label %53
49: ; preds = %29, %29
%50 = load i8*, i8** %5
store i8 86, i8* %50
br label %53
51: ; preds = %29, %29
%52 = load i8*, i8** %5
store i8 66, i8* %52
br label %53
53: ; preds = %29, %51, %49, %47, %45, %43, %41, %39, %37, %35, %33
br label %63
54: ; preds = %26
%55 = load i32, i32* %6
%56 = icmp ne i32 %55, 0
br i1 %56, label %61, label %57
57: ; preds = %54
%58 = load i8*, i8** %5
%59 = load i8, i8* %58
%60 = sext i8 %59 to i32
store i32 %60, i32* %6
br label %61
61: ; preds = %57, %54
%62 = load i8*, i8** %5
store i8 78, i8* %62
br label %63
63: ; preds = %61, %53
br label %64
64: ; preds = %63, %24, %22, %20, %18, %16
%65 = load i8*, i8** %5
%66 = getelementptr inbounds i8, i8* %65, i32 1
store i8* %66, i8** %5
br label %8
67: ; preds = %8
%68 = load i32, i32* %6
%69 = trunc i32 %68 to i8
ret i8 %69
}

LLVM IR (-O2):
define signext i8 @dna_to_upper(i8* nocapture %0, i32 %1) {
%3 = load i8, i8* %0
%4 = icmp eq i8 %3, 0
br i1 %4, label %38, label %5
5: ; preds = %2
%6 = icmp eq i32 %1, 0
br label %7
7: ; preds = %5, %33
%8 = phi i8 [ %3, %5 ], [ %36, %33 ]
%9 = phi i32 [ 0, %5 ], [ %34, %33 ]
%10 = phi i8* [ %0, %5 ], [ %35, %33 ]
%11 = sext i8 %8 to i32
switch i32 %11, label %16 [
i32 97, label %30
i32 65, label %30
i32 99, label %12
i32 67, label %12
i32 103, label %13
i32 71, label %13
i32 116, label %14
i32 84, label %14
i32 110, label %15
i32 78, label %15
]
12: ; preds = %7, %7
br label %30
13: ; preds = %7, %7
br label %30
14: ; preds = %7, %7
br label %30
15: ; preds = %7, %7
br label %30
16: ; preds = %7
br i1 %6, label %27, label %17
17: ; preds = %16
switch i32 %11, label %33 [
i32 114, label %30
i32 82, label %30
i32 121, label %18
i32 89, label %18
i32 109, label %19
i32 77, label %19
i32 119, label %20
i32 87, label %20
i32 115, label %21
i32 83, label %21
i32 107, label %22
i32 75, label %22
i32 100, label %23
i32 68, label %23
i32 104, label %24
i32 72, label %24
i32 118, label %25
i32 86, label %25
i32 98, label %26
i32 66, label %26
]
18: ; preds = %17, %17
br label %30
19: ; preds = %17, %17
br label %30
20: ; preds = %17, %17
br label %30
21: ; preds = %17, %17
br label %30
22: ; preds = %17, %17
br label %30
23: ; preds = %17, %17
br label %30
24: ; preds = %17, %17
br label %30
25: ; preds = %17, %17
br label %30
26: ; preds = %17, %17
br label %30
27: ; preds = %16
%28 = icmp eq i32 %9, 0
%29 = select i1 %28, i32 %11, i32 %9
br label %30
30: ; preds = %17, %17, %7, %7, %12, %13, %14, %15, %18, %19, %20, %21, %22, %23, %24, %25, %26, %27
%31 = phi i8 [ 78, %27 ], [ 66, %26 ], [ 86, %25 ], [ 72, %24 ], [ 68, %23 ], [ 75, %22 ], [ 83, %21 ], [ 87, %20 ], [ 77, %19 ], [ 89, %18 ], [ 78, %15 ], [ 84, %14 ], [ 71, %13 ], [ 67, %12 ], [ 65, %7 ], [ 65, %7 ], [ 82, %17 ], [ 82, %17 ]
%32 = phi i32 [ %29, %27 ], [ %9, %26 ], [ %9, %25 ], [ %9, %24 ], [ %9, %23 ], [ %9, %22 ], [ %9, %21 ], [ %9, %20 ], [ %9, %19 ], [ %9, %18 ], [ %9, %15 ], [ %9, %14 ], [ %9, %13 ], [ %9, %12 ], [ %9, %7 ], [ %9, %7 ], [ %9, %17 ], [ %9, %17 ]
store i8 %31, i8* %10
br label %33
33: ; preds = %30, %17
%34 = phi i32 [ %9, %17 ], [ %32, %30 ]
%35 = getelementptr inbounds i8, i8* %10, i64 1
%36 = load i8, i8* %35
%37 = icmp eq i8 %36, 0
br i1 %37, label %38, label %7
38: ; preds = %33, %2
%39 = phi i32 [ 0, %2 ], [ %34, %33 ]
%40 = trunc i32 %39 to i8
ret i8 %40
}