Skip to content

Commit efe45cf

Browse files
committed
test
1 parent d7e40f3 commit efe45cf

File tree

3 files changed

+114
-27
lines changed

3 files changed

+114
-27
lines changed

llvm/include/llvm/Analysis/ValueTracking.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,14 @@ findValuesAffectedByCondition(Value *Cond, bool IsAssume,
10241024
LLVM_ABI Value *stripNullTest(Value *V);
10251025
LLVM_ABI const Value *stripNullTest(const Value *V);
10261026

1027+
/// Enumerates all possible values of V.
1028+
/// Return true if the result is complete.
1029+
/// Otherwise, the result is invalid.
1030+
LLVM_ABI bool
1031+
collectPossibleValues(const Value *V,
1032+
SmallPtrSetImpl<const Constant *> &Constants,
1033+
unsigned MaxCount, unsigned Depth = 0);
1034+
10271035
} // end namespace llvm
10281036

10291037
#endif // LLVM_ANALYSIS_VALUETRACKING_H

llvm/lib/Analysis/ValueTracking.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10405,3 +10405,69 @@ const Value *llvm::stripNullTest(const Value *V) {
1040510405
Value *llvm::stripNullTest(Value *V) {
1040610406
return const_cast<Value *>(stripNullTest(const_cast<const Value *>(V)));
1040710407
}
10408+
10409+
bool llvm::collectPossibleValues(const Value *V,
10410+
SmallPtrSetImpl<const Constant *> &Constants,
10411+
unsigned MaxCount, unsigned Depth) {
10412+
auto Add = [&](const Constant *C) -> bool {
10413+
if (Constants.contains(C))
10414+
return true;
10415+
if (Constants.size() == MaxCount)
10416+
return false;
10417+
Constants.insert(C);
10418+
return true;
10419+
};
10420+
if (auto *C = dyn_cast<Constant>(V))
10421+
return Add(C);
10422+
if (Depth++ == MaxAnalysisRecursionDepth)
10423+
return false;
10424+
auto *Inst = dyn_cast<Instruction>(V);
10425+
if (!Inst)
10426+
return false;
10427+
Type *Ty = Inst->getType();
10428+
switch (Inst->getOpcode()) {
10429+
case Instruction::Select: {
10430+
if (!collectPossibleValues(Inst->getOperand(0), Constants, Depth))
10431+
return false;
10432+
if (!collectPossibleValues(Inst->getOperand(1), Constants, Depth))
10433+
return false;
10434+
return true;
10435+
}
10436+
case Instruction::PHI: {
10437+
for (Value *IncomingValue : cast<PHINode>(Inst)->incoming_values()) {
10438+
if (IncomingValue == Inst)
10439+
continue;
10440+
if (auto *C = dyn_cast<Constant>(IncomingValue)) {
10441+
if (!Add(C))
10442+
return false;
10443+
continue;
10444+
}
10445+
return false;
10446+
}
10447+
return true;
10448+
}
10449+
case Instruction::And: {
10450+
const APInt *Bit;
10451+
if (match(Inst->getOperand(1), m_Power2(Bit))) {
10452+
Constant *Zero = ConstantInt::getNullValue(Ty);
10453+
Constant *BitVal = ConstantInt::get(Ty, *Bit);
10454+
return Add(Zero) && Add(BitVal);
10455+
}
10456+
break;
10457+
}
10458+
case Instruction::ZExt:
10459+
case Instruction::SExt: {
10460+
if (Inst->getOperand(0)->getType()->isIntegerTy(1)) {
10461+
Constant *Zero = ConstantInt::getNullValue(Ty);
10462+
Constant *One = ConstantInt::get(Ty, APInt(Ty->getScalarSizeInBits(),
10463+
isa<ZExtInst>(Inst) ? 1 : -1,
10464+
/*IsSigned=*/true));
10465+
return Add(Zero) && Add(One);
10466+
}
10467+
break;
10468+
}
10469+
default:
10470+
break;
10471+
}
10472+
return false;
10473+
}

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5990,6 +5990,8 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
59905990
const DataLayout &DL) {
59915991
Value *Cond = SI->getCondition();
59925992
KnownBits Known = computeKnownBits(Cond, DL, AC, SI);
5993+
SmallPtrSet<const Constant *, 4> KnownValues;
5994+
bool IsKnownValuesValid = collectPossibleValues(Cond, KnownValues, 4);
59935995

59945996
// We can also eliminate cases by determining that their values are outside of
59955997
// the limited range of the condition based on how many significant (non-sign)
@@ -6009,15 +6011,18 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
60096011
UniqueSuccessors.push_back(Successor);
60106012
++It->second;
60116013
}
6012-
const APInt &CaseVal = Case.getCaseValue()->getValue();
6014+
ConstantInt *CaseC = Case.getCaseValue();
6015+
const APInt &CaseVal = CaseC->getValue();
60136016
if (Known.Zero.intersects(CaseVal) || !Known.One.isSubsetOf(CaseVal) ||
6014-
(CaseVal.getSignificantBits() > MaxSignificantBitsInCond)) {
6015-
DeadCases.push_back(Case.getCaseValue());
6017+
(CaseVal.getSignificantBits() > MaxSignificantBitsInCond) ||
6018+
(IsKnownValuesValid && !KnownValues.contains(CaseC))) {
6019+
DeadCases.push_back(CaseC);
60166020
if (DTU)
60176021
--NumPerSuccessorCases[Successor];
60186022
LLVM_DEBUG(dbgs() << "SimplifyCFG: switch case " << CaseVal
60196023
<< " is dead.\n");
6020-
}
6024+
} else if (IsKnownValuesValid)
6025+
KnownValues.erase(CaseC);
60216026
}
60226027

60236028
// If we can prove that the cases must cover all possible values, the
@@ -6028,33 +6033,41 @@ static bool eliminateDeadSwitchCases(SwitchInst *SI, DomTreeUpdater *DTU,
60286033
const unsigned NumUnknownBits =
60296034
Known.getBitWidth() - (Known.Zero | Known.One).popcount();
60306035
assert(NumUnknownBits <= Known.getBitWidth());
6031-
if (HasDefault && DeadCases.empty() &&
6032-
NumUnknownBits < 64 /* avoid overflow */) {
6033-
uint64_t AllNumCases = 1ULL << NumUnknownBits;
6034-
if (SI->getNumCases() == AllNumCases) {
6036+
if (HasDefault && DeadCases.empty()) {
6037+
if (IsKnownValuesValid && all_of(KnownValues, IsaPred<UndefValue>)) {
60356038
createUnreachableSwitchDefault(SI, DTU);
60366039
return true;
60376040
}
6038-
// When only one case value is missing, replace default with that case.
6039-
// Eliminating the default branch will provide more opportunities for
6040-
// optimization, such as lookup tables.
6041-
if (SI->getNumCases() == AllNumCases - 1) {
6042-
assert(NumUnknownBits > 1 && "Should be canonicalized to a branch");
6043-
IntegerType *CondTy = cast<IntegerType>(Cond->getType());
6044-
if (CondTy->getIntegerBitWidth() > 64 ||
6045-
!DL.fitsInLegalInteger(CondTy->getIntegerBitWidth()))
6046-
return false;
60476041

6048-
uint64_t MissingCaseVal = 0;
6049-
for (const auto &Case : SI->cases())
6050-
MissingCaseVal ^= Case.getCaseValue()->getValue().getLimitedValue();
6051-
auto *MissingCase =
6052-
cast<ConstantInt>(ConstantInt::get(Cond->getType(), MissingCaseVal));
6053-
SwitchInstProfUpdateWrapper SIW(*SI);
6054-
SIW.addCase(MissingCase, SI->getDefaultDest(), SIW.getSuccessorWeight(0));
6055-
createUnreachableSwitchDefault(SI, DTU, /*RemoveOrigDefaultBlock*/ false);
6056-
SIW.setSuccessorWeight(0, 0);
6057-
return true;
6042+
if (NumUnknownBits < 64 /* avoid overflow */) {
6043+
uint64_t AllNumCases = 1ULL << NumUnknownBits;
6044+
if (SI->getNumCases() == AllNumCases) {
6045+
createUnreachableSwitchDefault(SI, DTU);
6046+
return true;
6047+
}
6048+
// When only one case value is missing, replace default with that case.
6049+
// Eliminating the default branch will provide more opportunities for
6050+
// optimization, such as lookup tables.
6051+
if (SI->getNumCases() == AllNumCases - 1) {
6052+
assert(NumUnknownBits > 1 && "Should be canonicalized to a branch");
6053+
IntegerType *CondTy = cast<IntegerType>(Cond->getType());
6054+
if (CondTy->getIntegerBitWidth() > 64 ||
6055+
!DL.fitsInLegalInteger(CondTy->getIntegerBitWidth()))
6056+
return false;
6057+
6058+
uint64_t MissingCaseVal = 0;
6059+
for (const auto &Case : SI->cases())
6060+
MissingCaseVal ^= Case.getCaseValue()->getValue().getLimitedValue();
6061+
auto *MissingCase = cast<ConstantInt>(
6062+
ConstantInt::get(Cond->getType(), MissingCaseVal));
6063+
SwitchInstProfUpdateWrapper SIW(*SI);
6064+
SIW.addCase(MissingCase, SI->getDefaultDest(),
6065+
SIW.getSuccessorWeight(0));
6066+
createUnreachableSwitchDefault(SI, DTU,
6067+
/*RemoveOrigDefaultBlock*/ false);
6068+
SIW.setSuccessorWeight(0, 0);
6069+
return true;
6070+
}
60586071
}
60596072
}
60606073

0 commit comments

Comments
 (0)