1*0a6a1f1dSLionel Sambuc // RUN: %clang_cc1 -triple x86_64-apple-darwin -std=c++11 -emit-llvm -o - %s | FileCheck %s
2*0a6a1f1dSLionel Sambuc
3*0a6a1f1dSLionel Sambuc // Verify while loop is recognized after unroll pragma.
while_test(int * List,int Length)4*0a6a1f1dSLionel Sambuc void while_test(int *List, int Length) {
5*0a6a1f1dSLionel Sambuc // CHECK: define {{.*}} @_Z10while_test
6*0a6a1f1dSLionel Sambuc int i = 0;
7*0a6a1f1dSLionel Sambuc
8*0a6a1f1dSLionel Sambuc #pragma unroll
9*0a6a1f1dSLionel Sambuc while (i < Length) {
10*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_1:.*]]
11*0a6a1f1dSLionel Sambuc List[i] = i * 2;
12*0a6a1f1dSLionel Sambuc i++;
13*0a6a1f1dSLionel Sambuc }
14*0a6a1f1dSLionel Sambuc }
15*0a6a1f1dSLionel Sambuc
16*0a6a1f1dSLionel Sambuc // Verify do loop is recognized after multi-option pragma clang loop directive.
do_test(int * List,int Length)17*0a6a1f1dSLionel Sambuc void do_test(int *List, int Length) {
18*0a6a1f1dSLionel Sambuc int i = 0;
19*0a6a1f1dSLionel Sambuc
20*0a6a1f1dSLionel Sambuc #pragma nounroll
21*0a6a1f1dSLionel Sambuc do {
22*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_2:.*]]
23*0a6a1f1dSLionel Sambuc List[i] = i * 2;
24*0a6a1f1dSLionel Sambuc i++;
25*0a6a1f1dSLionel Sambuc } while (i < Length);
26*0a6a1f1dSLionel Sambuc }
27*0a6a1f1dSLionel Sambuc
28*0a6a1f1dSLionel Sambuc // Verify for loop is recognized after unroll pragma.
for_test(int * List,int Length)29*0a6a1f1dSLionel Sambuc void for_test(int *List, int Length) {
30*0a6a1f1dSLionel Sambuc #pragma unroll 8
31*0a6a1f1dSLionel Sambuc for (int i = 0; i < Length; i++) {
32*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_3:.*]]
33*0a6a1f1dSLionel Sambuc List[i] = i * 2;
34*0a6a1f1dSLionel Sambuc }
35*0a6a1f1dSLionel Sambuc }
36*0a6a1f1dSLionel Sambuc
37*0a6a1f1dSLionel Sambuc // Verify c++11 for range loop is recognized after unroll pragma.
for_range_test()38*0a6a1f1dSLionel Sambuc void for_range_test() {
39*0a6a1f1dSLionel Sambuc double List[100];
40*0a6a1f1dSLionel Sambuc
41*0a6a1f1dSLionel Sambuc #pragma unroll(4)
42*0a6a1f1dSLionel Sambuc for (int i : List) {
43*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_4:.*]]
44*0a6a1f1dSLionel Sambuc List[i] = i;
45*0a6a1f1dSLionel Sambuc }
46*0a6a1f1dSLionel Sambuc }
47*0a6a1f1dSLionel Sambuc
48*0a6a1f1dSLionel Sambuc #define UNROLLCOUNT 8
49*0a6a1f1dSLionel Sambuc
50*0a6a1f1dSLionel Sambuc // Verify defines are correctly resolved in unroll pragmas.
for_define_test(int * List,int Length,int Value)51*0a6a1f1dSLionel Sambuc void for_define_test(int *List, int Length, int Value) {
52*0a6a1f1dSLionel Sambuc #pragma unroll(UNROLLCOUNT)
53*0a6a1f1dSLionel Sambuc for (int i = 0; i < Length; i++) {
54*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_5:.*]]
55*0a6a1f1dSLionel Sambuc List[i] = i * Value;
56*0a6a1f1dSLionel Sambuc }
57*0a6a1f1dSLionel Sambuc }
58*0a6a1f1dSLionel Sambuc
59*0a6a1f1dSLionel Sambuc // Verify metadata is generated when template is used.
60*0a6a1f1dSLionel Sambuc template <typename A>
for_template_test(A * List,int Length,A Value)61*0a6a1f1dSLionel Sambuc void for_template_test(A *List, int Length, A Value) {
62*0a6a1f1dSLionel Sambuc #pragma unroll 8
63*0a6a1f1dSLionel Sambuc for (int i = 0; i < Length; i++) {
64*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_6:.*]]
65*0a6a1f1dSLionel Sambuc List[i] = i * Value;
66*0a6a1f1dSLionel Sambuc }
67*0a6a1f1dSLionel Sambuc }
68*0a6a1f1dSLionel Sambuc
69*0a6a1f1dSLionel Sambuc // Verify define is resolved correctly when template is used.
70*0a6a1f1dSLionel Sambuc template <typename A>
for_template_define_test(A * List,int Length,A Value)71*0a6a1f1dSLionel Sambuc void for_template_define_test(A *List, int Length, A Value) {
72*0a6a1f1dSLionel Sambuc #pragma unroll(UNROLLCOUNT)
73*0a6a1f1dSLionel Sambuc for (int i = 0; i < Length; i++) {
74*0a6a1f1dSLionel Sambuc // CHECK: br i1 {{.*}}, label {{.*}}, label {{.*}}, !llvm.loop ![[LOOP_7:.*]]
75*0a6a1f1dSLionel Sambuc List[i] = i * Value;
76*0a6a1f1dSLionel Sambuc }
77*0a6a1f1dSLionel Sambuc }
78*0a6a1f1dSLionel Sambuc
79*0a6a1f1dSLionel Sambuc #undef UNROLLCOUNT
80*0a6a1f1dSLionel Sambuc
81*0a6a1f1dSLionel Sambuc // Use templates defined above. Test verifies metadata is generated correctly.
template_test(double * List,int Length)82*0a6a1f1dSLionel Sambuc void template_test(double *List, int Length) {
83*0a6a1f1dSLionel Sambuc double Value = 10;
84*0a6a1f1dSLionel Sambuc
85*0a6a1f1dSLionel Sambuc for_template_test<double>(List, Length, Value);
86*0a6a1f1dSLionel Sambuc for_template_define_test<double>(List, Length, Value);
87*0a6a1f1dSLionel Sambuc }
88*0a6a1f1dSLionel Sambuc
89*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_1]] = distinct !{![[LOOP_1]], ![[UNROLL_FULL:.*]]}
90*0a6a1f1dSLionel Sambuc // CHECK: ![[UNROLL_FULL]] = !{!"llvm.loop.unroll.full"}
91*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_2]] = distinct !{![[LOOP_2:.*]], ![[UNROLL_DISABLE:.*]]}
92*0a6a1f1dSLionel Sambuc // CHECK: ![[UNROLL_DISABLE]] = !{!"llvm.loop.unroll.disable"}
93*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_3]] = distinct !{![[LOOP_3]], ![[UNROLL_8:.*]]}
94*0a6a1f1dSLionel Sambuc // CHECK: ![[UNROLL_8]] = !{!"llvm.loop.unroll.count", i32 8}
95*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_4]] = distinct !{![[LOOP_4]], ![[UNROLL_4:.*]]}
96*0a6a1f1dSLionel Sambuc // CHECK: ![[UNROLL_4]] = !{!"llvm.loop.unroll.count", i32 4}
97*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_5]] = distinct !{![[LOOP_5]], ![[UNROLL_8:.*]]}
98*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_6]] = distinct !{![[LOOP_6]], ![[UNROLL_8:.*]]}
99*0a6a1f1dSLionel Sambuc // CHECK: ![[LOOP_7]] = distinct !{![[LOOP_7]], ![[UNROLL_8:.*]]}
100