summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Utils/SimplifyCFG.cpp35
1 files changed, 30 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 1204a94a32a..1ee1e388def 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2860,7 +2860,8 @@ static Value *ensureValueAvailableInSuccessor(Value *V, BasicBlock *BB,
static bool mergeConditionalStoreToAddress(BasicBlock *PTB, BasicBlock *PFB,
BasicBlock *QTB, BasicBlock *QFB,
BasicBlock *PostBB, Value *Address,
- bool InvertPCond, bool InvertQCond) {
+ bool InvertPCond, bool InvertQCond,
+ const DataLayout &DL) {
auto IsaBitcastOfPointerType = [](const Instruction &I) {
return Operator::getOpcode(&I) == Instruction::BitCast &&
I.getType()->isPointerTy();
@@ -2966,6 +2967,29 @@ static bool mergeConditionalStoreToAddress(BasicBlock *PTB, BasicBlock *PFB,
PStore->getAAMetadata(AAMD, /*Merge=*/false);
PStore->getAAMetadata(AAMD, /*Merge=*/true);
SI->setAAMetadata(AAMD);
+ unsigned PAlignment = PStore->getAlignment();
+ unsigned QAlignment = QStore->getAlignment();
+ unsigned TypeAlignment =
+ DL.getABITypeAlignment(SI->getValueOperand()->getType());
+ unsigned MinAlignment;
+ unsigned MaxAlignment;
+ std::tie(MinAlignment, MaxAlignment) = std::minmax(PAlignment, QAlignment);
+ // Choose the minimum alignment. If we could prove both stores execute, we
+ // could use biggest one. In this case, though, we only know that one of the
+ // stores executes. And we don't know it's safe to take the alignment from a
+ // store that doesn't execute.
+ if (MinAlignment != 0) {
+ // Choose the minimum of all non-zero alignments.
+ SI->setAlignment(MinAlignment);
+ } else if (MaxAlignment != 0) {
+ // Choose the minimal alignment between the non-zero alignment and the ABI
+ // default alignment for the type of the stored value.
+ SI->setAlignment(std::min(MaxAlignment, TypeAlignment));
+ } else {
+ // If both alignments are zero, use ABI default alignment for the type of
+ // the stored value.
+ SI->setAlignment(TypeAlignment);
+ }
QStore->eraseFromParent();
PStore->eraseFromParent();
@@ -2973,7 +2997,8 @@ static bool mergeConditionalStoreToAddress(BasicBlock *PTB, BasicBlock *PFB,
return true;
}
-static bool mergeConditionalStores(BranchInst *PBI, BranchInst *QBI) {
+static bool mergeConditionalStores(BranchInst *PBI, BranchInst *QBI,
+ const DataLayout &DL) {
// The intention here is to find diamonds or triangles (see below) where each
// conditional block contains a store to the same address. Both of these
// stores are conditional, so they can't be unconditionally sunk. But it may
@@ -3076,7 +3101,7 @@ static bool mergeConditionalStores(BranchInst *PBI, BranchInst *QBI) {
bool Changed = false;
for (auto *Address : CommonAddresses)
Changed |= mergeConditionalStoreToAddress(
- PTB, PFB, QTB, QFB, PostBB, Address, InvertPCond, InvertQCond);
+ PTB, PFB, QTB, QFB, PostBB, Address, InvertPCond, InvertQCond, DL);
return Changed;
}
@@ -3141,7 +3166,7 @@ static bool SimplifyCondBranchToCondBranch(BranchInst *PBI, BranchInst *BI,
// 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.
- if (MergeCondStores && mergeConditionalStores(PBI, BI))
+ if (MergeCondStores && mergeConditionalStores(PBI, BI, DL))
return true;
// If this is a conditional branch in an empty block, and if any
@@ -5829,7 +5854,7 @@ bool SimplifyCFGOpt::SimplifyCondBranch(BranchInst *BI, IRBuilder<> &Builder) {
if (BasicBlock *PrevBB = allPredecessorsComeFromSameSource(BB))
if (BranchInst *PBI = dyn_cast<BranchInst>(PrevBB->getTerminator()))
if (PBI != BI && PBI->isConditional())
- if (mergeConditionalStores(PBI, BI))
+ if (mergeConditionalStores(PBI, BI, DL))
return SimplifyCFG(BB, TTI, BonusInstThreshold, AC) | true;
return false;
OpenPOWER on IntegriCloud