[gimplefe] Add __VIEW_CONVERT parsing

Message ID alpine.LSU.2.20.1905141433210.10704@zhemvz.fhfr.qr
State New
Headers show
Series
  • [gimplefe] Add __VIEW_CONVERT parsing
Related show

Commit Message

Richard Biener May 14, 2019, 12:38 p.m.
For vector testcases this is very much required (as others, coming).

It also seems to handle __VIEW_CONVERT in a component-reference
chain just fine though handling this wasn't the original intention.

Bootstrap / regtest running on x86_64-unknown-linux-gnu.

Richard.

2019-05-14  Richard Biener  <rguenther@suse.de>

	* gimple-parser.c (c_parser_gimple_statement): Remove
	questionable auto-promotion to VIEW_CONVERT_EXPR.
	(c_parser_gimple_typespec): Split out from __MEM parsing.
	(c_parser_gimple_postfix_expression): Handle __VIEW_CONVERT.
	* tree-pretty-print.c (dump_generic_node): Dump VIEW_CONVERT_EXPR
	as __VIEW_CONVERT with -gimple.

	* gcc.dg/gimplefe-40.c: New testcase.

Patch

Index: gcc/c/gimple-parser.c
===================================================================
--- gcc/c/gimple-parser.c	(revision 271155)
+++ gcc/c/gimple-parser.c	(working copy)
@@ -724,14 +724,8 @@  c_parser_gimple_statement (gimple_parser
 	  && rhs.value != error_mark_node)
 	{
 	  enum tree_code code = NOP_EXPR;
-	  if (VECTOR_TYPE_P (TREE_TYPE (lhs.value)))
-	    {
-	      code = VIEW_CONVERT_EXPR;
-	      rhs.value = build1 (VIEW_CONVERT_EXPR,
-				  TREE_TYPE (lhs.value), rhs.value);
-	    }
-	  else if (FLOAT_TYPE_P (TREE_TYPE (lhs.value))
-		   && ! FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
+	  if (FLOAT_TYPE_P (TREE_TYPE (lhs.value))
+	      && ! FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
 	    code = FLOAT_EXPR;
 	  else if (! FLOAT_TYPE_P (TREE_TYPE (lhs.value))
 		   && FLOAT_TYPE_P (TREE_TYPE (rhs.value)))
@@ -1247,6 +1241,36 @@  c_parser_gimple_call_internal (gimple_pa
   return expr;
 }
 
+/* Parse '<' type [',' alignment] '>' and return a type on success
+   and NULL_TREE on error.  */
+
+static tree
+c_parser_gimple_typespec (gimple_parser &parser)
+{
+  struct c_type_name *type_name = NULL;
+  tree alignment = NULL_TREE;
+  if (c_parser_require (parser, CPP_LESS, "expected %<<%>"))
+    {
+      type_name = c_parser_type_name (parser);
+      /* Optional alignment.  */
+      if (c_parser_next_token_is (parser, CPP_COMMA))
+	{
+	  c_parser_consume_token (parser);
+	  alignment
+	      = c_parser_gimple_postfix_expression (parser).value;
+	}
+      c_parser_skip_until_found (parser,
+				 CPP_GREATER, "expected %<>%>");
+    }
+  if (!type_name)
+    return NULL_TREE;
+  tree tem;
+  tree type = groktypename (type_name, &tem, NULL);
+  if (alignment)
+    type = build_aligned_type (type, tree_to_uhwi (alignment));
+  return type;
+}
+
 /* Parse gimple postfix expression.
 
    gimple-postfix-expression:
@@ -1316,21 +1340,7 @@  c_parser_gimple_postfix_expression (gimp
 		           [ '+' number ] ')'  */
 	      location_t loc = c_parser_peek_token (parser)->location;
 	      c_parser_consume_token (parser);
-	      struct c_type_name *type_name = NULL;
-	      tree alignment = NULL_TREE;
-	      if (c_parser_require (parser, CPP_LESS, "expected %<<%>"))
-	        {
-		  type_name = c_parser_type_name (parser);
-		  /* Optional alignment.  */
-		  if (c_parser_next_token_is (parser, CPP_COMMA))
-		    {
-		      c_parser_consume_token (parser);
-		      alignment
-			= c_parser_gimple_postfix_expression (parser).value;
-		    }
-		  c_parser_skip_until_found (parser,
-					     CPP_GREATER, "expected %<>%>");
-		}
+	      tree type = c_parser_gimple_typespec (parser);
 	      struct c_expr ptr;
 	      ptr.value = error_mark_node;
 	      tree alias_off = NULL_TREE;
@@ -1378,19 +1388,33 @@  c_parser_gimple_postfix_expression (gimp
 		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
 					     "expected %<)%>");
 		}
-	      if (! type_name || c_parser_error (parser))
+	      if (! type || c_parser_error (parser))
 		{
 		  c_parser_set_error (parser, false);
 		  return expr;
 		}
-	      tree tem = NULL_TREE;
-	      tree type = groktypename (type_name, &tem, NULL);
-	      if (alignment)
-		type = build_aligned_type (type, tree_to_uhwi (alignment));
 	      expr.value = build2_loc (loc, MEM_REF,
 				       type, ptr.value, alias_off);
 	      break;
 	    }
+	  else if (strcmp (IDENTIFIER_POINTER (id), "__VIEW_CONVERT") == 0)
+	    {
+	      /* __VIEW_CONVERT '<' type-name [ ',' number ] '>'
+	                        '(' postfix-expression ')'  */
+	      location_t loc = c_parser_peek_token (parser)->location;
+	      c_parser_consume_token (parser);
+	      tree type = c_parser_gimple_typespec (parser);
+	      if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+		{
+		  c_expr op = c_parser_gimple_postfix_expression (parser);
+		  c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+					     "expected %<)%>");
+		  if (type && op.value != error_mark_node)
+		    expr.value = build1_loc (loc, VIEW_CONVERT_EXPR,
+					     type, op.value);
+		}
+	      break;
+	    }
 	  else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0)
 	    {
 	      /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor ) */
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 271155)
+++ gcc/tree-pretty-print.c	(working copy)
@@ -2653,7 +2653,10 @@  dump_generic_node (pretty_printer *pp, t
       break;
 
     case VIEW_CONVERT_EXPR:
-      pp_string (pp, "VIEW_CONVERT_EXPR<");
+      if (flags & TDF_GIMPLE)
+	pp_string (pp, "__VIEW_CONVERT <");
+      else
+	pp_string (pp, "VIEW_CONVERT_EXPR<");
       dump_generic_node (pp, TREE_TYPE (node), spc, flags, false);
       pp_string (pp, ">(");
       dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
Index: gcc/testsuite/gcc.dg/gimplefe-40.c
===================================================================
--- gcc/testsuite/gcc.dg/gimplefe-40.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/gimplefe-40.c	(working copy)
@@ -0,0 +1,15 @@ 
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-fgimple -Wno-psabi -w" } */
+
+typedef float v4sf __attribute__((vector_size(16)));
+v4sf __GIMPLE (ssa)
+load (const void * p)
+{
+  __int128 unsigned _3;
+  v4sf _4;
+
+  __BB(2):
+  _3 = __MEM <__int128 unsigned, 8> ((char *)p_2(D));
+  _4 = __VIEW_CONVERT <v4sf>(_3);
+  return _4;
+}