Hi Richard,
The attached patch handles fma_expr in gimple-fe.
Does it look OK ?

Thanks,
Prathamesh
diff --git a/gcc/c/gimple-parser.c b/gcc/c/gimple-parser.c
index d959877..fbd4c8c 100644
--- a/gcc/c/gimple-parser.c
+++ b/gcc/c/gimple-parser.c
@@ -856,6 +856,50 @@ c_parser_gimple_postfix_expression (c_parser *parser)
              expr.value = fold_convert (type, val);
              return expr;
            }
+         else if (strcmp (IDENTIFIER_POINTER (id), "__FMA") == 0)
+           {
+             c_parser_consume_token (parser);
+             auto_vec<tree> args;
+
+             if (c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
+               {
+                 c_parser_gimple_expr_list (parser, &args);
+                 c_parser_skip_until_found (parser, CPP_CLOSE_PAREN,
+                                            "expected %<)%>");
+               }
+             if (args.length () != 3)
+               {
+                 error_at (loc, "invalid number of operands to __FMA");
+                 expr.value = error_mark_node;
+                 return expr;
+               }
+
+             tree arg0_type = TREE_TYPE (args[0]);
+             if (!SCALAR_FLOAT_TYPE_P (arg0_type))
+               {
+                 error_at (loc, "operands to __FMA should have"
+                                " floating point type");
+                 expr.value = error_mark_node;
+                 return expr;
+               }
+
+             for (int pass = 1; pass < 3; ++pass)
+               {
+                 tree type = TREE_TYPE (args[pass]);
+                 if (arg0_type != type
+                     || element_precision (arg0_type) != element_precision 
(type))
+                   {
+                     error_at (loc, "operands to __FMA should have same type");
+                     expr.value = error_mark_node;
+                     return expr;
+                   }
+               }
+
+             expr.value = build3_loc (loc, FMA_EXPR, TREE_TYPE (args[0]),
+                                      args[0], args[1], args[2]);
+             return expr;
+           }
+
          /* SSA name.  */
          unsigned version, ver_offset;
          if (! lookup_name (id)
diff --git a/gcc/testsuite/gcc.dg/gimplefe-26.c 
b/gcc/testsuite/gcc.dg/gimplefe-26.c
new file mode 100644
index 0000000..fa5877e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gimplefe-26.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fgimple -fdump-tree-ssa-gimple-raw" } */
+
+#define foo(type, num) \
+type __GIMPLE () foo_##num (type a, type b, type c) \
+{ \
+  type t0; \
+  t0_1 = __FMA (a, b, c); \
+  return t0_1; \
+}
+
+foo(float, 1)
+foo(double, 2)
+foo(long double, 3)
+
+/* { dg-final { scan-tree-dump-times "fma_expr" 3 "ssa" } } */

Reply via email to