llvm.org GIT mirror llvm / 47fbd9b
Revert "StructurizeCFG: Directly invert cmp instructions" This reverts commit r300732. This breaks a few tests. I think the problem is related to adding more uses of the condition that don't yet exist at this point. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301242 91177308-0d34-0410-b5e6-96231b3b80d8 Matt Arsenault 2 years ago
8 changed file(s) with 115 addition(s) and 187 deletion(s). Raw diff Collapse all Expand all
351351 if (Instruction *Inst = dyn_cast(Condition)) {
352352 // Third: Check all the users for an invert
353353 BasicBlock *Parent = Inst->getParent();
354 for (User *U : Condition->users()) {
355 if (Instruction *I = dyn_cast(U)) {
354 for (User *U : Condition->users())
355 if (Instruction *I = dyn_cast(U))
356356 if (I->getParent() == Parent && match(I, m_Not(m_Specific(Condition))))
357357 return I;
358 }
359 }
360
361 // Avoid creating a new instruction in the common case of a compare.
362 if (CmpInst *Cmp = dyn_cast(Inst)) {
363 if (Cmp->hasOneUse()) {
364 Cmp->setPredicate(Cmp->getInversePredicate());
365 return Cmp;
366 }
367 }
368358
369359 // Last option: Create a new instruction
370360 return BinaryOperator::CreateNot(Condition, "", Parent->getTerminator());
99
1010 ; OPT: bb4:
1111 ; OPT: load volatile
12 ; OPT: %cmp1 = icmp sge i32 %tmp, %load
12 ; OPT: xor i1 %cmp1
1313 ; OPT: call i64 @llvm.amdgcn.if.break(
1414 ; OPT: br label %Flow
1515
88 ; StructurizeCFG.
99
1010 ; IR-LABEL: @multi_divergent_region_exit_ret_ret(
11 ; IR: %Pivot = icmp sge i32 %tmp16, 2
12 ; IR-NEXT: %0 = call { i1, i64 } @llvm.amdgcn.if(i1 %Pivot)
13 ; IR: %1 = extractvalue { i1, i64 } %0, 0
14 ; IR: %2 = extractvalue { i1, i64 } %0, 1
15 ; IR: br i1 %1, label %LeafBlock1, label %Flow
11 ; IR: %1 = call { i1, i64 } @llvm.amdgcn.if(i1 %0)
12 ; IR: %2 = extractvalue { i1, i64 } %1, 0
13 ; IR: %3 = extractvalue { i1, i64 } %1, 1
14 ; IR: br i1 %2, label %LeafBlock1, label %Flow
1615
1716 ; IR: Flow:
18 ; IR: %3 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
19 ; IR: %4 = phi i1 [ %SwitchLeaf2, %LeafBlock1 ], [ false, %entry ]
20 ; IR: %5 = call { i1, i64 } @llvm.amdgcn.else(i64 %2)
21 ; IR: %6 = extractvalue { i1, i64 } %5, 0
22 ; IR: %7 = extractvalue { i1, i64 } %5, 1
23 ; IR: br i1 %6, label %LeafBlock, label %Flow1
17 ; IR: %4 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
18 ; IR: %5 = phi i1 [ %10, %LeafBlock1 ], [ false, %entry ]
19 ; IR: %6 = call { i1, i64 } @llvm.amdgcn.else(i64 %3)
20 ; IR: %7 = extractvalue { i1, i64 } %6, 0
21 ; IR: %8 = extractvalue { i1, i64 } %6, 1
22 ; IR: br i1 %7, label %LeafBlock, label %Flow1
2423
2524 ; IR: LeafBlock:
2625 ; IR: br label %Flow1
2928 ; IR: br label %Flow{{$}}
3029
3130 ; IR: Flow2:
32 ; IR: %8 = phi i1 [ false, %exit1 ], [ %12, %Flow1 ]
33 ; IR: call void @llvm.amdgcn.end.cf(i64 %16)
34 ; IR: [[IF:%[0-9]+]] = call { i1, i64 } @llvm.amdgcn.if(i1 %8)
35 ; IR: %10 = extractvalue { i1, i64 } [[IF]], 0
36 ; IR: %11 = extractvalue { i1, i64 } [[IF]], 1
37 ; IR: br i1 %10, label %exit0, label %UnifiedReturnBlock
31 ; IR: %11 = phi i1 [ false, %exit1 ], [ %15, %Flow1 ]
32 ; IR: call void @llvm.amdgcn.end.cf(i64 %19)
33 ; IR: %12 = call { i1, i64 } @llvm.amdgcn.if(i1 %11)
34 ; IR: %13 = extractvalue { i1, i64 } %12, 0
35 ; IR: %14 = extractvalue { i1, i64 } %12, 1
36 ; IR: br i1 %13, label %exit0, label %UnifiedReturnBlock
3837
3938 ; IR: exit0:
4039 ; IR: store volatile i32 9, i32 addrspace(1)* undef
4140 ; IR: br label %UnifiedReturnBlock
4241
4342 ; IR: Flow1:
44 ; IR: %12 = phi i1 [ %SwitchLeaf, %LeafBlock ], [ %3, %Flow ]
45 ; IR: %13 = phi i1 [ %SwitchLeaf, %LeafBlock ], [ %4, %Flow ]
46 ; IR: call void @llvm.amdgcn.end.cf(i64 %7)
47 ; IR: %14 = call { i1, i64 } @llvm.amdgcn.if(i1 %13)
48 ; IR: %15 = extractvalue { i1, i64 } %14, 0
49 ; IR: %16 = extractvalue { i1, i64 } %14, 1
50 ; IR: br i1 %15, label %exit1, label %Flow2
43 ; IR: %15 = phi i1 [ %SwitchLeaf, %LeafBlock ], [ %4, %Flow ]
44 ; IR: %16 = phi i1 [ %9, %LeafBlock ], [ %5, %Flow ]
45 ; IR: call void @llvm.amdgcn.end.cf(i64 %8)
46 ; IR: %17 = call { i1, i64 } @llvm.amdgcn.if(i1 %16)
47 ; IR: %18 = extractvalue { i1, i64 } %17, 0
48 ; IR: %19 = extractvalue { i1, i64 } %17, 1
49 ; IR: br i1 %18, label %exit1, label %Flow2
5150
5251 ; IR: exit1:
5352 ; IR: store volatile i32 17, i32 addrspace(3)* undef
5453 ; IR: br label %Flow2
5554
5655 ; IR: UnifiedReturnBlock:
57 ; IR: call void @llvm.amdgcn.end.cf(i64 %11)
56 ; IR: call void @llvm.amdgcn.end.cf(i64 %14)
5857 ; IR: ret void
5958
6059
6463 ; GCN: s_xor_b64
6564
6665
67 ; GCN: ; %LeafBlock
68 ; GCN: v_cmp_ne_u32_e32 vcc, 1, [[REG:v[0-9]+]]
66 ; FIXME: Why is this compare essentially repeated?
67 ; GCN: v_cmp_eq_u32_e32 vcc, 1, [[REG:v[0-9]+]]
68 ; GCN-NEXT: v_cmp_ne_u32_e64 s{{\[[0-9]+:[0-9]+\]}}, 1, [[REG]]
6969 ; GCN: v_cndmask_b32_e64 v{{[0-9]+}}, 0, -1, vcc
70 ; GCN: v_cndmask_b32_e64 v{{[0-9]+}}, 0, -1
7071
7172 ; GCN: ; %Flow1
7273 ; GCN-NEXT: s_or_b64 exec, exec
124125 }
125126
126127 ; IR-LABEL: @multi_divergent_region_exit_unreachable_unreachable(
127 ; IR: %Pivot = icmp sge i32 %tmp16, 2
128 ; IR-NEXT: %0 = call { i1, i64 } @llvm.amdgcn.if(i1 %Pivot)
129
130 ; IR: %5 = call { i1, i64 } @llvm.amdgcn.else(i64 %2)
131
132 ; IR: %8 = phi i1 [ false, %exit1 ], [ %12, %Flow1 ]
133 ; IR: call void @llvm.amdgcn.end.cf(i64 %16)
134 ; IR: %9 = call { i1, i64 } @llvm.amdgcn.if(i1 %8)
135 ; IR: br i1 %10, label %exit0, label %UnifiedUnreachableBlock
128 ; IR: %1 = call { i1, i64 } @llvm.amdgcn.if(i1 %0)
129
130 ; IR: %6 = call { i1, i64 } @llvm.amdgcn.else(i64 %3)
131
132 ; IR: %11 = phi i1 [ false, %exit1 ], [ %15, %Flow1 ]
133 ; IR: call void @llvm.amdgcn.end.cf(i64 %19)
134 ; IR: %12 = call { i1, i64 } @llvm.amdgcn.if(i1 %11)
135 ; IR: br i1 %13, label %exit0, label %UnifiedUnreachableBlock
136136
137137
138138 ; IR: UnifiedUnreachableBlock:
180180 }
181181
182182 ; IR-LABEL: @multi_exit_region_divergent_ret_uniform_ret(
183 ; IR: %divergent.cond0 = icmp sge i32 %tmp16, 2
183 ; IR: %divergent.cond0 = icmp slt i32 %tmp16, 2
184184 ; IR: llvm.amdgcn.if
185185 ; IR: br i1
186186
187187 ; IR: {{^}}Flow:
188 ; IR: %3 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
189 ; IR: %4 = phi i1 [ %uniform.cond0, %LeafBlock1 ], [ false, %entry ]
190 ; IR: %5 = call { i1, i64 } @llvm.amdgcn.else(i64 %2)
191 ; IR: br i1 %6, label %LeafBlock, label %Flow1
188 ; IR: %4 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
189 ; IR: %5 = phi i1 [ %10, %LeafBlock1 ], [ false, %entry ]
190 ; IR: %6 = call { i1, i64 } @llvm.amdgcn.else(i64 %3)
191 ; IR: br i1 %7, label %LeafBlock, label %Flow1
192192
193193 ; IR: {{^}}LeafBlock:
194 ; IR: %divergent.cond1 = icmp ne i32 %tmp16, 1
194 ; IR: %divergent.cond1 = icmp eq i32 %tmp16, 1
195 ; IR: %9 = xor i1 %divergent.cond1, true
195196 ; IR: br label %Flow1
196197
197198 ; IR: LeafBlock1:
198 ; IR: %uniform.cond0 = icmp ne i32 %arg3, 2
199 ; IR: %uniform.cond0 = icmp eq i32 %arg3, 2
200 ; IR: %10 = xor i1 %uniform.cond0, true
199201 ; IR: br label %Flow
200202
201203 ; IR: Flow2:
202 ; IR: %8 = phi i1 [ false, %exit1 ], [ %12, %Flow1 ]
203 ; IR: call void @llvm.amdgcn.end.cf(i64 %16)
204 ; IR: %9 = call { i1, i64 } @llvm.amdgcn.if(i1 %8)
205 ; IR: br i1 %10, label %exit0, label %UnifiedReturnBlock
204 ; IR: %11 = phi i1 [ false, %exit1 ], [ %15, %Flow1 ]
205 ; IR: call void @llvm.amdgcn.end.cf(i64 %19)
206 ; IR: %12 = call { i1, i64 } @llvm.amdgcn.if(i1 %11)
207 ; IR: br i1 %13, label %exit0, label %UnifiedReturnBlock
206208
207209 ; IR: exit0:
208210 ; IR: store volatile i32 9, i32 addrspace(1)* undef
209211 ; IR: br label %UnifiedReturnBlock
210212
211213 ; IR: {{^}}Flow1:
212 ; IR: %12 = phi i1 [ %divergent.cond1, %LeafBlock ], [ %3, %Flow ]
213 ; IR: %13 = phi i1 [ %divergent.cond1, %LeafBlock ], [ %4, %Flow ]
214 ; IR: call void @llvm.amdgcn.end.cf(i64 %7)
215 ; IR: %14 = call { i1, i64 } @llvm.amdgcn.if(i1 %13)
216 ; IR: %15 = extractvalue { i1, i64 } %14, 0
217 ; IR: %16 = extractvalue { i1, i64 } %14, 1
218 ; IR: br i1 %15, label %exit1, label %Flow2
214 ; IR: %15 = phi i1 [ %divergent.cond1, %LeafBlock ], [ %4, %Flow ]
215 ; IR: %16 = phi i1 [ %9, %LeafBlock ], [ %5, %Flow ]
216 ; IR: call void @llvm.amdgcn.end.cf(i64 %8)
217 ; IR: %17 = call { i1, i64 } @llvm.amdgcn.if(i1 %16)
218 ; IR: %18 = extractvalue { i1, i64 } %17, 0
219 ; IR: %19 = extractvalue { i1, i64 } %17, 1
220 ; IR: br i1 %18, label %exit1, label %Flow2
219221
220222 ; IR: exit1:
221223 ; IR: store volatile i32 17, i32 addrspace(3)* undef
222224 ; IR: br label %Flow2
223225
224226 ; IR: UnifiedReturnBlock:
225 ; IR: call void @llvm.amdgcn.end.cf(i64 %11)
227 ; IR: call void @llvm.amdgcn.end.cf(i64 %14)
226228 ; IR: ret void
227229 define amdgpu_kernel void @multi_exit_region_divergent_ret_uniform_ret(i32 addrspace(1)* nocapture %arg0, i32 addrspace(1)* nocapture %arg1, i32 addrspace(1)* nocapture %arg2, i32 %arg3) #0 {
228230 entry:
261263 }
262264
263265 ; IR-LABEL: @multi_exit_region_uniform_ret_divergent_ret(
264 ; IR: %Pivot = icmp sge i32 %tmp16, 2
265 ; IR-NEXT: %0 = call { i1, i64 } @llvm.amdgcn.if(i1 %Pivot)
266 ; IR: br i1 %1, label %LeafBlock1, label %Flow
266 ; IR: %1 = call { i1, i64 } @llvm.amdgcn.if(i1 %0)
267 ; IR: br i1 %2, label %LeafBlock1, label %Flow
267268
268269 ; IR: Flow:
269 ; IR: %3 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
270 ; IR: %4 = phi i1 [ %SwitchLeaf2, %LeafBlock1 ], [ false, %entry ]
271 ; IR: %5 = call { i1, i64 } @llvm.amdgcn.else(i64 %2)
272
273 ; IR: %8 = phi i1 [ false, %exit1 ], [ %12, %Flow1 ]
274 ; IR: call void @llvm.amdgcn.end.cf(i64 %16)
275 ; IR: %9 = call { i1, i64 } @llvm.amdgcn.if(i1 %8)
270 ; IR: %4 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
271 ; IR: %5 = phi i1 [ %10, %LeafBlock1 ], [ false, %entry ]
272 ; IR: %6 = call { i1, i64 } @llvm.amdgcn.else(i64 %3)
273
274 ; IR: %11 = phi i1 [ false, %exit1 ], [ %15, %Flow1 ]
275 ; IR: call void @llvm.amdgcn.end.cf(i64 %19)
276 ; IR: %12 = call { i1, i64 } @llvm.amdgcn.if(i1 %11)
276277
277278 define amdgpu_kernel void @multi_exit_region_uniform_ret_divergent_ret(i32 addrspace(1)* nocapture %arg0, i32 addrspace(1)* nocapture %arg1, i32 addrspace(1)* nocapture %arg2, i32 %arg3) #0 {
278279 entry:
312313
313314 ; IR-LABEL: @multi_divergent_region_exit_ret_ret_return_value(
314315 ; IR: Flow2:
315 ; IR: %8 = phi float [ 2.000000e+00, %exit1 ], [ undef, %Flow1 ]
316 ; IR: %9 = phi i1 [ false, %exit1 ], [ %13, %Flow1 ]
317 ; IR: call void @llvm.amdgcn.end.cf(i64 %17)
316 ; IR: %11 = phi float [ 2.000000e+00, %exit1 ], [ undef, %Flow1 ]
317 ; IR: %12 = phi i1 [ false, %exit1 ], [ %16, %Flow1 ]
318 ; IR: call void @llvm.amdgcn.end.cf(i64 %20)
318319
319320 ; IR: UnifiedReturnBlock:
320 ; IR: %UnifiedRetVal = phi float [ %8, %Flow2 ], [ 1.000000e+00, %exit0 ]
321 ; IR: call void @llvm.amdgcn.end.cf(i64 %12)
321 ; IR: %UnifiedRetVal = phi float [ %11, %Flow2 ], [ 1.000000e+00, %exit0 ]
322 ; IR: call void @llvm.amdgcn.end.cf(i64 %15)
322323 ; IR: ret float %UnifiedRetVal
323324 define amdgpu_ps float @multi_divergent_region_exit_ret_ret_return_value(i32 %vgpr) #0 {
324325 entry:
385386 }
386387
387388 ; IR-LABEL: @multi_divergent_region_exit_ret_unreachable(
388 ; IR: %Pivot = icmp sge i32 %tmp16, 2
389 ; IR-NEXT: %0 = call { i1, i64 } @llvm.amdgcn.if(i1 %Pivot)
389 ; IR: %1 = call { i1, i64 } @llvm.amdgcn.if(i1 %0)
390390
391391 ; IR: Flow:
392 ; IR: %3 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
393 ; IR: %4 = phi i1 [ %SwitchLeaf2, %LeafBlock1 ], [ false, %entry ]
394 ; IR: %5 = call { i1, i64 } @llvm.amdgcn.else(i64 %2)
392 ; IR: %4 = phi i1 [ true, %LeafBlock1 ], [ false, %entry ]
393 ; IR: %5 = phi i1 [ %10, %LeafBlock1 ], [ false, %entry ]
394 ; IR: %6 = call { i1, i64 } @llvm.amdgcn.else(i64 %3)
395395
396396 ; IR: Flow2:
397 ; IR: %8 = phi i1 [ false, %exit1 ], [ %12, %Flow1 ]
398 ; IR: call void @llvm.amdgcn.end.cf(i64 %16)
399 ; IR: %9 = call { i1, i64 } @llvm.amdgcn.if(i1 %8)
400 ; IR: br i1 %10, label %exit0, label %UnifiedReturnBlock
397 ; IR: %11 = phi i1 [ false, %exit1 ], [ %15, %Flow1 ]
398 ; IR: call void @llvm.amdgcn.end.cf(i64 %19)
399 ; IR: %12 = call { i1, i64 } @llvm.amdgcn.if(i1 %11)
400 ; IR: br i1 %13, label %exit0, label %UnifiedReturnBlock
401401
402402 ; IR: exit0:
403403 ; IR-NEXT: store volatile i32 17, i32 addrspace(3)* undef
404404 ; IR-NEXT: br label %UnifiedReturnBlock
405405
406406 ; IR: Flow1:
407 ; IR: %12 = phi i1 [ %SwitchLeaf, %LeafBlock ], [ %3, %Flow ]
408 ; IR: %13 = phi i1 [ %SwitchLeaf, %LeafBlock ], [ %4, %Flow ]
409 ; IR: call void @llvm.amdgcn.end.cf(i64 %7)
410 ; IR: %14 = call { i1, i64 } @llvm.amdgcn.if(i1 %13)
411 ; IR: %15 = extractvalue { i1, i64 } %14, 0
412 ; IR: %16 = extractvalue { i1, i64 } %14, 1
413 ; IR: br i1 %15, label %exit1, label %Flow2
407 ; IR: %15 = phi i1 [ %SwitchLeaf, %LeafBlock ], [ %4, %Flow ]
408 ; IR: %16 = phi i1 [ %9, %LeafBlock ], [ %5, %Flow ]
409 ; IR: call void @llvm.amdgcn.end.cf(i64 %8)
410 ; IR: %17 = call { i1, i64 } @llvm.amdgcn.if(i1 %16)
411 ; IR: %18 = extractvalue { i1, i64 } %17, 0
412 ; IR: %19 = extractvalue { i1, i64 } %17, 1
413 ; IR: br i1 %18, label %exit1, label %Flow2
414414
415415 ; IR: exit1:
416416 ; IR-NEXT: store volatile i32 9, i32 addrspace(1)* undef
418418 ; IR-NEXT: br label %Flow2
419419
420420 ; IR: UnifiedReturnBlock:
421 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %11)
421 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %14)
422422 ; IR-NEXT: ret void
423423 define amdgpu_kernel void @multi_divergent_region_exit_ret_unreachable(i32 addrspace(1)* nocapture %arg0, i32 addrspace(1)* nocapture %arg1, i32 addrspace(1)* nocapture %arg2) #0 {
424424 entry:
474474 ; IR-NEXT: br label %Flow2
475475
476476 ; IR: UnifiedReturnBlock: ; preds = %exit0, %Flow2
477 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %11)
477 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %14)
478478 ; IR-NEXT: ret void
479479 define amdgpu_kernel void @indirect_multi_divergent_region_exit_ret_unreachable(i32 addrspace(1)* nocapture %arg0, i32 addrspace(1)* nocapture %arg1, i32 addrspace(1)* nocapture %arg2) #0 {
480480 entry:
621621
622622 ; IR-LABEL: @uniform_complex_multi_ret_nest_in_divergent_triangle(
623623 ; IR: Flow1: ; preds = %uniform.ret1, %uniform.multi.exit.region
624 ; IR: %6 = phi i1 [ false, %uniform.ret1 ], [ true, %uniform.multi.exit.region ]
625 ; IR: br i1 %6, label %uniform.if, label %Flow2
624 ; IR: %8 = phi i1 [ false, %uniform.ret1 ], [ true, %uniform.multi.exit.region ]
625 ; IR: br i1 %8, label %uniform.if, label %Flow2
626626
627627 ; IR: Flow: ; preds = %uniform.then, %uniform.if
628 ; IR: %7 = phi i1 [ %uniform.cond2, %uniform.then ], [ %uniform.cond1, %uniform.if ]
629 ; IR: br i1 %7, label %uniform.endif, label %uniform.ret0
628 ; IR: %11 = phi i1 [ %10, %uniform.then ], [ %9, %uniform.if ]
629 ; IR: br i1 %11, label %uniform.endif, label %uniform.ret0
630630
631631 ; IR: UnifiedReturnBlock: ; preds = %Flow3, %Flow2
632 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %5)
632 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %6)
633633 ; IR-NEXT: ret void
634634 define amdgpu_kernel void @uniform_complex_multi_ret_nest_in_divergent_triangle(i32 %arg0) #0 {
635635 entry:
132132
133133 ; IR: Flow1:
134134 ; IR-NEXT: %loop.phi = phi i64 [ %loop.phi9, %Flow6 ], [ %phi.broken, %bb14 ]
135 ; IR-NEXT: %13 = phi <4 x i32> [ %28, %Flow6 ], [ undef, %bb14 ]
136 ; IR-NEXT: %14 = phi i32 [ %29, %Flow6 ], [ undef, %bb14 ]
137 ; IR-NEXT: %15 = phi i1 [ %30, %Flow6 ], [ false, %bb14 ]
135 ; IR-NEXT: %13 = phi <4 x i32> [ %29, %Flow6 ], [ undef, %bb14 ]
136 ; IR-NEXT: %14 = phi i32 [ %30, %Flow6 ], [ undef, %bb14 ]
137 ; IR-NEXT: %15 = phi i1 [ %31, %Flow6 ], [ false, %bb14 ]
138138 ; IR-NEXT: %16 = phi i1 [ false, %Flow6 ], [ %8, %bb14 ]
139139 ; IR-NEXT: %17 = call i64 @llvm.amdgcn.else.break(i64 %11, i64 %loop.phi)
140140 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %11)
143143
144144 ; IR: Flow2:
145145 ; IR-NEXT: %loop.phi10 = phi i64 [ %loop.phi11, %Flow5 ], [ %12, %bb16 ]
146 ; IR-NEXT: %19 = phi <4 x i32> [ %28, %Flow5 ], [ undef, %bb16 ]
147 ; IR-NEXT: %20 = phi i32 [ %29, %Flow5 ], [ undef, %bb16 ]
148 ; IR-NEXT: %21 = phi i1 [ %30, %Flow5 ], [ false, %bb16 ]
146 ; IR-NEXT: %19 = phi <4 x i32> [ %29, %Flow5 ], [ undef, %bb16 ]
147 ; IR-NEXT: %20 = phi i32 [ %30, %Flow5 ], [ undef, %bb16 ]
148 ; IR-NEXT: %21 = phi i1 [ %31, %Flow5 ], [ false, %bb16 ]
149149 ; IR-NEXT: %22 = phi i1 [ false, %Flow5 ], [ false, %bb16 ]
150150 ; IR-NEXT: %23 = phi i1 [ false, %Flow5 ], [ %8, %bb16 ]
151151 ; IR-NEXT: %24 = call { i1, i64 } @llvm.amdgcn.if(i1 %23)
155155
156156 ; IR: bb21:
157157 ; IR: %tmp12 = icmp slt i32 %tmp11, 9
158 ; IR-NEXT: %27 = call i64 @llvm.amdgcn.if.break(i1 %tmp12, i64 %phi.broken)
158 ; IR-NEXT: %27 = xor i1 %tmp12, true
159 ; IR-NEXT: %28 = call i64 @llvm.amdgcn.if.break(i1 %27, i64 %phi.broken)
159160 ; IR-NEXT: br label %Flow3
160161
161162 ; IR: Flow3:
162163 ; IR-NEXT: %loop.phi11 = phi i64 [ %phi.broken, %bb21 ], [ %phi.broken, %Flow2 ]
163 ; IR-NEXT: %loop.phi9 = phi i64 [ %27, %bb21 ], [ %loop.phi10, %Flow2 ]
164 ; IR-NEXT: %28 = phi <4 x i32> [ %tmp9, %bb21 ], [ %19, %Flow2 ]
165 ; IR-NEXT: %29 = phi i32 [ %tmp10, %bb21 ], [ %20, %Flow2 ]
166 ; IR-NEXT: %30 = phi i1 [ %tmp12, %bb21 ], [ %21, %Flow2 ]
164 ; IR-NEXT: %loop.phi9 = phi i64 [ %28, %bb21 ], [ %loop.phi10, %Flow2 ]
165 ; IR-NEXT: %29 = phi <4 x i32> [ %tmp9, %bb21 ], [ %19, %Flow2 ]
166 ; IR-NEXT: %30 = phi i32 [ %tmp10, %bb21 ], [ %20, %Flow2 ]
167 ; IR-NEXT: %31 = phi i1 [ %27, %bb21 ], [ %21, %Flow2 ]
167168 ; IR-NEXT: call void @llvm.amdgcn.end.cf(i64 %26)
168169 ; IR-NEXT: br i1 %22, label %bb31.loopexit, label %Flow4
169170
5555 }
5656
5757 ; GCN-LABEL: {{^}}uniform_br_nontrivial_ret_divergent_br_nontrivial_unreachable:
58 ; GCN: s_cbranch_scc1 [[RET_BB:BB[0-9]+_[0-9]+]]
58 ; GCN: s_cbranch_vccnz [[RET_BB:BB[0-9]+_[0-9]+]]
5959
6060 ; GCN: ; BB#{{[0-9]+}}: ; %else
6161 ; GCN: s_and_saveexec_b64 [[SAVE_EXEC:s\[[0-9]+:[0-9]+\]]], vcc
+0
-60
test/Transforms/StructurizeCFG/invert-compare.ll less more
None ; RUN: opt -S -structurizecfg %s | FileCheck %s
1
2 ; CHECK-LABEL: @directly_invert_compare_condition_jump_into_loop(
3 ; CHECK: %cmp0 = fcmp uge float %arg0, %arg1
4 ; CHECK-NEXT: br i1 %cmp0, label %end.loop, label %Flow
5 define void @directly_invert_compare_condition_jump_into_loop(i32 addrspace(1)* %out, i32 %n, float %arg0, float %arg1) #0 {
6 entry:
7 br label %for.body
8
9 for.body:
10 %i = phi i32 [0, %entry], [%i.inc, %end.loop]
11 %ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %i
12 store i32 %i, i32 addrspace(1)* %ptr, align 4
13 %cmp0 = fcmp olt float %arg0, %arg1
14 br i1 %cmp0, label %mid.loop, label %end.loop
15
16 mid.loop:
17 store i32 333, i32 addrspace(1)* %out, align 4
18 br label %for.end
19
20 end.loop:
21 %i.inc = add i32 %i, 1
22 %cmp = icmp ne i32 %i.inc, %n
23 br i1 %cmp, label %for.body, label %for.end
24
25 for.end:
26 ret void
27 }
28
29 ; CHECK-LABEL: @invert_multi_use_compare_condition_jump_into_loop(
30 ; CHECK: %cmp0 = fcmp olt float %arg0, %arg1
31 ; CHECK: store volatile i1 %cmp0, i1 addrspace(1)* undef
32 ; CHECK: %0 = xor i1 %cmp0, true
33 ; CHECK-NEXT: br i1 %0, label %end.loop, label %Flow
34 define void @invert_multi_use_compare_condition_jump_into_loop(i32 addrspace(1)* %out, i32 %n, float %arg0, float %arg1) #0 {
35 entry:
36 br label %for.body
37
38 for.body:
39 %i = phi i32 [0, %entry], [%i.inc, %end.loop]
40 %ptr = getelementptr i32, i32 addrspace(1)* %out, i32 %i
41 store i32 %i, i32 addrspace(1)* %ptr, align 4
42 %cmp0 = fcmp olt float %arg0, %arg1
43 store volatile i1 %cmp0, i1 addrspace(1)* undef
44 br i1 %cmp0, label %mid.loop, label %end.loop
45
46 mid.loop:
47 store i32 333, i32 addrspace(1)* %out, align 4
48 br label %for.end
49
50 end.loop:
51 %i.inc = add i32 %i, 1
52 %cmp = icmp ne i32 %i.inc, %n
53 br i1 %cmp, label %for.body, label %for.end
54
55 for.end:
56 ret void
57 }
58
59 attributes #0 = { nounwind }
1010 bb3: ; preds = %bb7, %bb
1111 %tmp = phi i64 [ 0, %bb ], [ %tmp8, %bb7 ]
1212 %tmp4 = fcmp ult float %arg1, 3.500000e+00
13 ; CHECK: %tmp4 = fcmp oge float %arg1, 3.500000e+00
14 ; CHECK: br i1 %tmp4, label %bb5, label %Flow
13 ; CHECK: %0 = xor i1 %tmp4, true
14 ; CHECK: br i1 %0, label %bb5, label %Flow
1515 br i1 %tmp4, label %bb7, label %bb5
1616
1717 ; CHECK: bb5:
2121 br i1 %tmp6, label %bb10, label %bb7
2222
2323 ; CHECK: Flow:
24 ; CHECK: %1 = phi i1 [ %tmp6, %bb5 ], [ %tmp4, %bb3 ]
25 ; CHECK-NEXT: br i1 %1, label %bb7, label %Flow1
24 ; CHECK: br i1 %3, label %bb7, label %Flow1
2625
2726 ; CHECK: bb7
2827 bb7: ; preds = %bb5, %bb3
3231 br i1 %tmp9, label %bb3, label %bb10
3332
3433 ; CHECK: Flow1:
35 ; CHECK: %4 = phi i1 [ %tmp9, %bb7 ], [ true, %Flow ]
36 ; CHECK-NEXT: br i1 %4, label %bb10, label %bb3
34 ; CHECK: br i1 %7, label %bb10, label %bb3
3735
38 ; CHECK: bb10:
36 ; CHECK: bb10
3937 bb10: ; preds = %bb7, %bb5
4038 %tmp11 = phi i32 [ 15, %bb5 ], [ 255, %bb7 ]
4139 store i32 %tmp11, i32 addrspace(1)* %arg, align 4
5858 ; CHECK: br i1 %{{[0-9]}}, label %for.body.1, label %Flow2
5959
6060 ; CHECK: for.body.1:
61 ; CHECK: %cmp1.5 = icmp ne i32 %tmp22, %K1
62 ; CHECK-NEXT: br i1 %cmp1.5, label %for.body.6, label %Flow3
61 ; CHECK: br i1 %{{[0-9]+}}, label %for.body.6, label %Flow3
6362 for.body.1: ; preds = %if.then, %lor.lhs.false
6463 %best_val.233 = phi float [ %tmp5, %if.then ], [ %best_val.027, %lor.lhs.false ]
6564 %best_count.231 = phi i32 [ %sub4, %if.then ], [ %best_count.025, %lor.lhs.false ]