Gimple FE support for internal functions

Message ID 871seaofij.fsf@linaro.org
State New
Headers show
Series
  • Gimple FE support for internal functions
Related show

Commit Message

Richard Sandiford May 17, 2018, 8:25 a.m.
This patch gets the gimple FE to parse calls to internal functions.
The only non-obvious thing was how the functions should be written
to avoid clashes with real function names.  One option would be to
go the magic number of underscores route, but we already do that for
built-in functions, and it would be good to keep them visually
distinct.  In the end I borrowed the local/internal label convention
from asm and used:

  x = .SQRT (y);

I don't think even C++ has found a meaning for a leading dot yet.

Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf
and x86_64-linux-gnu.  OK to install?

Richard


2018-05-17  Richard Sandiford  <richard.sandiford@linaro.org>

gcc/
	* internal-fn.h (lookup_internal_fn): Declare
	* internal-fn.c (lookup_internal_fn): New function.
	* gimple.c (gimple_build_call_from_tree): Handle calls to
	internal functions.
	* gimple-pretty-print.c (dump_gimple_call): Print "." before
	internal function names.
	* tree-pretty-print.c (dump_generic_node): Likewise.
	* tree-ssa-scopedtables.c (expr_hash_elt::print): Likewise.

gcc/c/
	* gimple-parser.c: Include internal-fn.h.
	(c_parser_gimple_statement): Treat a leading CPP_DOT as a call.
	(c_parser_gimple_call_internal): New function.
	(c_parser_gimple_postfix_expression): Use it to handle CPP_DOT.
	Fix typos in comment.

gcc/testsuite/
	* gcc.dg/gimplefe-28.c: New test.
	* gcc.dg/asan/use-after-scope-9.c: Adjust expected output for
	internal function calls.
	* gcc.dg/goacc/loop-processing-1.c: Likewise.

Comments

Richard Biener May 17, 2018, 10:46 a.m. | #1
On Thu, May 17, 2018 at 10:27 AM Richard Sandiford <
richard.sandiford@linaro.org> wrote:

> This patch gets the gimple FE to parse calls to internal functions.

> The only non-obvious thing was how the functions should be written

> to avoid clashes with real function names.  One option would be to

> go the magic number of underscores route, but we already do that for

> built-in functions, and it would be good to keep them visually

> distinct.  In the end I borrowed the local/internal label convention

> from asm and used:


>    x = .SQRT (y);


> I don't think even C++ has found a meaning for a leading dot yet.


Heh, clever idea!

> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf

> and x86_64-linux-gnu.  OK to install?


OK and thanks for doing this!

Richard.

> Richard



> 2018-05-17  Richard Sandiford  <richard.sandiford@linaro.org>


> gcc/

>          * internal-fn.h (lookup_internal_fn): Declare

>          * internal-fn.c (lookup_internal_fn): New function.

>          * gimple.c (gimple_build_call_from_tree): Handle calls to

>          internal functions.

>          * gimple-pretty-print.c (dump_gimple_call): Print "." before

>          internal function names.

>          * tree-pretty-print.c (dump_generic_node): Likewise.

>          * tree-ssa-scopedtables.c (expr_hash_elt::print): Likewise.


> gcc/c/

>          * gimple-parser.c: Include internal-fn.h.

>          (c_parser_gimple_statement): Treat a leading CPP_DOT as a call.

>          (c_parser_gimple_call_internal): New function.

>          (c_parser_gimple_postfix_expression): Use it to handle CPP_DOT.

>          Fix typos in comment.


> gcc/testsuite/

>          * gcc.dg/gimplefe-28.c: New test.

>          * gcc.dg/asan/use-after-scope-9.c: Adjust expected output for

>          internal function calls.

>          * gcc.dg/goacc/loop-processing-1.c: Likewise.


> Index: gcc/internal-fn.h

> ===================================================================

> --- gcc/internal-fn.h   2018-05-16 12:48:59.194282896 +0100

> +++ gcc/internal-fn.h   2018-05-17 09:17:58.757608747 +0100

> @@ -107,6 +107,8 @@ internal_fn_name (enum internal_fn fn)

>     return internal_fn_name_array[(int) fn];

>   }


> +extern internal_fn lookup_internal_fn (const char *);

> +

>   /* Return the ECF_* flags for function FN.  */


>   extern const int internal_fn_flags_array[];

> Index: gcc/internal-fn.c

> ===================================================================

> --- gcc/internal-fn.c   2018-05-16 12:48:59.410941892 +0100

> +++ gcc/internal-fn.c   2018-05-17 09:22:49.808912358 +0100

> @@ -64,6 +64,26 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS

>     0

>   };


> +/* Return the internal function called NAME, or IFN_LAST if there's

> +   no such function.  */

> +

> +internal_fn

> +lookup_internal_fn (const char *name)

> +{

> +  typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type;

> +  static name_to_fn_map_type *name_to_fn_map;

> +

> +  if (!name_to_fn_map)

> +    {

> +      name_to_fn_map = new name_to_fn_map_type (IFN_LAST);

> +      for (unsigned int i = 0; i < IFN_LAST; ++i)

> +       name_to_fn_map->put (internal_fn_name (internal_fn (i)),

> +                            internal_fn (i));

> +    }

> +  internal_fn *entry = name_to_fn_map->get (name);

> +  return entry ? *entry : IFN_LAST;

> +}

> +

>   /* Fnspec of each internal function, indexed by function number.  */

>   const_tree internal_fn_fnspec_array[IFN_LAST + 1];


> Index: gcc/gimple.c

> ===================================================================

> --- gcc/gimple.c        2018-05-16 12:48:59.410941892 +0100

> +++ gcc/gimple.c        2018-05-17 09:22:49.808912358 +0100

> @@ -350,12 +350,19 @@ gimple_build_call_from_tree (tree t, tre

>   {

>     unsigned i, nargs;

>     gcall *call;

> -  tree fndecl = get_callee_fndecl (t);


>     gcc_assert (TREE_CODE (t) == CALL_EXPR);


>     nargs = call_expr_nargs (t);

> -  call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);

> +

> +  tree fndecl = NULL_TREE;

> +  if (CALL_EXPR_FN (t) == NULL_TREE)

> +    call = gimple_build_call_internal_1 (CALL_EXPR_IFN (t), nargs);

> +  else

> +    {

> +      fndecl = get_callee_fndecl (t);

> +      call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t),

nargs);
> +    }


>     for (i = 0; i < nargs; i++)

>       gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i));

> Index: gcc/gimple-pretty-print.c

> ===================================================================

> --- gcc/gimple-pretty-print.c   2018-05-16 12:48:59.410941892 +0100

> +++ gcc/gimple-pretty-print.c   2018-05-17 09:22:49.808912358 +0100

> @@ -874,7 +874,7 @@ dump_gimple_call (pretty_printer *buffer

>     if (flags & TDF_RAW)

>       {

>         if (gimple_call_internal_p (gs))

> -       dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs,

> +       dump_gimple_fmt (buffer, spc, flags, "%G <.%s, %T", gs,

>                           internal_fn_name (gimple_call_internal_fn (gs)),

lhs);
>         else

>          dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T", gs, fn, lhs);

> @@ -898,7 +898,10 @@ dump_gimple_call (pretty_printer *buffer

>            pp_space (buffer);

>           }

>         if (gimple_call_internal_p (gs))

> -       pp_string (buffer, internal_fn_name (gimple_call_internal_fn

(gs)));
> +       {

> +         pp_dot (buffer);

> +         pp_string (buffer, internal_fn_name (gimple_call_internal_fn

(gs)));
> +       }

>         else

>          print_call_name (buffer, fn, flags);

>         pp_string (buffer, " (");

> Index: gcc/tree-pretty-print.c

> ===================================================================

> --- gcc/tree-pretty-print.c     2018-05-16 12:48:59.410941892 +0100

> +++ gcc/tree-pretty-print.c     2018-05-17 09:22:49.808912358 +0100

> @@ -2262,7 +2262,10 @@ dump_generic_node (pretty_printer *pp, t

>         if (CALL_EXPR_FN (node) != NULL_TREE)

>          print_call_name (pp, CALL_EXPR_FN (node), flags);

>         else

> -       pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));

> +       {

> +         pp_dot (pp);

> +         pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));

> +       }


>         /* Print parameters.  */

>         pp_space (pp);

> Index: gcc/tree-ssa-scopedtables.c

> ===================================================================

> --- gcc/tree-ssa-scopedtables.c 2018-02-08 13:34:20.649280969 +0000

> +++ gcc/tree-ssa-scopedtables.c 2018-05-17 09:17:58.758608713 +0100

> @@ -906,8 +906,8 @@ expr_hash_elt::print (FILE *stream)


>             fn_from = m_expr.ops.call.fn_from;

>             if (gimple_call_internal_p (fn_from))

> -            fputs (internal_fn_name (gimple_call_internal_fn (fn_from)),

> -                   stream);

> +           fprintf (stream, ".%s",

> +                    internal_fn_name (gimple_call_internal_fn

(fn_from)));
>             else

>              print_generic_expr (stream, gimple_call_fn (fn_from));

>             fprintf (stream, " (");

> Index: gcc/c/gimple-parser.c

> ===================================================================

> --- gcc/c/gimple-parser.c       2018-05-16 12:48:59.410941892 +0100

> +++ gcc/c/gimple-parser.c       2018-05-17 09:22:49.808912358 +0100

> @@ -53,6 +53,7 @@ Software Foundation; either version 3, o

>   #include "tree-ssanames.h"

>   #include "gimple-ssa.h"

>   #include "tree-dfa.h"

> +#include "internal-fn.h"



>   /* Gimple parsing functions.  */

> @@ -400,9 +401,10 @@ c_parser_gimple_statement (c_parser *par

>       }


>     /* GIMPLE call with lhs.  */

> -  if (c_parser_next_token_is (parser, CPP_NAME)

> -      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN

> -      && lookup_name (c_parser_peek_token (parser)->value))

> +  if (c_parser_next_token_is (parser, CPP_DOT)

> +      || (c_parser_next_token_is (parser, CPP_NAME)

> +         && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN

> +         && lookup_name (c_parser_peek_token (parser)->value)))

>       {

>         rhs = c_parser_gimple_unary_expression (parser);

>         if (rhs.value != error_mark_node)

> @@ -726,14 +728,57 @@ c_parser_parse_ssa_name (c_parser *parse

>     return name;

>   }


> +/* Parse a gimple call to an internal function.

> +

> +   gimple-call-internal:

> +     . identifier ( gimple-argument-expression-list[opt] )  */

> +

> +static struct c_expr

> +c_parser_gimple_call_internal (c_parser *parser)

> +{

> +  struct c_expr expr;

> +  expr.set_error ();

> +

> +  gcc_assert (c_parser_next_token_is (parser, CPP_DOT));

> +  c_parser_consume_token (parser);

> +  location_t loc = c_parser_peek_token (parser)->location;

> +  if (!c_parser_next_token_is (parser, CPP_NAME)

> +      || c_parser_peek_token (parser)->id_kind != C_ID_ID)

> +    {

> +      c_parser_error (parser, "expecting internal function name");

> +      return expr;

> +    }

> +  tree id = c_parser_peek_token (parser)->value;

> +  internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id));

> +  c_parser_consume_token (parser);

> +  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))

> +    {

> +      auto_vec<tree> exprlist;

> +      if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))

> +       c_parser_gimple_expr_list (parser, &exprlist);

> +      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected

%<)%>");
> +      if (ifn == IFN_LAST)

> +       error_at (loc, "unknown internal function %qE", id);

> +      else

> +       {

> +         expr.value = build_call_expr_internal_loc_array

> +           (loc, ifn, void_type_node, exprlist.length (),

> +            exprlist.address ());

> +         expr.original_code = ERROR_MARK;

> +         expr.original_type = NULL;

> +       }

> +    }

> +  return expr;

> +}

> +

>   /* Parse gimple postfix expression.


>      gimple-postfix-expression:

>        gimple-primary-expression

> -     gimple-primary-xpression [ gimple-primary-expression ]

> +     gimple-primary-expression [ gimple-primary-expression ]

>        gimple-primary-expression ( gimple-argument-expression-list[opt] )

> -     postfix-expression . identifier

> -     postfix-expression -> identifier

> +     gimple-postfix-expression . identifier

> +     gimple-postfix-expression -> identifier


>      gimple-argument-expression-list:

>        gimple-unary-expression

> @@ -743,6 +788,7 @@ c_parser_parse_ssa_name (c_parser *parse

>        identifier

>        constant

>        string-literal

> +     gimple-call-internal


>   */


> @@ -779,6 +825,9 @@ c_parser_gimple_postfix_expression (c_pa

>         expr.original_code = STRING_CST;

>         c_parser_consume_token (parser);

>         break;

> +    case CPP_DOT:

> +      expr = c_parser_gimple_call_internal (parser);

> +      break;

>       case CPP_NAME:

>         if (c_parser_peek_token (parser)->id_kind == C_ID_ID)

>          {

> Index: gcc/testsuite/gcc.dg/gimplefe-28.c

> ===================================================================

> --- /dev/null   2018-04-20 16:19:46.369131350 +0100

> +++ gcc/testsuite/gcc.dg/gimplefe-28.c  2018-05-17 09:17:58.757608747

+0100
> @@ -0,0 +1,16 @@

> +/* { dg-do compile { target sqrt_insn } } */

> +/* { dg-options "-fgimple -O2" } */

> +

> +double __GIMPLE

> +f1 (double x)

> +{

> +  double res;

> +  res = .SQRT (x);

> +  return res;

> +}

> +

> +void __GIMPLE

> +f2 (double x)

> +{

> +  .SQRT (x); // Dead code

> +}

> Index: gcc/testsuite/gcc.dg/asan/use-after-scope-9.c

> ===================================================================

> --- gcc/testsuite/gcc.dg/asan/use-after-scope-9.c       2017-02-23

19:54:08.000000000 +0000
> +++ gcc/testsuite/gcc.dg/asan/use-after-scope-9.c       2018-05-17

09:17:58.757608747 +0100
> @@ -17,7 +17,7 @@ main (int argc, char **argv)

>     return *ptr;

>   }


> -// { dg-final { scan-tree-dump-times "= ASAN_POISON \\(\\)" 1 "asan1" } }

> +// { dg-final { scan-tree-dump-times {= \.ASAN_POISON \(\)} 1 "asan1" } }

>   // { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on

address.*(\n|\r\n|\r)" }
>   // { dg-output "READ of size .*" }

>   // { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside

this variable.*" }
> Index: gcc/testsuite/gcc.dg/goacc/loop-processing-1.c

> ===================================================================

> --- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c      2017-02-23

19:54:08.000000000 +0000
> +++ gcc/testsuite/gcc.dg/goacc/loop-processing-1.c      2018-05-17

09:17:58.757608747 +0100
> @@ -15,4 +15,4 @@ void vector_1 (int *ary, int size)

>     }

>   }


> -/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop

24\(1\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1,
36\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1,
36\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+,
0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK,
\.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN,
\.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = UNIQUE
\(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE
\(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK,
\.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = UNIQUE
\(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE
\(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ =
UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ =
UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+
= UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ =
UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */
> +/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop

24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1,
36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1,
36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+,
0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK,
\.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN,
\.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE
\(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE
\(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK,
\.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE
\(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE
\(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ =
\.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ =
\.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+,
2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK,
\.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN,
\.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */
Christophe Lyon May 21, 2018, 3:22 p.m. | #2
On 17 May 2018 at 10:25, Richard Sandiford <richard.sandiford@linaro.org> wrote:
> This patch gets the gimple FE to parse calls to internal functions.

> The only non-obvious thing was how the functions should be written

> to avoid clashes with real function names.  One option would be to

> go the magic number of underscores route, but we already do that for

> built-in functions, and it would be good to keep them visually

> distinct.  In the end I borrowed the local/internal label convention

> from asm and used:

>

>   x = .SQRT (y);

>

> I don't think even C++ has found a meaning for a leading dot yet.

>

> Tested on aarch64-linux-gnu (with and without SVE), aarch64_be-elf

> and x86_64-linux-gnu.  OK to install?

>

> Richard

>

>

> 2018-05-17  Richard Sandiford  <richard.sandiford@linaro.org>

>

> gcc/

>         * internal-fn.h (lookup_internal_fn): Declare

>         * internal-fn.c (lookup_internal_fn): New function.

>         * gimple.c (gimple_build_call_from_tree): Handle calls to

>         internal functions.

>         * gimple-pretty-print.c (dump_gimple_call): Print "." before

>         internal function names.

>         * tree-pretty-print.c (dump_generic_node): Likewise.

>         * tree-ssa-scopedtables.c (expr_hash_elt::print): Likewise.

>

> gcc/c/

>         * gimple-parser.c: Include internal-fn.h.

>         (c_parser_gimple_statement): Treat a leading CPP_DOT as a call.

>         (c_parser_gimple_call_internal): New function.

>         (c_parser_gimple_postfix_expression): Use it to handle CPP_DOT.

>         Fix typos in comment.

>

> gcc/testsuite/

>         * gcc.dg/gimplefe-28.c: New test.


Hi Richard,

I've noticed that this new test fails on arm-none-linux-gnueabi and
arm-none-eabi:
during RTL pass: expand
/gcc/testsuite/gcc.dg/gimplefe-28.c: In function 'f1':
/gcc/testsuite/gcc.dg/gimplefe-28.c:5:1: internal compiler error: in
maybe_gen_insn, at optabs.c:7240
0xa9157a maybe_gen_insn(insn_code, unsigned int, expand_operand*)
        /gcc/optabs.c:7240
0xa91658 maybe_expand_insn(insn_code, unsigned int, expand_operand*)
        /gcc/optabs.c:7284
0xa91688 expand_insn(insn_code, unsigned int, expand_operand*)
        /gcc/optabs.c:7315
0x94242d expand_direct_optab_fn
        /gcc/internal-fn.c:2918
0x6c5d14 expand_call_stmt
        /gcc/cfgexpand.c:2598
0x6c6fd4 expand_gimple_stmt_1
        /gcc/cfgexpand.c:3644
0x6c6fd4 expand_gimple_stmt
        /gcc/cfgexpand.c:3810
0x6c7ab4 expand_gimple_tailcall
        /gcc/cfgexpand.c:3856
0x6c9183 expand_gimple_basic_block
        /gcc/cfgexpand.c:5816
0x6cbf26 execute
        /gcc/cfgexpand.c:6445

It passes on arm-none-linux-gnueabihf and armeb-none-linux-gnueabihf.

Christophe


>         * gcc.dg/asan/use-after-scope-9.c: Adjust expected output for

>         internal function calls.

>         * gcc.dg/goacc/loop-processing-1.c: Likewise.

>

> Index: gcc/internal-fn.h

> ===================================================================

> --- gcc/internal-fn.h   2018-05-16 12:48:59.194282896 +0100

> +++ gcc/internal-fn.h   2018-05-17 09:17:58.757608747 +0100

> @@ -107,6 +107,8 @@ internal_fn_name (enum internal_fn fn)

>    return internal_fn_name_array[(int) fn];

>  }

>

> +extern internal_fn lookup_internal_fn (const char *);

> +

>  /* Return the ECF_* flags for function FN.  */

>

>  extern const int internal_fn_flags_array[];

> Index: gcc/internal-fn.c

> ===================================================================

> --- gcc/internal-fn.c   2018-05-16 12:48:59.410941892 +0100

> +++ gcc/internal-fn.c   2018-05-17 09:22:49.808912358 +0100

> @@ -64,6 +64,26 @@ #define DEF_INTERNAL_FN(CODE, FLAGS, FNS

>    0

>  };

>

> +/* Return the internal function called NAME, or IFN_LAST if there's

> +   no such function.  */

> +

> +internal_fn

> +lookup_internal_fn (const char *name)

> +{

> +  typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type;

> +  static name_to_fn_map_type *name_to_fn_map;

> +

> +  if (!name_to_fn_map)

> +    {

> +      name_to_fn_map = new name_to_fn_map_type (IFN_LAST);

> +      for (unsigned int i = 0; i < IFN_LAST; ++i)

> +       name_to_fn_map->put (internal_fn_name (internal_fn (i)),

> +                            internal_fn (i));

> +    }

> +  internal_fn *entry = name_to_fn_map->get (name);

> +  return entry ? *entry : IFN_LAST;

> +}

> +

>  /* Fnspec of each internal function, indexed by function number.  */

>  const_tree internal_fn_fnspec_array[IFN_LAST + 1];

>

> Index: gcc/gimple.c

> ===================================================================

> --- gcc/gimple.c        2018-05-16 12:48:59.410941892 +0100

> +++ gcc/gimple.c        2018-05-17 09:22:49.808912358 +0100

> @@ -350,12 +350,19 @@ gimple_build_call_from_tree (tree t, tre

>  {

>    unsigned i, nargs;

>    gcall *call;

> -  tree fndecl = get_callee_fndecl (t);

>

>    gcc_assert (TREE_CODE (t) == CALL_EXPR);

>

>    nargs = call_expr_nargs (t);

> -  call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);

> +

> +  tree fndecl = NULL_TREE;

> +  if (CALL_EXPR_FN (t) == NULL_TREE)

> +    call = gimple_build_call_internal_1 (CALL_EXPR_IFN (t), nargs);

> +  else

> +    {

> +      fndecl = get_callee_fndecl (t);

> +      call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);

> +    }

>

>    for (i = 0; i < nargs; i++)

>      gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i));

> Index: gcc/gimple-pretty-print.c

> ===================================================================

> --- gcc/gimple-pretty-print.c   2018-05-16 12:48:59.410941892 +0100

> +++ gcc/gimple-pretty-print.c   2018-05-17 09:22:49.808912358 +0100

> @@ -874,7 +874,7 @@ dump_gimple_call (pretty_printer *buffer

>    if (flags & TDF_RAW)

>      {

>        if (gimple_call_internal_p (gs))

> -       dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs,

> +       dump_gimple_fmt (buffer, spc, flags, "%G <.%s, %T", gs,

>                          internal_fn_name (gimple_call_internal_fn (gs)), lhs);

>        else

>         dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T", gs, fn, lhs);

> @@ -898,7 +898,10 @@ dump_gimple_call (pretty_printer *buffer

>           pp_space (buffer);

>          }

>        if (gimple_call_internal_p (gs))

> -       pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs)));

> +       {

> +         pp_dot (buffer);

> +         pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs)));

> +       }

>        else

>         print_call_name (buffer, fn, flags);

>        pp_string (buffer, " (");

> Index: gcc/tree-pretty-print.c

> ===================================================================

> --- gcc/tree-pretty-print.c     2018-05-16 12:48:59.410941892 +0100

> +++ gcc/tree-pretty-print.c     2018-05-17 09:22:49.808912358 +0100

> @@ -2262,7 +2262,10 @@ dump_generic_node (pretty_printer *pp, t

>        if (CALL_EXPR_FN (node) != NULL_TREE)

>         print_call_name (pp, CALL_EXPR_FN (node), flags);

>        else

> -       pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));

> +       {

> +         pp_dot (pp);

> +         pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));

> +       }

>

>        /* Print parameters.  */

>        pp_space (pp);

> Index: gcc/tree-ssa-scopedtables.c

> ===================================================================

> --- gcc/tree-ssa-scopedtables.c 2018-02-08 13:34:20.649280969 +0000

> +++ gcc/tree-ssa-scopedtables.c 2018-05-17 09:17:58.758608713 +0100

> @@ -906,8 +906,8 @@ expr_hash_elt::print (FILE *stream)

>

>            fn_from = m_expr.ops.call.fn_from;

>            if (gimple_call_internal_p (fn_from))

> -            fputs (internal_fn_name (gimple_call_internal_fn (fn_from)),

> -                   stream);

> +           fprintf (stream, ".%s",

> +                    internal_fn_name (gimple_call_internal_fn (fn_from)));

>            else

>             print_generic_expr (stream, gimple_call_fn (fn_from));

>            fprintf (stream, " (");

> Index: gcc/c/gimple-parser.c

> ===================================================================

> --- gcc/c/gimple-parser.c       2018-05-16 12:48:59.410941892 +0100

> +++ gcc/c/gimple-parser.c       2018-05-17 09:22:49.808912358 +0100

> @@ -53,6 +53,7 @@ Software Foundation; either version 3, o

>  #include "tree-ssanames.h"

>  #include "gimple-ssa.h"

>  #include "tree-dfa.h"

> +#include "internal-fn.h"

>

>

>  /* Gimple parsing functions.  */

> @@ -400,9 +401,10 @@ c_parser_gimple_statement (c_parser *par

>      }

>

>    /* GIMPLE call with lhs.  */

> -  if (c_parser_next_token_is (parser, CPP_NAME)

> -      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN

> -      && lookup_name (c_parser_peek_token (parser)->value))

> +  if (c_parser_next_token_is (parser, CPP_DOT)

> +      || (c_parser_next_token_is (parser, CPP_NAME)

> +         && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN

> +         && lookup_name (c_parser_peek_token (parser)->value)))

>      {

>        rhs = c_parser_gimple_unary_expression (parser);

>        if (rhs.value != error_mark_node)

> @@ -726,14 +728,57 @@ c_parser_parse_ssa_name (c_parser *parse

>    return name;

>  }

>

> +/* Parse a gimple call to an internal function.

> +

> +   gimple-call-internal:

> +     . identifier ( gimple-argument-expression-list[opt] )  */

> +

> +static struct c_expr

> +c_parser_gimple_call_internal (c_parser *parser)

> +{

> +  struct c_expr expr;

> +  expr.set_error ();

> +

> +  gcc_assert (c_parser_next_token_is (parser, CPP_DOT));

> +  c_parser_consume_token (parser);

> +  location_t loc = c_parser_peek_token (parser)->location;

> +  if (!c_parser_next_token_is (parser, CPP_NAME)

> +      || c_parser_peek_token (parser)->id_kind != C_ID_ID)

> +    {

> +      c_parser_error (parser, "expecting internal function name");

> +      return expr;

> +    }

> +  tree id = c_parser_peek_token (parser)->value;

> +  internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id));

> +  c_parser_consume_token (parser);

> +  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))

> +    {

> +      auto_vec<tree> exprlist;

> +      if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))

> +       c_parser_gimple_expr_list (parser, &exprlist);

> +      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");

> +      if (ifn == IFN_LAST)

> +       error_at (loc, "unknown internal function %qE", id);

> +      else

> +       {

> +         expr.value = build_call_expr_internal_loc_array

> +           (loc, ifn, void_type_node, exprlist.length (),

> +            exprlist.address ());

> +         expr.original_code = ERROR_MARK;

> +         expr.original_type = NULL;

> +       }

> +    }

> +  return expr;

> +}

> +

>  /* Parse gimple postfix expression.

>

>     gimple-postfix-expression:

>       gimple-primary-expression

> -     gimple-primary-xpression [ gimple-primary-expression ]

> +     gimple-primary-expression [ gimple-primary-expression ]

>       gimple-primary-expression ( gimple-argument-expression-list[opt] )

> -     postfix-expression . identifier

> -     postfix-expression -> identifier

> +     gimple-postfix-expression . identifier

> +     gimple-postfix-expression -> identifier

>

>     gimple-argument-expression-list:

>       gimple-unary-expression

> @@ -743,6 +788,7 @@ c_parser_parse_ssa_name (c_parser *parse

>       identifier

>       constant

>       string-literal

> +     gimple-call-internal

>

>  */

>

> @@ -779,6 +825,9 @@ c_parser_gimple_postfix_expression (c_pa

>        expr.original_code = STRING_CST;

>        c_parser_consume_token (parser);

>        break;

> +    case CPP_DOT:

> +      expr = c_parser_gimple_call_internal (parser);

> +      break;

>      case CPP_NAME:

>        if (c_parser_peek_token (parser)->id_kind == C_ID_ID)

>         {

> Index: gcc/testsuite/gcc.dg/gimplefe-28.c

> ===================================================================

> --- /dev/null   2018-04-20 16:19:46.369131350 +0100

> +++ gcc/testsuite/gcc.dg/gimplefe-28.c  2018-05-17 09:17:58.757608747 +0100

> @@ -0,0 +1,16 @@

> +/* { dg-do compile { target sqrt_insn } } */

> +/* { dg-options "-fgimple -O2" } */

> +

> +double __GIMPLE

> +f1 (double x)

> +{

> +  double res;

> +  res = .SQRT (x);

> +  return res;

> +}

> +

> +void __GIMPLE

> +f2 (double x)

> +{

> +  .SQRT (x); // Dead code

> +}

> Index: gcc/testsuite/gcc.dg/asan/use-after-scope-9.c

> ===================================================================

> --- gcc/testsuite/gcc.dg/asan/use-after-scope-9.c       2017-02-23 19:54:08.000000000 +0000

> +++ gcc/testsuite/gcc.dg/asan/use-after-scope-9.c       2018-05-17 09:17:58.757608747 +0100

> @@ -17,7 +17,7 @@ main (int argc, char **argv)

>    return *ptr;

>  }

>

> -// { dg-final { scan-tree-dump-times "= ASAN_POISON \\(\\)" 1 "asan1" } }

> +// { dg-final { scan-tree-dump-times {= \.ASAN_POISON \(\)} 1 "asan1" } }

>  // { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }

>  // { dg-output "READ of size .*" }

>  // { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside this variable.*" }

> Index: gcc/testsuite/gcc.dg/goacc/loop-processing-1.c

> ===================================================================

> --- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c      2017-02-23 19:54:08.000000000 +0000

> +++ gcc/testsuite/gcc.dg/goacc/loop-processing-1.c      2018-05-17 09:17:58.757608747 +0100

> @@ -15,4 +15,4 @@ void vector_1 (int *ary, int size)

>    }

>  }

>

> -/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */

> +/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */

Patch

Index: gcc/internal-fn.h
===================================================================
--- gcc/internal-fn.h	2018-05-16 12:48:59.194282896 +0100
+++ gcc/internal-fn.h	2018-05-17 09:17:58.757608747 +0100
@@ -107,6 +107,8 @@  internal_fn_name (enum internal_fn fn)
   return internal_fn_name_array[(int) fn];
 }
 
+extern internal_fn lookup_internal_fn (const char *);
+
 /* Return the ECF_* flags for function FN.  */
 
 extern const int internal_fn_flags_array[];
Index: gcc/internal-fn.c
===================================================================
--- gcc/internal-fn.c	2018-05-16 12:48:59.410941892 +0100
+++ gcc/internal-fn.c	2018-05-17 09:22:49.808912358 +0100
@@ -64,6 +64,26 @@  #define DEF_INTERNAL_FN(CODE, FLAGS, FNS
   0
 };
 
+/* Return the internal function called NAME, or IFN_LAST if there's
+   no such function.  */
+
+internal_fn
+lookup_internal_fn (const char *name)
+{
+  typedef hash_map<nofree_string_hash, internal_fn> name_to_fn_map_type;
+  static name_to_fn_map_type *name_to_fn_map;
+
+  if (!name_to_fn_map)
+    {
+      name_to_fn_map = new name_to_fn_map_type (IFN_LAST);
+      for (unsigned int i = 0; i < IFN_LAST; ++i)
+	name_to_fn_map->put (internal_fn_name (internal_fn (i)),
+			     internal_fn (i));
+    }
+  internal_fn *entry = name_to_fn_map->get (name);
+  return entry ? *entry : IFN_LAST;
+}
+
 /* Fnspec of each internal function, indexed by function number.  */
 const_tree internal_fn_fnspec_array[IFN_LAST + 1];
 
Index: gcc/gimple.c
===================================================================
--- gcc/gimple.c	2018-05-16 12:48:59.410941892 +0100
+++ gcc/gimple.c	2018-05-17 09:22:49.808912358 +0100
@@ -350,12 +350,19 @@  gimple_build_call_from_tree (tree t, tre
 {
   unsigned i, nargs;
   gcall *call;
-  tree fndecl = get_callee_fndecl (t);
 
   gcc_assert (TREE_CODE (t) == CALL_EXPR);
 
   nargs = call_expr_nargs (t);
-  call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);
+
+  tree fndecl = NULL_TREE;
+  if (CALL_EXPR_FN (t) == NULL_TREE)
+    call = gimple_build_call_internal_1 (CALL_EXPR_IFN (t), nargs);
+  else
+    {
+      fndecl = get_callee_fndecl (t);
+      call = gimple_build_call_1 (fndecl ? fndecl : CALL_EXPR_FN (t), nargs);
+    }
 
   for (i = 0; i < nargs; i++)
     gimple_call_set_arg (call, i, CALL_EXPR_ARG (t, i));
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	2018-05-16 12:48:59.410941892 +0100
+++ gcc/gimple-pretty-print.c	2018-05-17 09:22:49.808912358 +0100
@@ -874,7 +874,7 @@  dump_gimple_call (pretty_printer *buffer
   if (flags & TDF_RAW)
     {
       if (gimple_call_internal_p (gs))
-	dump_gimple_fmt (buffer, spc, flags, "%G <%s, %T", gs,
+	dump_gimple_fmt (buffer, spc, flags, "%G <.%s, %T", gs,
 			 internal_fn_name (gimple_call_internal_fn (gs)), lhs);
       else
 	dump_gimple_fmt (buffer, spc, flags, "%G <%T, %T", gs, fn, lhs);
@@ -898,7 +898,10 @@  dump_gimple_call (pretty_printer *buffer
 	  pp_space (buffer);
         }
       if (gimple_call_internal_p (gs))
-	pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs)));
+	{
+	  pp_dot (buffer);
+	  pp_string (buffer, internal_fn_name (gimple_call_internal_fn (gs)));
+	}
       else
 	print_call_name (buffer, fn, flags);
       pp_string (buffer, " (");
Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	2018-05-16 12:48:59.410941892 +0100
+++ gcc/tree-pretty-print.c	2018-05-17 09:22:49.808912358 +0100
@@ -2262,7 +2262,10 @@  dump_generic_node (pretty_printer *pp, t
       if (CALL_EXPR_FN (node) != NULL_TREE)
 	print_call_name (pp, CALL_EXPR_FN (node), flags);
       else
-	pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));
+	{
+	  pp_dot (pp);
+	  pp_string (pp, internal_fn_name (CALL_EXPR_IFN (node)));
+	}
 
       /* Print parameters.  */
       pp_space (pp);
Index: gcc/tree-ssa-scopedtables.c
===================================================================
--- gcc/tree-ssa-scopedtables.c	2018-02-08 13:34:20.649280969 +0000
+++ gcc/tree-ssa-scopedtables.c	2018-05-17 09:17:58.758608713 +0100
@@ -906,8 +906,8 @@  expr_hash_elt::print (FILE *stream)
 
           fn_from = m_expr.ops.call.fn_from;
           if (gimple_call_internal_p (fn_from))
-            fputs (internal_fn_name (gimple_call_internal_fn (fn_from)),
-                   stream);
+	    fprintf (stream, ".%s",
+		     internal_fn_name (gimple_call_internal_fn (fn_from)));
           else
 	    print_generic_expr (stream, gimple_call_fn (fn_from));
           fprintf (stream, " (");
Index: gcc/c/gimple-parser.c
===================================================================
--- gcc/c/gimple-parser.c	2018-05-16 12:48:59.410941892 +0100
+++ gcc/c/gimple-parser.c	2018-05-17 09:22:49.808912358 +0100
@@ -53,6 +53,7 @@  Software Foundation; either version 3, o
 #include "tree-ssanames.h"
 #include "gimple-ssa.h"
 #include "tree-dfa.h"
+#include "internal-fn.h"
 
 
 /* Gimple parsing functions.  */
@@ -400,9 +401,10 @@  c_parser_gimple_statement (c_parser *par
     }
 
   /* GIMPLE call with lhs.  */
-  if (c_parser_next_token_is (parser, CPP_NAME)
-      && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
-      && lookup_name (c_parser_peek_token (parser)->value))
+  if (c_parser_next_token_is (parser, CPP_DOT)
+      || (c_parser_next_token_is (parser, CPP_NAME)
+	  && c_parser_peek_2nd_token (parser)->type == CPP_OPEN_PAREN
+	  && lookup_name (c_parser_peek_token (parser)->value)))
     {
       rhs = c_parser_gimple_unary_expression (parser);
       if (rhs.value != error_mark_node)
@@ -726,14 +728,57 @@  c_parser_parse_ssa_name (c_parser *parse
   return name;
 }
 
+/* Parse a gimple call to an internal function.
+
+   gimple-call-internal:
+     . identifier ( gimple-argument-expression-list[opt] )  */
+
+static struct c_expr
+c_parser_gimple_call_internal (c_parser *parser)
+{
+  struct c_expr expr;
+  expr.set_error ();
+
+  gcc_assert (c_parser_next_token_is (parser, CPP_DOT));
+  c_parser_consume_token (parser);
+  location_t loc = c_parser_peek_token (parser)->location;
+  if (!c_parser_next_token_is (parser, CPP_NAME)
+      || c_parser_peek_token (parser)->id_kind != C_ID_ID)
+    {
+      c_parser_error (parser, "expecting internal function name");
+      return expr;
+    }
+  tree id = c_parser_peek_token (parser)->value;
+  internal_fn ifn = lookup_internal_fn (IDENTIFIER_POINTER (id));
+  c_parser_consume_token (parser);
+  if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+    {
+      auto_vec<tree> exprlist;
+      if (!c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
+	c_parser_gimple_expr_list (parser, &exprlist);
+      c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+      if (ifn == IFN_LAST)
+	error_at (loc, "unknown internal function %qE", id);
+      else
+	{
+	  expr.value = build_call_expr_internal_loc_array
+	    (loc, ifn, void_type_node, exprlist.length (),
+	     exprlist.address ());
+	  expr.original_code = ERROR_MARK;
+	  expr.original_type = NULL;
+	}
+    }
+  return expr;
+}
+
 /* Parse gimple postfix expression.
 
    gimple-postfix-expression:
      gimple-primary-expression
-     gimple-primary-xpression [ gimple-primary-expression ]
+     gimple-primary-expression [ gimple-primary-expression ]
      gimple-primary-expression ( gimple-argument-expression-list[opt] )
-     postfix-expression . identifier
-     postfix-expression -> identifier
+     gimple-postfix-expression . identifier
+     gimple-postfix-expression -> identifier
 
    gimple-argument-expression-list:
      gimple-unary-expression
@@ -743,6 +788,7 @@  c_parser_parse_ssa_name (c_parser *parse
      identifier
      constant
      string-literal
+     gimple-call-internal
 
 */
 
@@ -779,6 +825,9 @@  c_parser_gimple_postfix_expression (c_pa
       expr.original_code = STRING_CST;
       c_parser_consume_token (parser);
       break;
+    case CPP_DOT:
+      expr = c_parser_gimple_call_internal (parser);
+      break;
     case CPP_NAME:
       if (c_parser_peek_token (parser)->id_kind == C_ID_ID)
 	{
Index: gcc/testsuite/gcc.dg/gimplefe-28.c
===================================================================
--- /dev/null	2018-04-20 16:19:46.369131350 +0100
+++ gcc/testsuite/gcc.dg/gimplefe-28.c	2018-05-17 09:17:58.757608747 +0100
@@ -0,0 +1,16 @@ 
+/* { dg-do compile { target sqrt_insn } } */
+/* { dg-options "-fgimple -O2" } */
+
+double __GIMPLE
+f1 (double x)
+{
+  double res;
+  res = .SQRT (x);
+  return res;
+}
+
+void __GIMPLE
+f2 (double x)
+{
+  .SQRT (x); // Dead code
+}
Index: gcc/testsuite/gcc.dg/asan/use-after-scope-9.c
===================================================================
--- gcc/testsuite/gcc.dg/asan/use-after-scope-9.c	2017-02-23 19:54:08.000000000 +0000
+++ gcc/testsuite/gcc.dg/asan/use-after-scope-9.c	2018-05-17 09:17:58.757608747 +0100
@@ -17,7 +17,7 @@  main (int argc, char **argv)
   return *ptr;
 }
 
-// { dg-final { scan-tree-dump-times "= ASAN_POISON \\(\\)" 1 "asan1" } }
+// { dg-final { scan-tree-dump-times {= \.ASAN_POISON \(\)} 1 "asan1" } }
 // { dg-output "ERROR: AddressSanitizer: stack-use-after-scope on address.*(\n|\r\n|\r)" }
 // { dg-output "READ of size .*" }
 // { dg-output ".*'a' <== Memory access at offset \[0-9\]* is inside this variable.*" }
Index: gcc/testsuite/gcc.dg/goacc/loop-processing-1.c
===================================================================
--- gcc/testsuite/gcc.dg/goacc/loop-processing-1.c	2017-02-23 19:54:08.000000000 +0000
+++ gcc/testsuite/gcc.dg/goacc/loop-processing-1.c	2018-05-17 09:17:58.757608747 +0100
@@ -15,4 +15,4 @@  void vector_1 (int *ary, int size)
   }
 }
 
-/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */
+/* { dg-final { scan-tree-dump {OpenACC loops.*Loop 0\(0\).*Loop 24\(1\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 1, 36\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 0\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 0\);.*Loop 6\(6\).*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*Head-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, 0, 2, 6\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 1\);.*Head-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_HEAD_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_FORK, \.data_dep\.[0-9_]+, 2\);.*Tail-1:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 2\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 2\);.*Tail-0:.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_TAIL_MARK, \.data_dep\.[0-9_]+, 1\);.*\.data_dep\.[0-9_]+ = \.UNIQUE \(OACC_JOIN, \.data_dep\.[0-9_]+, 1\);} "oaccdevlow" } } */