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