Skip to content

Commit d8bc546

Browse files
committed
[InstCombine] Fix phi or icmp fold with disjoint flag
We're changing the operand of the or here, such that the disjoint flag may no longer hold. Clear it.
1 parent b7af286 commit d8bc546

File tree

2 files changed

+9
-4
lines changed

2 files changed

+9
-4
lines changed

llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,13 +1460,16 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
14601460
// icmp(or(phi)) can equally be replaced with any non-zero constant as the
14611461
// "or" will only add bits.
14621462
if (!PN.hasNUsesOrMore(3)) {
1463-
bool AllUsesOfPhiEndsInCmp = all_of(PN.users(), [&PN](User *U) {
1463+
SmallVector<Instruction *> DropPoisonFlags;
1464+
bool AllUsesOfPhiEndsInCmp = all_of(PN.users(), [&](User *U) {
14641465
auto *CmpInst = dyn_cast<ICmpInst>(U);
14651466
if (!CmpInst) {
14661467
// This is always correct as OR only add bits and we are checking
14671468
// against 0.
1468-
if (U->hasOneUse() && match(U, m_c_Or(m_Specific(&PN), m_Value())))
1469+
if (U->hasOneUse() && match(U, m_c_Or(m_Specific(&PN), m_Value()))) {
1470+
DropPoisonFlags.push_back(cast<Instruction>(U));
14691471
CmpInst = dyn_cast<ICmpInst>(U->user_back());
1472+
}
14701473
}
14711474
if (!CmpInst || !isa<IntegerType>(PN.getType()) ||
14721475
!CmpInst->isEquality() || !match(CmpInst->getOperand(1), m_Zero())) {
@@ -1486,6 +1489,9 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
14861489
NonZeroConst = getAnyNonZeroConstInt(PN);
14871490
if (NonZeroConst != VA) {
14881491
replaceOperand(PN, I, NonZeroConst);
1492+
// The "disjoint" flag may no longer hold after the transform.
1493+
for (Instruction *I : DropPoisonFlags)
1494+
I->dropPoisonGeneratingFlags();
14891495
MadeChange = true;
14901496
}
14911497
}

llvm/test/Transforms/InstCombine/phi.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,6 @@ if.end:
14211421
ret i1 %cmp1
14221422
}
14231423

1424-
; FIXME: This is a miscompile.
14251424
define i1 @phi_knownnonzero_eq_or_disjoint_icmp(i32 %n, i32 %s, ptr %P, i32 %val) {
14261425
; CHECK-LABEL: @phi_knownnonzero_eq_or_disjoint_icmp(
14271426
; CHECK-NEXT: entry:
@@ -1431,7 +1430,7 @@ define i1 @phi_knownnonzero_eq_or_disjoint_icmp(i32 %n, i32 %s, ptr %P, i32 %val
14311430
; CHECK-NEXT: br label [[IF_END]]
14321431
; CHECK: if.end:
14331432
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
1434-
; CHECK-NEXT: [[ORPHI:%.*]] = or disjoint i32 [[PHI]], [[VAL:%.*]]
1433+
; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[PHI]], [[VAL:%.*]]
14351434
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ORPHI]], 0
14361435
; CHECK-NEXT: ret i1 [[CMP1]]
14371436
;

0 commit comments

Comments
 (0)