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