#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 */
double cos(double);
double exp(double);
double sin(double);
double c_y(double x, double y, int I) {
  double speed;
  if (I == 2) {
    speed = -0.8 * exp(-10.0 * (y - 0.3) * (y - 0.3)) *
            exp(-20.0 * (x - 0.25) * (x - 0.25));
    speed = -0.4 - 20.0 * speed * (y - 0.3);
    return (speed);
  } else if (I == 1) {
    if (y < 0 || y > 1)
      return (0.0);
    else
      return (3.141592 * cos(3.141592 * (y - 0.5)) * sin(3.141592 * (y - 0.5)));
  }
  return (0);
}


x86 assembly (clang, -O0):
<c_y>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
mov    %edi,-0x1c(%rbp)
cmpl   $0x2,-0x1c(%rbp)
jne    123b <c_y+0x10b>
movsd  -0x18(%rbp),%xmm1
movsd  0xec4(%rip),%xmm0
subsd  %xmm0,%xmm1
movsd  0xee0(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  0xea7(%rip),%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
call   1040 <exp@plt>
movaps %xmm0,%xmm1
movsd  0xeaf(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x30(%rbp)
movsd  -0x10(%rbp),%xmm1
movsd  0xe89(%rip),%xmm0
subsd  %xmm0,%xmm1
movsd  0xe85(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  -0x10(%rbp),%xmm1
movsd  0xe6c(%rip),%xmm2
subsd  %xmm2,%xmm1
mulsd  %xmm1,%xmm0
call   1040 <exp@plt>
movaps %xmm0,%xmm1
movsd  -0x30(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  0xe3e(%rip),%xmm0
mulsd  -0x28(%rbp),%xmm0
movsd  -0x18(%rbp),%xmm1
movsd  0xe24(%rip),%xmm2
subsd  %xmm2,%xmm1
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
mulsd  %xmm1,%xmm0
movsd  0xdf5(%rip),%xmm1
addsd  %xmm1,%xmm0
movsd  %xmm0,-0x28(%rbp)
movsd  -0x28(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f2 <c_y+0x1c2>
cmpl   $0x1,-0x1c(%rbp)
jne    12e5 <c_y+0x1b5>
xorps  %xmm0,%xmm0
ucomisd -0x18(%rbp),%xmm0
ja     126a <c_y+0x13a>
movsd  -0x18(%rbp),%xmm0
movsd  0xda0(%rip),%xmm1
ucomisd %xmm1,%xmm0
jbe    1277 <c_y+0x147>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f2 <c_y+0x1c2>
movsd  -0x18(%rbp),%xmm1
movsd  0xd8c(%rip),%xmm0
subsd  %xmm0,%xmm1
movsd  0xd78(%rip),%xmm0
mulsd  %xmm1,%xmm0
call   1050 <cos@plt>
movaps %xmm0,%xmm1
movsd  0xd64(%rip),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x18(%rbp),%xmm1
movsd  0xd56(%rip),%xmm0
subsd  %xmm0,%xmm1
movsd  0xd42(%rip),%xmm0
mulsd  %xmm1,%xmm0
call   1030 <sin@plt>
movaps %xmm0,%xmm1
movsd  -0x38(%rbp),%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    12f2 <c_y+0x1c2>
jmp    12ea <c_y+0x1ba>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<c_y>:
sub    $0x18,%rsp
cmp    $0x1,%edi
je     11c7 <c_y+0x97>
movapd %xmm0,%xmm2
xorpd  %xmm0,%xmm0
cmp    $0x2,%edi
jne    1217 <c_y+0xe7>
addsd  0xec2(%rip),%xmm1
movsd  %xmm1,0x8(%rsp)
movsd  0xebc(%rip),%xmm0
mulsd  %xmm1,%xmm0
mulsd  %xmm1,%xmm0
movsd  %xmm2,0x10(%rsp)
call   1040 <exp@plt>
mulsd  0xea9(%rip),%xmm0
movsd  %xmm0,(%rsp)
movsd  0x10(%rsp),%xmm2
addsd  0xe9e(%rip),%xmm2
movapd %xmm2,%xmm0
mulsd  0xe9a(%rip),%xmm0
mulsd  %xmm2,%xmm0
call   1040 <exp@plt>
mulsd  (%rsp),%xmm0
mulsd  0xe84(%rip),%xmm0
mulsd  0x8(%rsp),%xmm0
addsd  0xe7e(%rip),%xmm0
add    $0x18,%rsp
ret
xorpd  %xmm0,%xmm0
ucomisd %xmm1,%xmm0
ja     1217 <c_y+0xe7>
ucomisd 0xe27(%rip),%xmm1
ja     1217 <c_y+0xe7>
addsd  0xe25(%rip),%xmm1
mulsd  0xe25(%rip),%xmm1
movsd  %xmm1,0x8(%rsp)
movapd %xmm1,%xmm0
call   1050 <cos@plt>
mulsd  0xe0e(%rip),%xmm0
movsd  %xmm0,(%rsp)
movsd  0x8(%rsp),%xmm0
call   1030 <sin@plt>
mulsd  (%rsp),%xmm0
add    $0x18,%rsp
ret

LLVM IR (-O0):
define double @c_y(double %0, double %1, i32 %2) {
%4 = alloca double
%5 = alloca double
%6 = alloca double
%7 = alloca i32
%8 = alloca double
store double %0, double* %5
store double %1, double* %6
store i32 %2, i32* %7
%9 = load i32, i32* %7
%10 = icmp eq i32 %9, 2
br i1 %10, label %11, label %35
11: ; preds = %3
%12 = load double, double* %6
%13 = fsub double %12, 3.000000e-01
%14 = fmul double -1.000000e+01, %13
%15 = load double, double* %6
%16 = fsub double %15, 3.000000e-01
%17 = fmul double %14, %16
%18 = call double @exp(double %17)
%19 = fmul double -8.000000e-01, %18
%20 = load double, double* %5
%21 = fsub double %20, 2.500000e-01
%22 = fmul double -2.000000e+01, %21
%23 = load double, double* %5
%24 = fsub double %23, 2.500000e-01
%25 = fmul double %22, %24
%26 = call double @exp(double %25)
%27 = fmul double %19, %26
store double %27, double* %8
%28 = load double, double* %8
%29 = fmul double 2.000000e+01, %28
%30 = load double, double* %6
%31 = fsub double %30, 3.000000e-01
%32 = fneg double %29
%33 = call double @llvm.fmuladd.f64(double %32, double %31, double -4.000000e-01)
store double %33, double* %8
%34 = load double, double* %8
store double %34, double* %4
br label %58
35: ; preds = %3
%36 = load i32, i32* %7
%37 = icmp eq i32 %36, 1
br i1 %37, label %38, label %56
38: ; preds = %35
%39 = load double, double* %6
%40 = fcmp olt double %39, 0.000000e+00
br i1 %40, label %44, label %41
41: ; preds = %38
%42 = load double, double* %6
%43 = fcmp ogt double %42, 1.000000e+00
br i1 %43, label %44, label %45
44: ; preds = %41, %38
store double 0.000000e+00, double* %4
br label %58
45: ; preds = %41
%46 = load double, double* %6
%47 = fsub double %46, 5.000000e-01
%48 = fmul double 0x400921FAFC8B007A, %47
%49 = call double @cos(double %48)
%50 = fmul double 0x400921FAFC8B007A, %49
%51 = load double, double* %6
%52 = fsub double %51, 5.000000e-01
%53 = fmul double 0x400921FAFC8B007A, %52
%54 = call double @sin(double %53)
%55 = fmul double %50, %54
store double %55, double* %4
br label %58
56: ; preds = %35
br label %57
57: ; preds = %56
store double 0.000000e+00, double* %4
br label %58
58: ; preds = %57, %45, %44, %11
%59 = load double, double* %4
ret double %59
}

LLVM IR (-O2):
define double @c_y(double %0, double %1, i32 %2) {
switch i32 %2, label %28 [
i32 2, label %4
i32 1, label %17
]
4: ; preds = %3
%5 = fadd double %1, -3.000000e-01
%6 = fmul double %5, -1.000000e+01
%7 = fmul double %5, %6
%8 = tail call double @exp(double %7)
%9 = fmul double %8, -8.000000e-01
%10 = fadd double %0, -2.500000e-01
%11 = fmul double %10, -2.000000e+01
%12 = fmul double %10, %11
%13 = tail call double @exp(double %12)
%14 = fmul double %9, %13
%15 = fmul double %14, -2.000000e+01
%16 = tail call double @llvm.fmuladd.f64(double %15, double %5, double -4.000000e-01)
br label %28
17: ; preds = %3
%18 = fcmp olt double %1, 0.000000e+00
%19 = fcmp ogt double %1, 1.000000e+00
%20 = or i1 %18, %19
br i1 %20, label %28, label %21
21: ; preds = %17
%22 = fadd double %1, -5.000000e-01
%23 = fmul double %22, 0x400921FAFC8B007A
%24 = tail call double @cos(double %23)
%25 = fmul double %24, 0x400921FAFC8B007A
%26 = tail call double @sin(double %23)
%27 = fmul double %25, %26
br label %28
28: ; preds = %3, %17, %21, %4
%29 = phi double [ %16, %4 ], [ %27, %21 ], [ 0.000000e+00, %17 ], [ 0.000000e+00, %3 ]
ret double %29
}