Re-land [openmp] Fix warnings when building on Windows with latest MSVC or Clang...
[llvm-project.git] / llvm / test / Verifier / convergencectrl-invalid.ll
blobe1fffcd1c603347da57836597493d35f6f8b66df
1 ; RUN: not llvm-as < %s -o /dev/null 2>&1 | FileCheck %s
3 ; CHECK: Entry or anchor intrinsic cannot have a convergencectrl token operand.
4 ; CHECK-NEXT: %t04_tok2 = call token
5 ; CHECK: Loop intrinsic must have a convergencectrl token operand.
6 ; CHECK-NEXT: %t04_tok3 = call token
7 define void @basic_syntax() {
8   %t04_tok1 = call token @llvm.experimental.convergence.anchor()
9   %t04_tok2 = call token @llvm.experimental.convergence.anchor() [ "convergencectrl"(token %t04_tok1) ]
10   %t04_tok3 = call token @llvm.experimental.convergence.loop()
11   ret void
14 ; CHECK: Convergence control tokens can only be produced by calls to the convergence control intrinsics.
15 ; CHECK-NEXT:  %t04_tok1 = call token @produce_token()
16 ; CHECK-NEXT:  call void @f() [ "convergencectrl"(token %t04_tok1) ]
17 define void @wrong_token() {
18   %t04_tok1 = call token @produce_token()
19   call void @f() [ "convergencectrl"(token %t04_tok1) ]
20   ret void
23 ; CHECK: Convergence control token can only be used in a convergent call.
24 ; CHECK-NEXT  call void @g(){{.*}}%t05_tok1
25 define void @missing.attribute() {
26   %t05_tok1 = call token @llvm.experimental.convergence.anchor()
27   call void @g() [ "convergencectrl"(token %t05_tok1) ]
28   ret void
31 ; CHECK: The 'convergencectrl' bundle requires exactly one token use.
32 ; CHECK-NEXT:  call void @g()
33 define void @multiple_tokens() {
34   %t06_tok1 = call token @llvm.experimental.convergence.anchor()
35   %t06_tok2 = call token @llvm.experimental.convergence.anchor()
36   call void @g() [ "convergencectrl"(token %t06_tok2, token %t06_tok1) ]
37   ret void
40 ; CHECK: The 'convergencectrl' bundle can occur at most once on a call
41 ; CHECK-NEXT:  call void @g()
42 define void @multiple_bundles() {
43   %t07_tok1 = call token @llvm.experimental.convergence.anchor()
44   %t07_tok2 = call token @llvm.experimental.convergence.anchor()
45   call void @g() [ "convergencectrl"(token %t07_tok2), "convergencectrl"(token %t07_tok1) ]
46   ret void
49 ; CHECK: Cannot mix controlled and uncontrolled convergence in the same function
50 ; CHECK-NEXT  call void @f()
51 define void @mixed1() {
52   call void @g() ; not convergent
53   %t10_tok1 = call token @llvm.experimental.convergence.anchor()
54   call void @f() [ "convergencectrl"(token %t10_tok1) ]
55   call void @g()
56   call void @f() ; uncontrolled convergent
57   ret void
60 ; CHECK: Cannot mix controlled and uncontrolled convergence in the same function
61 ; CHECK:  %t20_tok1 = call token @llvm.experimental.convergence.anchor()
62 ; CHECK: Cannot mix controlled and uncontrolled convergence in the same function
63 ; CHECK:  call void @f() [ "convergencectrl"(token %t20_tok1) ]
64 define void @mixed2() {
65   call void @g() ; not convergent
66   call void @f() ; uncontrolled convergent
67   call void @g()
68   %t20_tok1 = call token @llvm.experimental.convergence.anchor()
69   call void @f() [ "convergencectrl"(token %t20_tok1) ]
70   ret void
73 ; CHECK: Convergence region is not well-nested.
74 ; CHECK:   %t30_tok2
75 define void @region_nesting1() {
76   %t30_tok1 = call token @llvm.experimental.convergence.anchor()
77   %t30_tok2 = call token @llvm.experimental.convergence.anchor()
78   call void @f() [ "convergencectrl"(token %t30_tok1) ]
79   call void @f() [ "convergencectrl"(token %t30_tok2) ]
80   ret void
83 ; CHECK: Convergence region is not well-nested.
84 ; CHECK:   %t40_tok2
85 define void @region_nesting2(i1 %cond) {
87   %t40_tok1 = call token @llvm.experimental.convergence.anchor()
88   %t40_tok2 = call token @llvm.experimental.convergence.anchor()
89   br i1 %cond, label %B, label %C
92   call void @f() [ "convergencectrl"(token %t40_tok1) ]
93   br label %C
96   call void @f() [ "convergencectrl"(token %t40_tok2) ]
97   ret void
100 ; CHECK: Convergence token used by an instruction other than llvm.experimental.convergence.loop in a cycle that does not contain the token's definition.
101 ; CHECK:   token %t50_tok1
102 define void @use_in_cycle() {
104   %t50_tok1 = call token @llvm.experimental.convergence.anchor()
105   br label %B
108   call void @f() [ "convergencectrl"(token %t50_tok1) ]
109   br label %B
112 ; CHECK: Entry intrinsic cannot be preceded by a convergent operation in the same basic block.
113 ; CHECK:   %t60_tok1
114 define void @entry_at_start(i32 %x, i32 %y) convergent {
115   %z = add i32 %x, %y
116   call void @f()
117   %t60_tok1 = call token @llvm.experimental.convergence.entry()
118   ret void
121 ; CHECK: Entry intrinsic can occur only in a convergent function.
122 ; CHECK:   %t60_tok2
123 define void @entry_in_convergent(i32 %x, i32 %y) {
124   %t60_tok2 = call token @llvm.experimental.convergence.entry()
125   ret void
128 ; CHECK: Loop intrinsic cannot be preceded by a convergent operation in the same basic block.
129 ; CHECK-NEXT: %h1
130 ; CHECK-SAME: %t60_tok3
131 define void @loop_at_start(i32 %x, i32 %y) convergent {
133   %t60_tok3 = call token @llvm.experimental.convergence.entry()
134   br label %B
136   %z = add i32 %x, %y
137   ; This is not an error
138   %h2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t60_tok3) ]
139   br label %C
141   call void @f()
142   %h1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t60_tok3) ]
143   ret void
146 ; CHECK: Entry intrinsic can occur only in the entry block.
147 ; CHECK:   %t60_tok4
148 define void @entry_at_entry(i32 %x, i32 %y) convergent {
150   %z = add i32 %x, %y
151   br label %B
153   %t60_tok4 = call token @llvm.experimental.convergence.entry()
154   ret void
157 ; CHECK: Two static convergence token uses in a cycle that does not contain either token's definition.
158 ; CHECK:   token %t70_tok1
159 ; CHECK:   token %t70_tok2
160 define void @multiple_hearts() {
162   %t70_tok1 = call token @llvm.experimental.convergence.anchor()
163   %t70_tok2 = call token @llvm.experimental.convergence.anchor()
164   br label %B
167   %h2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t70_tok2) ]
168   %h1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t70_tok1) ]
169   br label %B
172 ; CHECK: Two static convergence token uses in a cycle that does not contain either token's definition.
173 ; CHECK:   token %h0
174 ; CHECK:   token %h0
175 define void @multiple_hearts_nested(i1 %cond1, i1 %cond2) {
177   %t70_tok3 = call token @llvm.experimental.convergence.anchor()
178   br label %B
181   %h0 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t70_tok3) ]
182   br i1 %cond1, label %C, label %B
185   %h1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %h0) ]
186   %h2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %h0) ]
187   br i1 %cond2, label %C, label %B
190 ; CHECK: Cycle heart must dominate all blocks in the cycle.
191 ; CHECK: %h3 = call token
192 ; CHECK:   label %C
193 define void @invalid_heart_nested(i1 %cond1, i1 %cond2) {
195   %t70_tok4 = call token @llvm.experimental.convergence.anchor()
196   br label %B
199   br i1 %cond1, label %C, label %B
202   %h3 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t70_tok4) ]
203   br i1 %cond2, label %C, label %B
206 ; CHECK: Cycle heart must dominate all blocks in the cycle.
207 ; CHECK: %h4 = call token
208 ; CHECK: label %C
209 define void @irreducible1(i1 %cond) {
211   %a = call token @llvm.experimental.convergence.anchor()
212   br i1 %cond, label %B, label %C
215   %b = call token @llvm.experimental.convergence.anchor()
216   br i1 %cond, label %C, label %D
219   %h4 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %a) ]
220   br i1 %cond, label %B, label %E
223   call void @f() [ "convergencectrl"(token %b) ]
224   br i1 %cond, label %B, label %F
227   call void @f() [ "convergencectrl"(token %h4) ]
228   br i1 %cond, label %C, label %F
231   call void @f() [ "convergencectrl"(token %a) ]
232   ret void
235 ; Mirror image of @irreducible1
236 ; CHECK: Cycle heart must dominate all blocks in the cycle.
237 ; CHECK: %h5 = call token
238 ; CHECK: label %B
239 define void @irreducible2(i1 %cond) {
241   %a = call token @llvm.experimental.convergence.anchor()
242   br i1 %cond, label %B, label %C
245   %h5 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %a) ]
246   br i1 %cond, label %C, label %D
249   %c = call token @llvm.experimental.convergence.anchor()
250   br i1 %cond, label %B, label %E
253   call void @f() [ "convergencectrl"(token %h5) ]
254   br i1 %cond, label %B, label %F
257   call void @f() [ "convergencectrl"(token %c) ]
258   br i1 %cond, label %C, label %F
261   call void @f() [ "convergencectrl"(token %a) ]
262   ret void
265 declare token @produce_token()
267 declare void @f() convergent
268 declare void @g()
270 declare token @llvm.experimental.convergence.entry()
271 declare token @llvm.experimental.convergence.anchor()
272 declare token @llvm.experimental.convergence.loop()