Skip to content

Commit

Permalink
Remove unused PHI node cycles
Browse files Browse the repository at this point in the history
Sometimes PHI nodes form a cyclic dependency, which uses some values but
not used anywhere. Such cycles are not removed by DCE and, what is much
worse, often prevent used instructions from being bailed
  • Loading branch information
mshelego authored and igcbot committed Aug 28, 2023
1 parent 9416dab commit 7924e15
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 17 deletions.
7 changes: 1 addition & 6 deletions IGC/VectorCompiler/lib/GenXCodeGen/GenXGEPLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,8 @@ Value *GenXGEPLowering::visitPtrToIntInst(PtrToIntInst &PTI) {
// The `addrspacecast` is just no-op so it can be eliminated
Src = Cast->getOperand(0);
} else if (isa<BitCastInst>(Cast)) {
auto *Arg = Cast->getOperand(0);
auto *ArgTy = Arg->getType();
auto *CastTy = Cast->getType();
if (ArgTy->isVectorTy() != CastTy->isVectorTy())
break;
// The `bitcast` is just no-op so it can be eliminated
Src = Arg;
Src = Cast->getOperand(0);
} else {
// We found `inttoptr`, getting rid of `ptrtoint`
if (isa<IntToPtrInst>(Cast))
Expand Down
36 changes: 36 additions & 0 deletions IGC/VectorCompiler/lib/GenXCodeGen/GenXPatternMatch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ class GenXPatternMatch : public FunctionPass,

void visitICmpInst(ICmpInst &I);

void visitPHINode(PHINode &I);

void visitSRem(BinaryOperator &I);

void visitSDiv(BinaryOperator &I);
Expand Down Expand Up @@ -3669,3 +3671,37 @@ bool GenXPatternMatch::extendMask(BinaryOperator *BO) {

return true;
}

void GenXPatternMatch::visitPHINode(PHINode &I) {
if (Kind != PatternMatchKind::PreLegalization)
return;

std::unordered_set<PHINode *> Visited;
SmallVector<PHINode *, 8> Stack;
Stack.push_back(&I);
bool Cycle = false;
while (!Stack.empty()) {
auto *Phi = Stack.pop_back_val();
if (Visited.find(Phi) != Visited.end()) {
Cycle = true;
continue;
}
Visited.insert(Phi);
for (auto U : Phi->users()) {
auto *PhiUser = dyn_cast<PHINode>(U);
if (!PhiUser)
return;
Stack.push_back(PhiUser);
}
}

if (!Cycle)
return;

for (auto *Inst : Visited) {
Inst->replaceAllUsesWith(UndefValue::get(Inst->getType()));
Inst->eraseFromParent();
}

Changed = true;
}
11 changes: 0 additions & 11 deletions IGC/VectorCompiler/test/GenXGEPLowering/fold-ptrtoint.ll
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,3 @@ label: ; preds = %entry
%splat = shufflevector <16 x i64> %ins, <16 x i64> undef, <16 x i32> zeroinitializer
ret void
}

; CHECK-LABEL: @test_bitcast_vector_to_scalar
define i64 @test_bitcast_vector_to_scalar(<1 x i8*> %vptr) {
%ptr = bitcast <1 x i8*> %vptr to i8*
%gep = getelementptr i8, i8* %ptr, i32 123
%addr = ptrtoint i8* %gep to i64
; CHECK: [[PTI:%[^ ]+]] = ptrtoint i8* %ptr to i64
; CHECK: [[ADD:%[^ ]+]] = add i64 [[PTI]], 123
; CHECK: ret i64 [[ADD]]
ret i64 %addr
}
41 changes: 41 additions & 0 deletions IGC/VectorCompiler/test/PatternMatch/phi_cycle.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
;=========================== begin_copyright_notice ============================
;
; Copyright (C) 2023 Intel Corporation
;
; SPDX-License-Identifier: MIT
;
;============================ end_copyright_notice =============================
;
; RUN: opt %use_old_pass_manager% -GenXPatternMatch -march=genx64 -mcpu=Gen9 -mtriple=spir64-unknown-unknown -S < %s | FileCheck %s
; CHECK-NOT: %bad1 = phi i32 [ undef, %entry ], [ %bad2, %loop.end ]
; CHECK-NOT: %bad2 = phi i32 [ %bad1, %true ], [ %mul, %false ]

define i32 @test(i32 %a, i32 %n) {
entry:
br label %loop

loop:
%bad1 = phi i32 [ undef, %entry ], [ %bad2, %loop.end ]
%res = phi i32 [ 0, %entry ], [ %res.next, %loop.end ]
%i = phi i32 [ 0, %entry ], [ %i.next, %loop.end ]
%if.cond = icmp slt i32 %i, 10
br i1 %if.cond, label %true, label %false

true:
%add = add i32 %res, %a
br label %loop.end

false:
%mul = mul i32 %res, %a
br label %loop.end

loop.end:
%bad2 = phi i32 [ %bad1, %true ], [ %mul, %false ]
%res.next = phi i32 [ %add, %true ], [ %mul, %false ]
%i.next = add i32 %i, 1
%loop.cond = icmp slt i32 %i.next, %n
br i1 %loop.cond, label %loop, label %exit

exit:
ret i32 %res.next
}

0 comments on commit 7924e15

Please sign in to comment.