tested on x86_64-pc-linux-gnu with no new failures. OK for master?
New builtin to enable explicit use of PAREN_EXPR in C & C++ code.
Signed-off-by: Matthias Kretz <m.kr...@gsi.de>
gcc/testsuite/ChangeLog:
* c-c++-common/builtin-assoc-barrier-1.c: New test.
gcc/cp/ChangeLog:
* cp-objcp-common.c (names_builtin_p): Handle
RID_BUILTIN_ASSOC_BARRIER.
* parser.c (cp_parser_postfix_expression): Handle
RID_BUILTIN_ASSOC_BARRIER.
gcc/c-family/ChangeLog:
* c-common.c (c_common_reswords): Add __builtin_assoc_barrier.
* c-common.h (enum rid): Add RID_BUILTIN_ASSOC_BARRIER.
gcc/c/ChangeLog:
* c-decl.c (names_builtin_p): Handle RID_BUILTIN_ASSOC_BARRIER.
* c-parser.c (c_parser_postfix_expression): Likewise.
gcc/ChangeLog:
* doc/extend.texi: Document __builtin_assoc_barrier.
---
gcc/c-family/c-common.c | 1 +
gcc/c-family/c-common.h | 2 +-
gcc/c/c-decl.c | 1 +
gcc/c/c-parser.c | 20 ++++++++++++++++
gcc/cp/cp-objcp-common.c | 1 +
gcc/cp/parser.c | 14 +++++++++++
gcc/doc/extend.texi | 18 ++++++++++++++
.../c-c++-common/builtin-assoc-barrier-1.c | 24 +++++++++++++++++++
8 files changed, 80 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/c-c++-common/builtin-assoc-barrier-1.c
--
──────────────────────────────────────────────────────────────────────────
Dr. Matthias Kretz https://mattkretz.github.io
GSI Helmholtz Centre for Heavy Ion Research https://gsi.de
std::experimental::simd https://github.com/VcDevel/std-simd
──────────────────────────────────────────────────────────────────────────
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 681fcc972f4..c62a6398a47 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -384,6 +384,7 @@ const struct c_common_resword c_common_reswords[] =
{ "__builtin_convertvector", RID_BUILTIN_CONVERTVECTOR, 0 },
{ "__builtin_has_attribute", RID_BUILTIN_HAS_ATTRIBUTE, 0 },
{ "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY },
+ { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
{ "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 },
{ "__builtin_shufflevector", RID_BUILTIN_SHUFFLEVECTOR, 0 },
{ "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 50ca8fb6ebd..f34dc47c2ba 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -108,7 +108,7 @@ enum rid
RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR,
RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH,
- RID_BUILTIN_HAS_ATTRIBUTE,
+ RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER,
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
/* TS 18661-3 keywords, in the same sequence as the TI_* values. */
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 983d65e930c..dcf4a2d7c32 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -10557,6 +10557,7 @@ names_builtin_p (const char *name)
case RID_BUILTIN_HAS_ATTRIBUTE:
case RID_BUILTIN_SHUFFLE:
case RID_BUILTIN_SHUFFLEVECTOR:
+ case RID_BUILTIN_ASSOC_BARRIER:
case RID_CHOOSE_EXPR:
case RID_OFFSETOF:
case RID_TYPES_COMPATIBLE_P:
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 9a56e0c04c6..fffd81f4e5b 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -8931,6 +8931,7 @@ c_parser_predefined_identifier (c_parser *parser)
assignment-expression ,
assignment-expression, )
__builtin_convertvector ( assignment-expression , type-name )
+ __builtin_assoc_barrier ( assignment-expression )
offsetof-member-designator:
identifier
@@ -10076,6 +10077,25 @@ c_parser_postfix_expression (c_parser *parser)
}
}
break;
+ case RID_BUILTIN_ASSOC_BARRIER:
+ {
+ location_t start_loc = loc;
+ c_parser_consume_token (parser);
+ matching_parens parens;
+ if (!parens.require_open (parser))
+ {
+ expr.set_error ();
+ break;
+ }
+ e1 = c_parser_expr_no_commas (parser, NULL);
+ mark_exp_read (e1.value);
+ location_t end_loc = c_parser_peek_token (parser)->get_finish ();
+ parens.skip_until_found_close (parser);
+ expr.value = build1_loc (loc, PAREN_EXPR, TREE_TYPE (e1.value),
+ e1.value);
+ set_c_expr_source_range (&expr, start_loc, end_loc);
+ }
+ break;
case RID_AT_SELECTOR:
{
gcc_assert (c_dialect_objc ());
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index ee255732d5a..04522a23eda 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -395,6 +395,7 @@ names_builtin_p (const char *name)
case RID_BUILTIN_SHUFFLE:
case RID_BUILTIN_SHUFFLEVECTOR:
case RID_BUILTIN_LAUNDER:
+ case RID_BUILTIN_ASSOC_BARRIER:
case RID_BUILTIN_BIT_CAST:
case RID_OFFSETOF:
case RID_HAS_NOTHROW_ASSIGN:
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 62f3465539b..4ee7899ce66 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -7316,6 +7316,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
case RID_BUILTIN_SHUFFLE:
case RID_BUILTIN_SHUFFLEVECTOR:
case RID_BUILTIN_LAUNDER:
+ case RID_BUILTIN_ASSOC_BARRIER:
{
vec<tree, va_gc> *vec;
@@ -7358,6 +7359,19 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
}
break;
+ case RID_BUILTIN_ASSOC_BARRIER:
+ if (vec->length () == 1)
+ postfix_expression = build1_loc (loc, PAREN_EXPR,
+ TREE_TYPE ((*vec)[0]),
+ (*vec)[0]);
+ else
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_assoc_barrier%>");
+ postfix_expression = error_mark_node;
+ }
+ break;
+
case RID_BUILTIN_SHUFFLE:
if (vec->length () == 2)
postfix_expression
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 96640ba156f..cb08f830940 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13951,6 +13951,24 @@ int g (int c)
@end deftypefn
+@deftypefn {Built-in Function} @var{type} __builtin_assoc_barrier (@var{type} @var{expr})
+This built-in represents a re-association barrier for the floating-point
+expression @var{expr} with operations following the built-in. The expression
+@var{expr} itself can be reordered, and the whole expression @var{expr} can be
+reordered with operations after the barrier. The barrier is only relevant when
+@code{-fassociative-math} is active, since otherwise floating-point is not
+treated as associative.
+
+@smallexample
+float x0 = a + b - b;
+float x1 = __builtin_assoc_barrier(a + b) - b;
+@end smallexample
+
+@noindent
+means that, with @code{-fassociative-math}, @code{x0} can be optimized to
+@code{x0 = a} but @code{x1} cannot.
+@end deftypefn
+
@deftypefn {Built-in Function} {void *} __builtin_assume_aligned (const void *@var{exp}, size_t @var{align}, ...)
This function returns its first argument, and allows the compiler
to assume that the returned pointer is at least @var{align} bytes
diff --git a/gcc/testsuite/c-c++-common/builtin-assoc-barrier-1.c b/gcc/testsuite/c-c++-common/builtin-assoc-barrier-1.c
new file mode 100644
index 00000000000..51efb1ab96c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin-assoc-barrier-1.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+
+float a = 1.f;
+float b = 1.e20f;
+
+__attribute__((optimize("-ffast-math")))
+float
+fast()
+{
+ return __builtin_assoc_barrier (a + b) - b;
+}
+
+float
+normal()
+{
+ return a + b - b;
+}
+
+int main()
+{
+ if (fast() != normal())
+ __builtin_abort();
+ return 0;
+}