double arithmetic(double a, double b, char *operator) {
  switch (*operator) {
  case 97:
    return a + b;
  case 115:
    return a - b;
  case 109:
    return a * b;
  case 100:
    return a / b;
  default:
    return 0;
  }
}


x86 assembly (clang, -O0):
<arithmetic>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %rdi,-0x20(%rbp)
mov    -0x20(%rbp),%rax
movsbl (%rax),%eax
add    $0xffffff9f,%eax
mov    %eax,%ecx
mov    %rcx,-0x28(%rbp)
sub    $0x12,%eax
ja     118f <arithmetic+0x8f>
mov    -0x28(%rbp),%rax
lea    0xeca(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movsd  -0x10(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1197 <arithmetic+0x97>
movsd  -0x10(%rbp),%xmm0
subsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1197 <arithmetic+0x97>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1197 <arithmetic+0x97>
movsd  -0x10(%rbp),%xmm0
divsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1197 <arithmetic+0x97>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<arithmetic>:
movsbl (%rdi),%eax
xorpd  %xmm2,%xmm2
add    $0xffffff9f,%eax
cmp    $0x12,%eax
ja     1139 <arithmetic+0x39>
lea    0xeea(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
addsd  %xmm1,%xmm0
jmp    1135 <arithmetic+0x35>
divsd  %xmm1,%xmm0
jmp    1135 <arithmetic+0x35>
mulsd  %xmm1,%xmm0
jmp    1135 <arithmetic+0x35>
subsd  %xmm1,%xmm0
movapd %xmm0,%xmm2
movapd %xmm2,%xmm0
ret

LLVM IR (-O0):
define double @arithmetic(double %0, double %1, i8* %2) {
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca i8*
store double %0, double* %5
store double %1, double* %6
store i8* %2, i8** %7
%8 = load i8*, i8** %7
%9 = load i8, i8* %8
%10 = sext i8 %9 to i32
switch i32 %10, label %27 [
i32 97, label %11
i32 115, label %15
i32 109, label %19
i32 100, label %23
]
11: ; preds = %3
%12 = load double, double* %5
%13 = load double, double* %6
%14 = fadd double %12, %13
store double %14, double* %4
br label %28
15: ; preds = %3
%16 = load double, double* %5
%17 = load double, double* %6
%18 = fsub double %16, %17
store double %18, double* %4
br label %28
19: ; preds = %3
%20 = load double, double* %5
%21 = load double, double* %6
%22 = fmul double %20, %21
store double %22, double* %4
br label %28
23: ; preds = %3
%24 = load double, double* %5
%25 = load double, double* %6
%26 = fdiv double %24, %25
store double %26, double* %4
br label %28
27: ; preds = %3
store double 0.000000e+00, double* %4
br label %28
28: ; preds = %27, %23, %19, %15, %11
%29 = load double, double* %4
ret double %29
}

LLVM IR (-O2):
define double @arithmetic(double %0, double %1, i8* nocapture %2) {
%4 = load i8, i8* %2
%5 = sext i8 %4 to i32
switch i32 %5, label %14 [
i32 97, label %6
i32 115, label %8
i32 109, label %10
i32 100, label %12
]
6: ; preds = %3
%7 = fadd double %0, %1
br label %14
8: ; preds = %3
%9 = fsub double %0, %1
br label %14
10: ; preds = %3
%11 = fmul double %0, %1
br label %14
12: ; preds = %3
%13 = fdiv double %0, %1
br label %14
14: ; preds = %3, %12, %10, %8, %6
%15 = phi double [ %13, %12 ], [ %11, %10 ], [ %9, %8 ], [ %7, %6 ], [ 0.000000e+00, %3 ]
ret double %15
}