I failed to come up with ways using generic vector code to create specific GIMPLE the vectorizer creates so the following fills in the missing parsing of constructors in the GIMPLE FE. Notably aggregate assignments from empty constructors was also missing. (the special case of clobbers still is)
In particular I was searching for the best way to represent movq mem, %xmm0 on GIMPLE. Aka an 8 byte load into a vector register implicitely zero-extending. I settled with _2 = { v8qi, { 0,.... } }; but the explicit zero doesn't get optimized. Expect a PR for that now with a GIMPLE testcase ;) Bootstrap & regtest running on x86_64-unknown-linux-gnu. Richard. 2018-11-30 Richard Biener <rguent...@suse.de> c/ * gimple-parser.c (c_parser_gimple_postfix_expression): Parse _Literal (type) { ... } as empty aggregate or vector constructor. * gcc.dg/gimplefe-34.c: New testcase. * gcc.dg/gimplefe-35.c: Likewise. Index: gcc/c/gimple-parser.c =================================================================== --- gcc/c/gimple-parser.c (revision 266657) +++ gcc/c/gimple-parser.c (working copy) @@ -806,6 +806,7 @@ c_parser_gimple_call_internal (c_parser identifier constant string-literal + constructor gimple-call-internal */ @@ -934,7 +935,7 @@ c_parser_gimple_postfix_expression (c_pa } else if (strcmp (IDENTIFIER_POINTER (id), "_Literal") == 0) { - /* _Literal '(' type-name ')' [ '-' ] constant */ + /* _Literal '(' type-name ')' ( [ '-' ] constant | constructor ) */ c_parser_consume_token (parser); tree type = NULL_TREE; if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>")) @@ -946,28 +947,90 @@ c_parser_gimple_postfix_expression (c_pa c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); } - bool neg_p; - if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS))) - c_parser_consume_token (parser); - tree val = c_parser_gimple_postfix_expression (parser).value; - if (! type - || ! val - || val == error_mark_node - || ! CONSTANT_CLASS_P (val)) + if (! type) { c_parser_error (parser, "invalid _Literal"); return expr; } - if (neg_p) + if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) { - val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val); - if (! val) + c_parser_consume_token (parser); + if (!AGGREGATE_TYPE_P (type) + && !VECTOR_TYPE_P (type)) + { + c_parser_error (parser, "invalid type for _Literal with " + "constructor"); + c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, + "expected %<}%>"); + return expr; + } + vec<constructor_elt, va_gc> *v = NULL; + bool constant_p = true; + if (VECTOR_TYPE_P (type) + && !c_parser_next_token_is (parser, CPP_CLOSE_BRACE)) + { + vec_alloc (v, TYPE_VECTOR_SUBPARTS (type).to_constant ()); + do + { + tree val + = c_parser_gimple_postfix_expression (parser).value; + if (! val + || val == error_mark_node + || (! CONSTANT_CLASS_P (val) + && ! SSA_VAR_P (val))) + { + c_parser_error (parser, "invalid _Literal"); + return expr; + } + CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, val); + if (! CONSTANT_CLASS_P (val)) + constant_p = false; + if (c_parser_next_token_is (parser, CPP_COMMA)) + c_parser_consume_token (parser); + else + break; + } + while (1); + } + if (c_parser_require (parser, CPP_CLOSE_BRACE, + "expected %<}%>")) + { + if (v && constant_p) + expr.value = build_vector_from_ctor (type, v); + else + expr.value = build_constructor (type, v); + } + else + { + c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, + "expected %<}%>"); + return expr; + } + } + else + { + bool neg_p; + if ((neg_p = c_parser_next_token_is (parser, CPP_MINUS))) + c_parser_consume_token (parser); + tree val = c_parser_gimple_postfix_expression (parser).value; + if (! val + || val == error_mark_node + || ! CONSTANT_CLASS_P (val)) { c_parser_error (parser, "invalid _Literal"); return expr; } + if (neg_p) + { + val = const_unop (NEGATE_EXPR, TREE_TYPE (val), val); + if (! val) + { + c_parser_error (parser, "invalid _Literal"); + return expr; + } + } + expr.value = fold_convert (type, val); } - expr.value = fold_convert (type, val); return expr; } Index: gcc/testsuite/gcc.dg/gimplefe-34.c =================================================================== --- gcc/testsuite/gcc.dg/gimplefe-34.c (nonexistent) +++ gcc/testsuite/gcc.dg/gimplefe-34.c (working copy) @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +typedef unsigned char v16qi __attribute__((vector_size(16))); +typedef unsigned char v8qi __attribute__((vector_size(8))); + +v16qi x; + +void __GIMPLE foo (unsigned char *p) +{ + v8qi _2; + v16qi _3; + +bb_2: + _2 = __MEM <v8qi, 8> (p_1(D)); + _3 = _Literal (v16qi) { _2, _Literal (v8qi) { _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0, _Literal (unsigned char) 0 } }; + x = _3; + return; +} + Index: gcc/testsuite/gcc.dg/gimplefe-35.c =================================================================== --- gcc/testsuite/gcc.dg/gimplefe-35.c (nonexistent) +++ gcc/testsuite/gcc.dg/gimplefe-35.c (working copy) @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +struct X { int i; } x; +void __GIMPLE foo (void) +{ +bb_2: + x = _Literal (struct X) {}; + return; +} +