diff mbox

[Cilkplus] Gather Scatter Operations in Array Notations

Message ID BF230D13CA30DD48930C31D4099330000290EF@FMSMSX102.amr.corp.intel.com
State New
Headers show

Commit Message

Iyer, Balaji V Jan. 31, 2012, 4:25 a.m. UTC
Hello Everyone,
    This patch is for the Cilkplus branch, affecting both the C and C++ Compilers. It implements the Gather, scatter operations.

Thanking You,

Yours Sincerely,

Balaji V. Iyer.
diff mbox

Patch

diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk
index 4297c91..5913883 100644
--- a/gcc/ChangeLog.cilk
+++ b/gcc/ChangeLog.cilk
@@ -1,3 +1,8 @@ 
+2012-01-31  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* c-array-notation.c (build_array_notation_expr): Added another
+	dimension to lhs variables to handle gather scatter of array notations.
+
 2012-01-26  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* c-array-notation.c (fix_builtin_array_notation_fn): Initialized the
diff --git a/gcc/c-array-notation.c b/gcc/c-array-notation.c
index b3039a2..fe00520 100644
--- a/gcc/c-array-notation.c
+++ b/gcc/c-array-notation.c
@@ -283,12 +283,12 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
 			   enum tree_code modifycode, location_t rhs_loc,
 			   tree rhs, tree rhs_origtype)
 {
-  bool *lhs_vector = NULL, **rhs_vector = NULL, found_builtin_fn = false;
-  tree *lhs_array = NULL, **rhs_array = NULL;
+  bool **lhs_vector = NULL, **rhs_vector = NULL, found_builtin_fn = false;
+  tree **lhs_array = NULL, **rhs_array = NULL;
   tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
   tree array_expr = NULL_TREE;
-  tree *lhs_value = NULL, **rhs_value = NULL;
-  tree *lhs_stride = NULL, *lhs_length = NULL, *lhs_start = NULL;
+  tree **lhs_value = NULL, **rhs_value = NULL;
+  tree **lhs_stride = NULL, **lhs_length = NULL, **lhs_start = NULL;
   tree **rhs_stride = NULL, **rhs_length = NULL, **rhs_start = NULL;
   tree loop = NULL_TREE, *lhs_var = NULL, *rhs_var = NULL;
   tree *body_label = NULL, *body_label_expr = NULL;
@@ -296,12 +296,13 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   tree *if_stmt_label = NULL;
   tree *lhs_expr_incr = NULL, *rhs_expr_incr = NULL;
   tree *lhs_ind_init = NULL, *rhs_ind_init = NULL;
-  bool *lhs_count_down = NULL, **rhs_count_down = NULL;
+  bool **lhs_count_down = NULL, **rhs_count_down = NULL;
   tree *lhs_compare = NULL, *rhs_compare = NULL, *rhs_array_operand = NULL;
+  tree *lhs_array_operand = NULL;
   int lhs_rank = 0, rhs_rank = 0, ii = 0, jj = 0;
-  tree ii_tree = NULL_TREE, new_modify_expr;
+  tree ii_tree = NULL_TREE, new_modify_expr, *lhs_list = NULL;
   tree *rhs_list = NULL, new_var = NULL_TREE, builtin_loop = NULL_TREE;
-  int rhs_list_size = 0;
+  int rhs_list_size = 0, lhs_list_size = 0;
 
   find_rank (rhs, false, &rhs_rank);
 
@@ -349,6 +350,7 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   rhs_list_size = 0;
   rhs_list = NULL;
   extract_array_notation_exprs (rhs, true, &rhs_list, &rhs_list_size);
+  extract_array_notation_exprs (lhs, true, &lhs_list, &lhs_list_size);
   
   if (lhs_rank == 0 && rhs_rank != 0)
     {
@@ -362,35 +364,51 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
       return error_mark_node;
     }
   
-  lhs_vector = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+  lhs_vector = (bool **) xmalloc (sizeof (bool *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_vector[ii] = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+  
   rhs_vector = (bool **) xmalloc (sizeof (bool *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_vector[ii] = (bool *) xmalloc (sizeof (bool) * rhs_rank);
   
-  lhs_array = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  lhs_array = (tree **) xmalloc (sizeof (tree *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_array[ii] = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  
   rhs_array = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_array[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_value = (tree *) xmalloc (sizeof (tree) * lhs_rank);
-
+  lhs_value = (tree **) xmalloc (sizeof (tree *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_value[ii] = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  
   rhs_value = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_value[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_stride = (tree *) xmalloc (sizeof (tree) * lhs_rank);
-
+  lhs_stride = (tree **) xmalloc (sizeof (tree *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_stride[ii] = (tree *) xmalloc (sizeof (tree *) * lhs_rank);
+  
   rhs_stride = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_stride[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_length = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  lhs_length = (tree **) xmalloc (sizeof (tree *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_length[ii] = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  
   rhs_length = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_length[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
   
 
-  lhs_start = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  lhs_start = (tree **) xmalloc (sizeof (tree *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_start[ii] = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+  
   rhs_start = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_start[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
@@ -419,7 +437,10 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   lhs_ind_init = (tree *) xmalloc (sizeof (tree) * lhs_rank);
   rhs_ind_init = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_count_down = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+  lhs_count_down = (bool **) xmalloc (sizeof (bool *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_count_down[ii] = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+  
   rhs_count_down = (bool **) xmalloc (sizeof (bool *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_count_down[ii] = (bool *) xmalloc (sizeof (bool) * rhs_rank);
@@ -428,15 +449,25 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
   rhs_compare = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
   rhs_array_operand = (tree *) xmalloc (sizeof (tree) * rhs_list_size);
+  lhs_array_operand = (tree *) xmalloc (sizeof (tree) * lhs_list_size);
 
-  ii = 0;
-  for (ii_tree = lhs; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
-       ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+  if (lhs_rank)
     {
-      lhs_array[ii] = ii_tree;
-      ii++;
+      for (ii = 0; ii < lhs_list_size; ii++)
+	{
+	  jj = 0;
+	  for (ii_tree = lhs_list[ii];
+	       ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
+	       ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+	    {
+	      lhs_array[ii][jj] = ii_tree;
+	      jj++;
+	    }
+	}
     }
-
+  else
+    lhs_array[0][0] = NULL_TREE;
+  
   if (rhs_rank)
     {
       for (ii = 0; ii < rhs_list_size; ii++)
@@ -452,31 +483,36 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
 	}
     }
 
-  if (TREE_CODE (lhs) == ARRAY_NOTATION_REF)
+  for (ii = 0; ii < lhs_list_size; ii++)
     {
-      for (ii = 0; ii < lhs_rank; ii++)
+      if (TREE_CODE (lhs_list[ii]) == ARRAY_NOTATION_REF)
 	{
-	  if (TREE_CODE (lhs_array[ii]) == ARRAY_NOTATION_REF)
+	  for (jj = 0; jj < lhs_rank; jj++)
 	    {
-	      lhs_value[ii] = ARRAY_NOTATION_ARRAY (lhs_array[ii]);
-	      lhs_start[ii] = ARRAY_NOTATION_START (lhs_array[ii]);
-	      lhs_length[ii] = ARRAY_NOTATION_LENGTH (lhs_array[ii]);
-	      lhs_stride[ii] = ARRAY_NOTATION_STRIDE (lhs_array[ii]);
-	      lhs_vector[ii] = true;
-	      /* IF the stride value is variable (i.e. not constant) then
-	       * assume that the length is positive
-	       */
-	      if (!TREE_CONSTANT (lhs_length[ii]))
-		lhs_count_down[ii] = false;
-	      else if (tree_int_cst_lt
-		       (lhs_length[ii],
-			build_int_cst (TREE_TYPE (lhs_length[ii]), 0)))
-		lhs_count_down[ii] = true;
+	      if (TREE_CODE (lhs_array[ii][jj]) == ARRAY_NOTATION_REF)
+		{
+		  lhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (lhs_array[ii][jj]);
+		  lhs_start[ii][jj] = ARRAY_NOTATION_START (lhs_array[ii][jj]);
+		  lhs_length[ii][jj] =
+		    ARRAY_NOTATION_LENGTH (lhs_array[ii][jj]);
+		  lhs_stride[ii][jj] =
+		    ARRAY_NOTATION_STRIDE (lhs_array[ii][jj]);
+		  lhs_vector[ii][jj] = true;
+		  /* IF the stride value is variable (i.e. not constant) then
+		   * assume that the length is positive
+		   */
+		  if (!TREE_CONSTANT (lhs_length[ii][jj]))
+		    lhs_count_down[ii][jj] = false;
+		  else if (tree_int_cst_lt
+			   (lhs_length[ii][jj],
+			    build_zero_cst (TREE_TYPE (lhs_length[ii][jj]))))
+		    lhs_count_down[ii][jj] = true;
+		  else
+		    lhs_count_down[ii][jj] = false;
+		}
 	      else
-		lhs_count_down[ii] = false;
+		lhs_vector[ii][jj] = false;
 	    }
-	  else
-	    lhs_vector[ii] = false;
 	}
     }
 
@@ -517,15 +553,15 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
 
   for (ii = 0; ii < lhs_rank; ii++)
     {
-      if (lhs_vector[ii])
+      if (lhs_vector[0][ii])
 	{
 	  lhs_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
-				    TREE_TYPE (lhs_start[ii]));
+				    integer_type_node);
 	  lhs_ind_init[ii] = build_modify_expr
 	    (UNKNOWN_LOCATION, lhs_var[ii], TREE_TYPE (lhs_var[ii]),
 	     NOP_EXPR,
-	     UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start[ii]), 0),
-	     TREE_TYPE (lhs_start[ii]));
+	     UNKNOWN_LOCATION, build_zero_cst (TREE_TYPE (lhs_var[ii])),
+	     TREE_TYPE (lhs_var[ii]));
 	  
 	}
     }
@@ -575,29 +611,40 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
 
   if (lhs_rank)
     {
+      for (ii = 0; ii < lhs_list_size; ii++)
+	{
+	  if (lhs_vector[ii][0])
+	    {
       /* The last ARRAY_NOTATION element's ARRAY component should be the array's
        * base value
        */
-      array_expr_lhs = lhs_value[lhs_rank - 1];
-      for (ii = lhs_rank - 1; ii >= 0; ii--)
-	{
-	  /* Array[start_index + (induction_var * stride)] */
-	  array_expr_lhs = build_array_ref
-	    (location, array_expr_lhs,
-	     build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_start[ii],
-		     build2 (MULT_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
-			     lhs_stride[ii])));
-	  if (lhs_count_down[ii])
-	    lhs_expr_incr[ii] =
-	      build2 (MODIFY_EXPR, void_type_node, lhs_var[ii],
-		      build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
-			      build_int_cst (TREE_TYPE (lhs_var[ii]), -1)));
-	  else
-	    lhs_expr_incr[ii] =
-	      build2 (MODIFY_EXPR, void_type_node, lhs_var[ii],
-		      build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
-			      build_int_cst (TREE_TYPE (lhs_var[ii]), 1)));
+	      lhs_array_operand[ii] = lhs_value[ii][lhs_rank - 1];
+	      gcc_assert (lhs_array_operand[ii]);
+	      for (jj = lhs_rank - 1; jj >= 0; jj--)
+		{
+		  if (lhs_count_down[ii][jj])
+		      /* Array[start_index + (induction_var * stride)] */
+		      lhs_array_operand[ii] = build_array_ref
+			(UNKNOWN_LOCATION, lhs_array_operand[ii],
+			 build2 (MINUS_EXPR, TREE_TYPE (lhs_var[jj]),
+				 lhs_start[ii][jj],
+				 build2 (MULT_EXPR, TREE_TYPE (lhs_var[jj]),
+					 lhs_var[jj],
+					 lhs_stride[ii][jj])));
+		  else
+		    lhs_array_operand[ii] = build_array_ref
+		      (UNKNOWN_LOCATION, lhs_array_operand[ii],
+		       build2 (PLUS_EXPR, TREE_TYPE (lhs_var[jj]),
+			       lhs_start[ii][jj],
+			       build2 (MULT_EXPR, TREE_TYPE (lhs_var[jj]),
+				       lhs_var[jj],
+				       lhs_stride[ii][jj])));
+		}
+	    }
 	}
+      replace_array_notations (&lhs, true, lhs_list, lhs_array_operand,
+			       lhs_list_size);
+      array_expr_lhs = lhs;
     }
 
   if (rhs_rank)
@@ -698,9 +745,17 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
       rhs_expr_incr[ii] = build2
 	(MODIFY_EXPR, void_type_node, rhs_var[ii],
 	 build2 (PLUS_EXPR, TREE_TYPE (rhs_var[ii]), rhs_var[ii],
-		 build_int_cst (TREE_TYPE (rhs_var[ii]), 1)));
+		 build_one_cst (TREE_TYPE (rhs_var[ii]))));
     } 
 
+  for (ii = 0; ii < lhs_rank; ii++)
+    {
+      lhs_expr_incr[ii] = build2
+	(MODIFY_EXPR, void_type_node, lhs_var[ii],
+	 build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
+		 build_one_cst (TREE_TYPE (lhs_var[ii]))));
+    }
+  
   if (!array_expr_lhs)
     array_expr_lhs = lhs;
 
@@ -712,13 +767,13 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
     {
       if (rhs_rank && rhs_expr_incr[jj])
 	{
-	  if (lhs_count_down[jj])
+	  if (lhs_count_down[0][jj])
 	    lhs_compare[jj] = build2
-	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 	  
 	  else
 	    lhs_compare[jj] = build2
-	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 
 
 	  /* What we are doing here is this:
@@ -742,12 +797,12 @@  build_array_notation_expr (location_t location, tree lhs, tree lhs_origtype,
 	}
       else
 	{
-	  if (lhs_count_down[jj])
+	  if (lhs_count_down[0][jj])
 	    cond_expr[jj] = build2
-	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 	  else
 	    cond_expr[jj] = build2
-	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 	}
     }
   
diff --git a/gcc/cp/ChangeLog.cilk b/gcc/cp/ChangeLog.cilk
index dff1fb5..4a596a6 100644
--- a/gcc/cp/ChangeLog.cilk
+++ b/gcc/cp/ChangeLog.cilk
@@ -1,3 +1,14 @@ 
+2012-01-31  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* cp-array-notation.c (build_x_array_notation_expr): Added another
+	dimension to lhs parameters to handle scatter of array notations.  Also
+	replaced all cases of build_int_cst with 0 or 1 with build_zero_cst and
+	build_one_cst, respectively.
+	(fix_conditional_array_notations_1): Replaced build_int_cst with 0 or 1
+	with build_zero_cst and build_one_cst, respectively.
+	(fix_builtin_array_notation_fn): Likewise.
+	(fix_unary_array_notation_exprs): Likewise.
+
 2012-01-26  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* cp-array-notation.c (fix_builtin_array_notation_fn): Added new var
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index a2d83d0..244233c 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -294,12 +294,12 @@  tree
 build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 			     tsubst_flags_t complain)
 {
-  bool *lhs_vector = NULL, **rhs_vector = NULL;
-  tree *lhs_array = NULL, **rhs_array = NULL;
+  bool lhs_vector[100][100], **rhs_vector = NULL;
+  tree lhs_array[100][100], **rhs_array = NULL;
   tree array_expr_lhs = NULL_TREE, array_expr_rhs = NULL_TREE;
   tree array_expr = NULL_TREE;
-  tree *lhs_value = NULL, **rhs_value = NULL;
-  tree *lhs_stride = NULL, *lhs_length = NULL, *lhs_start = NULL;
+  tree lhs_value[100][100], **rhs_value = NULL;
+  tree lhs_stride[100][100], lhs_length[100][100], lhs_start[100][100];
   tree **rhs_stride = NULL, **rhs_length = NULL, **rhs_start = NULL;
   tree loop = NULL_TREE, *lhs_var = NULL, *rhs_var = NULL;
   tree *body_label = NULL, *body_label_expr = NULL;
@@ -307,17 +307,19 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
   tree *if_stmt_label = NULL;
   tree *lhs_expr_incr = NULL, *rhs_expr_incr = NULL;
   tree *lhs_ind_init = NULL, *rhs_ind_init = NULL;
-  bool *lhs_count_down = NULL, **rhs_count_down = NULL;
+  bool **lhs_count_down = NULL, **rhs_count_down = NULL;
   tree *lhs_compare = NULL, *rhs_compare = NULL, *rhs_array_operand = NULL;
+  tree *lhs_array_operand = NULL;
   int lhs_rank = 0, rhs_rank = 0, ii = 0, jj = 0;
   tree ii_tree = NULL_TREE;
-  tree *rhs_list = NULL;
-  int rhs_list_size = 0;
+  tree *rhs_list = NULL, *lhs_list = NULL;
+  int rhs_list_size = 0, lhs_list_size = 0;
   an_reduce_type type = REDUCE_UNKNOWN;
   
   find_rank (lhs, true, &lhs_rank);
   find_rank (rhs, true, &rhs_rank);
 
+  
   /* If both are scalar, then no reason to do any of the components inside this
    * function... a simple build_x_modify_expr would do.
    */
@@ -349,40 +351,34 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
       error ("Rank-mismatch");
       return error_mark_node;
     }
-  
-  lhs_vector = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+
+  /* We need this when we have a scatter issue */
+  extract_array_notation_exprs (lhs, true, &lhs_list, &lhs_list_size);
+
   rhs_vector = (bool **) xmalloc (sizeof (bool *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_vector[ii] = (bool *) xmalloc (sizeof (bool) * rhs_rank);
-  
-  lhs_array = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+    
   rhs_array = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_array[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_value = (tree *) xmalloc (sizeof (tree) * lhs_rank);
-
   rhs_value = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_value[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
-
-  lhs_stride = (tree *) xmalloc (sizeof (tree) * lhs_rank);
-
+ 
   rhs_stride = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_stride[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_length = (tree *) xmalloc (sizeof (tree) * lhs_rank);
   rhs_length = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_length[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
-  
-
-  lhs_start = (tree *) xmalloc (sizeof (tree) * lhs_rank);
+    
   rhs_start = (tree **) xmalloc (sizeof (tree *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_start[ii] = (tree *) xmalloc (sizeof (tree) * rhs_rank);
-
+   
   lhs_var = (tree *) xmalloc (sizeof (tree) * lhs_rank);
   rhs_var = (tree *) xmalloc (sizeof (tree) * rhs_rank);
   
@@ -407,7 +403,10 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
   lhs_ind_init = (tree *) xmalloc (sizeof (tree) * lhs_rank);
   rhs_ind_init = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
-  lhs_count_down = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+  lhs_count_down = (bool **) xmalloc (sizeof (bool *) * lhs_list_size);
+  for (ii = 0; ii < lhs_list_size; ii++)
+    lhs_count_down[ii] = (bool *) xmalloc (sizeof (bool) * lhs_rank);
+  
   rhs_count_down = (bool **) xmalloc (sizeof (bool *) * rhs_list_size);
   for (ii = 0; ii < rhs_list_size; ii++)
     rhs_count_down[ii] = (bool *) xmalloc (sizeof (bool) * rhs_rank);
@@ -415,20 +414,29 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
   lhs_compare = (tree *) xmalloc (sizeof (tree) * lhs_rank);
   rhs_compare = (tree *) xmalloc (sizeof (tree) * rhs_rank);
 
+  lhs_array_operand = (tree *) xmalloc (sizeof (tree) * lhs_list_size);
   rhs_array_operand = (tree *) xmalloc (sizeof (tree) * rhs_list_size);
-
-  ii = 0;
+  
   if (lhs_rank)
     {
-      for (ii_tree = lhs; ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
-	   ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+      for (ii = 0; ii < lhs_list_size; ii++)
+	for (jj = 0; jj < lhs_rank; jj++)
+	  lhs_array[ii][jj] = NULL_TREE;
+
+      for (ii = 0; ii < lhs_list_size; ii++)
 	{
-	  lhs_array[ii] = ii_tree;
-	  ii++;
+	  jj = 0;
+	  for (ii_tree = lhs_list[ii];
+	       ii_tree && TREE_CODE (ii_tree) == ARRAY_NOTATION_REF;
+	       ii_tree = ARRAY_NOTATION_ARRAY (ii_tree))
+	    {
+	      lhs_array[ii][jj] = ii_tree;
+	      jj++;
+	    }
 	}
     }
   else
-    lhs_array[0] = NULL_TREE;
+    lhs_array[0][0] = NULL_TREE;
 
   if (rhs_rank)
     {
@@ -445,31 +453,36 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	}
     }
 
-  if (TREE_CODE (lhs) == ARRAY_NOTATION_REF)
+  for (ii = 0; ii < lhs_list_size; ii++)
     {
-      for (ii = 0; ii < lhs_rank; ii++)
+      if (TREE_CODE (lhs_list[ii]) == ARRAY_NOTATION_REF)
 	{
-	  if (TREE_CODE (lhs_array[ii]) == ARRAY_NOTATION_REF)
+	  for (jj = 0; jj < lhs_rank; jj++)
 	    {
-	      lhs_value[ii] = ARRAY_NOTATION_ARRAY (lhs_array[ii]);
-	      lhs_start[ii] = ARRAY_NOTATION_START (lhs_array[ii]);
-	      lhs_length[ii] = ARRAY_NOTATION_LENGTH (lhs_array[ii]);
-	      lhs_stride[ii] = ARRAY_NOTATION_STRIDE (lhs_array[ii]);
-	      lhs_vector[ii] = true;
-	      /* IF the stride value is variable (i.e. not constant) then
-	       * assume that the length is positive
-	       */
-	      if (!TREE_CONSTANT (lhs_length[ii]))
-		lhs_count_down[ii] = false;
-	      else if (tree_int_cst_lt
-		       (lhs_length[ii],
-			build_int_cst (TREE_TYPE (lhs_length[ii]), 0)))
-		lhs_count_down[ii] = true;
+	      if (TREE_CODE (lhs_array[ii][jj]) == ARRAY_NOTATION_REF)
+		{
+		  lhs_value[ii][jj] = ARRAY_NOTATION_ARRAY (lhs_array[ii][jj]);
+		  lhs_start[ii][jj] = ARRAY_NOTATION_START (lhs_array[ii][jj]);
+		  lhs_length[ii][jj] =
+		    ARRAY_NOTATION_LENGTH (lhs_array[ii][jj]);
+		  lhs_stride[ii][jj] =
+		    ARRAY_NOTATION_STRIDE (lhs_array[ii][jj]);
+		  lhs_vector[ii][jj] = true;
+		  
+		  /* IF the stride value is variable (i.e. not constant) then
+		   * assume that the length is positive  */
+		  if (!TREE_CONSTANT (lhs_length[ii][jj]))
+		    lhs_count_down[ii][jj] = false;
+		  else if (tree_int_cst_lt
+			   (lhs_length[ii][jj],
+			    build_zero_cst (TREE_TYPE (lhs_length[ii][jj]))))
+		    lhs_count_down[ii][jj] = true;
+		  else
+		    lhs_count_down[ii][jj] = false;
+		}
 	      else
-		lhs_count_down[ii] = false;
+		lhs_vector[ii][jj] = false;
 	    }
-	  else
-	    lhs_vector[ii] = false;
 	}
     }
 
@@ -495,7 +508,7 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 		    rhs_count_down[ii][jj] = false;
 		  else if (tree_int_cst_lt
 			   (rhs_length[ii][jj],
-			    build_int_cst (TREE_TYPE (rhs_length[ii][jj]), 0)))
+			    build_zero_cst (TREE_TYPE (rhs_length[ii][jj]))))
 		    rhs_count_down[ii][jj] = true;
 		  else
 		    rhs_count_down[ii][jj] = false;	
@@ -510,15 +523,15 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
   for (ii = 0; ii < lhs_rank; ii++)
     {
-      if (lhs_vector[ii])
+      if (lhs_vector[0][ii])
 	{
 	  lhs_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
-				    TREE_TYPE (lhs_start[ii]));
+				    TREE_TYPE (lhs_start[0][ii]));
 	  lhs_ind_init[ii] = build_modify_expr
 	    (UNKNOWN_LOCATION, lhs_var[ii], TREE_TYPE (lhs_var[ii]),
 	     NOP_EXPR,
-	     UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (lhs_start[ii]), 0),
-	     TREE_TYPE (lhs_start[ii]));
+	     UNKNOWN_LOCATION, build_zero_cst (TREE_TYPE (lhs_var[ii])),
+	     TREE_TYPE (lhs_var[ii]));
 	  
 	}
     }
@@ -526,14 +539,13 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
   for (ii = 0; ii < rhs_rank; ii++)
     {
       /* When we have a polynomial, we assume that the indices are of type
-       * integer
-       */
+       * integer */
       rhs_var[ii] = build_decl (UNKNOWN_LOCATION, VAR_DECL, NULL_TREE,
 				integer_type_node);
       rhs_ind_init[ii] = build_modify_expr
 	(UNKNOWN_LOCATION, rhs_var[ii], TREE_TYPE (rhs_var[ii]),
 	 NOP_EXPR,
-	 UNKNOWN_LOCATION, build_int_cst (TREE_TYPE (rhs_var[ii]), 0),
+	 UNKNOWN_LOCATION, build_zero_cst (TREE_TYPE (rhs_var[ii])),
 	 TREE_TYPE (rhs_var[ii]));
     }
   
@@ -568,29 +580,43 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 
   if (lhs_rank)
     {
-      /* The last ARRAY_NOTATION element's ARRAY component should be the array's
-       * base value
-       */
-      array_expr_lhs = lhs_value[lhs_rank - 1];
-      for (ii = lhs_rank - 1; ii >= 0; ii--)
+      for (ii = 0; ii < lhs_list_size; ii++)
 	{
-	  /* Array[start_index + (induction_var * stride)] */
-	  array_expr_lhs = build_array_ref
-	    (UNKNOWN_LOCATION, array_expr_lhs,
-	     build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_start[ii],
-		     build2 (MULT_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
-			     lhs_stride[ii])));
-	  if (lhs_count_down[ii])
-	    lhs_expr_incr[ii] =
-	      build2 (MODIFY_EXPR, void_type_node, lhs_var[ii],
-		      build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
-			      build_int_cst (TREE_TYPE (lhs_var[ii]), -1)));
-	  else
-	    lhs_expr_incr[ii] =
-	      build2 (MODIFY_EXPR, void_type_node, lhs_var[ii],
-		      build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
-			      build_int_cst (TREE_TYPE (lhs_var[ii]), 1)));
+	  if (lhs_vector[ii][0])
+	    {
+	      /* The last ARRAY_NOTATION element's ARRAY component should be
+	       * the array's base value */
+	      lhs_array_operand[ii] = lhs_value[ii][lhs_rank - 1];
+	      gcc_assert (lhs_array_operand[ii]);
+		for (jj = lhs_rank - 1; jj >= 0; jj--)
+		  {
+		    if (lhs_count_down[ii][jj])
+		      {
+			/* Array[start_index + (induction_var * stride)] */
+			lhs_array_operand[ii] = build_array_ref
+			  (UNKNOWN_LOCATION, lhs_array_operand[ii],
+			   build2 (MINUS_EXPR, TREE_TYPE (lhs_var[jj]),
+				   lhs_start[ii][jj],
+				   build2 (MULT_EXPR, TREE_TYPE (lhs_var[jj]),
+					   lhs_var[jj],
+					   lhs_stride[ii][jj])));
+		      }
+		    else
+		      {
+			lhs_array_operand[ii] = build_array_ref
+			  (UNKNOWN_LOCATION, lhs_array_operand[ii],
+			   build2 (PLUS_EXPR, TREE_TYPE (lhs_var[jj]),
+				   lhs_start[ii][jj],
+				   build2 (MULT_EXPR, TREE_TYPE (lhs_var[jj]),
+					   lhs_var[jj],
+					   lhs_stride[ii][jj])));
+		      }
+		  }
+	    }
 	}
+      replace_array_notations (&lhs, true, lhs_list, lhs_array_operand,
+			       lhs_list_size);
+      array_expr_lhs = lhs;
     }
 
   if (rhs_rank)
@@ -649,11 +675,10 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 		      }
 		  }
 	    }
-	}
-	      
+	}	
       replace_array_notations (&rhs, true, rhs_list, rhs_array_operand,
 				 rhs_list_size);
-	array_expr_rhs = rhs;
+      array_expr_rhs = rhs;
     }
   else
     {
@@ -691,9 +716,15 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
       rhs_expr_incr[ii] = build2
 	(MODIFY_EXPR, void_type_node, rhs_var[ii],
 	 build2 (PLUS_EXPR, TREE_TYPE (rhs_var[ii]), rhs_var[ii],
-		 build_int_cst (TREE_TYPE (rhs_var[ii]), 1)));
+		 build_one_cst (TREE_TYPE (rhs_var[ii]))));
+    }
+  for (ii = 0; ii < lhs_rank; ii++)
+    {
+      lhs_expr_incr[ii] = build2
+	(MODIFY_EXPR, void_type_node, lhs_var[ii],
+	 build2 (PLUS_EXPR, TREE_TYPE (lhs_var[ii]), lhs_var[ii],
+		 build_one_cst (TREE_TYPE (lhs_var[ii]))));	
     }
-  
   if (!array_expr_lhs)
     array_expr_lhs = lhs;
   
@@ -704,13 +735,13 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
     {
       if (rhs_rank && rhs_expr_incr[jj])
 	{
-	  if (lhs_count_down[jj])
+	  if (lhs_count_down[0][jj])
 	    lhs_compare[jj] = build2
-	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 	  
 	  else
 	    lhs_compare[jj] = build2
-	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 
 
 	  /* What we are doing here is this:
@@ -737,12 +768,12 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	}
       else
 	{
-	  if (lhs_count_down[jj])
+	  if (lhs_count_down[0][jj])
 	    cond_expr[jj] = build2
-	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (GT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 	  else
 	    cond_expr[jj] = build2
-	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[jj]);
+	      (LT_EXPR, boolean_type_node, lhs_var[jj], lhs_length[0][jj]);
 	}
     }
   
@@ -792,7 +823,62 @@  build_x_array_notation_expr (tree lhs, enum tree_code modifycode, tree rhs,
 	(build1 (GOTO_EXPR, void_type_node, if_stmt_label[ii]), &loop);
       append_to_statement_list (exit_label_expr[ii], &loop);
     }
-   
+
+  for (ii = 0; ii < rhs_list_size; ii++)
+    {
+      free (rhs_vector[ii]);
+      free (rhs_array[ii]);
+      free (rhs_value[ii]);
+      free (rhs_length[ii]);
+      free (rhs_stride[ii]);
+      free (rhs_start[ii]);
+    }
+  if (rhs_vector)
+    free (rhs_vector);
+
+  if (rhs_array)
+    free (rhs_array);
+  if (rhs_value)
+    free (rhs_value);
+  if (rhs_length)
+    free (rhs_length);
+  if (rhs_stride)
+    free (rhs_stride);
+  if (rhs_start)
+    free (rhs_start);
+
+  
+  if (exit_label)    
+    free (exit_label);
+  if (exit_label_expr)
+    free (exit_label_expr);
+
+  if (if_stmt_label)
+    free (if_stmt_label);
+  if (body_label)
+    free (body_label);
+  if (body_label_expr)
+    free (body_label_expr);
+  
+  if (rhs_expr_incr)    
+    free (rhs_expr_incr);
+  if (rhs_ind_init)
+    free (rhs_ind_init);
+  
+  if (lhs_array_operand)
+    free (lhs_array_operand);
+  if (rhs_array_operand)
+    free (rhs_array_operand);
+  if (rhs_compare)
+    free (rhs_compare);
+  if (lhs_compare)
+    free (lhs_compare);
+
+  if (lhs_list)
+    free (lhs_list);
+  if (rhs_list)
+    free (rhs_list);
+
   return loop;
 }
 
@@ -910,8 +996,7 @@  fix_conditional_array_notations_1 (tree stmt)
 		      count_down[ii][jj] = false;
 		  else if (tree_int_cst_lt
 			   (array_length[ii][jj],
-			    build_int_cst (TREE_TYPE (array_length[ii][jj]),
-					   0)))
+			    build_zero_cst (TREE_TYPE (array_length[ii][jj]))))
 		    count_down[ii][jj] = true;
 		  else
 		    count_down[ii][jj] = false;
@@ -933,7 +1018,7 @@  fix_conditional_array_notations_1 (tree stmt)
 	build_modify_expr (UNKNOWN_LOCATION, array_var[ii],
 			   TREE_TYPE (array_var[ii]), NOP_EXPR,
 			   UNKNOWN_LOCATION,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
+			   build_zero_cst (TREE_TYPE (array_var[ii])),
 			   TREE_TYPE (array_var[ii]));
 	
     }
@@ -1005,7 +1090,7 @@  fix_conditional_array_notations_1 (tree stmt)
       expr_incr[ii] =
 	build2 (MODIFY_EXPR, void_type_node, array_var[ii],
 		build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
-			build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+			build_one_cst (TREE_TYPE (array_var[ii]))));
     }
   
   for (jj = 0; jj < rank; jj++)
@@ -1423,8 +1508,7 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
 		      count_down[ii][jj] = false;
 		  else if (tree_int_cst_lt
 			   (array_length[ii][jj],
-			    build_int_cst (TREE_TYPE (array_length[ii][jj]),
-					   0)))
+			    build_zero_cst (TREE_TYPE (array_length[ii][jj]))))
 		    count_down[ii][jj] = true;
 		  else
 		    count_down[ii][jj] = false;
@@ -1446,7 +1530,7 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
 	build_modify_expr (UNKNOWN_LOCATION, array_var[ii],
 			   TREE_TYPE (array_var[ii]), NOP_EXPR,
 			   UNKNOWN_LOCATION,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
+			   build_zero_cst (TREE_TYPE (array_var[ii])),
 			   TREE_TYPE (array_var[ii]));	
     }
 
@@ -1518,7 +1602,7 @@  fix_builtin_array_notation_fn (tree an_builtin_fn, tree *new_var)
       expr_incr[ii] =
 	build2 (MODIFY_EXPR, void_type_node, array_var[ii],
 		build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
-			build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+			build_one_cst (TREE_TYPE (array_var[ii]))));
     }
   
   for (jj = 0; jj < rank; jj++)
@@ -1856,8 +1940,7 @@  fix_unary_array_notation_exprs (tree orig_stmt)
 		      count_down[ii][jj] = false;
 		  else if (tree_int_cst_lt
 			   (array_length[ii][jj],
-			    build_int_cst (TREE_TYPE (array_length[ii][jj]),
-					   0)))
+			    build_zero_cst (TREE_TYPE (array_length[ii][jj]))))
 		    count_down[ii][jj] = true;
 		  else
 		    count_down[ii][jj] = false;
@@ -1878,7 +1961,7 @@  fix_unary_array_notation_exprs (tree orig_stmt)
 	build_modify_expr (UNKNOWN_LOCATION, array_var[ii],
 			   TREE_TYPE (array_var[ii]), NOP_EXPR,
 			   UNKNOWN_LOCATION,
-			   build_int_cst (TREE_TYPE (array_var[ii]), 0),
+			   build_zero_cst (TREE_TYPE (array_var[ii])),
 			   TREE_TYPE (array_var[ii]));	
     }
 
@@ -1949,7 +2032,7 @@  fix_unary_array_notation_exprs (tree orig_stmt)
       expr_incr[ii] =
 	build2 (MODIFY_EXPR, void_type_node, array_var[ii],
 		build2 (PLUS_EXPR, TREE_TYPE (array_var[ii]), array_var[ii],
-			build_int_cst (TREE_TYPE (array_var[ii]), 1)));
+			build_one_cst (TREE_TYPE (array_var[ii]))));
     }
   
   for (jj = 0; jj < rank; jj++)
diff --git a/gcc/testsuite/ChangeLog.cilk b/gcc/testsuite/ChangeLog.cilk
index eb193f5..10f9cae 100644
--- a/gcc/testsuite/ChangeLog.cilk
+++ b/gcc/testsuite/ChangeLog.cilk
@@ -1,3 +1,7 @@ 
+2012-01-31  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* gcc.dg/cilk-plus/array_notation_tests/gather_scatter.c: New.
+	* g++.dg/cilk-plus/array_notation_tests/gather_scatter.cc: Likewise.
 2012-01-30  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* g++.dg/cilk-plus/array_notation_tests/array_test2.cc: Changed a
diff --git a/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/gather_scatter.cc b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/gather_scatter.cc
new file mode 100644
index 0000000..6b8a353
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cilk-plus/array_notation_tests/gather_scatter.cc
@@ -0,0 +1,35 @@ 
+#if HAVE_IO
+#include <iostream> 
+#endif
+/* #include <cstdlib> */
+
+int main(int argc, char **argv)
+{
+  int array[10], array2[10], x = 0, y;
+  float array3[10][10][10];
+  int x_correct, y_correct;
+
+  for (int ii = 0; ii < 10; ii++)
+    {
+      array[ii] = 1+ii;
+      array2[ii]= 2;
+    }
+  
+  array[array2[:]] = 5;
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    std::cout << "array[" << ii << "] = " << array[ii] << std::endl;
+#endif
+
+  array3[array[:]][array2[:]][array[0:10:1]] = (float)array[array2[:]];
+
+#if HAVE_IO
+  for (int ii = 0; ii < 10; ii++)
+    for (int jj = 0; jj < 10; jj++)
+      for (int kk = 0; kk < 10; kk++)
+	std::cout << "array[" << ii << "][" << jj << "][" << kk << "] = "
+	  << array3[ii][jj][kk] << std::endl;
+#endif
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/gather_scatter.c b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/gather_scatter.c
new file mode 100644
index 0000000..0e7ac28
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/array_notation_tests/gather_scatter.c
@@ -0,0 +1,47 @@ 
+#if HAVE_IO
+#include <stdio.h>
+#endif
+/* #include <cstdlib> */
+
+int main(int argc, char **argv)
+{
+  int array[10][10], array2[10], array3[10], x = 0, y;
+  int x_correct, y_correct, ii, jj = 0;
+  float array4[10][10][10][10];
+  for (ii = 0; ii < 10; ii++)
+    {
+      for (jj = 0; jj < 10; jj++)
+	{
+	  array[ii][jj] = 1+ii;
+	  array2[ii]= 2;
+	  array3[ii]= 3;
+	}
+    }
+  
+  array[array2[:]][array3[:]] = 1000;
+  
+#if HAVE_IO
+  for (ii = 0; ii < 10; ii++) {
+    for (jj = 0; jj < 10; jj++) {
+      printf("%4d\t", array[ii][jj]);
+    }
+    printf("\n");
+  }
+#endif
+
+  array4[array2[:]][array3[0:10:1]][array2[0:10:1]][array3[0:10:1]] =
+    (float)array[array2[:]][array3[:]]; 
+
+#if HAVE_IO
+  for (ii = 0; ii < 10; ii++) {
+      for (jj = 0; jj < 10; jj++) {
+	  for (kk = 0; kk < 10; kk++) {
+	      for (ll = 0; ll < 10; ll++) {
+		  printf("%4d\n", array4[ii][jj][kk][ll]);
+	      }
+	  }
+      }
+  }
+#endif  
+  return 0;
+}