diff options
Diffstat (limited to 'llvm/lib/Transforms/Scalar/LICM.cpp')
| -rw-r--r-- | llvm/lib/Transforms/Scalar/LICM.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp index 1be0d053b7b..93ee25cbfb8 100644 --- a/llvm/lib/Transforms/Scalar/LICM.cpp +++ b/llvm/lib/Transforms/Scalar/LICM.cpp @@ -1924,9 +1924,21 @@ bool llvm::promoteLoopAccessesToScalars( SawUnorderedAtomic |= Load->isAtomic(); SawNotAtomic |= !Load->isAtomic(); - if (!DereferenceableInPH) - DereferenceableInPH = isSafeToExecuteUnconditionally( - *Load, DT, CurLoop, SafetyInfo, ORE, Preheader->getTerminator()); + unsigned InstAlignment = Load->getAlignment(); + if (!InstAlignment) + InstAlignment = + MDL.getABITypeAlignment(Load->getType()); + + // Note that proving a load safe to speculate requires proving + // sufficient alignment at the target location. Proving it guaranteed + // to execute does as well. Thus we can increase our guaranteed + // alignment as well. + if (!DereferenceableInPH || (InstAlignment > Alignment)) + if (isSafeToExecuteUnconditionally(*Load, DT, CurLoop, SafetyInfo, + ORE, Preheader->getTerminator())) { + DereferenceableInPH = true; + Alignment = std::max(Alignment, InstAlignment); + } } else if (const StoreInst *Store = dyn_cast<StoreInst>(UI)) { // Stores *of* the pointer are not interesting, only stores *to* the // pointer. @@ -1997,6 +2009,14 @@ bool llvm::promoteLoopAccessesToScalars( if (SawUnorderedAtomic && SawNotAtomic) return false; + // If we're inserting an atomic load in the preheader, we must be able to + // lower it. We're only guaranteed to be able to lower naturally aligned + // atomics. + auto *SomePtrElemType = SomePtr->getType()->getPointerElementType(); + if (SawUnorderedAtomic && + Alignment < MDL.getTypeStoreSize(SomePtrElemType)) + return false; + // If we couldn't prove we can hoist the load, bail. if (!DereferenceableInPH) return false; |

