@@ -1862,6 +1862,10 @@ init_pragma (void)
cpp_register_deferred_pragma (parse_in, "GCC", "unroll", PRAGMA_UNROLL,
false, false);
+ if (!flag_preprocess_only)
+ cpp_register_deferred_pragma (parse_in, NULL, "unroll",
+ PRAGMA_UNROLL_UNQUALIFIED, false, false);
+
if (!flag_preprocess_only)
cpp_register_deferred_pragma (parse_in, "GCC", "novector", PRAGMA_NOVECTOR,
false, false);
@@ -93,6 +93,7 @@ enum pragma_kind {
PRAGMA_GCC_PCH_PREPROCESS,
PRAGMA_IVDEP,
PRAGMA_UNROLL,
+ PRAGMA_UNROLL_UNQUALIFIED,
PRAGMA_NOVECTOR,
PRAGMA_FIRST_EXTERNAL
@@ -16027,7 +16027,7 @@ c_parse_pragma_novector (c_parser *parser)
return true;
}
-/* Parse a pragma GCC unroll. */
+/* Parse a pragma GCC unroll or a pragma unroll. */
static unsigned short
c_parser_pragma_unroll (c_parser *parser)
@@ -16291,6 +16291,7 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p,
case PRAGMA_NOVECTOR:
case PRAGMA_UNROLL:
+ case PRAGMA_UNROLL_UNQUALIFIED:
case PRAGMA_IVDEP:
{
bool novector = false;
@@ -16305,6 +16306,9 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p,
case PRAGMA_UNROLL:
unroll = c_parser_pragma_unroll (parser);
break;
+ case PRAGMA_UNROLL_UNQUALIFIED:
+ unroll = c_parser_pragma_unroll (parser);
+ break;
case PRAGMA_IVDEP:
ivdep = c_parse_pragma_ivdep (parser);
break;
@@ -16324,6 +16328,9 @@ c_parser_pragma (c_parser *parser, enum pragma_context context, bool *if_p,
case PRAGMA_UNROLL:
unroll = c_parser_pragma_unroll (parser);
break;
+ case PRAGMA_UNROLL_UNQUALIFIED:
+ unroll = c_parser_pragma_unroll (parser);
+ break;
case PRAGMA_NOVECTOR:
novector = c_parse_pragma_novector (parser);
break;
@@ -57771,6 +57771,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
case PRAGMA_IVDEP:
case PRAGMA_UNROLL:
+ case PRAGMA_UNROLL_UNQUALIFIED:
case PRAGMA_NOVECTOR:
{
bool ivdep = false;
@@ -57783,6 +57784,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
case PRAGMA_IVDEP:
pragma_str = "ivdep";
break;
+ case PRAGMA_UNROLL_UNQUALIFIED:
case PRAGMA_UNROLL:
pragma_str = "unroll";
break;
@@ -57814,6 +57816,7 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context, bool *if_p)
ivdep = cp_parser_pragma_ivdep (parser, tok);
break;
}
+ case PRAGMA_UNROLL_UNQUALIFIED:
case PRAGMA_UNROLL:
{
if (tok != pragma_tok)
@@ -10889,6 +10889,12 @@ loop is unrolled or not will be determined by target costing. The resulting
vectorized loop may still be unrolled more in later passes depending on the
target costing.
+@cindex pragma, unroll
+@item #pragma unroll @var{n}
+
+This pragma is an alias for @code{#pragma GCC unroll @var{n}} for
+inter-compiler compatibility.
+
@end table
@node Thread-Local
new file mode 100644
@@ -0,0 +1,46 @@
+/*
+ <#pragma unroll N> basic tests
+ taken from unroll-1.c
+ */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cunrolli-details -fdump-rtl-loop2_unroll-details" } */
+
+extern void bar (int);
+
+int j;
+
+void test (void)
+{
+ #pragma unroll 8
+ for (unsigned long i = 1; i <= 8; ++i)
+ bar(i);
+ /* { dg-final { scan-tree-dump "16:.*: loop with 8 iterations completely unrolled" "cunrolli" } } */
+
+ #pragma unroll 8
+ for (unsigned long i = 1; i <= 7; ++i)
+ bar(i);
+ /* { dg-final { scan-tree-dump "21:.*: loop with 7 iterations completely unrolled" "cunrolli" } } */
+
+ #pragma unroll 8
+ for (unsigned long i = 1; i <= 15; ++i)
+ bar(i);
+ /* { dg-final { scan-rtl-dump "26:.*: optimized: loop unrolled 7 times" "loop2_unroll" } } */
+
+ #pragma unroll 8
+ for (unsigned long i = 1; i <= j; ++i)
+ bar(i);
+ /* { dg-final { scan-rtl-dump "31:.*: optimized: loop unrolled 7 times" "loop2_unroll" } } */
+
+ #pragma unroll 7
+ for (unsigned long i = 1; i <= j; ++i)
+ bar(i);
+ /* { dg-final { scan-rtl-dump "36:.*: optimized: loop unrolled 3 times" "loop2_unroll" } } */
+
+ unsigned long i = 0;
+ #pragma unroll 3
+ do {
+ bar(i);
+ } while (++i < 9);
+ /* { dg-final { scan-rtl-dump "4\[24\]:.*: optimized: loop unrolled 2 times" "loop2_unroll" } } */
+}
new file mode 100644
@@ -0,0 +1,31 @@
+/*
+ <#pragma unroll N> no-unrolling tests
+ taken from unroll-4.c
+ */
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -funroll-all-loops -fdump-rtl-loop2_unroll-details -fdump-tree-cunrolli-details" } */
+
+extern void bar (int);
+
+int j;
+
+void test (void)
+{
+ #pragma unroll 0
+ #pragma GCC ivdep
+ for (unsigned long i = 1; i <= 3; ++i)
+ bar(i);
+
+ #pragma GCC ivdep
+ #pragma unroll 0
+ for (unsigned long i = 1; i <= j; ++i)
+ bar(i);
+
+ #pragma unroll 1
+ for (unsigned long i = 1; i <= j; ++i)
+ bar(i);
+
+ /* { dg-final { scan-tree-dump "Not unrolling loop .: user didn't want it unrolled completely" "cunrolli" } } */
+ /* { dg-final { scan-rtl-dump-times "Not unrolling loop, user didn't want it unrolled" 3 "loop2_unroll" } } */
+}
new file mode 100644
@@ -0,0 +1,35 @@
+/*
+ <#pragma unroll N> syntax tests
+ taken from unroll-5.c
+ */
+
+/* { dg-do compile } */
+
+extern void bar (int);
+
+int j;
+
+void test (void)
+{
+ #pragma unroll 4+4
+ for (unsigned long i = 1; i <= 8; ++i)
+ bar(i);
+
+ #pragma unroll -1 /* { dg-error "requires an assignment-expression that evaluates to a non-negative integral constant less than" } */
+ for (unsigned long i = 1; i <= 8; ++i)
+ bar(i);
+
+ #pragma unroll 20000000000 /* { dg-error "requires an assignment-expression that evaluates to a non-negative integral constant less than" } */
+ for (unsigned long i = 1; i <= 8; ++i)
+ bar(i);
+
+ #pragma unroll j /* { dg-error "requires an assignment-expression that evaluates to a non-negative integral constant less than" } */
+ /* { dg-error "cannot appear in a constant-expression|is not usable in a constant expression" "" { target c++ } .-1 } */
+ for (unsigned long i = 1; i <= 8; ++i)
+ bar(i);
+
+ #pragma unroll 4.2 /* { dg-error "requires an assignment-expression that evaluates to a non-negative integral constant less than" } */
+ for (unsigned long i = 1; i <= 8; ++i)
+ bar(i);
+}
+
new file mode 100644
@@ -0,0 +1,12 @@
+/*
+ Derived from pr126323.C but tests `#pragma unroll N`
+*/
+
+class C {
+#pragma GCC novector // { dg-error "must be inside a function" }
+#pragma unroll(0) // { dg-error "must be inside a function" }
+#pragma GCC ivdep // { dg-error "must be inside a function" }
+ for (int i = 0; i < 2; i++) // { dg-error "expected unqualified-id" }
+ // { dg-error "does not name a type" "" { target *-*-* } .-1 }
+ ;
+};