/// any constant expressions.
bool containsConstantExpression() const;
- /// Return true if evaluation of this constant could trap. This is true for
- /// things like constant expressions that could divide by zero.
- bool canTrap() const;
-
/// Return true if the value can vary between threads.
bool isThreadDependent() const;
return UndefValue::get(PN->getType());
if (HasUndefInput) {
- // We cannot start executing a trapping constant expression on more control
- // flow paths.
- auto *C = dyn_cast<Constant>(CommonValue);
- if (C && C->canTrap())
- return nullptr;
-
// If we have a PHI node like phi(X, undef, X), where X is defined by some
// instruction, we cannot return X as the result of the PHI node unless it
// dominates the PHI block.
}
#endif
- for (unsigned i = 0, e = Inst->getNumOperands(); i != e; ++i)
- if (Constant *C = dyn_cast<Constant>(Inst->getOperand(i)))
- if (C->canTrap())
- return false;
-
switch (Opcode) {
default:
return true;
#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/LazyBlockFrequencyInfo.h"
#include "llvm/Analysis/LegacyDivergenceAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
MachineFunctionPass::getAnalysisUsage(AU);
}
-/// SplitCriticalSideEffectEdges - Look for critical edges with a PHI value that
-/// may trap on it. In this case we have to split the edge so that the path
-/// through the predecessor block that doesn't go to the phi block doesn't
-/// execute the possibly trapping instruction. If available, we pass domtree
-/// and loop info to be updated when we split critical edges. This is because
-/// SelectionDAGISel preserves these analyses.
-/// This is required for correctness, so it must be done at -O0.
-///
-static void SplitCriticalSideEffectEdges(Function &Fn, DominatorTree *DT,
- LoopInfo *LI) {
- // Loop for blocks with phi nodes.
- for (BasicBlock &BB : Fn) {
- PHINode *PN = dyn_cast<PHINode>(BB.begin());
- if (!PN) continue;
-
- ReprocessBlock:
- // For each block with a PHI node, check to see if any of the input values
- // are potentially trapping constant expressions. Constant expressions are
- // the only potentially trapping value that can occur as the argument to a
- // PHI.
- for (BasicBlock::iterator I = BB.begin(); (PN = dyn_cast<PHINode>(I)); ++I)
- for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
- Constant *C = dyn_cast<Constant>(PN->getIncomingValue(i));
- if (!C || !C->canTrap()) continue;
-
- // The only case we have to worry about is when the edge is critical.
- // Since this block has a PHI Node, we assume it has multiple input
- // edges: check to see if the pred has multiple successors.
- BasicBlock *Pred = PN->getIncomingBlock(i);
- if (Pred->getTerminator()->getNumSuccessors() == 1)
- continue;
-
- // Okay, we have to split this edge.
- SplitCriticalEdge(
- Pred->getTerminator(), GetSuccessorNumber(Pred, &BB),
- CriticalEdgeSplittingOptions(DT, LI).setMergeIdenticalEdges());
- goto ReprocessBlock;
- }
- }
-}
-
static void computeUsesMSVCFloatingPoint(const Triple &TT, const Function &F,
MachineModuleInfo &MMI) {
// Only needed for MSVC
ORE = std::make_unique<OptimizationRemarkEmitter>(&Fn);
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>();
DominatorTree *DT = DTWP ? &DTWP->getDomTree() : nullptr;
- auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
- LoopInfo *LI = LIWP ? &LIWP->getLoopInfo() : nullptr;
auto *PSI = &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
BlockFrequencyInfo *BFI = nullptr;
if (PSI && PSI->hasProfileSummary() && OptLevel != CodeGenOpt::None)
LLVM_DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
- SplitCriticalSideEffectEdges(const_cast<Function &>(Fn), DT, LI);
-
CurDAG->init(*MF, *ORE, this, LibInfo,
getAnalysisIfAvailable<LegacyDivergenceAnalysis>(), PSI, BFI);
FuncInfo->set(Fn, *MF, CurDAG);
}
}
-bool Constant::canTrap() const {
- return false;
-}
-
/// Check if C contains a GlobalValue for which Predicate is true.
static bool
ConstHasGlobalValuePredicate(const Constant *C,
if (SimpleV.getValue())
EffectiveV = SimpleV.getValue();
if (auto *C = dyn_cast<Constant>(EffectiveV))
- if (!C->canTrap())
- return C;
+ return C;
if (CtxI && AA::isValidAtPosition(AA::ValueAndContext(*EffectiveV, *CtxI),
A.getInfoCache()))
return ensureType(A, *EffectiveV, Ty, CtxI, Check);
}
Value *StoredOnceValue = GS.getStoredOnceValue();
if (GS.StoredType == GlobalStatus::StoredOnce && StoredOnceValue) {
- // Avoid speculating constant expressions that might trap (div/rem).
- auto *SOVConstant = dyn_cast<Constant>(StoredOnceValue);
- if (SOVConstant && SOVConstant->canTrap())
- return Changed;
-
Function &StoreFn =
const_cast<Function &>(*GS.StoredOnceStore->getFunction());
bool CanHaveNonUndefGlobalInitializer =
// This is restricted to address spaces that allow globals to have
// initializers. NVPTX, for example, does not support initializers for
// shared memory (AS 3).
+ auto *SOVConstant = dyn_cast<Constant>(StoredOnceValue);
if (SOVConstant && isa<UndefValue>(GV->getInitializer()) &&
DL.getTypeAllocSize(SOVConstant->getType()) ==
DL.getTypeAllocSize(GV->getValueType()) &&
// icmp(phi(C1, C2, ...), C) -> phi(icmp(C1, C), icmp(C2, C), ...).
Constant *C = dyn_cast<Constant>(Op1);
- if (!C || C->canTrap())
+ if (!C)
return nullptr;
if (auto *Phi = dyn_cast<PHINode>(Op0))
return TTI.getUserCost(I, TargetTransformInfo::TCK_SizeAndLatency);
}
-/// Check whether this is a potentially trapping constant.
-static bool canTrap(const Value *V) {
- if (auto *C = dyn_cast<Constant>(V))
- return C->canTrap();
- return false;
-}
-
/// If we have a merge point of an "if condition" as accepted above,
/// return true if the specified value dominates the block. We
/// don't handle the true generality of domination here, just a special case
Instruction *I = dyn_cast<Instruction>(V);
if (!I) {
- // Non-instructions all dominate instructions, but not all constantexprs
- // can be executed unconditionally.
- return !canTrap(V);
+ // Non-instructions dominate all instructions and can be executed
+ // unconditionally.
+ return true;
}
BasicBlock *PBB = I->getParent();
passingValueIsAlwaysUndefined(ThenV, &PN))
return false;
- if (canTrap(OrigV) || canTrap(ThenV))
- return false;
-
HaveRewritablePHIs = true;
ConstantExpr *OrigCE = dyn_cast<ConstantExpr>(OrigV);
ConstantExpr *ThenCE = dyn_cast<ConstantExpr>(ThenV);
Cond->getParent() != BB || !Cond->hasOneUse())
return false;
- // Cond is known to be a compare or binary operator. Check to make sure that
- // neither operand is a potentially-trapping constant expression.
- if (canTrap(Cond->getOperand(0)))
- return false;
- if (canTrap(Cond->getOperand(1)))
- return false;
-
// Finally, don't infinitely unroll conditional loops.
if (is_contained(successors(BB), BB))
return false;
if (tryWidenCondBranchToCondBranch(PBI, BI, DTU))
return true;
- if (canTrap(BI->getCondition()))
- return false;
-
// If both branches are conditional and both contain stores to the same
// address, remove the stores from the conditionals and create a conditional
// merged store at the end.
// insertion of a large number of select instructions. For targets
// without predication/cmovs, this is a big pessimization.
- // Also do not perform this transformation if any phi node in the common
- // destination block can trap when reached by BB or PBB (PR17073). In that
- // case, it would be unsafe to hoist the operation into a select instruction.
-
BasicBlock *CommonDest = PBI->getSuccessor(PBIOp);
BasicBlock *RemovedDest = PBI->getSuccessor(PBIOp ^ 1);
unsigned NumPhis = 0;
++II, ++NumPhis) {
if (NumPhis > 2) // Disable this xform.
return false;
-
- PHINode *PN = cast<PHINode>(II);
- Value *BIV = PN->getIncomingValueForBlock(BB);
- if (canTrap(BIV))
- return false;
-
- unsigned PBBIdx = PN->getBasicBlockIndex(PBI->getParent());
- Value *PBIV = PN->getIncomingValue(PBBIdx);
- if (canTrap(PBIV))
- return false;
}
// Finally, if everything is ok, fold the branches to logical ops.
return true;
}
-/// Check whether it is safe to if-convert this phi node.
-///
-/// Phi nodes with constant expressions that can trap are not safe to if
-/// convert.
-static bool canIfConvertPHINodes(BasicBlock *BB) {
- for (PHINode &Phi : BB->phis()) {
- for (Value *V : Phi.incoming_values())
- if (auto *C = dyn_cast<Constant>(V))
- if (C->canTrap())
- return false;
- }
- return true;
-}
-
static Type *convertPointerToIntegerType(const DataLayout &DL, Type *Ty) {
if (Ty->isPointerTy())
return DL.getIntPtrType(Ty);
SmallPtrSetImpl<const Instruction *> &MaskedOp,
SmallPtrSetImpl<Instruction *> &ConditionalAssumes) const {
for (Instruction &I : *BB) {
- // Check that we don't have a constant expression that can trap as operand.
- for (Value *Operand : I.operands()) {
- if (auto *C = dyn_cast<Constant>(Operand))
- if (C->canTrap())
- return false;
- }
-
// We can predicate blocks with calls to assume, as long as we drop them in
// case we flatten the CFG via predication.
if (match(&I, m_Intrinsic<Intrinsic::assume>())) {
BB->getTerminator());
return false;
}
- } else if (BB != Header && !canIfConvertPHINodes(BB)) {
- reportVectorizationFailure(
- "Control flow cannot be substituted for a select",
- "control flow cannot be substituted for a select",
- "NoCFGForSelect", ORE, TheLoop,
- BB->getTerminator());
- return false;
}
}