blob: 8e1eb7c3fa9ab63d86ca81ebcc8ebced5baae9eb [file] [log] [blame] [edit]
// RUN: %clang -std=c11 -ffast-math -O0 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O1 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O0 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O1 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli -
// RUN: %clang -std=c11 -ffast-math -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli -
#include "../test_utils.h"
__attribute__((always_inline))
inline void doA(double x[2])
{
double t;
t = 4*__builtin_cos(x[0] + x[1]);
x[0] = 3*__builtin_sin(2*x[0] + x[1]);
x[1] = t;
}
__attribute__((always_inline))
inline void doB(double x[2])
{
double t;
t = 4*__builtin_sin(2*x[0] + x[1]);
x[0] = 4*__builtin_cos(x[0] + 2*x[1]);
x[1] = t;
}
// for input x = {0.9, 0.7}
void fcheck(double x[2])
{
doA(x);
doA(x);
doB(x);
doB(x);
doA(x);
doB(x);
}
void f(double x[2])
{
A: doA(x);
if (x[0]*x[0] < x[1])
return;
else if (x[0] > 0)
goto A;
else
goto B;
B: doB(x);
if (x[0]*x[0] < x[1])
return;
else if (x[0] > 0)
goto A;
else
goto B;
}
extern void* __enzyme_augmentfwd(void*, double*, double*);
extern void __enzyme_reverse(void*, double*, double*, void*);
extern void __enzyme_autodiff(void*, double*, double*);
int main()
{
double x[2], x_b[2], y[2], y_b[2];
x[0] = y[0] = 0.9;
x[1] = y[1] = 0.7;
x_b[0] = y_b[0] = 1;
x_b[1] = y_b[1] = 2;
void* tape = __enzyme_augmentfwd((void*)f, x, x_b);
__enzyme_reverse((void*)f, x, x_b, tape);
__enzyme_autodiff((void*)fcheck, y, y_b);
APPROX_EQ(x[0], y[0], 1e-10);
APPROX_EQ(x[1], y[1], 1e-10);
APPROX_EQ(x_b[0], y_b[0], 1e-10);
APPROX_EQ(x_b[1], y_b[1], 1e-10);
}