double funcao_x(double x) {
  if (x <= 1) {
    return 1;
  }
  if (x > 1 && x <= 2) {
    return 2;
  }
  if (x > 2 && x <= 3) {
    return (x * x);
  }
  if (x > 3) {
    return (x * x * x);
  }
}


x86 assembly (clang, -O0):
<funcao_x>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  0xeef(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     112e <funcao_x+0x2e>
movsd  0xedc(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d3 <funcao_x+0xd3>
movsd  -0x10(%rbp),%xmm0
movsd  0xec5(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    116a <funcao_x+0x6a>
movsd  0xebb(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     116a <funcao_x+0x6a>
movsd  0xea8(%rip),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d3 <funcao_x+0xd3>
movsd  -0x10(%rbp),%xmm0
movsd  0xe91(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11a8 <funcao_x+0xa8>
movsd  0xe87(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jb     11a8 <funcao_x+0xa8>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    11d3 <funcao_x+0xd3>
movsd  -0x10(%rbp),%xmm0
movsd  0xe5b(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    11d3 <funcao_x+0xd3>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<funcao_x>:
movsd  0xef8(%rip),%xmm1
ucomisd %xmm0,%xmm1
jae    1162 <funcao_x+0x62>
ucomisd 0xeea(%rip),%xmm0
jbe    112f <funcao_x+0x2f>
movsd  0xee8(%rip),%xmm1
ucomisd %xmm0,%xmm1
jb     112f <funcao_x+0x2f>
movsd  0xeda(%rip),%xmm0
ret
ucomisd 0xed1(%rip),%xmm0
jbe    114c <funcao_x+0x4c>
movsd  0xecf(%rip),%xmm1
ucomisd %xmm0,%xmm1
jb     114c <funcao_x+0x4c>
mulsd  %xmm0,%xmm0
ret
ucomisd 0xebc(%rip),%xmm0
jbe    1162 <funcao_x+0x62>
movapd %xmm0,%xmm1
mulsd  %xmm0,%xmm1
mulsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
ret

LLVM IR (-O0):
define double @funcao_x(double %0) {
%2 = alloca double
%3 = alloca double
store double %0, double* %3
%4 = load double, double* %3
%5 = fcmp ole double %4, 1.000000e+00
br i1 %5, label %6, label %7
6: ; preds = %1
store double 1.000000e+00, double* %2
br label %33
7: ; preds = %1
%8 = load double, double* %3
%9 = fcmp ogt double %8, 1.000000e+00
br i1 %9, label %10, label %14
10: ; preds = %7
%11 = load double, double* %3
%12 = fcmp ole double %11, 2.000000e+00
br i1 %12, label %13, label %14
13: ; preds = %10
store double 2.000000e+00, double* %2
br label %33
14: ; preds = %10, %7
%15 = load double, double* %3
%16 = fcmp ogt double %15, 2.000000e+00
br i1 %16, label %17, label %24
17: ; preds = %14
%18 = load double, double* %3
%19 = fcmp ole double %18, 3.000000e+00
br i1 %19, label %20, label %24
20: ; preds = %17
%21 = load double, double* %3
%22 = load double, double* %3
%23 = fmul double %21, %22
store double %23, double* %2
br label %33
24: ; preds = %17, %14
%25 = load double, double* %3
%26 = fcmp ogt double %25, 3.000000e+00
br i1 %26, label %27, label %33
27: ; preds = %24
%28 = load double, double* %3
%29 = load double, double* %3
%30 = fmul double %28, %29
%31 = load double, double* %3
%32 = fmul double %30, %31
store double %32, double* %2
br label %33
33: ; preds = %6, %13, %20, %27, %24
%34 = load double, double* %2
ret double %34
}

LLVM IR (-O2):
define double @funcao_x(double %0) {
%2 = fcmp ugt double %0, 1.000000e+00
br i1 %2, label %3, label %18
3: ; preds = %1
%4 = fcmp ogt double %0, 1.000000e+00
%5 = fcmp ole double %0, 2.000000e+00
%6 = and i1 %4, %5
br i1 %6, label %18, label %7
7: ; preds = %3
%8 = fcmp ogt double %0, 2.000000e+00
%9 = fcmp ole double %0, 3.000000e+00
%10 = and i1 %8, %9
br i1 %10, label %11, label %13
11: ; preds = %7
%12 = fmul double %0, %0
br label %18
13: ; preds = %7
%14 = fcmp ogt double %0, 3.000000e+00
br i1 %14, label %15, label %18
15: ; preds = %13
%16 = fmul double %0, %0
%17 = fmul double %16, %0
br label %18
18: ; preds = %3, %1, %11, %15, %13
%19 = phi double [ %12, %11 ], [ %17, %15 ], [ undef, %13 ], [ 1.000000e+00, %1 ], [ 2.000000e+00, %3 ]
ret double %19
}