diff options
author | Alexander Kornienko <alexfh@google.com> | 2022-12-16 16:43:58 +0100 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2022-12-16 17:23:35 +0100 |
commit | 37b8f09a4b61bf9bf9d0b9017d790c8b82be2e17 (patch) | |
tree | a5c1fbee7839ef7c95761eddbb29996b13116b51 /llvm/lib/Transforms/Utils/SimplifyCFG.cpp | |
parent | 7f8bd8ac0658b5e75049fd5c04fcf8c31352f397 (diff) | |
download | llvm-37b8f09a4b61bf9bf9d0b9017d790c8b82be2e17.zip llvm-37b8f09a4b61bf9bf9d0b9017d790c8b82be2e17.tar.gz llvm-37b8f09a4b61bf9bf9d0b9017d790c8b82be2e17.tar.bz2 |
Revert "[SimplifyCFG] `FoldBranchToCommonDest()`: deal with mismatched IV's in PHI's in common successor block"
This reverts commit 1bd0b82e508d049efdb07f4f8a342f35818df341, since it leads to
miscompiles. See https://reviews.llvm.org/D139275#3993229 and
https://reviews.llvm.org/D139275#4001580.
Diffstat (limited to 'llvm/lib/Transforms/Utils/SimplifyCFG.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/SimplifyCFG.cpp | 159 |
1 files changed, 5 insertions, 154 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp index 1095931..d5c3f2a 100644 --- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp +++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp @@ -3566,67 +3566,7 @@ shouldFoldCondBranchesToCommonDestination(BranchInst *BI, BranchInst *PBI, return std::nullopt; } -struct CompatibleIncomingValue { - Value *V; - CompatibleIncomingValue() = default; - CompatibleIncomingValue(Value *V_) : V(V_) {} - operator Value *() const { return V; } -}; -struct SelectMaterializationRecipe { - Value *Cond = nullptr; - Value *TrueVal = nullptr; - Value *FalseVal = nullptr; -}; -// Maintain recipes on how to deal with each of the PHI nodes in the common -// successor block when coming from it's two predecessors, one of which also -// branches to the other one. For each PHI, we may either have an preexisting -// Value that we can use when branching from the common predecessor, or we have -// (an uniqued!) recipe on how to compute such a value via a select. -// This cache is unique, and is maintained per the predecessor block. -struct SelectCache { - using UniqueSelectIndex = unsigned; - SmallDenseMap<SelectMaterializationRecipe, UniqueSelectIndex, 2> SelectCSE; - SmallVector<std::variant<CompatibleIncomingValue, UniqueSelectIndex>, 2> Phis; -}; - -static bool operator==(const SelectMaterializationRecipe &A, - const SelectMaterializationRecipe &B) { - return std::tie(A.Cond, A.TrueVal, A.FalseVal) == - std::tie(B.Cond, B.TrueVal, B.FalseVal); -} - -namespace llvm { -template <> struct DenseMapInfo<SelectMaterializationRecipe> { - static SelectMaterializationRecipe getEmptyKey() { - SelectMaterializationRecipe R; - for (Value **E : {&R.Cond, &R.TrueVal, &R.FalseVal}) - *E = DenseMapInfo<Value *>::getEmptyKey(); - return R; - } - - static SelectMaterializationRecipe getTombstoneKey() { - SelectMaterializationRecipe R; - for (Value **E : {&R.Cond, &R.TrueVal, &R.FalseVal}) - *E = DenseMapInfo<Value *>::getTombstoneKey(); - return R; - } - - static unsigned getHashValue(SelectMaterializationRecipe R) { - return static_cast<unsigned>( - hash_combine(DenseMapInfo<Value *>::getHashValue(R.Cond), - DenseMapInfo<Value *>::getHashValue(R.TrueVal), - DenseMapInfo<Value *>::getHashValue(R.FalseVal))); - } - - static bool isEqual(SelectMaterializationRecipe LHS, - SelectMaterializationRecipe RHS) { - return LHS == RHS; - } -}; -} // namespace llvm - static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, - SelectCache *Cache, DomTreeUpdater *DTU, MemorySSAUpdater *MSSAU, const TargetTransformInfo *TTI) { @@ -3655,7 +3595,6 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, if (NewCond->hasOneUse() && isa<CmpInst>(NewCond)) { CmpInst *CI = cast<CmpInst>(NewCond); CI->setPredicate(CI->getInversePredicate()); - CI->setName(CI->getName() + ".not"); } else { NewCond = Builder.CreateNot(NewCond, PBI->getCondition()->getName() + ".not"); @@ -3663,14 +3602,6 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, PBI->setCondition(NewCond); PBI->swapSuccessors(); - - if (Cache) { - // And likewise, for the select recipes. - for (auto &I : Cache->SelectCSE) { - I.first.Cond = NewCond; - std::swap(I.first.TrueVal, I.first.FalseVal); - } - } } BasicBlock *UniqueSucc = @@ -3736,45 +3667,6 @@ static bool performBranchToCommonDestFolding(BranchInst *BI, BranchInst *PBI, ValueToValueMapTy VMap; // maps original values to cloned values CloneInstructionsIntoPredecessorBlockAndUpdateSSAUses(BB, PredBlock, VMap); - assert((bool)Cache == !std::empty(CommonSucc->phis())); - if (Cache) { - SmallVector<std::pair<SelectMaterializationRecipe, Value *>, 2> - UniqueSelects; - UniqueSelects.resize(Cache->SelectCSE.size()); - for (auto I : Cache->SelectCSE) - UniqueSelects[I.second].first = I.first; - - for (auto I : zip(CommonSucc->phis(), Cache->Phis)) { - PHINode &PN = std::get<0>(I); - std::variant<CompatibleIncomingValue, SelectCache::UniqueSelectIndex> - &PhiRecipe = std::get<1>(I); - - // Now, we have a recipe on how to deal with this PHI node. Either, there - // is an existing Value that we can use as an Incoming Value for the new - // predecessor we add, or we have a recipe for a select that will compute - // the Value the PHI node would have taken when coming from old BB's. - Value **MaterializedSelect; - if (auto *V = std::get_if<CompatibleIncomingValue>(&PhiRecipe)) { - MaterializedSelect = &V->V; - } else { - unsigned UniqSelIdx = - std::get<SelectCache::UniqueSelectIndex>(PhiRecipe); - const SelectMaterializationRecipe &SelRecipe = - UniqueSelects[UniqSelIdx].first; - MaterializedSelect = &UniqueSelects[UniqSelIdx].second; - if (!*MaterializedSelect) { - *MaterializedSelect = - Builder.CreateSelect(SelRecipe.Cond, SelRecipe.TrueVal, - SelRecipe.FalseVal, PN.getName() + ".sel"); - if (auto *I = dyn_cast<Instruction>(*MaterializedSelect)) - RemapInstruction(I, VMap, - RF_NoModuleLevelChanges | RF_IgnoreMissingLocals); - } - } - PN.setIncomingValueForBlock(PredBlock, *MaterializedSelect); - } - } - // Now that the Cond was cloned into the predecessor basic block, // or/and the two conditions together. Value *BICond = VMap[BI->getCondition()]; @@ -3832,11 +3724,6 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, if (is_contained(successors(BB), BB)) return false; - SmallDenseMap<BasicBlock *, SelectCache> PerPredBBCaches; - - unsigned NumSelectsNeeded = 0; - bool SawVectorSelect = false; - // With which predecessors will we want to deal with? SmallVector<BasicBlock *, 8> Preds; for (BasicBlock *PredBlock : predecessors(BB)) { @@ -3845,7 +3732,7 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, // Check that we have two conditional branches. If there is a PHI node in // the common successor, verify that the same value flows in from both // blocks. - if (!PBI || PBI->isUnconditional()) + if (!PBI || PBI->isUnconditional() || !SafeToMergeTerminators(BI, PBI)) continue; // Determine if the two branches share a common destination. @@ -3863,45 +3750,13 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, Type *Ty = BI->getCondition()->getType(); InstructionCost Cost = TTI->getArithmeticInstrCost(Opc, Ty, CostKind); if (InvertPredCond && (!PBI->getCondition()->hasOneUse() || - !isa<CmpInst>(PBI->getCondition()))) + !isa<CmpInst>(PBI->getCondition()))) Cost += TTI->getArithmeticInstrCost(Instruction::Xor, Ty, CostKind); if (Cost > BranchFoldThreshold) continue; } - SelectCache *Cache = nullptr; - if (!std::empty(CommonSucc->phis())) - Cache = &PerPredBBCaches.insert({PredBlock, SelectCache()}) - .first->getSecond(); - auto getIncomingBlockInCommonSuccessor = [CommonSucc, PredBlock, - BB](BasicBlock *SuccOfPredBB) { - if (SuccOfPredBB == CommonSucc) - return PredBlock; - assert(SuccOfPredBB == BB); - return BB; - }; - for (PHINode &PN : CommonSucc->phis()) { - SelectMaterializationRecipe R; - R.Cond = PBI->getCondition(); - R.TrueVal = PN.getIncomingValueForBlock( - getIncomingBlockInCommonSuccessor(PBI->getSuccessor(0))); - R.FalseVal = PN.getIncomingValueForBlock( - getIncomingBlockInCommonSuccessor(PBI->getSuccessor(1))); - if (R.TrueVal == R.FalseVal) { - Cache->Phis.emplace_back(R.TrueVal); // CompatibleIncomingValue - continue; - } - // FIXME: can we get better results by using InstSimplify here? - auto [iterator, NewUniqueSelect] = - Cache->SelectCSE.insert({R, Cache->SelectCSE.size()}); - Cache->Phis.emplace_back(iterator->second); // UniqueSelectIndex - if (!NewUniqueSelect) - continue; - ++NumSelectsNeeded; - SawVectorSelect |= PN.getType()->isVectorTy(); - } - // Ok, we do want to deal with this predecessor. Record it. Preds.emplace_back(PredBlock); } @@ -3917,8 +3772,8 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, // as "bonus instructions", and only allow this transformation when the // number of the bonus instructions we'll need to create when cloning into // each predecessor does not exceed a certain threshold. - unsigned NumBonusInsts = NumSelectsNeeded; - bool SawVectorOp = SawVectorSelect; + unsigned NumBonusInsts = 0; + bool SawVectorOp = false; const unsigned PredCount = Preds.size(); for (Instruction &I : *BB) { // Don't check the branch condition comparison itself. @@ -3963,11 +3818,7 @@ bool llvm::FoldBranchToCommonDest(BranchInst *BI, DomTreeUpdater *DTU, // Ok, we have the budget. Perform the transformation. for (BasicBlock *PredBlock : Preds) { auto *PBI = cast<BranchInst>(PredBlock->getTerminator()); - - SelectCache *Cache = nullptr; - if (auto it = PerPredBBCaches.find(PredBlock); it != PerPredBBCaches.end()) - Cache = &it->second; - return performBranchToCommonDestFolding(BI, PBI, Cache, DTU, MSSAU, TTI); + return performBranchToCommonDestFolding(BI, PBI, DTU, MSSAU, TTI); } return false; } |