[llvm-commits] [test-suite] r168836 - in /test-suite/trunk/SingleSource/UnitTests: Makefile Vectorizer/ Vectorizer/Makefile Vectorizer/gcc-loops.cpp Vectorizer/gcc-loops.reference_output
Nadav Rotem
nrotem at apple.com
Wed Nov 28 16:23:02 PST 2012
Author: nadav
Date: Wed Nov 28 18:23:02 2012
New Revision: 168836
URL: http://llvm.org/viewvc/llvm-project?rev=168836&view=rev
Log:
Add unit tests to verify the vectorizers.
The tests are loops from the GCC vectorizer example page [1].
Dorit Nuzman said that we can use them.
[1] - http://gcc.gnu.org/projects/tree-ssa/vectorization.html
Added:
test-suite/trunk/SingleSource/UnitTests/Vectorizer/
test-suite/trunk/SingleSource/UnitTests/Vectorizer/Makefile
test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.cpp
test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.reference_output
Modified:
test-suite/trunk/SingleSource/UnitTests/Makefile
Modified: test-suite/trunk/SingleSource/UnitTests/Makefile
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Makefile?rev=168836&r1=168835&r2=168836&view=diff
==============================================================================
--- test-suite/trunk/SingleSource/UnitTests/Makefile (original)
+++ test-suite/trunk/SingleSource/UnitTests/Makefile Wed Nov 28 18:23:02 2012
@@ -8,6 +8,7 @@
DIRS :=
DIRS += Vector
+DIRS += Vectorizer
DIRS += SignlessTypes Threads
Added: test-suite/trunk/SingleSource/UnitTests/Vectorizer/Makefile
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vectorizer/Makefile?rev=168836&view=auto
==============================================================================
--- test-suite/trunk/SingleSource/UnitTests/Vectorizer/Makefile (added)
+++ test-suite/trunk/SingleSource/UnitTests/Vectorizer/Makefile Wed Nov 28 18:23:02 2012
@@ -0,0 +1,9 @@
+# SingleSource/UnitTests/Vectorizer/Makefile
+LEVEL = ../../..
+
+include $(LEVEL)/Makefile.config
+
+
+include $(LEVEL)/SingleSource/Makefile.singlesrc
+
+
Added: test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.cpp
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.cpp?rev=168836&view=auto
==============================================================================
--- test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.cpp (added)
+++ test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.cpp Wed Nov 28 18:23:02 2012
@@ -0,0 +1,394 @@
+#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <iostream>
+#include <vector>
+#include <numeric>
+
+/// This test contains some of the loops from the GCC vectrorizer example page [1].
+/// Dorit Nuzman who developed the gcc vectorizer said that we can use them in our test suite.
+///
+/// [1] - http://gcc.gnu.org/projects/tree-ssa/vectorization.html
+
+#define N 1024
+#define M 32
+#define K 4
+
+unsigned short usa[N];
+short sa[N];
+short sb[N];
+short sc[N];
+unsigned int ua[N];
+int ia[N];
+int ib[N];
+int ic[N];
+unsigned int ub[N];
+unsigned int uc[N];
+float fa[N], fb[N];
+float da[N], db[N], dc[N], dd[N];
+int dj[N];
+
+struct A {
+ int ca[N];
+} s;
+
+int a[N*2], b[N*2], c[N*2], d[N*2];
+
+__attribute__((noinline))
+void example1 () {
+ int i;
+
+ for (i=0; i<256; i++){
+ a[i] = b[i] + c[i];
+ }
+}
+
+__attribute__((noinline))
+void example2a (int n, int x) {
+ int i;
+
+ /* feature: support for unknown loop bound */
+ /* feature: support for loop invariants */
+ for (i=0; i<n; i++) {
+ b[i] = x;
+ }
+}
+
+__attribute__((noinline))
+void example2b (int n, int x) {
+ int i = 0;
+ /* feature: general loop exit condition */
+ /* feature: support for bitwise operations */
+ while (n--){
+ a[i] = b[i]&c[i]; i++;
+ }
+}
+
+
+typedef int aint __attribute__ ((__aligned__(16)));
+__attribute__((noinline))
+void example3 (int n, aint * __restrict__ p, aint * __restrict q) {
+
+ /* feature: support for (aligned) pointer accesses. */
+ while (n--){
+ *p++ = *q++;
+ }
+}
+
+__attribute__((noinline))
+void example4a (int n, aint * __restrict__ p, aint * __restrict__ q) {
+ int i;
+ const int MAX = 4;
+ /* feature: support for (aligned) pointer accesses */
+ /* feature: support for constants */
+ while (n--){
+ *p++ = *q++ + 5;
+ }
+}
+
+__attribute__((noinline))
+void example4b (int n, aint * __restrict__ p, aint * __restrict__ q) {
+ int i;
+ const int MAX = 4;
+
+ /* feature: support for read accesses with a compile time known misalignment */
+ for (i=0; i<n; i++){
+ a[i] = b[i+1] + c[i+3];
+ }
+}
+
+__attribute__((noinline))
+void example4c (int n, aint * __restrict__ p, aint * __restrict__ q) {
+ int i;
+ const int MAX = 4;
+ /* feature: support for if-conversion */
+ for (i=0; i<n; i++){
+ int j = a[i];
+ b[i] = (j > MAX ? MAX : 0);
+ }
+}
+
+__attribute__((noinline))
+void example5 (int n, struct A *s) {
+ int i;
+ for (i = 0; i < n; i++) {
+ /* feature: support for alignable struct access */
+ s->ca[i] = 5;
+ }
+}
+
+__attribute__((noinline))
+void example7 (int x) {
+ int i;
+
+ /* feature: support for read accesses with an unknown misalignment */
+ for (i=0; i<N; i++){
+ a[i] = b[i+x];
+ }
+}
+
+int G[M][N];
+__attribute__((noinline))
+void example8 (int x) {
+ int i,j;
+
+ /* feature: support for multidimensional arrays */
+ for (i=0; i<M; i++) {
+ for (j=0; j<N; j++) {
+ G[i][j] = x;
+ }
+ }
+}
+
+
+__attribute__((noinline))
+void example9 (unsigned *ret) {
+ int i;
+
+ /* feature: support summation reduction.
+ note: in case of floats use -funsafe-math-optimizations */
+ unsigned int diff = 0;
+ for (i = 0; i < N; i++) {
+ diff += (ub[i] - uc[i]);
+ }
+
+ *ret = diff;
+}
+
+
+/* feature: support data-types of different sizes.
+ Currently only a single vector-size per target is supported;
+ it can accommodate n elements such that n = vector-size/element-size
+ (e.g, 4 ints, 8 shorts, or 16 chars for a vector of size 16 bytes).
+ A combination of data-types of different sizes in the same loop
+ requires special handling. This support is now present in mainline,
+ and also includes support for type conversions. */
+__attribute__((noinline))
+void example10a(short *__restrict__ sa, short *__restrict__ sb, short *__restrict__ sc, int* __restrict__ ia, int* __restrict__ ib, int* __restrict__ ic) {
+ int i;
+ for (i = 0; i < N; i++) {
+ ia[i] = ib[i] + ic[i];
+ sa[i] = sb[i] + sc[i];
+ }
+}
+
+__attribute__((noinline))
+void example10b(short *__restrict__ sa, short *__restrict__ sb, short *__restrict__ sc, int* __restrict__ ia, int* __restrict__ ib, int* __restrict__ ic) {
+ int i;
+ for (i = 0; i < N; i++) {
+ ia[i] = (int) sb[i];
+ }
+}
+
+/* feature: support strided accesses - the data elements
+ that are to be operated upon in parallel are not consecutive - they
+ are accessed with a stride > 1 (in the example, the stride is 2): */
+__attribute__((noinline))
+void example11() {
+ int i;
+ for (i = 0; i < N/2; i++){
+ a[i] = b[2*i+1] * c[2*i+1] - b[2*i] * c[2*i];
+ d[i] = b[2*i] * c[2*i+1] + b[2*i+1] * c[2*i];
+ }
+}
+
+
+__attribute__((noinline))
+void example12() {
+ for (int i = 0; i < N; i++) {
+ a[i] = i;
+ }
+}
+
+__attribute__((noinline))
+void example13(int **A, int **B, int *out) {
+ int i,j;
+ for (i = 0; i < M; i++) {
+ int diff = 0;
+ for (j = 0; j < N; j+=8) {
+ diff += (A[i][j] - B[i][j]);
+ }
+ out[i] = diff;
+ }
+}
+
+__attribute__((noinline))
+void example14(int **in, int **coeff, int *out) {
+ int k,j,i=0;
+ for (k = 0; k < K; k++) {
+ int sum = 0;
+ for (j = 0; j < M; j++)
+ for (i = 0; i < N; i++)
+ sum += in[i+k][j] * coeff[i][j];
+
+ out[k] = sum;
+ }
+
+}
+
+
+__attribute__((noinline))
+int example21(int *b, int n)
+{
+ int i, a = 0;
+
+ for (i = n-1; i >= 0; i--)
+ a += b[i];
+
+ return a;
+}
+
+__attribute__((noinline))
+void example23 (unsigned short *src, unsigned int *dst)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ *dst++ = *src++ << 7;
+}
+
+
+__attribute__((noinline))
+void example24 (short x, short y)
+{
+ int i;
+ for (i = 0; i < N; i++)
+ ic[i] = fa[i] < fb[i] ? x : y;
+}
+
+
+__attribute__((noinline))
+void example25 (void)
+{
+ int i;
+ char x, y;
+ for (i = 0; i < N; i++)
+ {
+ x = (da[i] < db[i]);
+ y = (dc[i] < dd[i]);
+ dj[i] = x & y;
+ }
+}
+
+void init_memory(void *start, void* end) {
+ unsigned char state = 1;
+ while (start != end) {
+ state *= 7; state ^= 0x27; state += 1;
+ *((unsigned char*)start) = state;
+ start = ((char*)start) + 1;
+ }
+}
+
+void init_memory_float(float *start, float* end) {
+ float state = 1.0;
+ while (start != end) {
+ state *= 1.1;
+ *start = state;
+ start++;
+ }
+}
+
+unsigned digest_memory(void *start, void* end) {
+ unsigned state = 1;
+ while (start != end) {
+ state *= 3;
+ state ^= *((unsigned char*)start);
+ state = (state >> 8 ^ state << 8);
+ start = ((char*)start) + 1;
+ }
+ return state;
+}
+
+class Timer {
+
+public:
+ Timer(const char* title, bool print) {
+ Title = title;
+ Print = print;
+ gettimeofday(&Start, 0);
+ }
+
+ ~Timer() {
+ gettimeofday(&End, 0);
+ long mtime, s,us;
+ s = End.tv_sec - Start.tv_sec;
+ us = End.tv_usec - Start.tv_usec;
+ mtime = (s*1000 + us/1000.0)+0.5;
+ if (Print)
+ std::cout<<Title<<", "<<mtime<<", msec\n";
+ }
+
+private:
+ const char* Title;
+ bool Print;
+ struct timeval Start, End;
+};
+
+
+// Warmup and then measure.
+#define BENCH(NAME, RUN_LINE, ITER, DIGEST_LINE) {\
+ RUN_LINE;\
+ Timer atimer(NAME, print_times);\
+ for (int i=0; i < (ITER); ++i) RUN_LINE;\
+ unsigned r = DIGEST_LINE;\
+ results.push_back(r);\
+ }
+
+int main(int argc,char* argv[]){
+
+ bool print_times = argc > 1;
+
+ std::vector<unsigned> results;
+ unsigned dummy = 0;
+ const int Mi = 1<<20;
+ init_memory(&ia[0], &ia[N]);
+ init_memory(&ib[0], &ib[N]);
+ init_memory(&ic[0], &ic[N]);
+ init_memory(&sa[0], &sa[N]);
+ init_memory(&sb[0], &sb[N]);
+ init_memory(&sc[0], &sc[N]);
+ init_memory(&a[0], &a[N*2]);
+ init_memory(&b[0], &b[N*2]);
+ init_memory(&c[0], &c[N*2]);
+ init_memory(&ua[0], &ua[N]);
+ init_memory(&ub[0], &ub[N]);
+ init_memory(&uc[0], &uc[N]);
+ init_memory(&G[0][0], &G[0][N]);
+ init_memory_float(&fa[0], &fa[N]);
+ init_memory_float(&fb[0], &fb[N]);
+ init_memory_float(&da[0], &da[N]);
+ init_memory_float(&db[0], &db[N]);
+ init_memory_float(&dc[0], &dc[N]);
+ init_memory_float(&dd[0], &dd[N]);
+
+ BENCH("Example1", example1(), Mi*10, digest_memory(&a[0], &a[256]));
+ BENCH("Example2a", example2a(N, 2), Mi, digest_memory(&b[0], &b[N]));
+ BENCH("Example2b", example2b(N, 2), Mi, digest_memory(&a[0], &a[N]));
+ BENCH("Example3", example3(N, ia, ib), Mi, digest_memory(&ia[0], &ia[N]));
+ BENCH("Example4a", example4a(N, ia, ib), Mi, digest_memory(&ia[0], &ia[N]));
+ BENCH("Example4b", example4b(N-10, ia, ib), Mi, digest_memory(&ia[0], &ia[N]));
+ BENCH("Example4c", example4c(N, ia, ib), Mi, digest_memory(&ib[0], &ib[N]));
+ BENCH("Example7", example7(4), Mi, digest_memory(&a[0], &a[N]));
+ BENCH("Example8", example8(8), Mi/4, digest_memory(&G[0][0], &G[0][N]));
+ BENCH("Example9", example9(&dummy), Mi, dummy);
+ BENCH("Example10a", example10a(sa,sb,sc,ia,ib,ic), Mi, digest_memory(&ia[0], &ia[N]) + digest_memory(&sa[0], &sa[N]));
+ BENCH("Example10b", example10b(sa,sb,sc,ia,ib,ic), Mi*2, digest_memory(&ia[0], &ia[N]));
+ BENCH("Example11", example11(), Mi*2, digest_memory(&d[0], &d[N]));
+ BENCH("Example12", example12(), Mi*2, digest_memory(&a[0], &a[N]));
+ BENCH("Example23", example23(usa,ua), Mi*2, digest_memory(&usa[0], &usa[256]));
+ BENCH("Example24", example24(2,4), Mi*2, 0);
+ BENCH("Example25", example25(), Mi*2, digest_memory(&dj[0], &dj[N]));
+
+ std::cout<<std::hex;
+ std::cout<<"Results: ("<<std::accumulate(results.begin(), results.end(), 0)<<"):";
+ for (int i=0; i < results.size(); ++i) {
+ std::cout<<" "<<results[i];
+ }
+ std::cout<<"\n";
+
+ return 0;
+}
+
+
+
Added: test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.reference_output
URL: http://llvm.org/viewvc/llvm-project/test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.reference_output?rev=168836&view=auto
==============================================================================
--- test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.reference_output (added)
+++ test-suite/trunk/SingleSource/UnitTests/Vectorizer/gcc-loops.reference_output Wed Nov 28 18:23:02 2012
@@ -0,0 +1,2 @@
+Results: (7c5e742b): ed7aa26a b9b28d5b 67808d19 b4412829 132bc4c6 132bc4c6 b4412829 eb3492a9 7e51915b 0 61ffda0c f95b0406 495fecb4 ab6b4a02 bdaa178a 0 67808d19
+exit 0
More information about the llvm-commits
mailing list