summaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/InstCombine
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-10-21 11:01:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-10-21 11:01:02 +0000
commite6b732792813cf49a23ba2f780c55f8d3279183e (patch)
tree95a0ed209e2fb21f748e1151d801664be5790a8d /llvm/lib/Transforms/InstCombine
parent0370629593a68f2e04a9710d201d120a2ce437d4 (diff)
Diffstat (limited to 'llvm/lib/Transforms/InstCombine')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index f9caa4da4493..3222e8298c3f 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -926,9 +926,11 @@ static Value *foldIsPowerOf2OrZero(ICmpInst *Cmp0, ICmpInst *Cmp1, bool IsAnd,
}
/// Reduce a pair of compares that check if a value has exactly 1 bit set.
-/// Also used for logical and/or, must be poison safe.
+/// Also used for logical and/or, must be poison safe if range attributes are
+/// dropped.
static Value *foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
- InstCombiner::BuilderTy &Builder) {
+ InstCombiner::BuilderTy &Builder,
+ InstCombinerImpl &IC) {
// Handle 'and' / 'or' commutation: make the equality check the first operand.
if (JoinedByAnd && Cmp1->getPredicate() == ICmpInst::ICMP_NE)
std::swap(Cmp0, Cmp1);
@@ -942,7 +944,10 @@ static Value *foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
match(Cmp1, m_ICmp(Pred1, m_Intrinsic<Intrinsic::ctpop>(m_Specific(X)),
m_SpecificInt(2))) &&
Pred0 == ICmpInst::ICMP_NE && Pred1 == ICmpInst::ICMP_ULT) {
- Value *CtPop = Cmp1->getOperand(0);
+ auto *CtPop = cast<Instruction>(Cmp1->getOperand(0));
+ // Drop range attributes and re-infer them in the next iteration.
+ CtPop->dropPoisonGeneratingAnnotations();
+ IC.addToWorklist(CtPop);
return Builder.CreateICmpEQ(CtPop, ConstantInt::get(CtPop->getType(), 1));
}
// (X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1
@@ -950,7 +955,10 @@ static Value *foldIsPowerOf2(ICmpInst *Cmp0, ICmpInst *Cmp1, bool JoinedByAnd,
match(Cmp1, m_ICmp(Pred1, m_Intrinsic<Intrinsic::ctpop>(m_Specific(X)),
m_SpecificInt(1))) &&
Pred0 == ICmpInst::ICMP_EQ && Pred1 == ICmpInst::ICMP_UGT) {
- Value *CtPop = Cmp1->getOperand(0);
+ auto *CtPop = cast<Instruction>(Cmp1->getOperand(0));
+ // Drop range attributes and re-infer them in the next iteration.
+ CtPop->dropPoisonGeneratingAnnotations();
+ IC.addToWorklist(CtPop);
return Builder.CreateICmpNE(CtPop, ConstantInt::get(CtPop->getType(), 1));
}
return nullptr;
@@ -3347,7 +3355,7 @@ Value *InstCombinerImpl::foldAndOrOfICmps(ICmpInst *LHS, ICmpInst *RHS,
if (Value *V = foldSignedTruncationCheck(LHS, RHS, I, Builder))
return V;
- if (Value *V = foldIsPowerOf2(LHS, RHS, IsAnd, Builder))
+ if (Value *V = foldIsPowerOf2(LHS, RHS, IsAnd, Builder, *this))
return V;
if (Value *V = foldPowerOf2AndShiftedMask(LHS, RHS, IsAnd, Builder))