Skip to content

Commit bc09c74

Browse files
authored
[AMDGPU] Fix for ControlFlowUtils reconnectPHIs. (llvm#132954)
Description: reconnectPHIs must consider self-loops to avoid PHI income pair that does not exists anymore.
1 parent 747214e commit bc09c74

File tree

2 files changed

+66
-8
lines changed

2 files changed

+66
-8
lines changed

llvm/lib/Transforms/Utils/ControlFlowUtils.cpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,14 @@ static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock,
246246
bool AllUndef = true;
247247
for (auto [BB, Succ0, Succ1] : Incoming) {
248248
Value *V = PoisonValue::get(Phi->getType());
249-
if (BB == Out) {
250-
V = NewPhi;
251-
} else if (Phi->getBasicBlockIndex(BB) != -1) {
249+
if (Phi->getBasicBlockIndex(BB) != -1) {
252250
V = Phi->removeIncomingValue(BB, false);
251+
if (BB == Out) {
252+
V = NewPhi;
253+
}
253254
AllUndef &= isa<UndefValue>(V);
254255
}
256+
255257
NewPhi->addIncoming(V, BB);
256258
}
257259
assert(NewPhi->getNumIncomingValues() == Incoming.size());

llvm/test/Transforms/FixIrreducible/basic.ll

+61-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ define i32 @basic(i1 %PredEntry, i1 %PredLeft, i1 %PredRight, i32 %X, i32 %Y) {
1818
; CHECK-NEXT: [[Z:%.*]] = phi i32 [ [[L]], [[LEFT]] ], [ [[R_PHI_MOVED]], [[RIGHT]] ]
1919
; CHECK-NEXT: ret i32 [[Z]]
2020
; CHECK: irr.guard:
21-
; CHECK-NEXT: [[L_PHI_MOVED]] = phi i32 [ [[L_PHI_MOVED]], [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
21+
; CHECK-NEXT: [[L_PHI_MOVED]] = phi i32 [ poison, [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
2222
; CHECK-NEXT: [[R_PHI_MOVED]] = phi i32 [ [[L]], [[LEFT]] ], [ [[Y:%.*]], [[ENTRY]] ]
2323
; CHECK-NEXT: [[GUARD_RIGHT:%.*]] = phi i1 [ true, [[LEFT]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
2424
; CHECK-NEXT: br i1 [[GUARD_RIGHT]], label [[RIGHT]], label [[LEFT]]
@@ -54,7 +54,7 @@ define i32 @feedback_loop(i1 %PredEntry, i1 %PredLeft, i1 %PredRight, i32 %X, i3
5454
; CHECK-NEXT: [[Z:%.*]] = phi i32 [ [[L_PHI]], [[LEFT]] ], [ [[R_PHI_MOVED]], [[RIGHT]] ]
5555
; CHECK-NEXT: ret i32 [[Z]]
5656
; CHECK: irr.guard:
57-
; CHECK-NEXT: [[L_PHI_MOVED]] = phi i32 [ [[L_PHI_MOVED]], [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
57+
; CHECK-NEXT: [[L_PHI_MOVED]] = phi i32 [ poison, [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
5858
; CHECK-NEXT: [[R_PHI_MOVED]] = phi i32 [ [[L_PHI]], [[LEFT]] ], [ [[Y:%.*]], [[ENTRY]] ]
5959
; CHECK-NEXT: [[GUARD_RIGHT:%.*]] = phi i1 [ true, [[LEFT]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
6060
; CHECK-NEXT: br i1 [[GUARD_RIGHT]], label [[RIGHT]], label [[LEFT]]
@@ -95,7 +95,7 @@ define i32 @multiple_predecessors(i1 %PredEntry, i1 %PredA, i1 %PredB, i1 %PredC
9595
; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[C_PHI_MOVED]], [[C]] ], [ [[D_INC]], [[D]] ]
9696
; CHECK-NEXT: ret i32 [[RET]]
9797
; CHECK: irr.guard:
98-
; CHECK-NEXT: [[D_PHI_MOVED]] = phi i32 [ [[D_PHI_MOVED]], [[D]] ], [ [[Y:%.*]], [[B]] ], [ [[A_INC]], [[A]] ]
98+
; CHECK-NEXT: [[D_PHI_MOVED]] = phi i32 [ poison, [[D]] ], [ [[Y:%.*]], [[B]] ], [ [[A_INC]], [[A]] ]
9999
; CHECK-NEXT: [[C_PHI_MOVED]] = phi i32 [ [[D_INC]], [[D]] ], [ [[Y]], [[B]] ], [ [[X]], [[A]] ]
100100
; CHECK-NEXT: [[GUARD_C:%.*]] = phi i1 [ true, [[D]] ], [ [[PREDB_INV]], [[B]] ], [ [[PREDA:%.*]], [[A]] ]
101101
; CHECK-NEXT: br i1 [[GUARD_C]], label [[C]], label [[D]]
@@ -143,7 +143,7 @@ define i32 @separate_predecessors(i1 %PredEntry, i1 %PredA, i1 %PredB, i1 %PredC
143143
; CHECK-NEXT: [[RET:%.*]] = phi i32 [ [[C_PHI]], [[C]] ], [ [[D_INC]], [[D]] ]
144144
; CHECK-NEXT: ret i32 [[RET]]
145145
; CHECK: irr.guard:
146-
; CHECK-NEXT: [[C_PHI_MOVED]] = phi i32 [ [[C_PHI_MOVED]], [[C]] ], [ poison, [[B]] ], [ [[X]], [[A]] ]
146+
; CHECK-NEXT: [[C_PHI_MOVED]] = phi i32 [ poison, [[C]] ], [ poison, [[B]] ], [ [[X]], [[A]] ]
147147
; CHECK-NEXT: [[D_PHI_MOVED]] = phi i32 [ [[C_PHI]], [[C]] ], [ [[Y:%.*]], [[B]] ], [ poison, [[A]] ]
148148
; CHECK-NEXT: [[GUARD_D:%.*]] = phi i1 [ true, [[C]] ], [ true, [[B]] ], [ false, [[A]] ]
149149
; CHECK-NEXT: br i1 [[GUARD_D]], label [[D]], label [[C]]
@@ -247,7 +247,7 @@ define i32 @hidden_nodes(i1 %PredEntry, i1 %PredA, i1 %PredB, i1 %PredC, i1 %Pre
247247
; CHECK: exit:
248248
; CHECK-NEXT: ret i32 [[B_PHI_MOVED]]
249249
; CHECK: irr.guard:
250-
; CHECK-NEXT: [[A_PHI_MOVED]] = phi i32 [ [[A_PHI_MOVED]], [[A]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
250+
; CHECK-NEXT: [[A_PHI_MOVED]] = phi i32 [ poison, [[A]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
251251
; CHECK-NEXT: [[B_PHI_MOVED]] = phi i32 [ [[A_INC]], [[A]] ], [ [[Y:%.*]], [[ENTRY]] ]
252252
; CHECK-NEXT: [[GUARD_B:%.*]] = phi i1 [ true, [[A]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
253253
; CHECK-NEXT: br i1 [[GUARD_B]], label [[B:%.*]], label [[A]]
@@ -277,3 +277,59 @@ E:
277277
exit:
278278
ret i32 %B.phi
279279
}
280+
281+
282+
define void @recursive_phis(i1 %cond, ptr addrspace(5) %ptr) {
283+
; CHECK-LABEL: @recursive_phis(
284+
; CHECK-NEXT: entry:
285+
; CHECK-NEXT: [[ALLOCA:%.*]] = alloca i8, align 1, addrspace(5)
286+
; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[IRR_GUARD:%.*]]
287+
; CHECK: then:
288+
; CHECK-NEXT: [[PTR_INT:%.*]] = ptrtoint ptr addrspace(5) [[PTR:%.*]] to i32
289+
; CHECK-NEXT: [[PTR_OR:%.*]] = and i32 [[PTR_INT]], 65535
290+
; CHECK-NEXT: [[KB_PTR:%.*]] = inttoptr i32 [[PTR_OR]] to ptr addrspace(5)
291+
; CHECK-NEXT: br label [[IRR_GUARD]]
292+
; CHECK: else:
293+
; CHECK-NEXT: br i1 [[COND]], label [[IRR_GUARD]], label [[BB:%.*]]
294+
; CHECK: BB:
295+
; CHECK-NEXT: br label [[FINALLY:%.*]]
296+
; CHECK: finally:
297+
; CHECK-NEXT: [[PHI_PTR:%.*]] = phi ptr addrspace(5) [ [[OTHER_PHI_MOVED:%.*]], [[BB]] ], [ [[PHI_PTR_MOVED:%.*]], [[IRR_GUARD]] ]
298+
; CHECK-NEXT: [[X:%.*]] = addrspacecast ptr addrspace(5) [[PHI_PTR]] to ptr
299+
; CHECK-NEXT: store volatile i32 7, ptr [[X]], align 4
300+
; CHECK-NEXT: br i1 [[COND]], label [[IRR_GUARD]], label [[END:%.*]]
301+
; CHECK: end:
302+
; CHECK-NEXT: ret void
303+
; CHECK: irr.guard:
304+
; CHECK-NEXT: [[PHI_PTR_MOVED]] = phi ptr addrspace(5) [ poison, [[FINALLY]] ], [ poison, [[ELSE:%.*]] ], [ poison, [[ENTRY:%.*]] ], [ [[KB_PTR]], [[THEN]] ]
305+
; CHECK-NEXT: [[OTHER_PHI_MOVED]] = phi ptr addrspace(5) [ [[PHI_PTR]], [[FINALLY]] ], [ [[OTHER_PHI_MOVED]], [[ELSE]] ], [ [[ALLOCA]], [[ENTRY]] ], [ poison, [[THEN]] ]
306+
; CHECK-NEXT: [[GUARD_ELSE:%.*]] = phi i1 [ true, [[FINALLY]] ], [ true, [[ELSE]] ], [ true, [[ENTRY]] ], [ false, [[THEN]] ]
307+
; CHECK-NEXT: br i1 [[GUARD_ELSE]], label [[ELSE]], label [[FINALLY]]
308+
;
309+
310+
entry:
311+
%alloca = alloca i8, align 1, addrspace(5)
312+
br i1 %cond, label %then, label %else
313+
314+
then: ; preds = %entry
315+
%ptr.int = ptrtoint ptr addrspace(5) %ptr to i32
316+
%ptr.or = and i32 %ptr.int, 65535
317+
%kb.ptr = inttoptr i32 %ptr.or to ptr addrspace(5)
318+
br label %finally
319+
320+
else: ; preds = %finally, %else, %entry
321+
%other.phi = phi ptr addrspace(5) [ %alloca, %entry ], [ %phi.ptr, %finally ], [ undef, %else ]
322+
br i1 %cond, label %else, label %BB
323+
324+
BB: ; preds = %else
325+
br label %finally
326+
327+
finally: ; preds = %BB, %then
328+
%phi.ptr = phi ptr addrspace(5) [ %kb.ptr, %then ], [ %other.phi, %BB ]
329+
%x = addrspacecast ptr addrspace(5) %phi.ptr to ptr
330+
store volatile i32 7, ptr %x, align 4
331+
br i1 %cond, label %else, label %end
332+
333+
end: ; preds = %finally
334+
ret void
335+
}

0 commit comments

Comments
 (0)