diff options
| author | Mark Heffernan <meheff@google.com> | 2014-07-21 18:08:34 +0000 |
|---|---|---|
| committer | Mark Heffernan <meheff@google.com> | 2014-07-21 18:08:34 +0000 |
| commit | bd26f5ea4d9c6ed042965167aa2331cc1aecc539 (patch) | |
| tree | bcc470dfa7c0a34949bfca3d56c74b2a64077e2f /clang/test | |
| parent | 4f42fc4e1d7e1a373a3f0346de7200b18f49ca22 (diff) | |
| download | bcm5719-llvm-bd26f5ea4d9c6ed042965167aa2331cc1aecc539.tar.gz bcm5719-llvm-bd26f5ea4d9c6ed042965167aa2331cc1aecc539.zip | |
Add support for '#pragma unroll'.
llvm-svn: 213574
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CodeGen/pragma-unroll.cpp | 99 | ||||
| -rw-r--r-- | clang/test/PCH/pragma-loop.cpp | 22 | ||||
| -rw-r--r-- | clang/test/Parser/pragma-loop.cpp | 8 | ||||
| -rw-r--r-- | clang/test/Parser/pragma-unroll.cpp | 89 | ||||
| -rw-r--r-- | clang/test/Parser/warn-cuda-compat.cu | 13 |
5 files changed, 227 insertions, 4 deletions
diff --git a/clang/test/CodeGen/pragma-unroll.cpp b/clang/test/CodeGen/pragma-unroll.cpp new file mode 100644 index 00000000000..b321e74a115 --- /dev/null +++ b/clang/test/CodeGen/pragma-unroll.cpp @@ -0,0 +1,99 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s + +// Verify while loop is recognized after unroll pragma. +void while_test(int *List, int Length) { + // CHECK: define {{.*}} @_Z10while_test + int i = 0; + +#pragma unroll + while (i < Length) { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]] + List[i] = i * 2; + i++; + } +} + +// Verify do loop is recognized after multi-option pragma clang loop directive. +void do_test(int *List, int Length) { + int i = 0; + +#pragma unroll 16 + do { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]] + List[i] = i * 2; + i++; + } while (i < Length); +} + +// Verify for loop is recognized after unroll pragma. +void for_test(int *List, int Length) { +#pragma unroll 8 + for (int i = 0; i < Length; i++) { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]] + List[i] = i * 2; + } +} + +// Verify c++11 for range loop is recognized after unroll pragma. +void for_range_test() { + double List[100]; + +#pragma unroll(4) + for (int i : List) { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]] + List[i] = i; + } +} + +#define UNROLLCOUNT 8 + +// Verify defines are correctly resolved in unroll pragmas. +void for_define_test(int *List, int Length, int Value) { +#pragma unroll(UNROLLCOUNT) + for (int i = 0; i < Length; i++) { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]] + List[i] = i * Value; + } +} + +// Verify metadata is generated when template is used. +template <typename A> +void for_template_test(A *List, int Length, A Value) { +#pragma unroll 8 + for (int i = 0; i < Length; i++) { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]] + List[i] = i * Value; + } +} + +// Verify define is resolved correctly when template is used. +template <typename A> +void for_template_define_test(A *List, int Length, A Value) { +#pragma unroll(UNROLLCOUNT) + for (int i = 0; i < Length; i++) { + // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]] + List[i] = i * Value; + } +} + +#undef UNROLLCOUNT + +// Use templates defined above. Test verifies metadata is generated correctly. +void template_test(double *List, int Length) { + double Value = 10; + + for_template_test<double>(List, Length, Value); + for_template_define_test<double>(List, Length, Value); +} + +// CHECK: ![[LOOP_1]] = metadata !{metadata ![[LOOP_1]], metadata ![[UNROLLENABLE_1:.*]]} +// CHECK: ![[UNROLLENABLE_1]] = metadata !{metadata !"llvm.loop.unroll.enable", i1 true} +// CHECK: ![[LOOP_2]] = metadata !{metadata ![[LOOP_2:.*]], metadata ![[UNROLL_16:.*]]} +// CHECK: ![[UNROLL_16]] = metadata !{metadata !"llvm.loop.unroll.count", i32 16} +// CHECK: ![[LOOP_3]] = metadata !{metadata ![[LOOP_3]], metadata ![[UNROLL_8:.*]]} +// CHECK: ![[UNROLL_8]] = metadata !{metadata !"llvm.loop.unroll.count", i32 8} +// CHECK: ![[LOOP_4]] = metadata !{metadata ![[LOOP_4]], metadata ![[UNROLL_4:.*]]} +// CHECK: ![[UNROLL_4]] = metadata !{metadata !"llvm.loop.unroll.count", i32 4} +// CHECK: ![[LOOP_5]] = metadata !{metadata ![[LOOP_5]], metadata ![[UNROLL_8:.*]]} +// CHECK: ![[LOOP_6]] = metadata !{metadata ![[LOOP_6]], metadata ![[UNROLL_8:.*]]} +// CHECK: ![[LOOP_7]] = metadata !{metadata ![[LOOP_7]], metadata ![[UNROLL_8:.*]]} diff --git a/clang/test/PCH/pragma-loop.cpp b/clang/test/PCH/pragma-loop.cpp index 6258b3781b0..1456a2778f3 100644 --- a/clang/test/PCH/pragma-loop.cpp +++ b/clang/test/PCH/pragma-loop.cpp @@ -13,6 +13,8 @@ // CHECK: #pragma clang loop unroll(enable) // CHECK: #pragma clang loop interleave(enable) // CHECK: #pragma clang loop vectorize(disable) +// CHECK: #pragma unroll +// CHECK: #pragma unroll (32) #ifndef HEADER #define HEADER @@ -51,6 +53,24 @@ public: i++; } } + + inline void run4(int *List, int Length) { + int i = 0; +#pragma unroll + while (i - 3 < Length) { + List[i] = i; + i++; + } + } + + inline void run5(int *List, int Length) { + int i = 0; +#pragma unroll 32 + while (i - 3 < Length) { + List[i] = i; + i++; + } + } }; #else @@ -63,6 +83,8 @@ void test() { pt.run1(List, 100); pt.run2(List, 100); pt.run3(List, 100); + pt.run4(List, 100); + pt.run5(List, 100); } #endif diff --git a/clang/test/Parser/pragma-loop.cpp b/clang/test/Parser/pragma-loop.cpp index fad4feb8707..23f185d5228 100644 --- a/clang/test/Parser/pragma-loop.cpp +++ b/clang/test/Parser/pragma-loop.cpp @@ -55,9 +55,9 @@ void test(int *List, int Length) { /* expected-error {{expected ')'}} */ #pragma clang loop interleave_count(4 /* expected-error {{expected ')'}} */ #pragma clang loop unroll_count(4 -/* expected-error {{missing argument to loop pragma 'vectorize'}} */ #pragma clang loop vectorize() -/* expected-error {{missing argument to loop pragma 'interleave_count'}} */ #pragma clang loop interleave_count() -/* expected-error {{missing argument to loop pragma 'unroll'}} */ #pragma clang loop unroll() +/* expected-error {{missing argument to '#pragma clang loop vectorize'; expected a positive integer value}} */ #pragma clang loop vectorize() +/* expected-error {{missing argument to '#pragma clang loop interleave_count'; expected a positive integer value}} */ #pragma clang loop interleave_count() +/* expected-error {{missing argument to '#pragma clang loop unroll'; expected a positive integer value}} */ #pragma clang loop unroll() /* expected-error {{missing option}} */ #pragma clang loop /* expected-error {{invalid option 'badkeyword'}} */ #pragma clang loop badkeyword @@ -110,7 +110,7 @@ void test(int *List, int Length) { } #pragma clang loop vectorize(enable) -/* expected-error {{expected a for, while, or do-while loop to follow the '#pragma clang loop' directive}} */ int j = Length; +/* expected-error {{expected a for, while, or do-while loop to follow '#pragma clang loop'}} */ int j = Length; List[0] = List[1]; while (j-1 < Length) { diff --git a/clang/test/Parser/pragma-unroll.cpp b/clang/test/Parser/pragma-unroll.cpp new file mode 100644 index 00000000000..1d89e63028c --- /dev/null +++ b/clang/test/Parser/pragma-unroll.cpp @@ -0,0 +1,89 @@ +// 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 i = 0; + +#pragma unroll + while (i + 1 < Length) { + List[i] = i; + } + +#pragma unroll 4 + while (i - 1 < Length) { + List[i] = i; + } + +#pragma unroll(8) + while (i - 2 < Length) { + List[i] = i; + } + +#pragma unroll +#pragma unroll(8) + while (i - 3 < Length) { + List[i] = i; + } + +#pragma clang loop unroll(enable) +#pragma unroll(8) + while (i - 4 < Length) { + List[i] = i; + } + +#pragma unroll +#pragma clang loop unroll_count(4) + while (i - 5 < Length) { + List[i] = i; + } + +/* expected-error {{expected ')'}} */ #pragma unroll(4 +/* expected-error {{missing argument to '#pragma unroll'; expected a positive integer value}} */ #pragma unroll() +/* expected-warning {{extra tokens at end of '#pragma unroll'}} */ #pragma unroll 1 2 + while (i-6 < Length) { + List[i] = i; + } + +/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(() +/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll - +/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(0) +/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll 0 +/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll(3000000000) +/* expected-error {{invalid argument; expected a positive integer value}} */ #pragma unroll 3000000000 + while (i-8 < Length) { + List[i] = i; + } + +#pragma unroll +/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int j = Length; +#pragma unroll 4 +/* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int k = Length; + +/* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma unroll 4 +#pragma clang loop unroll(disable) + while (i-10 < Length) { + List[i] = i; + } + +/* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll +#pragma unroll + while (i-14 < Length) { + List[i] = i; + } + +/* expected-error {{duplicate directives 'unroll(enable)' and '#pragma unroll'}} */ #pragma unroll +#pragma clang loop unroll(enable) + while (i-15 < Length) { + List[i] = i; + } + +/* expected-error {{duplicate directives '#pragma unroll(4)' and '#pragma unroll(4)'}} */ #pragma unroll 4 +#pragma unroll(4) + while (i-16 < Length) { + List[i] = i; + } + +#pragma unroll +/* expected-error {{expected statement}} */ } diff --git a/clang/test/Parser/warn-cuda-compat.cu b/clang/test/Parser/warn-cuda-compat.cu new file mode 100644 index 00000000000..c3aad6f6636 --- /dev/null +++ b/clang/test/Parser/warn-cuda-compat.cu @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -Wno-cuda-compat -Werror %s +// RUN: %clang_cc1 -Wcuda-compat -verify %s +// RUN: %clang_cc1 -x c++ -Wcuda-compat -Werror %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) { +/* expected-warning {{argument to '#pragma unroll' should not be in parentheses in CUDA C/C++}} */#pragma unroll(4) + for (int i = 0; i < Length; ++i) { + List[i] = i; + } +} |

