blob: c9a828301c67d935abead3ed703993f1c20ca009 [file] [log] [blame]
#include <functional>
#include <iostream>
#include <limits>
#include <memory>
#include <random>
#include <stdint.h>
// Tests for vectorizing loops with recurrences.
static std::mt19937 rng;
// Initialize arrays A with random numbers.
template <typename Ty>
static void init_data(const std::unique_ptr<Ty[]> &A, unsigned N) {
std::uniform_int_distribution<uint64_t> distrib(
std::numeric_limits<Ty>::min(), std::numeric_limits<Ty>::max());
for (unsigned i = 0; i < N; i++)
A[i] = distrib(rng);
}
template <typename Ty>
static void check(const std::unique_ptr<Ty[]> &Reference,
const std::unique_ptr<Ty[]> &Tmp, unsigned NumElements) {
if (!std::equal(&Reference[0], &Reference[0] + NumElements, &Tmp[0])) {
std::cerr << "Miscompare\n";
exit(1);
}
}
#define DEFINE_SCALAR_AND_VECTOR_FN2(Init, Loop) \
auto ScalarFn = [](auto *A, auto *B, unsigned TC) { \
Init _Pragma("clang loop vectorize(disable)") Loop \
}; \
auto VectorFn = [](auto *A, auto *B, unsigned TC) { \
Init _Pragma("clang loop vectorize(enable)") Loop \
};
template <typename Ty> using Fn2Ty = std::function<void(Ty *, Ty *, unsigned)>;
template <typename Ty>
static void checkVectorFunction(Fn2Ty<Ty> ScalarFn, Fn2Ty<Ty> VectorFn,
const char *Name) {
std::cout << "Checking " << Name << "\n";
unsigned N = 1000;
std::unique_ptr<Ty[]> Src1(new Ty[N]);
init_data(Src1, N);
std::unique_ptr<Ty[]> Src2(new Ty[N]);
for (unsigned I = 0; I < N; ++I)
Src2[I] = Src1[I];
std::unique_ptr<Ty[]> Reference(new Ty[N]);
std::unique_ptr<Ty[]> ToCheck(new Ty[N]);
ScalarFn(&Src1[0], &Reference[0], N);
VectorFn(&Src2[0], &ToCheck[0], N);
check(Reference, ToCheck, N);
}
int main(void) {
rng = std::mt19937(15);
{
DEFINE_SCALAR_AND_VECTOR_FN2(
int for1 = 33;,
for (unsigned I = 0; I < TC; I++) {
B[I] = for1 + I;
for1 = I;
});
checkVectorFunction<uint32_t>(ScalarFn, VectorFn, "first_order_recurrence");
}
{
DEFINE_SCALAR_AND_VECTOR_FN2(
int for2 = 22; int for1 = 33;,
for (unsigned I = 0; I < TC; I++) {
int t1 = for1;
int t2 = for2;
for2 = for1;
for1 = A[I];
B[I] = t1 + t2;
});
checkVectorFunction<uint32_t>(ScalarFn, VectorFn,
"second_order_recurrence");
}
{
DEFINE_SCALAR_AND_VECTOR_FN2(
int for1 = 33; int for2 = 22; int for3 = 11;,
for (unsigned I = 0; I < TC; I++) {
int t1 = for1;
int t2 = for2;
int t3 = for3;
for3 = for2;
for2 = for1;
for1 = A[I];
B[I] = t1 + t2 + t3;
});
checkVectorFunction<uint32_t>(ScalarFn, VectorFn, "third_order_recurrence");
}
return 0;
}