testgamma() {
  double x, xfac;
  extern double gamma(), exp();
  printf("testing gamma ...\n");
  for (x = 1.0, xfac = 1.0; x < 30.0; x += 1.0) {
    dotest("exp(gamma(%.2f))", x, exp(gamma(x)), xfac);
    xfac *= x;
  }
}


x86 assembly (clang, -O0):
<testgamma>:
push   %rbp
mov    %rsp,%rbp
sub    $0x20,%rsp
lea    0xec1(%rip),%rdi
mov    $0x0,%al
call   1050 <printf@plt>
movsd  0xea2(%rip),%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  0xe95(%rip),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xe90(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11df <testgamma+0x9f>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x20(%rbp)
movsd  -0x10(%rbp),%xmm0
mov    $0x1,%al
call   1030 <gamma@plt>
call   1060 <exp@plt>
movaps %xmm0,%xmm1
movsd  -0x20(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm2
lea    0xe71(%rip),%rdi
mov    $0x3,%al
call   1040 <dotest@plt>
movsd  -0x10(%rbp),%xmm0
mulsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x18(%rbp)
movsd  0xe30(%rip),%xmm0
addsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
jmp    1170 <testgamma+0x30>
mov    -0x4(%rbp),%eax
add    $0x20,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<testgamma>:
push   %rbp
push   %rbx
sub    $0x18,%rsp
lea    0xecc(%rip),%rdi
call   1030 <puts@plt>
movsd  0xea6(%rip),%xmm0
mov    $0x1d,%ebp
lea    0xea2(%rip),%rbx
movsd  %xmm0,0x8(%rsp)
nopl   0x0(%rax)
movsd  %xmm0,0x10(%rsp)
movsd  0x10(%rsp),%xmm0
mov    $0x1,%al
call   1040 <gamma@plt>
call   1060 <exp@plt>
movaps %xmm0,%xmm1
mov    %rbx,%rdi
movsd  0x10(%rsp),%xmm0
movsd  0x8(%rsp),%xmm2
mov    $0x3,%al
call   1050 <dotest@plt>
movsd  0x10(%rsp),%xmm0
movsd  0x8(%rsp),%xmm1
mulsd  %xmm0,%xmm1
movsd  %xmm1,0x8(%rsp)
addsd  0xe41(%rip),%xmm0
add    $0xffffffff,%ebp
jne    1170 <testgamma+0x30>
add    $0x18,%rsp
pop    %rbx
pop    %rbp
ret

LLVM IR (-O0):
@.str = [19 x i8] c"testing gamma ...\0A\00"
@.str.1 = [17 x i8] c"exp(gamma(%.2f))\00"
define i32 @testgamma() {
%1 = alloca i32
%2 = alloca double
%3 = alloca double
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([19 x i8], [19 x i8]* @.str, i64 0, i64 0))
store double 1.000000e+00, double* %2
store double 1.000000e+00, double* %3
br label %5
5: ; preds = %18, %0
%6 = load double, double* %2
%7 = fcmp olt double %6, 3.000000e+01
br i1 %7, label %8, label %21
8: ; preds = %5
%9 = load double, double* %2
%10 = load double, double* %2
%11 = call double (double, ...) bitcast (double (...)* @gamma to double (double, ...)*)(double %10)
%12 = call double @exp(double %11)
%13 = load double, double* %3
%14 = call i32 (i8*, double, double, double, ...) bitcast (i32 (...)* @dotest to i32 (i8*, double, double, double, ...)*)(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0), double %9, double %12, double %13)
%15 = load double, double* %2
%16 = load double, double* %3
%17 = fmul double %16, %15
store double %17, double* %3
br label %18
18: ; preds = %8
%19 = load double, double* %2
%20 = fadd double %19, 1.000000e+00
store double %20, double* %2
br label %5
21: ; preds = %5
%22 = load i32, i32* %1
ret i32 %22
}

LLVM IR (-O2):
@.str.1 = [17 x i8] c"exp(gamma(%.2f))\00"
@str = [18 x i8] c"testing gamma ...\00"
define i32 @testgamma() {
%1 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([18 x i8], [18 x i8]* @str, i64 0, i64 0))
br label %2
2: ; preds = %0, %2
%3 = phi double [ 1.000000e+00, %0 ], [ %9, %2 ]
%4 = phi i32 [ 1, %0 ], [ %10, %2 ]
%5 = sitofp i32 %4 to double
%6 = tail call double (double, ...) bitcast (double (...)* @gamma to double (double, ...)*)(double %5)
%7 = tail call double @exp(double %6)
%8 = tail call i32 (i8*, double, double, double, ...) bitcast (i32 (...)* @dotest to i32 (i8*, double, double, double, ...)*)(i8* getelementptr inbounds ([17 x i8], [17 x i8]* @.str.1, i64 0, i64 0), double %5, double %7, double %3)
%9 = fmul double %3, %5
%10 = add nuw nsw i32 %4, 1
%11 = icmp eq i32 %10, 30
br i1 %11, label %12, label %2
12: ; preds = %2
ret i32 undef
}