diff --git a/gcc/ChangeLog.cilk b/gcc/ChangeLog.cilk
index ebabff6..1398870 100644
--- a/gcc/ChangeLog.cilk
+++ b/gcc/ChangeLog.cilk
@@ -1,3 +1,15 @@
+2012-03-09  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+	* attribs.c (decl_attributes): Added a check for elemental function
+	attribute.
+	(is_elem_fn_attribute_p): New function.
+	* c-parser.c (c_parser_attributes): Added a check for vector attribute.
+	(c_parser_elem_fn_processor_clause): New function.
+	(c_parser_elem_fn_uniform_clause): Likewise.
+	(c_parser_elem_fn_linear_clause): Likewise.
+	(c_parser_elem_fn_vlength_clause): Likewise.
+	(c_parser_elem_fn_expr_list): Likewise.
+
 2012-02-15  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
 	* cilk.c (cilk_fix_stack_reg): New function.
diff --git a/gcc/attribs.c b/gcc/attribs.c
index 0e94fd2..2ececc4 100644
--- a/gcc/attribs.c
+++ b/gcc/attribs.c
@@ -228,6 +228,18 @@ lookup_attribute_spec (const_tree name)
 			 substring_hash (attr.str, attr.length));
 }
 
+
+static bool
+is_elem_fn_attribute_p (tree name)
+{
+  return is_attribute_p ("mask", name)
+    || is_attribute_p ("unmask", name)
+    || is_attribute_p ("vectorlength", name)
+    || is_attribute_p ("vector", name)
+    || is_attribute_p ("linear", name)
+    || is_attribute_p ("uniform", name);
+}
+
 /* Process the attributes listed in ATTRIBUTES and install them in *NODE,
    which is either a DECL (including a TYPE_DECL) or a TYPE.  If a DECL,
    it should be modified in place; if a TYPE, a copy should be created
@@ -312,8 +324,9 @@ decl_attributes (tree *node, tree attributes, int flags)
 
       if (spec == NULL)
 	{
-	  warning (OPT_Wattributes, "%qE attribute directive ignored",
-		   name);
+	  if (!is_elem_fn_attribute_p (name))
+	    warning (OPT_Wattributes, "%qE attribute directive ignored",
+		     name);
 	  continue;
 	}
       else if (list_length (args) < spec->min_length
diff --git a/gcc/c-parser.c b/gcc/c-parser.c
index c67ea97..4f940e1 100644
--- a/gcc/c-parser.c
+++ b/gcc/c-parser.c
@@ -65,6 +65,7 @@ extern struct c_expr  fix_array_notation_expr (location_t, enum tree_code,
 extern bool contains_array_notation_expr (tree);
 struct pragma_simd_values local_simd_values;
 
+		    
 
 /* Initialization routine for this file.  */
 
@@ -242,6 +243,8 @@ typedef struct GTY(()) c_parser {
 
 static GTY (()) c_parser *the_parser;
 
+static VEC(tree,gc) *c_parser_elem_fn_expr_list (c_parser *parser);
+
 /* Read in and lex a single token, storing it in *TOKEN.  */
 
 static void
@@ -3635,7 +3638,12 @@ c_parser_attributes (c_parser *parser)
 		attr_args = NULL_TREE;
 	      else
 		{
-		  expr_list = c_parser_expr_list (parser, false, true, NULL);
+		  if (TREE_CODE (attr_name) == IDENTIFIER_NODE
+		      && simple_cst_equal (attr_name,
+					   get_identifier ("vector")) == 1)
+		    expr_list = c_parser_elem_fn_expr_list (parser);
+		  else
+		    expr_list = c_parser_expr_list (parser, false, true, NULL);
 		  attr_args = build_tree_list_vec (expr_list);
 		  release_tree_vector (expr_list);
 		}
@@ -11870,4 +11878,421 @@ c_parser_array_notation (c_parser *parser, tree initial_index, tree array_value)
   return value_tree;
 }
 
+static tree
+c_parser_elem_fn_processor_clause (c_parser *parser)
+{
+  c_token *token;
+  tree proc_tree_list = NULL_TREE;
+  VEC(tree,gc) *proc_vec_list = NULL;
+
+  token = c_parser_peek_token (parser);
+  if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_error (parser, "expected %<)%>");
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+      return NULL_TREE;
+    }
+  else
+    c_parser_consume_token (parser);
+
+  proc_vec_list = make_tree_vector ();
+  
+  if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      token = c_parser_peek_token (parser);
+      if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	  && simple_cst_equal (token->value, get_identifier ("pentium_4")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  VEC_safe_push (tree, gc, proc_vec_list,
+			 build_string (strlen ("pentium_4"), "pentium_4"));
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("pentium4_sse3")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  VEC_safe_push (tree, gc, proc_vec_list,
+			 build_string (strlen ("pentium4_sse3"),
+				       "pentium4_sse3"));
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("core2_duo_ssse3")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  VEC_safe_push (tree, gc, proc_vec_list,
+			 build_string (strlen ("core2_duo_ssse3"),
+				       "core2_duo_ssse3"));
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("core2_duo_sse_4_1")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  VEC_safe_push (tree, gc, proc_vec_list,
+			 build_string (strlen ("core2_duo_sse_4_1"),
+				       "core2_duo_sse_4_1"));
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("core_i7_sse4_2")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  VEC_safe_push (tree, gc, proc_vec_list,
+			 build_string (strlen ("core_i7_sse4_2"),
+				       "core_i7_sse4_2"));
+	}
+      else
+	{
+	  sorry ("Processor type not supported");
+	}
+      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+	c_parser_consume_token (parser);
+      else
+	c_parser_error (parser, "expected %>)%>");
+    }
+  else
+    c_parser_error (parser, "expected %>(%> and CPUID");
+
+  proc_tree_list = build_tree_list_vec (proc_vec_list);
+  release_tree_vector (proc_vec_list);
+  proc_tree_list = build_tree_list (get_identifier ("processor"),
+				    proc_tree_list);
+  return proc_tree_list;
+}
+
+static tree
+c_parser_elem_fn_uniform_clause (c_parser *parser)
+{
+  c_token *token;
+  tree uniform_tree;
+  tree str_token = NULL_TREE;
+  VEC(tree,gc) *uniform_vec = NULL;
+
+  if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_error (parser, "expected %<)%>");
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+      return NULL_TREE;
+    }
+  else
+    c_parser_consume_token (parser);
+  
+  uniform_vec =  make_tree_vector ();
+  while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      token = c_parser_peek_token (parser);
+      if (token->value && token->type == CPP_NAME)
+	{
+	  /* convert the variable to a string */
+	  str_token = build_string (strlen (IDENTIFIER_POINTER (token->value)),
+				    IDENTIFIER_POINTER (token->value));
+	  VEC_safe_push (tree, gc, uniform_vec, str_token);
+	  c_parser_consume_token (parser);
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is_not (parser, CPP_NAME))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return NULL_TREE;
+		}
+	    }
+	  else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+	    {
+	      c_parser_error (parser,
+			      "expected %<,%> or %<)%> after identifier");
+	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+	      return NULL_TREE;
+	    }
+	}
+      else
+	{
+	  c_parser_error (parser, "expected number or comma");
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+	  return NULL_TREE;
+	}
+    }
+  c_parser_consume_token (parser);     
+  uniform_tree = build_tree_list_vec (uniform_vec);
+  release_tree_vector (uniform_vec);
+  uniform_tree = build_tree_list (get_identifier ("uniform"), uniform_tree);
+  return uniform_tree;
+}
+
+static tree
+c_parser_elem_fn_linear_clause (c_parser *parser)
+{
+  c_token *token;
+  VEC(tree,gc) *linear_vec = NULL;
+  tree linear_tree = NULL_TREE;
+  tree var_str, step_size;
+
+  if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_error (parser, "expected %<)%>");
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+      return NULL_TREE;
+    }
+  else
+    c_parser_consume_token (parser);
+  linear_vec = make_tree_vector ();
+  // VEC_safe_push (tree, gc, linear_vec, get_identifier ("linear"));
+
+  while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      token = c_parser_peek_token (parser);
+      if (token->value && token->type == CPP_NAME)
+	{
+	  var_str = build_string (strlen (IDENTIFIER_POINTER (token->value)),
+				  IDENTIFIER_POINTER (token->value));
+	  c_parser_consume_token (parser);
+	  if (c_parser_next_token_is (parser, CPP_COLON))
+	    {
+	      c_parser_consume_token (parser);
+	      token = c_parser_peek_token (parser);
+	      if (token->value && token->type == CPP_NUMBER)
+		step_size = token->value;
+	      else
+		{
+		  c_parser_error (parser, "expected step-size");
+		  return NULL_TREE;
+		}
+	      c_parser_consume_token (parser);
+	    }
+	  else
+	    step_size = integer_one_node;
+	  VEC_safe_push (tree, gc, linear_vec, var_str);
+	  VEC_safe_push (tree, gc, linear_vec, step_size);
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is_not (parser, CPP_NAME))
+		{
+		  c_parser_error (parser,
+				  "expected variable after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return NULL_TREE;
+		}
+	    }
+	  else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+	    {
+	      c_parser_error (parser,
+			      "expected %<,%> or %<)%> after variable/step");
+	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+	      return NULL_TREE;
+	    }
+	}
+      else
+	{
+	  c_parser_error (parser, "expected variable name or comma");
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+	  return NULL_TREE;
+	}
+    }
+  c_parser_consume_token (parser); /* consume the ')' */
+  linear_tree = build_tree_list_vec (linear_vec);
+  release_tree_vector (linear_vec);
+  linear_tree = build_tree_list (get_identifier ("linear"), linear_tree);
+  return linear_tree;
+}
+
+static tree
+c_parser_elem_fn_vlength_clause (c_parser *parser)
+{
+  c_token *token;
+  VEC(tree,gc) *vlength_vec = NULL;
+  tree vlength_tree = NULL_TREE;
+
+  if (!c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_error (parser, "expected %<)%>");
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+      return NULL_TREE;
+    }
+  else
+    c_parser_consume_token (parser);
+
+  vlength_vec = make_tree_vector ();
+  // VEC_safe_push (tree, gc, vlength_vec, get_identifier ("vectorlength"));
+  while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      token = c_parser_peek_token (parser);
+      if (token->value && token->type == CPP_NUMBER)
+	{
+	  VEC_safe_push (tree, gc, vlength_vec, token->value);
+	  c_parser_consume_token (parser);
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is_not (parser, CPP_NUMBER))
+		{
+		  c_parser_error (parser, "expected vectorlength after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return NULL_TREE;
+		}
+	    }
+	  else if (c_parser_next_token_is_not (parser, CPP_CLOSE_PAREN))
+	    {
+	      c_parser_error (parser,
+			      "expected %<,%> or %<)%> after vectorlength");
+	      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+	      return NULL_TREE;
+	    }
+	}
+      else
+	{
+	  c_parser_error (parser, "expected number or comma");
+	  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+	  return NULL_TREE;
+	}
+    }
+  c_parser_consume_token (parser);
+  vlength_tree = build_tree_list_vec (vlength_vec);
+  release_tree_vector (vlength_vec);
+  vlength_tree = build_tree_list (get_identifier ("vectorlength"),
+				  vlength_tree);
+  return vlength_tree;
+}
+  
+static VEC(tree,gc) *
+c_parser_elem_fn_expr_list (c_parser *parser)
+{
+  c_token *token;
+  VEC(tree,gc) *expr_list = NULL;
+  tree proc_list = NULL_TREE, mask_list = NULL_TREE, uniform_list = NULL_TREE;
+  tree vlength_list = NULL_TREE, linear_list = NULL_TREE;
+
+  expr_list = make_tree_vector ();
+
+  while (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+    {
+      token = c_parser_peek_token (parser);
+      if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	  && simple_cst_equal (token->value,
+			       get_identifier ("processor")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  gcc_assert (proc_list == NULL_TREE);
+	  proc_list = c_parser_elem_fn_processor_clause (parser);
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return expr_list;
+		}
+	    }
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("mask")) == 1)
+	{
+	  gcc_assert (mask_list == NULL_TREE);
+	  mask_list = get_identifier ("mask");
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return expr_list;
+		}
+	    }	 
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("unmask")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  gcc_assert (mask_list == NULL_TREE);
+	  mask_list = get_identifier ("unmask");
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return expr_list;
+		}
+	    }	  
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("vectorlength")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  gcc_assert (vlength_list == NULL_TREE);
+	  vlength_list = c_parser_elem_fn_vlength_clause (parser);
+	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return expr_list;
+		}
+	    }	  
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("uniform")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  gcc_assert (uniform_list == NULL_TREE);
+	  uniform_list = c_parser_elem_fn_uniform_clause (parser);
+	  	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return expr_list;
+		}
+	    }
+	}
+      else if (token->value && TREE_CODE (token->value) == IDENTIFIER_NODE
+	       && simple_cst_equal (token->value,
+				    get_identifier ("linear")) == 1)
+	{
+	  c_parser_consume_token (parser);
+	  gcc_assert (linear_list == NULL_TREE);
+	  linear_list = c_parser_elem_fn_linear_clause (parser);
+	  	  if (c_parser_next_token_is (parser, CPP_COMMA))
+	    {
+	      c_parser_consume_token (parser);
+	      if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+		{
+		  c_parser_error (parser, "expected identifier after %<,%>");
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
+		  return expr_list;
+		}
+	    }
+	}
+    }
+
+  if (proc_list)
+    VEC_safe_push (tree, gc, expr_list, proc_list);
+  if (vlength_list)
+    VEC_safe_push (tree, gc, expr_list, vlength_list);
+  if (uniform_list)
+    VEC_safe_push (tree, gc, expr_list, uniform_list);
+  if (mask_list)
+    VEC_safe_push (tree, gc, expr_list, mask_list);
+  if (linear_list)
+    VEC_safe_push (tree, gc, expr_list, linear_list);
+  
+  return expr_list;
+}
+
 #include "gt-c-parser.h"

