double celsius2temp(double tempc, char tscale, double toffset) {
  double temperature;
  switch (tscale) {
  case 'F':
    temperature = 1.8 * tempc + 32.0;
    break;
  case 'R':
    temperature = 1.8 * tempc + 32.0 + 459.67;
    break;
  case 'K':
    temperature = tempc + 273.15;
    break;
  default:
    temperature = tempc;
    break;
  }
  temperature += toffset;
  return temperature;
}


x86 assembly (clang, -O0):
<celsius2temp>:
push   %rbp
mov    %rsp,%rbp
mov    %dil,%al
movsd  %xmm0,-0x8(%rbp)
mov    %al,-0x9(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsbl -0x9(%rbp),%eax
mov    %eax,-0x24(%rbp)
sub    $0x46,%eax
je     114b <celsius2temp+0x4b>
jmp    1129 <celsius2temp+0x29>
mov    -0x24(%rbp),%eax
sub    $0x4b,%eax
je     11a5 <celsius2temp+0xa5>
jmp    113a <celsius2temp+0x3a>
mov    -0x24(%rbp),%eax
sub    $0x52,%eax
je     1172 <celsius2temp+0x72>
jmp    11bc <celsius2temp+0xbc>
movsd  -0x8(%rbp),%xmm0
movsd  0xeb8(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xeb4(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    11c6 <celsius2temp+0xc6>
movsd  -0x8(%rbp),%xmm0
movsd  0xe91(%rip),%xmm1
mulsd  %xmm1,%xmm0
movsd  0xe8d(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  0xe71(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    11c6 <celsius2temp+0xc6>
movsd  0xe53(%rip),%xmm0
addsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
jmp    11c6 <celsius2temp+0xc6>
movsd  -0x8(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x18(%rbp),%xmm0
addsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x20(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<celsius2temp>:
cmp    $0x52,%edi
je     1124 <celsius2temp+0x24>
cmp    $0x4b,%edi
je     1141 <celsius2temp+0x41>
cmp    $0x46,%edi
jne    1149 <celsius2temp+0x49>
mulsd  0xef1(%rip),%xmm0
addsd  0xef1(%rip),%xmm0
addsd  %xmm1,%xmm0
ret
mulsd  0xedc(%rip),%xmm0
addsd  0xedc(%rip),%xmm0
addsd  0xedc(%rip),%xmm0
addsd  %xmm1,%xmm0
ret
addsd  0xeb7(%rip),%xmm0
addsd  %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @celsius2temp(double %0, i8 signext %1, double %2) {
%4 = alloca double
%5 = alloca i8
%6 = alloca double
%7 = alloca double
store double %0, double* %4
store i8 %1, i8* %5
store double %2, double* %6
%8 = load i8, i8* %5
%9 = sext i8 %8 to i32
switch i32 %9, label %20 [
i32 70, label %10
i32 82, label %13
i32 75, label %17
]
10: ; preds = %3
%11 = load double, double* %4
%12 = call double @llvm.fmuladd.f64(double 1.800000e+00, double %11, double 3.200000e+01)
store double %12, double* %7
br label %22
13: ; preds = %3
%14 = load double, double* %4
%15 = call double @llvm.fmuladd.f64(double 1.800000e+00, double %14, double 3.200000e+01)
%16 = fadd double %15, 4.596700e+02
store double %16, double* %7
br label %22
17: ; preds = %3
%18 = load double, double* %4
%19 = fadd double %18, 2.731500e+02
store double %19, double* %7
br label %22
20: ; preds = %3
%21 = load double, double* %4
store double %21, double* %7
br label %22
22: ; preds = %20, %17, %13, %10
%23 = load double, double* %6
%24 = load double, double* %7
%25 = fadd double %24, %23
store double %25, double* %7
%26 = load double, double* %7
ret double %26
}

LLVM IR (-O2):
define double @celsius2temp(double %0, i8 signext %1, double %2) {
%4 = sext i8 %1 to i32
switch i32 %4, label %12 [
i32 70, label %5
i32 82, label %7
i32 75, label %10
]
5: ; preds = %3
%6 = tail call double @llvm.fmuladd.f64(double %0, double 1.800000e+00, double 3.200000e+01)
br label %12
7: ; preds = %3
%8 = tail call double @llvm.fmuladd.f64(double %0, double 1.800000e+00, double 3.200000e+01)
%9 = fadd double %8, 4.596700e+02
br label %12
10: ; preds = %3
%11 = fadd double %0, 2.731500e+02
br label %12
12: ; preds = %3, %10, %7, %5
%13 = phi double [ %11, %10 ], [ %9, %7 ], [ %6, %5 ], [ %0, %3 ]
%14 = fadd double %13, %2
ret double %14
}