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