[VPlan] Replace CondBit with BranchOnCond VPInstruction.
This patch removes CondBit and Predicate from VPBasicBlock. To do so,
the patch introduces a new branch-on-cond VPInstruction opcode to model
a branch on a condition explicitly.
This addresses a long-standing TODO/FIXME that blocks shouldn't be users
of VPValues. Those extra users can cause issues for VPValue-based
analyses that don't expect blocks. Addressing this fixme should allow us
to re-introduce 266ea446ab
.
The generic branch opcode can also be used in follow-up patches.
Depends on D123005.
Reviewed By: Ayal
Differential Revision: https://reviews.llvm.org/D126618
This commit is contained in:
parent
39f28397e2
commit
a5bb4a3b4d
|
@ -8528,7 +8528,7 @@ VPRegionBlock *VPRecipeBuilder::createReplicateRegion(Instruction *Instr,
|
|||
|
||||
// Note: first set Entry as region entry and then connect successors starting
|
||||
// from it in order, to propagate the "parent" of each VPBasicBlock.
|
||||
VPBlockUtils::insertTwoBlocksAfter(Pred, Exiting, BlockInMask, Entry);
|
||||
VPBlockUtils::insertTwoBlocksAfter(Pred, Exiting, Entry);
|
||||
VPBlockUtils::connectBlocks(Pred, Exiting);
|
||||
|
||||
return Region;
|
||||
|
@ -8661,7 +8661,7 @@ void LoopVectorizationPlanner::buildVPlansWithVPRecipes(ElementCount MinVF,
|
|||
// CanonicalIVIncrement{NUW} VPInstruction to increment it by VF * UF and a
|
||||
// BranchOnCount VPInstruction to the latch.
|
||||
static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, DebugLoc DL,
|
||||
bool HasNUW, bool IsVPlanNative) {
|
||||
bool HasNUW) {
|
||||
Value *StartIdx = ConstantInt::get(IdxTy, 0);
|
||||
auto *StartV = Plan.getOrAddVPValue(StartIdx);
|
||||
|
||||
|
@ -8677,8 +8677,6 @@ static void addCanonicalIVRecipes(VPlan &Plan, Type *IdxTy, DebugLoc DL,
|
|||
CanonicalIVPHI->addOperand(CanonicalIVIncrement);
|
||||
|
||||
VPBasicBlock *EB = TopRegion->getExitingBasicBlock();
|
||||
if (IsVPlanNative)
|
||||
EB->setCondBit(nullptr);
|
||||
EB->appendRecipe(CanonicalIVIncrement);
|
||||
|
||||
auto *BranchOnCount =
|
||||
|
@ -8785,7 +8783,7 @@ VPlanPtr LoopVectorizationPlanner::buildVPlanWithVPRecipes(
|
|||
getDebugLocFromInstOrOperands(Legal->getPrimaryInduction());
|
||||
addCanonicalIVRecipes(*Plan, Legal->getWidestInductionType(),
|
||||
DLInst ? DLInst->getDebugLoc() : DebugLoc(),
|
||||
!CM.foldTailByMasking(), false);
|
||||
!CM.foldTailByMasking());
|
||||
|
||||
// Scan the body of the loop in a topological order to visit each basic block
|
||||
// after having visited its predecessor basic blocks.
|
||||
|
@ -9089,8 +9087,14 @@ VPlanPtr LoopVectorizationPlanner::buildVPlan(VFRange &Range) {
|
|||
[this](PHINode *P) { return Legal->getIntOrFpInductionDescriptor(P); },
|
||||
DeadInstructions, *PSE.getSE());
|
||||
|
||||
// Remove the existing terminator of the exiting block of the top-most region.
|
||||
// A BranchOnCount will be added instead when adding the canonical IV recipes.
|
||||
auto *Term =
|
||||
Plan->getVectorLoopRegion()->getExitingBasicBlock()->getTerminator();
|
||||
Term->eraseFromParent();
|
||||
|
||||
addCanonicalIVRecipes(*Plan, Legal->getWidestInductionType(), DebugLoc(),
|
||||
true, true);
|
||||
true);
|
||||
return Plan;
|
||||
}
|
||||
|
||||
|
|
|
@ -188,28 +188,6 @@ VPBlockBase *VPBlockBase::getEnclosingBlockWithPredecessors() {
|
|||
return Parent->getEnclosingBlockWithPredecessors();
|
||||
}
|
||||
|
||||
VPValue *VPBlockBase::getCondBit() {
|
||||
return CondBitUser.getSingleOperandOrNull();
|
||||
}
|
||||
|
||||
const VPValue *VPBlockBase::getCondBit() const {
|
||||
return CondBitUser.getSingleOperandOrNull();
|
||||
}
|
||||
|
||||
void VPBlockBase::setCondBit(VPValue *CV) { CondBitUser.resetSingleOpUser(CV); }
|
||||
|
||||
VPValue *VPBlockBase::getPredicate() {
|
||||
return PredicateUser.getSingleOperandOrNull();
|
||||
}
|
||||
|
||||
const VPValue *VPBlockBase::getPredicate() const {
|
||||
return PredicateUser.getSingleOperandOrNull();
|
||||
}
|
||||
|
||||
void VPBlockBase::setPredicate(VPValue *CV) {
|
||||
PredicateUser.resetSingleOpUser(CV);
|
||||
}
|
||||
|
||||
void VPBlockBase::deleteCFG(VPBlockBase *Entry) {
|
||||
SmallVector<VPBlockBase *, 8> Blocks(depth_first(Entry));
|
||||
|
||||
|
@ -357,29 +335,6 @@ void VPBasicBlock::execute(VPTransformState *State) {
|
|||
for (VPRecipeBase &Recipe : Recipes)
|
||||
Recipe.execute(*State);
|
||||
|
||||
VPValue *CBV;
|
||||
if (EnableVPlanNativePath && (CBV = getCondBit())) {
|
||||
assert(CBV->getUnderlyingValue() &&
|
||||
"Unexpected null underlying value for condition bit");
|
||||
|
||||
// Condition bit value in a VPBasicBlock is used as the branch selector. In
|
||||
// the VPlan-native path case, since all branches are uniform we generate a
|
||||
// branch instruction using the condition value from vector lane 0 and dummy
|
||||
// successors. The successors are fixed later when the successor blocks are
|
||||
// visited.
|
||||
Value *NewCond = State->get(CBV, {0, 0});
|
||||
|
||||
// Replace the temporary unreachable terminator with the new conditional
|
||||
// branch.
|
||||
auto *CurrentTerminator = NewBB->getTerminator();
|
||||
assert(isa<UnreachableInst>(CurrentTerminator) &&
|
||||
"Expected to replace unreachable terminator with conditional "
|
||||
"branch.");
|
||||
auto *CondBr = BranchInst::Create(NewBB, nullptr, NewCond);
|
||||
CondBr->setSuccessor(0, nullptr);
|
||||
ReplaceInstWithInst(CurrentTerminator, CondBr);
|
||||
}
|
||||
|
||||
LLVM_DEBUG(dbgs() << "LV: filled BB:" << *NewBB);
|
||||
}
|
||||
|
||||
|
@ -428,6 +383,50 @@ VPRegionBlock *VPBasicBlock::getEnclosingLoopRegion() {
|
|||
return P;
|
||||
}
|
||||
|
||||
static bool hasConditionalTerminator(const VPBasicBlock *VPBB) {
|
||||
if (VPBB->empty()) {
|
||||
assert(
|
||||
VPBB->getNumSuccessors() < 2 &&
|
||||
"block with multiple successors doesn't have a recipe as terminator");
|
||||
return false;
|
||||
}
|
||||
|
||||
const VPRecipeBase *R = &VPBB->back();
|
||||
auto *VPI = dyn_cast<VPInstruction>(R);
|
||||
bool IsCondBranch =
|
||||
isa<VPBranchOnMaskRecipe>(R) ||
|
||||
(VPI && (VPI->getOpcode() == VPInstruction::BranchOnCond ||
|
||||
VPI->getOpcode() == VPInstruction::BranchOnCount));
|
||||
|
||||
if (VPBB->getNumSuccessors() >= 2 || VPBB->isExiting()) {
|
||||
assert(IsCondBranch && "block with multiple successors not terminated by "
|
||||
"conditional branch recipe");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
assert(
|
||||
!IsCondBranch &&
|
||||
"block with 0 or 1 successors terminated by conditional branch recipe");
|
||||
return false;
|
||||
}
|
||||
|
||||
VPRecipeBase *VPBasicBlock::getTerminator() {
|
||||
if (hasConditionalTerminator(this))
|
||||
return &back();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const VPRecipeBase *VPBasicBlock::getTerminator() const {
|
||||
if (hasConditionalTerminator(this))
|
||||
return &back();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool VPBasicBlock::isExiting() const {
|
||||
return getParent()->getExitingBasicBlock() == this;
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
void VPBlockBase::printSuccessors(raw_ostream &O, const Twine &Indent) const {
|
||||
if (getSuccessors().empty()) {
|
||||
|
@ -444,13 +443,6 @@ void VPBlockBase::printSuccessors(raw_ostream &O, const Twine &Indent) const {
|
|||
void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
|
||||
VPSlotTracker &SlotTracker) const {
|
||||
O << Indent << getName() << ":\n";
|
||||
if (const VPValue *Pred = getPredicate()) {
|
||||
O << Indent << "BlockPredicate:";
|
||||
Pred->printAsOperand(O, SlotTracker);
|
||||
if (const auto *PredInst = dyn_cast<VPInstruction>(Pred))
|
||||
O << " (" << PredInst->getParent()->getName() << ")";
|
||||
O << '\n';
|
||||
}
|
||||
|
||||
auto RecipeIndent = Indent + " ";
|
||||
for (const VPRecipeBase &Recipe : *this) {
|
||||
|
@ -459,14 +451,6 @@ void VPBasicBlock::print(raw_ostream &O, const Twine &Indent,
|
|||
}
|
||||
|
||||
printSuccessors(O, Indent);
|
||||
|
||||
if (const VPValue *CBV = getCondBit()) {
|
||||
O << Indent << "CondBit: ";
|
||||
CBV->printAsOperand(O, SlotTracker);
|
||||
if (const auto *CBI = dyn_cast<VPInstruction>(CBV))
|
||||
O << " (" << CBI->getParent()->getName() << ")";
|
||||
O << '\n';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -781,6 +765,26 @@ void VPInstruction::generateInstruction(VPTransformState &State,
|
|||
State.set(this, Next, Part);
|
||||
break;
|
||||
}
|
||||
case VPInstruction::BranchOnCond: {
|
||||
if (Part != 0)
|
||||
break;
|
||||
Value *Cond = State.get(getOperand(0), VPIteration(Part, 0));
|
||||
VPRegionBlock *ParentRegion = getParent()->getParent();
|
||||
VPBasicBlock *Header = ParentRegion->getEntryBasicBlock();
|
||||
|
||||
// Replace the temporary unreachable terminator with a new conditional
|
||||
// branch, hooking it up to backward destination for exiting blocks now and
|
||||
// to forward destination(s) later when they are created.
|
||||
BranchInst *CondBr =
|
||||
Builder.CreateCondBr(Cond, Builder.GetInsertBlock(), nullptr);
|
||||
|
||||
if (getParent()->isExiting())
|
||||
CondBr->setSuccessor(1, State.CFG.VPBB2IRBB[Header]);
|
||||
|
||||
CondBr->setSuccessor(0, nullptr);
|
||||
Builder.GetInsertBlock()->getTerminator()->eraseFromParent();
|
||||
break;
|
||||
}
|
||||
case VPInstruction::BranchOnCount: {
|
||||
if (Part != 0)
|
||||
break;
|
||||
|
@ -854,6 +858,9 @@ void VPInstruction::print(raw_ostream &O, const Twine &Indent,
|
|||
case VPInstruction::CanonicalIVIncrementNUW:
|
||||
O << "VF * UF +(nuw) ";
|
||||
break;
|
||||
case VPInstruction::BranchOnCond:
|
||||
O << "branch-on-cond";
|
||||
break;
|
||||
case VPInstruction::BranchOnCount:
|
||||
O << "branch-on-count ";
|
||||
break;
|
||||
|
|
|
@ -351,41 +351,6 @@ struct VPTransformState {
|
|||
Loop *CurrentVectorLoop = nullptr;
|
||||
};
|
||||
|
||||
/// VPUsers instance used by VPBlockBase to manage CondBit and the block
|
||||
/// predicate. Currently VPBlockUsers are used in VPBlockBase for historical
|
||||
/// reasons, but in the future the only VPUsers should either be recipes or
|
||||
/// live-outs.VPBlockBase uses.
|
||||
struct VPBlockUser : public VPUser {
|
||||
VPBlockUser() : VPUser({}, VPUserID::Block) {}
|
||||
|
||||
VPValue *getSingleOperandOrNull() {
|
||||
if (getNumOperands() == 1)
|
||||
return getOperand(0);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
const VPValue *getSingleOperandOrNull() const {
|
||||
if (getNumOperands() == 1)
|
||||
return getOperand(0);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void resetSingleOpUser(VPValue *NewVal) {
|
||||
assert(getNumOperands() <= 1 && "Didn't expect more than one operand!");
|
||||
if (!NewVal) {
|
||||
if (getNumOperands() == 1)
|
||||
removeLastOperand();
|
||||
return;
|
||||
}
|
||||
|
||||
if (getNumOperands() == 1)
|
||||
setOperand(0, NewVal);
|
||||
else
|
||||
addOperand(NewVal);
|
||||
}
|
||||
};
|
||||
|
||||
/// VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
|
||||
/// A VPBlockBase can be either a VPBasicBlock or a VPRegionBlock.
|
||||
class VPBlockBase {
|
||||
|
@ -406,16 +371,6 @@ class VPBlockBase {
|
|||
/// List of successor blocks.
|
||||
SmallVector<VPBlockBase *, 1> Successors;
|
||||
|
||||
/// Successor selector managed by a VPUser. For blocks with zero or one
|
||||
/// successors, there is no operand. Otherwise there is exactly one operand
|
||||
/// which is the branch condition.
|
||||
VPBlockUser CondBitUser;
|
||||
|
||||
/// If the block is predicated, its predicate is stored as an operand of this
|
||||
/// VPUser to maintain the def-use relations. Otherwise there is no operand
|
||||
/// here.
|
||||
VPBlockUser PredicateUser;
|
||||
|
||||
/// VPlan containing the block. Can only be set on the entry block of the
|
||||
/// plan.
|
||||
VPlan *Plan = nullptr;
|
||||
|
@ -561,20 +516,6 @@ public:
|
|||
return getEnclosingBlockWithPredecessors()->getSinglePredecessor();
|
||||
}
|
||||
|
||||
/// \return the condition bit selecting the successor.
|
||||
VPValue *getCondBit();
|
||||
/// \return the condition bit selecting the successor.
|
||||
const VPValue *getCondBit() const;
|
||||
/// Set the condition bit selecting the successor.
|
||||
void setCondBit(VPValue *CV);
|
||||
|
||||
/// \return the block's predicate.
|
||||
VPValue *getPredicate();
|
||||
/// \return the block's predicate.
|
||||
const VPValue *getPredicate() const;
|
||||
/// Set the block's predicate.
|
||||
void setPredicate(VPValue *Pred);
|
||||
|
||||
/// Set a given VPBlockBase \p Successor as the single successor of this
|
||||
/// VPBlockBase. This VPBlockBase is not added as predecessor of \p Successor.
|
||||
/// This VPBlockBase must have no successors.
|
||||
|
@ -584,14 +525,11 @@ public:
|
|||
}
|
||||
|
||||
/// Set two given VPBlockBases \p IfTrue and \p IfFalse to be the two
|
||||
/// successors of this VPBlockBase. \p Condition is set as the successor
|
||||
/// selector. This VPBlockBase is not added as predecessor of \p IfTrue or \p
|
||||
/// IfFalse. This VPBlockBase must have no successors.
|
||||
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse,
|
||||
VPValue *Condition) {
|
||||
/// successors of this VPBlockBase. This VPBlockBase is not added as
|
||||
/// predecessor of \p IfTrue or \p IfFalse. This VPBlockBase must have no
|
||||
/// successors.
|
||||
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse) {
|
||||
assert(Successors.empty() && "Setting two successors when others exist.");
|
||||
assert(Condition && "Setting two successors without condition!");
|
||||
setCondBit(Condition);
|
||||
appendSuccessor(IfTrue);
|
||||
appendSuccessor(IfFalse);
|
||||
}
|
||||
|
@ -608,11 +546,8 @@ public:
|
|||
/// Remove all the predecessor of this block.
|
||||
void clearPredecessors() { Predecessors.clear(); }
|
||||
|
||||
/// Remove all the successors of this block and set to null its condition bit
|
||||
void clearSuccessors() {
|
||||
Successors.clear();
|
||||
setCondBit(nullptr);
|
||||
}
|
||||
/// Remove all the successors of this block.
|
||||
void clearSuccessors() { Successors.clear(); }
|
||||
|
||||
/// The method which generates the output IR that correspond to this
|
||||
/// VPBlockBase, thereby "executing" the VPlan.
|
||||
|
@ -821,6 +756,7 @@ public:
|
|||
CanonicalIVIncrement,
|
||||
CanonicalIVIncrementNUW,
|
||||
BranchOnCount,
|
||||
BranchOnCond
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -909,6 +845,7 @@ public:
|
|||
case Instruction::Unreachable:
|
||||
case Instruction::Fence:
|
||||
case Instruction::AtomicRMW:
|
||||
case VPInstruction::BranchOnCond:
|
||||
case VPInstruction::BranchOnCount:
|
||||
return false;
|
||||
default:
|
||||
|
@ -2098,6 +2035,14 @@ public:
|
|||
using VPBlockBase::print; // Get the print(raw_stream &O) version.
|
||||
#endif
|
||||
|
||||
/// If the block has multiple successors, return the branch recipe terminating
|
||||
/// the block. If there are no or only a single successor, return nullptr;
|
||||
VPRecipeBase *getTerminator();
|
||||
const VPRecipeBase *getTerminator() const;
|
||||
|
||||
/// Returns true if the block is exiting it's parent region.
|
||||
bool isExiting() const;
|
||||
|
||||
private:
|
||||
/// Create an IR BasicBlock to hold the output instructions generated by this
|
||||
/// VPBasicBlock, and return it. Update the CFGState accordingly.
|
||||
|
@ -2785,9 +2730,8 @@ public:
|
|||
/// Insert disconnected VPBlockBase \p NewBlock after \p BlockPtr. Add \p
|
||||
/// NewBlock as successor of \p BlockPtr and \p BlockPtr as predecessor of \p
|
||||
/// NewBlock, and propagate \p BlockPtr parent to \p NewBlock. \p BlockPtr's
|
||||
/// successors are moved from \p BlockPtr to \p NewBlock and \p BlockPtr's
|
||||
/// conditional bit is propagated to \p NewBlock. \p NewBlock must have
|
||||
/// neither successors nor predecessors.
|
||||
/// successors are moved from \p BlockPtr to \p NewBlock. \p NewBlock must
|
||||
/// have neither successors nor predecessors.
|
||||
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) {
|
||||
assert(NewBlock->getSuccessors().empty() &&
|
||||
NewBlock->getPredecessors().empty() &&
|
||||
|
@ -2798,24 +2742,22 @@ public:
|
|||
disconnectBlocks(BlockPtr, Succ);
|
||||
connectBlocks(NewBlock, Succ);
|
||||
}
|
||||
NewBlock->setCondBit(BlockPtr->getCondBit());
|
||||
BlockPtr->setCondBit(nullptr);
|
||||
connectBlocks(BlockPtr, NewBlock);
|
||||
}
|
||||
|
||||
/// Insert disconnected VPBlockBases \p IfTrue and \p IfFalse after \p
|
||||
/// BlockPtr. Add \p IfTrue and \p IfFalse as succesors of \p BlockPtr and \p
|
||||
/// BlockPtr as predecessor of \p IfTrue and \p IfFalse. Propagate \p BlockPtr
|
||||
/// parent to \p IfTrue and \p IfFalse. \p Condition is set as the successor
|
||||
/// selector. \p BlockPtr must have no successors and \p IfTrue and \p IfFalse
|
||||
/// must have neither successors nor predecessors.
|
||||
/// parent to \p IfTrue and \p IfFalse. \p BlockPtr must have no successors
|
||||
/// and \p IfTrue and \p IfFalse must have neither successors nor
|
||||
/// predecessors.
|
||||
static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse,
|
||||
VPValue *Condition, VPBlockBase *BlockPtr) {
|
||||
VPBlockBase *BlockPtr) {
|
||||
assert(IfTrue->getSuccessors().empty() &&
|
||||
"Can't insert IfTrue with successors.");
|
||||
assert(IfFalse->getSuccessors().empty() &&
|
||||
"Can't insert IfFalse with successors.");
|
||||
BlockPtr->setTwoSuccessors(IfTrue, IfFalse, Condition);
|
||||
BlockPtr->setTwoSuccessors(IfTrue, IfFalse);
|
||||
IfTrue->setPredecessors({BlockPtr});
|
||||
IfFalse->setPredecessors({BlockPtr});
|
||||
IfTrue->setParent(BlockPtr->getParent());
|
||||
|
@ -3035,7 +2977,6 @@ bool onlyFirstLaneUsed(VPValue *Def);
|
|||
/// create a new one.
|
||||
VPValue *getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr,
|
||||
ScalarEvolution &SE);
|
||||
|
||||
} // end namespace vputils
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
|
@ -216,10 +216,13 @@ void PlainCFGBuilder::createVPInstructionsForVPBB(VPBasicBlock *VPBB,
|
|||
"Instruction shouldn't have been visited.");
|
||||
|
||||
if (auto *Br = dyn_cast<BranchInst>(Inst)) {
|
||||
// Branch instruction is not explicitly represented in VPlan but we need
|
||||
// to represent its condition bit when it's conditional.
|
||||
if (Br->isConditional())
|
||||
getOrCreateVPOperand(Br->getCondition());
|
||||
// Conditional branch instruction are represented using BranchOnCond
|
||||
// recipes.
|
||||
if (Br->isConditional()) {
|
||||
VPValue *Cond = getOrCreateVPOperand(Br->getCondition());
|
||||
VPBB->appendRecipe(
|
||||
new VPInstruction(VPInstruction::BranchOnCond, {Cond}));
|
||||
}
|
||||
|
||||
// Skip the rest of the Instruction processing for Branch instructions.
|
||||
continue;
|
||||
|
@ -310,10 +313,9 @@ VPBasicBlock *PlainCFGBuilder::buildPlainCFG() {
|
|||
// representing the condition bit in VPlan (which may be in another VPBB).
|
||||
assert(IRDef2VPValue.count(BrCond) &&
|
||||
"Missing condition bit in IRDef2VPValue!");
|
||||
VPValue *VPCondBit = IRDef2VPValue[BrCond];
|
||||
|
||||
// Link successors using condition bit.
|
||||
VPBB->setTwoSuccessors(SuccVPBB0, SuccVPBB1, VPCondBit);
|
||||
// Link successors.
|
||||
VPBB->setTwoSuccessors(SuccVPBB0, SuccVPBB1);
|
||||
} else
|
||||
llvm_unreachable("Number of successors not supported.");
|
||||
|
||||
|
|
|
@ -27,8 +27,12 @@ void VPlanTransforms::VPInstructionsToVPRecipes(
|
|||
ReversePostOrderTraversal<VPBlockRecursiveTraversalWrapper<VPBlockBase *>>
|
||||
RPOT(Plan->getEntry());
|
||||
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
|
||||
VPRecipeBase *Term = VPBB->getTerminator();
|
||||
auto EndIter = Term ? Term->getIterator() : VPBB->end();
|
||||
// Introduce each ingredient into VPlan.
|
||||
for (VPRecipeBase &Ingredient : llvm::make_early_inc_range(*VPBB)) {
|
||||
for (VPRecipeBase &Ingredient :
|
||||
make_early_inc_range(make_range(VPBB->begin(), EndIter))) {
|
||||
|
||||
VPValue *VPV = Ingredient.getVPSingleValue();
|
||||
Instruction *Inst = cast<Instruction>(VPV->getUnderlyingValue());
|
||||
if (DeadInstructions.count(Inst)) {
|
||||
|
|
|
@ -209,9 +209,6 @@ public:
|
|||
enum class VPUserID {
|
||||
Recipe,
|
||||
LiveOut,
|
||||
// TODO: Currently VPUsers are used in VPBlockBase, but in the future the
|
||||
// only VPUsers should either be recipes or live-outs.
|
||||
Block
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -49,11 +49,14 @@ static void verifyBlocksInRegion(const VPRegionBlock *Region) {
|
|||
// Check block's parent.
|
||||
assert(VPB->getParent() == Region && "VPBlockBase has wrong parent");
|
||||
|
||||
auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
|
||||
// Check block's condition bit.
|
||||
if (VPB->getNumSuccessors() > 1 || Region->getExitingBasicBlock() == VPB)
|
||||
assert(VPB->getCondBit() && "Missing condition bit!");
|
||||
if (VPB->getNumSuccessors() > 1 || (VPBB && VPBB->isExiting()))
|
||||
assert(VPBB && VPBB->getTerminator() &&
|
||||
"Block has multiple successors but doesn't "
|
||||
"have a proper branch recipe!");
|
||||
else
|
||||
assert(!VPB->getCondBit() && "Unexpected condition bit!");
|
||||
assert((!VPBB || !VPBB->getTerminator()) && "Unexpected branch recipe!");
|
||||
|
||||
// Check block's successors.
|
||||
const auto &Successors = VPB->getSuccessors();
|
||||
|
|
|
@ -32,7 +32,6 @@ define void @sink_replicate_region_1(i32 %x, i8* %ptr) optsize {
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
|
||||
|
@ -54,7 +53,6 @@ define void @sink_replicate_region_1(i32 %x, i8* %ptr) optsize {
|
|||
; CHECK-NEXT: pred.srem.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.srem.if, pred.srem.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.srem.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
|
||||
|
@ -128,7 +126,6 @@ define void @sink_replicate_region_2(i32 %x, i8 %y, i32* %ptr) optsize {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x>
|
||||
|
@ -201,7 +198,6 @@ define i32 @sink_replicate_region_3_reduction(i32 %x, i8 %y, i32* %ptr) optsize
|
|||
; CHECK-NEXT: pred.srem.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.srem.if, pred.srem.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.srem.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
|
||||
|
@ -278,7 +274,6 @@ define void @sink_replicate_region_4_requires_split_at_end_of_block(i32 %x, i8*
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%lv> = load ir<%gep> (S->V)
|
||||
|
@ -302,7 +297,6 @@ define void @sink_replicate_region_4_requires_split_at_end_of_block(i32 %x, i8*
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
|
||||
; CHECK: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x> (S->V)
|
||||
|
@ -383,7 +377,6 @@ define void @sink_replicate_region_after_replicate_region(i32* %ptr, i32 %x, i8
|
|||
; CHECK-NEXT: pred.srem.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.srem.if, pred.srem.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.srem.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%rem> = srem vp<[[SPLICE]]>, ir<%x>
|
||||
|
@ -402,7 +395,6 @@ define void @sink_replicate_region_after_replicate_region(i32* %ptr, i32 %x, i8
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%rem.div> = sdiv ir<20>, vp<[[PRED]]>
|
||||
|
|
|
@ -58,7 +58,6 @@ for.end:
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[COND]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[COND]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep> = getelementptr ir<%ptr>, vp<[[STEPS]]>
|
||||
|
|
|
@ -26,16 +26,16 @@ define void @foo(i64 %n) {
|
|||
; CHECK-NEXT: EMIT store ir<%add> ir<%gep.2>
|
||||
; CHECK-NEXT: EMIT ir<%inner.iv.next> = add ir<%inner.iv> ir<1>
|
||||
; CHECK-NEXT: EMIT ir<%inner.ec> = icmp ir<%inner.iv.next> ir<8>
|
||||
; CHECK-NEXT: EMIT branch-on-cond ir<%inner.ec>
|
||||
; CHECK-NEXT: No successors
|
||||
; CHECK-NEXT: CondBit: ir<%inner.ec> (inner)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Successor(s): outer.latch
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: outer.latch:
|
||||
; CHECK-NEXT: EMIT ir<%outer.iv.next> = add ir<%outer.iv> ir<1>
|
||||
; CHECK-NEXT: EMIT ir<%outer.ec> = icmp ir<%outer.iv.next> ir<8>
|
||||
; CHECK-NEXT: EMIT branch-on-cond ir<%outer.ec>
|
||||
; CHECK-NEXT: No successors
|
||||
; CHECK-NEXT: CondBit: ir<%outer.ec> (outer.latch)
|
||||
; CHECK-NEXT: }
|
||||
; CHECK-NEXT: Successor(s): exit
|
||||
; CHECK-EMPTY:
|
||||
|
|
|
@ -215,7 +215,6 @@ define void @print_replicate_predicated_phi(i64 %n, i64* %x) {
|
|||
; CHECK-NEXT: pred.udiv.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK ir<%cmp>
|
||||
; CHECK-NEXT: Successor(s): pred.udiv.if, pred.udiv.continue
|
||||
; CHECK-NEXT: CondBit: ir<%cmp>
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.udiv.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%tmp4> = udiv ir<%n>, vp<[[STEPS]]> (S->V)
|
||||
|
@ -420,7 +419,6 @@ define void @debug_loc_vpinstruction(i32* nocapture %asd, i32* nocapture %bsd) !
|
|||
; CHECK-NEXT: pred.sdiv.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[OR1]]>
|
||||
; CHECK-NEXT: Successor(s): pred.sdiv.if, pred.sdiv.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[OR1]]> (if.then)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.sdiv.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%sd1> = sdiv ir<%psd>, ir<%lsd> (S->V)
|
||||
|
|
|
@ -31,7 +31,6 @@ define void @sink_with_sideeffects(i1 %c, i8* %ptr) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK ir<%c>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: ir<%c>
|
||||
|
||||
; CHECK: pred.store.if:
|
||||
; CHECK-NEXT: CLONE store ir<%tmp5>, ir<%tmp2>
|
||||
|
|
|
@ -33,7 +33,6 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
|
||||
; CHECK: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<@b>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -100,7 +99,6 @@ exit:
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
|
||||
; CHECK: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<@b>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -120,7 +118,6 @@ exit:
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
|
||||
; CHECK: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%add> = add vp<[[PRED]]>, ir<10>
|
||||
|
@ -183,7 +180,6 @@ exit:
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
|
||||
; CHECK: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<@b>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -204,7 +200,6 @@ exit:
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
|
||||
; CHECK: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr ir<@a>, ir<0>, ir<%mul>
|
||||
|
@ -270,7 +265,6 @@ define void @uniform_gep(i64 %k, i16* noalias %A, i16* noalias %B) {
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%lv> = load ir<%gep.A.uniform>
|
||||
|
@ -295,7 +289,6 @@ define void @uniform_gep(i64 %k, i16* noalias %A, i16* noalias %B) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK2]]> (loop.then)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.B> = getelementptr ir<%B>, vp<[[STEPS]]>
|
||||
|
@ -368,7 +361,6 @@ define void @pred_cfg1(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK2]]> (then.0)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<@b>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -395,7 +387,6 @@ define void @pred_cfg1(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[OR]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[OR]]> (next.0)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr ir<@a>, ir<0>, ir<%mul>
|
||||
|
@ -474,7 +465,6 @@ define void @pred_cfg2(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK2]]> (then.0)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<@b>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -505,7 +495,6 @@ define void @pred_cfg2(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK4]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK4]]> (then.1)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr ir<@a>, ir<0>, ir<%mul>
|
||||
|
@ -593,7 +582,6 @@ define void @pred_cfg3(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK2]]> (then.0)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.b> = getelementptr ir<@b>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -623,7 +611,6 @@ define void @pred_cfg3(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK5]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK5]]> (then.1)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.a> = getelementptr ir<@a>, ir<0>, ir<%mul>
|
||||
|
@ -711,7 +698,6 @@ define void @merge_3_replicate_region(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%lv.a> = load ir<%gep.a>
|
||||
|
@ -742,7 +728,6 @@ define void @merge_3_replicate_region(i32 %k, i32 %j) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK2]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK2]]> (then.0)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep.c.1> = getelementptr ir<@c>, ir<0>, vp<[[STEPS]]>
|
||||
|
@ -827,7 +812,6 @@ define void @update_2_uses_in_same_recipe_in_merged_block(i32 %k) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%lv.a> = load ir<%gep.a>
|
||||
|
@ -893,7 +877,6 @@ define void @recipe_in_merge_candidate_used_by_first_order_recurrence(i32 %k) {
|
|||
; CHECK-NEXT: pred.load.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.load.if, pred.load.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.load.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%lv.a> = load ir<%gep.a>
|
||||
|
@ -916,7 +899,6 @@ define void @recipe_in_merge_candidate_used_by_first_order_recurrence(i32 %k) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (vector.body)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%div> = sdiv vp<[[SPLICE]]>, vp<[[PRED]]>
|
||||
|
@ -980,7 +962,6 @@ define void @update_multiple_users(i16* noalias %src, i8* noalias %dst, i1 %c) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK ir<%c>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: ir<%c>
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%l1> = load ir<%src>
|
||||
|
@ -1059,7 +1040,6 @@ define void @sinking_requires_duplication(float* %addr) {
|
|||
; CHECK-NEXT: pred.store.entry:
|
||||
; CHECK-NEXT: BRANCH-ON-MASK vp<[[MASK]]>
|
||||
; CHECK-NEXT: Successor(s): pred.store.if, pred.store.continue
|
||||
; CHECK-NEXT: CondBit: vp<[[MASK]]> (then)
|
||||
; CHECK-EMPTY:
|
||||
; CHECK-NEXT: pred.store.if:
|
||||
; CHECK-NEXT: REPLICATE ir<%gep> = getelementptr ir<%addr>, vp<[[STEPS]]>
|
||||
|
|
|
@ -45,7 +45,6 @@ TEST_F(VPlanHCFGTest, testBuildHCFGInnerLoop) {
|
|||
EXPECT_NE(nullptr, Entry->getSingleSuccessor());
|
||||
EXPECT_EQ(0u, Entry->getNumPredecessors());
|
||||
EXPECT_EQ(1u, Entry->getNumSuccessors());
|
||||
EXPECT_EQ(nullptr, Entry->getCondBit());
|
||||
|
||||
// Check that the region following the preheader is a single basic-block
|
||||
// region (loop).
|
||||
|
@ -91,7 +90,6 @@ TEST_F(VPlanHCFGTest, testBuildHCFGInnerLoop) {
|
|||
EXPECT_EQ(Instruction::ICmp, ICmp->getOpcode());
|
||||
EXPECT_EQ(2u, ICmp->getNumOperands());
|
||||
EXPECT_EQ(IndvarAdd, ICmp->getOperand(0));
|
||||
EXPECT_EQ(VecBB->getCondBit(), ICmp);
|
||||
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
// Add an external value to check we do not print the list of external values,
|
||||
|
@ -123,7 +121,6 @@ compound=true
|
|||
" EMIT ir\<%indvars.iv.next\> = add ir\<%indvars.iv\> ir\<1\>\l" +
|
||||
" EMIT ir\<%exitcond\> = icmp ir\<%indvars.iv.next\> ir\<%N\>\l" +
|
||||
"No successors\l" +
|
||||
"CondBit: ir\<%exitcond\> (vector.body)\l"
|
||||
]
|
||||
}
|
||||
N1 -> N3 [ label="" ltail=cluster_N2]
|
||||
|
|
Loading…
Reference in New Issue