llvm.org GIT mirror llvm / a6e8fb6
Merging r266088: ------------------------------------------------------------------------ r266088 | nhaehnle | 2016-04-12 09:10:38 -0700 (Tue, 12 Apr 2016) | 16 lines AMDGPU/SI: Fix a mis-compilation of multi-level breaks Summary: Under certain circumstances, multi-level breaks (or what is understood by the control flow passes as such) could be miscompiled in a way that causes infinite loops, by emitting incorrect control flow intrinsics. This fixes a hang in dEQP-GLES3.functional.shaders.loops.while_dynamic_iterations.conditional_continue_vertex Reviewers: arsenm, tstellarAMD Subscribers: arsenm, llvm-commits Differential Revision: http://reviews.llvm.org/D18967 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_38@271730 91177308-0d34-0410-b5e6-96231b3b80d8 Tom Stellard 3 years ago
2 changed file(s) with 57 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
251251
252252 BasicBlock *From = Phi->getIncomingBlock(i);
253253 if (From == IDom) {
254 // We're in the following situation:
255 // IDom/From
256 // | \
257 // | If-block
258 // | /
259 // Parent
260 // where we want to break out of the loop if the If-block is not taken.
261 // Due to the depth-first traversal, there should be an end.cf
262 // intrinsic in Parent, and we insert an else.break before it.
263 //
264 // Note that the end.cf need not be the first non-phi instruction
265 // of parent, particularly when we're dealing with a multi-level
266 // break, but it should occur within a group of intrinsic calls
267 // at the beginning of the block.
254268 CallInst *OldEnd = dyn_cast(Parent->getFirstInsertionPt());
269 while (OldEnd && OldEnd->getCalledFunction() != EndCf)
270 OldEnd = dyn_cast(OldEnd->getNextNode());
255271 if (OldEnd && OldEnd->getCalledFunction() == EndCf) {
256272 Value *Args[] = { OldEnd->getArgOperand(0), NewPhi };
257273 Ret = CallInst::Create(ElseBreak, Args, "", OldEnd);
0 ; RUN: opt -S -mtriple=amdgcn-- -structurizecfg -si-annotate-control-flow < %s | FileCheck %s
1
2 ; CHECK-LABEL: {{^}}define void @main
3 ; CHECK: main_body:
4 ; CHECK: LOOP.outer:
5 ; CHECK: LOOP:
6 ; CHECK: [[if:%[0-9]+]] = call { i1, i64 } @llvm.SI.if(
7 ; CHECK: [[if_exec:%[0-9]+]] = extractvalue { i1, i64 } [[if]], 1
8 ;
9 ; CHECK: Flow:
10 ;
11 ; Ensure two else.break calls, for both the inner and outer loops
12 ;
13 ; CHECK: call i64 @llvm.SI.else.break(i64 [[if_exec]],
14 ; CHECK-NEXT: call i64 @llvm.SI.else.break(i64 [[if_exec]],
15 ; CHECK-NEXT: call void @llvm.SI.end.cf
16 ;
17 ; CHECK: Flow1:
18 define void @main(<4 x float> %vec, i32 %ub, i32 %cont) {
19 main_body:
20 br label %LOOP.outer
21
22 LOOP.outer: ; preds = %ENDIF, %main_body
23 %tmp43 = phi i32 [ 0, %main_body ], [ %tmp47, %ENDIF ]
24 br label %LOOP
25
26 LOOP: ; preds = %ENDIF, %LOOP.outer
27 %tmp45 = phi i32 [ %tmp43, %LOOP.outer ], [ %tmp47, %ENDIF ]
28 %tmp47 = add i32 %tmp45, 1
29 %tmp48 = icmp slt i32 %tmp45, %ub
30 br i1 %tmp48, label %ENDIF, label %IF
31
32 IF: ; preds = %LOOP
33 ret void
34
35 ENDIF: ; preds = %LOOP
36 %tmp51 = icmp eq i32 %tmp47, %cont
37 br i1 %tmp51, label %LOOP, label %LOOP.outer
38 }
39
40 attributes #0 = { nounwind readnone }