tree-vectorizer.c: New File: loop vectorization on SSAed GIMPLE trees.
authorDorit Naishlos <dorit@il.ibm.com>
Tue, 17 Aug 2004 16:17:14 +0000 (16:17 +0000)
committerDorit Nuzman <dorit@gcc.gnu.org>
Tue, 17 Aug 2004 16:17:14 +0000 (16:17 +0000)
        * tree-vectorizer.c: New File: loop vectorization on SSAed GIMPLE trees.
        * tree-vectorizer.h: New File: Same.
        * Makefile.in (tree-vectorizer.c, tree-vectorizer.h): Add new files.
        * common.opt (ftree-vectorize): New flag to enable vectorization.
        * timevar.def (TV_TREE_VECTORIZATION): New dump file for vectorization
        pass.
        * tree-data-ref.h (init_data_ref): Additional argument.
        (array_base_name_differ_p): Moved to tree-data-ref.c.
        * tree-data-ref.c (array_base_name_differ_p): Revised.
        (initialize_data_dependence_relation): Call array_base_name_differ_p
        with an extra argument.
        (analyze_all_data_dependences): Same.
        (init_data_ref): Additional argument is_read to set DR_IS_READ.
        * tree-ssa-phiopt.c (empty_block_p): Expose for usage out of this file.
        * tree-flow.h (vectorize_loops, empty_block_p): Add declaration.
        * tree-optimize.c (pass_vectorize): Schedule the vectorization pass.
        * tree-pass.h (tree_opt_pass pass_vectorize): Declare the new
        vectorization pass.
        * tree-ssa-loop.c (tree_ssa_loop_init): Call scev_initialize.
        (tree_ssa_loop_done): Call scev_finalize.
        (tree_vectorize): Define the new vectorization pass.
        * defaults.h (UNITS_PER_SIMD_WORD): Allow targets to specify the size of
        the vector they support (until support for multiple vector sizes is
        added to the vectorizer).
        * config/i386/i386.h (UNITS_PER_SIMD_WORD): Define.
        * config/rs6000/rs6000.h (UNITS_PER_SIMD_WORD): Define.
        * invoke.texi (fdump-tree-vect, ftree-vectorize): Add
        documentation.

From-SVN: r86131

81 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/common.opt
gcc/defaults.h
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/vect/pr16105.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/tree-vect.h [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-16.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-17.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-18.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-19.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-20.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-21.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-22.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-23.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-24.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-25.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-26.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-27.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-28.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-29.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-30.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-31.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-32.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-33.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-34.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-35.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-36.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-37.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-38.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-40.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-41.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-42.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-43.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-44.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-45.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-46.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-47.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-48.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-49.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-50.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-51.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-52.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-53.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-54.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-55.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-56.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-57.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-58.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-59.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-60.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-61.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-all.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect-none.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/vect/vect.exp [new file with mode: 0644]
gcc/timevar.def
gcc/tree-data-ref.c
gcc/tree-data-ref.h
gcc/tree-flow.h
gcc/tree-optimize.c
gcc/tree-pass.h
gcc/tree-ssa-loop.c
gcc/tree-ssa-phiopt.c
gcc/tree-vectorizer.c [new file with mode: 0644]
gcc/tree-vectorizer.h [new file with mode: 0644]

index dd4cf89d3fc12a610c3ff03c75ac02e91536ee71..99a4aab4aa0dca8a6a8103f9d2b5f2ab02eaee43 100644 (file)
@@ -1,3 +1,34 @@
+2004-08-17  Dorit Naishlos  <dorit@il.ibm.com>
+
+       * tree-vectorizer.c: New File: loop vectorization on SSAed GIMPLE trees.
+       * tree-vectorizer.h: New File: Same.
+       * Makefile.in (tree-vectorizer.c, tree-vectorizer.h): Add new files.
+       * common.opt (ftree-vectorize): New flag to enable vectorization.
+       * timevar.def (TV_TREE_VECTORIZATION): New dump file for vectorization
+       pass.
+       * tree-data-ref.h (init_data_ref): Additional argument.
+       (array_base_name_differ_p): Moved to tree-data-ref.c.
+       * tree-data-ref.c (array_base_name_differ_p): Revised.
+       (initialize_data_dependence_relation): Call array_base_name_differ_p
+       with an extra argument.
+       (analyze_all_data_dependences): Same.
+       (init_data_ref): Additional argument is_read to set DR_IS_READ.
+       * tree-ssa-phiopt.c (empty_block_p): Expose for usage out of this file.
+       * tree-flow.h (vectorize_loops, empty_block_p): Add declaration.
+       * tree-optimize.c (pass_vectorize): Schedule the vectorization pass.
+       * tree-pass.h (tree_opt_pass pass_vectorize): Declare the new 
+       vectorization pass.
+       * tree-ssa-loop.c (tree_ssa_loop_init): Call scev_initialize.
+       (tree_ssa_loop_done): Call scev_finalize.
+       (tree_vectorize): Define the new vectorization pass.
+       * defaults.h (UNITS_PER_SIMD_WORD): Allow targets to specify the size of
+       the vector they support (until support for multiple vector sizes is
+       added to the vectorizer).
+       * config/i386/i386.h (UNITS_PER_SIMD_WORD): Define.
+       * config/rs6000/rs6000.h (UNITS_PER_SIMD_WORD): Define.
+       * invoke.texi (fdump-tree-vect, ftree-vectorize): Add
+       documentation.
+
 2004-08-17  Nathan Sidwell  <nathan@codesourcery.com>
 
        * objc/objc-act.c (build_protocol_initializer): Fix build_int_cst
index f9c03ea9e1466b708c985f4820a51e183d43f69d..57939960d0d353429d3fb4470f11860f27718c48 100644 (file)
@@ -887,6 +887,7 @@ OBJS-common = \
  tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o    \
  tree-phinodes.o tree-ssanames.o tree-sra.o tree-complex.o tree-ssa-loop.o \
  tree-ssa-loop-niter.o tree-ssa-loop-manip.o tree-ssa-threadupdate.o      \
+ tree-vectorizer.o                                                        \
  alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o                   \
  cfg.o cfganal.o cfgbuild.o cfgcleanup.o cfglayout.o cfgloop.o            \
  cfgloopanal.o cfgloopmanip.o loop-init.o loop-unswitch.o loop-unroll.o           \
@@ -1727,6 +1728,10 @@ tree-data-ref.o: tree-data-ref.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    errors.h $(GGC_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) diagnostic.h \
    $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) cfgloop.h \
    tree-data-ref.h $(SCEV_H) tree-pass.h lambda.h
+tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+   errors.h $(GGC_H) $(OPTABS_H) $(TREE_H) $(RTL_H) $(BASIC_BLOCK_H) diagnostic.h \
+   $(TREE_FLOW_H) $(TREE_DUMP_H) $(TIMEVAR_H) cfgloop.h tree-pass.h \
+   tree-vectorizer.h tree-data-ref.h $(SCEV_H)
 tree-gimple.o : tree-gimple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
        $(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H)
 tree-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
index 7694df121c67bb51db2002b9597c06b26a55dc00..6c855a63390ec0e334d1e01c05078d627fc5a06c 100644 (file)
@@ -907,6 +907,10 @@ fvar-tracking
 Common Report Var(flag_var_tracking) VarExists
 Perform variable tracking
 
+ftree-vectorize
+Common Report Var(flag_tree_vectorize)
+Enable loop vectorization on trees
+
 ; -fverbose-asm causes extra commentary information to be produced in
 ; the generated assembly code (to make it more readable).  This option
 ; is generally only of use to those who actually need to read the
index ef8469c2dfaf651337f42be41c6d6d15fbcd7da0..04be1c9c37077e0ced2df5957b1d97666f681f2e 100644 (file)
@@ -674,6 +674,10 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 #define VECTOR_MODE_SUPPORTED_P(MODE) 0
 #endif
 
+#ifndef UNITS_PER_SIMD_WORD
+#define UNITS_PER_SIMD_WORD 0
+#endif
+
 /* Determine whether __cxa_atexit, rather than atexit, is used to
    register C++ destructors for local statics and global objects.  */
 #ifndef DEFAULT_USE_CXA_ATEXIT
index 98b66e293857adda6481935a7d325af9793f74f9..4eb1498ddca49d44dbba0c13bd2e8325b1a876e7 100644 (file)
@@ -263,7 +263,7 @@ Objective-C and Objective-C++ Dialects}.
 -fdump-tree-phiopt@r{[}-@var{n}@r{]} @gol
 -fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
 -fdump-tree-copyrename@r{[}-@var{n}@r{]} @gol
--fdump-tree-nrv @gol
+-fdump-tree-nrv -fdump-tree-vect @gol
 -fdump-tree-sra@r{[}-@var{n}@r{]} @gol
 -fdump-tree-fre@r{[}-@var{n}@r{]} @gol
 -feliminate-dwarf2-dups -feliminate-unused-debug-types @gol
@@ -318,7 +318,7 @@ Objective-C and Objective-C++ Dialects}.
 -ftree-pre  -ftree-ccp  -ftree-dce -ftree-loop-optimize @gol
 -ftree-lim @gol
 -ftree-dominator-opts -ftree-dse -ftree-copyrename @gol
--ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre @gol
+-ftree-ch -ftree-sra -ftree-ter -ftree-lrs -ftree-fre -ftree-vectorize @gol
 --param @var{name}=@var{value}
 -O  -O0  -O1  -O2  -O3  -Os}
 
@@ -3664,6 +3664,11 @@ Dump each function after applying the named return value optimization on
 generic trees.  The file name is made by appending @file{.nrv} to the source
 file name.
 
+@item vect
+@opindex fdump-tree-vect
+Dump each function after applying vectorization of loops.  The file name is 
+made by appending @file{.vect} to the source file name.
+
 @item all
 @opindex fdump-tree-all
 Enable all the available tree dumps with the flags provided in this option.
@@ -4499,6 +4504,9 @@ Perform live range splitting during the SSA->normal phase.  Distinct live
 ranges of a variable are split into unique variables, allowing for better
 optimization later.  This is enabled by default at -O and higher.
 
+@item -ftree-vectorize
+Perform loop vectorization on trees.
+
 @item -ftracer
 @opindex ftracer
 Perform tail duplication to enlarge superblock size. This transformation
index 7ceee259881f3446b80f1243ae8a57a7832dde11..64344815c7d9f33c87110119510c294dbb3d1517 100644 (file)
@@ -1,3 +1,8 @@
+2004-08-17  Dorit Naishlos  <dorit@il.ibm.com>
+
+       * gcc.dg/vect: New directory for vectorizer tests.
+       (vect-*.c): New tests. 
+
 2004-08-17  Paul Brook  <paul@codesourcery.com>
 
        PR fortran/13082
diff --git a/gcc/testsuite/gcc.dg/vect/pr16105.c b/gcc/testsuite/gcc.dg/vect/pr16105.c
new file mode 100644 (file)
index 0000000..c75ab99
--- /dev/null
@@ -0,0 +1,22 @@
+/* { dg-do compile { target powerpc*-*-* i?86-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* } } */
+
+#define VECTOR_SIZE 512
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+extern void check(const afloat * __restrict__ v);
+
+void square(const afloat * __restrict__ a,
+           afloat * __restrict__ out)
+{
+    unsigned int i;
+    for (i = 0; i < VECTOR_SIZE; i++) {
+       float ai = a[i];
+       float a2 = ai * ai;
+       out[i] = a2; 
+    }
+    check(out);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"} } */
diff --git a/gcc/testsuite/gcc.dg/vect/tree-vect.h b/gcc/testsuite/gcc.dg/vect/tree-vect.h
new file mode 100644 (file)
index 0000000..c282e38
--- /dev/null
@@ -0,0 +1,24 @@
+/* Check if system supports SIMD */
+#include <signal.h>
+
+extern void abort (void);
+extern void exit (int);
+
+void
+sig_ill_handler (int sig)
+{
+  exit(0);
+}
+
+void check_vect (void)
+{
+  signal(SIGILL, sig_ill_handler);
+#if defined(__ppc__) || defined(__ppc64__)
+  /* Altivec instruction, 'vor %v0,%v0,%v0'.  */
+  asm volatile (".long 0x10000484");
+#elif defined(__i386__) || defined(__x86_64__)
+  /* SSE2 instruction: movsd %xmm0,%xmm0 */
+  asm volatile (".byte 0xf2,0x0f,0x10,0xc0");
+#endif
+  signal (SIGILL, SIG_DFL);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-1.c b/gcc/testsuite/gcc.dg/vect/vect-1.c
new file mode 100644 (file)
index 0000000..aa0b1f2
--- /dev/null
@@ -0,0 +1,102 @@
+/* { dg-do compile { target powerpc*-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#define N 16
+
+void fbar (float *);
+void ibar (int *);
+void sbar (short *);
+
+/* multiple loops */
+
+foo (int n)
+{
+  float a[N+1];
+  float b[N];
+  float c[N];
+  float d[N];
+  int ia[N];
+  int ib[N];
+  int ic[N];
+  short sa[N];
+  short sb[N];
+  short sc[N];
+  int i,j;
+  int diff = 0;
+  char cb[N];
+  char cc[N];
+  char image[N][N];
+  char block[N][N];
+
+  /* Not vetorizable yet (cross-iteration cycle).  */
+  diff = 0;
+  for (i = 0; i < N; i++) {
+    diff += (cb[i] - cc[i]);
+  }
+  ibar (&diff);
+
+
+  /* Not vetorizable yet (outer-loop: not attempted. 
+     inner-loop: cross iteration cycle; multi-dimensional arrays).  */
+  diff = 0;
+  for (i = 0; i < N; i++) {
+    for (i = 0; i < N; i++) {
+      diff += (image[i][j] - block[i][j]);
+    }
+  }
+  ibar (&diff);
+
+
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++){
+    a[i] = b[i];
+  }
+  fbar (a);
+
+
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++){
+    a[i] = b[i] + c[i] + d[i];
+  }
+  fbar (a);
+
+
+  /* Not vetorizable yet (access pattern).  */
+  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];
+  }
+  fbar (a);
+
+
+  /* Vectorizable.  */
+  for (i = 0; i < N; i++){
+    a[i] = b[i] + c[i];
+    d[i] = b[i] + c[i];
+    ia[i] = ib[i] + ic[i];
+  }
+  ibar (ia);
+  fbar (a);
+  fbar (d);
+
+
+  /* Not vectorizable yet (two types with different nunits in vector).  */
+  for (i = 0; i < N; i++){
+    ia[i] = ib[i] + ic[i];
+    sa[i] = sb[i] + sc[i];
+  }
+  ibar (ia);
+  sbar (sa);
+
+
+  /* Not vetorizable yet (too conservative dependence test).  */
+  for (i = 0; i < N; i++){
+    a[i] = b[i] + c[i];
+    a[i+1] = b[i] + c[i];
+  }
+  fbar (a);
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-10.c b/gcc/testsuite/gcc.dg/vect/vect-10.c
new file mode 100644 (file)
index 0000000..b14f8ea
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile { target powerpc*-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#define N 16
+
+short a[N];
+short d[N];
+
+int foo ()
+{
+  int i;
+  short b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  short c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+
+  /* Not vetorizable yet (strided access pattern).  */
+  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];
+    } 
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-11.c b/gcc/testsuite/gcc.dg/vect/vect-11.c
new file mode 100644 (file)
index 0000000..cfcc642
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 ()
+{
+  int i;
+  int ia[N];
+  int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+
+  /* Not vetorizable yet (integer mult).  */
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] * ic[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != ib[i] * ic[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-12.c b/gcc/testsuite/gcc.dg/vect/vect-12.c
new file mode 100644 (file)
index 0000000..902a18a
--- /dev/null
@@ -0,0 +1,45 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 ()
+{
+  int i;
+  int ia[N];
+  int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  short sa[N];
+  short sc[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+
+  /* Not vetorizable yet (multiple types with different nunits in vector).  */
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] + ic[i];
+      sa[i] = sb[i] + sc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != ib[i] + ic[i] || sa[i] != sb[i] + sc[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-13.c b/gcc/testsuite/gcc.dg/vect/vect-13.c
new file mode 100644 (file)
index 0000000..0a73a18
--- /dev/null
@@ -0,0 +1,25 @@
+/* { dg-do compile { target powerpc*-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+
+#define N 16
+
+int a[N];
+int results[N] = {0,1,2,3,0,0,0,0,0,0,0,0,12,13,14,15};
+
+int main ()
+{
+  int i;
+  int b[N] = {0,1,2,3,-4,-5,-6,-7,-8,-9,-10,-11,12,13,14,15};
+
+  /* Not vectorizable yet (condition in loop).  */
+  for (i = 0; i < N; i++)
+    {
+      a[i] = (b[i] >= 0 ? b[i] : 0);
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-14.c b/gcc/testsuite/gcc.dg/vect/vect-14.c
new file mode 100644 (file)
index 0000000..f6207c8
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 ()
+{
+  int i;
+  int ia[N];
+
+
+  /* Not vetorizable yet (induction).  */
+  for ( i = 0; i < N; i++) {
+    ia[i] = i;
+  }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != i)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-15.c b/gcc/testsuite/gcc.dg/vect/vect-15.c
new file mode 100644 (file)
index 0000000..96c173d
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 ()
+{
+  int i;
+  int a[N];
+  int b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+
+  /* Not vetorizable yet (reverse access and forward access).  */
+  for (i = N; i > 0; i--)
+    {
+      a[N-i] = b[i-1];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (a[i] != b[N-1-i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-16.c b/gcc/testsuite/gcc.dg/vect/vect-16.c
new file mode 100644 (file)
index 0000000..f09845e
--- /dev/null
@@ -0,0 +1,39 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+#define DIFF 240
+
+int main1 ()
+{
+  int i;
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  float diff;
+
+  /* Not vetorizable yet (reduction).  */
+  diff = 0;
+  for (i = 0; i < N; i++) {
+    diff += (b[i] - c[i]);
+  }
+
+  /* check results:  */
+  if (diff != DIFF)
+    abort ();
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-17.c b/gcc/testsuite/gcc.dg/vect/vect-17.c
new file mode 100644 (file)
index 0000000..bae19e0
--- /dev/null
@@ -0,0 +1,130 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] & ic[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != ib[i] & ic[i])
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = cb[i] & cc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != cb[i] & cc[i])
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = sb[i] & sc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != sb[i] & sc[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-18.c b/gcc/testsuite/gcc.dg/vect/vect-18.c
new file mode 100644 (file)
index 0000000..88b0fc0
--- /dev/null
@@ -0,0 +1,129 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = (ib[i] | ic[i]);
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != (ib[i] | ic[i]))
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = (cb[i] | cc[i]);
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ca[i] != (cb[i] | cc[i]))
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = (sb[i] | sc[i]);
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != (sb[i] | sc[i]))
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-19.c b/gcc/testsuite/gcc.dg/vect/vect-19.c
new file mode 100644 (file)
index 0000000..dbfc272
--- /dev/null
@@ -0,0 +1,129 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] ^ ic[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != ib[i] ^ ic[i])
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = cb[i] ^ cc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != cb[i] ^ cc[i])
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = sb[i] ^ sc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != sb[i] ^ sc[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-2.c b/gcc/testsuite/gcc.dg/vect/vect-2.c
new file mode 100644 (file)
index 0000000..0a13ae1
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int main1 ()
+{  
+  char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  char ca[N];
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ca[i] != cb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-20.c b/gcc/testsuite/gcc.dg/vect/vect-20.c
new file mode 100644 (file)
index 0000000..c5f4cef
--- /dev/null
@@ -0,0 +1,129 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ~ib[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != ~ib[i])
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = ~cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != ~cb[i])
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = ~sb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != ~sb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-21.c b/gcc/testsuite/gcc.dg/vect/vect-21.c
new file mode 100644 (file)
index 0000000..fbe8e6a
--- /dev/null
@@ -0,0 +1,130 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = !ib[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != !ib[i])
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = !cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != !cb[i])
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = !sb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != !sb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-22.c b/gcc/testsuite/gcc.dg/vect/vect-22.c
new file mode 100644 (file)
index 0000000..0538515
--- /dev/null
@@ -0,0 +1,130 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = -ib[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != -ib[i])
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = -cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != -cb[i])
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = -sb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != -sb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-23.c b/gcc/testsuite/gcc.dg/vect/vect-23.c
new file mode 100644 (file)
index 0000000..801c0c8
--- /dev/null
@@ -0,0 +1,130 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] && ic[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != ib[i] && ic[i])
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = cb[i] && cc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != cb[i] && cc[i])
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = sb[i] && sc[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != sb[i] && sc[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-24.c b/gcc/testsuite/gcc.dg/vect/vect-24.c
new file mode 100644 (file)
index 0000000..db71cb4
--- /dev/null
@@ -0,0 +1,130 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 64
+
+int
+main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N]= 
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+  int ic[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char ca[N];
+  char cb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  char cc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sa[N];
+  short sb[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  short sc[N] =
+    {1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0,
+     1,1,0,0,1,0,1,0};
+
+  /* Check ints.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = (ib[i] || ic[i]);
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ia[i] != (ib[i] || ic[i]))
+        abort ();
+    }
+
+  /* Check chars.  */
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = (cb[i] || cc[i]);
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (ca[i] != (cb[i] || cc[i]))
+        abort ();
+    }
+
+  /* Check shorts.  */
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = (sb[i] || sc[i]);
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (sa[i] != (sb[i] || sc[i]))
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-25.c b/gcc/testsuite/gcc.dg/vect/vect-25.c
new file mode 100644 (file)
index 0000000..05bd15f
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+
+int main1 (int n, int *p)
+{
+  int i;
+  int ib[N];
+  int ia[N];
+  int k;
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = n;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != n)
+        abort ();
+    }
+
+  k = *p;
+  for (i = 0; i < N; i++)
+    {
+      ib[i] = k;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ib[i] != k)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  int m = 8;
+
+  check_vect ();
+  
+  return main1 (m, &m);
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-26.c b/gcc/testsuite/gcc.dg/vect/vect-26.c
new file mode 100644 (file)
index 0000000..bfeb76e
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+
+/* unaligned store.  */
+
+int main1 ()
+{
+  int i;
+  int ia[N+1];
+
+  for (i = 1; i <= N; i++)
+    {
+      ia[i] = 5;
+    }
+
+  /* check results:  */
+  for (i = 1; i <= N; i++)
+    {
+      if (ia[i] != 5)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-27.c b/gcc/testsuite/gcc.dg/vect/vect-27.c
new file mode 100644 (file)
index 0000000..35e8f41
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+
+/* unaligned load.  */
+
+int main1 ()
+{
+  int i;
+  int ia[N];
+  int ib[N+1];
+
+  for (i=0; i < N; i++)
+    {
+      ib[i] = i;
+    }
+
+  for (i = 1; i <= N; i++)
+    {
+      ia[i-1] = ib[i];
+    }
+
+  /* check results:  */
+  for (i = 1; i <= N; i++)
+    {
+      if (ia[i-1] != ib[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-28.c b/gcc/testsuite/gcc.dg/vect/vect-28.c
new file mode 100644 (file)
index 0000000..b10cf13
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+#define OFF 3
+
+/* unaligned store.  */
+
+int main1 (int off)
+{
+  int i;
+  int ia[N+OFF];
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i+off] = 5;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i+off] != 5)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  main1 (0); /* aligned */
+  main1 (OFF); /* unaligned */
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-29.c b/gcc/testsuite/gcc.dg/vect/vect-29.c
new file mode 100644 (file)
index 0000000..80754f5
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+#define OFF 3
+
+/* unaligned load.  */
+
+int main1 (int off)
+{
+  int i;
+  int ia[N];
+  int ib[N+OFF];
+
+  for (i = 0; i < N+OFF; i++)
+    {
+      ib[i] = i;
+    }
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i+off];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != ib[i+off])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  main1 (0); /* aligned */
+  main1 (OFF); /* unaligned */
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-3.c b/gcc/testsuite/gcc.dg/vect/vect-3.c
new file mode 100644 (file)
index 0000000..cd49a0d
--- /dev/null
@@ -0,0 +1,54 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 20
+
+int
+main1 ()
+{
+  int i;
+  float a[N];
+  float e[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
+  int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ia[N];
+
+  for (i = 0; i < N; i++)
+    {
+      a[i] = b[i] + c[i] + d[i];
+      e[i] = b[i] + c[i] + d[i];
+      ia[i] = ib[i] + ic[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      float fres = b[i] + c[i] + d[i];
+      int ires = ib[i] + ic[i];        
+      if (a[i] != fres || e[i] != fres || ia[i] != ires)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
+
+
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-30.c b/gcc/testsuite/gcc.dg/vect/vect-30.c
new file mode 100644 (file)
index 0000000..0e42679
--- /dev/null
@@ -0,0 +1,65 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+float b[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
+float a[N];
+float c[N];
+
+int main1 (int n)
+{
+  int i=0;
+
+  /* Vectorized: unknown loop bound.  */
+  while (n--) {
+    a[i] = b[i];
+    i++;
+  }
+
+  /* check results:  */
+  for (i = 0; i < n; i++)
+    {
+      if (a[i] != b[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main2 (unsigned int n)
+{
+  int i=0;
+  int nn = n;
+
+  /* Vectorized: unknown loop bound.  */
+  while (n--) {
+    c[i] = b[i];
+    i++;
+  }
+
+  /* check results:  */
+  for (i = 0; i < nn; i++)
+    {
+      if (c[i] != b[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  main1 (N);
+  main2 (N);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-31.c b/gcc/testsuite/gcc.dg/vect/vect-31.c
new file mode 100644 (file)
index 0000000..cb7f7cc
--- /dev/null
@@ -0,0 +1,92 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 32
+
+struct t{
+  int k[N];
+  int l; 
+};
+  
+struct s{
+  char a;      /* aligned */
+  char b[N-1];  /* unaligned (offset 1B) */
+  char c[N];    /* aligned (offset NB) */
+  struct t d;   /* aligned (offset 2NB) */
+  struct t e;   /* unaligned (offset 2N+4N+4 B) */
+};
+int main1 ()
+{  
+  int i;
+  struct s tmp;
+
+  /* unaligned */
+  for (i = 0; i < N/2; i++)
+    {
+      tmp.b[i] = 5;
+    }
+
+  /* check results:  */
+  for (i = 0; i <N/2; i++)
+    {
+      if (tmp.b[i] != 5)
+        abort ();
+    }
+
+  /* aligned */
+  for (i = 0; i < N/2; i++)
+    {
+      tmp.c[i] = 6;
+    }
+
+  /* check results:  */
+  for (i = 0; i <N/2; i++)
+    {
+      if (tmp.c[i] != 6)
+        abort ();
+    }
+
+  /* aligned */
+  for (i = 0; i < N/2; i++)
+    {
+      tmp.d.k[i] = 7;
+    }
+
+  /* check results:  */
+  for (i = 0; i <N/2; i++)
+    {
+      if (tmp.d.k[i] != 7)
+        abort ();
+    }
+
+  /* unaligned */
+  for (i = 0; i < N/2; i++)
+    {
+      tmp.e.k[i] = 8;
+    }
+
+  /* check results:  */
+  for (i = 0; i <N/2; i++)
+    {
+      if (tmp.e.k[i] != 8)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-32.c b/gcc/testsuite/gcc.dg/vect/vect-32.c
new file mode 100644 (file)
index 0000000..8e1cb18
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int main1 ()
+{  
+  struct {
+    char ca[N];
+  } s;
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      s.ca[i] = 5;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.ca[i] != 5)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-33.c b/gcc/testsuite/gcc.dg/vect/vect-33.c
new file mode 100644 (file)
index 0000000..137e698
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do compile { target powerpc*-*-* } } */
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-S -O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-S -O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+struct test {
+  char ca[N];
+};
+
+extern struct test s;
+int main1 ()
+{  
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      s.ca[i] = 5;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.ca[i] != 5)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  return main1 ();
+} 
+
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-34.c b/gcc/testsuite/gcc.dg/vect/vect-34.c
new file mode 100644 (file)
index 0000000..7adbf68
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int main1 ()
+{  
+  struct {
+    char ca[N];
+  } s;
+  char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      s.ca[i] = cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.ca[i] != cb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-35.c b/gcc/testsuite/gcc.dg/vect/vect-35.c
new file mode 100644 (file)
index 0000000..b29da49
--- /dev/null
@@ -0,0 +1,50 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+typedef char achar __attribute__ ((__aligned__(16)));
+
+#define N 16
+achar x[N];
+int main1 ()
+{  
+  union {
+    achar a[N];
+    achar b[N];
+  } s;
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      s.b[i] = 3*i;
+    }
+
+  for (i = 0; i < N; i++)
+    {
+      s.a[i] = s.b[i] + 1;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.a[i] != s.b[i])
+       abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-36.c b/gcc/testsuite/gcc.dg/vect/vect-36.c
new file mode 100644 (file)
index 0000000..b3c60d9
--- /dev/null
@@ -0,0 +1,47 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+int main1 ()
+{  
+  struct {
+    char ca[N];
+    char cb[N];
+  } s;
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      s.cb[i] = 3*i;
+    }
+
+  for (i = 0; i < N; i++)
+    {
+      s.ca[i] = s.cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.ca[i] != s.cb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-37.c b/gcc/testsuite/gcc.dg/vect/vect-37.c
new file mode 100644 (file)
index 0000000..97f3110
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+typedef char achar __attribute__ ((__aligned__(16)));
+
+#define N 16
+achar x[N];
+int main1 (achar *y)
+{  
+  struct {
+    achar *p;
+    achar *q;
+  } s;
+  achar cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int i;
+
+  s.p = y;
+  for (i = 0; i < N; i++)
+    {
+      s.p[i] = cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.p[i] != cb[i])
+        abort ();
+    }
+
+  s.q = cb;
+  for (i = 0; i < N; i++)
+    {
+      s.p[i] = s.q[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (s.p[i] != s.q[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 (x);
+} 
+
+
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-38.c b/gcc/testsuite/gcc.dg/vect/vect-38.c
new file mode 100644 (file)
index 0000000..df2cf9c
--- /dev/null
@@ -0,0 +1,41 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+double cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+double ca[N];
+
+int main1 ()
+{  
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = cb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ca[i] != cb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+} 
+
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail powerpc*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-4.c b/gcc/testsuite/gcc.dg/vect/vect-4.c
new file mode 100644 (file)
index 0000000..943d71f
--- /dev/null
@@ -0,0 +1,42 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 20
+
+int
+main1 ()
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  for (i = 0; i < N; i++)
+    {
+      a[i] = b[i] * c[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (a[i] != b[i] * c[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-40.c b/gcc/testsuite/gcc.dg/vect/vect-40.c
new file mode 100644 (file)
index 0000000..e3dd277
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * __restrict__ pa, afloat * __restrict__ pb, afloat * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+  bar (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"} } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-41.c b/gcc/testsuite/gcc.dg/vect/vect-41.c
new file mode 100644 (file)
index 0000000..0f9cae4
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * pa, afloat * pb, afloat * pc)
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-42.c b/gcc/testsuite/gcc.dg/vect/vect-42.c
new file mode 100644 (file)
index 0000000..7f79d42
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * __restrict__ pa)
+{
+  int i;
+  afloat pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a);
+  bar (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect"} } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-43.c b/gcc/testsuite/gcc.dg/vect/vect-43.c
new file mode 100644 (file)
index 0000000..370b5dd
--- /dev/null
@@ -0,0 +1,59 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * pa)
+{
+  int i;
+  afloat pb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat pc[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-44.c b/gcc/testsuite/gcc.dg/vect/vect-44.c
new file mode 100644 (file)
index 0000000..4068ab1
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+
+void bar (float *pa, float *pb, float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (float * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-45.c b/gcc/testsuite/gcc.dg/vect/vect-45.c
new file mode 100644 (file)
index 0000000..c0b0029
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+
+void bar (const float *pa, const float *pb, const float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (float *pa, float *pb, float *pc)
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-46.c b/gcc/testsuite/gcc.dg/vect/vect-46.c
new file mode 100644 (file)
index 0000000..1fb08a7
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n , afloat * __restrict__ pa, afloat * __restrict__ pb, afloat * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  int n=N;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (n,a,b,c);
+  bar (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-47.c b/gcc/testsuite/gcc.dg/vect/vect-47.c
new file mode 100644 (file)
index 0000000..e1e1d38
--- /dev/null
@@ -0,0 +1,57 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n , afloat *  pa, afloat *  pb, afloat *  pc)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  int n=N;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (n,a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-48.c b/gcc/testsuite/gcc.dg/vect/vect-48.c
new file mode 100644 (file)
index 0000000..c7485be
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (float *pa, float *pb, float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-49.c b/gcc/testsuite/gcc.dg/vect/vect-49.c
new file mode 100644 (file)
index 0000000..8d8b212
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (const float *pa, const float *pb, const float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat *pa, float *pb, float *pc)
+{
+  int i;
+
+  for (i = 0; i < N; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-5.c b/gcc/testsuite/gcc.dg/vect/vect-5.c
new file mode 100644 (file)
index 0000000..bab9e23
--- /dev/null
@@ -0,0 +1,58 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 ()
+{
+  int i, j;
+  float a[N];
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
+
+  i = 0;
+  j = 0;
+  while (i < 5*N)
+    {
+      a[j] = c[j];
+      i += 5;
+      j++;
+    }
+
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (a[i] != c[i])
+        abort ();
+    }
+
+
+  for (i = N; i > 0; i--)
+    {
+      a[N-i] = d[N-i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (a[i] != d[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-50.c b/gcc/testsuite/gcc.dg/vect/vect-50.c
new file mode 100644 (file)
index 0000000..cd7cf5d
--- /dev/null
@@ -0,0 +1,54 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+
+void bar (float *pa, float *pb, float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n, float * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (N,a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-51.c b/gcc/testsuite/gcc.dg/vect/vect-51.c
new file mode 100644 (file)
index 0000000..65c0f40
--- /dev/null
@@ -0,0 +1,54 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+
+void bar (const float *pa, const float *pb, const float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n, float *pa, float *pb, float *pc)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  float a[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (N,a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-52.c b/gcc/testsuite/gcc.dg/vect/vect-52.c
new file mode 100644 (file)
index 0000000..32a584b
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (float *pa, float *pb, float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n, afloat * __restrict__ pa, float * __restrict__ pb, float * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+
+  check_vect ();
+
+  main1 (N,a,&b[1],c);
+  main1 (N,a,&b[1],&c[1]);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-53.c b/gcc/testsuite/gcc.dg/vect/vect-53.c
new file mode 100644 (file)
index 0000000..4b99304
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+  
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (const float *pa, const float *pb, const float *pc) 
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (pa[i] != (pb[i] * pc[i]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n, afloat *pa, float *pb, float *pc)
+{
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      pa[i] = pb[i] * pc[i];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N+1] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60};
+  afloat c[N+1] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
+
+  check_vect ();
+
+  main1 (N,a,&b[1],c);
+  main1 (N,a,&b[1],&c[1]);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-54.c b/gcc/testsuite/gcc.dg/vect/vect-54.c
new file mode 100644 (file)
index 0000000..5ab9e02
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i+1] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * __restrict__ pa, afloat * __restrict__ pb, afloat * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < N/2; i++)
+    {
+      pa[i+1] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-55.c b/gcc/testsuite/gcc.dg/vect/vect-55.c
new file mode 100644 (file)
index 0000000..2257a23
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i+1] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat *  pa, afloat *  pb, afloat *  pc)
+{
+  int i;
+
+  for (i = 0; i < N/2; i++)
+    {
+      pa[i+1] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-56.c b/gcc/testsuite/gcc.dg/vect/vect-56.c
new file mode 100644 (file)
index 0000000..0e20137
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat * __restrict__ pa, afloat * __restrict__ pb, afloat * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < N/2; i++)
+    {
+      pa[i] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-57.c b/gcc/testsuite/gcc.dg/vect/vect-57.c
new file mode 100644 (file)
index 0000000..0e675d7
--- /dev/null
@@ -0,0 +1,55 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (afloat *  pa, afloat *  pb, afloat * pc)
+{
+  int i;
+
+  for (i = 0; i < N/2; i++)
+    {
+      pa[i] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-58.c b/gcc/testsuite/gcc.dg/vect/vect-58.c
new file mode 100644 (file)
index 0000000..57c2779
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i+1] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n , afloat * __restrict__ pa, afloat * __restrict__ pb, afloat * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < n/2; i++)
+    {
+      pa[i+1] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  int n=N;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (n,a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-59.c b/gcc/testsuite/gcc.dg/vect/vect-59.c
new file mode 100644 (file)
index 0000000..3dfbe19
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i+1] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n , afloat *  pa, afloat *  pb, afloat *  pc)
+{
+  int i;
+
+  for (i = 0; i < n/2; i++)
+    {
+      pa[i+1] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  int n=N;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (n,a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-6.c b/gcc/testsuite/gcc.dg/vect/vect-6.c
new file mode 100644 (file)
index 0000000..2671fd7
--- /dev/null
@@ -0,0 +1,61 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+float results1[N] = {192.00,240.00,288.00,336.00,384.00,432.00,480.00,528.00,0.00};
+float results2[N] = {0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,0.00,54.00,120.00,198.00,288.00,390.00,504.00,630.00};
+
+int main1 ()
+{
+  int i;
+  float a[N] = {0};
+  float e[N] = {0};
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+
+  for (i = 0; i < N/2; i++)
+    { 
+      a[i] = b[i+N/2] * c[i+N/2] - b[i] * c[i];
+      e[i+N/2] = b[i] * c[i+N/2] + b[i+N/2] * c[i];
+    }
+
+  /* check results:  */
+  for (i=0; i<N; i++)
+    {
+      if (a[i] != results1[i] || e[i] != results2[i])
+       abort(); 
+    }
+
+
+  for (i = 1; i <=N-4; i++)
+    {
+      a[i+3] = b[i-1];
+    }
+
+  /* check results:  */
+  for (i = 1; i <=N-4; i++)
+    {
+      if (a[i+3] != b[i-1])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
+
+
diff --git a/gcc/testsuite/gcc.dg/vect/vect-60.c b/gcc/testsuite/gcc.dg/vect/vect-60.c
new file mode 100644 (file)
index 0000000..276b7e2
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n , afloat * __restrict__ pa, afloat * __restrict__ pb, afloat * __restrict__ pc)
+{
+  int i;
+
+  for (i = 0; i < n/2; i++)
+    {
+      pa[i] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  int n=N;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (n,a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-61.c b/gcc/testsuite/gcc.dg/vect/vect-61.c
new file mode 100644 (file)
index 0000000..257ef38
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 256
+
+typedef float afloat __attribute__ ((__aligned__(16)));
+
+void bar (afloat *pa, afloat *pb, afloat *pc)
+{
+  int i;
+
+  /* check results:  */
+  for (i = 0; i < N/2; i++)
+    {
+      if (pa[i] != (pb[i+1] * pc[i+1]))
+       abort ();
+    }
+
+  return;
+}
+
+
+int
+main1 (int n , afloat *  pa, afloat *  pb, afloat *  pc)
+{
+  int i;
+
+  for (i = 0; i < n/2; i++)
+    {
+      pa[i] = pb[i+1] * pc[i+1];
+    }
+
+  bar (pa,pb,pc);
+
+  return 0;
+}
+
+int main (void)
+{
+  int i;
+  int n=N;
+  afloat a[N];
+  afloat b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57};
+  afloat c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
+
+  check_vect ();
+
+  main1 (n,a,b,c);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-7.c b/gcc/testsuite/gcc.dg/vect/vect-7.c
new file mode 100644 (file)
index 0000000..76e0106
--- /dev/null
@@ -0,0 +1,52 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 128
+
+int main1 ()
+{
+  int i;
+  short sa[N];
+  short sb[N];
+  
+  for (i = 0; i < N; i++)
+    {
+      sb[i] = 5;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (sb[i] != 5)
+        abort ();
+    }
+  
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = sb[i] + 100;
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (sa[i] != 105)
+        abort ();
+    }
+  
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 ();
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-8.c b/gcc/testsuite/gcc.dg/vect/vect-8.c
new file mode 100644 (file)
index 0000000..08c986c
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+float b[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
+float a[N];
+
+int main1 (int n)
+{
+  int i;
+
+  /* Vectorized: unknown loop bound).  */
+  for (i = 0; i < n; i++){
+    a[i] = b[i];
+  }
+
+  /* check results:  */
+  for (i = 0; i < n; i++)
+    {
+      if (a[i] != b[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+  
+  return main1 (N);
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-9.c b/gcc/testsuite/gcc.dg/vect/vect-9.c
new file mode 100644 (file)
index 0000000..0501bb8
--- /dev/null
@@ -0,0 +1,40 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int main1 ()
+{
+  int i;
+  short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ia[N];
+
+  /* Not vetorizable yet (type cast).  */
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = (int) sb[i];
+    }
+
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != (int) sb[i])
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{ 
+  check_vect ();
+
+  return main1 ();
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-all.c b/gcc/testsuite/gcc.dg/vect/vect-all.c
new file mode 100644 (file)
index 0000000..a36d308
--- /dev/null
@@ -0,0 +1,218 @@
+/* { dg-do run { target powerpc*-*-* } } */
+/* { dg-do run { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#include <stdarg.h>
+#include "tree-vect.h"
+
+#define N 16
+
+int iadd_results[N] = {0,6,12,18,24,30,36,42,48,54,60,66,72,78,84,90};
+float fadd_results[N] = {0.0,6.0,12.0,18.0,24.0,30.0,36.0,42.0,48.0,54.0,60.0,66.0,72.0,78.0,84.0,90.0};
+float fmul_results[N] = {0.0,3.0,12.0,27.0,48.0,75.0,108.0,147.0,192.0,243.0,300.0,363.0,432.0,507.0,588.0,675.0};
+float fresults1[N] = {192.00,240.00,288.00,336.00,384.00,432.00,480.00,528.00,48.00,54.00,60.00,66.00,72.00,78.00,84.00,90.00};
+float fresults2[N] = {0.00,6.00,12.00,18.00,24.00,30.00,36.00,42.00,0.00,54.00,120.00,198.00,288.00,390.00,504.00,630.00};
+
+/****************************************************/
+void icheck_results (int *a, int *results)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      if (a[i] != results[i])
+       abort ();
+    }
+}
+
+void fcheck_results (float *a, float *results)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      if (a[i] != results[i])
+       abort ();
+    }
+}   
+
+void 
+fbar_mul (float *a)
+{
+  fcheck_results (a, fmul_results);
+} 
+
+void 
+fbar_add (float *a)
+{
+  fcheck_results (a, fadd_results);
+} 
+
+void 
+ibar_add (int *a)
+{
+  icheck_results (a, iadd_results);
+} 
+
+void 
+fbar1 (float *a)
+{
+  fcheck_results (a, fresults1);
+} 
+
+void 
+fbar2 (float *a)
+{
+  fcheck_results (a, fresults2);
+} 
+
+
+/* All of the loops below are currently vectorizable.  */
+
+int
+main1 ()
+{
+  int i,j;
+  float a[N];
+  float e[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
+  int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ia[N];
+  char cb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  char ca[N];
+  short sa[N];
+
+  /* Test 1: copy chars.  */
+  for (i = 0; i < N; i++)
+    {
+      ca[i] = cb[i];
+    }
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ca[i] != cb[i])
+       abort ();
+    }
+
+
+  /* Test 2: fp mult.  */
+  for (i = 0; i < N; i++)
+    {
+      a[i] = b[i] * c[i];
+    }
+  fbar_mul (a);
+
+
+  /* Test 3: mixed types (int, fp), same nunits in vector.  */
+  for (i = 0; i < N; i++)
+    {
+      a[i] = b[i] + c[i] + d[i];
+      e[i] = b[i] + c[i] + d[i];
+      ia[i] = ib[i] + ic[i];
+    }
+  ibar_add (ia);
+  fbar_add (a);
+  fbar_add (e);
+
+
+  /* Test 4: access with offset.  */
+  for (i = 0; i < N/2; i++)
+    {
+      a[i] = b[i+N/2] * c[i+N/2] - b[i] * c[i];
+      e[i+N/2] = b[i] * c[i+N/2] + b[i+N/2] * c[i];
+    }
+  fbar1 (a);
+  fbar2 (e);
+
+
+  /* Test 5: access with offset */
+  for (i = 1; i <=N-4; i++)
+    {
+      a[i+3] = b[i-1];
+    }
+  /* check results:  */
+  for (i = 1; i <=N-4; i++)
+    {
+      if (a[i+3] != b[i-1])
+       abort ();
+    }
+
+
+  /* Test 6 - loop induction with stride != 1.  */
+  i = 0;
+  j = 0;
+  while (i < 5*N)
+    {
+      a[j] = c[j];
+      i += 5;
+      j++;
+    }
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (a[i] != c[i])
+        abort ();
+    }
+
+
+  /* Test 7 - reverse access.  */
+  for (i = N; i > 0; i--)
+    {
+      a[N-i] = d[N-i];
+    }
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (a[i] != d[i])
+        abort ();
+    }
+
+
+  /* Tests 8,9,10 - constants.  */
+  for (i = 0; i < N; i++)
+    {
+      a[i] = 5.0;
+    }
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (a[i] != 5.0)
+        abort ();
+    }
+
+  for (i = 0; i < N; i++)
+    {
+      sa[i] = 5;
+    }
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (sa[i] != 5)
+        abort ();
+    }
+
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] + 5;
+    }
+  /* check results:  */
+  for (i = 0; i < N; i++)
+    {
+      if (ia[i] != ib[i] + 5)
+        abort ();
+    }
+
+  return 0;
+}
+
+int main (void)
+{
+  check_vect ();
+
+  return main1 ();
+}
+
+/* xfail: local arrays can't be aligned on a boundary greater than STACK_BOUNDARY */
+/* { dg-final { scan-tree-dump-times "vectorized 10 loops" 1 "vect" {xfail i?86-*-* x86_64-*-*} } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-none.c b/gcc/testsuite/gcc.dg/vect/vect-none.c
new file mode 100644 (file)
index 0000000..8680d21
--- /dev/null
@@ -0,0 +1,193 @@
+/* { dg-do compile { target powerpc*-*-* i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -maltivec" { target powerpc*-*-* } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-stats -msse2" { target i?86-*-* x86_64-*-* } } */
+
+#define N 16
+
+extern void abort (void);
+
+int iadd_results[N] = {0,6,12,18,24,30,36,42,48,54,60,66,72,78,84,90};
+float fadd_results[N] = {0.0,6.0,12.0,18.0,24.0,30.0,36.0,42.0,48.0,54.0,60.0,66.0,72.0,78.0,84.0,90.0};
+float fmul_results[N] = {0.0,3.0,12.0,27.0,48.0,75.0,108.0,147.0,192.0,243.0,300.0,363.0,432.0,507.0,588.0,675.0};
+float fresults1[N] = {192.00,240.00,288.00,336.00,384.00,432.00,480.00,528.00,48.00,54.00,60.00,66.00,72.00,78.00,84.00,90.00};
+float fresults2[N] = {0.00,6.00,12.00,18.00,24.00,30.00,36.00,42.00,0.00,54.00,120.00,198.00,288.00,390.00,504.00,630.00};
+
+/****************************************************/
+void icheck_results (int *a, int *results)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      if (a[i] != results[i])
+       abort ();
+    }
+}
+
+void fcheck_results (float *a, float *results)
+{
+  int i;
+  for (i = 0; i < N; i++)
+    {
+      if (a[i] != results[i])
+       abort ();
+    }
+}   
+
+void 
+fbar_mul (float *a)
+{
+  fcheck_results (a, fmul_results);
+} 
+
+void 
+fbar_add (float *a)
+{
+  fcheck_results (a, fadd_results);
+} 
+
+void 
+ibar_add (int *a)
+{
+  icheck_results (a, iadd_results);
+} 
+
+void 
+fbar1 (float *a)
+{
+  fcheck_results (a, fresults1);
+} 
+
+void 
+fbar2 (float *a)
+{
+  fcheck_results (a, fresults2);
+} 
+
+
+/* None of the loops below is currently vectorizable. The vectorizer will
+   be enhanced to vectorize most of these loops.  */
+
+int
+foo (int n)
+{
+  int i,j;
+  float a[N];
+  float e[N];
+  float b[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  float c[N] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
+  float d[N] = {0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30};
+  short sc[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  short sb[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  short sa[N];
+  int ic[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ib[N] = {0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45};
+  int ia[N];
+  int diff = 0;
+  char cb[N];
+  char cc[N];
+  char image[N][N];
+  char block[N][N];
+
+
+  /* Test 1 - unknown loop bound.  */
+  for (i = 0; i < n; i++)
+    {
+      a[i] = b[i];
+    }
+  fbar (a);
+
+
+  /* Test 2 - type cast.  */
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = (int) sb[i];
+    }
+  fbar (a);
+
+
+  /* Test 3 - strided access pattern.  */
+  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];
+    }
+  fbar (a);
+
+
+  /* Test 4 - no target support for integer mult.  */
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] * ic[i];
+    }
+  ibar (ia);
+
+
+  /* Test 5 - two types with different nunits in vector.  */
+  for (i = 0; i < N; i++)
+    {
+      ia[i] = ib[i] + ic[i];
+      sa[i] = sb[i] + sc[i];
+    }
+  ibar (ia);
+  sbar (sa);
+
+
+  /* Test 6 - too conservative dependence test.  */
+  for (i = 0; i < N; i++){
+    a[i] = b[i] + c[i];
+    a[i+1] = b[i] + c[i];
+  }
+  fbar (a);
+
+
+  /* Test 7 - condition in loop.  */
+  for (i = 0; i < N; i++){
+    a[i] = (b[i] > 0 ? b[i] : 0);
+  }
+  fbar (a);
+
+
+  /* Test 8 - cross-iteration cycle.  */
+  diff = 0;
+  for (i = 0; i < N; i++) {
+    diff += (cb[i] - cc[i]);
+  }
+  ibar (&diff);
+
+
+  /* Test 9 - outer-loop not attempted; inner-loop has cross 
+     iteration cycle and multi-dimensional arrays.  */
+  diff = 0;
+  for (i = 0; i < N; i++) {
+    for (i = 0; i < N; i++) {
+      diff += (image[i][j] - block[i][j]);
+    }
+  }
+  ibar (&diff);
+
+
+  /* Test 10 - induction.  */
+  for ( i = 0; i < N; i++) {
+    a[i] = i;
+  }
+  fbar (a);
+
+
+  /* Test 11 - reverse access and forward access.  */
+  for (i = N; i > 0; i--)
+    {
+      a[N-i] = b[i-1];
+    }
+  /* check results:  */
+  for (i = 0; i <N; i++)
+    {
+      if (a[i] != b[N-1-i])
+       abort ();
+    }
+
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized " 3 "vect"} } */
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 3 "vect"} } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp
new file mode 100644 (file)
index 0000000..ee83948
--- /dev/null
@@ -0,0 +1,35 @@
+#   Copyright (C) 1997 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
index e3567103683ff3f992f35d32ab65b71aa6c2b927..617f26b7eadabf90a57bedc58c3f311a91449d02 100644 (file)
@@ -83,6 +83,7 @@ DEFTIMEVAR (TV_TREE_CD_DCE         , "tree aggressive DCE")
 DEFTIMEVAR (TV_TREE_DSE                     , "tree DSE")
 DEFTIMEVAR (TV_TREE_LOOP            , "tree loop optimization")
 DEFTIMEVAR (TV_LIM                   , "loop invariant motion")
+DEFTIMEVAR (TV_TREE_VECTORIZATION    , "tree loop vectorization")
 DEFTIMEVAR (TV_TREE_CH              , "tree copy headers")
 DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL    , "tree SSA to normal")
 DEFTIMEVAR (TV_TREE_NRV                     , "tree NRV optimization")
index 1f14bcb011d32685fbdca7361bb8b4b5204d3776..c45762d8540f42474ab3a9bae6ccf31cab1ef136 100644 (file)
@@ -99,6 +99,110 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 static unsigned int data_ref_id = 0;
 
 \f
+/* This is the simplest data dependence test: determines whether the
+   data references A and B access the same array/region. If can't determine -
+   return false; Otherwise, return true, and DIFFER_P will record
+   the result. This utility will not be necessary when alias_sets_conflict_p
+   will be less conservative.  */
+
+bool
+array_base_name_differ_p (struct data_reference *a,
+                          struct data_reference *b,
+                          bool *differ_p)
+{
+  tree base_a = DR_BASE_NAME (a);
+  tree base_b = DR_BASE_NAME (b);
+  tree ta = TREE_TYPE (base_a);
+  tree tb = TREE_TYPE (base_b);
+
+
+  /** Determine if same base  **/
+
+  /* array accesses: a[i],b[i] or pointer accesses: *a,*b. bases are a,b.  */
+  if (base_a == base_b)
+    {
+      *differ_p = false;
+      return true;
+    }
+
+  /* pointer based accesses - (*p)[i],(*q)[j]. bases are (*p),(*q)  */
+  if (TREE_CODE (base_a) == INDIRECT_REF && TREE_CODE (base_b) == INDIRECT_REF
+      && TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0))
+    {
+      *differ_p = false;
+      return true;
+    }
+
+  /* record/union based accesses - s.a[i], t.b[j]. bases are s.a,t.b.  */ 
+  if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) == COMPONENT_REF
+      && TREE_OPERAND (base_a, 0) == TREE_OPERAND (base_b, 0)
+      && TREE_OPERAND (base_a, 1) == TREE_OPERAND (base_b, 1))
+    {
+      *differ_p = false;
+      return true;
+    }
+
+
+  /** Determine if different bases  **/
+
+  /* at this point we know that base_a != base_b. However, pointer accesses
+     of the form x=(*p) and y=(*q), which bases are p and q, may still by pointing
+     to the same base. In SSAed GIMPLE p and q will be SSA_NAMES in this case.
+     Therefore, here we check if it's really two diferent declarations.  */
+  if (TREE_CODE (base_a) == VAR_DECL && TREE_CODE (base_b) == VAR_DECL)
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  /* compare two record/union bases s.a and t.b: 
+     s != t or (a != b and s and t are not unions)  */
+  if (TREE_CODE (base_a) == COMPONENT_REF && TREE_CODE (base_b) == COMPONENT_REF
+      && ((TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL
+           && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL
+           && TREE_OPERAND (base_a, 0) != TREE_OPERAND (base_b, 0))
+          || (TREE_CODE (TREE_TYPE (TREE_OPERAND (base_a, 0))) == RECORD_TYPE 
+              && TREE_CODE (TREE_TYPE (TREE_OPERAND (base_b, 0))) == RECORD_TYPE
+              && TREE_OPERAND (base_a, 1) != TREE_OPERAND (base_b, 1))))
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  /* compare a record/union access and an array access.  */ 
+  if ((TREE_CODE (base_a) == VAR_DECL
+       && (TREE_CODE (base_b) == COMPONENT_REF
+           && TREE_CODE (TREE_OPERAND (base_b, 0)) == VAR_DECL))
+      || (TREE_CODE (base_b) == VAR_DECL
+       && (TREE_CODE (base_a) == COMPONENT_REF
+           && TREE_CODE (TREE_OPERAND (base_a, 0)) == VAR_DECL)))
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  if (!alias_sets_conflict_p (get_alias_set (base_a), get_alias_set (base_b)))
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  /* An insn writing through a restricted pointer is "independent" of any
+     insn reading or writing through a different pointer, in the same
+     block/scope.
+   */
+  if ((TREE_CODE (ta) == POINTER_TYPE && TYPE_RESTRICT (ta)
+       && !DR_IS_READ(a))
+      || (TREE_CODE (tb) == POINTER_TYPE && TYPE_RESTRICT (tb)
+         && !DR_IS_READ(b)))
+    {
+      *differ_p = true;
+      return true;
+    }
+
+  *differ_p = false; /* Don't know, but be conservative.  */
+  return false;
+}
 
 /* Returns true iff A divides B.  */
 
@@ -466,7 +570,8 @@ struct data_reference *
 init_data_ref (tree stmt, 
               tree ref,
               tree base,
-              tree access_fn)
+              tree access_fn,
+              bool is_read)
 {
   struct data_reference *res;
 
@@ -486,6 +591,7 @@ init_data_ref (tree stmt,
   VARRAY_TREE_INIT (DR_ACCESS_FNS (res), 5, "access_fns");
   DR_BASE_NAME (res) = base;
   VARRAY_PUSH_TREE (DR_ACCESS_FNS (res), access_fn);
+  DR_IS_READ (res) = is_read;
   
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, ")\n");
@@ -532,6 +638,7 @@ initialize_data_dependence_relation (struct data_reference *a,
                                     struct data_reference *b)
 {
   struct data_dependence_relation *res;
+  bool differ_p;
   
   res = ggc_alloc (sizeof (struct data_dependence_relation));
   DDR_A (res) = a;
@@ -545,7 +652,7 @@ initialize_data_dependence_relation (struct data_reference *a,
   /* When the dimensions of A and B differ, we directly initialize
      the relation to "there is no dependence": chrec_known.  */
   else if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
-          || array_base_name_differ_p (a, b))
+          || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
     DDR_ARE_DEPENDENT (res) = chrec_known;
   
   else
@@ -1842,9 +1949,10 @@ analyze_all_data_dependences (struct loops *loops)
            {
              struct data_reference *a = DDR_A (ddr);
              struct data_reference *b = DDR_B (ddr);
+             bool differ_p;    
              
              if (DR_NUM_DIMENSIONS (a) != DR_NUM_DIMENSIONS (b)
-                 || array_base_name_differ_p (a, b))
+                 || (array_base_name_differ_p (a, b, &differ_p) && differ_p))
                nb_basename_differ++;
              else
                nb_bot_relations++;
index a31b0af32c329495aa1ce4f218cb9283f01cc913..bc069c1b7e06bd48e2f085e852768914e2e13f39 100644 (file)
@@ -151,7 +151,7 @@ extern void analyze_all_data_dependences (struct loops *);
 extern void compute_data_dependences_for_loop (unsigned, struct loop *, 
                                               varray_type *, varray_type *, 
                                               varray_type *, varray_type *);
-extern struct data_reference * init_data_ref (tree, tree, tree, tree);
+extern struct data_reference * init_data_ref (tree, tree, tree, tree, bool);
 extern struct data_reference *analyze_array (tree, tree, bool);
 
 extern void dump_data_reference (FILE *, struct data_reference *);
@@ -161,28 +161,9 @@ extern void dump_data_dependence_relation (FILE *,
 extern void dump_data_dependence_relations (FILE *, varray_type);
 extern void dump_data_dependence_direction (FILE *, 
                                            enum data_dependence_direction);
+extern bool array_base_name_differ_p (struct data_reference *, 
+                                     struct data_reference *, bool *p);
 
 \f
 
-/* Inline functions.  */
-
-/* This is the simplest data dependence test: determines whether the
-   data references A and B access the same array.  */
-
-static inline bool
-array_base_name_differ_p (struct data_reference *a, 
-                         struct data_reference *b)
-{
-  if (DR_BASE_NAME (a) == DR_BASE_NAME (b))
-    return false;
-  
-  if (TREE_CODE (DR_BASE_NAME (a)) == INDIRECT_REF
-      && TREE_CODE (DR_BASE_NAME (b)) == INDIRECT_REF
-      && TREE_OPERAND (DR_BASE_NAME (a), 0) 
-      == TREE_OPERAND (DR_BASE_NAME (b), 0))
-    return false;
-  
-  return true;
-}
-
 #endif  /* GCC_TREE_DATA_REF_H  */
index 1faa91a9199cae9379576da3acd9ccf07834bf21..0e60e411e2813fd2d8a48588c152ae5ec68951ad 100644 (file)
@@ -628,6 +628,12 @@ struct tree_niter_desc
                           the loop), then the information would be lost.  */
 };
 
+/* In tree-vectorizer.c */
+void vectorize_loops (struct loops *);
+
+/* In tree-ssa-phiopt.c */
+bool empty_block_p (basic_block);
+
 /* In tree-ssa-loop*.c  */
 
 void tree_ssa_lim (struct loops *);
index d41bebc618a1bc762a2bb8f378ddf83b7af18e69..0f37aaf0d842afd0ca9d648459c7683e2b85d518 100644 (file)
@@ -367,6 +367,7 @@ init_tree_optimization_passes (void)
   p = &pass_loop.sub;
   NEXT_PASS (pass_loop_init);
   NEXT_PASS (pass_lim);
+  NEXT_PASS (pass_vectorize);
   NEXT_PASS (pass_loop_done);
   *p = NULL;
 
index 2bf63ee77b66c08c10d1230259cf404edd8f6de7..5302232e5ff83797adcede8ccb9feecc1bf56d15 100644 (file)
@@ -109,6 +109,7 @@ extern struct tree_opt_pass pass_tail_calls;
 extern struct tree_opt_pass pass_loop;
 extern struct tree_opt_pass pass_loop_init;
 extern struct tree_opt_pass pass_lim;
+extern struct tree_opt_pass pass_vectorize;
 extern struct tree_opt_pass pass_loop_done;
 extern struct tree_opt_pass pass_ch;
 extern struct tree_opt_pass pass_ccp;
index a1e6494712a501a6753c9efe3546ca364c20bf61..99dbc71aefde94e8b2a2f73764176515a75af440 100644 (file)
@@ -37,6 +37,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "cfgloop.h"
 #include "flags.h"
 #include "tree-inline.h"
+#include "tree-scalar-evolution.h"
 
 /* The loop tree currently optimized.  */
 
@@ -98,6 +99,9 @@ static void
 tree_ssa_loop_init (void)
 {
   current_loops = tree_loop_optimizer_init (dump_file);
+  if (!current_loops)
+    return;
+  scev_initialize (current_loops);
 }
   
 struct tree_opt_pass pass_loop_init = 
@@ -149,6 +153,40 @@ struct tree_opt_pass pass_lim =
   TODO_dump_func                       /* todo_flags_finish */
 };
 
+/* Loop autovectorization.  */
+
+static void
+tree_vectorize (void)
+{
+  if (!current_loops)
+    return;
+
+  bitmap_clear (vars_to_rename);
+  vectorize_loops (current_loops);
+}
+
+static bool
+gate_tree_vectorize (void)
+{
+  return flag_tree_vectorize != 0;
+}
+
+struct tree_opt_pass pass_vectorize =
+{
+  "vect",                               /* name */
+  gate_tree_vectorize,                  /* gate */
+  tree_vectorize,                       /* execute */
+  NULL,                                 /* sub */
+  NULL,                                 /* next */
+  0,                                    /* static_pass_number */
+  TV_TREE_VECTORIZATION,                /* tv_id */
+  PROP_cfg | PROP_ssa,                  /* properties_required */
+  0,                                    /* properties_provided */
+  0,                                    /* properties_destroyed */
+  0,                                    /* todo_flags_start */
+  TODO_dump_func                       /* todo_flags_finish */
+};
+
 /* Loop optimizer finalization.  */
 
 static void
@@ -157,6 +195,8 @@ tree_ssa_loop_done (void)
   if (!current_loops)
     return;
 
+  scev_finalize ();
+
 #ifdef ENABLE_CHECKING
   verify_loop_closed_ssa ();
 #endif
index ee48b25b2145ac263f373f91014f3f8fd71d508a..220c391598e4ccc55e65b356ef759c2b3be5d7d4 100644 (file)
@@ -45,7 +45,6 @@ static void replace_phi_with_stmt (block_stmt_iterator, basic_block,
 static bool candidate_bb_for_phi_optimization (basic_block,
                                               basic_block *,
                                               basic_block *);
-static bool empty_block_p (basic_block);
 
 /* This pass eliminates PHI nodes which can be trivially implemented as
    an assignment from a conditional expression.  ie if we have something
@@ -147,7 +146,7 @@ tree_ssa_phiopt (void)
 
 /* Return TRUE if block BB has no executable statements, otherwise return
    FALSE.  */
-static bool
+bool
 empty_block_p (basic_block bb)
 {
   block_stmt_iterator bsi;
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
new file mode 100644 (file)
index 0000000..8369a6b
--- /dev/null
@@ -0,0 +1,3544 @@
+/* Loop Vectorization
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Contributed by Dorit Naishlos <dorit@il.ibm.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+/* Loop Vectorization Pass.
+
+   This pass tries to vectorize loops. This first implementation focuses on
+   simple inner-most loops, with no conditional control flow, and a set of
+   simple operations which vector form can be expressed using existing
+   tree codes (PLUS, MULT etc).
+
+   For example, the vectorizer transforms the following simple loop:
+
+       short a[N]; short b[N]; short c[N]; int i;
+
+       for (i=0; i<N; i++){
+         a[i] = b[i] + c[i];
+       }
+
+   as if it was manually vectorized by rewriting the source code into:
+
+       typedef int __attribute__((mode(V8HI))) v8hi;
+       short a[N];  short b[N]; short c[N];   int i;
+       v8hi *pa = (v8hi*)a, *pb = (v8hi*)b, *pc = (v8hi*)c;
+       v8hi va, vb, vc;
+
+       for (i=0; i<N/8; i++){
+         vb = pb[i];
+         vc = pc[i];
+         va = vb + vc;
+         pa[i] = va;
+       }
+
+       The main entry to this pass is vectorize_loops(), in which
+   the vectorizer applies a set of analyses on a given set of loops,
+   followed by the actual vectorization transformation for the loops that
+   had successfully passed the analysis phase.
+
+       Throughout this pass we make a distinction between two types of
+   data: scalars (which are represented by SSA_NAMES), and memory references
+   ("data-refs"). These two types of data require different handling both 
+   during analysis and transformation. The types of data-refs that the 
+   vectorizer currently supports are ARRAY_REFS that are one dimensional 
+   arrays which base is an array DECL (not a pointer), and INDIRECT_REFS 
+   through pointers; both array and pointer accesses are required to have a 
+   simple (consecutive) access pattern.
+
+   Analysis phase:
+   ===============
+       The driver for the analysis phase is vect_analyze_loop_nest().
+   It applies a set of analyses, some of which rely on the scalar evolution 
+   analyzer (scev) developed by Sebastian Pop.
+
+       During the analysis phase the vectorizer records some information
+   per stmt in a "stmt_vec_info" struct which is attached to each stmt in the 
+   loop, as well as general information about the loop as a whole, which is
+   recorded in a "loop_vec_info" struct attached to each loop.
+
+   Transformation phase:
+   =====================
+       The loop transformation phase scans all the stmts in the loop, and
+   creates a vector stmt (or a sequence of stmts) for each scalar stmt S in
+   the loop that needs to be vectorized. It insert the vector code sequence
+   just before the scalar stmt S, and records a pointer to the vector code
+   in STMT_VINFO_VEC_STMT (stmt_info) (stmt_info is the stmt_vec_info struct 
+   attached to S). This pointer will be used for the vectorization of following
+   stmts which use the def of stmt S. Stmt S is removed if it writes to memory;
+   otherwise, we rely on dead code elimination for removing it.
+
+       For example, say stmt S1 was vectorized into stmt VS1:
+
+   VS1: vb = px[i];
+   S1: b = x[i];    STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
+   S2:  a = b;
+
+   To vectorize stmt S2, the vectorizer first finds the stmt that defines
+   the operand 'b' (S1), and gets the relevant vector def 'vb' from the
+   vector stmt VS1 pointed by STMT_VINFO_VEC_STMT (stmt_info (S1)). The
+   resulting sequence would be:
+
+   VS1: vb = px[i];
+   S1: b = x[i];       STMT_VINFO_VEC_STMT (stmt_info (S1)) = VS1
+   VS2: va = vb;
+   S2:  a = b;          STMT_VINFO_VEC_STMT (stmt_info (S2)) = VS2
+
+       Operands that are not SSA_NAMEs, are data-refs that appear in 
+   load/store operations (like 'x[i]' in S1), and are handled differently.
+
+   Target modeling:
+   =================
+       Currently the only target specific information that is used is the
+   size of the vector (in bytes) - "UNITS_PER_SIMD_WORD". Targets that can 
+   support different sizes of vectors, for now will need to specify one value 
+   for "UNITS_PER_SIMD_WORD". More flexibility will be added in the future.
+
+       Since we only vectorize operations which vector form can be
+   expressed using existing tree codes, to verify that an operation is
+   supported, the vectorizer checks the relevant optab at the relevant
+   machine_mode (e.g, add_optab->handlers[(int) V8HImode].insn_code). If
+   the value found is CODE_FOR_nothing, then there's no target support, and
+   we can't vectorize the stmt.
+
+   For additional information on this project see:
+   http://gcc.gnu.org/projects/tree-ssa/vectorization.html
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "errors.h"
+#include "ggc.h"
+#include "tree.h"
+#include "target.h"
+
+#include "rtl.h"
+#include "basic-block.h"
+#include "diagnostic.h"
+#include "tree-flow.h"
+#include "tree-dump.h"
+#include "timevar.h"
+#include "cfgloop.h"
+#include "cfglayout.h"
+#include "expr.h"
+#include "optabs.h"
+#include "tree-chrec.h"
+#include "tree-data-ref.h"
+#include "tree-scalar-evolution.h"
+#include "tree-vectorizer.h"
+#include "tree-pass.h"
+
+/* Main analysis functions.  */
+static loop_vec_info vect_analyze_loop (struct loop *);
+static loop_vec_info vect_analyze_loop_form (struct loop *);
+static bool vect_analyze_data_refs (loop_vec_info);
+static bool vect_mark_stmts_to_be_vectorized (loop_vec_info);
+static bool vect_analyze_scalar_cycles (loop_vec_info);
+static bool vect_analyze_data_ref_accesses (loop_vec_info);
+static bool vect_analyze_data_refs_alignment (loop_vec_info);
+static void vect_compute_data_refs_alignment (loop_vec_info);
+static bool vect_analyze_operations (loop_vec_info);
+
+/* Main code transformation functions.  */
+static void vect_transform_loop (loop_vec_info, struct loops *);
+static void vect_transform_loop_bound (loop_vec_info);
+static bool vect_transform_stmt (tree, block_stmt_iterator *);
+static bool vectorizable_load (tree, block_stmt_iterator *, tree *);
+static bool vectorizable_store (tree, block_stmt_iterator *, tree *);
+static bool vectorizable_operation (tree, block_stmt_iterator *, tree *);
+static bool vectorizable_assignment (tree, block_stmt_iterator *, tree *);
+static void vect_align_data_ref (tree);
+static void vect_enhance_data_refs_alignment (loop_vec_info);
+
+/* Utility functions for the analyses.  */
+static bool vect_is_simple_use (tree , struct loop *, tree *);
+static bool exist_non_indexing_operands_for_use_p (tree, tree);
+static bool vect_is_simple_iv_evolution (unsigned, tree, tree *, tree *, bool);
+static void vect_mark_relevant (varray_type, tree);
+static bool vect_stmt_relevant_p (tree, loop_vec_info);
+static tree vect_get_loop_niters (struct loop *, HOST_WIDE_INT *);
+static void vect_compute_data_ref_alignment 
+  (struct data_reference *, loop_vec_info);
+static bool vect_analyze_data_ref_access (struct data_reference *);
+static bool vect_get_first_index (tree, tree *);
+static bool vect_can_force_dr_alignment_p (tree, unsigned int);
+static tree vect_get_base_decl_and_bit_offset (tree, tree *);
+static struct data_reference * vect_analyze_pointer_ref_access (tree, tree, bool);
+
+/* Utility functions for the code transformation.  */
+static tree vect_create_destination_var (tree, tree);
+static tree vect_create_data_ref (tree, block_stmt_iterator *);
+static tree vect_create_index_for_array_ref (tree, block_stmt_iterator *);
+static tree get_vectype_for_scalar_type (tree);
+static tree vect_get_new_vect_var (tree, enum vect_var_kind, const char *);
+static tree vect_get_vec_def_for_operand (tree, tree);
+static tree vect_init_vector (tree, tree);
+static void vect_finish_stmt_generation 
+  (tree stmt, tree vec_stmt, block_stmt_iterator *bsi);
+
+/* Utilities for creation and deletion of vec_info structs.  */
+loop_vec_info new_loop_vec_info (struct loop *loop);
+void destroy_loop_vec_info (loop_vec_info);
+stmt_vec_info new_stmt_vec_info (tree stmt, struct loop *loop);
+
+static bool vect_debug_stats (struct loop *loop);
+static bool vect_debug_details (struct loop *loop);
+
+
+/* Function new_stmt_vec_info.
+
+   Create and initialize a new stmt_vec_info struct for STMT.  */
+
+stmt_vec_info
+new_stmt_vec_info (tree stmt, struct loop *loop)
+{
+  stmt_vec_info res;
+  res = (stmt_vec_info) xcalloc (1, sizeof (struct _stmt_vec_info));
+
+  STMT_VINFO_TYPE (res) = undef_vec_info_type;
+  STMT_VINFO_STMT (res) = stmt;
+  STMT_VINFO_LOOP (res) = loop;
+  STMT_VINFO_RELEVANT_P (res) = 0;
+  STMT_VINFO_VECTYPE (res) = NULL;
+  STMT_VINFO_VEC_STMT (res) = NULL;
+  STMT_VINFO_DATA_REF (res) = NULL;
+  STMT_VINFO_MEMTAG (res) = NULL;
+
+  return res;
+}
+
+
+/* Function new_loop_vec_info.
+
+   Create and initialize a new loop_vec_info struct for LOOP, as well as
+   stmt_vec_info structs for all the stmts in LOOP.  */
+
+loop_vec_info
+new_loop_vec_info (struct loop *loop)
+{
+  loop_vec_info res;
+  basic_block *bbs;
+  block_stmt_iterator si;
+  unsigned int i;
+
+  res = (loop_vec_info) xcalloc (1, sizeof (struct _loop_vec_info));
+
+  bbs = get_loop_body (loop);
+
+  /* Create stmt_info for all stmts in the loop.  */
+  for (i = 0; i < loop->num_nodes; i++)
+    {
+      basic_block bb = bbs[i];
+      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+       {
+         tree stmt = bsi_stmt (si);
+         stmt_ann_t ann;
+
+         get_stmt_operands (stmt);
+         ann = stmt_ann (stmt);
+         set_stmt_info (ann, new_stmt_vec_info (stmt, loop));
+       }
+    }
+
+  LOOP_VINFO_LOOP (res) = loop;
+  LOOP_VINFO_BBS (res) = bbs;
+  LOOP_VINFO_EXIT_COND (res) = NULL;
+  LOOP_VINFO_NITERS (res) = -1;
+  LOOP_VINFO_VECTORIZABLE_P (res) = 0;
+  LOOP_VINFO_VECT_FACTOR (res) = 0;
+  VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_WRITES (res), 20,
+                          "loop_write_datarefs");
+  VARRAY_GENERIC_PTR_INIT (LOOP_VINFO_DATAREF_READS (res), 20,
+                          "loop_read_datarefs");
+  return res;
+}
+
+
+/* Function destroy_loop_vec_info.
+   Free LOOP_VINFO struct, as well as all the stmt_vec_info structs of all the 
+   stmts in the loop.  */
+
+void
+destroy_loop_vec_info (loop_vec_info loop_vinfo)
+{
+  struct loop *loop;
+  basic_block *bbs;
+  int nbbs;
+  block_stmt_iterator si;
+  int j;
+
+  if (!loop_vinfo)
+    return;
+
+  loop = LOOP_VINFO_LOOP (loop_vinfo);
+
+  bbs = LOOP_VINFO_BBS (loop_vinfo);
+  nbbs = loop->num_nodes;
+
+  for (j = 0; j < nbbs; j++)
+    {
+      basic_block bb = bbs[j];
+      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+       {
+         tree stmt = bsi_stmt (si);
+         stmt_ann_t ann = stmt_ann (stmt);
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         free (stmt_info);
+         set_stmt_info (ann, NULL);
+       }
+    }
+
+  free (LOOP_VINFO_BBS (loop_vinfo));
+  varray_clear (LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
+  varray_clear (LOOP_VINFO_DATAREF_READS (loop_vinfo));
+
+  free (loop_vinfo);
+}
+
+
+/* Function debug_loop_stats.
+
+   For vectorization statistics dumps.  */
+
+static bool
+vect_debug_stats (struct loop *loop)
+{
+  basic_block bb;
+  block_stmt_iterator si;
+  tree node = NULL_TREE;
+
+  if (!dump_file || !(dump_flags & TDF_STATS))
+    return false;
+
+  if (!loop)
+    {
+      fprintf (dump_file, "\n");
+      return true;
+    }
+
+  if (!loop->header)
+    return false;
+
+  bb = loop->header;
+
+  for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+    {
+      node = bsi_stmt (si);
+      if (node && EXPR_P (node) && EXPR_LOCUS (node))
+        break;
+    }
+
+  if (node && EXPR_P (node) && EXPR_LOCUS (node) 
+      && EXPR_FILENAME (node) && EXPR_LINENO (node))
+    {
+      fprintf (dump_file, "\nloop at %s:%d: ", 
+       EXPR_FILENAME (node), EXPR_LINENO (node));
+      return true;
+    }
+
+  return false;
+}
+
+
+/* Function debug_loop_details.
+
+   For vectorization debug dumps.  */
+
+static bool
+vect_debug_details (struct loop *loop)
+{
+   basic_block bb;
+   block_stmt_iterator si;
+   tree node = NULL_TREE;
+
+  if (!dump_file || !(dump_flags & TDF_DETAILS))
+    return false;
+
+  if (!loop)
+    {
+      fprintf (dump_file, "\n");
+      return true;
+    }
+
+  if (!loop->header)
+    return false;
+
+  bb = loop->header;
+
+  for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+    {
+      node = bsi_stmt (si);
+      if (node && EXPR_P (node) && EXPR_LOCUS (node))
+       break;
+    }
+
+  if (node && EXPR_P (node) && EXPR_LOCUS (node)
+      && EXPR_FILENAME (node) && EXPR_LINENO (node))
+    {
+      fprintf (dump_file, "\nloop at %s:%d: ", 
+               EXPR_FILENAME (node), EXPR_LINENO (node));
+      return true;
+    }
+
+  return false;
+}
+
+
+/*  THIS IS A COPY OF THE FUNCTION IN TREE-SSA-IVOPTS.C, MODIFIED
+    TO NOT USE FORCE_GIMPLE_OPERAND.  When that function is accepted
+    into he mainline, This function can go away and be replaced by it.
+    Creates an induction variable with value BASE + STEP * iteration in
+    LOOP.  It is expected that neither BASE nor STEP are shared with
+    other expressions (unless the sharing rules allow this).  Use VAR
+    as a base var_decl for it (if NULL, a new temporary will be
+    created).  The increment will occur at INCR_POS (after it if AFTER
+    is true, before it otherwise).  The ssa versions of the variable
+    before and after increment will be stored in VAR_BEFORE and
+    VAR_AFTER (unless they are NULL).  */
+
+static void
+vect_create_iv_simple (tree base, tree step, tree var, struct loop *loop,
+                          block_stmt_iterator *incr_pos, bool after,
+                          tree *var_before, tree *var_after)
+{
+   tree stmt, stmts, initial;
+   tree vb, va;
+   stmts = NULL;
+
+   if (!var)
+     {
+       var = create_tmp_var (TREE_TYPE (base), "ivtmp");
+       add_referenced_tmp_var (var);
+     }
+
+   vb = make_ssa_name (var, build_empty_stmt ());
+   if (var_before)
+     *var_before = vb;
+   va = make_ssa_name (var, build_empty_stmt ());
+   if (var_after)
+     *var_after = va;
+
+   stmt = build (MODIFY_EXPR, void_type_node, va,
+                build (PLUS_EXPR, TREE_TYPE (base), vb, step));
+   SSA_NAME_DEF_STMT (va) = stmt;
+   if (after)
+     bsi_insert_after (incr_pos, stmt, BSI_NEW_STMT);
+   else
+     bsi_insert_before (incr_pos, stmt, BSI_NEW_STMT);
+
+   /* Our base is always a GIMPLE variable, thus, we don't need to
+      force_gimple_operand it.  */
+   initial = base;
+   if (stmts)
+     {
+       edge pe = loop_preheader_edge (loop);
+       bsi_insert_on_edge (pe, stmts);
+     }
+
+   stmt = create_phi_node (vb, loop->header);
+   SSA_NAME_DEF_STMT (vb) = stmt;
+   add_phi_arg (&stmt, initial, loop_preheader_edge (loop));
+   add_phi_arg (&stmt, va, loop_latch_edge (loop));
+}
+
+
+/* Function vect_get_base_decl_and_bit_offset
+   
+   Get the decl from which the data reference REF is based, 
+   and compute the OFFSET from it in bits on the way.  
+   FORNOW: Handle only component-refs that consist of
+   VAR_DECLs (no ARRAY_REF or INDIRECT_REF).  */
+
+static tree 
+vect_get_base_decl_and_bit_offset (tree ref, tree *offset)
+{
+  tree decl;
+  if (TREE_CODE (ref) == VAR_DECL)
+    return ref;
+
+  if (TREE_CODE (ref) == COMPONENT_REF)
+    {
+      tree this_offset;
+      tree oprnd0 = TREE_OPERAND (ref, 0);
+      tree oprnd1 = TREE_OPERAND (ref, 1);
+
+      this_offset = bit_position (oprnd1);
+      if (!host_integerp (this_offset,1))
+       return NULL_TREE;
+       
+      decl = vect_get_base_decl_and_bit_offset (oprnd0, offset);
+
+      if (decl)
+       {
+          *offset = int_const_binop (PLUS_EXPR, *offset, this_offset, 1);
+
+          if (!host_integerp (*offset,1) || TREE_OVERFLOW (*offset)) 
+           return NULL_TREE;
+
+         if (vect_debug_details (NULL))
+           {
+             print_generic_expr (dump_file, ref, TDF_SLIM);
+             fprintf (dump_file, " --> total offset for ref: ");
+             print_generic_expr (dump_file, *offset, TDF_SLIM);
+           }
+       }
+
+      return decl;
+    }
+
+  /* TODO: extend to handle more cases.  */
+  return NULL_TREE;
+}
+
+
+/* Function vect_force_dr_alignment_p.
+
+   Returns whether the alignment of a DECL can be forced to be aligned
+   on ALIGNMENT bit boundary.  */
+
+static bool 
+vect_can_force_dr_alignment_p (tree decl, unsigned int alignment)
+{
+  if (TREE_CODE (decl) != VAR_DECL)
+    return false;
+
+  if (DECL_EXTERNAL (decl))
+    return false;
+
+  if (TREE_STATIC (decl))
+    return (alignment <= MAX_OFILE_ALIGNMENT);
+  else
+    return (alignment <= STACK_BOUNDARY);
+}
+
+
+/* Function vect_get_new_vect_var.
+
+   Returns a name for a new variable. The current naming scheme appends the 
+   prefix "vect_" or "vect_p" (depending on the value of VAR_KIND) to 
+   the name of vectorizer generated variables, and appends that to NAME if 
+   provided.  */
+
+static tree
+vect_get_new_vect_var (tree type, enum vect_var_kind var_kind, const char *name)
+{
+  const char *prefix;
+  int prefix_len;
+  tree new_vect_var;
+
+  if (var_kind == vect_simple_var)
+    prefix = "vect_"; 
+  else
+    prefix = "vect_p";
+
+  prefix_len = strlen (prefix);
+
+  if (name)
+    new_vect_var = create_tmp_var (type, concat (prefix, name, NULL));
+  else
+    new_vect_var = create_tmp_var (type, prefix);
+
+  return new_vect_var;
+}
+
+
+/* Function create_index_for_array_ref.
+
+   Create (and return) an index variable, along with it's update chain in the
+   loop. This variable will be used to access a memory location in a vector
+   operation.
+
+   Input:
+   STMT: The stmt that contains a memory data-ref.
+   BSI: The block_stmt_iterator where STMT is. Any new stmts created by this
+        function can be added here, or in the loop pre-header.
+
+   FORNOW: We are only handling array accesses with step 1.  */
+
+static tree
+vect_create_index_for_array_ref (tree stmt, block_stmt_iterator *bsi)
+{
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  struct loop *loop = STMT_VINFO_LOOP (stmt_info);
+  struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
+  tree expr = DR_REF (dr);
+  tree access_fn;
+  tree init, step;
+  loop_vec_info loop_info = loop->aux;
+  int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_info);
+  tree vf;
+  tree array_first_index;
+  tree indx_before_incr, indx_after_incr;
+  int loopnum = loop->num;
+  bool ok;
+#ifdef ENABLE_CHECKING
+  varray_type access_fns = DR_ACCESS_FNS (dr);
+
+  /* FORNOW: handling only one dimensional arrays.  */
+  if (VARRAY_ACTIVE_SIZE (access_fns) != 1)
+    abort ();
+
+  if (!vectorization_factor)
+    abort ();
+#endif
+
+  access_fn = DR_ACCESS_FN (dr, 0);
+  ok = vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step, true)
+       && vect_get_first_index (expr, &array_first_index);
+
+#ifdef ENABLE_CHECKING
+  if (!ok)
+    abort ();
+
+  /* FORNOW: Handling only constant 'init'.  */
+  if (TREE_CODE (init) != INTEGER_CST)
+    abort ();  
+#endif
+
+  vf = build_int_cst (unsigned_type_node, vectorization_factor, 0);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "int vf = %d",vectorization_factor);
+      fprintf (dump_file, ", vf:");
+      print_generic_expr (dump_file, vf, TDF_SLIM);
+      fprintf (dump_file, ", init:");
+      print_generic_expr (dump_file, init, TDF_SLIM);
+      fprintf (dump_file, ", array_first_index:");
+      print_generic_expr (dump_file, array_first_index, TDF_SLIM);
+    }
+
+  /* Calculate the 'init' of the new index.
+     init = (init - array_first_index) / vectorization_factor  */
+  init = int_const_binop (TRUNC_DIV_EXPR,
+                 int_const_binop (MINUS_EXPR, init, array_first_index, 1),
+                 vf, 1);
+
+  /* Calculate the 'step' of the new index.  FORNOW: always 1.  */
+  step = size_one_node;
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "create iv for (");
+      print_generic_expr (dump_file, init, TDF_SLIM);
+      fprintf (dump_file, ", + ,");
+      print_generic_expr (dump_file, step, TDF_SLIM);
+      fprintf (dump_file, ")");
+    }
+
+  /* both init and step are guaranted to be gimple expressions,
+     so we can use vect_create_iv_simple.  */
+  vect_create_iv_simple (init, step, NULL, loop, bsi, false, 
+       &indx_before_incr, &indx_after_incr); 
+
+  return indx_before_incr;
+}
+
+
+/* Function get_vectype_for_scalar_type.
+
+   Returns the vector type corresponding to SCALAR_TYPE as supported
+   by the target.  */
+
+static tree
+get_vectype_for_scalar_type (tree scalar_type)
+{
+  enum machine_mode inner_mode = TYPE_MODE (scalar_type);
+  int nbytes = GET_MODE_SIZE (inner_mode);
+  int nunits;
+
+  if (nbytes == 0)
+    return NULL_TREE;
+
+  /* FORNOW: Only a single vector size per target (UNITS_PER_SIMD_WORD)
+     is expected.  */
+  nunits = UNITS_PER_SIMD_WORD / nbytes;
+
+  return build_vector_type (scalar_type, nunits);
+}
+
+
+/* Function vect_align_data_ref.
+
+   Handle mislignment of a memory accesses.
+
+   FORNOW: Can't handle misaligned accesses. 
+   Make sure that the dataref is aligned.  */
+
+static void
+vect_align_data_ref (tree stmt)
+{
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
+
+  /* FORNOW: can't handle misaligned accesses; 
+             all accesses expected to be aligned.  */
+  if (!aligned_access_p (dr))
+    abort ();
+}
+
+
+/* Function vect_create_data_ref.
+
+   Create a memory reference expression for vector access, to be used in a
+   vector load/store stmt.
+
+   Input:
+   STMT: a stmt that references memory. expected to be of the form
+        MODIFY_EXPR <name, data-ref> or MODIFY_EXPR <data-ref, name>.
+   BSI: block_stmt_iterator where new stmts can be added.
+
+   Output:
+   1. Declare a new ptr to vector_type, and have it point to the array base.
+      For example, for vector of type V8HI:
+      v8hi *p0;
+      p0 = (v8hi *)&a;
+   2. Create a data-reference based on the new vector pointer p0, and using
+      a new index variable 'idx'. Return the expression '(*p0)[idx]'.
+
+   FORNOW: handle only aligned and consecutive accesses.  */
+
+static tree
+vect_create_data_ref (tree stmt, block_stmt_iterator *bsi)
+{
+  tree new_base;
+  tree data_ref;
+  tree idx;
+  tree vec_stmt;
+  tree new_temp;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  tree vect_ptr_type;
+  tree vect_ptr;
+  tree addr_ref;
+  v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+  v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+  vuse_optype vuses = STMT_VUSE_OPS (stmt);
+  int nvuses, nv_may_defs, nv_must_defs;
+  int i;
+  struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info);
+  tree array_type;
+  tree base_addr = NULL_TREE;
+  struct loop *loop = STMT_VINFO_LOOP (stmt_info);
+  edge pe;
+  tree tag;
+  tree addr_expr;
+  tree scalar_ptr_type;
+
+  /* FORNOW: make sure the data reference is aligned.  */
+  vect_align_data_ref (stmt);
+
+  addr_ref = DR_BASE_NAME (dr);
+
+  array_type = build_array_type (vectype, 0);
+  TYPE_ALIGN (array_type) = TYPE_ALIGN (TREE_TYPE (addr_ref));
+  vect_ptr_type = build_pointer_type (array_type);
+  scalar_ptr_type = build_pointer_type (TREE_TYPE (addr_ref));
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "create array_ref of type: ");
+      print_generic_expr (dump_file, vectype, TDF_SLIM);
+    }
+
+  /*** create: vectype_array *p;  ***/
+  vect_ptr = vect_get_new_vect_var (vect_ptr_type, vect_pointer_var, 
+               get_name (addr_ref));
+  add_referenced_tmp_var (vect_ptr);
+
+#ifdef ENABLE_CHECKING
+  if (TREE_CODE (addr_ref) != VAR_DECL
+      && TREE_CODE (addr_ref) != COMPONENT_REF
+      && TREE_CODE (addr_ref) != SSA_NAME)
+    abort ();
+#endif
+
+  if (vect_debug_details (NULL))
+    {
+      if (TREE_CODE (addr_ref) == VAR_DECL)
+       fprintf (dump_file, "vectorizing an array ref: ");
+      else if (TREE_CODE (addr_ref) == SSA_NAME)
+       fprintf (dump_file, "vectorizing a pointer ref: ");
+      else if (TREE_CODE (addr_ref) == COMPONENT_REF)
+       fprintf (dump_file, "vectorizing a record ref: ");
+      print_generic_expr (dump_file, addr_ref, TDF_SLIM);
+    }
+
+  /* Get base address:  */
+  if (TREE_CODE (addr_ref) == SSA_NAME)
+    base_addr = addr_ref;
+  else
+    base_addr = build_fold_addr_expr (addr_ref);
+
+  /* Handle aliasing:  */ 
+  tag = STMT_VINFO_MEMTAG (stmt_info);
+#ifdef ENABLE_CHECKING
+  if (!tag)
+    abort ();
+#endif
+  get_var_ann (vect_ptr)->type_mem_tag = tag;
+  
+  /* Mark for renaming all aliased variables
+     (i.e, the may-aliases of the type-mem-tag) */
+  nvuses = NUM_VUSES (vuses);
+  nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
+  nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
+  for (i = 0; i < nvuses; i++)
+    {
+      tree use = VUSE_OP (vuses, i);
+      if (TREE_CODE (use) == SSA_NAME)
+        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (use))->uid);
+    }
+  for (i = 0; i < nv_may_defs; i++)
+    {
+      tree def = V_MAY_DEF_RESULT (v_may_defs, i);
+      if (TREE_CODE (def) == SSA_NAME)
+        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
+    }
+  for (i = 0; i < nv_must_defs; i++)
+    {
+      tree def = V_MUST_DEF_OP (v_must_defs, i);
+      if (TREE_CODE (def) == SSA_NAME)
+        bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
+    }
+
+  pe = loop_preheader_edge (loop);
+
+  /*** create: p = (vectype *)&a; ***/
+
+  /* addr_expr = &a */
+  addr_expr = vect_get_new_vect_var (scalar_ptr_type, vect_pointer_var,
+                                       get_name (addr_ref));
+  add_referenced_tmp_var (addr_expr);
+  vec_stmt = build2 (MODIFY_EXPR, void_type_node, addr_expr, base_addr);
+  new_temp = make_ssa_name (addr_expr, vec_stmt);
+  TREE_OPERAND (vec_stmt, 0) = new_temp;
+  bsi_insert_on_edge (pe, vec_stmt);
+
+  /* vect_ptr = (vectype_array *)&a; */
+  vec_stmt = fold_convert (vect_ptr_type, new_temp); 
+  vec_stmt = build2 (MODIFY_EXPR, void_type_node, vect_ptr, vec_stmt);
+  new_temp = make_ssa_name (vect_ptr, vec_stmt);
+  TREE_OPERAND (vec_stmt, 0) = new_temp;
+  bsi_insert_on_edge (pe, vec_stmt);
+
+  /*** create data ref: '(*p)[idx]' ***/
+
+  idx = vect_create_index_for_array_ref (stmt, bsi);
+
+  new_base = build_fold_indirect_ref (new_temp);
+  data_ref = build4 (ARRAY_REF, vectype, new_base, idx, NULL_TREE, NULL_TREE);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "created new data-ref: ");
+      print_generic_expr (dump_file, data_ref, TDF_SLIM);
+    }
+
+  return data_ref;
+}
+
+
+/* Function vect_create_destination_var.
+
+   Create a new temporary of type VECTYPE.  */
+
+static tree
+vect_create_destination_var (tree scalar_dest, tree vectype)
+{
+  tree vec_dest;
+  const char *new_name;
+
+#ifdef ENABLE_CHECKING
+  if (TREE_CODE (scalar_dest) != SSA_NAME)
+    abort ();
+#endif
+
+  new_name = get_name (scalar_dest);
+  if (!new_name)
+    new_name = "var_";
+  vec_dest = vect_get_new_vect_var (vectype, vect_simple_var, new_name);
+  add_referenced_tmp_var (vec_dest);
+
+  return vec_dest;
+}
+
+
+/* Function vect_init_vector.
+
+   Insert a new stmt (INIT_STMT) that initializes a new vector variable with
+   the vector elements of VECTOR_VAR. Return the DEF of INIT_STMT. It will be
+   used in the vectorization of STMT.  */
+
+static tree
+vect_init_vector (tree stmt, tree vector_var)
+{
+  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  struct loop *loop = STMT_VINFO_LOOP (stmt_vinfo);
+  tree new_var;
+  tree init_stmt;
+  tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo); 
+  tree vec_oprnd;
+  edge pe;
+  tree new_temp;
+  new_var = vect_get_new_vect_var (vectype, vect_simple_var, "cst_");
+  add_referenced_tmp_var (new_var); 
+  init_stmt = build2 (MODIFY_EXPR, vectype, new_var, vector_var);
+  new_temp = make_ssa_name (new_var, init_stmt);
+  TREE_OPERAND (init_stmt, 0) = new_temp;
+
+  pe = loop_preheader_edge (loop);
+  bsi_insert_on_edge (pe, init_stmt);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "created new init_stmt: ");
+      print_generic_expr (dump_file, init_stmt, TDF_SLIM);
+    }
+
+  vec_oprnd = TREE_OPERAND (init_stmt, 0);
+  return vec_oprnd;
+}
+
+
+/* Function vect_get_vec_def_for_operand.
+
+   OP is an operand in STMT. This function returns a (vector) def that will be
+   used in the vectorized stmt for STMT.
+
+   In the case that OP is an SSA_NAME which is defined in the loop, then
+   STMT_VINFO_VEC_STMT of the defining stmt holds the relevant def.
+
+   In case OP is an invariant or constant, a new stmt that creates a vector def
+   needs to be introduced.  */
+
+static tree
+vect_get_vec_def_for_operand (tree op, tree stmt)
+{
+  tree vec_oprnd;
+  tree vec_stmt;
+  tree def_stmt;
+  stmt_vec_info def_stmt_info = NULL;
+  stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
+  int nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
+  struct loop *loop = STMT_VINFO_LOOP (stmt_vinfo);
+  basic_block bb;
+  tree vec_inv;
+  tree t = NULL_TREE;
+  tree def;
+  int i;
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "vect_get_vec_def_for_operand: ");
+      print_generic_expr (dump_file, op, TDF_SLIM);
+    }
+
+  /** ===> Case 1: operand is a constant.  **/
+
+  if (TREE_CODE (op) == INTEGER_CST || TREE_CODE (op) == REAL_CST)
+    {
+      /* Create 'vect_cst_ = {cst,cst,...,cst}'  */
+
+      tree vec_cst;
+      stmt_vec_info stmt_vinfo = vinfo_for_stmt (stmt);
+      tree vectype = STMT_VINFO_VECTYPE (stmt_vinfo);
+      int nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
+      tree t = NULL_TREE;
+      int i;
+
+      /* Build a tree with vector elements.  */
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "Create vector_cst. nunits = %d", nunits);
+
+      for (i = nunits - 1; i >= 0; --i)
+        {
+          t = tree_cons (NULL_TREE, op, t);
+        }
+      vec_cst = build_vector (vectype, t);
+      return vect_init_vector (stmt, vec_cst);
+    }
+
+#ifdef ENABLE_CHECKING
+  if (TREE_CODE (op) != SSA_NAME)
+    abort ();
+#endif
+  /** ===> Case 2: operand is an SSA_NAME - find the stmt that defines it.  **/
+
+  def_stmt = SSA_NAME_DEF_STMT (op);
+  def_stmt_info = vinfo_for_stmt (def_stmt);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "vect_get_vec_def_for_operand: def_stmt: ");
+      print_generic_expr (dump_file, def_stmt, TDF_SLIM);
+    }
+
+
+  /** ==> Case 2.1: operand is defined inside the loop.  **/
+
+  if (def_stmt_info)
+    {
+      /* Get the def from the vectorized stmt.  */
+
+      vec_stmt = STMT_VINFO_VEC_STMT (def_stmt_info);
+#ifdef ENABLE_CHECKING
+      if (!vec_stmt)
+        abort ();
+#endif
+      vec_oprnd = TREE_OPERAND (vec_stmt, 0);
+      return vec_oprnd;
+    }
+
+
+  /** ==> Case 2.2: operand is defined by the loop-header phi-node - 
+                    it is a reduction/induction.  **/
+
+  bb = bb_for_stmt (def_stmt);
+  if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "reduction/induction - unsupported.");
+      abort (); /* FORNOW no support for reduction/induction.  */
+    }
+
+
+  /** ==> Case 2.3: operand is defined outside the loop - 
+                    it is a loop invariant.  */
+
+  switch (TREE_CODE (def_stmt))
+    {
+    case PHI_NODE:
+      def = PHI_RESULT (def_stmt);
+      break;
+    case MODIFY_EXPR:
+      def = TREE_OPERAND (def_stmt, 0);
+      break;
+    case NOP_EXPR:
+      def = TREE_OPERAND (def_stmt, 0);
+#ifdef ENABLE_CHECKING
+      if (!IS_EMPTY_STMT (def_stmt))
+       abort ();
+#endif
+      def = op;
+      break;
+    default:
+      if (vect_debug_details (NULL))
+       {
+          fprintf (dump_file, "unsupported defining stmt: ");
+         print_generic_expr (dump_file, def_stmt, TDF_SLIM);
+       }
+      abort ();
+    }
+
+  /* Build a tree with vector elements. Create 'vec_inv = {inv,inv,..,inv}'  */
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "Create vector_inv.");
+
+  for (i = nunits - 1; i >= 0; --i)
+    {
+      t = tree_cons (NULL_TREE, def, t);
+    }
+
+  vec_inv = build_constructor (vectype, t);
+  return vect_init_vector (stmt, vec_inv);
+}
+
+
+/* Function vect_finish_stmt_generation.
+
+   Insert a new stmt.  */
+
+static void
+vect_finish_stmt_generation (tree stmt, tree vec_stmt, block_stmt_iterator *bsi)
+{
+  bsi_insert_before (bsi, vec_stmt, BSI_SAME_STMT);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "add new stmt: ");
+      print_generic_expr (dump_file, vec_stmt, TDF_SLIM);
+    }
+
+  /* Make sure bsi points to the stmt that is being vectorized.  */
+
+  /* Assumption: any stmts created for the vectorization of smtmt S are
+     inserted before S. BSI may point to S or some new stmt before it.  */
+
+  while (stmt != bsi_stmt (*bsi) && !bsi_end_p (*bsi))
+    bsi_next (bsi);
+#ifdef ENABLE_CHECKING
+  if (stmt != bsi_stmt (*bsi))
+    abort ();
+#endif
+}
+
+
+/* Function vectorizable_assignment.
+
+   Check if STMT performs an assignment (copy) that can be vectorized. 
+   If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
+   stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+   Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+
+static bool
+vectorizable_assignment (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+{
+  tree vec_dest;
+  tree scalar_dest;
+  tree op;
+  tree vec_oprnd;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  struct loop *loop = STMT_VINFO_LOOP (stmt_info);
+  tree new_temp;
+
+  /* Is vectorizable assignment?  */
+
+  if (TREE_CODE (stmt) != MODIFY_EXPR)
+    return false;
+
+  scalar_dest = TREE_OPERAND (stmt, 0);
+  if (TREE_CODE (scalar_dest) != SSA_NAME)
+    return false;
+
+  op = TREE_OPERAND (stmt, 1);
+  if (!vect_is_simple_use (op, loop, NULL))
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "use not simple.");
+      return false;
+    }
+
+  if (!vec_stmt) /* transformation not required.  */
+    {
+      STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
+      return true;
+    }
+
+  /** Trasform.  **/
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "transform assignment.");
+
+  /* Handle def.  */
+  vec_dest = vect_create_destination_var (scalar_dest, vectype);
+
+  /* Handle use.  */
+  op = TREE_OPERAND (stmt, 1);
+  vec_oprnd = vect_get_vec_def_for_operand (op, stmt);
+
+  /* Arguments are ready. create the new vector stmt.  */
+  *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, vec_oprnd);
+  new_temp = make_ssa_name (vec_dest, *vec_stmt);
+  TREE_OPERAND (*vec_stmt, 0) = new_temp;
+  vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+  
+  return true;
+}
+
+
+/* Function vectorizable_operation.
+
+   Check if STMT performs a binary or unary operation that can be vectorized. 
+   If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
+   stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+   Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+
+static bool
+vectorizable_operation (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+{
+  tree vec_dest;
+  tree scalar_dest;
+  tree operation;
+  tree op0, op1 = NULL;
+  tree vec_oprnd0, vec_oprnd1=NULL;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  struct loop *loop = STMT_VINFO_LOOP (stmt_info);
+  int i;
+  enum tree_code code;
+  enum machine_mode vec_mode;
+  tree new_temp;
+  int op_type;
+  tree op;
+  optab optab;
+
+  /* Is STMT a vectorizable binary/unary operation?   */
+  if (TREE_CODE (stmt) != MODIFY_EXPR)
+    return false;
+
+  if (TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
+    return false;
+
+  operation = TREE_OPERAND (stmt, 1);
+  code = TREE_CODE (operation);
+  optab = optab_for_tree_code (code, vectype);
+
+  /* Support only unary or binary operations.  */
+  op_type = TREE_CODE_LENGTH (code);
+  if (op_type != unary_op && op_type != binary_op)
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "num. args = %d (not unary/binary op).", op_type);
+      return false;
+    }
+
+  for (i = 0; i < op_type; i++)
+    {
+      op = TREE_OPERAND (operation, i);
+      if (!vect_is_simple_use (op, loop, NULL))
+       {
+         if (vect_debug_details (NULL))
+           fprintf (dump_file, "use not simple.");
+         return false;
+       }       
+    } 
+
+  /* Supportable by target?  */
+  if (!optab)
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "no optab.");
+      return false;
+    }
+  vec_mode = TYPE_MODE (vectype);
+  if (optab->handlers[(int) vec_mode].insn_code == CODE_FOR_nothing)
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "op not supported by target.");
+      return false;
+    }
+
+  if (!vec_stmt) /* transformation not required.  */
+    {
+      STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
+      return true;
+    }
+
+  /** Trasform.  **/
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "transform binary/unary operation.");
+
+  /* Handle def.  */
+  scalar_dest = TREE_OPERAND (stmt, 0);
+  vec_dest = vect_create_destination_var (scalar_dest, vectype);
+
+  /* Handle uses.  */
+  op0 = TREE_OPERAND (operation, 0);
+  vec_oprnd0 = vect_get_vec_def_for_operand (op0, stmt);
+
+  if (op_type == binary_op)
+    {
+      op1 = TREE_OPERAND (operation, 1);
+      vec_oprnd1 = vect_get_vec_def_for_operand (op1, stmt); 
+    }
+
+  /* Arguments are ready. create the new vector stmt.  */
+
+  if (op_type == binary_op)
+    *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
+               build2 (code, vectype, vec_oprnd0, vec_oprnd1));
+  else
+    *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest,
+               build1 (code, vectype, vec_oprnd0));
+  new_temp = make_ssa_name (vec_dest, *vec_stmt);
+  TREE_OPERAND (*vec_stmt, 0) = new_temp;
+  vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+
+  return true;
+}
+
+
+/* Function vectorizable_store.
+
+   Check if STMT defines a non scalar data-ref (array/pointer/structure) that 
+   can be vectorized. 
+   If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
+   stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+   Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+
+static bool
+vectorizable_store (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+{
+  tree scalar_dest;
+  tree data_ref;
+  tree op;
+  tree vec_oprnd1;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  struct loop *loop = STMT_VINFO_LOOP (stmt_info);
+  enum machine_mode vec_mode;
+
+  /* Is vectorizable store? */
+
+  if (TREE_CODE (stmt) != MODIFY_EXPR)
+    return false;
+
+  scalar_dest = TREE_OPERAND (stmt, 0);
+  if (TREE_CODE (scalar_dest) != ARRAY_REF
+      && TREE_CODE (scalar_dest) != INDIRECT_REF)
+    return false;
+
+  op = TREE_OPERAND (stmt, 1);
+  if (!vect_is_simple_use (op, loop, NULL))
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "use not simple.");
+      return false;
+    }
+
+  vec_mode = TYPE_MODE (vectype);
+  /* FORNOW. In some cases can vectorize even if data-type not supported
+     (e.g. - array initialization with 0).  */
+  if (mov_optab->handlers[(int)vec_mode].insn_code == CODE_FOR_nothing)
+    return false;
+
+  if (!STMT_VINFO_DATA_REF (stmt_info))
+    return false;
+
+  if (!vec_stmt) /* transformation not required.  */
+    {
+      STMT_VINFO_TYPE (stmt_info) = store_vec_info_type;
+      return true;
+    }
+
+  /** Trasform.  **/
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "transform store");
+
+  /* Handle use - get the vectorized def from the defining stmt.  */
+  vec_oprnd1 = vect_get_vec_def_for_operand (op, stmt);
+
+  /* Handle def.  */
+  data_ref = vect_create_data_ref (stmt, bsi);
+
+  /* Arguments are ready. create the new vector stmt.  */
+  *vec_stmt = build2 (MODIFY_EXPR, vectype, data_ref, vec_oprnd1);
+  vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+
+  return true;
+}
+
+
+/* vectorizable_load.
+
+   Check if STMT reads a non scalar data-ref (array/pointer/structure) that 
+   can be vectorized. 
+   If VEC_STMT is also passed, vectorize the STMT: create a vectorized 
+   stmt to replace it, put it in VEC_STMT, and insert it at BSI.
+   Return FALSE if not a vectorizable STMT, TRUE otherwise.  */
+
+static bool
+vectorizable_load (tree stmt, block_stmt_iterator *bsi, tree *vec_stmt)
+{
+  tree scalar_dest;
+  tree vec_dest = NULL;
+  tree data_ref = NULL;
+  tree op;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+  tree new_temp;
+  enum machine_mode vec_mode;
+
+  /* Is vectorizable load? */
+
+  if (TREE_CODE (stmt) != MODIFY_EXPR)
+    return false;
+
+  scalar_dest = TREE_OPERAND (stmt, 0);
+  if (TREE_CODE (scalar_dest) != SSA_NAME)
+    return false;
+
+  op = TREE_OPERAND (stmt, 1);
+  if (TREE_CODE (op) != ARRAY_REF && TREE_CODE (op) != INDIRECT_REF)
+    return false;
+
+  if (!STMT_VINFO_DATA_REF (stmt_info))
+    return false;
+
+  vec_mode = TYPE_MODE (vectype);
+  /* FORNOW. In some cases can vectorize even if data-type not supported
+     (e.g. - data copies).  */
+  if (mov_optab->handlers[(int)vec_mode].insn_code == CODE_FOR_nothing)
+    return false;
+
+  if (!vec_stmt) /* transformation not required.  */
+    {
+      STMT_VINFO_TYPE (stmt_info) = load_vec_info_type;
+      return true;
+    }
+
+  /** Trasform.  **/
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "transform load.");
+
+  /* Handle def.  */
+  vec_dest = vect_create_destination_var (scalar_dest, vectype);
+
+  /* Handle use.  */
+  op = TREE_OPERAND (stmt, 1);
+  data_ref = vect_create_data_ref (stmt, bsi);
+
+  /* Arguments are ready. create the new vector stmt.  */
+  *vec_stmt = build2 (MODIFY_EXPR, vectype, vec_dest, data_ref);
+  new_temp = make_ssa_name (vec_dest, *vec_stmt);
+  TREE_OPERAND (*vec_stmt, 0) = new_temp;
+  vect_finish_stmt_generation (stmt, *vec_stmt, bsi);
+
+  return true;
+}
+
+
+/* Function vect_transform_stmt.
+
+   Create a vectorized stmt to replace STMT, and insert it at BSI.  */
+
+static bool
+vect_transform_stmt (tree stmt, block_stmt_iterator *bsi)
+{
+  bool is_store = false;
+  tree vec_stmt = NULL_TREE;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+
+  switch (STMT_VINFO_TYPE (stmt_info))
+    {
+    case op_vec_info_type:
+      if (!vectorizable_operation (stmt, bsi, &vec_stmt))
+        abort ();
+      break;
+
+    case assignment_vec_info_type:
+      if (!vectorizable_assignment (stmt, bsi, &vec_stmt))
+       abort ();
+      break;
+
+    case load_vec_info_type:
+      if (!vectorizable_load (stmt, bsi, &vec_stmt))
+       abort ();
+      break;
+
+    case store_vec_info_type:
+      if (!vectorizable_store (stmt, bsi, &vec_stmt))
+       abort ();
+      is_store = true;
+      break;
+    default:
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "stmt not supported.");
+      abort ();
+    }
+
+  STMT_VINFO_VEC_STMT (stmt_info) = vec_stmt;
+
+  return is_store;
+}
+
+
+/* Function vect_transform_loop_bound.
+
+   Create a new exit condition for the loop.  */
+
+static void
+vect_transform_loop_bound (loop_vec_info loop_vinfo)
+{
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  edge exit_edge = loop->exit_edges[0];
+  block_stmt_iterator loop_exit_bsi = bsi_last (exit_edge->src);
+  tree indx_before_incr, indx_after_incr;
+  tree orig_cond_expr;
+  HOST_WIDE_INT old_N = 0;
+  int vf;
+  tree cond_stmt;
+  tree new_loop_bound;
+  tree cond;
+  tree lb_type;
+
+#ifdef ENABLE_CHECKING
+  if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
+    abort ();
+#endif
+  old_N = LOOP_VINFO_NITERS (loop_vinfo);
+  vf = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+
+#ifdef ENABLE_CHECKING
+  /* FORNOW: 
+     assuming number-of-iterations divides by the vectorization factor.  */
+  if (old_N % vf)
+    abort ();
+#endif
+
+  orig_cond_expr = LOOP_VINFO_EXIT_COND (loop_vinfo);
+#ifdef ENABLE_CHECKING
+  if (!orig_cond_expr)
+    abort ();
+#endif
+  if (orig_cond_expr != bsi_stmt (loop_exit_bsi))
+    abort ();
+
+  /* both init and step are guaranted to be gimple expressions,
+     so we can use vect_create_iv_simple.  */
+  vect_create_iv_simple (integer_zero_node, integer_one_node, NULL_TREE, loop, 
+       &loop_exit_bsi, false, &indx_before_incr, &indx_after_incr);
+
+  /* bsi_insert is using BSI_NEW_STMT. We need to bump it back 
+     to point to the exit condition. */
+  bsi_next (&loop_exit_bsi);
+  if (bsi_stmt (loop_exit_bsi) != orig_cond_expr)
+    abort ();
+
+  /* new loop exit test:  */
+  lb_type = TREE_TYPE (TREE_OPERAND (TREE_OPERAND (orig_cond_expr, 0), 1));
+  new_loop_bound = build_int_cst (lb_type, old_N/vf, 0);
+
+  if (exit_edge->flags & EDGE_TRUE_VALUE) /* 'then' edge exits the loop.  */
+    cond = build2 (GE_EXPR, boolean_type_node, indx_after_incr, new_loop_bound);
+  else /* 'then' edge loops back.   */
+    cond = build2 (LT_EXPR, boolean_type_node, indx_after_incr, new_loop_bound);
+
+  cond_stmt = build3 (COND_EXPR, TREE_TYPE (orig_cond_expr), cond,
+       TREE_OPERAND (orig_cond_expr, 1), TREE_OPERAND (orig_cond_expr, 2));
+
+  bsi_insert_before (&loop_exit_bsi, cond_stmt, BSI_SAME_STMT);   
+
+  /* remove old loop exit test:  */
+  bsi_remove (&loop_exit_bsi);
+
+  if (vect_debug_details (NULL))
+    print_generic_expr (dump_file, cond_stmt, TDF_SLIM);
+}
+
+
+/* Function vect_transform_loop.
+
+   The analysis phase has determined that the loop is vectorizable.
+   Vectorize the loop - created vectorized stmts to replace the scalar
+   stmts in the loop, and update the loop exit condition.  */
+
+static void
+vect_transform_loop (loop_vec_info loop_vinfo, 
+                    struct loops *loops ATTRIBUTE_UNUSED)
+{
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+  int nbbs = loop->num_nodes;
+  block_stmt_iterator si;
+  int i;
+#ifdef ENABLE_CHECKING
+  int vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
+#endif
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vec_transform_loop>>\n");
+
+  /* 1) Make sure the loop header has exactly two entries
+     2) Make sure we have a preheader basic block.  */
+
+  if (!loop->header->pred->pred_next
+      || loop->header->pred->pred_next->pred_next)
+    abort ();
+
+  loop_split_edge_with (loop_preheader_edge (loop), NULL);
+
+
+  /* FORNOW: the vectorizer supports only loops which body consist
+     of one basic block (header + empty latch). When the vectorizer will 
+     support more involved loop forms, the order by which the BBs are 
+     traversed need to be reconsidered.  */
+
+  for (i = 0; i < nbbs; i++)
+    {
+      basic_block bb = bbs[i];
+
+      for (si = bsi_start (bb); !bsi_end_p (si);)
+       {
+         tree stmt = bsi_stmt (si);
+         stmt_vec_info stmt_info;
+         bool is_store;
+#ifdef ENABLE_CHECKING
+         tree vectype;
+#endif
+
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "------>vectorizing statement: ");
+             print_generic_expr (dump_file, stmt, TDF_SLIM);
+           }   
+         stmt_info = vinfo_for_stmt (stmt);
+#ifdef ENABLE_CHECKING
+         if (!stmt_info)
+           abort ();
+#endif
+         if (!STMT_VINFO_RELEVANT_P (stmt_info))
+           {
+             bsi_next (&si);
+             continue;
+           }
+#ifdef ENABLE_CHECKING
+         /* FORNOW: Verify that all stmts operate on the same number of
+                    units and no inner unrolling is necessary.  */
+         vectype = STMT_VINFO_VECTYPE (stmt_info);
+         if (GET_MODE_NUNITS (TYPE_MODE (vectype)) != vectorization_factor)
+           abort ();
+#endif
+         /* -------- vectorize statement ------------ */
+         if (vect_debug_details (NULL))
+           fprintf (dump_file, "transform statement.");
+
+         is_store = vect_transform_stmt (stmt, &si);
+         if (is_store)
+           {
+             /* free the attached stmt_vec_info and remove the stmt.  */
+             stmt_ann_t ann = stmt_ann (stmt);
+             free (stmt_info);
+             set_stmt_info (ann, NULL);
+             bsi_remove (&si);
+             continue;
+           }
+
+         bsi_next (&si);
+       }                       /* stmts in BB */
+    }                          /* BBs in loop */
+
+  vect_transform_loop_bound (loop_vinfo);
+
+  if (vect_debug_details (loop))
+    fprintf (dump_file,"Success! loop vectorized.");
+  if (vect_debug_stats (loop))
+    fprintf (dump_file, "LOOP VECTORIZED.");
+}
+
+
+/* Function vect_is_simple_use.
+
+   Input:
+   LOOP - the loop that is being vectorized.
+   OPERAND - operand of a stmt in LOOP.
+   DEF - the defining stmt in case OPERAND is an SSA_NAME.
+
+   Returns whether a stmt with OPERAND can be vectorized.
+   Supportable operands are constants, loop invariants, and operands that are
+   defined by the current iteration of the loop. Unsupportable opernads are 
+   those that are defined by a previous iteration of the loop (as is the case
+   in reduction/induction computations).  */
+
+static bool
+vect_is_simple_use (tree operand, struct loop *loop, tree *def)
+{ 
+  tree def_stmt;
+  basic_block bb;
+
+  if (def)
+    *def = NULL_TREE;
+
+  if (TREE_CODE (operand) == INTEGER_CST || TREE_CODE (operand) == REAL_CST)
+    return true;
+
+  if (TREE_CODE (operand) != SSA_NAME)
+    return false;
+
+  def_stmt = SSA_NAME_DEF_STMT (operand);
+  if (def_stmt == NULL_TREE )
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "no def_stmt.");
+      return false;
+    }
+
+  /* empty stmt is expected only in case of a function argument.
+     (Otherwise - we expect a phi_node or a modify_expr).  */
+  if (IS_EMPTY_STMT (def_stmt))
+    {
+      tree arg = TREE_OPERAND (def_stmt, 0);
+      if (TREE_CODE (arg) == INTEGER_CST || TREE_CODE (arg) == REAL_CST)
+       return true;
+      if (vect_debug_details (NULL))
+       {
+         fprintf (dump_file, "Unexpected empty stmt: ");
+         print_generic_expr (dump_file, def_stmt, TDF_SLIM);
+       }
+      return false;  
+    }
+
+  /* phi_node inside the loop indicates an induction/reduction pattern.
+     This is not supported yet.  */
+  bb = bb_for_stmt (def_stmt);
+  if (TREE_CODE (def_stmt) == PHI_NODE && flow_bb_inside_loop_p (loop, bb))
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "reduction/induction - unsupported.");
+      return false; /* FORNOW: not supported yet.  */
+    }
+
+  /* Expecting a modify_expr or a phi_node.  */
+  if (TREE_CODE (def_stmt) == MODIFY_EXPR
+      || TREE_CODE (def_stmt) == PHI_NODE)
+    {
+      if (def)
+        *def = def_stmt;       
+      return true;
+    }
+
+  return false;
+}
+
+
+/* Function vect_analyze_operations.
+
+   Scan the loop stmts and make sure they are all vectorizable.  */
+
+static bool
+vect_analyze_operations (loop_vec_info loop_vinfo)
+{
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+  int nbbs = loop->num_nodes;
+  block_stmt_iterator si;
+  int vectorization_factor = 0;
+  int i;
+  bool ok;
+  tree scalar_type;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_analyze_operations>>\n");
+
+  for (i = 0; i < nbbs; i++)
+    {
+      basic_block bb = bbs[i];
+
+      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+       {
+         tree stmt = bsi_stmt (si);
+         int nunits;
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         tree vectype;
+
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "==> examining statement: ");
+             print_generic_expr (dump_file, stmt, TDF_SLIM);
+           }
+#ifdef ENABLE_CHECKING
+         if (!stmt_info)
+           abort ();
+#endif
+         /* skip stmts which do not need to be vectorized.
+            this is expected to include:
+            - the COND_EXPR which is the loop exit condition
+            - any LABEL_EXPRs in the loop
+            - computations that are used only for array indexing or loop
+            control  */
+
+         if (!STMT_VINFO_RELEVANT_P (stmt_info))
+           {
+             if (vect_debug_details (NULL))
+               fprintf (dump_file, "irrelevant.");
+             continue;
+           }
+
+         if (VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (stmt))))
+           {
+             if (vect_debug_stats (loop) || vect_debug_details (loop))
+               {
+                  fprintf (dump_file, "not vectorized: vector stmt in loop:");
+                 print_generic_expr (dump_file, stmt, TDF_SLIM);
+               }
+             return false;
+           }
+
+          if (STMT_VINFO_DATA_REF (stmt_info))
+            scalar_type = TREE_TYPE (DR_REF (STMT_VINFO_DATA_REF (stmt_info)));    
+          else if (TREE_CODE (stmt) == MODIFY_EXPR)
+           scalar_type = TREE_TYPE (TREE_OPERAND (stmt, 0));
+         else
+           scalar_type = TREE_TYPE (stmt);
+
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "get vectype for scalar type:  ");
+             print_generic_expr (dump_file, scalar_type, TDF_SLIM);
+           }
+
+         vectype = get_vectype_for_scalar_type (scalar_type);
+         if (!vectype)
+           {
+             if (vect_debug_stats (loop) || vect_debug_details (loop))
+               {
+                  fprintf (dump_file, "not vectorized: unsupported data-type ");
+                 print_generic_expr (dump_file, scalar_type, TDF_SLIM);
+               }
+             return false;
+           }
+
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "vectype: ");
+             print_generic_expr (dump_file, vectype, TDF_SLIM);
+           }
+         STMT_VINFO_VECTYPE (stmt_info) = vectype;
+
+         ok = (vectorizable_operation (stmt, NULL, NULL)
+               || vectorizable_assignment (stmt, NULL, NULL)
+               || vectorizable_load (stmt, NULL, NULL)
+               || vectorizable_store (stmt, NULL, NULL));
+
+         if (!ok)
+           {
+             if (vect_debug_stats (loop) || vect_debug_details (loop))
+               {
+                  fprintf (dump_file, "not vectorized: stmt not supported: ");
+                 print_generic_expr (dump_file, stmt, TDF_SLIM);
+               }
+             return false;
+           }
+
+         nunits = GET_MODE_NUNITS (TYPE_MODE (vectype));
+         if (vect_debug_details (NULL))
+           fprintf (dump_file, "nunits = %d", nunits);
+
+         if (vectorization_factor)
+           {
+             /* FORNOW: don't allow mixed units.
+                This restriction will be relaxed in the future.  */
+             if (nunits != vectorization_factor)
+               {
+                 if (vect_debug_stats (loop) || vect_debug_details (loop))
+                   fprintf (dump_file, "not vectorized: mixed data-types");
+                 return false;
+               }
+           }
+         else
+           vectorization_factor = nunits;
+       }
+    }
+
+  /* TODO: Analyze cost. Decide if worth while to vectorize.  */
+  if (!vectorization_factor)
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        fprintf (dump_file, "not vectorized: unsupported data-type");
+      return false;
+    }
+  LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
+
+  /* FORNOW: handle only cases where the loop bound divides by the
+     vectorization factor.  */
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, 
+       "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
+       vectorization_factor, LOOP_VINFO_NITERS (loop_vinfo));
+
+  if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)) 
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+       fprintf (dump_file, "not vectorized: Unknown loop bound.");
+      return false;
+    }
+
+  if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo) 
+      && LOOP_VINFO_NITERS (loop_vinfo) % vectorization_factor != 0)
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        fprintf (dump_file, "not vectorized: loop bound doesn't divided by %d.",
+                vectorization_factor);
+      return false;
+    }
+
+  return true;
+}
+
+
+/* Function exist_non_indexing_operands_for_use_p 
+
+   USE is one of the uses attached to STMT. Check if USE is 
+   used in STMT for anything other than indexing an array.  */
+
+static bool
+exist_non_indexing_operands_for_use_p (tree use, tree stmt)
+{
+  tree operand;
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  /* USE corresponds to some operand in STMT. If there is no data
+     reference in STMT, then any operand that corresponds to USE
+     is not indexing an array.  */
+  if (!STMT_VINFO_DATA_REF (stmt_info))
+    return true;
+  /* STMT has a data_ref. FORNOW this means that its of one of
+     the following forms:
+     -1- ARRAY_REF = var
+     -2- var = ARRAY_REF
+     (This should have been verified in analyze_data_refs).
+
+     'var' in the second case corresponds to a def, not a use,
+     so USE cannot correspond to any operands that are not used 
+     for array indexing.
+
+     Therefore, all we need to check is if STMT falls into the
+     first case, and whether var corresponds to USE.  */
+  if (TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
+    return false;
+
+  operand = TREE_OPERAND (stmt, 1);
+
+  if (TREE_CODE (operand) != SSA_NAME)
+    return false;
+
+  if (operand == use)
+    return true;
+
+  return false;
+}
+
+
+/* Function vect_is_simple_iv_evolution.
+
+   FORNOW: A simple evolution of an induction variables in the loop is
+   considered a polynomial evolution with constant step.  */
+
+static bool
+vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init, 
+                               tree * step, bool strict)
+{
+  tree init_expr;
+  tree step_expr;
+  
+  tree evolution_part = evolution_part_in_loop_num (access_fn, loop_nb);
+
+  /* When there is no evolution in this loop, the evolution function
+     is not "simple".  */  
+  if (evolution_part == NULL_TREE)
+    return false;
+  
+  /* When the evolution is a polynomial of degree >= 2
+     the evolution function is not "simple".  */
+  if (tree_is_chrec (evolution_part))
+    return false;
+  
+  step_expr = evolution_part;
+  init_expr = initial_condition (access_fn);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "step: ");
+      print_generic_expr (dump_file, step_expr, TDF_SLIM);
+      fprintf (dump_file, ",  init: ");
+      print_generic_expr (dump_file, init_expr, TDF_SLIM);
+    }
+
+  *init = init_expr;
+  *step = step_expr;
+
+  if (TREE_CODE (step_expr) != INTEGER_CST)
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "step unknown.");
+      return false;
+    }
+
+  if (strict)
+    if (!integer_onep (step_expr))
+      {
+        if (vect_debug_details (NULL))
+         print_generic_expr (dump_file, step_expr, TDF_SLIM);
+        return false;
+      }
+
+  return true;
+}
+
+
+/* Function vect_analyze_scalar_cycles.
+
+   Examine the cross iteration def-use cycles of scalar variables, by
+   analyzing the loop (scalar) PHIs; verify that the cross iteration def-use
+   cycles that they represent do not impede vectorization.
+
+   FORNOW: Reduction as in the following loop, is not supported yet:
+              loop1:
+              for (i=0; i<N; i++)
+                 sum += a[i];
+          The cross-iteration cycle corresponding to variable 'sum' will be
+          considered too complicated and will impede vectorization.
+
+   FORNOW: Induction as in the following loop, is not supported yet:
+              loop2:
+              for (i=0; i<N; i++)
+                 a[i] = i;
+
+           However, the following loop *is* vectorizable:
+              loop3:
+              for (i=0; i<N; i++)
+                 a[i] = b[i];
+
+           In both loops there exists a def-use cycle for the variable i:
+              loop: i_2 = PHI (i_0, i_1)
+                    a[i_2] = ...;
+                    i_1 = i_2 + 1;
+                    GOTO loop;
+
+           The evolution of the above cycle is considered simple enough,
+          however, we also check that the cycle does not need to be
+          vectorized, i.e - we check that the variable that this cycle
+          defines is only used for array indexing or in stmts that do not
+          need to be vectorized. This is not the case in loop2, but it
+          *is* the case in loop3.  */
+
+static bool
+vect_analyze_scalar_cycles (loop_vec_info loop_vinfo)
+{
+  tree phi;
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  basic_block bb = loop->header;
+  tree dummy;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_analyze_scalar_cycles>>\n");
+
+  for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+    {
+      tree access_fn = NULL;
+
+      if (vect_debug_details (NULL))
+       {
+          fprintf (dump_file, "Analyze phi: ");
+          print_generic_expr (dump_file, phi, TDF_SLIM);
+       }
+
+      /* Skip virtual phi's. The data dependences that are associated with
+         virtual defs/uses (i.e., memory accesses) are analyzed elsewhere.  */
+
+      if (!is_gimple_reg (SSA_NAME_VAR (PHI_RESULT (phi))))
+       {
+         if (vect_debug_details (NULL))
+           fprintf (dump_file, "virtual phi. skip.");
+         continue;
+       }
+
+      /* Analyze the evolution function.  */
+
+      /* FORNOW: The only scalar cross-iteration cycles that we allow are
+         those of loop induction variables; This property is verified here.
+
+         Furthermore, if that induction variable is used in an operation
+         that needs to be vectorized (i.e, is not solely used to index
+         arrays and check the exit condition) - we do not support its
+         vectorization yet. This property is verified in vect_is_simple_use,
+         during vect_analyze_operations.  */
+
+      access_fn = instantiate_parameters
+       (loop,
+        analyze_scalar_evolution (loop, PHI_RESULT (phi)));
+
+      if (!access_fn)
+       {
+         if (vect_debug_stats (loop) || vect_debug_details (loop))
+           fprintf (dump_file, "not vectorized: unsupported scalar cycle.");
+         return false;
+       }
+
+      if (vect_debug_details (NULL))
+        {
+           fprintf (dump_file, "Access function of PHI: ");
+           print_generic_expr (dump_file, access_fn, TDF_SLIM);
+        }
+
+      if (!vect_is_simple_iv_evolution (loop->num, access_fn, &dummy, 
+                                       &dummy, false))
+       {
+         if (vect_debug_stats (loop) || vect_debug_details (loop))
+           fprintf (dump_file, "not vectorized: unsupported scalar cycle.");
+         return false;
+       }
+    }
+
+  return true;
+}
+
+
+/* Function vect_analyze_data_ref_dependence.
+
+   Return TRUE if there (might) exist a dependence between a memory-reference
+   DRA and a memory-reference DRB.  */
+
+static bool
+vect_analyze_data_ref_dependence (struct data_reference *dra,
+                                 struct data_reference *drb, 
+                                 struct loop *loop)
+{
+  bool differ_p;
+  struct data_dependence_relation *ddr;
+
+  if (!array_base_name_differ_p (dra, drb, &differ_p))
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        {
+          fprintf (dump_file, 
+               "not vectorized: can't determine dependence between: ");
+          print_generic_expr (dump_file, DR_REF (dra), TDF_SLIM);
+          fprintf (dump_file, " and ");
+          print_generic_expr (dump_file, DR_REF (drb), TDF_SLIM);
+        }
+      return true;
+    }
+
+  if (differ_p)
+    return false;
+
+  ddr = initialize_data_dependence_relation (dra, drb);
+  compute_affine_dependence (ddr);
+
+  if (DDR_ARE_DEPENDENT (ddr) == chrec_known)
+    return false;
+  
+  if (vect_debug_stats (loop) || vect_debug_details (loop))
+    {
+      fprintf (dump_file,
+       "not vectorized: possible dependence between data-refs ");
+      print_generic_expr (dump_file, DR_REF (dra), TDF_SLIM);
+      fprintf (dump_file, " and ");
+      print_generic_expr (dump_file, DR_REF (drb), TDF_SLIM);
+    }
+
+  return true;
+}
+
+
+/* Function vect_analyze_data_ref_dependences.
+
+   Examine all the data references in the loop, and make sure there do not
+   exist any data dependences between them.
+
+   TODO: dependences which distance is greater than the vectorization factor
+         can be ignored.   */
+
+static bool
+vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo)
+{
+  unsigned int i, j;
+  varray_type loop_write_refs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
+  varray_type loop_read_refs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+
+  /* Examine store-store (output) dependences.  */
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_analyze_dependences>>\n");
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "compare all store-store pairs.");
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_refs); i++)
+    {
+      for (j = i + 1; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
+       {
+         struct data_reference *dra =
+           VARRAY_GENERIC_PTR (loop_write_refs, i);
+         struct data_reference *drb =
+           VARRAY_GENERIC_PTR (loop_write_refs, j);
+         if (vect_analyze_data_ref_dependence (dra, drb, loop))
+           return false;
+       }
+    }
+
+  /* Examine load-store (true/anti) dependences.  */
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "compare all load-store pairs.");
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_refs); i++)
+    {
+      for (j = 0; j < VARRAY_ACTIVE_SIZE (loop_write_refs); j++)
+       {
+         struct data_reference *dra = VARRAY_GENERIC_PTR (loop_read_refs, i);
+         struct data_reference *drb =
+           VARRAY_GENERIC_PTR (loop_write_refs, j);
+         if (vect_analyze_data_ref_dependence (dra, drb, loop))
+           return false;
+       }
+    }
+
+  return true;
+}
+
+
+/* Function vect_get_first_index.
+
+   REF is a data reference.  
+   If it is an ARRAY_REF: if its lower bound is simple enough, 
+   put it in ARRAY_FIRST_INDEX and return TRUE; otherwise - return FALSE.
+   If it is not an ARRAY_REF: REF has no "first index";
+   ARRAY_FIRST_INDEX in zero, and the function returns TRUE.  */
+
+static bool
+vect_get_first_index (tree ref, tree *array_first_index)
+{
+  tree array_start;
+
+  if (TREE_CODE (ref) != ARRAY_REF)
+    *array_first_index = size_zero_node;
+  else
+    {
+      array_start = array_ref_low_bound (ref);
+      if (!host_integerp (array_start,0))
+       {
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "array min val not simple integer cst.");
+             print_generic_expr (dump_file, array_start, TDF_DETAILS);
+           }
+         return false;
+       }
+      *array_first_index = array_start;
+    }
+
+  return true;
+}
+
+
+/* Function vect_compute_data_ref_alignment
+
+   Compute the misalignment of the data reference DR.
+
+   FOR NOW: No analysis is actually performed. Misalignment is calculated
+   only for trivial cases. TODO.  */
+
+static void
+vect_compute_data_ref_alignment (struct data_reference *dr, 
+                                loop_vec_info loop_vinfo ATTRIBUTE_UNUSED)
+{
+  tree stmt = DR_STMT (dr);
+  tree ref = DR_REF (dr);
+  tree vectype;
+  tree access_fn = DR_ACCESS_FN (dr, 0); /* FORNOW: single access_fn.  */
+  tree init;
+  tree scalar_type;
+  tree misalign;
+  tree array_first_index;
+  tree array_base = DR_BASE_NAME (dr);
+  tree base_decl = NULL_TREE;
+  tree bit_offset = size_zero_node;
+  tree offset = size_zero_node;
+  tree unit_bits = build_int_cst (unsigned_type_node, BITS_PER_UNIT, 0);
+  tree nunits;
+  tree alignment;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "vect_compute_data_ref_alignment:");
+
+  /* Initialize misalignment to unknown.  */
+  DR_MISALIGNMENT (dr) = -1;
+
+  scalar_type = TREE_TYPE (ref);
+  vectype = get_vectype_for_scalar_type (scalar_type);
+  if (!vectype)
+    {
+      if (vect_debug_details (NULL))
+        {
+          fprintf (dump_file, "no vectype for stmt: ");
+          print_generic_expr (dump_file, stmt, TDF_SLIM);
+          fprintf (dump_file, "scalar_type: ");
+          print_generic_expr (dump_file, scalar_type, TDF_DETAILS);
+        }
+      return;
+    }
+
+  if (TYPE_ALIGN (TREE_TYPE (TREE_TYPE (array_base))) < TYPE_ALIGN (vectype))
+    {
+      base_decl = vect_get_base_decl_and_bit_offset (array_base, &bit_offset);
+      if (!base_decl)
+       {
+         if (vect_debug_details (NULL))
+           fprintf (dump_file, "Unknown alignment for access");
+         return;
+       }
+
+      offset = int_const_binop (TRUNC_DIV_EXPR, bit_offset, unit_bits, 1); 
+      bit_offset = int_const_binop (TRUNC_MOD_EXPR, bit_offset, unit_bits, 1); 
+      if (!integer_zerop (bit_offset))
+       {
+         if (vect_debug_details (NULL))
+            {
+              fprintf (dump_file, "bit offset alignment: ");
+              print_generic_expr (dump_file, bit_offset, TDF_SLIM);
+            }
+         return;
+       }
+
+      if (!base_decl ||
+         (DECL_ALIGN (base_decl) < TYPE_ALIGN (vectype)
+          && !vect_can_force_dr_alignment_p (base_decl, TYPE_ALIGN (vectype))))
+       {
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "can't force alignment of ref: "); 
+             print_generic_expr (dump_file, array_base, TDF_SLIM);
+           }
+         return;
+       }
+
+       if (DECL_ALIGN (base_decl) < TYPE_ALIGN (vectype))
+        {
+          /* Force the alignment of the decl.  
+             NOTE: This is the only change to the code we make during
+             the analysis phase, before deciding to vectorize the loop.  */ 
+          if (vect_debug_details (NULL))
+            fprintf (dump_file, "force alignment");
+          DECL_ALIGN (base_decl) = TYPE_ALIGN (vectype); 
+          DECL_USER_ALIGN (base_decl) = TYPE_ALIGN (vectype);  
+        }
+    }
+
+  /* The misalignement is:
+     (base_alignment + offset + index_access_fn_init) % alignment.
+     At this point we already guaranteed that base_alignment == 0,
+     and computed the offset. 
+     It remains to check the first index accessed.  */
+
+  if (!vect_get_first_index (ref, &array_first_index))
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "no first_index for array.");
+      return;
+    }
+  
+  /* Check the index of the array_ref.  */
+
+  init = initial_condition (access_fn);
+
+  /* FORNOW: In order to simplify the handling of alignment, we make sure 
+     that the first location at which the array is accessed ('init') is on an 
+     'NUNITS' boundary, since we are assuming here that 'array base' is aligned. 
+     This is too conservative, since we require that 
+     both {'array_base' is a multiple of NUNITS} && {'init' is a multiple of 
+     NUNITS}, instead of just {('array_base' + 'init') is a multiple of NUNITS}.
+     This should be relaxed in the future.  */
+
+  if (!init || !host_integerp (init,0))
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "init not simple INTEGER_CST.");
+      return;
+    }
+
+  /* alignment required, in bytes: */
+  alignment = build_int_cst (unsigned_type_node, 
+                               TYPE_ALIGN (vectype)/BITS_PER_UNIT, 0);
+  /* bytes per scalar element: */
+  nunits = build_int_cst (unsigned_type_node, 
+                               GET_MODE_SIZE (TYPE_MODE (scalar_type)), 0);
+
+  /* misalign = (offset + (init-array_first_index)*nunits) % alignment  */
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "misalign = ( offset <");
+      print_generic_expr (dump_file, offset, TDF_SLIM);  
+      fprintf (dump_file, "> + (init <");
+      print_generic_expr (dump_file, init, TDF_SLIM);  
+      fprintf (dump_file, "> - first_indx <");
+      print_generic_expr (dump_file, array_first_index, TDF_SLIM);  
+      fprintf (dump_file, ">) * nunits <");
+      print_generic_expr (dump_file, nunits, TDF_SLIM);  
+      fprintf (dump_file, ">)  mod alignment <");
+      print_generic_expr (dump_file, alignment, TDF_SLIM);  
+      fprintf (dump_file, ">");
+    }
+
+  misalign = int_const_binop (MINUS_EXPR, init, array_first_index, 0);
+  misalign = int_const_binop (MULT_EXPR, misalign, nunits, 0);
+  misalign = int_const_binop (PLUS_EXPR, misalign, offset, 0);
+  misalign = int_const_binop (TRUNC_MOD_EXPR, misalign, alignment, 0);
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "misalign = ");
+      print_generic_expr (dump_file, misalign, TDF_SLIM);  
+    }
+
+  if (!host_integerp (misalign,1) || TREE_OVERFLOW (misalign))
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "unexpected misalign value");
+      return;
+    }
+
+  DR_MISALIGNMENT (dr) = tree_low_cst (misalign,1);
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "misalign = %d",DR_MISALIGNMENT (dr));
+}
+
+
+/* Function vect_compute_data_refs_alignment
+
+   Compute the misalignment of data references in the loop.
+   This pass may take place at function granularity instead of at loop
+   granularity.
+
+   FOR NOW: No analysis is actually performed. Misalignment is calculated
+   only for trivial cases. TODO.  */
+
+static void
+vect_compute_data_refs_alignment (loop_vec_info loop_vinfo)
+{
+  varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
+  varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
+  unsigned int i;
+  
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
+      vect_compute_data_ref_alignment (dr, loop_vinfo);
+    }
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
+      vect_compute_data_ref_alignment (dr, loop_vinfo);
+    }
+}
+
+
+/* Function vect_enhance_data_refs_alignment
+
+   This pass will use loop versioning and loop peeling in order to enhance
+   the alignment of data references in the loop.
+
+   FOR NOW: we assume that whatever versioning/peeling takes place, only the
+   original loop is to be vectorized; Any other loops that are created by
+   the transformations performed in this pass - are not supposed to be
+   vectorized. This restriction will be relaxed.
+
+   FOR NOW: No transformation is actually performed. TODO.  */
+
+static void
+vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo ATTRIBUTE_UNUSED)
+{
+  /*
+     This pass will require a cost model to guide it whether to apply peeling 
+     or versioning or a combination of the two. For example, the scheme that
+     intel uses when given a loop with several memory accesses, is as follows:
+     choose one memory access ('p') which alignment you want to force by doing 
+     peeling. Then, either (1) generate a loop in which 'p' is aligned and all 
+     other accesses are not necessarily aligned, or (2) use loop versioning to 
+     generate one loop in which all accesses are aligned, and another loop in 
+     which only 'p' is necessarily aligned. 
+
+     ("Automatic Intra-Register Vectorization for the Intel Architecture",
+      Aart J.C. Bik, Milind Girkar, Paul M. Grey and Ximmin Tian, International
+      Journal of Parallel Programming, Vol. 30, No. 2, April 2002.)    
+
+     Devising a cost model is the most critical aspect of this work. It will 
+     guide us on which access to peel for, whether to use loop versioning, how 
+     many versions to create, etc. The cost model will probably consist of 
+     generic considerations as well as target specific considerations (on 
+     powerpc for example, misaligned stores are more painful than misaligned 
+     loads). 
+
+     Here is the general steps involved in alignment enhancements:
+    
+     -- original loop, before alignment analysis:
+       for (i=0; i<N; i++){
+         x = q[i];                     # DR_MISALIGNMENT(q) = unknown
+         p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
+       }
+
+     -- After vect_compute_data_refs_alignment:
+       for (i=0; i<N; i++){
+         x = q[i];                     # DR_MISALIGNMENT(q) = 3
+         p[i] = y;                     # DR_MISALIGNMENT(p) = unknown
+       }
+
+     -- Possibility 1: we do loop versioning:
+     if (p is aligned) {
+       for (i=0; i<N; i++){    # loop 1A
+         x = q[i];                     # DR_MISALIGNMENT(q) = 3
+         p[i] = y;                     # DR_MISALIGNMENT(p) = 0
+       }
+     } 
+     else {
+       for (i=0; i<N; i++){    # loop 1B
+         x = q[i];                     # DR_MISALIGNMENT(q) = 3
+         p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
+       }
+     }
+   
+     -- Possibility 2: we do loop peeling:
+     for (i = 0; i < 3; i++){  # (scalar loop, not to be vectorized).
+       x = q[i];
+       p[i] = y;
+     }
+     for (i = 3; i < N; i++){  # loop 2A
+       x = q[i];                       # DR_MISALIGNMENT(q) = 0
+       p[i] = y;                       # DR_MISALIGNMENT(p) = unknown
+     }
+
+     -- Possibility 3: combination of loop peeling and versioning:
+     for (i = 0; i < 3; i++){  # (scalar loop, not to be vectorized).
+       x = q[i];
+       p[i] = y;
+     }
+     if (p is aligned) {
+       for (i = 3; i<N; i++){  # loop 3A
+         x = q[i];                     # DR_MISALIGNMENT(q) = 0
+         p[i] = y;                     # DR_MISALIGNMENT(p) = 0
+       }
+     } 
+     else {
+       for (i = 3; i<N; i++){  # loop 3B
+         x = q[i];                     # DR_MISALIGNMENT(q) = 0
+         p[i] = y;                     # DR_MISALIGNMENT(p) = unaligned
+       }
+     }
+
+     These loops are later passed to loop_transform to be vectorized. The 
+     vectorizer will use the alignment information to guide the transformation 
+     (whether to generate regular loads/stores, or with special handling for 
+     misalignment). 
+   */
+}
+
+
+/* Function vect_analyze_data_refs_alignment
+
+   Analyze the alignment of the data-references in the loop.
+   FOR NOW: Until support for misliagned accesses is in place, only if all
+   accesses are aligned can the loop be vectorized. This restriction will be 
+   relaxed.  */ 
+
+static bool
+vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo)
+{
+  varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
+  varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
+  unsigned int i;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_analyze_data_refs_alignment>>\n");
+
+
+  /* This pass may take place at function granularity instead of at loop
+     granularity.  */
+
+  vect_compute_data_refs_alignment (loop_vinfo);
+
+
+  /* This pass will use loop versioning and loop peeling in order to enhance
+     the alignment of data references in the loop.
+     FOR NOW: we assume that whatever versioning/peeling took place, the 
+     original loop is to be vectorized. Any other loops that were created by
+     the transformations performed in this pass - are not supposed to be 
+     vectorized. This restriction will be relaxed.  */
+
+  vect_enhance_data_refs_alignment (loop_vinfo);
+
+
+  /* Finally, check that loop can be vectorized. 
+     FOR NOW: Until support for misaligned accesses is in place, only if all
+     accesses are aligned can the loop be vectorized. This restriction will be 
+     relaxed.  */
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
+      if (!aligned_access_p (dr))
+       {
+         if (vect_debug_stats (LOOP_VINFO_LOOP (loop_vinfo))
+             || vect_debug_details (LOOP_VINFO_LOOP (loop_vinfo)))
+           fprintf (dump_file, "not vectorized: unaligned store.");
+         return false;
+       }
+    }
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
+      if (!aligned_access_p (dr))
+       {
+         if (vect_debug_stats (LOOP_VINFO_LOOP (loop_vinfo))
+             || vect_debug_details (LOOP_VINFO_LOOP (loop_vinfo)))
+           fprintf (dump_file, "not vectorized: unaligned load.");
+         return false;
+       }
+    }
+
+  return true;
+}
+
+
+/* Function vect_analyze_data_ref_access.
+
+   Analyze the access pattern of the data-reference DR. For now, a data access
+   has to consecutive and aligned to be considered vectorizable.  */
+
+static bool
+vect_analyze_data_ref_access (struct data_reference *dr)
+{
+  varray_type access_fns = DR_ACCESS_FNS (dr);
+  tree access_fn;
+  tree init, step;
+
+  /* FORNOW: handle only one dimensional arrays.
+     This restriction will be relaxed in the future.  */
+  if (VARRAY_ACTIVE_SIZE (access_fns) != 1)
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "multi dimensional array reference.");
+      return false;
+    }
+  access_fn = DR_ACCESS_FN (dr, 0);
+
+  if (!vect_is_simple_iv_evolution (loop_containing_stmt (DR_STMT (dr))->num, 
+                                   access_fn, &init, &step, true))
+    {
+      if (vect_debug_details (NULL))
+       {
+         fprintf (dump_file, "too complicated access function.");
+         print_generic_expr (dump_file, access_fn, TDF_SLIM);
+       }
+      return false;
+    }
+
+  return true;
+}
+
+
+/* Function vect_analyze_data_ref_accesses.
+
+   Analyze the access pattern of all the data references in the loop.
+
+   FORNOW: the only access pattern that is considered vectorizable is a
+          simple step 1 (consecutive) access.
+
+   FORNOW: handle only one dimensional arrays, and pointer accesses.  */
+
+static bool
+vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo)
+{
+  unsigned int i;
+  varray_type loop_write_datarefs = LOOP_VINFO_DATAREF_WRITES (loop_vinfo);
+  varray_type loop_read_datarefs = LOOP_VINFO_DATAREF_READS (loop_vinfo);
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_analyze_data_ref_accesses>>\n");
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_write_datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_write_datarefs, i);
+      bool ok = vect_analyze_data_ref_access (dr);
+      if (!ok)
+       {
+         if (vect_debug_stats (LOOP_VINFO_LOOP (loop_vinfo))
+             || vect_debug_details (LOOP_VINFO_LOOP (loop_vinfo)))
+           fprintf (dump_file, "not vectorized: complicated access pattern.");
+         return false;
+       }
+    }
+
+  for (i = 0; i < VARRAY_ACTIVE_SIZE (loop_read_datarefs); i++)
+    {
+      struct data_reference *dr = VARRAY_GENERIC_PTR (loop_read_datarefs, i);
+      bool ok = vect_analyze_data_ref_access (dr);
+      if (!ok)
+       {
+         if (vect_debug_stats (LOOP_VINFO_LOOP (loop_vinfo))
+             || vect_debug_details (LOOP_VINFO_LOOP (loop_vinfo))) 
+           fprintf (dump_file, "not vectorized: complicated access pattern.");
+         return false;
+       }
+    }
+
+  return true;
+}
+
+
+/* Function vect_analyze_pointer_ref_access.
+
+   Input:
+   STMT - a stmt that contains a data-ref
+   MEMREF - a data-ref in STMT, which is an INDIRECT_REF.
+
+   If the data-ref access is vectorizable, return a data_reference structure
+   that represents it (DR). Otherwise - return NULL.   */
+
+static struct data_reference *
+vect_analyze_pointer_ref_access (tree memref, tree stmt, bool is_read)
+{
+  stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+  struct loop *loop = STMT_VINFO_LOOP (stmt_info);
+  tree access_fn = analyze_scalar_evolution (loop, TREE_OPERAND (memref, 0));
+  tree init, step;     
+  int step_val;
+  tree reftype, innertype;
+  enum machine_mode innermode;
+  tree indx_access_fn; 
+  int loopnum = loop->num;
+  struct data_reference *dr;
+
+  if (!access_fn)
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        fprintf (dump_file, "not vectorized: complicated pointer access.");    
+      return NULL;
+    }
+
+  if (vect_debug_details (NULL))
+    {
+      fprintf (dump_file, "Access function of ptr: ");
+      print_generic_expr (dump_file, access_fn, TDF_SLIM);
+    }
+
+  if (!vect_is_simple_iv_evolution (loopnum, access_fn, &init, &step, false))
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop)) 
+       fprintf (dump_file, "not vectorized: pointer access is not simple.");   
+      return NULL;
+    }
+               
+  if (TREE_CODE (init) != SSA_NAME        /* FORNOW */
+      || !host_integerp (step,0))
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop)) 
+       fprintf (dump_file, 
+               "not vectorized: non constant init/step for pointer access.");  
+      return NULL;
+    }
+
+  step_val = TREE_INT_CST_LOW (step);
+
+  reftype = TREE_TYPE (TREE_OPERAND (memref, 0));
+  if (TREE_CODE (reftype) != POINTER_TYPE) 
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+       fprintf (dump_file, "not vectorized: unexpected pointer access form."); 
+      return NULL;
+    }
+
+  reftype = TREE_TYPE (init);
+  if (TREE_CODE (reftype) != POINTER_TYPE) 
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop)) 
+       fprintf (dump_file, "not vectorized: unexpected pointer access form.");
+      return NULL;
+    }
+
+  innertype = TREE_TYPE (reftype);
+  innermode = TYPE_MODE (innertype);
+  if (GET_MODE_SIZE (innermode) != step_val) 
+    {
+      /* FORNOW: support only consecutive access */
+      if (vect_debug_stats (loop) || vect_debug_details (loop)) 
+       fprintf (dump_file, "not vectorized: non consecutive access."); 
+      return NULL;
+    }
+
+  indx_access_fn = 
+       build_polynomial_chrec (loopnum, integer_zero_node, integer_one_node);
+  if (vect_debug_details (NULL)) 
+    {
+      fprintf (dump_file, "Access function of ptr indx: ");
+      print_generic_expr (dump_file, indx_access_fn, TDF_SLIM);
+    }
+  dr = init_data_ref (stmt, memref, init, indx_access_fn, is_read);
+  return dr;
+}
+
+
+/* Function vect_analyze_data_refs.
+
+   Find all the data references in the loop.
+
+   FORNOW: Handle aligned INDIRECT_REFs and one dimensional ARRAY_REFs 
+          which base is really an array (not a pointer) and which alignment 
+          can be forced. This restriction will be relaxed.   */
+
+static bool
+vect_analyze_data_refs (loop_vec_info loop_vinfo)
+{
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+  int nbbs = loop->num_nodes;
+  block_stmt_iterator si;
+  int j;
+  struct data_reference *dr;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_analyze_data_refs>>\n");
+
+  for (j = 0; j < nbbs; j++)
+    {
+      basic_block bb = bbs[j];
+      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+       {
+         bool is_read = false;
+         tree stmt = bsi_stmt (si);
+         stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
+         v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+         v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+         vuse_optype vuses = STMT_VUSE_OPS (stmt);
+         varray_type *datarefs = NULL;
+         int nvuses, nv_may_defs, nv_must_defs;
+         tree memref = NULL;
+         tree array_base;
+         tree symbl;
+
+         /* Assumption: there exists a data-ref in stmt, if and only if 
+             it has vuses/vdefs.  */
+
+         if (!vuses && !v_may_defs && !v_must_defs)
+           continue;
+
+         nvuses = NUM_VUSES (vuses);
+         nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
+         nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
+
+         if (nvuses && (nv_may_defs || nv_must_defs))
+           {
+             if (vect_debug_details (NULL))
+               {
+                 fprintf (dump_file, "unexpected vdefs and vuses in stmt: ");
+                 print_generic_expr (dump_file, stmt, TDF_SLIM);
+               }
+             return false;
+           }
+
+         if (TREE_CODE (stmt) != MODIFY_EXPR)
+           {
+             if (vect_debug_details (NULL))
+               {
+                 fprintf (dump_file, "unexpected vops in stmt: ");
+                 print_generic_expr (dump_file, stmt, TDF_SLIM);
+               }
+             return false;
+           }
+
+         if (vuses)
+           {
+             memref = TREE_OPERAND (stmt, 1);
+             datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
+             is_read = true;
+           } 
+         else /* vdefs */
+           {
+             memref = TREE_OPERAND (stmt, 0);
+             datarefs = &(LOOP_VINFO_DATAREF_WRITES (loop_vinfo));
+             is_read = false;
+           }
+
+         if (TREE_CODE (memref) == INDIRECT_REF)
+            {
+              dr = vect_analyze_pointer_ref_access (memref, stmt, is_read);
+              if (! dr)
+                return false; 
+             symbl = DR_BASE_NAME (dr);        
+            }
+         else if (TREE_CODE (memref) == ARRAY_REF)
+           {
+             tree base;
+             tree offset = size_zero_node;     
+             array_base = TREE_OPERAND (memref, 0);
+   
+              /* FORNOW: make sure that the array is one dimensional.
+                 This restriction will be relaxed in the future.  */
+              if (TREE_CODE (array_base) == ARRAY_REF)
+                {
+                  if (vect_debug_stats (loop) || vect_debug_details (loop))
+                   {
+                      fprintf (dump_file, 
+                               "not vectorized: multi-dimensional array.");
+                      print_generic_expr (dump_file, stmt, TDF_SLIM);
+                   }
+                  return false;
+                }
+
+              dr = analyze_array (stmt, memref, is_read);
+
+             /* Find the relevant symbol for aliasing purposes.  */    
+             base = DR_BASE_NAME (dr);
+             switch (TREE_CODE (base)) 
+               {
+               case VAR_DECL:
+                 symbl = base;
+                 break;
+               /* FORNOW: Disabled.  
+               case INDIRECT_REF:
+                 symbl = TREE_OPERAND (base, 0); 
+                 break;
+               */
+               case COMPONENT_REF:
+                 /* CHECKME: could have recorded more accurate information - 
+                    i.e, the actual FIELD_DECL that is being referenced -
+                    but later passes expect VAR_DECL as the nmt.  */   
+                 symbl = vect_get_base_decl_and_bit_offset (base, &offset);
+                 if (symbl)
+                   break;
+                 /* fall through */    
+               default:
+                  if (vect_debug_stats (loop) || vect_debug_details (loop))
+                   {
+                      fprintf (dump_file,
+                        "not vectorized: unhandled struct/class field access ");
+                      print_generic_expr (dump_file, stmt, TDF_SLIM);
+                   }
+                  return false;
+               } /* switch */
+           }
+         else
+           {
+             if (vect_debug_stats (loop) || vect_debug_details (loop))
+               {
+                 fprintf (dump_file, "not vectorized: unhandled data ref: ");
+                 print_generic_expr (dump_file, stmt, TDF_SLIM);
+               }
+             return false;
+           }
+       
+         /* Find and record the memtag assigned to this data-ref.  */
+         if (TREE_CODE (symbl) == VAR_DECL)
+           STMT_VINFO_MEMTAG (stmt_info) = symbl;
+         else if (TREE_CODE (symbl) == SSA_NAME)
+           {
+             tree tag;
+             symbl = SSA_NAME_VAR (symbl);
+             tag = get_var_ann (symbl)->type_mem_tag;
+             if (!tag)
+               {
+                 tree ptr = TREE_OPERAND (memref, 0);
+                 if (TREE_CODE (ptr) == SSA_NAME)
+                   tag = get_var_ann (SSA_NAME_VAR (ptr))->type_mem_tag;
+               }
+             if (!tag)
+               {
+                 if (vect_debug_stats (loop) || vect_debug_details (loop))
+                   fprintf (dump_file, "not vectorized: no memtag for ref.");
+                 return false;
+               }
+             STMT_VINFO_MEMTAG (stmt_info) = tag;
+           }
+         else
+           {
+             if (vect_debug_stats (loop) || vect_debug_details (loop))
+               {
+                 fprintf (dump_file, "not vectorized: unsupported data-ref: ");
+                 print_generic_expr (dump_file, memref, TDF_SLIM);
+               }
+             return false;
+            }
+
+         VARRAY_PUSH_GENERIC_PTR (*datarefs, dr);
+         STMT_VINFO_DATA_REF (stmt_info) = dr;
+       }
+    }
+
+  return true;
+}
+
+
+/* Utility functions used by vect_mark_stmts_to_be_vectorized. */
+
+/* Function vect_mark_relevant.
+
+   Mark STMT as "relevant for vectorization" and add it to WORKLIST.  */
+
+static void
+vect_mark_relevant (varray_type worklist, tree stmt)
+{
+  stmt_vec_info stmt_info;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "mark relevant.");
+
+  if (TREE_CODE (stmt) == PHI_NODE)
+    {
+      VARRAY_PUSH_TREE (worklist, stmt);
+      return;
+    }
+
+  stmt_info = vinfo_for_stmt (stmt);
+
+  if (!stmt_info)
+    {
+      if (vect_debug_details (NULL))
+       {
+         fprintf (dump_file, "mark relevant: no stmt info!!.");
+         print_generic_expr (dump_file, stmt, TDF_SLIM);
+       }
+      return;
+    }
+
+  if (STMT_VINFO_RELEVANT_P (stmt_info))
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "already marked relevant.");
+      return;
+    }
+
+  STMT_VINFO_RELEVANT_P (stmt_info) = 1;
+  VARRAY_PUSH_TREE (worklist, stmt);
+}
+
+
+/* Function vect_stmt_relevant_p.
+
+   Return true if STMT in loop that is represented by LOOP_VINFO is
+   "relevant for vectorization".
+
+   A stmt is considered "relevant for vectorization" if:
+   - it has uses outside the loop.
+   - it has vdefs (it alters memory).
+   - control stmts in the loop (except for the exit condition).
+
+   CHECKME: what other side effects would the vectorizer allow?  */
+
+static bool
+vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
+{
+  v_may_def_optype v_may_defs;
+  v_must_def_optype v_must_defs;
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  int i;
+  dataflow_t df;
+  int num_uses;
+
+  /* cond stmt other than loop exit cond.  */
+  if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
+    return true;
+
+  /* changing memory.  */
+  v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
+  v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
+  if (v_may_defs || v_must_defs)
+    {
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "vec_stmt_relevant_p: stmt has vdefs.");
+      return true;
+    }
+
+  /* uses outside the loop.  */
+  df = get_immediate_uses (stmt);
+  num_uses = num_immediate_uses (df);
+  for (i = 0; i < num_uses; i++)
+    {
+      tree use = immediate_use (df, i);
+      basic_block bb = bb_for_stmt (use);
+      if (!flow_bb_inside_loop_p (loop, bb))
+       {
+         if (vect_debug_details (NULL))
+           fprintf (dump_file, "vec_stmt_relevant_p: used out of loop.");
+         return true;
+       }
+    }
+
+  return false;
+}
+
+
+/* Function vect_mark_stmts_to_be_vectorized.
+
+   Not all stmts in the loop need to be vectorized. For example:
+
+     for i...
+       for j...
+   1.    T0 = i + j
+   2.   T1 = a[T0]
+
+   3.    j = j + 1
+
+   Stmt 1 and 3 do not need to be vectorized, because loop control and
+   addressing of vectorized data-refs are handled differently.
+
+   This pass detects such stmts.  */
+
+static bool
+vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
+{
+  varray_type worklist;
+  struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
+  basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
+  unsigned int nbbs = loop->num_nodes;
+  block_stmt_iterator si;
+  tree stmt;
+  stmt_ann_t ann;
+  unsigned int i;
+  int j;
+  use_optype use_ops;
+  stmt_vec_info stmt_info;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<vect_mark_stmts_to_be_vectorized>>\n");
+
+  VARRAY_TREE_INIT (worklist, 64, "work list");
+
+  /* 1. Init worklist.  */
+
+  for (i = 0; i < nbbs; i++)
+    {
+      basic_block bb = bbs[i];
+      for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
+       {
+         stmt = bsi_stmt (si);
+
+         if (vect_debug_details (NULL))
+           {
+             fprintf (dump_file, "init: stmt relevant? ");
+             print_generic_expr (dump_file, stmt, TDF_SLIM);
+           } 
+
+         stmt_info = vinfo_for_stmt (stmt);
+         STMT_VINFO_RELEVANT_P (stmt_info) = 0;
+
+         if (vect_stmt_relevant_p (stmt, loop_vinfo))
+           vect_mark_relevant (worklist, stmt);
+       }
+    }
+
+
+  /* 2. Process_worklist */
+
+  while (VARRAY_ACTIVE_SIZE (worklist) > 0)
+    {
+      stmt = VARRAY_TOP_TREE (worklist);
+      VARRAY_POP (worklist);
+
+      if (vect_debug_details (NULL))
+       {
+          fprintf (dump_file, "worklist: examine stmt: ");
+          print_generic_expr (dump_file, stmt, TDF_SLIM);
+       }
+
+      /* Examine the USES in this statement. Mark all the statements which
+         feed this statement's uses as "relevant", unless the USE is used as
+         an array index.  */
+
+      if (TREE_CODE (stmt) == PHI_NODE)
+       {
+         /* follow the def-use chain inside the loop.  */
+         for (j = 0; j < PHI_NUM_ARGS (stmt); j++)
+           {
+             tree arg = PHI_ARG_DEF (stmt, j);
+             tree def_stmt = NULL_TREE;
+             basic_block bb;
+             if (!vect_is_simple_use (arg, loop, &def_stmt))
+               {
+                 if (vect_debug_details (NULL))        
+                   fprintf (dump_file, "worklist: unsupported use.");
+                 varray_clear (worklist);
+                 return false;
+               }
+             if (!def_stmt)
+               continue;
+
+             if (vect_debug_details (NULL))
+               {
+                 fprintf (dump_file, "worklist: def_stmt: ");
+                 print_generic_expr (dump_file, def_stmt, TDF_SLIM);
+               }
+
+             bb = bb_for_stmt (def_stmt);
+             if (flow_bb_inside_loop_p (loop, bb))
+               vect_mark_relevant (worklist, def_stmt);
+           }
+       } 
+
+      ann = stmt_ann (stmt);
+      use_ops = USE_OPS (ann);
+
+      for (i = 0; i < NUM_USES (use_ops); i++)
+       {
+         tree use = USE_OP (use_ops, i);
+
+         /* We are only interested in uses that need to be vectorized. Uses 
+            that are used for address computation are not considered relevant.
+          */
+         if (exist_non_indexing_operands_for_use_p (use, stmt))
+           {
+              tree def_stmt = NULL_TREE;
+              basic_block bb;
+              if (!vect_is_simple_use (use, loop, &def_stmt))
+                {
+                  if (vect_debug_details (NULL))        
+                    fprintf (dump_file, "worklist: unsupported use.");
+                  varray_clear (worklist);
+                  return false;
+                }
+
+             if (!def_stmt)
+               continue;
+
+              if (vect_debug_details (NULL))
+                {
+                  fprintf (dump_file, "worklist: examine use %d: ", i);
+                  print_generic_expr (dump_file, use, TDF_SLIM);
+                }
+
+             bb = bb_for_stmt (def_stmt);
+             if (flow_bb_inside_loop_p (loop, bb))
+               vect_mark_relevant (worklist, def_stmt);
+           }
+       }
+    }                          /* while worklist */
+
+  varray_clear (worklist);
+  return true;
+}
+
+
+/* Function vect_get_loop_niters.
+
+   Determine how many iterations the loop is executed.  */
+
+static tree
+vect_get_loop_niters (struct loop *loop, HOST_WIDE_INT *number_of_iterations)
+{
+  tree niters;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<get_loop_niters>>\n");
+
+  niters = number_of_iterations_in_loop (loop);
+
+  if (niters != NULL_TREE
+      && niters != chrec_dont_know
+      && host_integerp (niters,0))
+    {
+      *number_of_iterations = TREE_INT_CST_LOW (niters);
+
+      if (vect_debug_details (NULL))
+        fprintf (dump_file, "==> get_loop_niters:" HOST_WIDE_INT_PRINT_DEC,
+                                *number_of_iterations);
+    }
+
+  return get_loop_exit_condition (loop);
+}
+
+
+/* Function vect_analyze_loop_form.
+
+   Verify the following restrictions (some may be relaxed in the future):
+   - it's an inner-most loop
+   - number of BBs = 2 (which are the loop header and the latch)
+   - the loop has a pre-header
+   - the loop has a single entry and exit
+   - the loop exit condition is simple enough, and the number of iterations
+     can be analyzed (a countable loop).  */
+
+static loop_vec_info
+vect_analyze_loop_form (struct loop *loop)
+{
+  loop_vec_info loop_vinfo;
+  tree loop_cond;
+  HOST_WIDE_INT number_of_iterations = -1;
+
+  if (vect_debug_details (loop))
+    fprintf (dump_file, "\n<<vect_analyze_loop_form>>\n");
+
+  if (loop->level > 1          /* FORNOW: inner-most loop  */
+      || loop->num_exits > 1 || loop->num_entries > 1 || loop->num_nodes != 2
+      || !loop->pre_header || !loop->header || !loop->latch)
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))        
+       {
+         fprintf (dump_file, "not vectorized: bad loop form. ");
+         if (loop->level > 1)
+           fprintf (dump_file, "nested loop.");
+         else if (loop->num_exits > 1 || loop->num_entries > 1)
+           fprintf (dump_file, "multiple entries or exits.");
+         else if (loop->num_nodes != 2 || !loop->header || !loop->latch)
+           fprintf (dump_file, "too many BBs in loop.");
+         else if (!loop->pre_header)
+           fprintf (dump_file, "no pre-header BB for loop.");
+       }
+
+      return NULL;
+    }
+
+  /* We assume that the loop exit condition is at the end of the loop. i.e,
+     that the loop is represented as a do-while (with a proper if-guard
+     before the loop if needed), where the loop header contains all the
+     executable statements, and the latch is empty.  */
+  if (!empty_block_p (loop->latch))
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        fprintf (dump_file, "not vectorized: unexpectd loop form.");
+      return NULL;
+    }
+
+  if (empty_block_p (loop->header))
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        fprintf (dump_file, "not vectorized: empty loop.");
+      return NULL;
+    }
+
+  loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
+  if (!loop_cond)
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+       fprintf (dump_file, "not vectorized: complicated exit condition.");
+      return NULL;
+    }
+
+  if (number_of_iterations < 0)
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+        fprintf (dump_file, "not vectorized: unknown loop bound.");
+      return NULL;
+    }
+
+  if (number_of_iterations == 0) /* CHECKME: can this happen? */
+    {
+      if (vect_debug_stats (loop) || vect_debug_details (loop))
+       fprintf (dump_file, "not vectorized: number of iterations = 0.");
+      return NULL;
+    }
+
+  loop_vinfo = new_loop_vec_info (loop);
+  LOOP_VINFO_EXIT_COND (loop_vinfo) = loop_cond;
+  LOOP_VINFO_NITERS (loop_vinfo) = number_of_iterations;
+
+  return loop_vinfo;
+}
+
+
+/* Function vect_analyze_loop.
+
+   Apply a set of analyses on LOOP, and create a loop_vec_info struct
+   for it. The different analyses will record information in the
+   loop_vec_info struct.  */
+
+static loop_vec_info
+vect_analyze_loop (struct loop *loop)
+{
+  bool ok;
+  loop_vec_info loop_vinfo;
+
+  if (vect_debug_details (NULL))
+    fprintf (dump_file, "\n<<<<<<< analyze_loop_nest >>>>>>>\n");
+
+  /* Check the CFG characteristics of the loop (nesting, entry/exit, etc.  */
+
+  loop_vinfo = vect_analyze_loop_form (loop);
+  if (!loop_vinfo)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad loop form.");
+      return NULL;
+    }
+
+  /* Find all data references in the loop (which correspond to vdefs/vuses)
+     and analyze their evolution in the loop.
+
+     FORNOW: Handle only simple, one-dimensional, array references, which
+     alignment can be forced, and aligned pointer-references.  */
+
+  ok = vect_analyze_data_refs (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad data references.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+
+  /* Data-flow analysis to detect stmts that do not need to be vectorized.  */
+
+  ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "unexpected pattern.");
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "not vectorized: unexpected pattern.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+
+  /* Check that all cross-iteration scalar data-flow cycles are OK.
+     Cross-iteration cycles caused by virtual phis are analyzed separately.  */
+
+  ok = vect_analyze_scalar_cycles (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad scalar cycle.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+
+  /* Analyze data dependences between the data-refs in the loop. 
+     FORNOW: fail at the first data dependence that we encounter.  */
+
+  ok = vect_analyze_data_ref_dependences (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad data dependence.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+
+  /* Analyze the access patterns of the data-refs in the loop (consecutive,
+     complex, etc.). FORNOW: Only handle consecutive access pattern.  */
+
+  ok = vect_analyze_data_ref_accesses (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad data access.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+
+  /* Analyze the alignment of the data-refs in the loop.
+     FORNOW: Only aligned accesses are handled.  */
+
+  ok = vect_analyze_data_refs_alignment (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad data alignment.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+
+  /* Scan all the operations in the loop and make sure they are
+     vectorizable.  */
+
+  ok = vect_analyze_operations (loop_vinfo);
+  if (!ok)
+    {
+      if (vect_debug_details (loop))
+       fprintf (dump_file, "bad operation or unsupported loop bound.");
+      destroy_loop_vec_info (loop_vinfo);
+      return NULL;
+    }
+
+  LOOP_VINFO_VECTORIZABLE_P (loop_vinfo) = 1;
+
+  return loop_vinfo;
+}
+
+
+/* Function need_imm_uses_for.
+
+   Return whether we ought to include information for 'var'
+   when calculating immediate uses.  For this pass we only want use
+   information for non-virtual variables.  */
+
+static bool
+need_imm_uses_for (tree var)
+{
+  return is_gimple_reg (var);
+}
+
+
+/* Function vectorize_loops.
+   
+   Entry Point to loop vectorization phase.  */
+
+void
+vectorize_loops (struct loops *loops)
+{
+  unsigned int i, loops_num;
+  unsigned int num_vectorized_loops = 0;
+
+  /* Does the target support SIMD?  */
+  /* FORNOW: until more sophisticated machine modelling is in place.  */
+  if (!UNITS_PER_SIMD_WORD)
+    {
+      if (vect_debug_details (NULL))
+       fprintf (dump_file, "vectorizer: target vector size is not defined.");
+      return;
+    }
+
+  compute_immediate_uses (TDFA_USE_OPS, need_imm_uses_for);
+
+  /*  ----------- Analyze loops. -----------  */
+
+  /* If some loop was duplicated, it gets bigger number 
+     than all previously defined loops. This fact allows us to run 
+     only over initial loops skipping newly generated ones.  */
+  loops_num = loops->num;
+  for (i = 1; i < loops_num; i++)
+    {
+      loop_vec_info loop_vinfo;
+      struct loop *loop = loops->parray[i];
+
+      if (!loop)
+        continue;
+
+      flow_loop_scan (loop, LOOP_ALL);
+
+      loop_vinfo = vect_analyze_loop (loop);
+      loop->aux = loop_vinfo;
+
+      if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
+       continue;
+
+      vect_transform_loop (loop_vinfo, loops); 
+      num_vectorized_loops++;
+    }
+
+  if (vect_debug_stats (NULL) || vect_debug_details (NULL))
+    fprintf (dump_file, "\nvectorized %u loops in function.\n",
+            num_vectorized_loops);
+
+  /*  ----------- Finalize. -----------  */
+
+  free_df ();
+  for (i = 1; i < loops_num; i++)
+    {
+      struct loop *loop = loops->parray[i];
+      loop_vec_info loop_vinfo = loop->aux;
+      if (!loop)
+        continue;
+      destroy_loop_vec_info (loop_vinfo);
+      loop->aux = NULL;
+    }
+
+  loop_commit_inserts (); 
+  rewrite_into_ssa (false);
+  if (bitmap_first_set_bit (vars_to_rename) >= 0)
+    {
+      /* The rewrite of ssa names may cause violation of loop closed ssa
+         form invariants.  TODO -- avoid these rewrites completely.
+         Information in virtual phi nodes is sufficient for it.  */
+      rewrite_into_loop_closed_ssa (); 
+    }
+  bitmap_clear (vars_to_rename);
+}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
new file mode 100644 (file)
index 0000000..4c280e9
--- /dev/null
@@ -0,0 +1,181 @@
+/* Loop Vectorization
+   Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+   Contributed by Dorit Naishlos <dorit@il.ibm.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#ifndef GCC_TREE_VECTORIZER_H
+#define GCC_TREE_VECTORIZER_H
+
+/* Used for naming of new temporaries.  */
+enum vect_var_kind {
+  vect_simple_var,
+  vect_pointer_var
+};
+
+/* Defines type of operation: unary or binary. */
+enum operation_type {
+  unary_op = 1,
+  binary_op
+};
+
+/*-----------------------------------------------------------------*/
+/* Info on vectorized defs.                                        */
+/*-----------------------------------------------------------------*/
+enum stmt_vec_info_type {
+  undef_vec_info_type = 0,
+  load_vec_info_type,
+  store_vec_info_type,
+  op_vec_info_type,
+  assignment_vec_info_type
+};
+
+typedef struct _stmt_vec_info {
+
+  enum stmt_vec_info_type type;
+
+  /* The stmt to which this info struct refers to.  */
+  tree stmt;
+
+  /* The loop with resprct to which STMT is vectorized.  */
+  struct loop *loop;
+
+  /* Not all stmts in the loop need to be vectorized. e.g, the incrementation
+     of the loop induction variable and computation of array indexes. relevant
+     indicates whether the stmt needs to be vectorized.  */
+  bool relevant;
+
+  /* The vector type to be used.  */
+  tree vectype;
+
+  /* The vectorized version of the stmt.  */
+  tree vectorized_stmt;
+
+
+  /** The following is relevant only for stmts that contain a non-scalar
+     data-ref (array/pointer/struct access). A GIMPLE stmt is expected to have 
+     at most one such data-ref.  **/
+
+  /* Information about the data-ref (access function, etc).  */
+  struct data_reference *data_ref_info;
+
+  /* Aliasing information.  */
+  tree memtag;
+} *stmt_vec_info;
+
+/* Access Functions.  */
+#define STMT_VINFO_TYPE(S)       (S)->type
+#define STMT_VINFO_STMT(S)       (S)->stmt
+#define STMT_VINFO_LOOP(S)       (S)->loop
+#define STMT_VINFO_RELEVANT_P(S) (S)->relevant
+#define STMT_VINFO_VECTYPE(S)    (S)->vectype
+#define STMT_VINFO_VEC_STMT(S)   (S)->vectorized_stmt
+#define STMT_VINFO_DATA_REF(S)   (S)->data_ref_info
+#define STMT_VINFO_MEMTAG(S)     (S)->memtag
+
+static inline void set_stmt_info (stmt_ann_t ann, stmt_vec_info stmt_info);
+static inline stmt_vec_info vinfo_for_stmt (tree stmt);
+
+static inline void
+set_stmt_info (stmt_ann_t ann, stmt_vec_info stmt_info)
+{
+  if (ann)
+    ann->common.aux = (char *) stmt_info;
+}
+
+static inline stmt_vec_info
+vinfo_for_stmt (tree stmt)
+{
+  stmt_ann_t ann = stmt_ann (stmt);
+  return ann ? (stmt_vec_info) ann->common.aux : NULL;
+}
+
+/*-----------------------------------------------------------------*/
+/* Info on data references alignment.                              */
+/*-----------------------------------------------------------------*/
+
+#define DR_MISALIGNMENT(DR)   (DR)->aux
+
+static inline bool
+aligned_access_p (struct data_reference *data_ref_info)
+{
+  return (DR_MISALIGNMENT (data_ref_info) == 0);
+}
+
+static inline bool
+unknown_alignment_for_access_p (struct data_reference *data_ref_info)
+{
+  return (DR_MISALIGNMENT (data_ref_info) == -1);
+}
+
+
+/*-----------------------------------------------------------------*/
+/* Info on vectorized loops.                                       */
+/*-----------------------------------------------------------------*/
+typedef struct _loop_vec_info {
+
+  /* The loop to which this info struct refers to.  */
+  struct loop *loop;
+
+  /* The loop basic blocks.  */
+  basic_block *bbs;
+
+  /* The loop exit_condition.  */
+  tree exit_cond;
+
+  /* Number of iterations. -1 if unknown.  */
+  HOST_WIDE_INT num_iters;
+
+  /* Is the loop vectorizable? */
+  bool vectorizable;
+
+  /* Unrolling factor  */
+  int vectorization_factor;
+
+  /* All data references in the loop that are being written to.  */
+  varray_type data_ref_writes;
+
+  /* All data references in the loop that are being read from.  */
+  varray_type data_ref_reads;
+} *loop_vec_info;
+
+/* Access Functions.  */
+#define LOOP_VINFO_LOOP(L)           (L)->loop
+#define LOOP_VINFO_BBS(L)            (L)->bbs
+#define LOOP_VINFO_EXIT_COND(L)      (L)->exit_cond
+#define LOOP_VINFO_NITERS(L)         (L)->num_iters
+#define LOOP_VINFO_VECTORIZABLE_P(L) (L)->vectorizable
+#define LOOP_VINFO_VECT_FACTOR(L)    (L)->vectorization_factor
+#define LOOP_VINFO_DATAREF_WRITES(L) (L)->data_ref_writes
+#define LOOP_VINFO_DATAREF_READS(L)  (L)->data_ref_reads
+
+#define LOOP_VINFO_NITERS_KNOWN_P(L) ((L)->num_iters > 0)
+
+/*-----------------------------------------------------------------*/
+/* Function prototypes.                                            */
+/*-----------------------------------------------------------------*/
+
+/* Main driver.  */
+extern void vectorize_loops (struct loops *);
+
+/* creation and deletion of loop and stmt info structs.  */
+extern loop_vec_info new_loop_vec_info (struct loop *loop);
+extern void destroy_loop_vec_info (loop_vec_info);
+extern stmt_vec_info new_stmt_vec_info (tree stmt, struct loop *loop);
+
+#endif  /* GCC_TREE_VECTORIZER_H  */