[llvm] d8bc546 - [InstCombine] Fix phi or icmp fold with disjoint flag
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 30 07:23:15 PST 2023
Author: Nikita Popov
Date: 2023-11-30T16:23:00+01:00
New Revision: d8bc5465330474b80c02ca37e76a9a51245f1d79
URL: https://github.com/llvm/llvm-project/commit/d8bc5465330474b80c02ca37e76a9a51245f1d79
DIFF: https://github.com/llvm/llvm-project/commit/d8bc5465330474b80c02ca37e76a9a51245f1d79.diff
LOG: [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.
Added:
Modified:
llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
llvm/test/Transforms/InstCombine/phi.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
index f8507e4929788c2..20b34c1379d575d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombinePHI.cpp
@@ -1460,13 +1460,16 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
// icmp(or(phi)) can equally be replaced with any non-zero constant as the
// "or" will only add bits.
if (!PN.hasNUsesOrMore(3)) {
- bool AllUsesOfPhiEndsInCmp = all_of(PN.users(), [&PN](User *U) {
+ SmallVector<Instruction *> DropPoisonFlags;
+ bool AllUsesOfPhiEndsInCmp = all_of(PN.users(), [&](User *U) {
auto *CmpInst = dyn_cast<ICmpInst>(U);
if (!CmpInst) {
// This is always correct as OR only add bits and we are checking
// against 0.
- if (U->hasOneUse() && match(U, m_c_Or(m_Specific(&PN), m_Value())))
+ if (U->hasOneUse() && match(U, m_c_Or(m_Specific(&PN), m_Value()))) {
+ DropPoisonFlags.push_back(cast<Instruction>(U));
CmpInst = dyn_cast<ICmpInst>(U->user_back());
+ }
}
if (!CmpInst || !isa<IntegerType>(PN.getType()) ||
!CmpInst->isEquality() || !match(CmpInst->getOperand(1), m_Zero())) {
@@ -1486,6 +1489,9 @@ Instruction *InstCombinerImpl::visitPHINode(PHINode &PN) {
NonZeroConst = getAnyNonZeroConstInt(PN);
if (NonZeroConst != VA) {
replaceOperand(PN, I, NonZeroConst);
+ // The "disjoint" flag may no longer hold after the transform.
+ for (Instruction *I : DropPoisonFlags)
+ I->dropPoisonGeneratingFlags();
MadeChange = true;
}
}
diff --git a/llvm/test/Transforms/InstCombine/phi.ll b/llvm/test/Transforms/InstCombine/phi.ll
index 787cad287406c6b..90818771675b2ed 100644
--- a/llvm/test/Transforms/InstCombine/phi.ll
+++ b/llvm/test/Transforms/InstCombine/phi.ll
@@ -1421,7 +1421,6 @@ if.end:
ret i1 %cmp1
}
-; FIXME: This is a miscompile.
define i1 @phi_knownnonzero_eq_or_disjoint_icmp(i32 %n, i32 %s, ptr %P, i32 %val) {
; CHECK-LABEL: @phi_knownnonzero_eq_or_disjoint_icmp(
; CHECK-NEXT: entry:
@@ -1431,7 +1430,7 @@ define i1 @phi_knownnonzero_eq_or_disjoint_icmp(i32 %n, i32 %s, ptr %P, i32 %val
; CHECK-NEXT: br label [[IF_END]]
; CHECK: if.end:
; CHECK-NEXT: [[PHI:%.*]] = phi i32 [ 1, [[IF_THEN]] ], [ [[N]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[ORPHI:%.*]] = or disjoint i32 [[PHI]], [[VAL:%.*]]
+; CHECK-NEXT: [[ORPHI:%.*]] = or i32 [[PHI]], [[VAL:%.*]]
; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[ORPHI]], 0
; CHECK-NEXT: ret i1 [[CMP1]]
;
More information about the llvm-commits
mailing list