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()
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) ]
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) ]
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) ]
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) ]
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) ]
56 call void @f() ; uncontrolled convergent
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
68 %t20_tok1 = call token @llvm.experimental.convergence.anchor()
69 call void @f() [ "convergencectrl"(token %t20_tok1) ]
73 ; CHECK: Convergence region is not well-nested.
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) ]
83 ; CHECK: Convergence region is not well-nested.
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) ]
96 call void @f() [ "convergencectrl"(token %t40_tok2) ]
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()
108 call void @f() [ "convergencectrl"(token %t50_tok1) ]
112 ; CHECK: Entry intrinsic cannot be preceded by a convergent operation in the same basic block.
114 define void @entry_at_start(i32 %x, i32 %y) convergent {
117 %t60_tok1 = call token @llvm.experimental.convergence.entry()
121 ; CHECK: Entry intrinsic can occur only in a convergent function.
123 define void @entry_in_convergent(i32 %x, i32 %y) {
124 %t60_tok2 = call token @llvm.experimental.convergence.entry()
128 ; CHECK: Loop intrinsic cannot be preceded by a convergent operation in the same basic block.
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()
137 ; This is not an error
138 %h2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t60_tok3) ]
142 %h1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t60_tok3) ]
146 ; CHECK: Entry intrinsic can occur only in the entry block.
148 define void @entry_at_entry(i32 %x, i32 %y) convergent {
153 %t60_tok4 = call token @llvm.experimental.convergence.entry()
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()
167 %h2 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t70_tok2) ]
168 %h1 = call token @llvm.experimental.convergence.loop() [ "convergencectrl"(token %t70_tok1) ]
172 ; CHECK: Two static convergence token uses in a cycle that does not contain either token's definition.
175 define void @multiple_hearts_nested(i1 %cond1, i1 %cond2) {
177 %t70_tok3 = call token @llvm.experimental.convergence.anchor()
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
193 define void @invalid_heart_nested(i1 %cond1, i1 %cond2) {
195 %t70_tok4 = call token @llvm.experimental.convergence.anchor()
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
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) ]
235 ; Mirror image of @irreducible1
236 ; CHECK: Cycle heart must dominate all blocks in the cycle.
237 ; CHECK: %h5 = call token
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) ]
265 declare token @produce_token()
267 declare void @f() convergent
270 declare token @llvm.experimental.convergence.entry()
271 declare token @llvm.experimental.convergence.anchor()
272 declare token @llvm.experimental.convergence.loop()