summaryrefslogtreecommitdiff
path: root/clang/test
diff options
context:
space:
mode:
authorDavid Green <david.green@arm.com>2018-08-01 14:36:12 +0000
committerDavid Green <david.green@arm.com>2018-08-01 14:36:12 +0000
commit68db10fded893cab159ac55a43b162f4c6d8d1c6 (patch)
tree991f41f0e590bba2f2588fcaecc6bdeeaa2851d8 /clang/test
parent71f322bfc276432e37004ad9f629c9a4a6a260f4 (diff)
[UnrollAndJam] Add unroll_and_jam pragma handling
This adds support for the unroll_and_jam pragma, to go with the recently added unroll and jam pass. The name of the pragma is the same as is used in the Intel compiler, and most of the code works the same as for unroll. #pragma clang loop unroll_and_jam has been separated into a different patch. This part adds #pragma unroll_and_jam with an optional count, and #pragma no_unroll_and_jam to disable the transform. Differential Revision: https://reviews.llvm.org/D47267
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp55
-rw-r--r--clang/test/Parser/pragma-unroll-and-jam.cpp78
2 files changed, 133 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp b/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
new file mode 100644
index 00000000000..98421260345
--- /dev/null
+++ b/clang/test/CodeGenCXX/pragma-unroll-and-jam.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -triple arm-none-eabi -std=c++11 -emit-llvm -o - %s | FileCheck %s
+
+void unroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z14unroll_and_jam
+#pragma unroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void unroll_and_jam_count(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z20unroll_and_jam_count
+#pragma unroll_and_jam(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void nounroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z16nounroll_and_jam
+#pragma nounroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+void clang_unroll_plus_nounroll_and_jam(int *List, int Length, int Value) {
+ // CHECK-LABEL: define {{.*}} @_Z34clang_unroll_plus_nounroll_and_jam
+#pragma nounroll_and_jam
+#pragma unroll(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ // CHECK: br label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
+ List[i * Length + j] = Value;
+ }
+ }
+}
+
+// CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNJ_ENABLE:.*]]}
+// CHECK: ![[UNJ_ENABLE]] = !{!"llvm.loop.unroll_and_jam.enable"}
+// CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2]], ![[UNJ_4:.*]]}
+// CHECK: ![[UNJ_4]] = !{!"llvm.loop.unroll_and_jam.count", i32 4}
+// CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[UNJ_DISABLE]] = !{!"llvm.loop.unroll_and_jam.disable"}
+// CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_4:.*]], ![[UNJ_DISABLE:.*]]}
+// CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
diff --git a/clang/test/Parser/pragma-unroll-and-jam.cpp b/clang/test/Parser/pragma-unroll-and-jam.cpp
new file mode 100644
index 00000000000..391d6b23ead
--- /dev/null
+++ b/clang/test/Parser/pragma-unroll-and-jam.cpp
@@ -0,0 +1,78 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Note that this puts the expected lines before the directives to work around
+// limitations in the -verify mode.
+
+void test(int *List, int Length, int Value) {
+ int i = 0;
+
+#pragma unroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+#pragma nounroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+#pragma unroll_and_jam 4
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+/* expected-error {{expected ')'}} */ #pragma unroll_and_jam(4
+/* expected-error {{missing argument; expected an integer value}} */ #pragma unroll_and_jam()
+/* expected-warning {{extra tokens at end of '#pragma unroll_and_jam'}} */ #pragma unroll_and_jam 1 2
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+/* expected-warning {{extra tokens at end of '#pragma nounroll_and_jam'}} */ #pragma nounroll_and_jam 1
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+#pragma unroll_and_jam
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll_and_jam'}} */ int j = Length;
+#pragma unroll_and_jam 4
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll_and_jam'}} */ int k = Length;
+#pragma nounroll_and_jam
+/* expected-error {{expected a for, while, or do-while loop to follow '#pragma nounroll_and_jam'}} */ int l = Length;
+
+/* expected-error {{incompatible directives '#pragma nounroll_and_jam' and '#pragma unroll_and_jam(4)'}} */ #pragma unroll_and_jam 4
+#pragma nounroll_and_jam
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+#pragma nounroll_and_jam
+#pragma unroll(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+// pragma clang unroll_and_jam is disabled for the moment
+/* expected-error {{invalid option 'unroll_and_jam'; expected vectorize, vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute}} */ #pragma clang loop unroll_and_jam(4)
+ for (int i = 0; i < Length; i++) {
+ for (int j = 0; j < Length; j++) {
+ List[i * Length + j] = Value;
+ }
+ }
+
+#pragma unroll_and_jam
+/* expected-error {{expected statement}} */ }