<p dir="ltr">Yep, if there was no proper fix yet, then it should probably be just reverted.</p>
<div class="gmail_extra"><br><div class="gmail_quote">On Jul 25, 2016 21:03, "Hans Wennborg" <<a href="mailto:hans@chromium.org">hans@chromium.org</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Maybe we should merge this to 3.9? It looks like this reverts a patch<br>
that was committed soon before the branch.<br>
<br>
On Mon, Jul 18, 2016 at 8:51 AM, Alexander Kornienko via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: alexfh<br>
> Date: Mon Jul 18 10:51:31 2016<br>
> New Revision: 275801<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=275801&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=275801&view=rev</a><br>
> Log:<br>
> Revert "r275571 [DSE]Enhance shorthening MemIntrinsic based on OverlapIntervals"<br>
><br>
> Causes <a href="https://llvm.org/bugs/show_bug.cgi?id=28588" rel="noreferrer" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=28588</a><br>
><br>
> Modified:<br>
> llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
> llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll<br>
> llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll<br>
><br>
> Modified: llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=275801&r1=275800&r2=275801&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp?rev=275801&r1=275800&r2=275801&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp (original)<br>
> +++ llvm/trunk/lib/Transforms/Scalar/DeadStoreElimination.cpp Mon Jul 18 10:51:31 2016<br>
> @@ -290,8 +290,8 @@ enum OverwriteResult {<br>
> };<br>
> }<br>
><br>
> -typedef std::map<int64_t, int64_t> OverlapIntervalsTy;<br>
> -typedef DenseMap<Instruction *, OverlapIntervalsTy> InstOverlapIntervalsTy;<br>
> +typedef DenseMap<Instruction *,<br>
> + std::map<int64_t, int64_t>> InstOverlapIntervalsTy;<br>
><br>
> /// Return 'OverwriteComplete' if a store to the 'Later' location completely<br>
> /// overwrites a store to the 'Earlier' location, 'OverwriteEnd' if the end of<br>
> @@ -438,9 +438,9 @@ static OverwriteResult isOverwrite(const<br>
> //<br>
> // In this case we may want to trim the size of earlier to avoid generating<br>
> // writes to addresses which will definitely be overwritten later<br>
> - if (!EnablePartialOverwriteTracking &&<br>
> - (LaterOff > EarlierOff && LaterOff < int64_t(EarlierOff + Earlier.Size) &&<br>
> - int64_t(LaterOff + Later.Size) >= int64_t(EarlierOff + Earlier.Size)))<br>
> + if (LaterOff > EarlierOff &&<br>
> + LaterOff < int64_t(EarlierOff + Earlier.Size) &&<br>
> + int64_t(LaterOff + Later.Size) >= int64_t(EarlierOff + Earlier.Size))<br>
> return OverwriteEnd;<br>
><br>
> // Finally, we also need to check if the later store overwrites the beginning<br>
> @@ -452,11 +452,9 @@ static OverwriteResult isOverwrite(const<br>
> // In this case we may want to move the destination address and trim the size<br>
> // of earlier to avoid generating writes to addresses which will definitely<br>
> // be overwritten later.<br>
> - if (!EnablePartialOverwriteTracking &&<br>
> - (LaterOff <= EarlierOff && int64_t(LaterOff + Later.Size) > EarlierOff)) {<br>
> - assert(int64_t(LaterOff + Later.Size) <<br>
> - int64_t(EarlierOff + Earlier.Size) &&<br>
> - "Expect to be handled as OverwriteComplete");<br>
> + if (LaterOff <= EarlierOff && int64_t(LaterOff + Later.Size) > EarlierOff) {<br>
> + assert (int64_t(LaterOff + Later.Size) < int64_t(EarlierOff + Earlier.Size)<br>
> + && "Expect to be handled as OverwriteComplete" );<br>
> return OverwriteBegin;<br>
> }<br>
> // Otherwise, they don't completely overlap.<br>
> @@ -821,119 +819,6 @@ static bool handleEndBlock(BasicBlock &B<br>
> return MadeChange;<br>
> }<br>
><br>
> -static bool tryToShorten(Instruction *EarlierWrite, int64_t &EarlierOffset,<br>
> - int64_t &EarlierSize, int64_t LaterOffset,<br>
> - int64_t LaterSize, bool IsOverwriteEnd) {<br>
> - // TODO: base this on the target vector size so that if the earlier<br>
> - // store was too small to get vector writes anyway then its likely<br>
> - // a good idea to shorten it<br>
> - // Power of 2 vector writes are probably always a bad idea to optimize<br>
> - // as any store/memset/memcpy is likely using vector instructions so<br>
> - // shortening it to not vector size is likely to be slower<br>
> - MemIntrinsic *EarlierIntrinsic = cast<MemIntrinsic>(EarlierWrite);<br>
> - unsigned EarlierWriteAlign = EarlierIntrinsic->getAlignment();<br>
> - if (!IsOverwriteEnd)<br>
> - LaterOffset = int64_t(LaterOffset + LaterSize);<br>
> -<br>
> - if (!(llvm::isPowerOf2_64(LaterOffset) && EarlierWriteAlign <= LaterOffset) &&<br>
> - !((EarlierWriteAlign != 0) && LaterOffset % EarlierWriteAlign == 0))<br>
> - return false;<br>
> -<br>
> - DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW "<br>
> - << (IsOverwriteEnd ? "END" : "BEGIN") << ": " << *EarlierWrite<br>
> - << "\n KILLER (offset " << LaterOffset << ", " << EarlierSize<br>
> - << ")\n");<br>
> -<br>
> - int64_t NewLength = IsOverwriteEnd<br>
> - ? LaterOffset - EarlierOffset<br>
> - : EarlierSize - (LaterOffset - EarlierOffset);<br>
> -<br>
> - Value *EarlierWriteLength = EarlierIntrinsic->getLength();<br>
> - Value *TrimmedLength =<br>
> - ConstantInt::get(EarlierWriteLength->getType(), NewLength);<br>
> - EarlierIntrinsic->setLength(TrimmedLength);<br>
> -<br>
> - EarlierSize = NewLength;<br>
> - if (!IsOverwriteEnd) {<br>
> - int64_t OffsetMoved = (LaterOffset - EarlierOffset);<br>
> - Value *Indices[1] = {<br>
> - ConstantInt::get(EarlierWriteLength->getType(), OffsetMoved)};<br>
> - GetElementPtrInst *NewDestGEP = GetElementPtrInst::CreateInBounds(<br>
> - EarlierIntrinsic->getRawDest(), Indices, "", EarlierWrite);<br>
> - EarlierIntrinsic->setDest(NewDestGEP);<br>
> - EarlierOffset = EarlierOffset + OffsetMoved;<br>
> - }<br>
> - return true;<br>
> -}<br>
> -<br>
> -static bool tryToShortenEnd(Instruction *EarlierWrite,<br>
> - OverlapIntervalsTy &IntervalMap,<br>
> - int64_t &EarlierStart, int64_t &EarlierSize) {<br>
> - if (IntervalMap.empty() || !isShortenableAtTheEnd(EarlierWrite))<br>
> - return false;<br>
> -<br>
> - OverlapIntervalsTy::iterator OII = --IntervalMap.end();<br>
> - int64_t LaterStart = OII->second;<br>
> - int64_t LaterSize = OII->first - LaterStart;<br>
> -<br>
> - if (LaterStart > EarlierStart && LaterStart < EarlierStart + EarlierSize &&<br>
> - LaterStart + LaterSize >= EarlierStart + EarlierSize) {<br>
> - if (tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart,<br>
> - LaterSize, true)) {<br>
> - IntervalMap.erase(OII);<br>
> - return true;<br>
> - }<br>
> - }<br>
> - return false;<br>
> -}<br>
> -<br>
> -static bool tryToShortenBegin(Instruction *EarlierWrite,<br>
> - OverlapIntervalsTy &IntervalMap,<br>
> - int64_t &EarlierStart, int64_t &EarlierSize) {<br>
> - if (IntervalMap.empty() || !isShortenableAtTheBeginning(EarlierWrite))<br>
> - return false;<br>
> -<br>
> - OverlapIntervalsTy::iterator OII = IntervalMap.begin();<br>
> - int64_t LaterStart = OII->second;<br>
> - int64_t LaterSize = OII->first - LaterStart;<br>
> -<br>
> - if (LaterStart <= EarlierStart && LaterStart + LaterSize > EarlierStart) {<br>
> - assert(LaterStart + LaterSize < EarlierStart + EarlierSize &&<br>
> - "Should have been handled as OverwriteComplete");<br>
> - if (tryToShorten(EarlierWrite, EarlierStart, EarlierSize, LaterStart,<br>
> - LaterSize, false)) {<br>
> - IntervalMap.erase(OII);<br>
> - return true;<br>
> - }<br>
> - }<br>
> - return false;<br>
> -}<br>
> -<br>
> -static bool removePartiallyOverlappedStores(AliasAnalysis *AA,<br>
> - const DataLayout &DL,<br>
> - InstOverlapIntervalsTy &IOL) {<br>
> - bool Changed = false;<br>
> - for (auto OI : IOL) {<br>
> - Instruction *EarlierWrite = OI.first;<br>
> - MemoryLocation Loc = getLocForWrite(EarlierWrite, *AA);<br>
> - assert(isRemovable(EarlierWrite) && "Expect only removable instruction");<br>
> - assert(Loc.Size != MemoryLocation::UnknownSize && "Unexpected mem loc");<br>
> -<br>
> - const Value *Ptr = Loc.Ptr->stripPointerCasts();<br>
> - int64_t EarlierStart = 0;<br>
> - int64_t EarlierSize = int64_t(Loc.Size);<br>
> - GetPointerBaseWithConstantOffset(Ptr, EarlierStart, DL);<br>
> - OverlapIntervalsTy &IntervalMap = OI.second;<br>
> - Changed =<br>
> - tryToShortenEnd(EarlierWrite, IntervalMap, EarlierStart, EarlierSize);<br>
> - if (IntervalMap.empty())<br>
> - continue;<br>
> - Changed |=<br>
> - tryToShortenBegin(EarlierWrite, IntervalMap, EarlierStart, EarlierSize);<br>
> - }<br>
> - return Changed;<br>
> -}<br>
> -<br>
> static bool eliminateNoopStore(Instruction *Inst, BasicBlock::iterator &BBI,<br>
> AliasAnalysis *AA, MemoryDependenceResults *MD,<br>
> const DataLayout &DL,<br>
> @@ -1051,7 +936,7 @@ static bool eliminateDeadStores(BasicBlo<br>
> if (OR == OverwriteComplete) {<br>
> DEBUG(dbgs() << "DSE: Remove Dead Store:\n DEAD: "<br>
> << *DepWrite << "\n KILLER: " << *Inst << '\n');<br>
> - IOL.erase(DepWrite);<br>
> +<br>
> // Delete the store and now-dead instructions that feed it.<br>
> deleteDeadInstruction(DepWrite, &BBI, *MD, *TLI);<br>
> ++NumFastStores;<br>
> @@ -1063,14 +948,48 @@ static bool eliminateDeadStores(BasicBlo<br>
> } else if ((OR == OverwriteEnd && isShortenableAtTheEnd(DepWrite)) ||<br>
> ((OR == OverwriteBegin &&<br>
> isShortenableAtTheBeginning(DepWrite)))) {<br>
> - assert(!EnablePartialOverwriteTracking && "Do not expect to perform "<br>
> - "when partial-overwrite "<br>
> - "tracking is enabled");<br>
> - int64_t EarlierSize = DepLoc.Size;<br>
> - int64_t LaterSize = Loc.Size;<br>
> + // TODO: base this on the target vector size so that if the earlier<br>
> + // store was too small to get vector writes anyway then its likely<br>
> + // a good idea to shorten it<br>
> + // Power of 2 vector writes are probably always a bad idea to optimize<br>
> + // as any store/memset/memcpy is likely using vector instructions so<br>
> + // shortening it to not vector size is likely to be slower<br>
> + MemIntrinsic *DepIntrinsic = cast<MemIntrinsic>(DepWrite);<br>
> + unsigned DepWriteAlign = DepIntrinsic->getAlignment();<br>
> bool IsOverwriteEnd = (OR == OverwriteEnd);<br>
> - MadeChange = tryToShorten(DepWrite, DepWriteOffset, EarlierSize,<br>
> - InstWriteOffset, LaterSize, IsOverwriteEnd);<br>
> + if (!IsOverwriteEnd)<br>
> + InstWriteOffset = int64_t(InstWriteOffset + Loc.Size);<br>
> +<br>
> + if ((llvm::isPowerOf2_64(InstWriteOffset) &&<br>
> + DepWriteAlign <= InstWriteOffset) ||<br>
> + ((DepWriteAlign != 0) && InstWriteOffset % DepWriteAlign == 0)) {<br>
> +<br>
> + DEBUG(dbgs() << "DSE: Remove Dead Store:\n OW "<br>
> + << (IsOverwriteEnd ? "END" : "BEGIN") << ": "<br>
> + << *DepWrite << "\n KILLER (offset "<br>
> + << InstWriteOffset << ", " << DepLoc.Size << ")"<br>
> + << *Inst << '\n');<br>
> +<br>
> + int64_t NewLength =<br>
> + IsOverwriteEnd<br>
> + ? InstWriteOffset - DepWriteOffset<br>
> + : DepLoc.Size - (InstWriteOffset - DepWriteOffset);<br>
> +<br>
> + Value *DepWriteLength = DepIntrinsic->getLength();<br>
> + Value *TrimmedLength =<br>
> + ConstantInt::get(DepWriteLength->getType(), NewLength);<br>
> + DepIntrinsic->setLength(TrimmedLength);<br>
> +<br>
> + if (!IsOverwriteEnd) {<br>
> + int64_t OffsetMoved = (InstWriteOffset - DepWriteOffset);<br>
> + Value *Indices[1] = {<br>
> + ConstantInt::get(DepWriteLength->getType(), OffsetMoved)};<br>
> + GetElementPtrInst *NewDestGEP = GetElementPtrInst::CreateInBounds(<br>
> + DepIntrinsic->getRawDest(), Indices, "", DepWrite);<br>
> + DepIntrinsic->setDest(NewDestGEP);<br>
> + }<br>
> + MadeChange = true;<br>
> + }<br>
> }<br>
> }<br>
><br>
> @@ -1093,9 +1012,6 @@ static bool eliminateDeadStores(BasicBlo<br>
> }<br>
> }<br>
><br>
> - if (EnablePartialOverwriteTracking)<br>
> - MadeChange |= removePartiallyOverlappedStores(AA, DL, IOL);<br>
> -<br>
> // If this block ends in a return, unwind, or unreachable, all allocas are<br>
> // dead at its end, which means stores to them are also dead.<br>
> if (BB.getTerminator()->getNumSuccessors() == 0)<br>
><br>
> Modified: llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll?rev=275801&r1=275800&r2=275801&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll?rev=275801&r1=275800&r2=275801&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll (original)<br>
> +++ llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreBegin.ll Mon Jul 18 10:51:31 2016<br>
> @@ -86,23 +86,5 @@ entry:<br>
> ret void<br>
> }<br>
><br>
> -define void @write8To15AndThen0To7(i64* nocapture %P) {<br>
> -entry:<br>
> -; CHECK-LABEL: @write8To15AndThen0To7(<br>
> -; CHECK: [[GEP:%[0-9]+]] = getelementptr inbounds i8, i8* %mybase0, i64 16<br>
> -; CHECK: tail call void @llvm.memset.p0i8.i64(i8* [[GEP]], i8 0, i64 16, i32 8, i1 false)<br>
> -<br>
> - %base0 = bitcast i64* %P to i8*<br>
> - %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0<br>
> - tail call void @llvm.memset.p0i8.i64(i8* %mybase0, i8 0, i64 32, i32 8, i1 false)<br>
> -<br>
> - %base64_0 = getelementptr inbounds i64, i64* %P, i64 0<br>
> - %base64_1 = getelementptr inbounds i64, i64* %P, i64 1<br>
> -<br>
> - store i64 1, i64* %base64_1<br>
> - store i64 2, i64* %base64_0<br>
> - ret void<br>
> -}<br>
> -<br>
> declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1) nounwind<br>
><br>
><br>
> Modified: llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll?rev=275801&r1=275800&r2=275801&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll?rev=275801&r1=275800&r2=275801&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll (original)<br>
> +++ llvm/trunk/test/Transforms/DeadStoreElimination/OverwriteStoreEnd.ll Mon Jul 18 10:51:31 2016<br>
> @@ -93,20 +93,3 @@ entry:<br>
> store i64 3, i64* %tf_trapno, align 8<br>
> ret void<br>
> }<br>
> -<br>
> -define void @write16To23AndThen24To31(i64* nocapture %P, i64 %n64, i32 %n32, i16 %n16, i8 %n8) {<br>
> -entry:<br>
> -; CHECK-LABEL: @write16To23AndThen24To31(<br>
> -; CHECK: tail call void @llvm.memset.p0i8.i64(i8* %mybase0, i8 0, i64 16, i32 8, i1 false)<br>
> -<br>
> - %base0 = bitcast i64* %P to i8*<br>
> - %mybase0 = getelementptr inbounds i8, i8* %base0, i64 0<br>
> - tail call void @llvm.memset.p0i8.i64(i8* %mybase0, i8 0, i64 32, i32 8, i1 false)<br>
> -<br>
> - %base64_2 = getelementptr inbounds i64, i64* %P, i64 2<br>
> - %base64_3 = getelementptr inbounds i64, i64* %P, i64 3<br>
> -<br>
> - store i64 3, i64* %base64_2<br>
> - store i64 3, i64* %base64_3<br>
> - ret void<br>
> -}<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div></div>