Skip to content

Commit

Permalink
remove cyclic undef PHIs (#1245)
Browse files Browse the repository at this point in the history
  • Loading branch information
rjodinchr authored Oct 4, 2023
1 parent 60c4f7b commit e3f4744
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
43 changes: 43 additions & 0 deletions lib/FixupStructuredCFGPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "llvm/ADT/DenseSet.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/Pass.h"
#include "llvm/Support/raw_ostream.h"

Expand All @@ -28,10 +29,52 @@ clspv::FixupStructuredCFGPass::run(Function &F, FunctionAnalysisManager &FAM) {
// Run after isolateContinue since this can invalidate loop info.
breakConditionalHeader(F, FAM);

removeUndefPHI(F);

PreservedAnalyses PA;
return PA;
}

void clspv::FixupStructuredCFGPass::removeUndefPHI(Function &F) {
SmallVector<PHINode *> ToBeDeleted;
DenseMap<PHINode *, SmallVector<PHINode *>> dict;
for (auto &BB : F) {
for (auto &I : BB) {
if (auto phi = dyn_cast<PHINode>(&I)) {
if (!phi->getType()->isPointerTy()) {
continue;
}
bool phiIsUndef = true;
for (unsigned i = 0; i < phi->getNumIncomingValues(); i++) {
auto Val = phi->getIncomingValue(i);
if (auto phi2 = dyn_cast<PHINode>(Val)) {
for (unsigned j = 0; j < phi2->getNumIncomingValues(); j++) {
auto Val2 = phi2->getIncomingValue(i);
if (auto phi3 = dyn_cast<PHINode>(Val2)) {
if (phi3 != phi) {
phiIsUndef = false;
}
} else if (!isa<UndefValue>(Val2)) {
phiIsUndef = false;
}
}
} else if (!isa<UndefValue>(Val)) {
phiIsUndef = false;
}
}
if (!phiIsUndef) {
continue;
}
phi->replaceAllUsesWith(UndefValue::get(phi->getType()));
ToBeDeleted.push_back(phi);
}
}
}
for (auto phi : ToBeDeleted) {
phi->eraseFromParent();
}
}

void clspv::FixupStructuredCFGPass::breakConditionalHeader(
Function &F, FunctionAnalysisManager &FAM) {
auto &LI = FAM.getResult<LoopAnalysis>(F);
Expand Down
1 change: 1 addition & 0 deletions lib/FixupStructuredCFGPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ struct FixupStructuredCFGPass : llvm::PassInfoMixin<FixupStructuredCFGPass> {
llvm::FunctionAnalysisManager &FAM);

private:
void removeUndefPHI(llvm::Function &F);
void breakConditionalHeader(llvm::Function &F, llvm::FunctionAnalysisManager &FAM);
void isolateContinue(llvm::Function &F, llvm::FunctionAnalysisManager &FAM);

Expand Down
30 changes: 30 additions & 0 deletions test/FixupStructuredCFG/UndefPHI.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
; RUN: clspv-opt %s -o %t.ll --passes=fixup-structured-cfg
; RUN: FileCheck %s < %t.ll

target datalayout = "e-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
target triple = "spir64-unknown-unknown"

define dso_local spir_kernel void @foo(i1 %cmp1, i1 %cmp2, i1 %cmp3) {
entry:
; CHECK: [[alloca:%[^ ]+]] = alloca i32, align 4
%alloca = alloca i32, align 4
br i1 %cmp1, label %b1, label %b2

; CHECK: b1:
; CHECK-NEXT: br
b1:
%b1_phi = phi ptr [ undef, %entry ], [ %b2_phi, %b2 ]
br i1 %cmp2, label %b2, label %exit

; CHECK: b2:
; CHECK-NEXT: br
b2:
%b2_phi = phi ptr [ undef, %entry ], [ %b1_phi, %b1 ]
br i1 %cmp3, label %b1, label %exit

; CHECK: exit:
; CHECK-NEXT: phi ptr [ undef, %b1 ], [ [[alloca]], %b2 ]
exit:
%exit_phi = phi ptr [ %b1_phi, %b1 ], [ %alloca, %b2 ]
ret void
}

0 comments on commit e3f4744

Please sign in to comment.