Skip to content

Commit 90d1ed7

Browse files
committed
add stripNullTest and update isKnownNonZero
1 parent b01dc16 commit 90d1ed7

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,11 @@ LLVM_ABI void
999999
findValuesAffectedByCondition(Value *Cond, bool IsAssume,
10001000
function_ref<void(Value *)> InsertAffected);
10011001

1002+
/// Returns the inner value X if the expression has the form f(X)
1003+
/// where f(X) == 0 if and only if X == 0, otherwise returns nullptr.
1004+
LLVM_ABI Value *stripNullTest(Value *V);
1005+
LLVM_ABI const Value *stripNullTest(const Value *V);
1006+
10021007
} // end namespace llvm
10031008

10041009
#endif // LLVM_ANALYSIS_VALUETRACKING_H

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,6 +3544,9 @@ bool isKnownNonZero(const Value *V, const APInt &DemandedElts,
35443544
isKnownNonNullFromDominatingCondition(V, Q.CxtI, Q.DT))
35453545
return true;
35463546

3547+
if (const Value *Stripped = stripNullTest(V))
3548+
return isKnownNonZero(Stripped, DemandedElts, Q, Depth + 1);
3549+
35473550
return false;
35483551
}
35493552

@@ -10193,3 +10196,26 @@ void llvm::findValuesAffectedByCondition(
1019310196
}
1019410197
}
1019510198
}
10199+
10200+
const Value *llvm::stripNullTest(const Value *V) {
10201+
// (X >> C) or/add (X & mask(C) != 0)
10202+
if (const auto *BO = dyn_cast<BinaryOperator>(V)) {
10203+
if (BO->getOpcode() == Instruction::Add ||
10204+
BO->getOpcode() == Instruction::Or) {
10205+
const Value *X;
10206+
const APInt *C1, *C2;
10207+
if (match(BO, m_c_BinOp(m_LShr(m_Value(X), m_APInt(C1)),
10208+
m_ZExt(m_SpecificICmp(
10209+
ICmpInst::ICMP_NE,
10210+
m_And(m_Deferred(X), m_LowBitMask(C2)),
10211+
m_Zero())))) &&
10212+
C2->popcount() == C1->getZExtValue())
10213+
return X;
10214+
}
10215+
}
10216+
return nullptr;
10217+
}
10218+
10219+
Value *llvm::stripNullTest(Value *V) {
10220+
return const_cast<Value *>(stripNullTest(const_cast<const Value *>(V)));
10221+
}

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1299,22 +1299,11 @@ Instruction *InstCombinerImpl::foldICmpWithZero(ICmpInst &Cmp) {
12991299
// will fold to a constant elsewhere.
13001300
}
13011301

1302-
// icmp eq/ne ((X >> C) or/add (X & mask(C) != 0)), 0 -> icmp eq/ne X, 0
1303-
if (ICmpInst::isEquality(Pred)) {
1304-
auto *BO = dyn_cast<BinaryOperator>(Cmp.getOperand(0));
1305-
Value *X;
1306-
const APInt *C1, *C2;
1307-
if (BO &&
1308-
(BO->getOpcode() == Instruction::Add ||
1309-
BO->getOpcode() == Instruction::Or) &&
1310-
match(BO, m_c_BinOp(m_LShr(m_Value(X), m_APInt(C1)),
1311-
m_ZExt(m_SpecificICmp(
1312-
ICmpInst::ICMP_NE,
1313-
m_And(m_Deferred(X), m_LowBitMask(C2)),
1314-
m_Zero())))) &&
1315-
C2->popcount() == C1->getZExtValue())
1316-
return new ICmpInst(Pred, X, ConstantInt::getNullValue(X->getType()));
1317-
}
1302+
// (icmp eq/ne f(X), 0) -> (icmp eq/ne X, 0)
1303+
// where f(X) == 0 if and only if X == 0
1304+
if (ICmpInst::isEquality(Pred))
1305+
if (Value *Stripped = stripNullTest(Cmp.getOperand(0)))
1306+
return new ICmpInst(Pred, Stripped, Cmp.getOperand(1));
13181307

13191308
return nullptr;
13201309
}

0 commit comments

Comments
 (0)