Skip to content

Commit 02b72f5

Browse files
committed
Revert "Recommit "[SCCP] Remove forcedconstant, go to overdefined instead""
This reverts commit bb310b3. This breaks the stage2 ASan build, see: https://bugs.llvm.org/show_bug.cgi?id=44898 rdar://59431448
1 parent 47abb43 commit 02b72f5

File tree

14 files changed

+349
-648
lines changed

14 files changed

+349
-648
lines changed

llvm/lib/Transforms/Scalar/SCCP.cpp

Lines changed: 235 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,19 @@ class LatticeVal {
8585
/// constant - This LLVM Value has a specific constant value.
8686
constant,
8787

88+
/// forcedconstant - This LLVM Value was thought to be undef until
89+
/// ResolvedUndefsIn. This is treated just like 'constant', but if merged
90+
/// with another (different) constant, it goes to overdefined, instead of
91+
/// asserting.
92+
forcedconstant,
93+
8894
/// overdefined - This instruction is not known to be constant, and we know
8995
/// it has a value.
9096
overdefined
9197
};
9298

9399
/// Val: This stores the current lattice value along with the Constant* for
94-
/// the constant if this is a 'constant' value.
100+
/// the constant if this is a 'constant' or 'forcedconstant' value.
95101
PointerIntPair<Constant *, 2, LatticeValueTy> Val;
96102

97103
LatticeValueTy getLatticeValue() const {
@@ -103,7 +109,9 @@ class LatticeVal {
103109

104110
bool isUnknown() const { return getLatticeValue() == unknown; }
105111

106-
bool isConstant() const { return getLatticeValue() == constant; }
112+
bool isConstant() const {
113+
return getLatticeValue() == constant || getLatticeValue() == forcedconstant;
114+
}
107115

108116
bool isOverdefined() const { return getLatticeValue() == overdefined; }
109117

@@ -123,15 +131,26 @@ class LatticeVal {
123131

124132
/// markConstant - Return true if this is a change in status.
125133
bool markConstant(Constant *V) {
126-
if (getLatticeValue() == constant) { // Constant
134+
if (getLatticeValue() == constant) { // Constant but not forcedconstant.
127135
assert(getConstant() == V && "Marking constant with different value");
128136
return false;
129137
}
130138

131-
assert(isUnknown());
132-
Val.setInt(constant);
133-
assert(V && "Marking constant with NULL");
134-
Val.setPointer(V);
139+
if (isUnknown()) {
140+
Val.setInt(constant);
141+
assert(V && "Marking constant with NULL");
142+
Val.setPointer(V);
143+
} else {
144+
assert(getLatticeValue() == forcedconstant &&
145+
"Cannot move from overdefined to constant!");
146+
// Stay at forcedconstant if the constant is the same.
147+
if (V == getConstant()) return false;
148+
149+
// Otherwise, we go to overdefined. Assumptions made based on the
150+
// forced value are possibly wrong. Assuming this is another constant
151+
// could expose a contradiction.
152+
Val.setInt(overdefined);
153+
}
135154
return true;
136155
}
137156

@@ -151,6 +170,12 @@ class LatticeVal {
151170
return nullptr;
152171
}
153172

173+
void markForcedConstant(Constant *V) {
174+
assert(isUnknown() && "Can't force a defined value!");
175+
Val.setInt(forcedconstant);
176+
Val.setPointer(V);
177+
}
178+
154179
ValueLatticeElement toValueLattice() const {
155180
if (isOverdefined())
156181
return ValueLatticeElement::getOverdefined();
@@ -396,7 +421,7 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
396421
}
397422

398423
private:
399-
// pushToWorkList - Helper for markConstant/markOverdefined
424+
// pushToWorkList - Helper for markConstant/markForcedConstant/markOverdefined
400425
void pushToWorkList(LatticeVal &IV, Value *V) {
401426
if (IV.isOverdefined())
402427
return OverdefinedInstWorkList.push_back(V);
@@ -418,6 +443,14 @@ class SCCPSolver : public InstVisitor<SCCPSolver> {
418443
return markConstant(ValueState[V], V, C);
419444
}
420445

446+
void markForcedConstant(Value *V, Constant *C) {
447+
assert(!V->getType()->isStructTy() && "structs should use mergeInValue");
448+
LatticeVal &IV = ValueState[V];
449+
IV.markForcedConstant(C);
450+
LLVM_DEBUG(dbgs() << "markForcedConstant: " << *C << ": " << *V << '\n');
451+
pushToWorkList(IV, V);
452+
}
453+
421454
// markOverdefined - Make a value be marked as "overdefined". If the
422455
// value is not already overdefined, add it to the overdefined instruction
423456
// work list so that the users of the instruction are updated later.
@@ -963,6 +996,8 @@ void SCCPSolver::visitUnaryOperator(Instruction &I) {
963996
LatticeVal V0State = getValueState(I.getOperand(0));
964997

965998
LatticeVal &IV = ValueState[&I];
999+
if (IV.isOverdefined()) return;
1000+
9661001
if (V0State.isConstant()) {
9671002
Constant *C = ConstantExpr::get(I.getOpcode(), V0State.getConstant());
9681003

@@ -997,10 +1032,8 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
9971032
}
9981033

9991034
// If something is undef, wait for it to resolve.
1000-
if (!V1State.isOverdefined() && !V2State.isOverdefined()) {
1001-
1035+
if (!V1State.isOverdefined() && !V2State.isOverdefined())
10021036
return;
1003-
}
10041037

10051038
// Otherwise, one of our operands is overdefined. Try to produce something
10061039
// better than overdefined with some tricks.
@@ -1021,6 +1054,7 @@ void SCCPSolver::visitBinaryOperator(Instruction &I) {
10211054
NonOverdefVal = &V1State;
10221055
else if (!V2State.isOverdefined())
10231056
NonOverdefVal = &V2State;
1057+
10241058
if (NonOverdefVal) {
10251059
if (NonOverdefVal->isUnknown())
10261060
return;
@@ -1140,6 +1174,7 @@ void SCCPSolver::visitLoadInst(LoadInst &I) {
11401174
if (PtrVal.isUnknown()) return; // The pointer is not resolved yet!
11411175

11421176
LatticeVal &IV = ValueState[&I];
1177+
if (IV.isOverdefined()) return;
11431178

11441179
if (!PtrVal.isConstant() || I.isVolatile())
11451180
return (void)markOverdefined(IV, &I);
@@ -1414,11 +1449,11 @@ void SCCPSolver::Solve() {
14141449
/// constraints on the condition of the branch, as that would impact other users
14151450
/// of the value.
14161451
///
1417-
/// This scan also checks for values that use undefs. It conservatively marks
1418-
/// them as overdefined.
1452+
/// This scan also checks for values that use undefs, whose results are actually
1453+
/// defined. For example, 'zext i8 undef to i32' should produce all zeros
1454+
/// conservatively, as "(zext i8 X -> i32) & 0xFF00" must always return zero,
1455+
/// even if X isn't defined.
14191456
bool SCCPSolver::ResolvedUndefsIn(Function &F) {
1420-
// Keep track of values that dependent on an yet unknown tracked function call. It only makes sense to resolve them once the call is resolved.
1421-
SmallPtrSet<Value *, 8> DependsOnSkipped;
14221457
for (BasicBlock &BB : F) {
14231458
if (!BBExecutable.count(&BB))
14241459
continue;
@@ -1433,15 +1468,14 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
14331468
// Tracked calls must never be marked overdefined in ResolvedUndefsIn.
14341469
if (CallSite CS = CallSite(&I))
14351470
if (Function *F = CS.getCalledFunction())
1436-
if (MRVFunctionsTracked.count(F)) {
1437-
DependsOnSkipped.insert(&I);
1471+
if (MRVFunctionsTracked.count(F))
14381472
continue;
1439-
}
14401473

14411474
// extractvalue and insertvalue don't need to be marked; they are
14421475
// tracked as precisely as their operands.
14431476
if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
14441477
continue;
1478+
14451479
// Send the results of everything else to overdefined. We could be
14461480
// more precise than this but it isn't worth bothering.
14471481
for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
@@ -1461,22 +1495,195 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
14611495
// 2. It could be constant-foldable.
14621496
// Because of the way we solve return values, tracked calls must
14631497
// never be marked overdefined in ResolvedUndefsIn.
1464-
if (CallSite CS = CallSite(&I))
1498+
if (CallSite CS = CallSite(&I)) {
14651499
if (Function *F = CS.getCalledFunction())
1466-
if (TrackedRetVals.count(F)) {
1467-
DependsOnSkipped.insert(&I);
1500+
if (TrackedRetVals.count(F))
14681501
continue;
1469-
}
14701502

1471-
// Skip instructions that depend on results of calls we skipped earlier. Otherwise we might mark I as overdefined to early when we would end up discovering a constant value for I, if the call later resolves to a constant.
1472-
if (any_of(I.operands(), [&DependsOnSkipped](Value *V) {
1473-
return DependsOnSkipped.find(V) != DependsOnSkipped.end(); })) {
1474-
DependsOnSkipped.insert(&I);
1503+
// If the call is constant-foldable, we mark it overdefined because
1504+
// we do not know what return values are valid.
1505+
markOverdefined(&I);
1506+
return true;
1507+
}
1508+
1509+
// extractvalue is safe; check here because the argument is a struct.
1510+
if (isa<ExtractValueInst>(I))
14751511
continue;
1512+
1513+
// Compute the operand LatticeVals, for convenience below.
1514+
// Anything taking a struct is conservatively assumed to require
1515+
// overdefined markings.
1516+
if (I.getOperand(0)->getType()->isStructTy()) {
1517+
markOverdefined(&I);
1518+
return true;
1519+
}
1520+
LatticeVal Op0LV = getValueState(I.getOperand(0));
1521+
LatticeVal Op1LV;
1522+
if (I.getNumOperands() == 2) {
1523+
if (I.getOperand(1)->getType()->isStructTy()) {
1524+
markOverdefined(&I);
1525+
return true;
1526+
}
1527+
1528+
Op1LV = getValueState(I.getOperand(1));
14761529
}
1530+
// If this is an instructions whose result is defined even if the input is
1531+
// not fully defined, propagate the information.
1532+
Type *ITy = I.getType();
1533+
switch (I.getOpcode()) {
1534+
case Instruction::Add:
1535+
case Instruction::Sub:
1536+
case Instruction::Trunc:
1537+
case Instruction::FPTrunc:
1538+
case Instruction::BitCast:
1539+
break; // Any undef -> undef
1540+
case Instruction::FSub:
1541+
case Instruction::FAdd:
1542+
case Instruction::FMul:
1543+
case Instruction::FDiv:
1544+
case Instruction::FRem:
1545+
// Floating-point binary operation: be conservative.
1546+
if (Op0LV.isUnknown() && Op1LV.isUnknown())
1547+
markForcedConstant(&I, Constant::getNullValue(ITy));
1548+
else
1549+
markOverdefined(&I);
1550+
return true;
1551+
case Instruction::FNeg:
1552+
break; // fneg undef -> undef
1553+
case Instruction::ZExt:
1554+
case Instruction::SExt:
1555+
case Instruction::FPToUI:
1556+
case Instruction::FPToSI:
1557+
case Instruction::FPExt:
1558+
case Instruction::PtrToInt:
1559+
case Instruction::IntToPtr:
1560+
case Instruction::SIToFP:
1561+
case Instruction::UIToFP:
1562+
// undef -> 0; some outputs are impossible
1563+
markForcedConstant(&I, Constant::getNullValue(ITy));
1564+
return true;
1565+
case Instruction::Mul:
1566+
case Instruction::And:
1567+
// Both operands undef -> undef
1568+
if (Op0LV.isUnknown() && Op1LV.isUnknown())
1569+
break;
1570+
// undef * X -> 0. X could be zero.
1571+
// undef & X -> 0. X could be zero.
1572+
markForcedConstant(&I, Constant::getNullValue(ITy));
1573+
return true;
1574+
case Instruction::Or:
1575+
// Both operands undef -> undef
1576+
if (Op0LV.isUnknown() && Op1LV.isUnknown())
1577+
break;
1578+
// undef | X -> -1. X could be -1.
1579+
markForcedConstant(&I, Constant::getAllOnesValue(ITy));
1580+
return true;
1581+
case Instruction::Xor:
1582+
// undef ^ undef -> 0; strictly speaking, this is not strictly
1583+
// necessary, but we try to be nice to people who expect this
1584+
// behavior in simple cases
1585+
if (Op0LV.isUnknown() && Op1LV.isUnknown()) {
1586+
markForcedConstant(&I, Constant::getNullValue(ITy));
1587+
return true;
1588+
}
1589+
// undef ^ X -> undef
1590+
break;
1591+
case Instruction::SDiv:
1592+
case Instruction::UDiv:
1593+
case Instruction::SRem:
1594+
case Instruction::URem:
1595+
// X / undef -> undef. No change.
1596+
// X % undef -> undef. No change.
1597+
if (Op1LV.isUnknown()) break;
1598+
1599+
// X / 0 -> undef. No change.
1600+
// X % 0 -> undef. No change.
1601+
if (Op1LV.isConstant() && Op1LV.getConstant()->isZeroValue())
1602+
break;
1603+
1604+
// undef / X -> 0. X could be maxint.
1605+
// undef % X -> 0. X could be 1.
1606+
markForcedConstant(&I, Constant::getNullValue(ITy));
1607+
return true;
1608+
case Instruction::AShr:
1609+
// X >>a undef -> undef.
1610+
if (Op1LV.isUnknown()) break;
1611+
1612+
// Shifting by the bitwidth or more is undefined.
1613+
if (Op1LV.isConstant()) {
1614+
if (auto *ShiftAmt = Op1LV.getConstantInt())
1615+
if (ShiftAmt->getLimitedValue() >=
1616+
ShiftAmt->getType()->getScalarSizeInBits())
1617+
break;
1618+
}
14771619

1478-
markOverdefined(&I);
1479-
return true;
1620+
// undef >>a X -> 0
1621+
markForcedConstant(&I, Constant::getNullValue(ITy));
1622+
return true;
1623+
case Instruction::LShr:
1624+
case Instruction::Shl:
1625+
// X << undef -> undef.
1626+
// X >> undef -> undef.
1627+
if (Op1LV.isUnknown()) break;
1628+
1629+
// Shifting by the bitwidth or more is undefined.
1630+
if (Op1LV.isConstant()) {
1631+
if (auto *ShiftAmt = Op1LV.getConstantInt())
1632+
if (ShiftAmt->getLimitedValue() >=
1633+
ShiftAmt->getType()->getScalarSizeInBits())
1634+
break;
1635+
}
1636+
1637+
// undef << X -> 0
1638+
// undef >> X -> 0
1639+
markForcedConstant(&I, Constant::getNullValue(ITy));
1640+
return true;
1641+
case Instruction::Select:
1642+
Op1LV = getValueState(I.getOperand(1));
1643+
// undef ? X : Y -> X or Y. There could be commonality between X/Y.
1644+
if (Op0LV.isUnknown()) {
1645+
if (!Op1LV.isConstant()) // Pick the constant one if there is any.
1646+
Op1LV = getValueState(I.getOperand(2));
1647+
} else if (Op1LV.isUnknown()) {
1648+
// c ? undef : undef -> undef. No change.
1649+
Op1LV = getValueState(I.getOperand(2));
1650+
if (Op1LV.isUnknown())
1651+
break;
1652+
// Otherwise, c ? undef : x -> x.
1653+
} else {
1654+
// Leave Op1LV as Operand(1)'s LatticeValue.
1655+
}
1656+
1657+
if (Op1LV.isConstant())
1658+
markForcedConstant(&I, Op1LV.getConstant());
1659+
else
1660+
markOverdefined(&I);
1661+
return true;
1662+
case Instruction::Load:
1663+
// A load here means one of two things: a load of undef from a global,
1664+
// a load from an unknown pointer. Either way, having it return undef
1665+
// is okay.
1666+
break;
1667+
case Instruction::ICmp:
1668+
// X == undef -> undef. Other comparisons get more complicated.
1669+
Op0LV = getValueState(I.getOperand(0));
1670+
Op1LV = getValueState(I.getOperand(1));
1671+
1672+
if ((Op0LV.isUnknown() || Op1LV.isUnknown()) &&
1673+
cast<ICmpInst>(&I)->isEquality())
1674+
break;
1675+
markOverdefined(&I);
1676+
return true;
1677+
case Instruction::Call:
1678+
case Instruction::Invoke:
1679+
case Instruction::CallBr:
1680+
llvm_unreachable("Call-like instructions should have be handled early");
1681+
default:
1682+
// If we don't know what should happen here, conservatively mark it
1683+
// overdefined.
1684+
markOverdefined(&I);
1685+
return true;
1686+
}
14801687
}
14811688

14821689
// Check to see if we have a branch or switch on an undefined value. If so

0 commit comments

Comments
 (0)