#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
int /*<<< orphan*/ abort();
int /*<<< orphan*/ assert(int);
double fmax(double, double);
double fmin(double, double);
double PayoffFunction(int type, int fCall, double S1, double S2, double Q1,
                      double Q2, double X1, double X2) {
  double z, qs1, qs2, result;
  assert(type >= 1);
  assert(type <= 7);
  if (fCall)
    z = 1.0;
  else
    z = -1.0;
  qs1 = Q1 * S1;
  qs2 = Q2 * S2;
  switch (type) {
  case 1:
    result = z * (qs1 - qs2) - z * X1;
    break;
  case 2:
    result = z * fmax(qs1, qs2) - z * X1;
    break;
  case 3:
    result = z * fmin(qs1, qs2) - z * X1;
    break;
  case 4:
    result = fmax(z * (qs1 - X1), z * (qs2 - X2));
    break;
  case 5:
    result = fmax(z * (qs1 - X1), z * (X2 - qs2));
    break;
  case 6:
    result = z * (qs1 + qs2) - z * X1;
    break;
  case 7:
    result = qs1 - qs2;
    break;
  default:
    abort();
  }
  result = fmax(0.0, result);
  return result;
}


x86 assembly (clang, -O0):
<PayoffFunction>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  %xmm4,-0x30(%rbp)
movsd  %xmm5,-0x38(%rbp)
cmpl   $0x1,-0x4(%rbp)
setge  %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
cmpl   $0x7,-0x4(%rbp)
setle  %al
and    $0x1,%al
movzbl %al,%edi
call   1040 <assert@plt>
cmpl   $0x0,-0x8(%rbp)
je     118a <PayoffFunction+0x6a>
movsd  0xe88(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
jmp    1197 <PayoffFunction+0x77>
movsd  0xe6e(%rip),%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x20(%rbp),%xmm0
movsd  -0x10(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x50(%rbp)
mov    -0x4(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,%ecx
mov    %rcx,-0x60(%rbp)
sub    $0x6,%eax
ja     13da <PayoffFunction+0x2ba>
mov    -0x60(%rbp),%rax
lea    0xe33(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movsd  -0x40(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
subsd  -0x50(%rbp),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
movsd  -0x40(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm4
movsd  -0x50(%rbp),%xmm3
movaps %xmm3,%xmm5
movaps %xmm4,%xmm2
cmpunordsd %xmm2,%xmm2
movaps %xmm2,%xmm1
pand   %xmm5,%xmm1
maxsd  %xmm4,%xmm3
pandn  %xmm3,%xmm2
por    %xmm1,%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
movsd  -0x40(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm4
movsd  -0x50(%rbp),%xmm3
movaps %xmm3,%xmm5
movaps %xmm4,%xmm2
cmpunordsd %xmm2,%xmm2
movaps %xmm2,%xmm1
pand   %xmm5,%xmm1
minsd  %xmm4,%xmm3
pandn  %xmm3,%xmm2
por    %xmm1,%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
movsd  -0x40(%rbp),%xmm3
movsd  -0x48(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
mulsd  %xmm0,%xmm3
movsd  -0x40(%rbp),%xmm2
movsd  -0x50(%rbp),%xmm0
subsd  -0x38(%rbp),%xmm0
mulsd  %xmm0,%xmm2
movaps %xmm2,%xmm4
movaps %xmm3,%xmm0
cmpunordsd %xmm0,%xmm0
movaps %xmm0,%xmm1
pand   %xmm4,%xmm1
maxsd  %xmm3,%xmm2
pandn  %xmm2,%xmm0
por    %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
movsd  -0x40(%rbp),%xmm3
movsd  -0x48(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
mulsd  %xmm0,%xmm3
movsd  -0x40(%rbp),%xmm2
movsd  -0x38(%rbp),%xmm0
subsd  -0x50(%rbp),%xmm0
mulsd  %xmm0,%xmm2
movaps %xmm2,%xmm4
movaps %xmm3,%xmm0
cmpunordsd %xmm0,%xmm0
movaps %xmm0,%xmm1
pand   %xmm4,%xmm1
maxsd  %xmm3,%xmm2
pandn  %xmm2,%xmm0
por    %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
movsd  -0x40(%rbp),%xmm0
movsd  -0x48(%rbp),%xmm2
addsd  -0x50(%rbp),%xmm2
movsd  -0x40(%rbp),%xmm1
mulsd  -0x30(%rbp),%xmm1
movq   %xmm1,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm1
mulsd  %xmm2,%xmm0
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
movsd  -0x48(%rbp),%xmm0
subsd  -0x50(%rbp),%xmm0
movsd  %xmm0,-0x58(%rbp)
jmp    13e1 <PayoffFunction+0x2c1>
mov    $0x0,%al
call   1030 <abort@plt>
movsd  -0x58(%rbp),%xmm0
xorps  %xmm1,%xmm1
maxsd  %xmm1,%xmm0
movsd  %xmm0,-0x58(%rbp)
movsd  -0x58(%rbp),%xmm0
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<PayoffFunction>:
push   %rbp
push   %r14
push   %rbx
sub    $0x40,%rsp
movapd %xmm5,0x20(%rsp)
movsd  %xmm4,(%rsp)
movsd  %xmm3,0x10(%rsp)
movsd  %xmm2,0x8(%rsp)
movapd %xmm1,0x30(%rsp)
movsd  %xmm0,0x18(%rsp)
mov    %edi,%ebx
xor    %r14d,%r14d
test   %esi,%esi
sete   %bpl
xor    %edi,%edi
test   %ebx,%ebx
setg   %dil
call   1040 <assert@plt>
xor    %edi,%edi
cmp    $0x8,%ebx
setl   %dil
call   1040 <assert@plt>
add    $0xffffffff,%ebx
cmp    $0x6,%ebx
ja     12a0 <PayoffFunction+0x180>
mov    %bpl,%r14b
lea    0xe79(%rip),%rax
movsd  (%rax,%r14,8),%xmm3
movsd  0x18(%rsp),%xmm0
mulsd  0x8(%rsp),%xmm0
movapd 0x30(%rsp),%xmm4
mulsd  0x10(%rsp),%xmm4
lea    0xe64(%rip),%rax
movslq (%rax,%rbx,4),%rcx
add    %rax,%rcx
jmp    *%rcx
subsd  %xmm4,%xmm0
jmp    1278 <PayoffFunction+0x158>
movapd %xmm0,%xmm1
cmpunordsd %xmm0,%xmm1
movapd %xmm1,%xmm2
andpd  %xmm4,%xmm2
maxsd  %xmm0,%xmm4
jmp    11ea <PayoffFunction+0xca>
movapd %xmm0,%xmm1
cmpunordsd %xmm0,%xmm1
movapd %xmm1,%xmm2
andpd  %xmm4,%xmm2
minsd  %xmm0,%xmm4
andnpd %xmm4,%xmm1
orpd   %xmm2,%xmm1
movsd  (%rsp),%xmm0
mulsd  %xmm3,%xmm0
mulsd  %xmm3,%xmm1
subsd  %xmm0,%xmm1
movapd %xmm1,%xmm0
jmp    128f <PayoffFunction+0x16f>
subsd  (%rsp),%xmm0
mulsd  %xmm3,%xmm0
subsd  0x20(%rsp),%xmm4
mulsd  %xmm3,%xmm4
movapd %xmm0,%xmm2
cmpunordsd %xmm0,%xmm2
movapd %xmm2,%xmm1
andpd  %xmm4,%xmm1
maxsd  %xmm0,%xmm4
andnpd %xmm4,%xmm2
jmp    126a <PayoffFunction+0x14a>
subsd  (%rsp),%xmm0
mulsd  %xmm3,%xmm0
movapd 0x20(%rsp),%xmm5
subsd  %xmm4,%xmm5
mulsd  %xmm3,%xmm5
movapd %xmm0,%xmm2
cmpunordsd %xmm0,%xmm2
movapd %xmm2,%xmm1
andpd  %xmm5,%xmm1
maxsd  %xmm0,%xmm5
andnpd %xmm5,%xmm2
orpd   %xmm1,%xmm2
movapd %xmm2,%xmm0
jmp    128f <PayoffFunction+0x16f>
addsd  %xmm4,%xmm0
movsd  (%rsp),%xmm1
mulsd  %xmm3,%xmm1
mulsd  %xmm3,%xmm0
subsd  %xmm1,%xmm0
jmp    128f <PayoffFunction+0x16f>
subsd  %xmm4,%xmm0
xorpd  %xmm1,%xmm1
maxsd  %xmm1,%xmm0
add    $0x40,%rsp
pop    %rbx
pop    %r14
pop    %rbp
ret
xor    %eax,%eax
call   1030 <abort@plt>

LLVM IR (-O0):
define double @PayoffFunction(i32 %0, i32 %1, double %2, double %3, double %4, double %5, double %6, double %7) {
%9 = alloca i32
%10 = alloca i32
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca double
%18 = alloca double
%19 = alloca double
%20 = alloca double
store i32 %0, i32* %9
store i32 %1, i32* %10
store double %2, double* %11
store double %3, double* %12
store double %4, double* %13
store double %5, double* %14
store double %6, double* %15
store double %7, double* %16
%21 = load i32, i32* %9
%22 = icmp sge i32 %21, 1
%23 = zext i1 %22 to i32
%24 = call i32 @assert(i32 %23)
%25 = load i32, i32* %9
%26 = icmp sle i32 %25, 7
%27 = zext i1 %26 to i32
%28 = call i32 @assert(i32 %27)
%29 = load i32, i32* %10
%30 = icmp ne i32 %29, 0
br i1 %30, label %31, label %32
31: ; preds = %8
store double 1.000000e+00, double* %17
br label %33
32: ; preds = %8
store double -1.000000e+00, double* %17
br label %33
33: ; preds = %32, %31
%34 = load double, double* %13
%35 = load double, double* %11
%36 = fmul double %34, %35
store double %36, double* %18
%37 = load double, double* %14
%38 = load double, double* %12
%39 = fmul double %37, %38
store double %39, double* %19
%40 = load i32, i32* %9
switch i32 %40, label %109 [
i32 1, label %41
i32 2, label %51
i32 3, label %61
i32 4, label %71
i32 5, label %83
i32 6, label %95
i32 7, label %105
]
41: ; preds = %33
%42 = load double, double* %17
%43 = load double, double* %18
%44 = load double, double* %19
%45 = fsub double %43, %44
%46 = load double, double* %17
%47 = load double, double* %15
%48 = fmul double %46, %47
%49 = fneg double %48
%50 = call double @llvm.fmuladd.f64(double %42, double %45, double %49)
store double %50, double* %20
br label %111
51: ; preds = %33
%52 = load double, double* %17
%53 = load double, double* %18
%54 = load double, double* %19
%55 = call double @llvm.maxnum.f64(double %53, double %54)
%56 = load double, double* %17
%57 = load double, double* %15
%58 = fmul double %56, %57
%59 = fneg double %58
%60 = call double @llvm.fmuladd.f64(double %52, double %55, double %59)
store double %60, double* %20
br label %111
61: ; preds = %33
%62 = load double, double* %17
%63 = load double, double* %18
%64 = load double, double* %19
%65 = call double @llvm.minnum.f64(double %63, double %64)
%66 = load double, double* %17
%67 = load double, double* %15
%68 = fmul double %66, %67
%69 = fneg double %68
%70 = call double @llvm.fmuladd.f64(double %62, double %65, double %69)
store double %70, double* %20
br label %111
71: ; preds = %33
%72 = load double, double* %17
%73 = load double, double* %18
%74 = load double, double* %15
%75 = fsub double %73, %74
%76 = fmul double %72, %75
%77 = load double, double* %17
%78 = load double, double* %19
%79 = load double, double* %16
%80 = fsub double %78, %79
%81 = fmul double %77, %80
%82 = call double @llvm.maxnum.f64(double %76, double %81)
store double %82, double* %20
br label %111
83: ; preds = %33
%84 = load double, double* %17
%85 = load double, double* %18
%86 = load double, double* %15
%87 = fsub double %85, %86
%88 = fmul double %84, %87
%89 = load double, double* %17
%90 = load double, double* %16
%91 = load double, double* %19
%92 = fsub double %90, %91
%93 = fmul double %89, %92
%94 = call double @llvm.maxnum.f64(double %88, double %93)
store double %94, double* %20
br label %111
95: ; preds = %33
%96 = load double, double* %17
%97 = load double, double* %18
%98 = load double, double* %19
%99 = fadd double %97, %98
%100 = load double, double* %17
%101 = load double, double* %15
%102 = fmul double %100, %101
%103 = fneg double %102
%104 = call double @llvm.fmuladd.f64(double %96, double %99, double %103)
store double %104, double* %20
br label %111
105: ; preds = %33
%106 = load double, double* %18
%107 = load double, double* %19
%108 = fsub double %106, %107
store double %108, double* %20
br label %111
109: ; preds = %33
%110 = call i32 (...) @abort()
unreachable
111: ; preds = %105, %95, %83, %71, %61, %51, %41
%112 = load double, double* %20
%113 = call double @llvm.maxnum.f64(double 0.000000e+00, double %112)
store double %113, double* %20
%114 = load double, double* %20
ret double %114
}

LLVM IR (-O2):
define double @PayoffFunction(i32 %0, i32 %1, double %2, double %3, double %4, double %5, double %6, double %7) {
%9 = icmp sgt i32 %0, 0
%10 = zext i1 %9 to i32
%11 = tail call i32 @assert(i32 %10)
%12 = icmp slt i32 %0, 8
%13 = zext i1 %12 to i32
%14 = tail call i32 @assert(i32 %13)
%15 = icmp eq i32 %1, 0
%16 = select i1 %15, double -1.000000e+00, double 1.000000e+00
%17 = fmul double %2, %4
%18 = fmul double %3, %5
switch i32 %0, label %53 [
i32 1, label %19
i32 2, label %24
i32 3, label %29
i32 4, label %34
i32 5, label %40
i32 6, label %46
i32 7, label %51
]
19: ; preds = %8
%20 = fsub double %17, %18
%21 = fneg double %16
%22 = fmul double %21, %6
%23 = tail call double @llvm.fmuladd.f64(double %16, double %20, double %22)
br label %55
24: ; preds = %8
%25 = tail call double @llvm.maxnum.f64(double %17, double %18)
%26 = fneg double %16
%27 = fmul double %26, %6
%28 = tail call double @llvm.fmuladd.f64(double %16, double %25, double %27)
br label %55
29: ; preds = %8
%30 = tail call double @llvm.minnum.f64(double %17, double %18)
%31 = fneg double %16
%32 = fmul double %31, %6
%33 = tail call double @llvm.fmuladd.f64(double %16, double %30, double %32)
br label %55
34: ; preds = %8
%35 = fsub double %17, %6
%36 = fmul double %16, %35
%37 = fsub double %18, %7
%38 = fmul double %16, %37
%39 = tail call double @llvm.maxnum.f64(double %36, double %38)
br label %55
40: ; preds = %8
%41 = fsub double %17, %6
%42 = fmul double %16, %41
%43 = fsub double %7, %18
%44 = fmul double %16, %43
%45 = tail call double @llvm.maxnum.f64(double %42, double %44)
br label %55
46: ; preds = %8
%47 = fadd double %17, %18
%48 = fneg double %16
%49 = fmul double %48, %6
%50 = tail call double @llvm.fmuladd.f64(double %16, double %47, double %49)
br label %55
51: ; preds = %8
%52 = fsub double %17, %18
br label %55
53: ; preds = %8
%54 = tail call i32 (...) @abort()
unreachable
55: ; preds = %51, %46, %40, %34, %29, %24, %19
%56 = phi double [ %52, %51 ], [ %50, %46 ], [ %45, %40 ], [ %39, %34 ], [ %33, %29 ], [ %28, %24 ], [ %23, %19 ]
%57 = tail call double @llvm.maxnum.f64(double %56, double 0.000000e+00)
ret double %57
}