diff --git a/debian/changelog b/debian/changelog index d4c437f0..13a83f85 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,9 +11,12 @@ llvm-toolchain-snapshot (1:8~svn336894-1~exp1) experimental; urgency=medium clang_Type_getObjCObjectBaseType clang_Type_getObjCProtocolDecl clang_Type_getObjCTypeArg - * python-recommonmark is a new build dep for the sphinx doc + * python-recommonmark is a new build dep for the sphinx doc + * Disable force-gcc-header-obj.diff as it is introducing + some regressions in the search headers + (Closes: #903709) - -- Sylvestre Ledru Sun, 12 Aug 2018 13:19:15 +0200 + -- Sylvestre Ledru Wed, 15 Aug 2018 15:35:08 +0200 llvm-toolchain-7 (1:7~+rc1-1~exp1) experimental; urgency=medium @@ -27,6 +30,8 @@ llvm-toolchain-7 (1:7~+rc1-1~exp1) experimental; urgency=medium [ Reshabh Sharma ] * Integrate libcxx and libcxxabi as part of the llvm-toolchain packages + Very similar to the previous packages + except that libc++abi-7-test & libc++-7-test are no longer shipped Outcome of the LLVM GSoC 2018 (Closes: #813673) @@ -1386,7 +1391,7 @@ llvm-toolchain-snapshot (1:3.5~svn195337-1) unstable; urgency=low * Switch from 3.4 to 3.5 * Remove patch 0046-Revert-Patch-to-set-is_stmt-a-little-better-for-prol.patch - Useless now and missleading + Useless now and misleading * Standards-Version updated to 3.9.5 * kfreebsd.diff remove (applied upstream) @@ -1533,7 +1538,7 @@ llvm-toolchain-3.4 (1:3.4~+rc1-1) unstable; urgency=low * New testing upstream release * kfreebsd.diff removed. Applied upstream * Remove patch 0046-Revert-Patch-to-set-is_stmt-a-little-better-for-prol.patch - Useless now and missleading + Useless now and misleading * Branch from llvm-toolchain-snapshot * Standards-Version updated to 3.9.5 diff --git a/debian/clang++-libc++-X.Y.in b/debian/clang++-libc++-X.Y.in deleted file mode 100644 index 40690829..00000000 --- a/debian/clang++-libc++-X.Y.in +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -clang++ -stdlib=libc++ "$@" diff --git a/debian/clang++-libc++.in b/debian/clang++-libc++.in new file mode 100755 index 00000000..46b56505 --- /dev/null +++ b/debian/clang++-libc++.in @@ -0,0 +1,2 @@ +#!/bin/sh +clang++-@LLVM_VERSION@ -stdlib=libc++ "$@" diff --git a/debian/control b/debian/control index c88dc367..05aae016 100644 --- a/debian/control +++ b/debian/control @@ -445,7 +445,7 @@ Description: Next generation, high-performance debugger, library Package: python-lldb-8 Section: python -Architecture: amd64 armel armhf i386 kfreebsd-amd64 kfreebsd-i386 ppc64el s390 sparc hppa m68k sh4 x32 mips mipsel arm64 +Architecture: amd64 armel armhf i386 kfreebsd-amd64 kfreebsd-i386 s390 sparc hppa m68k sh4 x32 mips mipsel arm64 ppc64el # ia64 mips mipsel hurd powerpc powerpcspe ppc64 alpha s390x sparc64 have been removed Depends: ${shlibs:Depends}, ${misc:Depends}, liblldb-8-dev, python, python-six Conflicts: python-lldb-3.8, python-lldb-3.9, python-lldb-x.y @@ -462,7 +462,7 @@ Description: Next generation, high-performance debugger, python lib Package: liblldb-8-dev Section: libdevel -Architecture: amd64 armel armhf i386 kfreebsd-amd64 kfreebsd-i386 ppc64el s390 sparc hppa m68k sh4 x32 mips mipsel arm64 +Architecture: amd64 armel armhf i386 kfreebsd-amd64 kfreebsd-i386 s390 sparc hppa m68k sh4 x32 mips mipsel arm64 ppc64el # ia64 mips mipsel hurd powerpc powerpcspe ppc64 alpha s390x sparc64 have been removed Depends: ${shlibs:Depends}, ${misc:Depends}, lldb-8 (= ${binary:Version}) Replaces: lldb-8-dev (<= 8~svn215195-2) @@ -526,6 +526,9 @@ Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Depends: ${shlibs:Depends}, ${misc:Depends} Suggests: clang +Replaces: libc++1 +Breaks: libc++1 +Provides: libc++1 Description: LLVM C++ Standard library libc++ is another implementation of the C++ standard library. . @@ -546,6 +549,7 @@ Multi-Arch: same Depends: libc++1-8 (= ${binary:Version}), ${misc:Depends}, libc++-helpers Provides: libstdc++-dev, libc++-8-dev Breaks: libc++-dev +Replaces: libc++-dev Description: LLVM C++ Standard library (development files) libc++ is another implementation of the C++ standard library . @@ -559,27 +563,6 @@ Description: LLVM C++ Standard library (development files) as exception objects, rtti and memory allocation. * Extensive unit tests. -Package: libc++-8-test -Section: libs -Architecture: any -Depends: libc++1-8 (= ${binary:Version}), ${misc:Depends} -Breaks: libc++-test -Provides: libc++-test -Description: LLVM C++ Standard library (test cases) - libc++ is another implementation of the C++ standard library. - . - Features and Goals - . - * Correctness as defined by the standards. - * Fast execution. - * Minimal memory use. - * Fast compile times. - * ABI compatibility with gcc's libstdc++ for some low-level features such - as exception objects, rtti and memory allocation. - * Extensive unit tests. - . - This package contains the test cases of libc++ library. - # ------------- libcxxabi ------------- Package: libc++abi1-8 @@ -590,6 +573,7 @@ Pre-Depends: ${misc:Pre-Depends} Depends: ${shlibs:Depends}, ${misc:Depends} Breaks: libc++abi1 Provides: libc++abi1 +Replaces: libc++abi1 Description: LLVM low level support for a standard C++ library libc++abi is another implementation of low level support for a standard C++ library. @@ -605,8 +589,9 @@ Section: libdevel Architecture: any Multi-Arch: same Depends: libc++abi1-8 (= ${binary:Version}), ${misc:Depends} -Replaces: libc++-8-dev (<< 3.9.0-3) -Breaks: libc++-dev (<< 3.9.0-3), libc++-8-dev +Replaces: libc++-8-dev +Breaks: libc++-dev , libc++-8-dev, libc++abi-dev +Provides: libc++-dev , libc++-8-dev, libc++abi-dev Description: LLVM low level support for a standard C++ library (development files) libc++abi is another implementation of low level support for a standard C++ library. @@ -617,30 +602,13 @@ Description: LLVM low level support for a standard C++ library (development file * Provide a portable sublayer to ease the porting of libc++ . -Package: libc++abi-8-test -Section: libs -Architecture: any -Depends: libc++abi1-8 (= ${binary:Version}), ${misc:Depends} -Breaks: libc++abi-test -Provides: libc++abi-test -Description: libc++abi test cases - libc++abi is another implementation of low level support for a standard C++ - library. - . - Features and Goals - . - * Correctness as defined by the C++ standards. - * Provide a portable sublayer to ease the porting of libc++ - . - Test cases of libc++abi library. - - Package: libc++-8-helpers Architecture: all Multi-Arch: foreign Depends: ${misc:Depends} -Breaks: libc++-8-helpers +Breaks: libc++-helpers Provides: libc++-helpers +Replaces: libc++-helpers Description: LLVM C++ Standard library - build helpers libc++ is another implementation of the C++ standard library . diff --git a/debian/copyright b/debian/copyright index ae2def30..dce9d49b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -361,6 +361,7 @@ Files: utils/unittest/googletest/* Copyright: 2006-2008, Google Inc. License: BSD-3-Clause +Files: libcxx/* License: BSD-3-Clause This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -378,6 +379,62 @@ License: BSD-3-Clause misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. +Files: libcxx*/* +Copyright: 2009-2012 by the contributors listed below + N: Howard Hinnant + E: hhinnant@apple.com + D: Architect and primary author of libc++ + . + N: Marshall Clow + E: marshall@idio.com + E: mclow@qualcomm.com + D: Minor patches and bug fixes. + . + N: Bjorn Reese + E: breese@users.sourceforge.net + D: Initial regex prototype + . + N: David Chisnall + E: theraven at theravensnest dot org + D: FreeBSD and Solaris ports, libcxxrt support, some atomics work. + . + N: Ruben Van Boxem + E: vanboxem dot ruben at gmail dot com + D: Initial Windows patches. + . + N: Arvid Picciani + E: aep at exys dot org + D: Minor patches and musl port. + . + N: Craig Silverstein + E: csilvers@google.com + D: Implemented Cityhash as the string hash function on 64-bit machines + . + N: Google Inc. + D: Copyright owner and contributor of the CityHash algorithm + . + N: Jeffrey Yasskin + E: jyasskin@gmail.com + E: jyasskin@google.com + D: Linux fixes. + . + N: Jonathan Sauer + D: Minor patches, mostly related to constexpr + . + N: Richard Smith + D: Minor patches. + . + The list is sorted by surname and formatted to allow easy grepping and + beautification by scripts. The fields are: name (N), email (E), web-address + (W), PGP key ID and fingerprint (P), description (D), and snail-mail address + (S). + . +License: NCSA or MIT + +Files: openmp/* +Copyright: 1997-2015 Intel Corporation +License: U-OF-I-BSD-LIKE + License: U-OF-I-BSD-LIKE ============================================================================== LLVM Release License diff --git a/debian/g++-libc++-X.Y.in b/debian/g++-libc++.in old mode 100644 new mode 100755 similarity index 100% rename from debian/g++-libc++-X.Y.in rename to debian/g++-libc++.in diff --git a/debian/libc++-X.Y-dev.install.in b/debian/libc++-X.Y-dev.install.in index 4baaf7d9..c65c7df2 100644 --- a/debian/libc++-X.Y-dev.install.in +++ b/debian/libc++-X.Y-dev.install.in @@ -1,3 +1,5 @@ usr/lib/llvm-@LLVM_VERSION@/lib/libc++.so -usr/lib/llvm-@LLVM_VERSION@/lib/libc++*.a -usr/lib/llvm-@LLVM_VERSION@/include/c++/* usr/lib/llvm-@LLVM_VERSION@/include/c++ +usr/lib/llvm-@LLVM_VERSION@/lib/libc++.a +usr/lib/llvm-@LLVM_VERSION@/lib/libc++fs.a +usr/lib/llvm-@LLVM_VERSION@/lib/libc++experimental.a +usr/lib/llvm-@LLVM_VERSION@/include/c++/* usr/lib/llvm-@LLVM_VERSION@/include/c++/v1 diff --git a/debian/libc++-X.Y-dev.lintian-overrides.in b/debian/libc++-X.Y-dev.lintian-overrides.in new file mode 100644 index 00000000..f3a3487b --- /dev/null +++ b/debian/libc++-X.Y-dev.lintian-overrides.in @@ -0,0 +1,3 @@ +libc++-@LLVM_VERSION@-dev: arch-dependent-file-not-in-arch-specific-directory usr/lib/llvm-@LLVM_VERSION@/lib/libc++.a +libc++-@LLVM_VERSION@-dev: arch-dependent-file-not-in-arch-specific-directory usr/lib/llvm-@LLVM_VERSION@/lib/libc++fs.a +libc++-@LLVM_VERSION@-dev: arch-dependent-file-not-in-arch-specific-directory usr/lib/llvm-@LLVM_VERSION@/lib/libc++experimental.a diff --git a/debian/libc++-X.Y-helpers.install.in b/debian/libc++-X.Y-helpers.install.in index 11bf449d..2cc801a1 100644 --- a/debian/libc++-X.Y-helpers.install.in +++ b/debian/libc++-X.Y-helpers.install.in @@ -1,2 +1,2 @@ -debian/clang++-libc++-@LLVM_VERSION@ usr/lib/llvm-@LLVM_VERSION@/bin/ -debian/g++-libc++-@LLVM_VERSION@ usr/lib/llvm-@LLVM_VERSION@/bin/ +debian/clang++-libc++ usr/lib/llvm-@LLVM_VERSION@/bin/ +debian/g++-libc++ usr/lib/llvm-@LLVM_VERSION@/bin/ diff --git a/debian/libc++-X.Y-helpers.links.in b/debian/libc++-X.Y-helpers.links.in index db9e72a6..2ef8d040 100644 --- a/debian/libc++-X.Y-helpers.links.in +++ b/debian/libc++-X.Y-helpers.links.in @@ -1,2 +1,2 @@ -usr/lib/llvm-@LLVM_VERSION@/bin/clang++-libc++-@LLVM_VERSION@ usr/bin/clang++-libc++-@LLVM_VERSION@ -usr/lib/llvm-@LLVM_VERSION@/bin/g++-libc++-@LLVM_VERSION@ usr/bin/g++-libc++-@LLVM_VERSION@ +usr/lib/llvm-@LLVM_VERSION@/bin/clang++-libc++-@LLVM_VERSION@ usr/bin/clang++-libc++ +usr/lib/llvm-@LLVM_VERSION@/bin/g++-libc++-@LLVM_VERSION@ usr/bin/g++-libc++ diff --git a/debian/libc++1-X.Y.install.in b/debian/libc++1-X.Y.install.in index 78e2cd3b..217769f8 100644 --- a/debian/libc++1-X.Y.install.in +++ b/debian/libc++1-X.Y.install.in @@ -1 +1 @@ -usr/lib/llvm-@LLVM_VERSION@/lib/libc++.so.* +usr/lib/llvm-@LLVM_VERSION@/lib/libc++.so* diff --git a/debian/libc++1-X.Y.links.in b/debian/libc++1-X.Y.links.in index 11f2a253..4d1955c5 100644 --- a/debian/libc++1-X.Y.links.in +++ b/debian/libc++1-X.Y.links.in @@ -1 +1,2 @@ -usr/lib/llvm-@LLVM_VERSION@/lib/libc++.so.1 /usr/lib/@DEB_HOST_MULTIARCH@/libc++.so.1 +usr/lib/llvm-@LLVM_VERSION@/lib/libc++.so.1.0 /usr/lib/@DEB_HOST_MULTIARCH@/libc++.so.1.0 +/usr/lib/@DEB_HOST_MULTIARCH@/libc++.so.1.0 /usr/lib/@DEB_HOST_MULTIARCH@/libc++.so.1 diff --git a/debian/libc++1-X.Y.lintian-overrides.in b/debian/libc++1-X.Y.lintian-overrides.in new file mode 100644 index 00000000..d8d46f92 --- /dev/null +++ b/debian/libc++1-X.Y.lintian-overrides.in @@ -0,0 +1 @@ +libc++1-@LLVM_VERSION@: arch-dependent-file-not-in-arch-specific-directory usr/lib/llvm-@LLVM_VERSION@/lib/libc++.so.1.0 diff --git a/debian/libc++abi-X.Y-dev.install.in b/debian/libc++abi-X.Y-dev.install.in index 8ac83468..8774c6ae 100644 --- a/debian/libc++abi-X.Y-dev.install.in +++ b/debian/libc++abi-X.Y-dev.install.in @@ -1,3 +1,3 @@ -usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.so +usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi*so usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.a -usr/lib/llvm-@LLVM_VERSION@/include/c++/v1/*cxxabi* +libcxxabi/include/* usr/lib/llvm-@LLVM_VERSION@/include/ diff --git a/debian/libc++abi-X.Y-dev.links.in b/debian/libc++abi-X.Y-dev.links.in index 85bcc0dd..6dd5f555 100644 --- a/debian/libc++abi-X.Y-dev.links.in +++ b/debian/libc++abi-X.Y-dev.links.in @@ -1,4 +1 @@ -usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.a /usr/lib/@DEB_HOST_MULTIARCH@/libc++abi.a usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.so /usr/lib/@DEB_HOST_MULTIARCH@/libc++abi.so -usr/lib/llvm-@LLVM_VERSION@/include/c++/v1/cxxabi.h /usr/include/c++/v1/cxxabi.h -usr/lib/llvm-@LLVM_VERSION@/include/c++/v1/__cxxabi_config.h /usr/include/c++/v1/__cxxabi_config.h diff --git a/debian/libc++abi-X.Y-dev.lintian-overrides.in b/debian/libc++abi-X.Y-dev.lintian-overrides.in new file mode 100644 index 00000000..e0aa6ed4 --- /dev/null +++ b/debian/libc++abi-X.Y-dev.lintian-overrides.in @@ -0,0 +1 @@ +libc++abi-@LLVM_VERSION@-dev: arch-dependent-file-not-in-arch-specific-directory usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.a diff --git a/debian/libc++abi1-X.Y.install.in b/debian/libc++abi1-X.Y.install.in index 5723df4a..4c93b5e9 100644 --- a/debian/libc++abi1-X.Y.install.in +++ b/debian/libc++abi1-X.Y.install.in @@ -1 +1 @@ -usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi* +usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.so* diff --git a/debian/libc++abi1-X.Y.links.in b/debian/libc++abi1-X.Y.links.in index 3486ecbf..a57ef065 100644 --- a/debian/libc++abi1-X.Y.links.in +++ b/debian/libc++abi1-X.Y.links.in @@ -1 +1,2 @@ -usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.so.1 /usr/lib/@DEB_HOST_MULTIARCH@/libc++abi.so.1 +usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.so.1.0 /usr/lib/@DEB_HOST_MULTIARCH@/libc++abi.so.1.0 +/usr/lib/@DEB_HOST_MULTIARCH@/libc++abi.so.1.0 /usr/lib/@DEB_HOST_MULTIARCH@/libc++abi.so.1 diff --git a/debian/libc++abi1-X.Y.lintian-overrides.in b/debian/libc++abi1-X.Y.lintian-overrides.in new file mode 100644 index 00000000..f51d4b1e --- /dev/null +++ b/debian/libc++abi1-X.Y.lintian-overrides.in @@ -0,0 +1 @@ +libc++abi1-@LLVM_VERSION@: arch-dependent-file-not-in-arch-specific-directory usr/lib/llvm-@LLVM_VERSION@/lib/libc++abi.so.1.0 diff --git a/debian/patches/D40146-JumpThreading-backport-1.diff b/debian/patches/D40146-JumpThreading-backport-1.diff new file mode 100644 index 00000000..25415a37 --- /dev/null +++ b/debian/patches/D40146-JumpThreading-backport-1.diff @@ -0,0 +1,2148 @@ +Index: llvm-toolchain-6.0-6.0.1/include/llvm/IR/Dominators.h +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/include/llvm/IR/Dominators.h ++++ llvm-toolchain-6.0-6.0.1/include/llvm/IR/Dominators.h +@@ -290,6 +290,90 @@ public: + void print(raw_ostream &OS, const Module *M = nullptr) const override; + }; + ++//===------------------------------------- ++/// \brief Class to defer updates to a DominatorTree. ++/// ++/// Definition: Applying updates to every edge insertion and deletion is ++/// expensive and not necessary. When one needs the DominatorTree for analysis ++/// they can request a flush() to perform a larger batch update. This has the ++/// advantage of the DominatorTree inspecting the set of updates to find ++/// duplicates or unnecessary subtree updates. ++/// ++/// The scope of DeferredDominance operates at a Function level. ++/// ++/// It is not necessary for the user to scrub the updates for duplicates or ++/// updates that point to the same block (Delete, BB_A, BB_A). Performance ++/// can be gained if the caller attempts to batch updates before submitting ++/// to applyUpdates(ArrayRef) in cases where duplicate edge requests will ++/// occur. ++/// ++/// It is required for the state of the LLVM IR to be applied *before* ++/// submitting updates. The update routines must analyze the current state ++/// between a pair of (From, To) basic blocks to determine if the update ++/// needs to be queued. ++/// Example (good): ++/// TerminatorInstructionBB->removeFromParent(); ++/// DDT->deleteEdge(BB, Successor); ++/// Example (bad): ++/// DDT->deleteEdge(BB, Successor); ++/// TerminatorInstructionBB->removeFromParent(); ++class DeferredDominance { ++public: ++ DeferredDominance(DominatorTree &DT_) : DT(DT_) {} ++ ++ /// \brief Queues multiple updates and discards duplicates. ++ void applyUpdates(ArrayRef Updates); ++ ++ /// \brief Helper method for a single edge insertion. It's almost always ++ /// better to batch updates and call applyUpdates to quickly remove duplicate ++ /// edges. This is best used when there is only a single insertion needed to ++ /// update Dominators. ++ void insertEdge(BasicBlock *From, BasicBlock *To); ++ ++ /// \brief Helper method for a single edge deletion. It's almost always better ++ /// to batch updates and call applyUpdates to quickly remove duplicate edges. ++ /// This is best used when there is only a single deletion needed to update ++ /// Dominators. ++ void deleteEdge(BasicBlock *From, BasicBlock *To); ++ ++ /// \brief Delays the deletion of a basic block until a flush() event. ++ void deleteBB(BasicBlock *DelBB); ++ ++ /// \brief Returns true if DelBB is awaiting deletion at a flush() event. ++ bool pendingDeletedBB(BasicBlock *DelBB); ++ ++ /// \brief Flushes all pending updates and block deletions. Returns a ++ /// correct DominatorTree reference to be used by the caller for analysis. ++ DominatorTree &flush(); ++ ++ /// \brief Drops all internal state and forces a (slow) recalculation of the ++ /// DominatorTree based on the current state of the LLVM IR in F. This should ++ /// only be used in corner cases such as the Entry block of F being deleted. ++ void recalculate(Function &F); ++ ++ /// \brief Debug method to help view the state of pending updates. ++ LLVM_DUMP_METHOD void dump() const; ++ ++private: ++ DominatorTree &DT; ++ SmallVector PendUpdates; ++ SmallPtrSet DeletedBBs; ++ ++ /// Apply an update (Kind, From, To) to the internal queued updates. The ++ /// update is only added when determined to be necessary. Checks for ++ /// self-domination, unnecessary updates, duplicate requests, and balanced ++ /// pairs of requests are all performed. Returns true if the update is ++ /// queued and false if it is discarded. ++ bool applyUpdate(DominatorTree::UpdateKind Kind, BasicBlock *From, ++ BasicBlock *To); ++ ++ /// Performs all pending basic block deletions. We have to defer the deletion ++ /// of these blocks until after the DominatorTree updates are applied. The ++ /// internal workings of the DominatorTree code expect every update's From ++ /// and To blocks to exist and to be a member of the same Function. ++ bool flushDelBB(); ++}; ++ + } // end namespace llvm + + #endif // LLVM_IR_DOMINATORS_H +Index: llvm-toolchain-6.0-6.0.1/include/llvm/Transforms/Scalar/JumpThreading.h +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/include/llvm/Transforms/Scalar/JumpThreading.h ++++ llvm-toolchain-6.0-6.0.1/include/llvm/Transforms/Scalar/JumpThreading.h +@@ -34,6 +34,7 @@ class BinaryOperator; + class BranchInst; + class CmpInst; + class Constant; ++class DeferredDominance; + class Function; + class Instruction; + class IntrinsicInst; +@@ -77,6 +78,7 @@ class JumpThreadingPass : public PassInf + TargetLibraryInfo *TLI; + LazyValueInfo *LVI; + AliasAnalysis *AA; ++ DeferredDominance *DDT; + std::unique_ptr BFI; + std::unique_ptr BPI; + bool HasProfileData = false; +@@ -107,8 +109,8 @@ public: + + // Glue for old PM. + bool runImpl(Function &F, TargetLibraryInfo *TLI_, LazyValueInfo *LVI_, +- AliasAnalysis *AA_, bool HasProfileData_, +- std::unique_ptr BFI_, ++ AliasAnalysis *AA_, DeferredDominance *DDT_, ++ bool HasProfileData_, std::unique_ptr BFI_, + std::unique_ptr BPI_); + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +Index: llvm-toolchain-6.0-6.0.1/include/llvm/Transforms/Utils/BasicBlockUtils.h +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/include/llvm/Transforms/Utils/BasicBlockUtils.h ++++ llvm-toolchain-6.0-6.0.1/include/llvm/Transforms/Utils/BasicBlockUtils.h +@@ -27,6 +27,7 @@ namespace llvm { + + class BlockFrequencyInfo; + class BranchProbabilityInfo; ++class DeferredDominance; + class DominatorTree; + class Function; + class Instruction; +@@ -38,7 +39,7 @@ class TargetLibraryInfo; + class Value; + + /// Delete the specified block, which must have no predecessors. +-void DeleteDeadBlock(BasicBlock *BB); ++void DeleteDeadBlock(BasicBlock *BB, DeferredDominance *DDT = nullptr); + + /// We know that BB has one predecessor. If there are any single-entry PHI nodes + /// in it, fold them away. This handles the case when all entries to the PHI +Index: llvm-toolchain-6.0-6.0.1/include/llvm/Transforms/Utils/Local.h +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/include/llvm/Transforms/Utils/Local.h ++++ llvm-toolchain-6.0-6.0.1/include/llvm/Transforms/Utils/Local.h +@@ -117,7 +117,8 @@ struct SimplifyCFGOptions { + /// conditions and indirectbr addresses this might make dead if + /// DeleteDeadConditions is true. + bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions = false, +- const TargetLibraryInfo *TLI = nullptr); ++ const TargetLibraryInfo *TLI = nullptr, ++ DeferredDominance *DDT = nullptr); + + //===----------------------------------------------------------------------===// + // Local dead code elimination. +@@ -171,18 +172,21 @@ bool SimplifyInstructionsInBlock(BasicBl + /// + /// .. and delete the predecessor corresponding to the '1', this will attempt to + /// recursively fold the 'and' to 0. +-void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred); ++void RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, ++ DeferredDominance *DDT = nullptr); + + /// BB is a block with one predecessor and its predecessor is known to have one + /// successor (BB!). Eliminate the edge between them, moving the instructions in + /// the predecessor into BB. This deletes the predecessor block. +-void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, DominatorTree *DT = nullptr); ++void MergeBasicBlockIntoOnlyPred(BasicBlock *BB, DominatorTree *DT = nullptr, ++ DeferredDominance *DDT = nullptr); + + /// BB is known to contain an unconditional branch, and contains no instructions + /// other than PHI nodes, potential debug intrinsics and the branch. If + /// possible, eliminate BB by rewriting all the predecessors to branch to the + /// successor block and return true. If we can't transform, return false. +-bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB); ++bool TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, ++ DeferredDominance *DDT = nullptr); + + /// Check for and eliminate duplicate PHI nodes in this block. This doesn't try + /// to be clever about PHI nodes which differ only in the order of the incoming +@@ -382,7 +386,8 @@ unsigned removeAllNonTerminatorAndEHPadI + /// Insert an unreachable instruction before the specified + /// instruction, making it and the rest of the code in the block dead. + unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, +- bool PreserveLCSSA = false); ++ bool PreserveLCSSA = false, ++ DeferredDominance *DDT = nullptr); + + /// Convert the CallInst to InvokeInst with the specified unwind edge basic + /// block. This also splits the basic block where CI is located, because +@@ -397,12 +402,13 @@ BasicBlock *changeToInvokeAndSplitBasicB + /// + /// \param BB Block whose terminator will be replaced. Its terminator must + /// have an unwind successor. +-void removeUnwindEdge(BasicBlock *BB); ++void removeUnwindEdge(BasicBlock *BB, DeferredDominance *DDT = nullptr); + + /// Remove all blocks that can not be reached from the function's entry. + /// + /// Returns true if any basic block was removed. +-bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr); ++bool removeUnreachableBlocks(Function &F, LazyValueInfo *LVI = nullptr, ++ DeferredDominance *DDT = nullptr); + + /// Combine the metadata of two instructions so that K can replace J + /// +Index: llvm-toolchain-6.0-6.0.1/lib/IR/Dominators.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/IR/Dominators.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/IR/Dominators.cpp +@@ -18,6 +18,7 @@ + #include "llvm/ADT/DepthFirstIterator.h" + #include "llvm/ADT/SmallPtrSet.h" + #include "llvm/IR/CFG.h" ++#include "llvm/IR/Constants.h" + #include "llvm/IR/Instructions.h" + #include "llvm/IR/PassManager.h" + #include "llvm/Support/CommandLine.h" +@@ -389,3 +390,190 @@ void DominatorTreeWrapperPass::print(raw + DT.print(OS); + } + ++//===----------------------------------------------------------------------===// ++// DeferredDominance Implementation ++//===----------------------------------------------------------------------===// ++// ++// The implementation details of the DeferredDominance class which allows ++// one to queue updates to a DominatorTree. ++// ++//===----------------------------------------------------------------------===// ++ ++/// \brief Queues multiple updates and discards duplicates. ++void DeferredDominance::applyUpdates( ++ ArrayRef Updates) { ++ SmallVector Seen; ++ for (auto U : Updates) ++ // Avoid duplicates to applyUpdate() to save on analysis. ++ if (std::none_of(Seen.begin(), Seen.end(), ++ [U](DominatorTree::UpdateType S) { return S == U; })) { ++ Seen.push_back(U); ++ applyUpdate(U.getKind(), U.getFrom(), U.getTo()); ++ } ++} ++ ++/// \brief Helper method for a single edge insertion. It's almost always better ++/// to batch updates and call applyUpdates to quickly remove duplicate edges. ++/// This is best used when there is only a single insertion needed to update ++/// Dominators. ++void DeferredDominance::insertEdge(BasicBlock *From, BasicBlock *To) { ++ applyUpdate(DominatorTree::Insert, From, To); ++} ++ ++/// \brief Helper method for a single edge deletion. It's almost always better ++/// to batch updates and call applyUpdates to quickly remove duplicate edges. ++/// This is best used when there is only a single deletion needed to update ++/// Dominators. ++void DeferredDominance::deleteEdge(BasicBlock *From, BasicBlock *To) { ++ applyUpdate(DominatorTree::Delete, From, To); ++} ++ ++/// \brief Delays the deletion of a basic block until a flush() event. ++void DeferredDominance::deleteBB(BasicBlock *DelBB) { ++ assert(DelBB && "Invalid push_back of nullptr DelBB."); ++ assert(pred_empty(DelBB) && "DelBB has one or more predecessors."); ++ // DelBB is unreachable and all its instructions are dead. ++ while (!DelBB->empty()) { ++ Instruction &I = DelBB->back(); ++ // Replace used instructions with an arbitrary value (undef). ++ if (!I.use_empty()) ++ I.replaceAllUsesWith(llvm::UndefValue::get(I.getType())); ++ DelBB->getInstList().pop_back(); ++ } ++ // Make sure DelBB has a valid terminator instruction. As long as DelBB is a ++ // Child of Function F it must contain valid IR. ++ new UnreachableInst(DelBB->getContext(), DelBB); ++ DeletedBBs.insert(DelBB); ++} ++ ++/// \brief Returns true if DelBB is awaiting deletion at a flush() event. ++bool DeferredDominance::pendingDeletedBB(BasicBlock *DelBB) { ++ if (DeletedBBs.empty()) ++ return false; ++ return DeletedBBs.count(DelBB) != 0; ++} ++ ++/// \brief Flushes all pending updates and block deletions. Returns a ++/// correct DominatorTree reference to be used by the caller for analysis. ++DominatorTree &DeferredDominance::flush() { ++ // Updates to DT must happen before blocks are deleted below. Otherwise the ++ // DT traversal will encounter badref blocks and assert. ++ if (!PendUpdates.empty()) { ++ DT.applyUpdates(PendUpdates); ++ PendUpdates.clear(); ++ } ++ flushDelBB(); ++ return DT; ++} ++ ++/// \brief Drops all internal state and forces a (slow) recalculation of the ++/// DominatorTree based on the current state of the LLVM IR in F. This should ++/// only be used in corner cases such as the Entry block of F being deleted. ++void DeferredDominance::recalculate(Function &F) { ++ // flushDelBB must be flushed before the recalculation. The state of the IR ++ // must be consistent before the DT traversal algorithm determines the ++ // actual DT. ++ if (flushDelBB() || !PendUpdates.empty()) { ++ DT.recalculate(F); ++ PendUpdates.clear(); ++ } ++} ++ ++/// \brief Debug method to help view the state of pending updates. ++#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) ++LLVM_DUMP_METHOD void DeferredDominance::dump() const { ++ raw_ostream &OS = llvm::dbgs(); ++ OS << "PendUpdates:\n"; ++ int I = 0; ++ for (auto U : PendUpdates) { ++ OS << " " << I << " : "; ++ ++I; ++ if (U.getKind() == DominatorTree::Insert) ++ OS << "Insert, "; ++ else ++ OS << "Delete, "; ++ BasicBlock *From = U.getFrom(); ++ if (From) { ++ auto S = From->getName(); ++ if (!From->hasName()) ++ S = "(no name)"; ++ OS << S << "(" << From << "), "; ++ } else { ++ OS << "(badref), "; ++ } ++ BasicBlock *To = U.getTo(); ++ if (To) { ++ auto S = To->getName(); ++ if (!To->hasName()) ++ S = "(no_name)"; ++ OS << S << "(" << To << ")\n"; ++ } else { ++ OS << "(badref)\n"; ++ } ++ } ++ OS << "DeletedBBs:\n"; ++ I = 0; ++ for (auto BB : DeletedBBs) { ++ OS << " " << I << " : "; ++ ++I; ++ if (BB->hasName()) ++ OS << BB->getName() << "("; ++ else ++ OS << "(no_name)("; ++ OS << BB << ")\n"; ++ } ++} ++#endif ++ ++/// Apply an update (Kind, From, To) to the internal queued updates. The ++/// update is only added when determined to be necessary. Checks for ++/// self-domination, unnecessary updates, duplicate requests, and balanced ++/// pairs of requests are all performed. Returns true if the update is ++/// queued and false if it is discarded. ++bool DeferredDominance::applyUpdate(DominatorTree::UpdateKind Kind, ++ BasicBlock *From, BasicBlock *To) { ++ if (From == To) ++ return false; // Cannot dominate self; discard update. ++ ++ // Discard updates by inspecting the current state of successors of From. ++ // Since applyUpdate() must be called *after* the Terminator of From is ++ // altered we can determine if the update is unnecessary. ++ bool HasEdge = std::any_of(succ_begin(From), succ_end(From), ++ [To](BasicBlock *B) { return B == To; }); ++ if (Kind == DominatorTree::Insert && !HasEdge) ++ return false; // Unnecessary Insert: edge does not exist in IR. ++ if (Kind == DominatorTree::Delete && HasEdge) ++ return false; // Unnecessary Delete: edge still exists in IR. ++ ++ // Analyze pending updates to determine if the update is unnecessary. ++ DominatorTree::UpdateType Update = {Kind, From, To}; ++ DominatorTree::UpdateType Invert = {Kind != DominatorTree::Insert ++ ? DominatorTree::Insert ++ : DominatorTree::Delete, ++ From, To}; ++ for (auto I = PendUpdates.begin(), E = PendUpdates.end(); I != E; ++I) { ++ if (Update == *I) ++ return false; // Discard duplicate updates. ++ if (Invert == *I) { ++ // Update and Invert are both valid (equivalent to a no-op). Remove ++ // Invert from PendUpdates and discard the Update. ++ PendUpdates.erase(I); ++ return false; ++ } ++ } ++ PendUpdates.push_back(Update); // Save the valid update. ++ return true; ++} ++ ++/// Performs all pending basic block deletions. We have to defer the deletion ++/// of these blocks until after the DominatorTree updates are applied. The ++/// internal workings of the DominatorTree code expect every update's From ++/// and To blocks to exist and to be a member of the same Function. ++bool DeferredDominance::flushDelBB() { ++ if (DeletedBBs.empty()) ++ return false; ++ for (auto *BB : DeletedBBs) ++ BB->eraseFromParent(); ++ DeletedBBs.clear(); ++ return true; ++} +Index: llvm-toolchain-6.0-6.0.1/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp +@@ -77,6 +77,7 @@ namespace { + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { ++ AU.addRequired(); + AU.addRequired(); + AU.addPreserved(); + } +@@ -88,6 +89,7 @@ char CorrelatedValuePropagation::ID = 0; + + INITIALIZE_PASS_BEGIN(CorrelatedValuePropagation, "correlated-propagation", + "Value Propagation", false, false) ++INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) + INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) + INITIALIZE_PASS_END(CorrelatedValuePropagation, "correlated-propagation", + "Value Propagation", false, false) +Index: llvm-toolchain-6.0-6.0.1/lib/Transforms/Scalar/JumpThreading.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/Transforms/Scalar/JumpThreading.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/Transforms/Scalar/JumpThreading.cpp +@@ -131,10 +131,11 @@ namespace { + bool runOnFunction(Function &F) override; + + void getAnalysisUsage(AnalysisUsage &AU) const override { +- if (PrintLVIAfterJumpThreading) +- AU.addRequired(); ++ AU.addRequired(); ++ AU.addPreserved(); + AU.addRequired(); + AU.addRequired(); ++ AU.addPreserved(); + AU.addPreserved(); + AU.addRequired(); + } +@@ -148,6 +149,7 @@ char JumpThreading::ID = 0; + + INITIALIZE_PASS_BEGIN(JumpThreading, "jump-threading", + "Jump Threading", false, false) ++INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) + INITIALIZE_PASS_DEPENDENCY(LazyValueInfoWrapperPass) + INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) + INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass) +@@ -278,8 +280,12 @@ bool JumpThreading::runOnFunction(Functi + if (skipFunction(F)) + return false; + auto TLI = &getAnalysis().getTLI(); ++ // Get DT analysis before LVI. When LVI is initialized it conditionally adds ++ // DT if it's available. ++ auto DT = &getAnalysis().getDomTree(); + auto LVI = &getAnalysis().getLVI(); + auto AA = &getAnalysis().getAAResults(); ++ DeferredDominance DDT(*DT); + std::unique_ptr BFI; + std::unique_ptr BPI; + bool HasProfileData = F.hasProfileData(); +@@ -289,12 +295,11 @@ bool JumpThreading::runOnFunction(Functi + BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); + } + +- bool Changed = Impl.runImpl(F, TLI, LVI, AA, HasProfileData, std::move(BFI), +- std::move(BPI)); ++ bool Changed = Impl.runImpl(F, TLI, LVI, AA, &DDT, HasProfileData, ++ std::move(BFI), std::move(BPI)); + if (PrintLVIAfterJumpThreading) { + dbgs() << "LVI for function '" << F.getName() << "':\n"; +- LVI->printLVI(F, getAnalysis().getDomTree(), +- dbgs()); ++ LVI->printLVI(F, *DT, dbgs()); + } + return Changed; + } +@@ -302,8 +307,12 @@ bool JumpThreading::runOnFunction(Functi + PreservedAnalyses JumpThreadingPass::run(Function &F, + FunctionAnalysisManager &AM) { + auto &TLI = AM.getResult(F); ++ // Get DT analysis before LVI. When LVI is initialized it conditionally adds ++ // DT if it's available. ++ auto &DT = AM.getResult(F); + auto &LVI = AM.getResult(F); + auto &AA = AM.getResult(F); ++ DeferredDominance DDT(DT); + + std::unique_ptr BFI; + std::unique_ptr BPI; +@@ -313,25 +322,28 @@ PreservedAnalyses JumpThreadingPass::run + BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); + } + +- bool Changed = runImpl(F, &TLI, &LVI, &AA, HasProfileData, std::move(BFI), +- std::move(BPI)); ++ bool Changed = runImpl(F, &TLI, &LVI, &AA, &DDT, HasProfileData, ++ std::move(BFI), std::move(BPI)); + + if (!Changed) + return PreservedAnalyses::all(); + PreservedAnalyses PA; + PA.preserve(); ++ PA.preserve(); ++ PA.preserve(); + return PA; + } + + bool JumpThreadingPass::runImpl(Function &F, TargetLibraryInfo *TLI_, + LazyValueInfo *LVI_, AliasAnalysis *AA_, +- bool HasProfileData_, ++ DeferredDominance *DDT_, bool HasProfileData_, + std::unique_ptr BFI_, + std::unique_ptr BPI_) { + DEBUG(dbgs() << "Jump threading on function '" << F.getName() << "'\n"); + TLI = TLI_; + LVI = LVI_; + AA = AA_; ++ DDT = DDT_; + BFI.reset(); + BPI.reset(); + // When profile data is available, we need to update edge weights after +@@ -353,7 +365,7 @@ bool JumpThreadingPass::runImpl(Function + // back edges. This works for normal cases but not for unreachable blocks as + // they may have cycle with no back edge. + bool EverChanged = false; +- EverChanged |= removeUnreachableBlocks(F, LVI); ++ EverChanged |= removeUnreachableBlocks(F, LVI, DDT); + + FindLoopHeaders(F); + +@@ -368,6 +380,10 @@ bool JumpThreadingPass::runImpl(Function + + ++I; + ++ // Don't thread branches over a block that's slated for deletion. ++ if (DDT->pendingDeletedBB(BB)) ++ continue; ++ + // If the block is trivially dead, zap it. This eliminates the successor + // edges which simplifies the CFG. + if (pred_empty(BB) && +@@ -376,7 +392,7 @@ bool JumpThreadingPass::runImpl(Function + << "' with terminator: " << *BB->getTerminator() << '\n'); + LoopHeaders.erase(BB); + LVI->eraseBlock(BB); +- DeleteDeadBlock(BB); ++ DeleteDeadBlock(BB, DDT); + Changed = true; + continue; + } +@@ -400,7 +416,7 @@ bool JumpThreadingPass::runImpl(Function + // awesome, but it allows us to use AssertingVH to prevent nasty + // dangling pointer issues within LazyValueInfo. + LVI->eraseBlock(BB); +- if (TryToSimplifyUncondBranchFromEmptyBlock(BB)) ++ if (TryToSimplifyUncondBranchFromEmptyBlock(BB, DDT)) + Changed = true; + } + } +@@ -408,6 +424,7 @@ bool JumpThreadingPass::runImpl(Function + } while (Changed); + + LoopHeaders.clear(); ++ DDT->flush(); + return EverChanged; + } + +@@ -931,8 +948,8 @@ static bool hasAddressTakenAndUsed(Basic + bool JumpThreadingPass::ProcessBlock(BasicBlock *BB) { + // If the block is trivially dead, just return and let the caller nuke it. + // This simplifies other transformations. +- if (pred_empty(BB) && +- BB != &BB->getParent()->getEntryBlock()) ++ if (DDT->pendingDeletedBB(BB) || ++ (pred_empty(BB) && BB != &BB->getParent()->getEntryBlock())) + return false; + + // If this block has a single predecessor, and if that pred has a single +@@ -948,7 +965,7 @@ bool JumpThreadingPass::ProcessBlock(Bas + LoopHeaders.insert(BB); + + LVI->eraseBlock(SinglePred); +- MergeBasicBlockIntoOnlyPred(BB); ++ MergeBasicBlockIntoOnlyPred(BB, nullptr, DDT); + + // Now that BB is merged into SinglePred (i.e. SinglePred Code followed by + // BB code within one basic block `BB`), we need to invalidate the LVI +@@ -1031,18 +1048,23 @@ bool JumpThreadingPass::ProcessBlock(Bas + // successors to branch to. Let GetBestDestForJumpOnUndef decide. + if (isa(Condition)) { + unsigned BestSucc = GetBestDestForJumpOnUndef(BB); ++ std::vector Updates; + + // Fold the branch/switch. + TerminatorInst *BBTerm = BB->getTerminator(); ++ Updates.reserve(BBTerm->getNumSuccessors()); + for (unsigned i = 0, e = BBTerm->getNumSuccessors(); i != e; ++i) { + if (i == BestSucc) continue; +- BBTerm->getSuccessor(i)->removePredecessor(BB, true); ++ BasicBlock *Succ = BBTerm->getSuccessor(i); ++ Succ->removePredecessor(BB, true); ++ Updates.push_back({DominatorTree::Delete, BB, Succ}); + } + + DEBUG(dbgs() << " In block '" << BB->getName() + << "' folding undef terminator: " << *BBTerm << '\n'); + BranchInst::Create(BBTerm->getSuccessor(BestSucc), BBTerm); + BBTerm->eraseFromParent(); ++ DDT->applyUpdates(Updates); + return true; + } + +@@ -1053,7 +1075,7 @@ bool JumpThreadingPass::ProcessBlock(Bas + DEBUG(dbgs() << " In block '" << BB->getName() + << "' folding terminator: " << *BB->getTerminator() << '\n'); + ++NumFolds; +- ConstantFoldTerminator(BB, true); ++ ConstantFoldTerminator(BB, true, nullptr, DDT); + return true; + } + +@@ -1086,7 +1108,8 @@ bool JumpThreadingPass::ProcessBlock(Bas + if (Ret != LazyValueInfo::Unknown) { + unsigned ToRemove = Ret == LazyValueInfo::True ? 1 : 0; + unsigned ToKeep = Ret == LazyValueInfo::True ? 0 : 1; +- CondBr->getSuccessor(ToRemove)->removePredecessor(BB, true); ++ BasicBlock *ToRemoveSucc = CondBr->getSuccessor(ToRemove); ++ ToRemoveSucc->removePredecessor(BB, true); + BranchInst::Create(CondBr->getSuccessor(ToKeep), CondBr); + CondBr->eraseFromParent(); + if (CondCmp->use_empty()) +@@ -1104,6 +1127,7 @@ bool JumpThreadingPass::ProcessBlock(Bas + ConstantInt::getFalse(CondCmp->getType()); + ReplaceFoldableUses(CondCmp, CI); + } ++ DDT->deleteEdge(BB, ToRemoveSucc); + return true; + } + +@@ -1182,9 +1206,12 @@ bool JumpThreadingPass::ProcessImpliedCo + Optional Implication = + isImpliedCondition(PBI->getCondition(), Cond, DL, CondIsTrue); + if (Implication) { +- BI->getSuccessor(*Implication ? 1 : 0)->removePredecessor(BB); +- BranchInst::Create(BI->getSuccessor(*Implication ? 0 : 1), BI); ++ BasicBlock *KeepSucc = BI->getSuccessor(*Implication ? 0 : 1); ++ BasicBlock *RemoveSucc = BI->getSuccessor(*Implication ? 1 : 0); ++ RemoveSucc->removePredecessor(BB); ++ BranchInst::Create(KeepSucc, BI); + BI->eraseFromParent(); ++ DDT->deleteEdge(BB, RemoveSucc); + return true; + } + CurrentBB = CurrentPred; +@@ -1594,17 +1621,22 @@ bool JumpThreadingPass::ProcessThreadabl + if (PredWithKnownDest == + (size_t)std::distance(pred_begin(BB), pred_end(BB))) { + bool SeenFirstBranchToOnlyDest = false; ++ std::vector Updates; ++ Updates.reserve(BB->getTerminator()->getNumSuccessors() - 1); + for (BasicBlock *SuccBB : successors(BB)) { +- if (SuccBB == OnlyDest && !SeenFirstBranchToOnlyDest) ++ if (SuccBB == OnlyDest && !SeenFirstBranchToOnlyDest) { + SeenFirstBranchToOnlyDest = true; // Don't modify the first branch. +- else ++ } else { + SuccBB->removePredecessor(BB, true); // This is unreachable successor. ++ Updates.push_back({DominatorTree::Delete, BB, SuccBB}); ++ } + } + + // Finally update the terminator. + TerminatorInst *Term = BB->getTerminator(); + BranchInst::Create(OnlyDest, Term); + Term->eraseFromParent(); ++ DDT->applyUpdates(Updates); + + // If the condition is now dead due to the removal of the old terminator, + // erase it. +@@ -1979,6 +2011,10 @@ bool JumpThreadingPass::ThreadEdge(Basic + PredTerm->setSuccessor(i, NewBB); + } + ++ DDT->applyUpdates({{DominatorTree::Insert, NewBB, SuccBB}, ++ {DominatorTree::Insert, PredBB, NewBB}, ++ {DominatorTree::Delete, PredBB, BB}}); ++ + // At this point, the IR is fully up to date and consistent. Do a quick scan + // over the new instructions and zap any that are constants or dead. This + // frequently happens because of phi translation. +@@ -1998,20 +2034,42 @@ bool JumpThreadingPass::ThreadEdge(Basic + BasicBlock *JumpThreadingPass::SplitBlockPreds(BasicBlock *BB, + ArrayRef Preds, + const char *Suffix) { ++ SmallVector NewBBs; ++ + // Collect the frequencies of all predecessors of BB, which will be used to +- // update the edge weight on BB->SuccBB. +- BlockFrequency PredBBFreq(0); ++ // update the edge weight of the result of splitting predecessors. ++ DenseMap FreqMap; + if (HasProfileData) + for (auto Pred : Preds) +- PredBBFreq += BFI->getBlockFreq(Pred) * BPI->getEdgeProbability(Pred, BB); ++ FreqMap.insert(std::make_pair( ++ Pred, BFI->getBlockFreq(Pred) * BPI->getEdgeProbability(Pred, BB))); ++ ++ // In the case when BB is a LandingPad block we create 2 new predecessors ++ // instead of just one. ++ if (BB->isLandingPad()) { ++ std::string NewName = std::string(Suffix) + ".split-lp"; ++ SplitLandingPadPredecessors(BB, Preds, Suffix, NewName.c_str(), NewBBs); ++ } else { ++ NewBBs.push_back(SplitBlockPredecessors(BB, Preds, Suffix)); ++ } + +- BasicBlock *PredBB = SplitBlockPredecessors(BB, Preds, Suffix); ++ std::vector Updates; ++ Updates.reserve((2 * Preds.size()) + NewBBs.size()); ++ for (auto NewBB : NewBBs) { ++ BlockFrequency NewBBFreq(0); ++ Updates.push_back({DominatorTree::Insert, NewBB, BB}); ++ for (auto Pred : predecessors(NewBB)) { ++ Updates.push_back({DominatorTree::Delete, Pred, BB}); ++ Updates.push_back({DominatorTree::Insert, Pred, NewBB}); ++ if (HasProfileData) // Update frequencies between Pred -> NewBB. ++ NewBBFreq += FreqMap.lookup(Pred); ++ } ++ if (HasProfileData) // Apply the summed frequency to NewBB. ++ BFI->setBlockFreq(NewBB, NewBBFreq.getFrequency()); ++ } + +- // Set the block frequency of the newly created PredBB, which is the sum of +- // frequencies of Preds. +- if (HasProfileData) +- BFI->setBlockFreq(PredBB, PredBBFreq.getFrequency()); +- return PredBB; ++ DDT->applyUpdates(Updates); ++ return NewBBs[0]; + } + + bool JumpThreadingPass::doesBlockHaveProfileData(BasicBlock *BB) { +@@ -2155,6 +2213,7 @@ bool JumpThreadingPass::DuplicateCondBra + } + + // And finally, do it! Start by factoring the predecessors if needed. ++ std::vector Updates; + BasicBlock *PredBB; + if (PredBBs.size() == 1) + PredBB = PredBBs[0]; +@@ -2163,6 +2222,7 @@ bool JumpThreadingPass::DuplicateCondBra + << " common predecessors.\n"); + PredBB = SplitBlockPreds(BB, PredBBs, ".thr_comm"); + } ++ Updates.push_back({DominatorTree::Delete, PredBB, BB}); + + // Okay, we decided to do this! Clone all the instructions in BB onto the end + // of PredBB. +@@ -2175,7 +2235,11 @@ bool JumpThreadingPass::DuplicateCondBra + BranchInst *OldPredBranch = dyn_cast(PredBB->getTerminator()); + + if (!OldPredBranch || !OldPredBranch->isUnconditional()) { +- PredBB = SplitEdge(PredBB, BB); ++ BasicBlock *OldPredBB = PredBB; ++ PredBB = SplitEdge(OldPredBB, BB); ++ Updates.push_back({DominatorTree::Insert, OldPredBB, PredBB}); ++ Updates.push_back({DominatorTree::Insert, PredBB, BB}); ++ Updates.push_back({DominatorTree::Delete, OldPredBB, BB}); + OldPredBranch = cast(PredBB->getTerminator()); + } + +@@ -2217,6 +2281,10 @@ bool JumpThreadingPass::DuplicateCondBra + // Otherwise, insert the new instruction into the block. + New->setName(BI->getName()); + PredBB->getInstList().insert(OldPredBranch->getIterator(), New); ++ // Update Dominance from simplified New instruction operands. ++ for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i) ++ if (BasicBlock *SuccBB = dyn_cast(New->getOperand(i))) ++ Updates.push_back({DominatorTree::Insert, PredBB, SuccBB}); + } + } + +@@ -2272,6 +2340,7 @@ bool JumpThreadingPass::DuplicateCondBra + + // Remove the unconditional branch at the end of the PredBB block. + OldPredBranch->eraseFromParent(); ++ DDT->applyUpdates(Updates); + + ++NumDupes; + return true; +@@ -2344,6 +2413,8 @@ bool JumpThreadingPass::TryToUnfoldSelec + // The select is now dead. + SI->eraseFromParent(); + ++ DDT->applyUpdates({{DominatorTree::Insert, NewBB, BB}, ++ {DominatorTree::Insert, Pred, NewBB}}); + // Update any other PHI nodes in BB. + for (BasicBlock::iterator BI = BB->begin(); + PHINode *Phi = dyn_cast(BI); ++BI) +@@ -2422,11 +2493,25 @@ bool JumpThreadingPass::TryToUnfoldSelec + // Expand the select. + TerminatorInst *Term = + SplitBlockAndInsertIfThen(SI->getCondition(), SI, false); ++ BasicBlock *SplitBB = SI->getParent(); ++ BasicBlock *NewBB = Term->getParent(); + PHINode *NewPN = PHINode::Create(SI->getType(), 2, "", SI); + NewPN->addIncoming(SI->getTrueValue(), Term->getParent()); + NewPN->addIncoming(SI->getFalseValue(), BB); + SI->replaceAllUsesWith(NewPN); + SI->eraseFromParent(); ++ // NewBB and SplitBB are newly created blocks which require insertion. ++ std::vector Updates; ++ Updates.reserve((2 * SplitBB->getTerminator()->getNumSuccessors()) + 3); ++ Updates.push_back({DominatorTree::Insert, BB, SplitBB}); ++ Updates.push_back({DominatorTree::Insert, BB, NewBB}); ++ Updates.push_back({DominatorTree::Insert, NewBB, SplitBB}); ++ // BB's successors were moved to SplitBB, update DDT accordingly. ++ for (auto *Succ : successors(SplitBB)) { ++ Updates.push_back({DominatorTree::Delete, BB, Succ}); ++ Updates.push_back({DominatorTree::Insert, SplitBB, Succ}); ++ } ++ DDT->applyUpdates(Updates); + return true; + } + return false; +@@ -2513,8 +2598,8 @@ bool JumpThreadingPass::ThreadGuard(Basi + if (!TrueDestIsSafe && !FalseDestIsSafe) + return false; + +- BasicBlock *UnguardedBlock = TrueDestIsSafe ? TrueDest : FalseDest; +- BasicBlock *GuardedBlock = FalseDestIsSafe ? TrueDest : FalseDest; ++ BasicBlock *PredUnguardedBlock = TrueDestIsSafe ? TrueDest : FalseDest; ++ BasicBlock *PredGuardedBlock = FalseDestIsSafe ? TrueDest : FalseDest; + + ValueToValueMapTy UnguardedMapping, GuardedMapping; + Instruction *AfterGuard = Guard->getNextNode(); +@@ -2523,18 +2608,29 @@ bool JumpThreadingPass::ThreadGuard(Basi + return false; + // Duplicate all instructions before the guard and the guard itself to the + // branch where implication is not proved. +- GuardedBlock = DuplicateInstructionsInSplitBetween( +- BB, GuardedBlock, AfterGuard, GuardedMapping); ++ BasicBlock *GuardedBlock = DuplicateInstructionsInSplitBetween( ++ BB, PredGuardedBlock, AfterGuard, GuardedMapping); + assert(GuardedBlock && "Could not create the guarded block?"); + // Duplicate all instructions before the guard in the unguarded branch. + // Since we have successfully duplicated the guarded block and this block + // has fewer instructions, we expect it to succeed. +- UnguardedBlock = DuplicateInstructionsInSplitBetween(BB, UnguardedBlock, +- Guard, UnguardedMapping); ++ BasicBlock *UnguardedBlock = DuplicateInstructionsInSplitBetween( ++ BB, PredUnguardedBlock, Guard, UnguardedMapping); + assert(UnguardedBlock && "Could not create the unguarded block?"); + DEBUG(dbgs() << "Moved guard " << *Guard << " to block " + << GuardedBlock->getName() << "\n"); +- ++ // DuplicateInstructionsInSplitBetween inserts a new block "BB.split" between ++ // PredBB and BB. We need to perform two inserts and one delete for each of ++ // the above calls to update Dominators. ++ DDT->applyUpdates( ++ {// Guarded block split. ++ {DominatorTree::Delete, PredGuardedBlock, BB}, ++ {DominatorTree::Insert, PredGuardedBlock, GuardedBlock}, ++ {DominatorTree::Insert, GuardedBlock, BB}, ++ // Unguarded block split. ++ {DominatorTree::Delete, PredUnguardedBlock, BB}, ++ {DominatorTree::Insert, PredUnguardedBlock, UnguardedBlock}, ++ {DominatorTree::Insert, UnguardedBlock, BB}}); + // Some instructions before the guard may still have uses. For them, we need + // to create Phi nodes merging their copies in both guarded and unguarded + // branches. Those instructions that have no uses can be just removed. +Index: llvm-toolchain-6.0-6.0.1/lib/Transforms/Utils/BasicBlockUtils.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/Transforms/Utils/BasicBlockUtils.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/Transforms/Utils/BasicBlockUtils.cpp +@@ -45,16 +45,22 @@ + + using namespace llvm; + +-void llvm::DeleteDeadBlock(BasicBlock *BB) { ++void llvm::DeleteDeadBlock(BasicBlock *BB, DeferredDominance *DDT) { + assert((pred_begin(BB) == pred_end(BB) || + // Can delete self loop. + BB->getSinglePredecessor() == BB) && "Block is not dead!"); + TerminatorInst *BBTerm = BB->getTerminator(); ++ std::vector Updates; + + // Loop through all of our successors and make sure they know that one + // of their predecessors is going away. +- for (BasicBlock *Succ : BBTerm->successors()) ++ if (DDT) ++ Updates.reserve(BBTerm->getNumSuccessors()); ++ for (BasicBlock *Succ : BBTerm->successors()) { + Succ->removePredecessor(BB); ++ if (DDT) ++ Updates.push_back({DominatorTree::Delete, BB, Succ}); ++ } + + // Zap all the instructions in the block. + while (!BB->empty()) { +@@ -69,8 +75,12 @@ void llvm::DeleteDeadBlock(BasicBlock *B + BB->getInstList().pop_back(); + } + +- // Zap the block! +- BB->eraseFromParent(); ++ if (DDT) { ++ DDT->applyUpdates(Updates); ++ DDT->deleteBB(BB); // Deferred deletion of BB. ++ } else { ++ BB->eraseFromParent(); // Zap the block! ++ } + } + + void llvm::FoldSingleEntryPHINodes(BasicBlock *BB, +Index: llvm-toolchain-6.0-6.0.1/lib/Transforms/Utils/Local.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/Transforms/Utils/Local.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/Transforms/Utils/Local.cpp +@@ -100,7 +100,8 @@ STATISTIC(NumRemoved, "Number of unreach + /// conditions and indirectbr addresses this might make dead if + /// DeleteDeadConditions is true. + bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions, +- const TargetLibraryInfo *TLI) { ++ const TargetLibraryInfo *TLI, ++ DeferredDominance *DDT) { + TerminatorInst *T = BB->getTerminator(); + IRBuilder<> Builder(T); + +@@ -123,6 +124,8 @@ bool llvm::ConstantFoldTerminator(BasicB + // Replace the conditional branch with an unconditional one. + Builder.CreateBr(Destination); + BI->eraseFromParent(); ++ if (DDT) ++ DDT->deleteEdge(BB, OldDest); + return true; + } + +@@ -193,9 +196,12 @@ bool llvm::ConstantFoldTerminator(BasicB + createBranchWeights(Weights)); + } + // Remove this entry. +- DefaultDest->removePredecessor(SI->getParent()); ++ BasicBlock *ParentBB = SI->getParent(); ++ DefaultDest->removePredecessor(ParentBB); + i = SI->removeCase(i); + e = SI->case_end(); ++ if (DDT) ++ DDT->deleteEdge(ParentBB, DefaultDest); + continue; + } + +@@ -221,14 +227,20 @@ bool llvm::ConstantFoldTerminator(BasicB + // Insert the new branch. + Builder.CreateBr(TheOnlyDest); + BasicBlock *BB = SI->getParent(); ++ std::vector Updates; ++ if (DDT) ++ Updates.reserve(SI->getNumSuccessors() - 1); + + // Remove entries from PHI nodes which we no longer branch to... + for (BasicBlock *Succ : SI->successors()) { + // Found case matching a constant operand? +- if (Succ == TheOnlyDest) ++ if (Succ == TheOnlyDest) { + TheOnlyDest = nullptr; // Don't modify the first branch to TheOnlyDest +- else ++ } else { + Succ->removePredecessor(BB); ++ if (DDT) ++ Updates.push_back({DominatorTree::Delete, BB, Succ}); ++ } + } + + // Delete the old switch. +@@ -236,6 +248,8 @@ bool llvm::ConstantFoldTerminator(BasicB + SI->eraseFromParent(); + if (DeleteDeadConditions) + RecursivelyDeleteTriviallyDeadInstructions(Cond, TLI); ++ if (DDT) ++ DDT->applyUpdates(Updates); + return true; + } + +@@ -281,14 +295,23 @@ bool llvm::ConstantFoldTerminator(BasicB + if (auto *BA = + dyn_cast(IBI->getAddress()->stripPointerCasts())) { + BasicBlock *TheOnlyDest = BA->getBasicBlock(); ++ std::vector Updates; ++ if (DDT) ++ Updates.reserve(IBI->getNumDestinations() - 1); ++ + // Insert the new branch. + Builder.CreateBr(TheOnlyDest); + + for (unsigned i = 0, e = IBI->getNumDestinations(); i != e; ++i) { +- if (IBI->getDestination(i) == TheOnlyDest) ++ if (IBI->getDestination(i) == TheOnlyDest) { + TheOnlyDest = nullptr; +- else +- IBI->getDestination(i)->removePredecessor(IBI->getParent()); ++ } else { ++ BasicBlock *ParentBB = IBI->getParent(); ++ BasicBlock *DestBB = IBI->getDestination(i); ++ DestBB->removePredecessor(ParentBB); ++ if (DDT) ++ Updates.push_back({DominatorTree::Delete, ParentBB, DestBB}); ++ } + } + Value *Address = IBI->getAddress(); + IBI->eraseFromParent(); +@@ -303,6 +326,8 @@ bool llvm::ConstantFoldTerminator(BasicB + new UnreachableInst(BB->getContext(), BB); + } + ++ if (DDT) ++ DDT->applyUpdates(Updates); + return true; + } + } +@@ -579,7 +604,8 @@ bool llvm::SimplifyInstructionsInBlock(B + /// + /// .. and delete the predecessor corresponding to the '1', this will attempt to + /// recursively fold the and to 0. +-void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred) { ++void llvm::RemovePredecessorAndSimplify(BasicBlock *BB, BasicBlock *Pred, ++ DeferredDominance *DDT) { + // This only adjusts blocks with PHI nodes. + if (!isa(BB->begin())) + return; +@@ -602,13 +628,18 @@ void llvm::RemovePredecessorAndSimplify( + // of the block. + if (PhiIt != OldPhiIt) PhiIt = &BB->front(); + } ++ if (DDT) ++ DDT->deleteEdge(Pred, BB); + } + + /// MergeBasicBlockIntoOnlyPred - DestBB is a block with one predecessor and its + /// predecessor is known to have one successor (DestBB!). Eliminate the edge + /// between them, moving the instructions in the predecessor into DestBB and + /// deleting the predecessor block. +-void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT) { ++void llvm::MergeBasicBlockIntoOnlyPred(BasicBlock *DestBB, DominatorTree *DT, ++ DeferredDominance *DDT) { ++ assert(!(DT && DDT) && "Cannot call with both DT and DDT."); ++ + // If BB has single-entry PHI nodes, fold them. + while (PHINode *PN = dyn_cast(DestBB->begin())) { + Value *NewVal = PN->getIncomingValue(0); +@@ -621,6 +652,25 @@ void llvm::MergeBasicBlockIntoOnlyPred(B + BasicBlock *PredBB = DestBB->getSinglePredecessor(); + assert(PredBB && "Block doesn't have a single predecessor!"); + ++ bool ReplaceEntryBB = false; ++ if (PredBB == &DestBB->getParent()->getEntryBlock()) ++ ReplaceEntryBB = true; ++ ++ // Deferred DT update: Collect all the edges that enter PredBB. These ++ // dominator edges will be redirected to DestBB. ++ std::vector Updates; ++ if (DDT && !ReplaceEntryBB) { ++ Updates.reserve(1 + ++ (2 * std::distance(pred_begin(PredBB), pred_end(PredBB)))); ++ Updates.push_back({DominatorTree::Delete, PredBB, DestBB}); ++ for (auto I = pred_begin(PredBB), E = pred_end(PredBB); I != E; ++I) { ++ Updates.push_back({DominatorTree::Delete, *I, PredBB}); ++ // This predecessor of PredBB may already have DestBB as a successor. ++ if (llvm::find(successors(*I), DestBB) == succ_end(*I)) ++ Updates.push_back({DominatorTree::Insert, *I, DestBB}); ++ } ++ } ++ + // Zap anything that took the address of DestBB. Not doing this will give the + // address an invalid value. + if (DestBB->hasAddressTaken()) { +@@ -641,7 +691,7 @@ void llvm::MergeBasicBlockIntoOnlyPred(B + + // If the PredBB is the entry block of the function, move DestBB up to + // become the entry block after we erase PredBB. +- if (PredBB == &DestBB->getParent()->getEntryBlock()) ++ if (ReplaceEntryBB) + DestBB->moveAfter(PredBB); + + if (DT) { +@@ -653,8 +703,19 @@ void llvm::MergeBasicBlockIntoOnlyPred(B + DT->eraseNode(PredBB); + } + } +- // Nuke BB. +- PredBB->eraseFromParent(); ++ ++ if (DDT) { ++ DDT->deleteBB(PredBB); // Deferred deletion of BB. ++ if (ReplaceEntryBB) ++ // The entry block was removed and there is no external interface for the ++ // dominator tree to be notified of this change. In this corner-case we ++ // recalculate the entire tree. ++ DDT->recalculate(*(DestBB->getParent())); ++ else ++ DDT->applyUpdates(Updates); ++ } else { ++ PredBB->eraseFromParent(); // Nuke BB. ++ } + } + + /// CanMergeValues - Return true if we can choose one of these values to use +@@ -861,7 +922,8 @@ static void redirectValuesFromPredecesso + /// potential side-effect free intrinsics and the branch. If possible, + /// eliminate BB by rewriting all the predecessors to branch to the successor + /// block and return true. If we can't transform, return false. +-bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB) { ++bool llvm::TryToSimplifyUncondBranchFromEmptyBlock(BasicBlock *BB, ++ DeferredDominance *DDT) { + assert(BB != &BB->getParent()->getEntryBlock() && + "TryToSimplifyUncondBranchFromEmptyBlock called on entry block!"); + +@@ -902,6 +964,19 @@ bool llvm::TryToSimplifyUncondBranchFrom + + DEBUG(dbgs() << "Killing Trivial BB: \n" << *BB); + ++ std::vector Updates; ++ if (DDT) { ++ Updates.reserve(1 + (2 * std::distance(pred_begin(BB), pred_end(BB)))); ++ Updates.push_back({DominatorTree::Delete, BB, Succ}); ++ // All predecessors of BB will be moved to Succ. ++ for (auto I = pred_begin(BB), E = pred_end(BB); I != E; ++I) { ++ Updates.push_back({DominatorTree::Delete, *I, BB}); ++ // This predecessor of BB may already have Succ as a successor. ++ if (llvm::find(successors(*I), Succ) == succ_end(*I)) ++ Updates.push_back({DominatorTree::Insert, *I, Succ}); ++ } ++ } ++ + if (isa(Succ->begin())) { + // If there is more than one pred of succ, and there are PHI nodes in + // the successor, then we need to add incoming edges for the PHI nodes +@@ -946,7 +1021,13 @@ bool llvm::TryToSimplifyUncondBranchFrom + // Everything that jumped to BB now goes to Succ. + BB->replaceAllUsesWith(Succ); + if (!Succ->hasName()) Succ->takeName(BB); +- BB->eraseFromParent(); // Delete the old basic block. ++ ++ if (DDT) { ++ DDT->deleteBB(BB); // Deferred deletion of the old basic block. ++ DDT->applyUpdates(Updates); ++ } else { ++ BB->eraseFromParent(); // Delete the old basic block. ++ } + return true; + } + +@@ -1448,13 +1529,19 @@ unsigned llvm::removeAllNonTerminatorAnd + } + + unsigned llvm::changeToUnreachable(Instruction *I, bool UseLLVMTrap, +- bool PreserveLCSSA) { ++ bool PreserveLCSSA, DeferredDominance *DDT) { + BasicBlock *BB = I->getParent(); ++ std::vector Updates; ++ + // Loop over all of the successors, removing BB's entry from any PHI + // nodes. +- for (BasicBlock *Successor : successors(BB)) ++ if (DDT) ++ Updates.reserve(BB->getTerminator()->getNumSuccessors()); ++ for (BasicBlock *Successor : successors(BB)) { + Successor->removePredecessor(BB, PreserveLCSSA); +- ++ if (DDT) ++ Updates.push_back({DominatorTree::Delete, BB, Successor}); ++ } + // Insert a call to llvm.trap right before this. This turns the undefined + // behavior into a hard fail instead of falling through into random code. + if (UseLLVMTrap) { +@@ -1474,11 +1561,13 @@ unsigned llvm::changeToUnreachable(Instr + BB->getInstList().erase(BBI++); + ++NumInstrsRemoved; + } ++ if (DDT) ++ DDT->applyUpdates(Updates); + return NumInstrsRemoved; + } + + /// changeToCall - Convert the specified invoke into a normal call. +-static void changeToCall(InvokeInst *II) { ++static void changeToCall(InvokeInst *II, DeferredDominance *DDT = nullptr) { + SmallVector Args(II->arg_begin(), II->arg_end()); + SmallVector OpBundles; + II->getOperandBundlesAsDefs(OpBundles); +@@ -1491,11 +1580,16 @@ static void changeToCall(InvokeInst *II) + II->replaceAllUsesWith(NewCall); + + // Follow the call by a branch to the normal destination. +- BranchInst::Create(II->getNormalDest(), II); ++ BasicBlock *NormalDestBB = II->getNormalDest(); ++ BranchInst::Create(NormalDestBB, II); + + // Update PHI nodes in the unwind destination +- II->getUnwindDest()->removePredecessor(II->getParent()); ++ BasicBlock *BB = II->getParent(); ++ BasicBlock *UnwindDestBB = II->getUnwindDest(); ++ UnwindDestBB->removePredecessor(BB); + II->eraseFromParent(); ++ if (DDT) ++ DDT->deleteEdge(BB, UnwindDestBB); + } + + BasicBlock *llvm::changeToInvokeAndSplitBasicBlock(CallInst *CI, +@@ -1536,7 +1630,8 @@ BasicBlock *llvm::changeToInvokeAndSplit + } + + static bool markAliveBlocks(Function &F, +- SmallPtrSetImpl &Reachable) { ++ SmallPtrSetImpl &Reachable, ++ DeferredDominance *DDT = nullptr) { + SmallVector Worklist; + BasicBlock *BB = &F.front(); + Worklist.push_back(BB); +@@ -1556,7 +1651,7 @@ static bool markAliveBlocks(Function &F, + if (II->getIntrinsicID() == Intrinsic::assume) { + if (match(II->getArgOperand(0), m_CombineOr(m_Zero(), m_Undef()))) { + // Don't insert a call to llvm.trap right before the unreachable. +- changeToUnreachable(II, false); ++ changeToUnreachable(II, false, false, DDT); + Changed = true; + break; + } +@@ -1573,7 +1668,8 @@ static bool markAliveBlocks(Function &F, + // still be useful for widening. + if (match(II->getArgOperand(0), m_Zero())) + if (!isa(II->getNextNode())) { +- changeToUnreachable(II->getNextNode(), /*UseLLVMTrap=*/ false); ++ changeToUnreachable(II->getNextNode(), /*UseLLVMTrap=*/false, ++ false, DDT); + Changed = true; + break; + } +@@ -1583,7 +1679,7 @@ static bool markAliveBlocks(Function &F, + if (auto *CI = dyn_cast(&I)) { + Value *Callee = CI->getCalledValue(); + if (isa(Callee) || isa(Callee)) { +- changeToUnreachable(CI, /*UseLLVMTrap=*/false); ++ changeToUnreachable(CI, /*UseLLVMTrap=*/false, false, DDT); + Changed = true; + break; + } +@@ -1593,7 +1689,7 @@ static bool markAliveBlocks(Function &F, + // though. + if (!isa(CI->getNextNode())) { + // Don't insert a call to llvm.trap right before the unreachable. +- changeToUnreachable(CI->getNextNode(), false); ++ changeToUnreachable(CI->getNextNode(), false, false, DDT); + Changed = true; + } + break; +@@ -1612,7 +1708,7 @@ static bool markAliveBlocks(Function &F, + if (isa(Ptr) || + (isa(Ptr) && + SI->getPointerAddressSpace() == 0)) { +- changeToUnreachable(SI, true); ++ changeToUnreachable(SI, true, false, DDT); + Changed = true; + break; + } +@@ -1624,16 +1720,20 @@ static bool markAliveBlocks(Function &F, + // Turn invokes that call 'nounwind' functions into ordinary calls. + Value *Callee = II->getCalledValue(); + if (isa(Callee) || isa(Callee)) { +- changeToUnreachable(II, true); ++ changeToUnreachable(II, true, false, DDT); + Changed = true; + } else if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(&F)) { + if (II->use_empty() && II->onlyReadsMemory()) { + // jump to the normal destination branch. +- BranchInst::Create(II->getNormalDest(), II); +- II->getUnwindDest()->removePredecessor(II->getParent()); ++ BasicBlock *NormalDestBB = II->getNormalDest(); ++ BasicBlock *UnwindDestBB = II->getUnwindDest(); ++ BranchInst::Create(NormalDestBB, II); ++ UnwindDestBB->removePredecessor(II->getParent()); + II->eraseFromParent(); ++ if (DDT) ++ DDT->deleteEdge(BB, UnwindDestBB); + } else +- changeToCall(II); ++ changeToCall(II, DDT); + Changed = true; + } + } else if (auto *CatchSwitch = dyn_cast(Terminator)) { +@@ -1679,7 +1779,7 @@ static bool markAliveBlocks(Function &F, + } + } + +- Changed |= ConstantFoldTerminator(BB, true); ++ Changed |= ConstantFoldTerminator(BB, true, nullptr, DDT); + for (BasicBlock *Successor : successors(BB)) + if (Reachable.insert(Successor).second) + Worklist.push_back(Successor); +@@ -1687,11 +1787,11 @@ static bool markAliveBlocks(Function &F, + return Changed; + } + +-void llvm::removeUnwindEdge(BasicBlock *BB) { ++void llvm::removeUnwindEdge(BasicBlock *BB, DeferredDominance *DDT) { + TerminatorInst *TI = BB->getTerminator(); + + if (auto *II = dyn_cast(TI)) { +- changeToCall(II); ++ changeToCall(II, DDT); + return; + } + +@@ -1719,15 +1819,18 @@ void llvm::removeUnwindEdge(BasicBlock * + UnwindDest->removePredecessor(BB); + TI->replaceAllUsesWith(NewTI); + TI->eraseFromParent(); ++ if (DDT) ++ DDT->deleteEdge(BB, UnwindDest); + } + + /// removeUnreachableBlocks - Remove blocks that are not reachable, even + /// if they are in a dead cycle. Return true if a change was made, false + /// otherwise. If `LVI` is passed, this function preserves LazyValueInfo + /// after modifying the CFG. +-bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI) { ++bool llvm::removeUnreachableBlocks(Function &F, LazyValueInfo *LVI, ++ DeferredDominance *DDT) { + SmallPtrSet Reachable; +- bool Changed = markAliveBlocks(F, Reachable); ++ bool Changed = markAliveBlocks(F, Reachable, DDT); + + // If there are unreachable blocks in the CFG... + if (Reachable.size() == F.size()) +@@ -1737,25 +1840,39 @@ bool llvm::removeUnreachableBlocks(Funct + NumRemoved += F.size()-Reachable.size(); + + // Loop over all of the basic blocks that are not reachable, dropping all of +- // their internal references... +- for (Function::iterator BB = ++F.begin(), E = F.end(); BB != E; ++BB) { +- if (Reachable.count(&*BB)) ++ // their internal references. Update DDT and LVI if available. ++ std::vector Updates; ++ for (Function::iterator I = ++F.begin(), E = F.end(); I != E; ++I) { ++ auto *BB = &*I; ++ if (Reachable.count(BB)) + continue; +- +- for (BasicBlock *Successor : successors(&*BB)) ++ for (BasicBlock *Successor : successors(BB)) { + if (Reachable.count(Successor)) +- Successor->removePredecessor(&*BB); ++ Successor->removePredecessor(BB); ++ if (DDT) ++ Updates.push_back({DominatorTree::Delete, BB, Successor}); ++ } + if (LVI) +- LVI->eraseBlock(&*BB); ++ LVI->eraseBlock(BB); + BB->dropAllReferences(); + } + +- for (Function::iterator I = ++F.begin(); I != F.end();) +- if (!Reachable.count(&*I)) +- I = F.getBasicBlockList().erase(I); +- else ++ for (Function::iterator I = ++F.begin(); I != F.end();) { ++ auto *BB = &*I; ++ if (Reachable.count(BB)) { ++ ++I; ++ continue; ++ } ++ if (DDT) { ++ DDT->deleteBB(BB); // deferred deletion of BB. + ++I; ++ } else { ++ I = F.getBasicBlockList().erase(I); ++ } ++ } + ++ if (DDT) ++ DDT->applyUpdates(Updates); + return true; + } + +Index: llvm-toolchain-6.0-6.0.1/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll ++++ llvm-toolchain-6.0-6.0.1/test/Analysis/LazyValueAnalysis/lvi-after-jumpthreading.ll +@@ -19,10 +19,13 @@ entry: + ; CHECK-NEXT: ; LatticeVal for: 'i32 %a' is: overdefined + ; CHECK-NEXT: ; LatticeVal for: 'i32 %length' is: overdefined + ; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%backedge' is: constantrange<0, 400> ++; CHECK-NEXT: ; LatticeVal for: ' %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ]' in BB: '%exit' is: constantrange<399, 400> + ; CHECK-NEXT: %iv = phi i32 [ 0, %entry ], [ %iv.next, %backedge ] + ; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%backedge' is: constantrange<1, 401> ++; CHECK-NEXT: ; LatticeVal for: ' %iv.next = add nsw i32 %iv, 1' in BB: '%exit' is: constantrange<400, 401> + ; CHECK-NEXT: %iv.next = add nsw i32 %iv, 1 + ; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%backedge' is: overdefined ++; CHECK-NEXT: ; LatticeVal for: ' %cont = icmp slt i32 %iv.next, 400' in BB: '%exit' is: constantrange<0, -1> + ; CHECK-NEXT: %cont = icmp slt i32 %iv.next, 400 + ; CHECK-NOT: loop + loop: +Index: llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/ddt-crash.ll +=================================================================== +--- /dev/null ++++ llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/ddt-crash.ll +@@ -0,0 +1,265 @@ ++; RUN: opt < %s -jump-threading -disable-output ++ ++%struct.ham = type { i8, i8, i16, i32 } ++%struct.zot = type { i32 (...)** } ++%struct.quux.0 = type { %struct.wombat } ++%struct.wombat = type { %struct.zot } ++ ++@global = external global %struct.ham*, align 8 ++@global.1 = external constant i8* ++ ++declare i32 @wombat.2() ++ ++define void @blam() { ++bb: ++ %tmp = load i32, i32* undef ++ %tmp1 = icmp eq i32 %tmp, 0 ++ br i1 %tmp1, label %bb11, label %bb2 ++ ++bb2: ++ %tmp3 = tail call i32 @wombat.2() ++ switch i32 %tmp3, label %bb4 [ ++ i32 0, label %bb5 ++ i32 1, label %bb7 ++ i32 2, label %bb7 ++ i32 3, label %bb11 ++ ] ++ ++bb4: ++ br label %bb7 ++ ++bb5: ++ %tmp6 = tail call i32 @wombat.2() ++ br label %bb7 ++ ++bb7: ++ %tmp8 = phi i32 [ 0, %bb5 ], [ 1, %bb4 ], [ 2, %bb2 ], [ 2, %bb2 ] ++ %tmp9 = icmp eq i32 %tmp8, 0 ++ br i1 %tmp9, label %bb11, label %bb10 ++ ++bb10: ++ ret void ++ ++bb11: ++ ret void ++} ++ ++define void @spam(%struct.ham* %arg) { ++bb: ++ %tmp = load i8, i8* undef, align 8 ++ switch i8 %tmp, label %bb11 [ ++ i8 1, label %bb11 ++ i8 2, label %bb11 ++ i8 3, label %bb1 ++ i8 4, label %bb1 ++ ] ++ ++bb1: ++ br label %bb2 ++ ++bb2: ++ %tmp3 = phi i32 [ 0, %bb1 ], [ %tmp3, %bb8 ] ++ br label %bb4 ++ ++bb4: ++ %tmp5 = load i8, i8* undef, align 8 ++ switch i8 %tmp5, label %bb11 [ ++ i8 0, label %bb11 ++ i8 1, label %bb10 ++ i8 2, label %bb10 ++ i8 3, label %bb6 ++ i8 4, label %bb6 ++ ] ++ ++bb6: ++ br label %bb7 ++ ++bb7: ++ br i1 undef, label %bb8, label %bb10 ++ ++bb8: ++ %tmp9 = icmp eq %struct.ham* undef, %arg ++ br i1 %tmp9, label %bb10, label %bb2 ++ ++bb10: ++ switch i32 %tmp3, label %bb4 [ ++ i32 0, label %bb14 ++ i32 1, label %bb11 ++ i32 2, label %bb12 ++ ] ++ ++bb11: ++ unreachable ++ ++bb12: ++ %tmp13 = load %struct.ham*, %struct.ham** undef ++ br label %bb14 ++ ++bb14: ++ %tmp15 = phi %struct.ham* [ %tmp13, %bb12 ], [ null, %bb10 ] ++ br label %bb16 ++ ++bb16: ++ %tmp17 = load i8, i8* undef, align 8 ++ switch i8 %tmp17, label %bb11 [ ++ i8 0, label %bb11 ++ i8 11, label %bb18 ++ i8 12, label %bb18 ++ ] ++ ++bb18: ++ br label %bb19 ++ ++bb19: ++ br label %bb20 ++ ++bb20: ++ %tmp21 = load %struct.ham*, %struct.ham** undef ++ switch i8 undef, label %bb22 [ ++ i8 0, label %bb4 ++ i8 11, label %bb10 ++ i8 12, label %bb10 ++ ] ++ ++bb22: ++ br label %bb23 ++ ++bb23: ++ %tmp24 = icmp eq %struct.ham* %tmp21, null ++ br i1 %tmp24, label %bb35, label %bb25 ++ ++bb25: ++ %tmp26 = icmp eq %struct.ham* %tmp15, null ++ br i1 %tmp26, label %bb34, label %bb27 ++ ++bb27: ++ %tmp28 = load %struct.ham*, %struct.ham** undef ++ %tmp29 = icmp eq %struct.ham* %tmp28, %tmp21 ++ br i1 %tmp29, label %bb35, label %bb30 ++ ++bb30: ++ br label %bb31 ++ ++bb31: ++ %tmp32 = load i8, i8* undef, align 8 ++ %tmp33 = icmp eq i8 %tmp32, 0 ++ br i1 %tmp33, label %bb31, label %bb34 ++ ++bb34: ++ br label %bb35 ++ ++bb35: ++ %tmp36 = phi i1 [ true, %bb34 ], [ false, %bb23 ], [ true, %bb27 ] ++ br label %bb37 ++ ++bb37: ++ %tmp38 = icmp eq %struct.ham* %tmp15, null ++ br i1 %tmp38, label %bb39, label %bb41 ++ ++bb39: ++ %tmp40 = load %struct.ham*, %struct.ham** @global ++ br label %bb41 ++ ++bb41: ++ %tmp42 = select i1 %tmp36, %struct.ham* undef, %struct.ham* undef ++ ret void ++} ++ ++declare i32 @foo(...) ++ ++define void @zot() align 2 personality i8* bitcast (i32 (...)* @foo to i8*) { ++bb: ++ invoke void @bar() ++ to label %bb1 unwind label %bb3 ++ ++bb1: ++ invoke void @bar() ++ to label %bb2 unwind label %bb4 ++ ++bb2: ++ invoke void @bar() ++ to label %bb6 unwind label %bb17 ++ ++bb3: ++ %tmp = landingpad { i8*, i32 } ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ unreachable ++ ++bb4: ++ %tmp5 = landingpad { i8*, i32 } ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ unreachable ++ ++bb6: ++ invoke void @bar() ++ to label %bb7 unwind label %bb19 ++ ++bb7: ++ invoke void @bar() ++ to label %bb10 unwind label %bb8 ++ ++bb8: ++ %tmp9 = landingpad { i8*, i32 } ++ cleanup ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ unreachable ++ ++bb10: ++ %tmp11 = load i32 (%struct.zot*)*, i32 (%struct.zot*)** undef, align 8 ++ %tmp12 = invoke i32 %tmp11(%struct.zot* nonnull undef) ++ to label %bb13 unwind label %bb21 ++ ++bb13: ++ invoke void @bar() ++ to label %bb14 unwind label %bb23 ++ ++bb14: ++ %tmp15 = load i32 (%struct.zot*)*, i32 (%struct.zot*)** undef, align 8 ++ %tmp16 = invoke i32 %tmp15(%struct.zot* nonnull undef) ++ to label %bb26 unwind label %bb23 ++ ++bb17: ++ %tmp18 = landingpad { i8*, i32 } ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ unreachable ++ ++bb19: ++ %tmp20 = landingpad { i8*, i32 } ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ unreachable ++ ++bb21: ++ %tmp22 = landingpad { i8*, i32 } ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ unreachable ++ ++bb23: ++ %tmp24 = phi %struct.quux.0* [ null, %bb26 ], [ null, %bb14 ], [ undef, %bb13 ] ++ %tmp25 = landingpad { i8*, i32 } ++ catch i8* bitcast (i8** @global.1 to i8*) ++ catch i8* null ++ br label %bb30 ++ ++bb26: ++ %tmp27 = load i32 (%struct.zot*)*, i32 (%struct.zot*)** undef, align 8 ++ %tmp28 = invoke i32 %tmp27(%struct.zot* nonnull undef) ++ to label %bb29 unwind label %bb23 ++ ++bb29: ++ unreachable ++ ++bb30: ++ %tmp31 = icmp eq %struct.quux.0* %tmp24, null ++ br i1 %tmp31, label %bb32, label %bb29 ++ ++bb32: ++ unreachable ++} ++ ++declare void @bar() +Index: llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/ddt-crash2.ll +=================================================================== +--- /dev/null ++++ llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/ddt-crash2.ll +@@ -0,0 +1,40 @@ ++; RUN: opt < %s -jump-threading -disable-output ++ ++%struct.aaa = type { i8 } ++ ++define void @chrome(%struct.aaa* noalias sret %arg) local_unnamed_addr #0 align 2 personality i8* bitcast (i32 (...)* @chrome2 to i8*) { ++bb: ++ %tmp = load i32, i32* undef, align 4 ++ %tmp1 = icmp eq i32 %tmp, 0 ++ br i1 %tmp1, label %bb2, label %bb13 ++ ++bb2: ++ %tmp3 = getelementptr inbounds %struct.aaa, %struct.aaa* %arg, i64 0, i32 0 ++ %tmp4 = load i8, i8* %tmp3, align 1 ++ %tmp5 = icmp eq i8 %tmp4, 0 ++ br i1 %tmp5, label %bb6, label %bb7 ++ ++bb6: ++ store i8 0, i8* %tmp3, align 1 ++ br label %bb7 ++ ++bb7: ++ %tmp8 = load i8, i8* %tmp3, align 1 ++ %tmp9 = icmp ne i8 %tmp8, 0 ++ %tmp10 = select i1 %tmp9, i1 true, i1 false ++ br i1 %tmp10, label %bb12, label %bb11 ++ ++bb11: ++ br label %bb12 ++ ++bb12: ++ br i1 %tmp9, label %bb14, label %bb13 ++ ++bb13: ++ unreachable ++ ++bb14: ++ ret void ++} ++ ++declare i32 @chrome2(...) +Index: llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/lvi-tristate.ll +=================================================================== +--- /dev/null ++++ llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/lvi-tristate.ll +@@ -0,0 +1,50 @@ ++; RUN: opt -jump-threading -simplifycfg -S < %s | FileCheck %s ++; CHECK-NOT: bb6: ++; CHECK-NOT: bb7: ++; CHECK-NOT: bb8: ++; CHECK-NOT: bb11: ++; CHECK-NOT: bb12: ++; CHECK: bb: ++; CHECK: bb2: ++; CHECK: bb4: ++; CHECK: bb10: ++; CHECK: bb13: ++declare void @ham() ++ ++define void @hoge() { ++bb: ++ %tmp = and i32 undef, 1073741823 ++ %tmp1 = icmp eq i32 %tmp, 2 ++ br i1 %tmp1, label %bb12, label %bb2 ++ ++bb2: ++ %tmp3 = icmp eq i32 %tmp, 3 ++ br i1 %tmp3, label %bb13, label %bb4 ++ ++bb4: ++ %tmp5 = icmp eq i32 %tmp, 5 ++ br i1 %tmp5, label %bb6, label %bb7 ++ ++bb6: ++ tail call void @ham() ++ br label %bb7 ++ ++bb7: ++ br i1 %tmp3, label %bb13, label %bb8 ++ ++bb8: ++ %tmp9 = icmp eq i32 %tmp, 4 ++ br i1 %tmp9, label %bb13, label %bb10 ++ ++bb10: ++ br i1 %tmp9, label %bb11, label %bb13 ++ ++bb11: ++ br label %bb13 ++ ++bb12: ++ br label %bb2 ++ ++bb13: ++ ret void ++} +Index: llvm-toolchain-6.0-6.0.1/unittests/IR/CMakeLists.txt +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/unittests/IR/CMakeLists.txt ++++ llvm-toolchain-6.0-6.0.1/unittests/IR/CMakeLists.txt +@@ -15,6 +15,7 @@ set(IRSources + ConstantsTest.cpp + DebugInfoTest.cpp + DebugTypeODRUniquingTest.cpp ++ DeferredDominanceTest.cpp + DominatorTreeTest.cpp + DominatorTreeBatchUpdatesTest.cpp + FunctionTest.cpp +Index: llvm-toolchain-6.0-6.0.1/unittests/IR/DeferredDominanceTest.cpp +=================================================================== +--- /dev/null ++++ llvm-toolchain-6.0-6.0.1/unittests/IR/DeferredDominanceTest.cpp +@@ -0,0 +1,344 @@ ++//===- llvm/unittests/IR/DeferredDominanceTest.cpp - DDT unit tests -------===// ++// ++// The LLVM Compiler Infrastructure ++// ++// This file is distributed under the University of Illinois Open Source ++// License. See LICENSE.TXT for details. ++// ++//===----------------------------------------------------------------------===// ++ ++#include "llvm/AsmParser/Parser.h" ++#include "llvm/IR/Constants.h" ++#include "llvm/IR/Dominators.h" ++#include "llvm/IR/Instructions.h" ++#include "llvm/IR/LLVMContext.h" ++#include "llvm/IR/Module.h" ++#include "llvm/Support/SourceMgr.h" ++#include "gtest/gtest.h" ++ ++using namespace llvm; ++ ++static std::unique_ptr makeLLVMModule(LLVMContext &Context, ++ StringRef ModuleStr) { ++ SMDiagnostic Err; ++ std::unique_ptr M = parseAssemblyString(ModuleStr, Err, Context); ++ assert(M && "Bad LLVM IR?"); ++ return M; ++} ++ ++TEST(DeferredDominance, BasicOperations) { ++ StringRef FuncName = "f"; ++ StringRef ModuleString = ++ "define i32 @f(i32 %i, i32 *%p) {\n" ++ " bb0:\n" ++ " store i32 %i, i32 *%p\n" ++ " switch i32 %i, label %bb1 [\n" ++ " i32 0, label %bb2\n" ++ " i32 1, label %bb2\n" ++ " i32 2, label %bb3\n" ++ " ]\n" ++ " bb1:\n" ++ " ret i32 1\n" ++ " bb2:\n" ++ " ret i32 2\n" ++ " bb3:\n" ++ " ret i32 3\n" ++ "}\n"; ++ // Make the module. ++ LLVMContext Context; ++ std::unique_ptr M = makeLLVMModule(Context, ModuleString); ++ Function *F = M->getFunction(FuncName); ++ ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << "."; ++ ++ // Make the DDT. ++ DominatorTree DT(*F); ++ DeferredDominance DDT(DT); ++ ASSERT_TRUE(DDT.flush().verify()); ++ ++ Function::iterator FI = F->begin(); ++ BasicBlock *BB0 = &*FI++; ++ BasicBlock *BB1 = &*FI++; ++ BasicBlock *BB2 = &*FI++; ++ BasicBlock *BB3 = &*FI++; ++ ++ // Test discards of invalid self-domination updates. These use the single ++ // short-hand interface but are still queued inside DDT. ++ DDT.deleteEdge(BB0, BB0); ++ DDT.insertEdge(BB1, BB1); ++ ++ // Delete edge bb0 -> bb3 and push the update twice to verify duplicate ++ // entries are discarded. ++ std::vector Updates; ++ Updates.reserve(4); ++ Updates.push_back({DominatorTree::Delete, BB0, BB3}); ++ Updates.push_back({DominatorTree::Delete, BB0, BB3}); ++ ++ // Unnecessary Insert: no edge bb1 -> bb2 after change to bb0. ++ Updates.push_back({DominatorTree::Insert, BB1, BB2}); ++ // Unnecessary Delete: edge exists bb0 -> bb1 after change to bb0. ++ Updates.push_back({DominatorTree::Delete, BB0, BB1}); ++ ++ // CFG Change: remove edge bb0 -> bb3 and one duplicate edge bb0 -> bb2. ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 4u); ++ BB0->getTerminator()->eraseFromParent(); ++ BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0); ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u); ++ ++ // Deletion of a BasicBlock is an immediate event. We remove all uses to the ++ // contained Instructions and change the Terminator to "unreachable" when ++ // queued for deletion. Its parent is still F until DDT.flush() is called. We ++ // don't defer this action because it can cause problems for other transforms ++ // or analysis as it's part of the actual CFG. We only defer updates to the ++ // DominatorTree. This code will crash if it is placed before the ++ // BranchInst::Create() call above. ++ ASSERT_FALSE(isa(BB3->getTerminator())); ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB3)); ++ DDT.deleteBB(BB3); ++ EXPECT_TRUE(DDT.pendingDeletedBB(BB3)); ++ ASSERT_TRUE(isa(BB3->getTerminator())); ++ EXPECT_EQ(BB3->getParent(), F); ++ ++ // Verify. Updates to DDT must be applied *after* all changes to the CFG ++ // (including block deletion). ++ DDT.applyUpdates(Updates); ++ ASSERT_TRUE(DDT.flush().verify()); ++} ++ ++TEST(DeferredDominance, PairedUpdate) { ++ StringRef FuncName = "f"; ++ StringRef ModuleString = ++ "define i32 @f(i32 %i, i32 *%p) {\n" ++ " bb0:\n" ++ " store i32 %i, i32 *%p\n" ++ " switch i32 %i, label %bb1 [\n" ++ " i32 0, label %bb2\n" ++ " i32 1, label %bb2\n" ++ " ]\n" ++ " bb1:\n" ++ " ret i32 1\n" ++ " bb2:\n" ++ " ret i32 2\n" ++ "}\n"; ++ // Make the module. ++ LLVMContext Context; ++ std::unique_ptr M = makeLLVMModule(Context, ModuleString); ++ Function *F = M->getFunction(FuncName); ++ ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << "."; ++ ++ // Make the DDT. ++ DominatorTree DT(*F); ++ DeferredDominance DDT(DT); ++ ASSERT_TRUE(DDT.flush().verify()); ++ ++ Function::iterator FI = F->begin(); ++ BasicBlock *BB0 = &*FI++; ++ BasicBlock *BB1 = &*FI++; ++ BasicBlock *BB2 = &*FI++; ++ ++ // CFG Change: only edge from bb0 is bb0 -> bb1. ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u); ++ BB0->getTerminator()->eraseFromParent(); ++ BranchInst::Create(BB1, BB0); ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u); ++ ++ // Must be done after the CFG change. The applyUpdate() routine analyzes the ++ // current state of the CFG. ++ DDT.deleteEdge(BB0, BB2); ++ ++ // CFG Change: bb0 now has bb0 -> bb1 and bb0 -> bb2. ++ // With this change no dominance has been altered from the original IR. DT ++ // doesn't care if the type of TerminatorInstruction changed, only if the ++ // unique edges have. ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u); ++ BB0->getTerminator()->eraseFromParent(); ++ BranchInst::Create(BB1, BB2, ConstantInt::getTrue(F->getContext()), BB0); ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u); ++ ++ // Must be done after the CFG change. The applyUpdate() routine analyzes the ++ // current state of the CFG. This DDT update pairs with the previous one and ++ // is cancelled out before ever applying updates to DT. ++ DDT.insertEdge(BB0, BB2); ++ ++ // Test the empty DeletedBB list. ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB0)); ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB1)); ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB2)); ++ ++ // The DT has no changes, this flush() simply returns a reference to the ++ // internal DT calculated at the beginning of this test. ++ ASSERT_TRUE(DDT.flush().verify()); ++} ++ ++TEST(DeferredDominance, ReplaceEntryBB) { ++ StringRef FuncName = "f"; ++ StringRef ModuleString = ++ "define i32 @f() {\n" ++ "bb0:\n" ++ " br label %bb1\n" ++ " bb1:\n" ++ " ret i32 1\n" ++ "}\n"; ++ // Make the module. ++ LLVMContext Context; ++ std::unique_ptr M = makeLLVMModule(Context, ModuleString); ++ Function *F = M->getFunction(FuncName); ++ ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << "."; ++ ++ // Make the DDT. ++ DominatorTree DT(*F); ++ DeferredDominance DDT(DT); ++ ASSERT_TRUE(DDT.flush().verify()); ++ ++ Function::iterator FI = F->begin(); ++ BasicBlock *BB0 = &*FI++; ++ BasicBlock *BB1 = &*FI++; ++ ++ // Add a block as the new function entry BB. We also link it to BB0. ++ BasicBlock *NewEntry = ++ BasicBlock::Create(F->getContext(), "new_entry", F, BB0); ++ BranchInst::Create(BB0, NewEntry); ++ EXPECT_EQ(F->begin()->getName(), NewEntry->getName()); ++ EXPECT_TRUE(&F->getEntryBlock() == NewEntry); ++ ++ // Insert the new edge between new_eentry -> bb0. Without this the ++ // recalculate() call below will not actually recalculate the DT as there ++ // are no changes pending and no blocks deleted. ++ DDT.insertEdge(NewEntry, BB0); ++ ++ // Changing the Entry BB requires a full recalulation. ++ DDT.recalculate(*F); ++ ASSERT_TRUE(DDT.flush().verify()); ++ ++ // CFG Change: remove new_edge -> bb0 and redirect to new_edge -> bb1. ++ EXPECT_EQ(NewEntry->getTerminator()->getNumSuccessors(), 1u); ++ NewEntry->getTerminator()->eraseFromParent(); ++ BranchInst::Create(BB1, NewEntry); ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u); ++ ++ // Update the DDT. At this point bb0 now has no predecessors but is still a ++ // Child of F. ++ DDT.applyUpdates({{DominatorTree::Delete, NewEntry, BB0}, ++ {DominatorTree::Insert, NewEntry, BB1}}); ++ ASSERT_TRUE(DDT.flush().verify()); ++ ++ // Now remove bb0 from F. ++ ASSERT_FALSE(isa(BB0->getTerminator())); ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB0)); ++ DDT.deleteBB(BB0); ++ EXPECT_TRUE(DDT.pendingDeletedBB(BB0)); ++ ASSERT_TRUE(isa(BB0->getTerminator())); ++ EXPECT_EQ(BB0->getParent(), F); ++ ++ // Perform a full recalculation of the DDT. It is not necessary here but we ++ // do this to test the case when there are no pending DT updates but there are ++ // pending deleted BBs. ++ DDT.recalculate(*F); ++ ASSERT_TRUE(DDT.flush().verify()); ++} ++ ++TEST(DeferredDominance, InheritedPreds) { ++ StringRef FuncName = "f"; ++ StringRef ModuleString = ++ "define i32 @f(i32 %i, i32 *%p) {\n" ++ " bb0:\n" ++ " store i32 %i, i32 *%p\n" ++ " switch i32 %i, label %bb1 [\n" ++ " i32 2, label %bb2\n" ++ " i32 3, label %bb3\n" ++ " ]\n" ++ " bb1:\n" ++ " br label %bb3\n" ++ " bb2:\n" ++ " br label %bb3\n" ++ " bb3:\n" ++ " ret i32 3\n" ++ "}\n"; ++ // Make the module. ++ LLVMContext Context; ++ std::unique_ptr M = makeLLVMModule(Context, ModuleString); ++ Function *F = M->getFunction(FuncName); ++ ASSERT_NE(F, nullptr) << "Couldn't get function " << FuncName << "."; ++ ++ // Make the DDT. ++ DominatorTree DT(*F); ++ DeferredDominance DDT(DT); ++ ASSERT_TRUE(DDT.flush().verify()); ++ ++ Function::iterator FI = F->begin(); ++ BasicBlock *BB0 = &*FI++; ++ BasicBlock *BB1 = &*FI++; ++ BasicBlock *BB2 = &*FI++; ++ BasicBlock *BB3 = &*FI++; ++ ++ // There are several CFG locations where we have: ++ // ++ // pred1..predN ++ // | | ++ // +> curr <+ converted into: pred1..predN curr ++ // | | | ++ // v +> succ <+ ++ // succ ++ // ++ // There is a specific shape of this we have to be careful of: ++ // ++ // pred1..predN ++ // || | ++ // |+> curr <+ converted into: pred1..predN curr ++ // | | | | ++ // | v +> succ <+ ++ // +-> succ ++ // ++ // While the final CFG form is functionally identical the updates to ++ // DDT are not. In the first case we must have DDT.insertEdge(Pred1, Succ) ++ // while in the latter case we must *NOT* have DDT.insertEdge(Pred1, Succ). ++ ++ // CFG Change: bb0 now only has bb0 -> bb1 and bb0 -> bb3. We are preparing to ++ // remove bb2. ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 3u); ++ BB0->getTerminator()->eraseFromParent(); ++ BranchInst::Create(BB1, BB3, ConstantInt::getTrue(F->getContext()), BB0); ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u); ++ ++ // Remove bb2 from F. This has to happen before the call to applyUpdates() for ++ // DDT to detect there is no longer an edge between bb2 -> bb3. The deleteBB() ++ // method converts bb2's TI into "unreachable". ++ ASSERT_FALSE(isa(BB2->getTerminator())); ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB2)); ++ DDT.deleteBB(BB2); ++ EXPECT_TRUE(DDT.pendingDeletedBB(BB2)); ++ ASSERT_TRUE(isa(BB2->getTerminator())); ++ EXPECT_EQ(BB2->getParent(), F); ++ ++ // Queue up the DDT updates. ++ std::vector Updates; ++ Updates.reserve(4); ++ Updates.push_back({DominatorTree::Delete, BB0, BB2}); ++ Updates.push_back({DominatorTree::Delete, BB2, BB3}); ++ ++ // Handle the specific shape case next. ++ // CFG Change: bb0 now only branches to bb3. We are preparing to remove bb1. ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 2u); ++ BB0->getTerminator()->eraseFromParent(); ++ BranchInst::Create(BB3, BB0); ++ EXPECT_EQ(BB0->getTerminator()->getNumSuccessors(), 1u); ++ ++ // Remove bb1 from F. This has to happen before the call to applyUpdates() for ++ // DDT to detect there is no longer an edge between bb1 -> bb3. The deleteBB() ++ // method converts bb1's TI into "unreachable". ++ ASSERT_FALSE(isa(BB1->getTerminator())); ++ EXPECT_FALSE(DDT.pendingDeletedBB(BB1)); ++ DDT.deleteBB(BB1); ++ EXPECT_TRUE(DDT.pendingDeletedBB(BB1)); ++ ASSERT_TRUE(isa(BB1->getTerminator())); ++ EXPECT_EQ(BB1->getParent(), F); ++ ++ // Update the DDT. In this case we don't call DDT.insertEdge(BB0, BB3) because ++ // the edge previously existed at the start of this test when DT was first ++ // created. ++ Updates.push_back({DominatorTree::Delete, BB0, BB1}); ++ Updates.push_back({DominatorTree::Delete, BB1, BB3}); ++ ++ // Verify everything. ++ DDT.applyUpdates(Updates); ++ ASSERT_TRUE(DDT.flush().verify()); ++} diff --git a/debian/patches/D42717-JumpThreading-backport-2.diff b/debian/patches/D42717-JumpThreading-backport-2.diff new file mode 100644 index 00000000..3b1f8a30 --- /dev/null +++ b/debian/patches/D42717-JumpThreading-backport-2.diff @@ -0,0 +1,267 @@ +Index: llvm-toolchain-6.0-6.0.1/include/llvm/Analysis/LazyValueInfo.h +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/include/llvm/Analysis/LazyValueInfo.h ++++ llvm-toolchain-6.0-6.0.1/include/llvm/Analysis/LazyValueInfo.h +@@ -113,6 +113,13 @@ public: + /// in LVI, so we need to pass it here as an argument. + void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS); + ++ /// Disables use of the DominatorTree within LVI. ++ void disableDT(); ++ ++ /// Enables use of the DominatorTree within LVI. Does nothing if the class ++ /// instance was initialized without a DT pointer. ++ void enableDT(); ++ + // For old PM pass. Delete once LazyValueInfoWrapperPass is gone. + void releaseMemory(); + +Index: llvm-toolchain-6.0-6.0.1/include/llvm/IR/Dominators.h +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/include/llvm/IR/Dominators.h ++++ llvm-toolchain-6.0-6.0.1/include/llvm/IR/Dominators.h +@@ -342,6 +342,9 @@ public: + /// \brief Returns true if DelBB is awaiting deletion at a flush() event. + bool pendingDeletedBB(BasicBlock *DelBB); + ++ /// \brief Returns true if pending DT updates are queued for a flush() event. ++ bool pending(); ++ + /// \brief Flushes all pending updates and block deletions. Returns a + /// correct DominatorTree reference to be used by the caller for analysis. + DominatorTree &flush(); +Index: llvm-toolchain-6.0-6.0.1/lib/Analysis/LazyValueInfo.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/Analysis/LazyValueInfo.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/Analysis/LazyValueInfo.cpp +@@ -401,6 +401,7 @@ namespace { + AssumptionCache *AC; ///< A pointer to the cache of @llvm.assume calls. + const DataLayout &DL; ///< A mandatory DataLayout + DominatorTree *DT; ///< An optional DT pointer. ++ DominatorTree *DisabledDT; ///< Stores DT if it's disabled. + + ValueLatticeElement getBlockValue(Value *Val, BasicBlock *BB); + bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T, +@@ -463,13 +464,30 @@ namespace { + TheCache.eraseBlock(BB); + } + ++ /// Disables use of the DominatorTree within LVI. ++ void disableDT() { ++ if (DT) { ++ assert(!DisabledDT && "Both DT and DisabledDT are not nullptr!"); ++ std::swap(DT, DisabledDT); ++ } ++ } ++ ++ /// Enables use of the DominatorTree within LVI. Does nothing if the class ++ /// instance was initialized without a DT pointer. ++ void enableDT() { ++ if (DisabledDT) { ++ assert(!DT && "Both DT and DisabledDT are not nullptr!"); ++ std::swap(DT, DisabledDT); ++ } ++ } ++ + /// This is the update interface to inform the cache that an edge from + /// PredBB to OldSucc has been threaded to be from PredBB to NewSucc. + void threadEdge(BasicBlock *PredBB,BasicBlock *OldSucc,BasicBlock *NewSucc); + + LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL, + DominatorTree *DT = nullptr) +- : AC(AC), DL(DL), DT(DT) {} ++ : AC(AC), DL(DL), DT(DT), DisabledDT(nullptr) {} + }; + } // end anonymous namespace + +@@ -1791,6 +1809,16 @@ void LazyValueInfo::printLVI(Function &F + } + } + ++void LazyValueInfo::disableDT() { ++ if (PImpl) ++ getImpl(PImpl, AC, DL, DT).disableDT(); ++} ++ ++void LazyValueInfo::enableDT() { ++ if (PImpl) ++ getImpl(PImpl, AC, DL, DT).enableDT(); ++} ++ + // Print the LVI for the function arguments at the start of each basic block. + void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot( + const BasicBlock *BB, formatted_raw_ostream &OS) { +Index: llvm-toolchain-6.0-6.0.1/lib/IR/Dominators.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/IR/Dominators.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/IR/Dominators.cpp +@@ -453,6 +453,9 @@ bool DeferredDominance::pendingDeletedBB + return DeletedBBs.count(DelBB) != 0; + } + ++/// \brief Returns true if pending DT updates are queued for a flush() event. ++bool DeferredDominance::pending() { return !PendUpdates.empty(); } ++ + /// \brief Flushes all pending updates and block deletions. Returns a + /// correct DominatorTree reference to be used by the caller for analysis. + DominatorTree &DeferredDominance::flush() { +Index: llvm-toolchain-6.0-6.0.1/lib/Transforms/Scalar/JumpThreading.cpp +=================================================================== +--- llvm-toolchain-6.0-6.0.1.orig/lib/Transforms/Scalar/JumpThreading.cpp ++++ llvm-toolchain-6.0-6.0.1/lib/Transforms/Scalar/JumpThreading.cpp +@@ -425,6 +425,7 @@ bool JumpThreadingPass::runImpl(Function + + LoopHeaders.clear(); + DDT->flush(); ++ LVI->enableDT(); + return EverChanged; + } + +@@ -617,6 +618,10 @@ bool JumpThreadingPass::ComputeValueKnow + // "X < 4" and "X < 3" is known true but "X < 4" itself is not available. + // Perhaps getConstantOnEdge should be smart enough to do this? + ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + for (BasicBlock *P : predecessors(BB)) { + // If the value is known by LazyValueInfo to be a constant in a + // predecessor, use that information to try to thread this block. +@@ -630,6 +635,10 @@ bool JumpThreadingPass::ComputeValueKnow + + /// If I is a PHI node, then we know the incoming values for any constants. + if (PHINode *PN = dyn_cast(I)) { ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + Value *InVal = PN->getIncomingValue(i); + if (Constant *KC = getKnownConstant(InVal, Preference)) { +@@ -759,6 +768,10 @@ bool JumpThreadingPass::ComputeValueKnow + const DataLayout &DL = PN->getModule()->getDataLayout(); + // We can do this simplification if any comparisons fold to true or false. + // See if any do. ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + BasicBlock *PredBB = PN->getIncomingBlock(i); + Value *LHS = PN->getIncomingValue(i); +@@ -792,6 +805,10 @@ bool JumpThreadingPass::ComputeValueKnow + + if (!isa(CmpLHS) || + cast(CmpLHS)->getParent() != BB) { ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + for (BasicBlock *P : predecessors(BB)) { + // If the value is known by LazyValueInfo to be a constant in a + // predecessor, use that information to try to thread this block. +@@ -820,6 +837,10 @@ bool JumpThreadingPass::ComputeValueKnow + match(CmpLHS, m_Add(m_Value(AddLHS), m_ConstantInt(AddConst)))) { + if (!isa(AddLHS) || + cast(AddLHS)->getParent() != BB) { ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + for (BasicBlock *P : predecessors(BB)) { + // If the value is known by LazyValueInfo to be a ConstantRange in + // a predecessor, use that information to try to thread this +@@ -901,6 +922,10 @@ bool JumpThreadingPass::ComputeValueKnow + } + + // If all else fails, see if LVI can figure out a constant value for us. ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + Constant *CI = LVI->getConstant(V, BB, CxtI); + if (Constant *KC = getKnownConstant(CI, Preference)) { + for (BasicBlock *Pred : predecessors(BB)) +@@ -1102,6 +1127,10 @@ bool JumpThreadingPass::ProcessBlock(Bas + // threading is concerned. + assert(CondBr->isConditional() && "Threading on unconditional terminator"); + ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + LazyValueInfo::Tristate Ret = + LVI->getPredicateAt(CondCmp->getPredicate(), CondCmp->getOperand(0), + CondConst, CondBr); +@@ -1914,6 +1943,10 @@ bool JumpThreadingPass::ThreadEdge(Basic + << ", across block:\n " + << *BB << "\n"); + ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + LVI->threadEdge(PredBB, BB, SuccBB); + + // We are going to have to map operands from the original BB block to the new +@@ -2383,6 +2416,10 @@ bool JumpThreadingPass::TryToUnfoldSelec + // Now check if one of the select values would allow us to constant fold the + // terminator in BB. We don't do the transform if both sides fold, those + // cases will be threaded in any case. ++ if (DDT->pending()) ++ LVI->disableDT(); ++ else ++ LVI->enableDT(); + LazyValueInfo::Tristate LHSFolds = + LVI->getPredicateOnEdge(CondCmp->getPredicate(), SI->getOperand(1), + CondRHS, Pred, BB, CondCmp); +Index: llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/pr36133.ll +=================================================================== +--- /dev/null ++++ llvm-toolchain-6.0-6.0.1/test/Transforms/JumpThreading/pr36133.ll +@@ -0,0 +1,44 @@ ++; RUN: opt -jump-threading -S < %s | FileCheck %s ++@global = external global i8*, align 8 ++ ++define i32 @foo(i32 %arg) { ++; CHECK-LABEL: @foo ++; CHECK-LABEL: bb: ++; CHECK: icmp eq ++; CHECK-NEXT: br i1 %tmp1, label %bb7, label %bb7 ++bb: ++ %tmp = load i8*, i8** @global, align 8 ++ %tmp1 = icmp eq i8* %tmp, null ++ br i1 %tmp1, label %bb3, label %bb2 ++ ++; CHECK-NOT: bb2: ++bb2: ++ br label %bb3 ++ ++; CHECK-NOT: bb3: ++bb3: ++ %tmp4 = phi i8 [ 1, %bb2 ], [ 0, %bb ] ++ %tmp5 = icmp eq i8 %tmp4, 0 ++ br i1 %tmp5, label %bb7, label %bb6 ++ ++; CHECK-NOT: bb6: ++bb6: ++ br label %bb7 ++ ++; CHECK-LABEL: bb7: ++bb7: ++ %tmp8 = icmp eq i32 %arg, -1 ++ br i1 %tmp8, label %bb9, label %bb10 ++ ++; CHECK-LABEL: bb9: ++bb9: ++ ret i32 0 ++ ++; CHECK-LABEL: bb10: ++bb10: ++ %tmp11 = icmp sgt i32 %arg, -1 ++ call void @llvm.assume(i1 %tmp11) ++ ret i32 1 ++} ++ ++declare void @llvm.assume(i1) diff --git a/debian/patches/lldb-soname.diff b/debian/patches/lldb-soname.diff index 16288a89..462ed552 100644 --- a/debian/patches/lldb-soname.diff +++ b/debian/patches/lldb-soname.diff @@ -29,7 +29,7 @@ Index: llvm-toolchain-snapshot_8~svn339515/lldb/source/API/CMakeLists.txt ) if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") -@@ -136,11 +141,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" +@@ -141,11 +141,6 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" if (MSVC AND NOT LLDB_DISABLE_PYTHON) target_link_libraries(liblldb PRIVATE ${PYTHON_LIBRARY}) endif() diff --git a/debian/patches/llvm-D49832-SCEVPred.patch b/debian/patches/llvm-D49832-SCEVPred.patch new file mode 100644 index 00000000..332b07ef --- /dev/null +++ b/debian/patches/llvm-D49832-SCEVPred.patch @@ -0,0 +1,187 @@ +commit 98592fcc61307968f7df1362771534595a1e1c21 +Author: Keno Fischer +Date: Wed Jul 25 19:29:02 2018 -0400 + + [SCEV] Don't expand Wrap predicate using inttoptr in ni addrspaces + + Summary: + In non-integral address spaces, we're not allowed to introduce inttoptr/ptrtoint + intrinsics. Instead, we need to expand any pointer arithmetic as geps on the + base pointer. Luckily this is a common task for SCEV, so all we have to do here + is hook up the corresponding helper function and add test case. + + Fixes PR38290 + + Reviewers: reames, sanjoy + + Subscribers: javed.absar, llvm-commits + + Differential Revision: https://reviews.llvm.org/D49832 + +diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp +index 7f76f057216..f441a3647fb 100644 +--- a/lib/Analysis/ScalarEvolutionExpander.cpp ++++ b/lib/Analysis/ScalarEvolutionExpander.cpp +@@ -2154,8 +2154,9 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, + const SCEV *Step = AR->getStepRecurrence(SE); + const SCEV *Start = AR->getStart(); + ++ Type *ARTy = AR->getType(); + unsigned SrcBits = SE.getTypeSizeInBits(ExitCount->getType()); +- unsigned DstBits = SE.getTypeSizeInBits(AR->getType()); ++ unsigned DstBits = SE.getTypeSizeInBits(ARTy); + + // The expression {Start,+,Step} has nusw/nssw if + // Step < 0, Start - |Step| * Backedge <= Start +@@ -2167,11 +2168,12 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, + Value *TripCountVal = expandCodeFor(ExitCount, CountTy, Loc); + + IntegerType *Ty = +- IntegerType::get(Loc->getContext(), SE.getTypeSizeInBits(AR->getType())); ++ IntegerType::get(Loc->getContext(), SE.getTypeSizeInBits(ARTy)); ++ Type *ARExpandTy = DL.isNonIntegralPointerType(ARTy) ? ARTy : Ty; + + Value *StepValue = expandCodeFor(Step, Ty, Loc); + Value *NegStepValue = expandCodeFor(SE.getNegativeSCEV(Step), Ty, Loc); +- Value *StartValue = expandCodeFor(Start, Ty, Loc); ++ Value *StartValue = expandCodeFor(Start, ARExpandTy, Loc); + + ConstantInt *Zero = + ConstantInt::get(Loc->getContext(), APInt::getNullValue(DstBits)); +@@ -2194,8 +2196,21 @@ Value *SCEVExpander::generateOverflowCheck(const SCEVAddRecExpr *AR, + // Compute: + // Start + |Step| * Backedge < Start + // Start - |Step| * Backedge > Start +- Value *Add = Builder.CreateAdd(StartValue, MulV); +- Value *Sub = Builder.CreateSub(StartValue, MulV); ++ Value *Add = nullptr, *Sub = nullptr; ++ if (ARExpandTy->isPointerTy()) { ++ PointerType *ARPtrTy = cast(ARExpandTy); ++ const SCEV *MulS = SE.getSCEV(MulV); ++ const SCEV *const StepArray[2] = {MulS, SE.getNegativeSCEV(MulS)}; ++ Add = Builder.CreateBitCast( ++ expandAddToGEP(&StepArray[0], &StepArray[1], ARPtrTy, Ty, StartValue), ++ ARPtrTy); ++ Sub = Builder.CreateBitCast( ++ expandAddToGEP(&StepArray[1], &StepArray[2], ARPtrTy, Ty, StartValue), ++ ARPtrTy); ++ } else { ++ Add = Builder.CreateAdd(StartValue, MulV); ++ Sub = Builder.CreateSub(StartValue, MulV); ++ } + + Value *EndCompareGT = Builder.CreateICmp( + Signed ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT, Sub, StartValue); +diff --git a/test/Analysis/LoopAccessAnalysis/wrapping-pointer-ni.ll b/test/Analysis/LoopAccessAnalysis/wrapping-pointer-ni.ll +new file mode 100644 +index 00000000000..ddcf5e1a195 +--- /dev/null ++++ b/test/Analysis/LoopAccessAnalysis/wrapping-pointer-ni.ll +@@ -0,0 +1,73 @@ ++; RUN: opt -loop-versioning -S < %s | FileCheck %s -check-prefix=LV ++ ++; NB: addrspaces 10-13 are non-integral ++target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:10:11:12:13" ++ ++; This matches the test case from PR38290 ++; Check that we expand the SCEV predicate check using GEP, rather ++; than ptrtoint. ++ ++%jl_value_t = type opaque ++%jl_array_t = type { i8 addrspace(13)*, i64, i16, i16, i32 } ++ ++declare i64 @julia_steprange_last_4949() ++ ++define void @"japi1_align!_9477"(%jl_value_t addrspace(10)**) #0 { ++; LV-LAVEL: L26.lver.check ++; LV: [[OFMul:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[Step:%[^ ]*]]) ++; LV-NEXT: [[OFMulResult:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul]], 0 ++; LV-NEXT: [[OFMulOverflow:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul]], 1 ++; LV-NEXT: [[PosGEP:%[^ ]*]] = getelementptr i32, i32 addrspace(13)* [[Base:%[^ ]*]], i64 [[Step]] ++; LV-NEXT: [[NegGEP:%[^ ]*]] = getelementptr i32, i32 addrspace(13)* [[Base]], i64 [[NegStep:%[^ ]*]] ++; LV-NEXT: icmp ugt i32 addrspace(13)* [[NegGEP]], [[Base]] ++; LV-NEXT: icmp ult i32 addrspace(13)* [[PosGEP]], [[Base]] ++; LV-NOT: inttoptr ++; LV-NOT: ptrtoint ++top: ++ %1 = load %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)** %0, align 8, !nonnull !1, !dereferenceable !2, !align !3 ++ %2 = load i32, i32* inttoptr (i64 12 to i32*), align 4, !tbaa !4 ++ %3 = sub i32 0, %2 ++ %4 = call i64 @julia_steprange_last_4949() ++ %5 = addrspacecast %jl_value_t addrspace(10)* %1 to %jl_value_t addrspace(11)* ++ %6 = bitcast %jl_value_t addrspace(11)* %5 to %jl_value_t addrspace(10)* addrspace(11)* ++ %7 = load %jl_value_t addrspace(10)*, %jl_value_t addrspace(10)* addrspace(11)* %6, align 8, !tbaa !4, !nonnull !1, !dereferenceable !9, !align !2 ++ %8 = addrspacecast %jl_value_t addrspace(10)* %7 to %jl_value_t addrspace(11)* ++ %9 = bitcast %jl_value_t addrspace(11)* %8 to i32 addrspace(13)* addrspace(11)* ++ %10 = load i32 addrspace(13)*, i32 addrspace(13)* addrspace(11)* %9, align 8, !tbaa !10, !nonnull !1 ++ %11 = sext i32 %3 to i64 ++ br label %L26 ++ ++L26: ; preds = %L26, %top ++ %value_phi3 = phi i64 [ 0, %top ], [ %12, %L26 ] ++ %12 = add i64 %value_phi3, -1 ++ %13 = getelementptr inbounds i32, i32 addrspace(13)* %10, i64 %12 ++ %14 = load i32, i32 addrspace(13)* %13, align 4, !tbaa !13 ++ %15 = add i64 %12, %11 ++ %16 = getelementptr inbounds i32, i32 addrspace(13)* %10, i64 %15 ++ store i32 %14, i32 addrspace(13)* %16, align 4, !tbaa !13 ++ %17 = icmp eq i64 %value_phi3, %4 ++ br i1 %17, label %L45, label %L26 ++ ++L45: ; preds = %L26 ++ ret void ++} ++ ++attributes #0 = { "thunk" } ++ ++!llvm.module.flags = !{!0} ++ ++!0 = !{i32 1, !"Debug Info Version", i32 3} ++!1 = !{} ++!2 = !{i64 16} ++!3 = !{i64 8} ++!4 = !{!5, !5, i64 0} ++!5 = !{!"jtbaa_mutab", !6, i64 0} ++!6 = !{!"jtbaa_value", !7, i64 0} ++!7 = !{!"jtbaa_data", !8, i64 0} ++!8 = !{!"jtbaa"} ++!9 = !{i64 40} ++!10 = !{!11, !11, i64 0} ++!11 = !{!"jtbaa_arrayptr", !12, i64 0} ++!12 = !{!"jtbaa_array", !8, i64 0} ++!13 = !{!14, !14, i64 0} ++!14 = !{!"jtbaa_arraybuf", !7, i64 0} +diff --git a/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll b/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll +index a7e5bce7445..fa6fccecbf1 100644 +--- a/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll ++++ b/test/Analysis/LoopAccessAnalysis/wrapping-pointer-versioning.ll +@@ -58,10 +58,10 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" + ; LV-NEXT: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE]]) + ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0 + ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1 +-; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 %a2, [[OFMulResult1]] +-; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 %a2, [[OFMulResult1]] +-; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], %a2 +-; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], %a2 ++; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[A0:%[^ ]*]], [[OFMulResult1]] ++; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[A0]], [[OFMulResult1]] ++; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[A0]] ++; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[A0]] + ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]] + ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]] + +@@ -233,10 +233,10 @@ for.end: ; preds = %for.body + ; LV: [[OFMul1:%[^ ]*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 4, i64 [[BE:%[^ ]*]]) + ; LV-NEXT: [[OFMulResult1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 0 + ; LV-NEXT: [[OFMulOverflow1:%[^ ]*]] = extractvalue { i64, i1 } [[OFMul1]], 1 +-; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 %a2, [[OFMulResult1]] +-; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 %a2, [[OFMulResult1]] +-; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], %a2 +-; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], %a2 ++; LV-NEXT: [[AddEnd1:%[^ ]*]] = add i64 [[A0:%[^ ]*]], [[OFMulResult1]] ++; LV-NEXT: [[SubEnd1:%[^ ]*]] = sub i64 [[A0]], [[OFMulResult1]] ++; LV-NEXT: [[CmpNeg1:%[^ ]*]] = icmp ugt i64 [[SubEnd1]], [[A0]] ++; LV-NEXT: [[CmpPos1:%[^ ]*]] = icmp ult i64 [[AddEnd1]], [[A0]] + ; LV-NEXT: [[Cmp:%[^ ]*]] = select i1 false, i1 [[CmpNeg1]], i1 [[CmpPos1]] + ; LV-NEXT: [[PredCheck1:%[^ ]*]] = or i1 [[Cmp]], [[OFMulOverflow1]] + diff --git a/debian/patches/llvm-rL323946-LSRTy.patch b/debian/patches/llvm-rL323946-LSRTy.patch new file mode 100644 index 00000000..ae1a7ac5 --- /dev/null +++ b/debian/patches/llvm-rL323946-LSRTy.patch @@ -0,0 +1,45 @@ +commit ab60b05a472e8651cbe53c19513b7e62b9ff32df +Author: Mikael Holmen +Date: Thu Feb 1 06:38:34 2018 +0000 + + [LSR] Don't force bases of foldable formulae to the final type. + + Summary: + Before emitting code for scaled registers, we prevent + SCEVExpander from hoisting any scaled addressing mode + by emitting all the bases first. However, these bases + are being forced to the final type, resulting in some + odd code. + + For example, if the type of the base is an integer and + the final type is a pointer, we will emit an inttoptr + for the base, a ptrtoint for the scale, and then a + 'reverse' GEP where the GEP pointer is actually the base + integer and the index is the pointer. It's more intuitive + to use the pointer as a pointer and the integer as index. + + Patch by: Bevin Hansson + + Reviewers: atrick, qcolombet, sanjoy + + Reviewed By: qcolombet + + Subscribers: llvm-commits + + Differential Revision: https://reviews.llvm.org/D42103 + + git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323946 91177308-0d34-0410-b5e6-96231b3b80d8 + +diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp +index 332c074a1df..4b8e2286ed9 100644 +--- a/lib/Transforms/Scalar/LoopStrengthReduce.cpp ++++ b/lib/Transforms/Scalar/LoopStrengthReduce.cpp +@@ -4993,7 +4993,7 @@ Value *LSRInstance::Expand(const LSRUse &LU, const LSRFixup &LF, + // Unless the addressing mode will not be folded. + if (!Ops.empty() && LU.Kind == LSRUse::Address && + isAMCompletelyFolded(TTI, LU, F)) { +- Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), Ty); ++ Value *FullV = Rewriter.expandCodeFor(SE.getAddExpr(Ops), nullptr); + Ops.clear(); + Ops.push_back(SE.getUnknown(FullV)); + } diff --git a/debian/patches/series b/debian/patches/series index b4335941..b1d83219 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -12,7 +12,8 @@ silent-gold-test.diff atomic_library_1.diff python-clangpath.diff fix-clang-path-and-build.diff -force-gcc-header-obj.diff +# commented because of bug 903709 +#force-gcc-header-obj.diff do-not-fail-on-unexpected-pass.diff silent-more-tests.diff disable-display-PASS-UNSUPPORTED-XFAIL.diff diff --git a/debian/rules b/debian/rules index df430434..55e16272 100755 --- a/debian/rules +++ b/debian/rules @@ -338,7 +338,6 @@ LIBCXX_CMAKE_OPTIONS := \ -DCMAKE_C_COMPILER=$(CURDIR)/$(TARGET_BUILD)/bin/clang \ -DLLVM_EXTERNAL_LIT=$(BASE_PATH)/utils/lit/lit.py - override_dh_auto_build: $(PRE_PROCESS) $(MAKE) $(NJOBS) -C $(TARGET_BUILD) VERBOSE=1 CLANG_VENDOR=$(VENDOR) CXXFLAGS="$(CXXFLAGS_EXTRA)" LDFLAGS="$(LDFLAGS_EXTRA)" REQUIRES_RTTI=1 DEBUGMAKE=1 ifeq (${LIBFUZZER_ENABLE},yes) @@ -350,7 +349,7 @@ ifeq (${LIBFUZZER_ENABLE},yes) ar ruv libFuzzer.a Fuzzer*.o endif -# Builds libcxx and libcxxabi +# Builds libcxx and libcxxabi mkdir -p libcxxabi/build mkdir -p libcxx/build @@ -360,8 +359,10 @@ endif $(LIBCXX_CMAKE_OPTIONS) \ -DLIBCXXABI_LIBCXX_PATH=$(BASE_PATH)/libcxx \ -DLIBCXXABI_LIBCXX_LIBRARY_PATH=$(BASE_PATH)/libcxx/build/lib \ + -DLIBCXXABI_LIBCXX_INCLUDES=$(BASE_PATH)/libcxx/include \ -DLIBCXXABI_ENABLE_EXCEPTIONS=$(LIBCXX_EXCEPTIONS) \ - -DLLVM_ENABLE_RTTI=ON + -DLLVM_ENABLE_RTTI=ON && \ + $(MAKE) $(NJOBS) VERBOSE=1 cd libcxx/build && \ cmake ../ \ @@ -370,7 +371,8 @@ endif -DLIBCXX_CXX_ABI_INCLUDE_PATHS=$(BASE_PATH)/libcxxabi/include \ -DLIBCXX_CXX_ABI_LIBRARY_PATH=$(BASE_PATH)/libcxxabi/build/lib \ -DLIBCXX_ENABLE_EXCEPTIONS=$(LIBCXX_EXCEPTIONS) \ - -DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON + -DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON && \ + $(MAKE) $(NJOBS) VERBOSE=1 override_dh_prep: build_doc dh_prep @@ -430,6 +432,8 @@ override_dh_auto_install: # Only run on executable, not script chrpath -d `find $(DEB_INST)/usr/lib/llvm-$(LLVM_VERSION)/bin/ -type f -executable -exec file -i '{}' \; | grep 'x-executable; charset=binary'|cut -d: -f1` + chrpath -d libcxxabi/build/lib/libc++abi.so.1.0 + chrpath -d libcxx/build/lib/libc++.so.1.0 cd debian/tmp/usr/lib/llvm-$(LLVM_VERSION)/lib/ && rm -f libclang.so.$(SONAME_EXT) libclang-$(LLVM_VERSION).so; \ ln -s libclang-$(LLVM_VERSION).so.$(SONAME_EXT) libclang.so.$(SONAME_EXT) @@ -440,7 +444,7 @@ override_dh_auto_install: mkdir -p debian/tmp/usr/lib/llvm-$(LLVM_VERSION)/include/openmp cp openmp/runtime/exports/common.dia.50.ompt.optional/include/* debian/tmp/usr/lib/llvm-$(LLVM_VERSION)/include/openmp -# Remove artefact (where compiler-rt is built) +# Remove artifact (where compiler-rt is built) # if test -d $(TARGET_BUILD)/tools/clang/runtime/compiler-rt/clang_linux; then \ # cd $(TARGET_BUILD)/tools/clang/runtime/compiler-rt/clang_linux && rm -rf $$(find . -mindepth 2 -maxdepth 2 -type d) && rm -rf $$(find -empty) && rm -rf */.dir; \ # fi @@ -559,7 +563,7 @@ endif # Delete the target build directory to save some space on the build systems # All the files have been installed in $(CURDIR)/debian/tmp/ already -# rm -rf $(TARGET_BUILD) + rm -rf $(TARGET_BUILD) override_dh_makeshlibs: