xref: /llvm-project/clang/test/Parser/pragma-unroll.cpp (revision c4c8d08b81e622529aaf0bfc3020d2b9e87267b3)
1 // RUN: %clang_cc1 -std=c++11 -verify %s
2 
3 // Note that this puts the expected lines before the directives to work around
4 // limitations in the -verify mode.
5 
test(int * List,int Length)6 void test(int *List, int Length) {
7   int i = 0;
8 
9 #pragma unroll
10   while (i + 1 < Length) {
11     List[i] = i;
12   }
13 
14 #pragma nounroll
15   while (i < Length) {
16     List[i] = i;
17   }
18 
19 #pragma unroll 4
20   while (i - 1 < Length) {
21     List[i] = i;
22   }
23 
24 #pragma unroll(8)
25   while (i - 2 < Length) {
26     List[i] = i;
27   }
28 
29 /* expected-error {{expected ')'}} */ #pragma unroll(4
30 /* expected-error {{missing argument; expected an integer value}} */ #pragma unroll()
31 /* expected-warning {{extra tokens at end of '#pragma unroll'}} */ #pragma unroll 1 2
32   while (i-6 < Length) {
33     List[i] = i;
34   }
35 
36 /* expected-warning {{extra tokens at end of '#pragma nounroll'}} */ #pragma nounroll 1
37   while (i-7 < Length) {
38     List[i] = i;
39   }
40 
41 /* expected-error {{expected ')'}} */ #pragma unroll(()
42 /* expected-error {{expected expression}} */ #pragma unroll -
43 /* The values of 0 and 1 block any unrolling of the loop. */ #pragma unroll 0
44 /* expected-error {{value '3000000000' is too large}} */ #pragma unroll(3000000000)
45 /* expected-error {{value '3000000000' is too large}} */ #pragma unroll 3000000000
46   while (i-8 < Length) {
47     List[i] = i;
48   }
49 
50 /* The values of 0 and 1 block any unrolling of the loop. */ #pragma unroll(0)
51   while (i-8 < Length) {
52     List[i] = i;
53   }
54 
55 #pragma unroll
56 /* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int j = Length;
57 #pragma unroll 4
58 /* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ int k = Length;
59 #pragma nounroll
60 /* expected-error {{expected a for, while, or do-while loop to follow '#pragma nounroll'}} */ int l = Length;
61 
62   switch (i) {
63   case 1:
64 #pragma unroll
65 /* expected-error {{expected a for, while, or do-while loop to follow '#pragma unroll'}} */ [[fallthrough]];
66   case 2:
67     for (int i = 0; i < 10; ++i);
68     break;
69   }
70 
71 #pragma unroll 4
72 /* expected-error {{incompatible directives 'unroll(disable)' and '#pragma unroll(4)'}} */ #pragma clang loop unroll(disable)
73   while (i-10 < Length) {
74     List[i] = i;
75   }
76 
77 #pragma unroll(4)
78 /* expected-error {{incompatible directives 'unroll(full)' and '#pragma unroll(4)'}} */ #pragma clang loop unroll(full)
79   while (i-11 < Length) {
80     List[i] = i;
81   }
82 
83 #pragma unroll(4)
84 /* expected-error {{incompatible directives 'unroll(enable)' and '#pragma unroll(4)'}} */ #pragma clang loop unroll(enable)
85   while (i-11 < Length) {
86     List[i] = i;
87   }
88 
89 #pragma unroll(4)
90 /* expected-error {{incompatible directives '#pragma unroll' and '#pragma unroll(4)'}} */ #pragma unroll
91   while (i-11 < Length) {
92     List[i] = i;
93   }
94 
95 #pragma clang loop unroll_count(4)
96 /* expected-error {{incompatible directives '#pragma nounroll' and 'unroll_count(4)'}} */ #pragma nounroll
97   while (i-12 < Length) {
98     List[i] = i;
99   }
100 
101 #pragma nounroll
102 /* expected-error {{duplicate directives '#pragma nounroll' and '#pragma nounroll'}} */ #pragma nounroll
103   while (i-13 < Length) {
104     List[i] = i;
105   }
106 
107 #pragma unroll
108 /* expected-error {{duplicate directives '#pragma unroll' and '#pragma unroll'}} */ #pragma unroll
109   while (i-14 < Length) {
110     List[i] = i;
111   }
112 
113 #pragma unroll
114 /* expected-error {{duplicate directives '#pragma unroll' and 'unroll(full)'}} */ #pragma clang loop unroll(full)
115   while (i-15 < Length) {
116     List[i] = i;
117   }
118 
119 #pragma unroll 4
120 /* expected-error {{duplicate directives '#pragma unroll(4)' and '#pragma unroll(4)'}} */ #pragma unroll(4)
121   while (i-16 < Length) {
122     List[i] = i;
123   }
124 
125 #pragma unroll
126 /* expected-error {{expected statement}} */ }
127 
128 using size_t = unsigned long long;
129 
130 template <bool Flag>
FailToBuild(int n)131 int FailToBuild(int n) {
132   constexpr int N = 100;
133   auto init = [=]() { return Flag ? n : 0UL; };
134   auto cond = [=](size_t ix) { return Flag ? ix != 0 : ix < 10; };
135   auto iter = [=](size_t ix) {
136     return Flag ? ix & ~(1ULL << __builtin_clzll(ix)) : ix + 1;
137   };
138 #pragma unroll Flag ? 0 : N // Ok, allow 0.
139   for (size_t ix = init(); cond(ix); ix = iter(ix)) {
140     n *= n;
141   }
142 #pragma GCC unroll Flag ? 0 : N // Ok, allow 0.
143   for (size_t ix = init(); cond(ix); ix = iter(ix)) {
144     n *= n;
145   }
146   return n;
147 }
148 
foo(int n)149 int foo(int n) {
150     return FailToBuild<true>(n);
151 }
152 
bar(int n)153 int bar(int n) {
154     return FailToBuild<false>(n);
155 }
156