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  <rguent...@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.

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;
+}

Reply via email to