Index: lib/Transforms/Scalar/SCCP.cpp =================================================================== --- lib/Transforms/Scalar/SCCP.cpp +++ lib/Transforms/Scalar/SCCP.cpp @@ -65,19 +65,13 @@ /// constant - This LLVM Value has a specific constant value. constant, - /// forcedconstant - This LLVM Value was thought to be undef until - /// ResolvedUndefsIn. This is treated just like 'constant', but if merged - /// with another (different) constant, it goes to overdefined, instead of - /// asserting. - forcedconstant, - /// overdefined - This instruction is not known to be constant, and we know /// it has a value. overdefined }; /// Val: This stores the current lattice value along with the Constant* for - /// the constant if this is a 'constant' or 'forcedconstant' value. + /// the constant if this is a 'constant' value. PointerIntPair Val; LatticeValueTy getLatticeValue() const { @@ -88,9 +82,7 @@ LatticeVal() : Val(nullptr, unknown) {} bool isUnknown() const { return getLatticeValue() == unknown; } - bool isConstant() const { - return getLatticeValue() == constant || getLatticeValue() == forcedconstant; - } + bool isConstant() const { return getLatticeValue() == constant; } bool isOverdefined() const { return getLatticeValue() == overdefined; } Constant *getConstant() const { @@ -109,7 +101,7 @@ /// markConstant - Return true if this is a change in status. bool markConstant(Constant *V) { - if (getLatticeValue() == constant) { // Constant but not forcedconstant. + if (getLatticeValue() == constant) { assert(getConstant() == V && "Marking constant with different value"); return false; } @@ -118,16 +110,6 @@ Val.setInt(constant); assert(V && "Marking constant with NULL"); Val.setPointer(V); - } else { - assert(getLatticeValue() == forcedconstant && - "Cannot move from overdefined to constant!"); - // Stay at forcedconstant if the constant is the same. - if (V == getConstant()) return false; - - // Otherwise, we go to overdefined. Assumptions made based on the - // forced value are possibly wrong. Assuming this is another constant - // could expose a contradiction. - Val.setInt(overdefined); } return true; } @@ -139,12 +121,6 @@ return dyn_cast(getConstant()); return nullptr; } - - void markForcedConstant(Constant *V) { - assert(isUnknown() && "Can't force a defined value!"); - Val.setInt(forcedconstant); - Val.setPointer(V); - } }; } // end anonymous namespace. @@ -259,13 +235,6 @@ /// void Solve(); - /// ResolvedUndefsIn - While solving the dataflow for a function, we assume - /// that branches on undef values cannot reach any of their successors. - /// However, this is not a safe assumption. After we solve dataflow, this - /// method should be use to handle this. If this returns true, the solver - /// should be rerun. - bool ResolvedUndefsIn(Function &F); - bool isBlockExecutable(BasicBlock *BB) const { return BBExecutable.count(BB); } @@ -337,7 +306,7 @@ } private: - // pushToWorkList - Helper for markConstant/markForcedConstant/markOverdefined + // pushToWorkList - Helper for markConstant/markOverdefined void pushToWorkList(LatticeVal &IV, Value *V) { if (IV.isOverdefined()) return OverdefinedInstWorkList.push_back(V); @@ -359,15 +328,6 @@ markConstant(ValueState[V], V, C); } - void markForcedConstant(Value *V, Constant *C) { - assert(!V->getType()->isStructTy() && "structs should use mergeInValue"); - LatticeVal &IV = ValueState[V]; - IV.markForcedConstant(C); - DEBUG(dbgs() << "markForcedConstant: " << *C << ": " << *V << '\n'); - pushToWorkList(IV, V); - } - - // markOverdefined - Make a value be marked as "overdefined". If the // value is not already overdefined, add it to the overdefined instruction // work list so that the users of the instruction are updated later. @@ -414,11 +374,10 @@ if (!I.second) return LV; // Common case, already in the map. - if (auto *C = dyn_cast(V)) { - // Undef values remain unknown. - if (!isa(V)) - LV.markConstant(C); // Constants are constant - } + // We found a value that's constant, so we set its lattice + // value to constant accordingly. + if (auto *C = dyn_cast(V)) + LV.markConstant(C); // All others are underdefined by default. return LV; @@ -445,8 +404,6 @@ if (!Elt) LV.markOverdefined(); // Unknown sort of constant. - else if (isa(Elt)) - ; // Undef values remain unknown. else LV.markConstant(Elt); // Constants are constant. } @@ -511,9 +468,6 @@ void visitSelectInst(SelectInst &I); void visitBinaryOperator(Instruction &I); void visitCmpInst(CmpInst &I); - void visitExtractElementInst(ExtractElementInst &I); - void visitInsertElementInst(InsertElementInst &I); - void visitShuffleVectorInst(ShuffleVectorInst &I); void visitExtractValueInst(ExtractValueInst &EVI); void visitInsertValueInst(InsertValueInst &IVI); void visitLandingPadInst(LandingPadInst &I) { markAnythingOverdefined(&I); } @@ -570,6 +524,7 @@ } LatticeVal BCValue = getValueState(BI->getCondition()); + ConstantInt *CI = BCValue.getConstantInt(); if (!CI) { // Overdefined condition variables, and branches on unfoldable constant @@ -596,6 +551,18 @@ return; } LatticeVal SCValue = getValueState(SI->getCondition()); + + // Handle branch on undef marking the first successor as live. + if (SCValue.isConstant()) { + Constant *C = SCValue.getConstant(); + assert(C && "C should be a constant"); + if (isa(C)) { + ConstantInt *CI = SI->case_begin().getCaseValue(); + Succs[SI->findCaseValue(CI).getSuccessorIndex()] = true; + return; + } + } + ConstantInt *CI = SCValue.getConstantInt(); if (!CI) { // Overdefined or unknown condition? @@ -710,13 +677,20 @@ // are overdefined, the PHI becomes overdefined as well. If they are all // constant, and they agree with each other, the PHI becomes the identical // constant. If they are constant and don't agree, the PHI is overdefined. - // If there are no executable operands, the PHI remains unknown. - // + // If all the operands are undefined, the PHI goes to overdefined. Constant *OperandVal = nullptr; for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { LatticeVal IV = getValueState(PN.getIncomingValue(i)); if (IV.isUnknown()) continue; // Doesn't influence PHI node. + // 'undef' doesn't influence a phi. + // For example, we have: + // %patatino = phi i32* [ undef, %a ], [ null, %b ], [ null, %c ] + // We can fold %patatino to null as the other two phi values agree + // and 'undef' has no effect here. + if (IV.isConstant() && isa(IV.getConstant())) + continue; + if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent())) continue; @@ -740,11 +714,11 @@ // If we exited the loop, this means that the PHI node only has constant // arguments that agree with each other(and OperandVal is the constant) or - // OperandVal is null because there are no defined incoming arguments. If - // this is the case, the PHI remains unknown. - // + // OperandVal is null because there are no defined incoming arguments. + // In the latter case, we send it to overdefined. if (OperandVal) - markConstant(&PN, OperandVal); // Acquire operand value + return markConstant(&PN, OperandVal); // Acquire operand value + return markOverdefined(&PN); } void SCCPSolver::visitReturnInst(ReturnInst &I) { @@ -788,15 +762,11 @@ void SCCPSolver::visitCastInst(CastInst &I) { LatticeVal OpSt = getValueState(I.getOperand(0)); - if (OpSt.isOverdefined()) // Inherit overdefinedness of operand - markOverdefined(&I); - else if (OpSt.isConstant()) { - // Fold the constant as we build. + if (OpSt.isOverdefined()) + return markOverdefined(&I); + if (OpSt.isConstant()) { Constant *C = ConstantFoldCastOperand(I.getOpcode(), OpSt.getConstant(), I.getType(), DL); - if (isa(C)) - return; - // Propagate constant value markConstant(&I, C); } } @@ -878,15 +848,23 @@ LatticeVal TVal = getValueState(I.getTrueValue()); LatticeVal FVal = getValueState(I.getFalseValue()); - // select ?, C, C -> C. - if (TVal.isConstant() && FVal.isConstant() && - TVal.getConstant() == FVal.getConstant()) - return markConstant(&I, FVal.getConstant()); + if (TVal.isConstant() && FVal.isConstant()) { + // FIXME: check if there's a way to just call an API instead of + // doing the constant folding dance in SCCP. + Constant *TC = TVal.getConstant(); + Constant *FC = FVal.getConstant(); + + // select ?, C, C -> C. + if (TC == FC) + return markConstant(&I, TC); - if (TVal.isUnknown()) // select ?, undef, X -> X. - return mergeInValue(&I, FVal); - if (FVal.isUnknown()) // select ?, X, undef -> X. - return mergeInValue(&I, TVal); + // select ?, undef, C -> C + // select ?, C, undef -> C + if (isa(TC)) + return markConstant(&I, FC); + if (isa(FC)) + return markConstant(&I, TC); + } markOverdefined(&I); } @@ -901,13 +879,10 @@ if (V1State.isConstant() && V2State.isConstant()) { Constant *C = ConstantExpr::get(I.getOpcode(), V1State.getConstant(), V2State.getConstant()); - // X op Y -> undef. - if (isa(C)) - return; return markConstant(IV, &I, C); } - // If something is undef, wait for it to resolve. + // If something is unknown, wait for it to resolve. if (!V1State.isOverdefined() && !V2State.isOverdefined()) return; @@ -931,14 +906,18 @@ if (I.getOpcode() == Instruction::And || I.getOpcode() == Instruction::Mul) { // X and 0 = 0 + // X and undef = 0 // X * 0 = 0 - if (NonOverdefVal->getConstant()->isNullValue()) - return markConstant(IV, &I, NonOverdefVal->getConstant()); + Constant *C = NonOverdefVal->getConstant(); + if (C->isNullValue() || isa(C)) + return markConstant(IV, &I, Constant::getNullValue(I.getType())); } else { // X or -1 = -1 - if (ConstantInt *CI = NonOverdefVal->getConstantInt()) - if (CI->isAllOnesValue()) - return markConstant(IV, &I, NonOverdefVal->getConstant()); + // X or undef = -1 + Constant *C = NonOverdefVal->getConstant(); + Constant *CI = NonOverdefVal->getConstantInt(); + if ((C && isa(C)) || (CI && CI->isAllOnesValue())) + return markConstant(IV, &I, Constant::getAllOnesValue(I.getType())); } } } @@ -958,8 +937,6 @@ if (V1State.isConstant() && V2State.isConstant()) { Constant *C = ConstantExpr::getCompare( I.getPredicate(), V1State.getConstant(), V2State.getConstant()); - if (isa(C)) - return; return markConstant(IV, &I, C); } @@ -970,21 +947,6 @@ markOverdefined(&I); } -void SCCPSolver::visitExtractElementInst(ExtractElementInst &I) { - // TODO : SCCP does not handle vectors properly. - return markOverdefined(&I); -} - -void SCCPSolver::visitInsertElementInst(InsertElementInst &I) { - // TODO : SCCP does not handle vectors properly. - return markOverdefined(&I); -} - -void SCCPSolver::visitShuffleVectorInst(ShuffleVectorInst &I) { - // TODO : SCCP does not handle vectors properly. - return markOverdefined(&I); -} - // Handle getelementptr instructions. If all operands are constants then we // can turn this into a getelementptr ConstantExpr. // @@ -1010,8 +972,6 @@ auto Indices = makeArrayRef(Operands.begin() + 1, Operands.end()); Constant *C = ConstantExpr::getGetElementPtr(I.getSourceElementType(), Ptr, Indices); - if (isa(C)) - return; markConstant(&I, C); } @@ -1053,6 +1013,7 @@ Constant *Ptr = PtrVal.getConstant(); // load null is undefined. + // XXXdavide: should we constant fold this one? if (isa(Ptr) && I.getPointerAddressSpace() == 0) return; @@ -1070,11 +1031,8 @@ } // Transform load from a constant into a constant if possible. - if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, I.getType(), DL)) { - if (isa(C)) - return; + if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, I.getType(), DL)) return markConstant(IV, &I, C); - } // Otherwise we cannot say for certain what value this load will produce. // Bail out. @@ -1116,12 +1074,8 @@ // If we can constant fold this, mark the result of the call as a // constant. - if (Constant *C = ConstantFoldCall(F, Operands, TLI)) { - // call -> undef. - if (isa(C)) - return; + if (Constant *C = ConstantFoldCall(F, Operands, TLI)) return markConstant(I, C); - } } // Otherwise, we don't know anything about this call, mark it overdefined. @@ -1232,295 +1186,6 @@ } } -/// ResolvedUndefsIn - While solving the dataflow for a function, we assume -/// that branches on undef values cannot reach any of their successors. -/// However, this is not a safe assumption. After we solve dataflow, this -/// method should be use to handle this. If this returns true, the solver -/// should be rerun. -/// -/// This method handles this by finding an unresolved branch and marking it one -/// of the edges from the block as being feasible, even though the condition -/// doesn't say it would otherwise be. This allows SCCP to find the rest of the -/// CFG and only slightly pessimizes the analysis results (by marking one, -/// potentially infeasible, edge feasible). This cannot usefully modify the -/// constraints on the condition of the branch, as that would impact other users -/// of the value. -/// -/// This scan also checks for values that use undefs, whose results are actually -/// defined. For example, 'zext i8 undef to i32' should produce all zeros -/// conservatively, as "(zext i8 X -> i32) & 0xFF00" must always return zero, -/// even if X isn't defined. -bool SCCPSolver::ResolvedUndefsIn(Function &F) { - for (BasicBlock &BB : F) { - if (!BBExecutable.count(&BB)) - continue; - - for (Instruction &I : BB) { - // Look for instructions which produce undef values. - if (I.getType()->isVoidTy()) continue; - - if (auto *STy = dyn_cast(I.getType())) { - // Only a few things that can be structs matter for undef. - - // Tracked calls must never be marked overdefined in ResolvedUndefsIn. - if (CallSite CS = CallSite(&I)) - if (Function *F = CS.getCalledFunction()) - if (MRVFunctionsTracked.count(F)) - continue; - - // extractvalue and insertvalue don't need to be marked; they are - // tracked as precisely as their operands. - if (isa(I) || isa(I)) - continue; - - // Send the results of everything else to overdefined. We could be - // more precise than this but it isn't worth bothering. - for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) { - LatticeVal &LV = getStructValueState(&I, i); - if (LV.isUnknown()) - markOverdefined(LV, &I); - } - continue; - } - - LatticeVal &LV = getValueState(&I); - if (!LV.isUnknown()) continue; - - // extractvalue is safe; check here because the argument is a struct. - if (isa(I)) - continue; - - // Compute the operand LatticeVals, for convenience below. - // Anything taking a struct is conservatively assumed to require - // overdefined markings. - if (I.getOperand(0)->getType()->isStructTy()) { - markOverdefined(&I); - return true; - } - LatticeVal Op0LV = getValueState(I.getOperand(0)); - LatticeVal Op1LV; - if (I.getNumOperands() == 2) { - if (I.getOperand(1)->getType()->isStructTy()) { - markOverdefined(&I); - return true; - } - - Op1LV = getValueState(I.getOperand(1)); - } - // If this is an instructions whose result is defined even if the input is - // not fully defined, propagate the information. - Type *ITy = I.getType(); - switch (I.getOpcode()) { - case Instruction::Add: - case Instruction::Sub: - case Instruction::Trunc: - case Instruction::FPTrunc: - case Instruction::BitCast: - break; // Any undef -> undef - case Instruction::FSub: - case Instruction::FAdd: - case Instruction::FMul: - case Instruction::FDiv: - case Instruction::FRem: - // Floating-point binary operation: be conservative. - if (Op0LV.isUnknown() && Op1LV.isUnknown()) - markForcedConstant(&I, Constant::getNullValue(ITy)); - else - markOverdefined(&I); - return true; - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FPToUI: - case Instruction::FPToSI: - case Instruction::FPExt: - case Instruction::PtrToInt: - case Instruction::IntToPtr: - case Instruction::SIToFP: - case Instruction::UIToFP: - // undef -> 0; some outputs are impossible - markForcedConstant(&I, Constant::getNullValue(ITy)); - return true; - case Instruction::Mul: - case Instruction::And: - // Both operands undef -> undef - if (Op0LV.isUnknown() && Op1LV.isUnknown()) - break; - // undef * X -> 0. X could be zero. - // undef & X -> 0. X could be zero. - markForcedConstant(&I, Constant::getNullValue(ITy)); - return true; - - case Instruction::Or: - // Both operands undef -> undef - if (Op0LV.isUnknown() && Op1LV.isUnknown()) - break; - // undef | X -> -1. X could be -1. - markForcedConstant(&I, Constant::getAllOnesValue(ITy)); - return true; - - case Instruction::Xor: - // undef ^ undef -> 0; strictly speaking, this is not strictly - // necessary, but we try to be nice to people who expect this - // behavior in simple cases - if (Op0LV.isUnknown() && Op1LV.isUnknown()) { - markForcedConstant(&I, Constant::getNullValue(ITy)); - return true; - } - // undef ^ X -> undef - break; - - case Instruction::SDiv: - case Instruction::UDiv: - case Instruction::SRem: - case Instruction::URem: - // X / undef -> undef. No change. - // X % undef -> undef. No change. - if (Op1LV.isUnknown()) break; - - // X / 0 -> undef. No change. - // X % 0 -> undef. No change. - if (Op1LV.isConstant() && Op1LV.getConstant()->isZeroValue()) - break; - - // undef / X -> 0. X could be maxint. - // undef % X -> 0. X could be 1. - markForcedConstant(&I, Constant::getNullValue(ITy)); - return true; - - case Instruction::AShr: - // X >>a undef -> undef. - if (Op1LV.isUnknown()) break; - - // Shifting by the bitwidth or more is undefined. - if (Op1LV.isConstant()) { - if (auto *ShiftAmt = Op1LV.getConstantInt()) - if (ShiftAmt->getLimitedValue() >= - ShiftAmt->getType()->getScalarSizeInBits()) - break; - } - - // undef >>a X -> 0 - markForcedConstant(&I, Constant::getNullValue(ITy)); - return true; - case Instruction::LShr: - case Instruction::Shl: - // X << undef -> undef. - // X >> undef -> undef. - if (Op1LV.isUnknown()) break; - - // Shifting by the bitwidth or more is undefined. - if (Op1LV.isConstant()) { - if (auto *ShiftAmt = Op1LV.getConstantInt()) - if (ShiftAmt->getLimitedValue() >= - ShiftAmt->getType()->getScalarSizeInBits()) - break; - } - - // undef << X -> 0 - // undef >> X -> 0 - markForcedConstant(&I, Constant::getNullValue(ITy)); - return true; - case Instruction::Select: - Op1LV = getValueState(I.getOperand(1)); - // undef ? X : Y -> X or Y. There could be commonality between X/Y. - if (Op0LV.isUnknown()) { - if (!Op1LV.isConstant()) // Pick the constant one if there is any. - Op1LV = getValueState(I.getOperand(2)); - } else if (Op1LV.isUnknown()) { - // c ? undef : undef -> undef. No change. - Op1LV = getValueState(I.getOperand(2)); - if (Op1LV.isUnknown()) - break; - // Otherwise, c ? undef : x -> x. - } else { - // Leave Op1LV as Operand(1)'s LatticeValue. - } - - if (Op1LV.isConstant()) - markForcedConstant(&I, Op1LV.getConstant()); - else - markOverdefined(&I); - return true; - case Instruction::Load: - // A load here means one of two things: a load of undef from a global, - // a load from an unknown pointer. Either way, having it return undef - // is okay. - break; - case Instruction::ICmp: - // X == undef -> undef. Other comparisons get more complicated. - if (cast(&I)->isEquality()) - break; - markOverdefined(&I); - return true; - case Instruction::Call: - case Instruction::Invoke: { - // There are two reasons a call can have an undef result - // 1. It could be tracked. - // 2. It could be constant-foldable. - // Because of the way we solve return values, tracked calls must - // never be marked overdefined in ResolvedUndefsIn. - if (Function *F = CallSite(&I).getCalledFunction()) - if (TrackedRetVals.count(F)) - break; - - // If the call is constant-foldable, we mark it overdefined because - // we do not know what return values are valid. - markOverdefined(&I); - return true; - } - default: - // If we don't know what should happen here, conservatively mark it - // overdefined. - markOverdefined(&I); - return true; - } - } - - // Check to see if we have a branch or switch on an undefined value. If so - // we force the branch to go one way or the other to make the successor - // values live. It doesn't really matter which way we force it. - TerminatorInst *TI = BB.getTerminator(); - if (auto *BI = dyn_cast(TI)) { - if (!BI->isConditional()) continue; - if (!getValueState(BI->getCondition()).isUnknown()) - continue; - - // If the input to SCCP is actually branch on undef, fix the undef to - // false. - if (isa(BI->getCondition())) { - BI->setCondition(ConstantInt::getFalse(BI->getContext())); - markEdgeExecutable(&BB, TI->getSuccessor(1)); - return true; - } - - // Otherwise, it is a branch on a symbolic value which is currently - // considered to be undef. Handle this by forcing the input value to the - // branch to false. - markForcedConstant(BI->getCondition(), - ConstantInt::getFalse(TI->getContext())); - return true; - } - - if (auto *SI = dyn_cast(TI)) { - if (!SI->getNumCases() || !getValueState(SI->getCondition()).isUnknown()) - continue; - - // If the input to SCCP is actually switch on undef, fix the undef to - // the first constant. - if (isa(SI->getCondition())) { - SI->setCondition(SI->case_begin().getCaseValue()); - markEdgeExecutable(&BB, SI->case_begin().getCaseSuccessor()); - return true; - } - - markForcedConstant(SI->getCondition(), SI->case_begin().getCaseValue()); - return true; - } - } - - return false; -} - static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V) { Constant *Const = nullptr; if (V->getType()->isStructTy()) { @@ -1565,14 +1230,7 @@ for (Argument &AI : F.args()) Solver.markAnythingOverdefined(&AI); - // Solve for constants. - bool ResolvedUndefs = true; - while (ResolvedUndefs) { - Solver.Solve(); - DEBUG(dbgs() << "RESOLVING UNDEFs\n"); - ResolvedUndefs = Solver.ResolvedUndefsIn(F); - } - + Solver.Solve(); bool MadeChanges = false; // If we decided that there are basic blocks that are dead in this function, @@ -1753,16 +1411,7 @@ if (!G.isConstant() && G.hasLocalLinkage() && !AddressIsTaken(&G)) Solver.TrackValueOfGlobalVariable(&G); - // Solve for constants. - bool ResolvedUndefs = true; - while (ResolvedUndefs) { - Solver.Solve(); - - DEBUG(dbgs() << "RESOLVING UNDEFS\n"); - ResolvedUndefs = false; - for (Function &F : M) - ResolvedUndefs |= Solver.ResolvedUndefsIn(F); - } + Solver.Solve(); bool MadeChanges = false; @@ -1802,6 +1451,29 @@ for (BasicBlock::iterator BI = BB->begin(), E = BB->end(); BI != E; ) { Instruction *Inst = &*BI++; + + // Fix branches to undef -> branches to false. + if (auto *BrInst = dyn_cast(Inst)) { + if (!BrInst->isConditional()) + continue; + auto *C = dyn_cast(BrInst->getCondition()); + if (!C || !isa(C)) + continue; + BrInst->setCondition(ConstantInt::getFalse(BrInst->getContext())); + Solver.MarkBlockExecutable(BrInst->getSuccessor(1)); + } + + // Fix switches on undef -> switch on the first constant. + if (auto *SI = dyn_cast(Inst)) { + if (!SI->getNumCases()) + continue; + auto *C = dyn_cast(SI->getCondition()); + if (!C || !isa(C)) + continue; + SI->setCondition(SI->case_begin().getCaseValue()); + Solver.MarkBlockExecutable(SI->case_begin().getCaseSuccessor()); + } + if (Inst->getType()->isVoidTy()) continue; if (tryToReplaceWithConstant(Solver, Inst)) { @@ -1832,32 +1504,7 @@ if (!I) continue; bool Folded = ConstantFoldTerminator(I->getParent()); - if (!Folded) { - // The constant folder may not have been able to fold the terminator - // if this is a branch or switch on undef. Fold it manually as a - // branch to the first successor. -#ifndef NDEBUG - if (auto *BI = dyn_cast(I)) { - assert(BI->isConditional() && isa(BI->getCondition()) && - "Branch should be foldable!"); - } else if (auto *SI = dyn_cast(I)) { - assert(isa(SI->getCondition()) && "Switch should fold"); - } else { - llvm_unreachable("Didn't fold away reference to block!"); - } -#endif - - // Make this an uncond branch to the first successor. - TerminatorInst *TI = I->getParent()->getTerminator(); - BranchInst::Create(TI->getSuccessor(0), TI); - - // Remove entries in successor phi nodes to remove edges. - for (unsigned i = 1, e = TI->getNumSuccessors(); i != e; ++i) - TI->getSuccessor(i)->removePredecessor(TI->getParent()); - - // Remove the old terminator. - TI->eraseFromParent(); - } + assert(Folded && "The terminator should've been folded"); } // Finally, delete the basic block. Index: test/Transforms/IPConstantProp/PR16052.ll =================================================================== --- test/Transforms/IPConstantProp/PR16052.ll +++ test/Transforms/IPConstantProp/PR16052.ll @@ -13,6 +13,7 @@ ; CHECK-DAG: define i64 @fn2( ; CHECK: %[[CALL:.*]] = call i64 @fn1(i64 undef) +; CHECK-NEXT: ret i64 undef define internal i64 @fn1(i64 %p1) { entry: @@ -22,5 +23,4 @@ } ; CHECK-DAG: define internal i64 @fn1( -; CHECK: %[[SEL:.*]] = select i1 undef, i64 undef, i64 undef -; CHECK: ret i64 %[[SEL]] +; CHECK: ret i64 undef Index: test/Transforms/IPConstantProp/PR26044.ll =================================================================== --- test/Transforms/IPConstantProp/PR26044.ll +++ test/Transforms/IPConstantProp/PR26044.ll @@ -24,8 +24,8 @@ } ; CHECK-LABEL: define void @fn2( -; CHECK: call i32 @fn1(i32 undef) +; CHECK: call i32 @fn1(i32 %0) ; CHECK-LABEL: define internal i32 @fn1( -; CHECK:%[[COND:.*]] = select i1 undef, i32 undef, i32 undef +; CHECK:%[[COND:.*]] = select i1 %tobool, i32 %p1, i32 %p1 ; CHECK: ret i32 %[[COND]] Index: test/Transforms/SCCP/undef-resolve.ll =================================================================== --- test/Transforms/SCCP/undef-resolve.ll +++ test/Transforms/SCCP/undef-resolve.ll @@ -154,12 +154,12 @@ ; CHECK: ret i1 undef } -; Make sure we don't conclude that relational comparisons simplify to undef +; Make sure we constant-fold to false define i1 @test9() { %t = icmp ugt i32 undef, -1 ret i1 %t ; CHECK-LABEL: @test9( -; CHECK: icmp ugt +; CHECK: ret i1 false } ; Make sure we handle extractvalue