[llvm] [AMDGPU] Fix for ControlFlowUtils reconnectPHIs. (PR #132954)

via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 2 03:49:58 PDT 2025


https://github.com/alex-t updated https://github.com/llvm/llvm-project/pull/132954

>From d7d07af1e53b6351be20ae2b19e44d9aa8530875 Mon Sep 17 00:00:00 2001
From: alex-t <alexander.timofeev at amd.com>
Date: Tue, 25 Mar 2025 11:37:07 -0500
Subject: [PATCH] [AMDGPU] Fix for ControlFlowUtils reconnectPHIs.

Description: reconnectPHIs must consider self-loops to avoid PHI income
pair that does not exists anymore.
---
 .../lib/Transforms/Utils/ControlFlowUtils.cpp |  8 ++-
 llvm/test/Transforms/FixIrreducible/basic.ll  | 66 +++++++++++++++++--
 2 files changed, 66 insertions(+), 8 deletions(-)

diff --git a/llvm/lib/Transforms/Utils/ControlFlowUtils.cpp b/llvm/lib/Transforms/Utils/ControlFlowUtils.cpp
index 0155a7ba2570b..4b0065d0030cd 100644
--- a/llvm/lib/Transforms/Utils/ControlFlowUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ControlFlowUtils.cpp
@@ -246,12 +246,14 @@ static void reconnectPhis(BasicBlock *Out, BasicBlock *GuardBlock,
     bool AllUndef = true;
     for (auto [BB, Succ0, Succ1] : Incoming) {
       Value *V = PoisonValue::get(Phi->getType());
-      if (BB == Out) {
-        V = NewPhi;
-      } else if (Phi->getBasicBlockIndex(BB) != -1) {
+      if  (Phi->getBasicBlockIndex(BB) != -1) {
         V = Phi->removeIncomingValue(BB, false);
+        if (BB == Out) {
+          V = NewPhi;
+        }
         AllUndef &= isa<UndefValue>(V);
       }
+
       NewPhi->addIncoming(V, BB);
     }
     assert(NewPhi->getNumIncomingValues() == Incoming.size());
diff --git a/llvm/test/Transforms/FixIrreducible/basic.ll b/llvm/test/Transforms/FixIrreducible/basic.ll
index 7f81e89bc5f5b..dee82acfc1da0 100644
--- a/llvm/test/Transforms/FixIrreducible/basic.ll
+++ b/llvm/test/Transforms/FixIrreducible/basic.ll
@@ -18,7 +18,7 @@ define i32 @basic(i1 %PredEntry, i1 %PredLeft, i1 %PredRight, i32 %X, i32 %Y) {
 ; CHECK-NEXT:    [[Z:%.*]] = phi i32 [ [[L]], [[LEFT]] ], [ [[R_PHI_MOVED]], [[RIGHT]] ]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ [[L_PHI_MOVED]], [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ poison, [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[R_PHI_MOVED]] = phi i32 [ [[L]], [[LEFT]] ], [ [[Y:%.*]], [[ENTRY]] ]
 ; CHECK-NEXT:    [[GUARD_RIGHT:%.*]] = phi i1 [ true, [[LEFT]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
 ; 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
 ; CHECK-NEXT:    [[Z:%.*]] = phi i32 [ [[L_PHI]], [[LEFT]] ], [ [[R_PHI_MOVED]], [[RIGHT]] ]
 ; CHECK-NEXT:    ret i32 [[Z]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ [[L_PHI_MOVED]], [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[L_PHI_MOVED]] = phi i32 [ poison, [[LEFT]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[R_PHI_MOVED]] = phi i32 [ [[L_PHI]], [[LEFT]] ], [ [[Y:%.*]], [[ENTRY]] ]
 ; CHECK-NEXT:    [[GUARD_RIGHT:%.*]] = phi i1 [ true, [[LEFT]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
 ; 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
 ; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[C_PHI_MOVED]], [[C]] ], [ [[D_INC]], [[D]] ]
 ; CHECK-NEXT:    ret i32 [[RET]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ [[D_PHI_MOVED]], [[D]] ], [ [[Y:%.*]], [[B]] ], [ [[A_INC]], [[A]] ]
+; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ poison, [[D]] ], [ [[Y:%.*]], [[B]] ], [ [[A_INC]], [[A]] ]
 ; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ [[D_INC]], [[D]] ], [ [[Y]], [[B]] ], [ [[X]], [[A]] ]
 ; CHECK-NEXT:    [[GUARD_C:%.*]] = phi i1 [ true, [[D]] ], [ [[PREDB_INV]], [[B]] ], [ [[PREDA:%.*]], [[A]] ]
 ; 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
 ; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[C_PHI]], [[C]] ], [ [[D_INC]], [[D]] ]
 ; CHECK-NEXT:    ret i32 [[RET]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ [[C_PHI_MOVED]], [[C]] ], [ poison, [[B]] ], [ [[X]], [[A]] ]
+; CHECK-NEXT:    [[C_PHI_MOVED]] = phi i32 [ poison, [[C]] ], [ poison, [[B]] ], [ [[X]], [[A]] ]
 ; CHECK-NEXT:    [[D_PHI_MOVED]] = phi i32 [ [[C_PHI]], [[C]] ], [ [[Y:%.*]], [[B]] ], [ poison, [[A]] ]
 ; CHECK-NEXT:    [[GUARD_D:%.*]] = phi i1 [ true, [[C]] ], [ true, [[B]] ], [ false, [[A]] ]
 ; 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
 ; CHECK:       exit:
 ; CHECK-NEXT:    ret i32 [[B_PHI_MOVED]]
 ; CHECK:       irr.guard:
-; CHECK-NEXT:    [[A_PHI_MOVED]] = phi i32 [ [[A_PHI_MOVED]], [[A]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
+; CHECK-NEXT:    [[A_PHI_MOVED]] = phi i32 [ poison, [[A]] ], [ [[X:%.*]], [[ENTRY:%.*]] ]
 ; CHECK-NEXT:    [[B_PHI_MOVED]] = phi i32 [ [[A_INC]], [[A]] ], [ [[Y:%.*]], [[ENTRY]] ]
 ; CHECK-NEXT:    [[GUARD_B:%.*]] = phi i1 [ true, [[A]] ], [ [[PREDENTRY_INV]], [[ENTRY]] ]
 ; CHECK-NEXT:    br i1 [[GUARD_B]], label [[B:%.*]], label [[A]]
@@ -277,3 +277,59 @@ E:
 exit:
   ret i32 %B.phi
 }
+
+
+define void @recursive_phis(i1 %cond, ptr addrspace(5) %ptr) {
+; CHECK-LABEL: @recursive_phis(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    [[ALLOCA:%.*]] = alloca i8, align 1, addrspace(5)
+; CHECK-NEXT:    br i1 [[COND:%.*]], label [[THEN:%.*]], label [[IRR_GUARD:%.*]]
+; CHECK:       then:
+; CHECK-NEXT:    [[PTR_INT:%.*]] = ptrtoint ptr addrspace(5) [[PTR:%.*]] to i32
+; CHECK-NEXT:    [[PTR_OR:%.*]] = and i32 [[PTR_INT]], 65535
+; CHECK-NEXT:    [[KB_PTR:%.*]] = inttoptr i32 [[PTR_OR]] to ptr addrspace(5)
+; CHECK-NEXT:    br label [[IRR_GUARD]]
+; CHECK:       else:
+; CHECK-NEXT:    br i1 [[COND]], label [[IRR_GUARD]], label [[BB:%.*]]
+; CHECK:       BB:
+; CHECK-NEXT:    br label [[FINALLY:%.*]]
+; CHECK:       finally:
+; CHECK-NEXT:    [[PHI_PTR:%.*]] = phi ptr addrspace(5) [ [[OTHER_PHI_MOVED:%.*]], [[BB]] ], [ [[PHI_PTR_MOVED:%.*]], [[IRR_GUARD]] ]
+; CHECK-NEXT:    [[X:%.*]] = addrspacecast ptr addrspace(5) [[PHI_PTR]] to ptr
+; CHECK-NEXT:    store volatile i32 7, ptr [[X]], align 4
+; CHECK-NEXT:    br i1 [[COND]], label [[IRR_GUARD]], label [[END:%.*]]
+; CHECK:       end:
+; CHECK-NEXT:    ret void
+; CHECK:       irr.guard:
+; CHECK-NEXT:    [[PHI_PTR_MOVED]] = phi ptr addrspace(5) [ poison, [[FINALLY]] ], [ poison, [[ELSE:%.*]] ], [ poison, [[ENTRY:%.*]] ], [ [[KB_PTR]], [[THEN]] ]
+; CHECK-NEXT:    [[OTHER_PHI_MOVED]] = phi ptr addrspace(5) [ [[PHI_PTR]], [[FINALLY]] ], [ [[OTHER_PHI_MOVED]], [[ELSE]] ], [ [[ALLOCA]], [[ENTRY]] ], [ poison, [[THEN]] ]
+; CHECK-NEXT:    [[GUARD_ELSE:%.*]] = phi i1 [ true, [[FINALLY]] ], [ true, [[ELSE]] ], [ true, [[ENTRY]] ], [ false, [[THEN]] ]
+; CHECK-NEXT:    br i1 [[GUARD_ELSE]], label [[ELSE]], label [[FINALLY]]
+;
+
+entry:
+  %alloca = alloca i8, align 1, addrspace(5)
+  br i1 %cond, label %then, label %else
+
+then:                                             ; preds = %entry
+  %ptr.int = ptrtoint ptr addrspace(5) %ptr to i32
+  %ptr.or = and i32 %ptr.int, 65535
+  %kb.ptr = inttoptr i32 %ptr.or to ptr addrspace(5)
+  br label %finally
+
+else:                                             ; preds = %finally, %else, %entry
+  %other.phi = phi ptr addrspace(5) [ %alloca, %entry ], [ %phi.ptr, %finally ], [ undef, %else ]
+  br i1 %cond, label %else, label %BB
+
+BB:                                               ; preds = %else
+  br label %finally
+
+finally:                                          ; preds = %BB, %then
+  %phi.ptr = phi ptr addrspace(5) [ %kb.ptr, %then ], [ %other.phi, %BB ]
+  %x = addrspacecast ptr addrspace(5) %phi.ptr to ptr
+  store volatile i32 7, ptr %x, align 4
+  br i1 %cond, label %else, label %end
+
+end:                                              ; preds = %finally
+  ret void
+}



More information about the llvm-commits mailing list