1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
// 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);
}