Skip to content

[SimplifyCFG] Improve FoldTwoEntryPHINode when one of phi values is undef #69021

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3376,7 +3376,8 @@ static bool FoldCondBranchOnValueKnownInPredecessor(BranchInst *BI,
/// Given a BB that starts with the specified two-entry PHI node,
/// see if we can eliminate it.
static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
DomTreeUpdater *DTU, const DataLayout &DL) {
DomTreeUpdater *DTU, const DataLayout &DL,
AssumptionCache *AC) {
// Ok, this is a two entry PHI node. Check to see if this is a simple "if
// statement", which has a very simple dominance structure. Basically, we
// are trying to find the condition that is being branched on, which
Expand Down Expand Up @@ -3543,9 +3544,20 @@ static bool FoldTwoEntryPHINode(PHINode *PN, const TargetTransformInfo &TTI,
Value *TrueVal = PN->getIncomingValueForBlock(IfTrue);
Value *FalseVal = PN->getIncomingValueForBlock(IfFalse);

Value *Sel = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI);
PN->replaceAllUsesWith(Sel);
Sel->takeName(PN);
Value *ReplaceVal = nullptr;
if (isa<UndefValue>(TrueVal) &&
isGuaranteedNotToBePoison(FalseVal, AC, IfFalse->getTerminator(),
/*DT*/ nullptr, /*Depth*/ 0)) {
ReplaceVal = FalseVal;
} else if (isa<UndefValue>(FalseVal) &&
isGuaranteedNotToBePoison(TrueVal, AC, IfTrue->getTerminator(),
/*DT*/ nullptr, /*Depth*/ 0)) {
ReplaceVal = TrueVal;
} else {
ReplaceVal = Builder.CreateSelect(IfCond, TrueVal, FalseVal, "", DomBI);
ReplaceVal->takeName(PN);
}
PN->replaceAllUsesWith(ReplaceVal);
PN->eraseFromParent();
}

Expand Down Expand Up @@ -7406,7 +7418,7 @@ bool SimplifyCFGOpt::simplifyOnce(BasicBlock *BB) {
// eliminate it, do so now.
if (auto *PN = dyn_cast<PHINode>(BB->begin()))
if (PN->getNumIncomingValues() == 2)
if (FoldTwoEntryPHINode(PN, TTI, DTU, DL))
if (FoldTwoEntryPHINode(PN, TTI, DTU, DL, Options.AC))
return true;
}

Expand Down
50 changes: 50 additions & 0 deletions llvm/test/Transforms/SimplifyCFG/pr67342.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3
; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s

; Tests from PR67342
define i16 @test1(i32 %err) {
; CHECK-LABEL: define i16 @test1(
; CHECK-SAME: i32 [[ERR:%.*]]) {
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[_3:%.*]] = icmp slt i32 [[ERR]], 0
; CHECK-NEXT: [[OK:%.*]] = trunc i32 [[ERR]] to i16
; CHECK-NEXT: ret i16 [[OK]]
;
%_3 = icmp slt i32 %err, 0
br i1 %_3, label %bb1, label %bb2

bb2:
%ok = trunc i32 %err to i16
br label %bb3

bb1:
br label %bb3

bb3:
%r.sroa.3.0 = phi i16 [ undef, %bb1 ], [ %ok, %bb2 ]
ret i16 %r.sroa.3.0
}

; commuted test
define i16 @test2(i32 %err) {
; CHECK-LABEL: define i16 @test2(
; CHECK-SAME: i32 [[ERR:%.*]]) {
; CHECK-NEXT: bb3:
; CHECK-NEXT: [[_3:%.*]] = icmp slt i32 [[ERR]], 0
; CHECK-NEXT: [[OK:%.*]] = trunc i32 [[ERR]] to i16
; CHECK-NEXT: ret i16 [[OK]]
;
%_3 = icmp slt i32 %err, 0
br i1 %_3, label %bb1, label %bb2

bb2:
br label %bb3

bb1:
%ok = trunc i32 %err to i16
br label %bb3

bb3:
%r.sroa.3.0 = phi i16 [ %ok, %bb1 ], [ undef, %bb2 ]
ret i16 %r.sroa.3.0
}