| // RUN: %clang -O0 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - | |
| // RUN: %clang -O1 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - | |
| // RUN: %clang -O1 -g %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - | |
| // RUN: %clang -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - | |
| // RUN: %clang -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -S | %lli - | |
| // RUN: %clang -O0 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - | |
| // RUN: %clang -O1 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - | |
| // RUN: %clang -O2 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - | |
| // RUN: %clang -O3 %s -S -emit-llvm -o - | %opt - %OPloadEnzyme %enzyme -enzyme-inline=1 -S | %lli - | |
| #include <stdio.h> | |
| #include "../test_utils.h" | |
| extern void __enzyme_batch(void *, int, int, char *, char *, char *, char *); | |
| extern int enzyme_dup; | |
| extern int enzyme_width; | |
| #pragma pack(1) | |
| struct Foo { | |
| int arr[3]; | |
| double x; | |
| float y; | |
| double res; | |
| }; | |
| void f(char *foo) { | |
| double *xptr = (double *)(foo + sizeof(int[3])); | |
| float *yptr = (float *)(foo + sizeof(int[3]) + sizeof(double)); | |
| double *resptr = | |
| (double *)(foo + sizeof(int[3]) + sizeof(double) + sizeof(float)); | |
| double x = *xptr; | |
| float y = *yptr; | |
| *resptr = x * y; | |
| } | |
| void df(char *dfoo1, char *dfoo2, char *dfoo3, char *dfoo4) { | |
| __enzyme_batch((void *)f, enzyme_width, 4, dfoo1, dfoo2, dfoo3, dfoo4); | |
| } | |
| int main() { | |
| Foo foo1; | |
| foo1.x = 10; | |
| foo1.y = 9.0; | |
| Foo foo2; | |
| foo2.x = 99.0; | |
| foo2.y = 7.0; | |
| Foo foo3; | |
| foo3.x = 1.1; | |
| foo3.y = 9.0; | |
| Foo foo4; | |
| foo4.x = 3.14; | |
| foo4.y = 0.1; | |
| double expected[4] = {90.0, 693.0, 9.9, 0.314}; | |
| df((char *)&foo1, (char *)&foo2, (char *)&foo3, (char *)&foo4); | |
| APPROX_EQ(foo1.res, expected[0], 1e-9); | |
| APPROX_EQ(foo2.res, expected[1], 1e-9); | |
| APPROX_EQ(foo3.res, expected[2], 1e-9); | |
| APPROX_EQ(foo4.res, expected[3], 1e-8); | |
| } |