char *combine(char letter, const char *name, char *buffer) {
  char first = tolower(name[0]);
  const char *stem = name + 1;
  if (first == 'a' || first == 'e' || first == 'i' || first == 'o' ||
      first == 'u') {
    sprintf(buffer, "%c%c%s", letter, first, stem);
  } else if (stem[0] == 'c' || stem[0] == 'h' || stem[0] == 't') {
    sprintf(buffer, "%c%s", letter, stem + 1);
  } else if ((letter == 'b' || letter == 'f' || letter == 'm') &&
             letter == first) {
    strcpy(buffer, stem);
  } else {
    sprintf(buffer, "%c%s", letter, stem);
  }
  return buffer;
}


x86 assembly (clang, -O0):
<combine>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
mov    %dil,%al
mov    %al,-0x1(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movsbl (%rax),%edi
call   1040 <tolower@plt>
mov    %al,-0x19(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
movsbl -0x19(%rbp),%eax
cmp    $0x61,%eax
je     11a2 <combine+0x72>
movsbl -0x19(%rbp),%eax
cmp    $0x65,%eax
je     11a2 <combine+0x72>
movsbl -0x19(%rbp),%eax
cmp    $0x69,%eax
je     11a2 <combine+0x72>
movsbl -0x19(%rbp),%eax
cmp    $0x6f,%eax
je     11a2 <combine+0x72>
movsbl -0x19(%rbp),%eax
cmp    $0x75,%eax
jne    11c5 <combine+0x95>
mov    -0x18(%rbp),%rdi
movsbl -0x1(%rbp),%edx
movsbl -0x19(%rbp),%ecx
mov    -0x28(%rbp),%r8
lea    0xe47(%rip),%rsi
mov    $0x0,%al
call   1050 <sprintf@plt>
jmp    1285 <combine+0x155>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x63,%eax
je     11f5 <combine+0xc5>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x68,%eax
je     11f5 <combine+0xc5>
mov    -0x28(%rbp),%rax
movsbl (%rax),%eax
cmp    $0x74,%eax
jne    1218 <combine+0xe8>
mov    -0x18(%rbp),%rdi
movsbl -0x1(%rbp),%edx
mov    -0x28(%rbp),%rcx
add    $0x1,%rcx
lea    0xdf6(%rip),%rsi
mov    $0x0,%al
call   1050 <sprintf@plt>
jmp    1280 <combine+0x150>
movsbl -0x1(%rbp),%eax
cmp    $0x62,%eax
je     123f <combine+0x10f>
movsbl -0x1(%rbp),%eax
cmp    $0x66,%eax
je     123f <combine+0x10f>
movsbl -0x1(%rbp),%eax
cmp    $0x6d,%eax
jne    1261 <combine+0x131>
movsbl -0x1(%rbp),%eax
movsbl -0x19(%rbp),%ecx
cmp    %ecx,%eax
jne    1261 <combine+0x131>
mov    -0x18(%rbp),%rdi
mov    -0x28(%rbp),%rsi
call   1030 <strcpy@plt>
jmp    127b <combine+0x14b>
mov    -0x18(%rbp),%rdi
movsbl -0x1(%rbp),%edx
mov    -0x28(%rbp),%rcx
lea    0xd8e(%rip),%rsi
mov    $0x0,%al
call   1050 <sprintf@plt>
jmp    1280 <combine+0x150>
jmp    1285 <combine+0x155>
mov    -0x18(%rbp),%rax
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<combine>:
push   %rbp
push   %r14
push   %rbx
mov    %rdx,%r14
mov    %rsi,%rbx
mov    %edi,%ebp
movsbl (%rsi),%edi
call   1040 <tolower@plt>
lea    0x1(%rbx),%r8
movsbl %al,%ecx
mov    %eax,%edx
and    $0xfb,%edx
cmp    $0x61,%edx
jne    1175 <combine+0x45>
movsbl %bpl,%edx
lea    0xe9d(%rip),%rsi
mov    %r14,%rdi
xor    %eax,%eax
call   1050 <sprintf@plt>
mov    %r14,%rax
pop    %rbx
pop    %r14
pop    %rbp
ret
shl    $0x18,%eax
cmp    $0x69000000,%eax
je     1158 <combine+0x28>
cmp    $0x75000000,%eax
je     1158 <combine+0x28>
cmp    $0x6f000000,%eax
je     1158 <combine+0x28>
mov    (%r8),%al
add    $0x9d,%al
cmp    $0x11,%al
ja     11c2 <combine+0x92>
movzbl %al,%eax
mov    $0x20021,%edx
bt     %rax,%rdx
jae    11c2 <combine+0x92>
movsbl %bpl,%edx
add    $0x2,%rbx
lea    0xe4f(%rip),%rsi
mov    %r14,%rdi
mov    %rbx,%rcx
xor    %eax,%eax
call   1050 <sprintf@plt>
jmp    116d <combine+0x3d>
movsbl %bpl,%edx
add    $0x9e,%bpl
cmp    $0xb,%bpl
ja     11f3 <combine+0xc3>
movzbl %bpl,%eax
mov    $0x811,%esi
bt     %rax,%rsi
jae    11f3 <combine+0xc3>
cmp    %edx,%ecx
jne    11f3 <combine+0xc3>
mov    %r14,%rdi
mov    %r8,%rsi
call   1030 <strcpy@plt>
jmp    116d <combine+0x3d>
lea    0xe08(%rip),%rsi
mov    %r14,%rdi
mov    %r8,%rcx
jmp    11b9 <combine+0x89>

LLVM IR (-O0):
@.str = [7 x i8] c"%c%c%s\00"
@.str.1 = [5 x i8] c"%c%s\00"
define i8* @combine(i8 signext %0, i8* %1, i8* %2) {
%4 = alloca i8
%5 = alloca i8*
%6 = alloca i8*
%7 = alloca i8
%8 = alloca i8*
store i8 %0, i8* %4
store i8* %1, i8** %5
store i8* %2, i8** %6
%9 = load i8*, i8** %5
%10 = getelementptr inbounds i8, i8* %9, i64 0
%11 = load i8, i8* %10
%12 = sext i8 %11 to i32
%13 = call i32 @tolower(i32 %12)
%14 = trunc i32 %13 to i8
store i8 %14, i8* %7
%15 = load i8*, i8** %5
%16 = getelementptr inbounds i8, i8* %15, i64 1
store i8* %16, i8** %8
%17 = load i8, i8* %7
%18 = sext i8 %17 to i32
%19 = icmp eq i32 %18, 97
br i1 %19, label %36, label %20
20: ; preds = %3
%21 = load i8, i8* %7
%22 = sext i8 %21 to i32
%23 = icmp eq i32 %22, 101
br i1 %23, label %36, label %24
24: ; preds = %20
%25 = load i8, i8* %7
%26 = sext i8 %25 to i32
%27 = icmp eq i32 %26, 105
br i1 %27, label %36, label %28
28: ; preds = %24
%29 = load i8, i8* %7
%30 = sext i8 %29 to i32
%31 = icmp eq i32 %30, 111
br i1 %31, label %36, label %32
32: ; preds = %28
%33 = load i8, i8* %7
%34 = sext i8 %33 to i32
%35 = icmp eq i32 %34, 117
br i1 %35, label %36, label %44
36: ; preds = %32, %28, %24, %20, %3
%37 = load i8*, i8** %6
%38 = load i8, i8* %4
%39 = sext i8 %38 to i32
%40 = load i8, i8* %7
%41 = sext i8 %40 to i32
%42 = load i8*, i8** %8
%43 = call i32 (i8*, i8*, ...) @sprintf(i8* %37, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0), i32 %39, i32 %41, i8* %42)
br label %99
44: ; preds = %32
%45 = load i8*, i8** %8
%46 = getelementptr inbounds i8, i8* %45, i64 0
%47 = load i8, i8* %46
%48 = sext i8 %47 to i32
%49 = icmp eq i32 %48, 99
br i1 %49, label %62, label %50
50: ; preds = %44
%51 = load i8*, i8** %8
%52 = getelementptr inbounds i8, i8* %51, i64 0
%53 = load i8, i8* %52
%54 = sext i8 %53 to i32
%55 = icmp eq i32 %54, 104
br i1 %55, label %62, label %56
56: ; preds = %50
%57 = load i8*, i8** %8
%58 = getelementptr inbounds i8, i8* %57, i64 0
%59 = load i8, i8* %58
%60 = sext i8 %59 to i32
%61 = icmp eq i32 %60, 116
br i1 %61, label %62, label %69
62: ; preds = %56, %50, %44
%63 = load i8*, i8** %6
%64 = load i8, i8* %4
%65 = sext i8 %64 to i32
%66 = load i8*, i8** %8
%67 = getelementptr inbounds i8, i8* %66, i64 1
%68 = call i32 (i8*, i8*, ...) @sprintf(i8* %63, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i32 %65, i8* %67)
br label %98
69: ; preds = %56
%70 = load i8, i8* %4
%71 = sext i8 %70 to i32
%72 = icmp eq i32 %71, 98
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 %75, 102
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 %79, 109
br i1 %80, label %81, label %91
81: ; preds = %77, %73, %69
%82 = load i8, i8* %4
%83 = sext i8 %82 to i32
%84 = load i8, i8* %7
%85 = sext i8 %84 to i32
%86 = icmp eq i32 %83, %85
br i1 %86, label %87, label %91
87: ; preds = %81
%88 = load i8*, i8** %6
%89 = load i8*, i8** %8
%90 = call i8* @strcpy(i8* %88, i8* %89)
br label %97
91: ; preds = %81, %77
%92 = load i8*, i8** %6
%93 = load i8, i8* %4
%94 = sext i8 %93 to i32
%95 = load i8*, i8** %8
%96 = call i32 (i8*, i8*, ...) @sprintf(i8* %92, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i32 %94, i8* %95)
br label %97
97: ; preds = %91, %87
br label %98
98: ; preds = %97, %62
br label %99
99: ; preds = %98, %36
%100 = load i8*, i8** %6
ret i8* %100
}

LLVM IR (-O2):
@.str = [7 x i8] c"%c%c%s\00"
@.str.1 = [5 x i8] c"%c%s\00"
define i8* @combine(i8 signext %0, i8* %1, i8* returned %2) {
%4 = load i8, i8* %1
%5 = sext i8 %4 to i32
%6 = tail call i32 @tolower(i32 %5)
%7 = getelementptr inbounds i8, i8* %1, i64 1
%8 = shl i32 %6, 24
%9 = ashr exact i32 %8, 24
%10 = freeze i32 %6
%11 = and i32 %10, 251
%12 = icmp eq i32 %11, 97
br i1 %12, label %14, label %13
13: ; preds = %3
switch i32 %8, label %17 [
i32 1962934272, label %14
i32 1862270976, label %14
i32 1761607680, label %14
]
14: ; preds = %13, %13, %13, %3
%15 = sext i8 %0 to i32
%16 = tail call i32 (i8*, i8*, ...) @sprintf(i8* dereferenceable(1) %2, i8* dereferenceable(1) getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i64 0, i64 0), i32 %15, i32 %9, i8* %7)
br label %31
17: ; preds = %13
%18 = load i8, i8* %7
switch i8 %18, label %23 [
i8 99, label %19
i8 104, label %19
i8 116, label %19
]
19: ; preds = %17, %17, %17
%20 = sext i8 %0 to i32
%21 = getelementptr inbounds i8, i8* %1, i64 2
%22 = tail call i32 (i8*, i8*, ...) @sprintf(i8* dereferenceable(1) %2, i8* dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i32 %20, i8* %21)
br label %31
23: ; preds = %17
%24 = sext i8 %0 to i32
switch i8 %0, label %29 [
i8 109, label %25
i8 102, label %25
i8 98, label %25
]
25: ; preds = %23, %23, %23
%26 = icmp eq i32 %9, %24
br i1 %26, label %27, label %29
27: ; preds = %25
%28 = tail call i8* @strcpy(i8* dereferenceable(1) %2, i8* %7)
br label %31
29: ; preds = %23, %25
%30 = tail call i32 (i8*, i8*, ...) @sprintf(i8* dereferenceable(1) %2, i8* dereferenceable(1) getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i32 %24, i8* %7)
br label %31
31: ; preds = %19, %29, %27, %14
ret i8* %2
}