[SingleSource] Add initial vectorizer tests with recurrences.
This patch adds dedicated test coverage for multi order
recurrences. D119661 will add support for vectorizing the second and
third order tests.
Reviewed By: Meinersbur
Differential Revision: https://reviews.llvm.org/D129339
diff --git a/SingleSource/UnitTests/Vectorizer/recurrences.cpp b/SingleSource/UnitTests/Vectorizer/recurrences.cpp
new file mode 100644
index 0000000..c9a8283
--- /dev/null
+++ b/SingleSource/UnitTests/Vectorizer/recurrences.cpp
@@ -0,0 +1,102 @@
+#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;
+}
diff --git a/SingleSource/UnitTests/Vectorizer/recurrences.reference_output b/SingleSource/UnitTests/Vectorizer/recurrences.reference_output
new file mode 100644
index 0000000..0a86289
--- /dev/null
+++ b/SingleSource/UnitTests/Vectorizer/recurrences.reference_output
@@ -0,0 +1,4 @@
+Checking first_order_recurrence
+Checking second_order_recurrence
+Checking third_order_recurrence
+exit 0