[llvm-branch-commits] [clang] [flang] [libc] [llvm] [mlir] Users/tstellar/merge doxygen (PR #213838)

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Aug 3 22:10:21 PDT 2026


Valentin Clement =?utf-8?b?KOODkOODrOODsw=?=,Ayokunle Amodu
 <ayokunle321 at gmail.com>,Tom Stellard <tstellar at redhat.com>,Michael Jones
 <michaelrj at google.com>,Tom Stellard <tstellar at redhat.com>,Tom Stellard
 <tstellar at redhat.com>,Tom Stellard <tstellar at redhat.com>,Tom Stellard
 <tstellar at redhat.com>
Message-ID: <llvm.org/llvm/llvm-project/pull/213838 at github.com>
In-Reply-To:


https://github.com/tstellar created https://github.com/llvm/llvm-project/pull/213838

None

>From c3a73d8cfa2610da3d6f6379545f617f8970bd05 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Tue, 28 Jul 2026 22:48:55 -0700
Subject: [PATCH 01/43] workflows/release-documentation: Rework workflow to
 make it testable

Removed the environment declaration from the validation job and split
out the www-releases update into a separate job.  This makes it safe
and possible to add a pull_request trigger so we can at least test
building the documentation when someone submits a pull request.
---
 .github/workflows/release-documentation.yml | 48 +++++++++++++++------
 1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index d0b6a9994edb5..5347d4136bc26 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -38,6 +38,24 @@ on:
       LLVM_TOKEN_GENERATOR_PRIVATE_KEY:
         description: "Private key for our GitHub App we use for generating access tokens."
         required: true
+  # Run on pull_requests for testing purposes.
+  pull_request:
+    paths:
+      - '.github/workflows/release-documentation.yml'
+      - 'llvm/utils/release/build-docs.sh'
+    types:
+      - opened
+      - synchronize
+      - reopened
+      # When a PR is closed, we still start this workflow, but then skip
+      # all the jobs, which makes it effectively a no-op.  The reason to
+      # do this is that it allows us to take advantage of concurrency groups
+      # to cancel in progress CI jobs whenever the PR is closed.
+      - closed
+
+concurrency:
+  group: ${{ github.workflow }}-${{ inputs.release-version || github.event.pull_request.number }}
+  cancel-in-progress: True
 
 jobs:
   # This job checks permissions and validates inputs to prevent potential
@@ -47,9 +65,6 @@ jobs:
   release-man-pages-validate-input:
     name: Release Man Pages Validate Input
     runs-on: ubuntu-24.04
-    environment:
-      name: release
-      deployment: false
     permissions:
       contents: read
     steps:
@@ -59,13 +74,6 @@ jobs:
           sparse-checkout: |
             .github/workflows/
 
-      - name: Check Permissions
-        uses: ./.github/workflows/require-team-membership
-        with:
-          team-slug: llvm-release-managers
-          LLVM_TOKEN_GENERATOR_CLIENT_ID: ${{ secrets.LLVM_TOKEN_GENERATOR_CLIENT_ID }}
-          LLVM_TOKEN_GENERATOR_PRIVATE_KEY: ${{ secrets.LLVM_TOKEN_GENERATOR_PRIVATE_KEY }}
-
       - name: Validate Input
         uses: ./.github/workflows/validate-release-version
         with:
@@ -84,8 +92,6 @@ jobs:
       man-page-tarball-name: ${{ steps.vars.outputs.man-page-tarball-name }}
       man-page-upload: ${{ steps.vars.outputs.man-page-upload }}
       man-page-attestation-name: ${{ steps.vars.outputs.man-page-attestation-name }}
-    env:
-      upload: ${{ inputs.upload && !contains(inputs.release-version, 'rc') }}
     steps:
       - name: Collect Variables
         id: vars
@@ -155,8 +161,23 @@ jobs:
           name: release-notes
           path: docs-build/html-export/
 
+
+  upload-release-notes:
+    name: "Upload Release Notes"
+    runs-on: ubuntu-24.04
+    environment:
+      deployment: false
+      name: release
+    needs:
+      - release-documentation
+    if: >-
+      github.event_name != 'pull_request' &&
+      inputs.upload &&
+      !contains(inputs.release-version, 'rc')
+    permissions:
+      contents: read
+    steps:
       - name: Clone www-releases
-        if: env.upload
         uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
         with:
           repository: ${{ github.repository_owner }}/www-releases
@@ -166,7 +187,6 @@ jobs:
           persist-credentials: false
 
       - name: Upload Release Notes
-        if: env.upload
         env:
           PUSH_TOKEN: ${{ secrets.LLVMBOT_WWW_RELEASES_PUSH }}
           GH_TOKEN: ${{ secrets.WWW_RELEASES_TOKEN }}

>From 32f690d630f6d95fec6e60f49ee1e14ed66aa5f9 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 11:18:49 -0700
Subject: [PATCH 02/43] More fixes

---
 .github/workflows/release-documentation.yml | 48 +++++++--------------
 1 file changed, 15 insertions(+), 33 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 5347d4136bc26..3c080dce679c9 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -58,41 +58,25 @@ concurrency:
   cancel-in-progress: True
 
 jobs:
-  # This job checks permissions and validates inputs to prevent potential
-  # malicious actions.  Since the release-documentation job has contents: write
-  # permissions we need to be extra careful about who can run the job and what
-  # inputs can be provided.
-  release-man-pages-validate-input:
-    name: Release Man Pages Validate Input
-    runs-on: ubuntu-24.04
-    permissions:
-      contents: read
-    steps:
-      - uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
-        with:
-          persist-credentials: false
-          sparse-checkout: |
-            .github/workflows/
-
-      - name: Validate Input
-        uses: ./.github/workflows/validate-release-version
-        with:
-          release-version: ${{ inputs.release-version }}
-
   release-documentation:
     name: Build and Upload Release Documentation and Man Pages
     runs-on: ubuntu-24.04
-    needs:
-      - release-man-pages-validate-input
+    permissions:
+      contents: read
     outputs:
       man-page-digest: ${{ steps.man-page-digest.outputs.man-page-digest }}
       man-page-artifact-id: ${{ steps.man-page-artifact-upload.outputs.artifact-id }}
 
       man-page-release-version: ${{ steps.vars.outputs.man-page-release-version }}
-      man-page-tarball-name: ${{ steps.vars.outputs.man-page-tarball-name }}
       man-page-upload: ${{ steps.vars.outputs.man-page-upload }}
       man-page-attestation-name: ${{ steps.vars.outputs.man-page-attestation-name }}
     steps:
+      - name: Validate Input
+        if: inputs.release-version
+        uses: ./.github/workflows/validate-release-version
+        with:
+          release-version: ${{ inputs.release-version }}
+
       - name: Collect Variables
         id: vars
         env:
@@ -102,7 +86,6 @@ jobs:
         run: |
           {
             echo "man-page-release-version=$INPUTS_RELEASE_VERSION"
-            echo "man-page-tarball-name=llvm_man_pages-$INPUTS_RELEASE_VERSION.tar.xz"
             echo "man-page-ref=llvmorg-$INPUTS_RELEASE_VERSION"
             echo "man-page-upload=$UPLOAD_MAN_PAGES"
             echo "man-page-attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-man-page-attestation"
@@ -113,11 +96,6 @@ jobs:
         with:
           persist-credentials: false
 
-      - name: Validate Input
-        uses: ./.github/workflows/validate-release-version
-        with:
-          release-version: ${{ inputs.release-version }}
-
       - name: Setup Python env
         uses: actions/setup-python at ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
         with:
@@ -135,17 +113,21 @@ jobs:
           pip3 install --require-hashes --user -r ./llvm/docs/requirements.txt
 
       - name: Build Documentation
+        id: build
         env:
           GITHUB_TOKEN: ${{ github.token }}
           INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
         run: |
-          ./llvm/utils/release/build-docs.sh -release "$INPUTS_RELEASE_VERSION" -no-doxygen
+          ./llvm/utils/release/build-docs.sh \
+            $(test -n "$INPUTS_RELEASE_VERSION" && echo -release $INPUTS_RELEASE_VERSION || echo -srcdir llvm) -no-doxygen
+          echo "man-page-tarball-name=$(find . -iname 'llvm_man_pages-*')" >> "$GITHUB_OUTPUT"
+
 
       - name: Generate sha256 digest for man page tarball
         id: man-page-digest
         shell: bash
         env:
-          TARBALL_NAME: ${{ steps.vars.outputs.man-page-tarball-name }}
+          TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
         run: |
             echo "man-page-digest=$(cat "$TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
 
@@ -153,7 +135,7 @@ jobs:
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
         with:
           path: |
-            ${{ steps.vars.outputs.man-page-tarball-name }}
+            ${{ steps.build.outputs.man-page-tarball-name }}
 
       - name: Create Release Notes Artifact
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1

>From cb399024cbe90862b9184d0b05412185fcea0630 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 14:07:40 -0700
Subject: [PATCH 03/43] Cleanups

---
 .github/workflows/release-documentation.yml | 24 +++------------------
 1 file changed, 3 insertions(+), 21 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 3c080dce679c9..b1bc2f586f935 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -66,10 +66,6 @@ jobs:
     outputs:
       man-page-digest: ${{ steps.man-page-digest.outputs.man-page-digest }}
       man-page-artifact-id: ${{ steps.man-page-artifact-upload.outputs.artifact-id }}
-
-      man-page-release-version: ${{ steps.vars.outputs.man-page-release-version }}
-      man-page-upload: ${{ steps.vars.outputs.man-page-upload }}
-      man-page-attestation-name: ${{ steps.vars.outputs.man-page-attestation-name }}
     steps:
       - name: Validate Input
         if: inputs.release-version
@@ -77,20 +73,6 @@ jobs:
         with:
           release-version: ${{ inputs.release-version }}
 
-      - name: Collect Variables
-        id: vars
-        env:
-          INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
-          UPLOAD_MAN_PAGES: ${{ inputs.upload }}
-        shell: bash
-        run: |
-          {
-            echo "man-page-release-version=$INPUTS_RELEASE_VERSION"
-            echo "man-page-ref=llvmorg-$INPUTS_RELEASE_VERSION"
-            echo "man-page-upload=$UPLOAD_MAN_PAGES"
-            echo "man-page-attestation-name=$RUNNER_OS-$RUNNER_ARCH-release-man-page-attestation"
-          } >> "$GITHUB_OUTPUT"
-
       - name: Checkout LLVM
         uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
         with:
@@ -205,10 +187,10 @@ jobs:
        id: man-page-artifact-upload
        uses: $/.github/workflows/upload-release-artifact
        with:
-         release-version: ${{ needs.release-documentation.outputs.man-page-release-version }}
+         release-version: ${{ inputs.release-version }}
          artifact-id: ${{ needs.release-documentation.outputs.man-page-artifact-id }}
-         attestation-name: ${{ needs.release-documentation.outputs.man-page-attestation-name }}
+         attestation-name: ${{ runner.os }}-${{ runner.arch }}-release-man-page-attestation
          digest: ${{ needs.release-documentation.outputs.man-page-digest }}
-         upload: ${{ needs.release-documentation.outputs.man-page-upload }}
+         upload: ${{ inputs.upload }}
          LLVM_TOKEN_GENERATOR_CLIENT_ID: ${{ secrets.LLVM_TOKEN_GENERATOR_CLIENT_ID }}
          LLVM_TOKEN_GENERATOR_PRIVATE_KEY: ${{ secrets.LLVM_TOKEN_GENERATOR_PRIVATE_KEY }}

>From 3903d540a1f4c13cdf7b5efecda907624e02e983 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 14:20:58 -0700
Subject: [PATCH 04/43] Fix build of libcxx docs

---
 llvm/utils/release/build-docs.sh | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 648c829a62618..12f437e1d3ca7 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -149,22 +149,14 @@ export CXX=clang++
 
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
+               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \
                -DCMAKE_BUILD_TYPE=Release \
                -DLLVM_BUILD_DOCS=ON \
                $sphinx_flag \
                $doxygen_flag \
                $man_page_flag
 
-ninja -C $builddir $sphinx_targets $doxygen_targets $man_page_targets
-
-cmake -G Ninja $srcdir/../runtimes -B $builddir/runtimes-doc \
-               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \
-               -DLLVM_ENABLE_SPHINX=ON \
-               -DLLVM_BUILD_DOCS=ON \
-               -DSPHINX_WARNINGS_AS_ERRORS=OFF
-
-ninja -C $builddir/runtimes-doc \
-               docs-libcxx-html
+ninja -C $builddir $sphinx_targets $doxygen_targets $man_page_targets docs-libcxx-html
 
 if [ "${no_man_page}" != "yes" ]; then
   output="llvm_man_pages-${release}"
@@ -196,5 +188,5 @@ done
 # Keep the documentation for the runtimes under /projects/ to avoid breaking existing links.
 for d in libcxx/docs/; do
   mkdir -p $html_dir/projects/$d
-  mv $builddir/runtimes-doc/$d/html/* $html_dir/projects/$d/
+  mv $builddir/$d/html/* $html_dir/projects/$d/
 done

>From 0a2c1abbe06944d9910ea2f42be01defcfe6532d Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 14:27:50 -0700
Subject: [PATCH 05/43] Fix typo

---
 llvm/utils/release/build-docs.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 12f437e1d3ca7..04f17b629c669 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -128,7 +128,7 @@ if [ "${no_man_pages}" != "yes" ]; then
   install_prefix=${builddir}/install
   man_page_flag=" -DLLVM_ENABLE_SPHINX=ON -DSPHINX_WARNINGS_AS_ERRORS=OFF -DSPHINX_OUTPUT_MAN:BOOL=ON -DCMAKE_INSTALL_PREFIX=${install_prefix}"
   extra_man_page_projects=";lldb;mlir;bolt"
-  extra_man_page_runtimes=";compiler-rt;openmp;"
+  extra_man_page_runtimes=";compiler-rt;openmp"
 else
   echo "Man pages: disabled"
 fi

>From 75bfe65962f1ea843dd1fa08c12e6e053e755e02 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 14:38:23 -0700
Subject: [PATCH 06/43] XXX: Debug

---
 llvm/utils/release/build-docs.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 04f17b629c669..0f630b2e600d5 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -147,6 +147,7 @@ fi
 export CC=clang
 export CXX=clang++
 
+set -ex
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
                -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \

>From eb9667fa754e0b49d46d0ae5993968e20cb94d94 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 14:42:26 -0700
Subject: [PATCH 07/43] Fix typo

---
 llvm/utils/release/build-docs.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 0f630b2e600d5..c7f440c638d34 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -150,7 +150,7 @@ export CXX=clang++
 set -ex
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
-               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \
+               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind${extra_man_page_runtimes}" \
                -DCMAKE_BUILD_TYPE=Release \
                -DLLVM_BUILD_DOCS=ON \
                $sphinx_flag \

>From d207ede60437c8809a253ae3bed441527bacdd6b Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:00:55 -0700
Subject: [PATCH 08/43] Revert "Fix typo"

This reverts commit a5d98fb1210839d7b0fe58b0be77ed6d379226b4.
---
 llvm/utils/release/build-docs.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index c7f440c638d34..0f630b2e600d5 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -150,7 +150,7 @@ export CXX=clang++
 set -ex
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
-               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind${extra_man_page_runtimes}" \
+               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \
                -DCMAKE_BUILD_TYPE=Release \
                -DLLVM_BUILD_DOCS=ON \
                $sphinx_flag \

>From 552261e3848c3c5d726235a056cf675f82883f1d Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:00:58 -0700
Subject: [PATCH 09/43] Revert "XXX: Debug"

This reverts commit 028443c5e4e259ca9f4d38145350a7d3d6494a66.
---
 llvm/utils/release/build-docs.sh | 1 -
 1 file changed, 1 deletion(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 0f630b2e600d5..04f17b629c669 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -147,7 +147,6 @@ fi
 export CC=clang
 export CXX=clang++
 
-set -ex
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
                -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \

>From e896a5010132f0911a697682cd9d6701e2a42adb Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:01:00 -0700
Subject: [PATCH 10/43] Revert "Fix typo"

This reverts commit f90c6dd3e5c5855b327b059982eb94d0ab3a0f73.
---
 llvm/utils/release/build-docs.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 04f17b629c669..12f437e1d3ca7 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -128,7 +128,7 @@ if [ "${no_man_pages}" != "yes" ]; then
   install_prefix=${builddir}/install
   man_page_flag=" -DLLVM_ENABLE_SPHINX=ON -DSPHINX_WARNINGS_AS_ERRORS=OFF -DSPHINX_OUTPUT_MAN:BOOL=ON -DCMAKE_INSTALL_PREFIX=${install_prefix}"
   extra_man_page_projects=";lldb;mlir;bolt"
-  extra_man_page_runtimes=";compiler-rt;openmp"
+  extra_man_page_runtimes=";compiler-rt;openmp;"
 else
   echo "Man pages: disabled"
 fi

>From cf5a93a31a41fdbebc29da37926c95f7d8ed81d7 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:01:02 -0700
Subject: [PATCH 11/43] Revert "Fix build of libcxx docs"

This reverts commit 179432674685f1eb5a7546f1fa1434ab75fee36f.
---
 llvm/utils/release/build-docs.sh | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 12f437e1d3ca7..648c829a62618 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -149,14 +149,22 @@ export CXX=clang++
 
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
-               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \
                -DCMAKE_BUILD_TYPE=Release \
                -DLLVM_BUILD_DOCS=ON \
                $sphinx_flag \
                $doxygen_flag \
                $man_page_flag
 
-ninja -C $builddir $sphinx_targets $doxygen_targets $man_page_targets docs-libcxx-html
+ninja -C $builddir $sphinx_targets $doxygen_targets $man_page_targets
+
+cmake -G Ninja $srcdir/../runtimes -B $builddir/runtimes-doc \
+               -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind;${extra_man_page_runtimes}" \
+               -DLLVM_ENABLE_SPHINX=ON \
+               -DLLVM_BUILD_DOCS=ON \
+               -DSPHINX_WARNINGS_AS_ERRORS=OFF
+
+ninja -C $builddir/runtimes-doc \
+               docs-libcxx-html
 
 if [ "${no_man_page}" != "yes" ]; then
   output="llvm_man_pages-${release}"
@@ -188,5 +196,5 @@ done
 # Keep the documentation for the runtimes under /projects/ to avoid breaking existing links.
 for d in libcxx/docs/; do
   mkdir -p $html_dir/projects/$d
-  mv $builddir/$d/html/* $html_dir/projects/$d/
+  mv $builddir/runtimes-doc/$d/html/* $html_dir/projects/$d/
 done

>From f834d30965598fd138d333f47e2ff749fe874fc5 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:10:40 -0700
Subject: [PATCH 12/43] Fix

---
 llvm/utils/release/build-docs.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index 648c829a62618..e19d1a39aeabc 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -144,8 +144,8 @@ fi
 # This is just to ensure we're using the right compiler
 # When running this locally, the script otherwise might
 # prefer GCC.
-export CC=clang
-export CXX=clang++
+#export CC=clang
+#export CXX=clang++
 
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \

>From d315d49db09582c6bb17487fc85770fdde6bb6cd Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:25:07 -0700
Subject: [PATCH 13/43] debug

---
 llvm/utils/release/build-docs.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index e19d1a39aeabc..a2c6a3776d03c 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -20,7 +20,7 @@
 #   * pip install --user -r ./llvm/docs/requirements.txt
 #===------------------------------------------------------------------------===#
 
-set -e
+set -ex
 
 builddir=docs-build
 srcdir=$(readlink -f $(dirname "$(readlink -f "$0")")/../..)

>From 94ddb9013b63a1f69c69bdd3fb2ac0eb1a45ad5e Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:41:12 -0700
Subject: [PATCH 14/43] Fix

---
 .github/workflows/release-documentation.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index b1bc2f586f935..0efb9e5ff44c4 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -102,7 +102,7 @@ jobs:
         run: |
           ./llvm/utils/release/build-docs.sh \
             $(test -n "$INPUTS_RELEASE_VERSION" && echo -release $INPUTS_RELEASE_VERSION || echo -srcdir llvm) -no-doxygen
-          echo "man-page-tarball-name=$(find . -iname 'llvm_man_pages-*')" >> "$GITHUB_OUTPUT"
+          echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*'))" >> "$GITHUB_OUTPUT"
 
 
       - name: Generate sha256 digest for man page tarball

>From c5cafa6d6add19fcbf42e3e61f9864d008a3ad61 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 16:58:50 -0700
Subject: [PATCH 15/43] Add artifact name

---
 .github/workflows/release-documentation.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 0efb9e5ff44c4..bf9c400d3bfc2 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -116,6 +116,7 @@ jobs:
       - id: man-page-artifact-upload
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
         with:
+          name: man-pages
           path: |
             ${{ steps.build.outputs.man-page-tarball-name }}
 

>From 69f79bb0526e5a2914b1db7f3bdb3620bd72b8a8 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Wed, 29 Jul 2026 17:12:40 -0700
Subject: [PATCH 16/43] Fixes and cleanups

---
 .github/workflows/release-documentation.yml | 10 +++++-----
 llvm/utils/release/build-docs.sh            |  8 +-------
 2 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index bf9c400d3bfc2..03fa40edcc91b 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -67,17 +67,17 @@ jobs:
       man-page-digest: ${{ steps.man-page-digest.outputs.man-page-digest }}
       man-page-artifact-id: ${{ steps.man-page-artifact-upload.outputs.artifact-id }}
     steps:
+      - name: Checkout LLVM
+        uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+        with:
+          persist-credentials: false
+
       - name: Validate Input
         if: inputs.release-version
         uses: ./.github/workflows/validate-release-version
         with:
           release-version: ${{ inputs.release-version }}
 
-      - name: Checkout LLVM
-        uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
-        with:
-          persist-credentials: false
-
       - name: Setup Python env
         uses: actions/setup-python at ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
         with:
diff --git a/llvm/utils/release/build-docs.sh b/llvm/utils/release/build-docs.sh
index a2c6a3776d03c..3c80af1317d11 100755
--- a/llvm/utils/release/build-docs.sh
+++ b/llvm/utils/release/build-docs.sh
@@ -20,7 +20,7 @@
 #   * pip install --user -r ./llvm/docs/requirements.txt
 #===------------------------------------------------------------------------===#
 
-set -ex
+set -e
 
 builddir=docs-build
 srcdir=$(readlink -f $(dirname "$(readlink -f "$0")")/../..)
@@ -141,12 +141,6 @@ else
    echo "Doxygen: disabled"
 fi
 
-# This is just to ensure we're using the right compiler
-# When running this locally, the script otherwise might
-# prefer GCC.
-#export CC=clang
-#export CXX=clang++
-
 cmake -G Ninja $srcdir -B $builddir \
                -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra;lld;polly;flang${extra_man_page_projects}" \
                -DCMAKE_BUILD_TYPE=Release \

>From fdd1f1c979c72e48acbc9e405c29259a4f4a9e16 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 09:25:50 -0700
Subject: [PATCH 17/43] Fix

---
 .github/workflows/release-documentation.yml | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 03fa40edcc91b..7e6171f2ab1d0 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -102,7 +102,7 @@ jobs:
         run: |
           ./llvm/utils/release/build-docs.sh \
             $(test -n "$INPUTS_RELEASE_VERSION" && echo -release $INPUTS_RELEASE_VERSION || echo -srcdir llvm) -no-doxygen
-          echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*'))" >> "$GITHUB_OUTPUT"
+          echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*.tar.xz'))" >> "$GITHUB_OUTPUT"
 
 
       - name: Generate sha256 digest for man page tarball
@@ -151,15 +151,20 @@ jobs:
           path: www-releases
           persist-credentials: false
 
+      - name: Download Release Notes Artifact
+        uses: actions/download-artifact at 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
+        id: download-artifact
+        with:
+          name: ${{ github.workspace }}/www-releases/${{ inputs.release-version }}
+
       - name: Upload Release Notes
         env:
           PUSH_TOKEN: ${{ secrets.LLVMBOT_WWW_RELEASES_PUSH }}
           GH_TOKEN: ${{ secrets.WWW_RELEASES_TOKEN }}
           INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
         run: |
-          mkdir -p www-releases/$INPUTS_RELEASE_VERSION
-          mv ./docs-build/html-export/* www-releases/$INPUTS_RELEASE_VERSION
           cd www-releases
+          ls -ltr www-releases/$INPUT_RELEASE_VERSION/*
           git checkout -b $INPUTS_RELEASE_VERSION
           git add $INPUTS_RELEASE_VERSION
           git config user.email "llvmbot at llvm.org"

>From 1c65ba5f1d8c813e498edb0a77a827c7e5b9bc9e Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 09:27:46 -0700
Subject: [PATCH 18/43] XXX: Debug

---
 .github/workflows/release-documentation.yml | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 7e6171f2ab1d0..f5dd9b170c3e7 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -130,15 +130,8 @@ jobs:
   upload-release-notes:
     name: "Upload Release Notes"
     runs-on: ubuntu-24.04
-    environment:
-      deployment: false
-      name: release
     needs:
       - release-documentation
-    if: >-
-      github.event_name != 'pull_request' &&
-      inputs.upload &&
-      !contains(inputs.release-version, 'rc')
     permissions:
       contents: read
     steps:

>From b6a39d128577f7ee07ae9ab9109246bdb1ca1a24 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 09:45:58 -0700
Subject: [PATCH 19/43] Fix

---
 .github/workflows/release-documentation.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index f5dd9b170c3e7..c082c1245ed74 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -148,7 +148,8 @@ jobs:
         uses: actions/download-artifact at 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
         id: download-artifact
         with:
-          name: ${{ github.workspace }}/www-releases/${{ inputs.release-version }}
+          name: release-notes
+          path: ${{ github.workspace }}/www-releases/${{ inputs.release-version }}
 
       - name: Upload Release Notes
         env:

>From d3f3fb4c19e23a3d8f9f0a82b1b770c100840be4 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 10:00:32 -0700
Subject: [PATCH 20/43] Debug

---
 .github/workflows/release-documentation.yml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index c082c1245ed74..cf16df8fa6b78 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -158,7 +158,8 @@ jobs:
           INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
         run: |
           cd www-releases
-          ls -ltr www-releases/$INPUT_RELEASE_VERSION/*
+          ls -ltr *
+          ls -ltr $INPUT_RELEASE_VERSION/*
           git checkout -b $INPUTS_RELEASE_VERSION
           git add $INPUTS_RELEASE_VERSION
           git config user.email "llvmbot at llvm.org"

>From c110e71d569ea0f95e8226bb0c840961985c0948 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 10:25:49 -0700
Subject: [PATCH 21/43] Remove debug

---
 .github/workflows/release-documentation.yml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index cf16df8fa6b78..4ecd012d337d2 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -158,8 +158,6 @@ jobs:
           INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
         run: |
           cd www-releases
-          ls -ltr *
-          ls -ltr $INPUT_RELEASE_VERSION/*
           git checkout -b $INPUTS_RELEASE_VERSION
           git add $INPUTS_RELEASE_VERSION
           git config user.email "llvmbot at llvm.org"

>From 977d086160d917cd95cb0bc6176f24f05adc8d36 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 10:27:05 -0700
Subject: [PATCH 22/43] Revert "XXX: Debug"

This reverts commit ef443b1bebd360a4aad44d46b2a63621ccaba589.
---
 .github/workflows/release-documentation.yml | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 4ecd012d337d2..ccfc649ba151e 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -130,8 +130,15 @@ jobs:
   upload-release-notes:
     name: "Upload Release Notes"
     runs-on: ubuntu-24.04
+    environment:
+      deployment: false
+      name: release
     needs:
       - release-documentation
+    if: >-
+      github.event_name != 'pull_request' &&
+      inputs.upload &&
+      !contains(inputs.release-version, 'rc')
     permissions:
       contents: read
     steps:

>From d15670a49c5636f8fc78c8ef268391f09fd3a5e2 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Thu, 30 Jul 2026 16:56:28 -0700
Subject: [PATCH 23/43] Remove permissions

---
 .github/workflows/release-documentation.yml | 2 --
 1 file changed, 2 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index ccfc649ba151e..58229407b0f5b 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -61,8 +61,6 @@ jobs:
   release-documentation:
     name: Build and Upload Release Documentation and Man Pages
     runs-on: ubuntu-24.04
-    permissions:
-      contents: read
     outputs:
       man-page-digest: ${{ steps.man-page-digest.outputs.man-page-digest }}
       man-page-artifact-id: ${{ steps.man-page-artifact-upload.outputs.artifact-id }}

>From 07b6aef5b643f2e3c41f6be62398e9e988c513dd Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 05:11:43 -0700
Subject: [PATCH 24/43] Add missing if

---
 .github/workflows/release-documentation.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 58229407b0f5b..c0b188eac6d24 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -61,6 +61,9 @@ jobs:
   release-documentation:
     name: Build and Upload Release Documentation and Man Pages
     runs-on: ubuntu-24.04
+    if: >-
+      github.repository_owner == 'llvm' &&
+      github.event.action != 'closed'
     outputs:
       man-page-digest: ${{ steps.man-page-digest.outputs.man-page-digest }}
       man-page-artifact-id: ${{ steps.man-page-artifact-upload.outputs.artifact-id }}

>From 8f376b886e99d93f5ae78838244918abe2767211 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 08:53:29 -0700
Subject: [PATCH 25/43] Fixes

---
 .github/workflows/release-documentation.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index c0b188eac6d24..34e8e59f094d9 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -55,7 +55,7 @@ on:
 
 concurrency:
   group: ${{ github.workflow }}-${{ inputs.release-version || github.event.pull_request.number }}
-  cancel-in-progress: True
+  cancel-in-progress: true
 
 jobs:
   release-documentation:
@@ -102,7 +102,7 @@ jobs:
           INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
         run: |
           ./llvm/utils/release/build-docs.sh \
-            $(test -n "$INPUTS_RELEASE_VERSION" && echo -release $INPUTS_RELEASE_VERSION || echo -srcdir llvm) -no-doxygen
+            $(test -n "$INPUTS_RELEASE_VERSION" && echo -release "$INPUTS_RELEASE_VERSION" || echo -srcdir llvm) -no-doxygen
           echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*.tar.xz'))" >> "$GITHUB_OUTPUT"
 
 

>From 9b5c4a56d7dd6b8d45e07477f0c6cfefceacadad Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 11:37:13 -0700
Subject: [PATCH 26/43] Quote variable

---
 .github/workflows/release-documentation.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 34e8e59f094d9..82cbfd72416e0 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -112,7 +112,7 @@ jobs:
         env:
           TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
         run: |
-            echo "man-page-digest=$(cat "$TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> $GITHUB_OUTPUT
+            echo "man-page-digest=$(cat "$TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
 
       - id: man-page-artifact-upload
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1

>From b11533f1725d153727fb434ff23e164b60ea0ecb Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Sat, 1 Aug 2026 15:48:36 -0700
Subject: [PATCH 27/43] Fix concurrency

---
 .github/workflows/release-documentation.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 82cbfd72416e0..c19148017cfec 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -54,7 +54,7 @@ on:
       - closed
 
 concurrency:
-  group: ${{ github.workflow }}-${{ inputs.release-version || github.event.pull_request.number }}
+  group: release-documentation-${{ inputs.release-version || github.event.pull_request.number }}
   cancel-in-progress: true
 
 jobs:

>From 6145f43f50ebc69124f43de3dc38aa676e4df3a5 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 16:59:35 -0700
Subject: [PATCH 28/43] workflows: Merge release-doxygen into
 release-documenation

These two workflows use the same script and have the same structure,
so it's easier just to have one job that builds both.
---
 .github/workflows/release-documentation.yml | 45 ++++++++++++++++-----
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index c19148017cfec..b32de1d056492 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -67,6 +67,8 @@ jobs:
     outputs:
       man-page-digest: ${{ steps.man-page-digest.outputs.man-page-digest }}
       man-page-artifact-id: ${{ steps.man-page-artifact-upload.outputs.artifact-id }}
+      doxygen-digest: ${{ steps.man-page-digest.outputs.doxygen-digest }}
+      doxygen-artifact-id: ${{ steps.doxygen-artifact-upload.outputs.artifact-id }}
     steps:
       - name: Checkout LLVM
         uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
@@ -95,6 +97,12 @@ jobs:
               texlive-font-utils
           pip3 install --require-hashes --user -r ./llvm/docs/requirements.txt
 
+          # Install Doxygen
+          curl -L https://github.com/doxygen/doxygen/releases/download/Release_1_17_0/doxygen-1.17.0.linux.bin.tar.gz -o doxygen.tar.gz
+          echo "75419ef4f446fc1c24ef12514b574e66e898ee6f527c6ae2ad84f91a905823c2  doxygen.tar.gz" | shasum --check -
+          tar -xf doxygen.tar.gz
+          sudo install -m 755 doxygen-1.17.0/bin/doxygen /usr/local/bin/doxygen
+
       - name: Build Documentation
         id: build
         env:
@@ -102,17 +110,20 @@ jobs:
           INPUTS_RELEASE_VERSION: ${{ inputs.release-version }}
         run: |
           ./llvm/utils/release/build-docs.sh \
-            $(test -n "$INPUTS_RELEASE_VERSION" && echo -release "$INPUTS_RELEASE_VERSION" || echo -srcdir llvm) -no-doxygen
+            $(test -n "$INPUTS_RELEASE_VERSION" && echo -release "$INPUTS_RELEASE_VERSION" || echo -srcdir llvm)
           echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*.tar.xz'))" >> "$GITHUB_OUTPUT"
+          echo "doxygen-tarball-name=$(baename $(find . -iname '*doxygen*.tar.xz')) >> "$GITHUB_OUTPUT"
 
 
-      - name: Generate sha256 digest for man page tarball
+      - name: Generate sha256 digest for tarballs
         id: man-page-digest
         shell: bash
         env:
-          TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
+          MAN_PAGE_TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
+          DOXYGEN_TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
         run: |
-            echo "man-page-digest=$(cat "$TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
+            echo "man-page-digest=$(cat "$MAN_PAGE_TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
+            echo "doxygen-digest=$(cat "$DOXYGEN_TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
 
       - id: man-page-artifact-upload
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -121,6 +132,13 @@ jobs:
           path: |
             ${{ steps.build.outputs.man-page-tarball-name }}
 
+      - id: doxygen-artifact-upload
+        uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+        with:
+          name: doxygen
+          path: |
+            ${{ steps.build.outputs.doxygen-tarball-name }}
+
       - name: Create Release Notes Artifact
         uses: actions/upload-artifact at 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
         with:
@@ -174,8 +192,8 @@ jobs:
           git push --force  "https://$PUSH_TOKEN@github.com/llvmbot/www-releases.git" HEAD:refs/heads/$INPUTS_RELEASE_VERSION
           gh pr create -f -B main -H llvmbot:$INPUTS_RELEASE_VERSION
 
-  upload-man-pages:
-    name: "Upload Man Pages"
+  upload-documentation:
+    name: "Upload Documentation"
     runs-on: ubuntu-24.04
     environment:
       deployment: false
@@ -188,16 +206,23 @@ jobs:
       contents: write     # For man page uploads
       id-token: write     # For artifact attestations
       attestations: write # For artifact attestations
-
+    matrix:
+      include:
+        - artifact-id: ${{ needs.release-documentation.outputs.man-page-artifact-id }}
+          attestation-name: release-man-page-attestation
+          digest: ${{ needs.release-documentation.outputs.man-page-digest }}
+        - artifact-id: ${{ needs.release-documentation.outputs.doxygen-artifact-id }}
+          attestation-name: release-doxygen-attestation
+          digest: ${{ needs.release-documentation.outputs.doxygen-digest }}
     steps:
      - name: Upload Man Page Artifacts
        id: man-page-artifact-upload
        uses: $/.github/workflows/upload-release-artifact
        with:
          release-version: ${{ inputs.release-version }}
-         artifact-id: ${{ needs.release-documentation.outputs.man-page-artifact-id }}
-         attestation-name: ${{ runner.os }}-${{ runner.arch }}-release-man-page-attestation
-         digest: ${{ needs.release-documentation.outputs.man-page-digest }}
+         artifact-id: ${{ matrix.artifact-id }}
+         attestation-name: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.attestation_name }}
+         digest: ${{ matrix.digest }}
          upload: ${{ inputs.upload }}
          LLVM_TOKEN_GENERATOR_CLIENT_ID: ${{ secrets.LLVM_TOKEN_GENERATOR_CLIENT_ID }}
          LLVM_TOKEN_GENERATOR_PRIVATE_KEY: ${{ secrets.LLVM_TOKEN_GENERATOR_PRIVATE_KEY }}

>From 51b938c32b9338b9babf78eba48e45d7fe42f05f Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 17:00:41 -0700
Subject: [PATCH 29/43] ebug

---
 .github/workflows/release-documentation.yml | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index b32de1d056492..ca4c7ab6312aa 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -195,13 +195,8 @@ jobs:
   upload-documentation:
     name: "Upload Documentation"
     runs-on: ubuntu-24.04
-    environment:
-      deployment: false
-      name: release
     needs:
       - release-documentation
-    if: >-
-      github.event_name != 'pull_request'
     permissions:
       contents: write     # For man page uploads
       id-token: write     # For artifact attestations

>From 37ddf1de0f01dd88479b8cf6faec1fe690edf5ff Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Fri, 31 Jul 2026 17:38:16 -0400
Subject: [PATCH 30/43] [SLP][NFC]Add an extra check for fmul to fmuladd
 promotion, NFC

Reviewers:

Pull Request: https://github.com/llvm/llvm-project/pull/213361
---
 .../X86/fmuladd-copyable-fmul.ll              | 138 ++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-fmul.ll b/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-fmul.ll
index 3614f8b1f1a91..28ca0b93a06f7 100644
--- a/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-fmul.ll
+++ b/llvm/test/Transforms/SLPVectorizer/X86/fmuladd-copyable-fmul.ll
@@ -1,6 +1,7 @@
 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
 ; RUN: opt -passes=slp-vectorizer -slp-threshold=-99999 -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=ENABLED
 ; RUN: opt -passes=slp-vectorizer -slp-threshold=-99999 -slp-copyable-elements=false -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=DISABLED
+; RUN: opt -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=COST
 
 declare float @llvm.fmuladd.f32(float, float, float)
 
@@ -59,6 +60,27 @@ define <4 x float> @buildvec_fmul_absorb(float %p, float %q, float %r, float %s,
 ; DISABLED-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[TMP19]], <4 x float> [[TMP20]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
 ; DISABLED-NEXT:    ret <4 x float> [[V31]]
 ;
+; COST-LABEL: define <4 x float> @buildvec_fmul_absorb(
+; COST-SAME: float [[P:%.*]], float [[Q:%.*]], float [[R:%.*]], float [[S:%.*]], float [[T:%.*]], float [[U:%.*]], float [[N:%.*]], float [[M:%.*]], float [[E:%.*]], float [[F:%.*]], float [[G:%.*]], float [[H:%.*]], ptr [[SRCB:%.*]]) {
+; COST-NEXT:  [[ENTRY:.*:]]
+; COST-NEXT:    [[TMP0:%.*]] = insertelement <2 x float> poison, float [[P]], i64 0
+; COST-NEXT:    [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[R]], i64 1
+; COST-NEXT:    [[TMP2:%.*]] = insertelement <2 x float> poison, float [[Q]], i64 0
+; COST-NEXT:    [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[S]], i64 1
+; COST-NEXT:    [[TMP4:%.*]] = fmul <2 x float> [[TMP1]], [[TMP3]]
+; COST-NEXT:    [[X:%.*]] = fmul float [[T]], [[U]]
+; COST-NEXT:    [[Z:%.*]] = fmul float [[N]], [[M]]
+; COST-NEXT:    [[C0:%.*]] = fadd float [[E]], [[F]]
+; COST-NEXT:    [[C1:%.*]] = fsub float [[G]], [[H]]
+; COST-NEXT:    [[TMP5:%.*]] = load <2 x float>, ptr [[SRCB]], align 4
+; COST-NEXT:    [[TMP6:%.*]] = insertelement <2 x float> poison, float [[C0]], i64 0
+; COST-NEXT:    [[TMP7:%.*]] = insertelement <2 x float> [[TMP6]], float [[C1]], i64 1
+; COST-NEXT:    [[TMP8:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> [[TMP4]], <2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; COST-NEXT:    [[TMP9:%.*]] = shufflevector <2 x float> [[TMP8]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; COST-NEXT:    [[V2:%.*]] = insertelement <4 x float> [[TMP9]], float [[X]], i32 2
+; COST-NEXT:    [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[Z]], i32 3
+; COST-NEXT:    ret <4 x float> [[V3]]
+;
 entry:
   %a0 = fmul float %p, %q
   %a1 = fmul float %r, %s
@@ -146,6 +168,33 @@ define void @storechain_1fmul(ptr %dst, ptr %srcB, float %p, float %q, float %r,
 ; DISABLED-NEXT:    store float [[FMA2]], ptr [[D3]], align 4
 ; DISABLED-NEXT:    ret void
 ;
+; COST-LABEL: define void @storechain_1fmul(
+; COST-SAME: ptr [[DST:%.*]], ptr [[SRCB:%.*]], float [[P:%.*]], float [[Q:%.*]], float [[R:%.*]], float [[S:%.*]], float [[T:%.*]], float [[U:%.*]], float [[N:%.*]], float [[M:%.*]], float [[E:%.*]], float [[F:%.*]], float [[G:%.*]], float [[H:%.*]], float [[I:%.*]], float [[J:%.*]], float [[K:%.*]], float [[L:%.*]]) {
+; COST-NEXT:  [[ENTRY:.*:]]
+; COST-NEXT:    [[TMP0:%.*]] = insertelement <2 x float> poison, float [[P]], i64 0
+; COST-NEXT:    [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[R]], i64 1
+; COST-NEXT:    [[TMP2:%.*]] = insertelement <2 x float> poison, float [[Q]], i64 0
+; COST-NEXT:    [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[S]], i64 1
+; COST-NEXT:    [[TMP4:%.*]] = fmul <2 x float> [[TMP1]], [[TMP3]]
+; COST-NEXT:    [[A2:%.*]] = fmul float [[I]], [[J]]
+; COST-NEXT:    [[X:%.*]] = fmul float [[T]], [[U]]
+; COST-NEXT:    [[C0:%.*]] = fadd float [[E]], [[F]]
+; COST-NEXT:    [[C1:%.*]] = fsub float [[G]], [[H]]
+; COST-NEXT:    [[C2:%.*]] = fadd float [[K]], [[L]]
+; COST-NEXT:    [[GEPB2:%.*]] = getelementptr float, ptr [[SRCB]], i32 2
+; COST-NEXT:    [[B2:%.*]] = load float, ptr [[GEPB2]], align 4
+; COST-NEXT:    [[FMA2:%.*]] = call float @llvm.fmuladd.f32(float [[A2]], float [[B2]], float [[C2]])
+; COST-NEXT:    [[D1:%.*]] = getelementptr float, ptr [[DST]], i32 1
+; COST-NEXT:    [[TMP5:%.*]] = load <2 x float>, ptr [[SRCB]], align 4
+; COST-NEXT:    [[TMP6:%.*]] = insertelement <2 x float> poison, float [[C0]], i64 0
+; COST-NEXT:    [[TMP7:%.*]] = insertelement <2 x float> [[TMP6]], float [[C1]], i64 1
+; COST-NEXT:    [[TMP8:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> [[TMP4]], <2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; COST-NEXT:    store float [[X]], ptr [[DST]], align 4
+; COST-NEXT:    store <2 x float> [[TMP8]], ptr [[D1]], align 4
+; COST-NEXT:    [[D3:%.*]] = getelementptr float, ptr [[DST]], i32 3
+; COST-NEXT:    store float [[FMA2]], ptr [[D3]], align 4
+; COST-NEXT:    ret void
+;
 entry:
   %a0 = fmul float %p, %q
   %a1 = fmul float %r, %s
@@ -231,6 +280,28 @@ define <4 x float> @buildvec_fmul_absorb_rev(float %p, float %q, float %r, float
 ; DISABLED-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[TMP19]], <4 x float> [[TMP20]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
 ; DISABLED-NEXT:    ret <4 x float> [[V31]]
 ;
+; COST-LABEL: define <4 x float> @buildvec_fmul_absorb_rev(
+; COST-SAME: float [[P:%.*]], float [[Q:%.*]], float [[R:%.*]], float [[S:%.*]], float [[T:%.*]], float [[U:%.*]], float [[N:%.*]], float [[M:%.*]], float [[E:%.*]], float [[F:%.*]], float [[G:%.*]], float [[H:%.*]], ptr [[SRCB:%.*]]) {
+; COST-NEXT:  [[ENTRY:.*:]]
+; COST-NEXT:    [[TMP0:%.*]] = insertelement <2 x float> poison, float [[P]], i64 0
+; COST-NEXT:    [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[R]], i64 1
+; COST-NEXT:    [[TMP2:%.*]] = insertelement <2 x float> poison, float [[Q]], i64 0
+; COST-NEXT:    [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[S]], i64 1
+; COST-NEXT:    [[TMP4:%.*]] = fmul <2 x float> [[TMP1]], [[TMP3]]
+; COST-NEXT:    [[X:%.*]] = fmul float [[T]], [[U]]
+; COST-NEXT:    [[Z:%.*]] = fmul float [[N]], [[M]]
+; COST-NEXT:    [[C0:%.*]] = fadd float [[E]], [[F]]
+; COST-NEXT:    [[C1:%.*]] = fsub float [[G]], [[H]]
+; COST-NEXT:    [[TMP5:%.*]] = load <2 x float>, ptr [[SRCB]], align 4
+; COST-NEXT:    [[TMP6:%.*]] = insertelement <2 x float> poison, float [[C0]], i64 0
+; COST-NEXT:    [[TMP7:%.*]] = insertelement <2 x float> [[TMP6]], float [[C1]], i64 1
+; COST-NEXT:    [[TMP8:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> [[TMP4]], <2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; COST-NEXT:    [[V0:%.*]] = insertelement <4 x float> poison, float [[X]], i32 0
+; COST-NEXT:    [[V1:%.*]] = insertelement <4 x float> [[V0]], float [[Z]], i32 1
+; COST-NEXT:    [[TMP9:%.*]] = shufflevector <2 x float> [[TMP8]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; COST-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[V1]], <4 x float> [[TMP9]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; COST-NEXT:    ret <4 x float> [[V31]]
+;
 entry:
   %a0 = fmul float %p, %q
   %a1 = fmul float %r, %s
@@ -317,6 +388,30 @@ define <4 x float> @buildvec_fmul_no_absorb_multiuse_rev(float %p, float %q, flo
 ; DISABLED-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[TMP21]], <4 x float> [[TMP22]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
 ; DISABLED-NEXT:    ret <4 x float> [[V31]]
 ;
+; COST-LABEL: define <4 x float> @buildvec_fmul_no_absorb_multiuse_rev(
+; COST-SAME: float [[P:%.*]], float [[Q:%.*]], float [[R:%.*]], float [[S:%.*]], float [[T:%.*]], float [[U:%.*]], float [[N:%.*]], float [[M:%.*]], float [[E:%.*]], float [[F:%.*]], float [[G:%.*]], float [[H:%.*]], ptr [[SRCB:%.*]], ptr [[DST2:%.*]]) {
+; COST-NEXT:  [[ENTRY:.*:]]
+; COST-NEXT:    [[TMP0:%.*]] = insertelement <2 x float> poison, float [[P]], i64 0
+; COST-NEXT:    [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[R]], i64 1
+; COST-NEXT:    [[TMP2:%.*]] = insertelement <2 x float> poison, float [[Q]], i64 0
+; COST-NEXT:    [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[S]], i64 1
+; COST-NEXT:    [[TMP4:%.*]] = fmul <2 x float> [[TMP1]], [[TMP3]]
+; COST-NEXT:    [[X:%.*]] = fmul float [[T]], [[U]]
+; COST-NEXT:    [[Z:%.*]] = fmul float [[N]], [[M]]
+; COST-NEXT:    [[C0:%.*]] = fadd float [[E]], [[F]]
+; COST-NEXT:    [[C1:%.*]] = fsub float [[G]], [[H]]
+; COST-NEXT:    [[TMP5:%.*]] = load <2 x float>, ptr [[SRCB]], align 4
+; COST-NEXT:    [[TMP6:%.*]] = insertelement <2 x float> poison, float [[C0]], i64 0
+; COST-NEXT:    [[TMP7:%.*]] = insertelement <2 x float> [[TMP6]], float [[C1]], i64 1
+; COST-NEXT:    [[TMP8:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> [[TMP4]], <2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; COST-NEXT:    store float [[X]], ptr [[DST2]], align 4
+; COST-NEXT:    store float [[Z]], ptr [[DST2]], align 4
+; COST-NEXT:    [[V0:%.*]] = insertelement <4 x float> poison, float [[X]], i32 0
+; COST-NEXT:    [[V1:%.*]] = insertelement <4 x float> [[V0]], float [[Z]], i32 1
+; COST-NEXT:    [[TMP9:%.*]] = shufflevector <2 x float> [[TMP8]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; COST-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[V1]], <4 x float> [[TMP9]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
+; COST-NEXT:    ret <4 x float> [[V31]]
+;
 entry:
   %a0 = fmul float %p, %q
   %a1 = fmul float %r, %s
@@ -391,6 +486,26 @@ define <4 x float> @buildvec_fmul_absorb_const(float %p, float %q, float %r, flo
 ; DISABLED-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[TMP17]], <4 x float> [[TMP18]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
 ; DISABLED-NEXT:    ret <4 x float> [[V31]]
 ;
+; COST-LABEL: define <4 x float> @buildvec_fmul_absorb_const(
+; COST-SAME: float [[P:%.*]], float [[Q:%.*]], float [[R:%.*]], float [[S:%.*]], float [[T:%.*]], float [[U:%.*]], float [[E:%.*]], float [[F:%.*]], float [[G:%.*]], float [[H:%.*]], ptr [[SRCB:%.*]]) {
+; COST-NEXT:  [[ENTRY:.*:]]
+; COST-NEXT:    [[A0:%.*]] = fmul float [[P]], [[Q]]
+; COST-NEXT:    [[A1:%.*]] = fmul float [[R]], [[S]]
+; COST-NEXT:    [[C0:%.*]] = fadd float [[E]], [[F]]
+; COST-NEXT:    [[C1:%.*]] = fsub float [[G]], [[H]]
+; COST-NEXT:    [[TMP0:%.*]] = load <2 x float>, ptr [[SRCB]], align 4
+; COST-NEXT:    [[TMP1:%.*]] = insertelement <4 x float> poison, float [[U]], i64 2
+; COST-NEXT:    [[TMP2:%.*]] = insertelement <4 x float> [[TMP1]], float [[A0]], i64 0
+; COST-NEXT:    [[TMP3:%.*]] = insertelement <4 x float> [[TMP2]], float [[A1]], i64 1
+; COST-NEXT:    [[TMP4:%.*]] = shufflevector <4 x float> [[TMP3]], <4 x float> poison, <4 x i32> <i32 0, i32 1, i32 2, i32 2>
+; COST-NEXT:    [[TMP5:%.*]] = shufflevector <2 x float> [[TMP0]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; COST-NEXT:    [[TMP6:%.*]] = shufflevector <4 x float> <float poison, float poison, float 1.000000e+00, float 1.000000e+00>, <4 x float> [[TMP5]], <4 x i32> <i32 4, i32 5, i32 2, i32 3>
+; COST-NEXT:    [[TMP7:%.*]] = insertelement <4 x float> <float poison, float poison, float -0.000000e+00, float -0.000000e+00>, float [[C0]], i64 0
+; COST-NEXT:    [[TMP8:%.*]] = insertelement <4 x float> [[TMP7]], float [[C1]], i64 1
+; COST-NEXT:    [[TMP9:%.*]] = call <4 x float> @llvm.fmuladd.v4f32(<4 x float> [[TMP4]], <4 x float> [[TMP6]], <4 x float> [[TMP8]])
+; COST-NEXT:    [[TMP10:%.*]] = fmul <4 x float> [[TMP9]], <float 1.000000e+00, float 1.000000e+00, float 2.000000e+00, float 4.000000e+00>
+; COST-NEXT:    ret <4 x float> [[TMP10]]
+;
 entry:
   %a0 = fmul float %p, %q
   %a1 = fmul float %r, %s
@@ -473,6 +588,29 @@ define <4 x float> @buildvec_fmul_no_absorb_multiuse(float %p, float %q, float %
 ; DISABLED-NEXT:    [[V31:%.*]] = shufflevector <4 x float> [[TMP21]], <4 x float> [[TMP22]], <4 x i32> <i32 0, i32 1, i32 4, i32 5>
 ; DISABLED-NEXT:    ret <4 x float> [[V31]]
 ;
+; COST-LABEL: define <4 x float> @buildvec_fmul_no_absorb_multiuse(
+; COST-SAME: float [[P:%.*]], float [[Q:%.*]], float [[R:%.*]], float [[S:%.*]], float [[T:%.*]], float [[U:%.*]], float [[N:%.*]], float [[M:%.*]], float [[E:%.*]], float [[F:%.*]], float [[G:%.*]], float [[H:%.*]], ptr [[SRCB:%.*]], ptr [[DST2:%.*]]) {
+; COST-NEXT:  [[ENTRY:.*:]]
+; COST-NEXT:    [[TMP0:%.*]] = insertelement <2 x float> poison, float [[P]], i64 0
+; COST-NEXT:    [[TMP1:%.*]] = insertelement <2 x float> [[TMP0]], float [[R]], i64 1
+; COST-NEXT:    [[TMP2:%.*]] = insertelement <2 x float> poison, float [[Q]], i64 0
+; COST-NEXT:    [[TMP3:%.*]] = insertelement <2 x float> [[TMP2]], float [[S]], i64 1
+; COST-NEXT:    [[TMP4:%.*]] = fmul <2 x float> [[TMP1]], [[TMP3]]
+; COST-NEXT:    [[X:%.*]] = fmul float [[T]], [[U]]
+; COST-NEXT:    [[Z:%.*]] = fmul float [[N]], [[M]]
+; COST-NEXT:    [[C0:%.*]] = fadd float [[E]], [[F]]
+; COST-NEXT:    [[C1:%.*]] = fsub float [[G]], [[H]]
+; COST-NEXT:    [[TMP5:%.*]] = load <2 x float>, ptr [[SRCB]], align 4
+; COST-NEXT:    [[TMP6:%.*]] = insertelement <2 x float> poison, float [[C0]], i64 0
+; COST-NEXT:    [[TMP7:%.*]] = insertelement <2 x float> [[TMP6]], float [[C1]], i64 1
+; COST-NEXT:    [[TMP8:%.*]] = call <2 x float> @llvm.fmuladd.v2f32(<2 x float> [[TMP4]], <2 x float> [[TMP5]], <2 x float> [[TMP7]])
+; COST-NEXT:    store float [[X]], ptr [[DST2]], align 4
+; COST-NEXT:    store float [[Z]], ptr [[DST2]], align 4
+; COST-NEXT:    [[TMP9:%.*]] = shufflevector <2 x float> [[TMP8]], <2 x float> poison, <4 x i32> <i32 0, i32 1, i32 poison, i32 poison>
+; COST-NEXT:    [[V2:%.*]] = insertelement <4 x float> [[TMP9]], float [[X]], i32 2
+; COST-NEXT:    [[V3:%.*]] = insertelement <4 x float> [[V2]], float [[Z]], i32 3
+; COST-NEXT:    ret <4 x float> [[V3]]
+;
 entry:
   %a0 = fmul float %p, %q
   %a1 = fmul float %r, %s

>From a53548854785e06e291e5517d0a72212f58a721d Mon Sep 17 00:00:00 2001
From: Zhen Wang <zhenw at nvidia.com>
Date: Fri, 31 Jul 2026 14:38:24 -0700
Subject: [PATCH 31/43] [flang-rt][cuda] Skip scope-exit cleanup when the
 context has a sticky error (#213184)

A sticky CUDA error (e.g. an illegal memory access in a kernel) leaves
the primary context active but unusable, so CUFDeviceIsActive() reports
it as fine and the compiler-generated scope-exit frees abort a program
that ran to completion: 'cudaFree(p)' failed with
'cudaErrorIllegalAddress'.

Detect this by freeing a null pointer, a no-op that still reports the
sticky error. It runs only once the primary context is known active, so
it cannot lazily create one.
---
 flang-rt/lib/cuda/allocator.cpp         | 7 +++++++
 flang/test/Lower/CUDA/cuda-return01.cuf | 6 ++++++
 2 files changed, 13 insertions(+)

diff --git a/flang-rt/lib/cuda/allocator.cpp b/flang-rt/lib/cuda/allocator.cpp
index 4161caa7cb022..d8287d6f696e3 100644
--- a/flang-rt/lib/cuda/allocator.cpp
+++ b/flang-rt/lib/cuda/allocator.cpp
@@ -59,6 +59,13 @@ static bool deviceContextTornDown() {
       int active{0};
       if (getState(device, &flags, &active) == CUDA_SUCCESS) {
         tornDown = active == 0;
+        // A sticky error (e.g. an illegal kernel memory access) leaves the
+        // primary context active but unusable: later calls all fail, so
+        // scope-exit frees would abort an otherwise successful program. A
+        // null free is a no-op that surfaces this without creating a context.
+        if (!tornDown && cudaFree(nullptr) != cudaSuccess) {
+          tornDown = true;
+        }
       }
     }
   } else {
diff --git a/flang/test/Lower/CUDA/cuda-return01.cuf b/flang/test/Lower/CUDA/cuda-return01.cuf
index 6e5d02c3b3962..9ea5ce1538081 100644
--- a/flang/test/Lower/CUDA/cuda-return01.cuf
+++ b/flang/test/Lower/CUDA/cuda-return01.cuf
@@ -31,13 +31,19 @@ end
 
 program main
   integer, allocatable, device :: a(:)
+  integer, device, pointer :: p(:)
   return
 end
 
+! The descriptor of a device pointer lives in managed memory and is freed at
+! scope exit, under the same device-active guard as the other cleanup.
+
 ! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "MAIN"}
 ! CHECK: cuf.alloc !fir.box<!fir.heap<!fir.array<?xi32>>> {bindc_name = "a", data_attr = #cuf.cuda<device>, uniq_name = "_QFEa"} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
+! CHECK: %[[PTR:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<pointer>, uniq_name = "_QFEp"}
 ! CHECK: %[[ACTIVE:.*]] = fir.call @_FortranACUFDeviceIsActive() {{.*}} : () -> i1
 ! CHECK-NEXT: fir.if %[[ACTIVE]] {
+! CHECK-NEXT: cuf.free %[[PTR]]#0 : !fir.ref<!fir.box<!fir.ptr<!fir.array<?xi32>>>>{{.*}}
 ! CHECK: cuf.deallocate
 ! CHECK: cuf.free{{.*}}
 ! CHECK-NEXT: }

>From 21ca681775641d012ddad0d7359a3393afc24866 Mon Sep 17 00:00:00 2001
From: Sam Elliott <aelliott at qti.qualcomm.com>
Date: Fri, 31 Jul 2026 15:03:31 -0700
Subject: [PATCH 32/43] [IPO] Remove IR Outliner (#211971)

The IR Outliner has major bugs and no active maintainer, and is disabled
by default. The new LLVM Policy states the pass should be removed.

This commit removes:
- The IROutliner pass
- The IRSimilarity analysis
- The `llvm-sim` executable, used for understanding the latter
- All tests of the above

Related discussion:
https://discourse.llvm.org/t/ir-outliner-status-interest/89672
---
 llvm/docs/ReleaseNotes.md                     |    3 +
 .../llvm/Analysis/IRSimilarityIdentifier.h    | 1192 -------
 llvm/include/llvm/InitializePasses.h          |    1 -
 llvm/include/llvm/Transforms/IPO/IROutliner.h |  469 ---
 llvm/lib/Analysis/Analysis.cpp                |    1 -
 llvm/lib/Analysis/CMakeLists.txt              |    1 -
 llvm/lib/Analysis/IRSimilarityIdentifier.cpp  | 1519 ---------
 llvm/lib/Passes/PassBuilder.cpp               |    1 -
 llvm/lib/Passes/PassBuilderPipelines.cpp      |   12 -
 llvm/lib/Passes/PassRegistry.def              |    3 -
 llvm/lib/Transforms/IPO/CMakeLists.txt        |    1 -
 llvm/lib/Transforms/IPO/IROutliner.cpp        | 2975 -----------------
 .../Analysis/IRSimilarityIdentifier/basic.ll  |  140 -
 .../debug-inst-starts-block.ll                |   77 -
 .../IRSimilarityIdentifier/different.ll       |   48 -
 .../IRSimilarityIdentifier/nothing.ll         |   14 -
 llvm/test/CMakeLists.txt                      |    1 -
 llvm/test/DebugInfo/AArch64/ir-outliner.ll    |  162 -
 llvm/test/Other/new-pm-defaults.ll            |    6 -
 .../IROutliner/alloca-addrspace-1.ll          |   46 -
 .../Transforms/IROutliner/alloca-addrspace.ll |   46 -
 .../IROutliner/different-intrinsics.ll        |   92 -
 .../IROutliner/different-order-phi-merges.ll  |  113 -
 .../IROutliner/duplicate-merging-phis.ll      |  113 -
 .../exit-block-phi-node-value-attribution.ll  |   96 -
 ...-nodes-incoming-value-constant-argument.ll |  110 -
 llvm/test/Transforms/IROutliner/extraction.ll |  127 -
 .../IROutliner/gvn-output-set-overload.ll     |  119 -
 .../Transforms/IROutliner/gvn-phi-debug.ll    |  175 -
 .../Transforms/IROutliner/illegal-allocas.ll  |   36 -
 .../Transforms/IROutliner/illegal-assumes.ll  |  143 -
 .../Transforms/IROutliner/illegal-branches.ll |   51 -
 .../Transforms/IROutliner/illegal-callbr.ll   |   64 -
 .../Transforms/IROutliner/illegal-catchpad.ll |   70 -
 .../Transforms/IROutliner/illegal-cleanup.ll  |   62 -
 .../Transforms/IROutliner/illegal-frozen.ll   |   49 -
 .../IROutliner/illegal-indirect-calls.ll      |   58 -
 .../Transforms/IROutliner/illegal-invoke.ll   |   64 -
 .../IROutliner/illegal-landingpad.ll          |   64 -
 .../Transforms/IROutliner/illegal-memcpy.ll   |   65 -
 .../Transforms/IROutliner/illegal-memmove.ll  |   65 -
 .../Transforms/IROutliner/illegal-memset.ll   |   41 -
 .../Transforms/IROutliner/illegal-nomerge.ll  |  104 -
 .../IROutliner/illegal-phi-nodes.ll           |   49 -
 .../IROutliner/illegal-returns-twice.ll       |   66 -
 .../IROutliner/illegal-typeid-for.ll          |  127 -
 .../Transforms/IROutliner/illegal-vaarg.ll    |   79 -
 .../IROutliner/included-phi-nodes-begin.ll    |   93 -
 .../IROutliner/included-phi-nodes-end.ll      |   94 -
 .../test/Transforms/IROutliner/legal-debug.ll |  139 -
 .../IROutliner/legal-indirect-calls.ll        |   71 -
 ...matched-phi-exits-not-in-first-outlined.ll |   84 -
 .../IROutliner/mismatched-phi-exits.ll        |   84 -
 .../mismatched-phi-outputs-ordering.ll        |  145 -
 .../must-capture-all-phi-nodes-begin.ll       |  106 -
 .../must-capture-all-phi-nodes-end.ll         |   88 -
 .../IROutliner/no-external-block-entries.ll   |   75 -
 .../IROutliner/no-outlining-optnone.ll        |   61 -
 .../IROutliner/nooutline-attribute.ll         |   30 -
 .../one-external-incoming-block-phi-node.ll   |   71 -
 .../test/Transforms/IROutliner/opt-remarks.ll |  405 ---
 .../Transforms/IROutliner/outline-memcpy.ll   |   60 -
 .../Transforms/IROutliner/outline-memmove.ll  |   60 -
 .../Transforms/IROutliner/outline-memset.ll   |   52 -
 .../IROutliner/outline-vaarg-intrinsic.ll     |   95 -
 .../IROutliner/outlining-across-branch.ll     |   77 -
 .../IROutliner/outlining-address-taken.ll     |   91 -
 .../IROutliner/outlining-basic-branches.ll    |   50 -
 .../IROutliner/outlining-bitcasts.ll          |  127 -
 .../outlining-branches-phi-nodes.ll           |  171 -
 .../IROutliner/outlining-call-and-indirect.ll |   70 -
 .../outlining-calls-names-must-match.ll       |   93 -
 .../Transforms/IROutliner/outlining-calls.ll  |   96 -
 .../IROutliner/outlining-commutative-fp.ll    |  107 -
 ...ing-commutative-operands-opposite-order.ll |   40 -
 .../IROutliner/outlining-commutative.ll       |  254 --
 ...ining-compatible-and-attribute-transfer.ll |  125 -
 ...ing-compatible-and-never-transfer-riscv.ll |  298 --
 ...lining-compatible-or-attribute-transfer.ll |   67 -
 .../outlining-constants-vs-registers.ll       |   82 -
 .../IROutliner/outlining-cost-model.ll        |  187 --
 .../IROutliner/outlining-debug-statements.ll  |   65 -
 .../outlining-different-constants.ll          |   58 -
 .../IROutliner/outlining-different-globals.ll |   42 -
 .../outlining-different-output-blocks.ll      |  106 -
 .../outlining-different-structure.ll          |   62 -
 .../IROutliner/outlining-exits-to-phi-node.ll |   92 -
 .../IROutliner/outlining-first-instruction.ll |   67 -
 .../Transforms/IROutliner/outlining-gep.ll    |   68 -
 .../outlining-isomorphic-predicates.ll        |  170 -
 .../outlining-larger-size-commutative.ll      |   89 -
 .../outlining-multiple-exits-diff-outputs.ll  |  221 --
 ...outlining-multiple-exits-one-output-set.ll |  192 --
 .../IROutliner/outlining-multiple-exits.ll    |  200 --
 .../IROutliner/outlining-musttail.ll          |   34 -
 .../outlining-no-return-functions.ll          |   54 -
 .../Transforms/IROutliner/outlining-odr.ll    |   70 -
 .../IROutliner/outlining-remapped-outputs.ll  |   70 -
 .../IROutliner/outlining-same-constants.ll    |   58 -
 .../IROutliner/outlining-same-globals.ll      |   41 -
 .../outlining-same-output-blocks.ll           |   94 -
 .../IROutliner/outlining-special-state.ll     |  163 -
 .../IROutliner/outlining-strip-loop-info.ll   |   78 -
 .../IROutliner/outlining-swift-error.ll       |   44 -
 .../IROutliner/outlining-swifttailcc.ll       |   33 -
 .../Transforms/IROutliner/outlining-tailcc.ll |   33 -
 .../IROutliner/phi-node-exit-path-order.ll    |  120 -
 .../IROutliner/phi-nodes-non-constant.ll      |   74 -
 .../IROutliner/phi-nodes-output-overload.ll   |  110 -
 .../phi-nodes-parent-block-referential.ll     |   98 -
 .../Transforms/IROutliner/phi-nodes-simple.ll |   56 -
 .../IROutliner/region-end-of-module.ll        |  112 -
 .../IROutliner/region-inputs-in-phi-nodes.ll  |  110 -
 llvm/test/lit.cfg.py                          |    2 -
 llvm/test/tools/llvm-sim/Inputs/sim1.ll       |   27 -
 llvm/test/tools/llvm-sim/fail-cases.test      |    8 -
 llvm/test/tools/llvm-sim/single-sim-file.test |   57 -
 llvm/test/tools/llvm-sim/single-sim.test      |   56 -
 llvm/tools/llvm-sim/CMakeLists.txt            |    9 -
 llvm/tools/llvm-sim/llvm-sim.cpp              |  148 -
 llvm/unittests/Analysis/CMakeLists.txt        |    1 -
 .../Analysis/IRSimilarityIdentifierTest.cpp   | 2850 ----------------
 .../gn/secondary/llvm/lib/Analysis/BUILD.gn   |    1 -
 .../llvm/lib/Transforms/IPO/BUILD.gn          |    1 -
 llvm/utils/gn/secondary/llvm/test/BUILD.gn    |    1 -
 .../gn/secondary/llvm/tools/llvm-sim/BUILD.gn |    8 -
 .../llvm/unittests/Analysis/BUILD.gn          |    1 -
 llvm/utils/profcheck-xfail.txt                |    1 -
 .../llvm-project-overlay/llvm/BUILD.bazel     |   17 -
 129 files changed, 3 insertions(+), 18737 deletions(-)
 delete mode 100644 llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
 delete mode 100644 llvm/include/llvm/Transforms/IPO/IROutliner.h
 delete mode 100644 llvm/lib/Analysis/IRSimilarityIdentifier.cpp
 delete mode 100644 llvm/lib/Transforms/IPO/IROutliner.cpp
 delete mode 100644 llvm/test/Analysis/IRSimilarityIdentifier/basic.ll
 delete mode 100644 llvm/test/Analysis/IRSimilarityIdentifier/debug-inst-starts-block.ll
 delete mode 100644 llvm/test/Analysis/IRSimilarityIdentifier/different.ll
 delete mode 100644 llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll
 delete mode 100644 llvm/test/DebugInfo/AArch64/ir-outliner.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/alloca-addrspace-1.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/alloca-addrspace.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/different-intrinsics.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/different-order-phi-merges.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/duplicate-merging-phis.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/exit-block-phi-node-value-attribution.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/exit-phi-nodes-incoming-value-constant-argument.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/extraction.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/gvn-output-set-overload.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/gvn-phi-debug.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-allocas.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-assumes.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-branches.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-callbr.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-catchpad.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-cleanup.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-frozen.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-invoke.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-landingpad.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-memcpy.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-memmove.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-memset.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-nomerge.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-returns-twice.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-typeid-for.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/illegal-vaarg.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/included-phi-nodes-begin.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/included-phi-nodes-end.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/legal-debug.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/legal-indirect-calls.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/mismatched-phi-exits-not-in-first-outlined.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/mismatched-phi-exits.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/mismatched-phi-outputs-ordering.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-begin.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-end.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/no-external-block-entries.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/no-outlining-optnone.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/nooutline-attribute.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/one-external-incoming-block-phi-node.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/opt-remarks.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outline-memcpy.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outline-memmove.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outline-memset.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outline-vaarg-intrinsic.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-across-branch.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-address-taken.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-basic-branches.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-bitcasts.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-branches-phi-nodes.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-call-and-indirect.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-calls-names-must-match.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-calls.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-commutative-operands-opposite-order.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-commutative.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-compatible-and-never-transfer-riscv.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-cost-model.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-debug-statements.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-different-constants.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-different-globals.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-different-structure.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-exits-to-phi-node.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-first-instruction.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-gep.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-larger-size-commutative.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-multiple-exits-diff-outputs.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-multiple-exits-one-output-set.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-multiple-exits.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-musttail.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-no-return-functions.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-odr.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-same-constants.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-same-globals.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-special-state.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-swift-error.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-swifttailcc.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/outlining-tailcc.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/phi-node-exit-path-order.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/phi-nodes-non-constant.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/phi-nodes-output-overload.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/phi-nodes-parent-block-referential.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/phi-nodes-simple.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/region-end-of-module.ll
 delete mode 100644 llvm/test/Transforms/IROutliner/region-inputs-in-phi-nodes.ll
 delete mode 100644 llvm/test/tools/llvm-sim/Inputs/sim1.ll
 delete mode 100644 llvm/test/tools/llvm-sim/fail-cases.test
 delete mode 100644 llvm/test/tools/llvm-sim/single-sim-file.test
 delete mode 100644 llvm/test/tools/llvm-sim/single-sim.test
 delete mode 100644 llvm/tools/llvm-sim/CMakeLists.txt
 delete mode 100644 llvm/tools/llvm-sim/llvm-sim.cpp
 delete mode 100644 llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp
 delete mode 100644 llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn

diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index b26fb21e3ad29..e567f4b0a37f9 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -64,6 +64,9 @@ Makes programs 10x faster by doing Special New Thing.
 
 ### Changes to Interprocedural Optimizations
 
+- The IR Outliner has been removed, due to lack of a maintainer and the presence
+  of correctness issues.
+
 ### Changes to Vectorizers
 
 ### Changes to the AArch64 Backend
diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
deleted file mode 100644
index c9eb5a40f0477..0000000000000
--- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h
+++ /dev/null
@@ -1,1192 +0,0 @@
-//===- IRSimilarityIdentifier.h - Find similarity in a module --------------==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// Interface file for the IRSimilarityIdentifier for identifying similarities in
-// IR including the IRInstructionMapper, which maps an Instruction to unsigned
-// integers.
-//
-// Two sequences of instructions are called "similar" if they perform the same
-// series of operations for all inputs.
-//
-// \code
-// %1 = add i32 %a, 10
-// %2 = add i32 %a, %1
-// %3 = icmp slt icmp %1, %2
-// \endcode
-//
-// and
-//
-// \code
-// %1 = add i32 11, %a
-// %2 = sub i32 %a, %1
-// %3 = icmp sgt icmp %2, %1
-// \endcode
-//
-// ultimately have the same result, even if the inputs, and structure are
-// slightly different.
-//
-// For instructions, we do not worry about operands that do not have fixed
-// semantic meaning to the program.  We consider the opcode that the instruction
-// has, the types, parameters, and extra information such as the function name,
-// or comparison predicate.  These are used to create a hash to map instructions
-// to integers to be used in similarity matching in sequences of instructions
-//
-// Terminology:
-// An IRSimilarityCandidate is a region of IRInstructionData (wrapped
-// Instructions), usually used to denote a region of similarity has been found.
-//
-// A SimilarityGroup is a set of IRSimilarityCandidates that are structurally
-// similar to one another.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
-#define LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
-
-#include "llvm/IR/InstVisitor.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Pass.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
-#include <optional>
-
-namespace llvm {
-
-namespace IRSimilarity {
-
-struct IRInstructionDataList;
-
-/// This represents what is and is not supported when finding similarity in
-/// Instructions.
-///
-/// Legal Instructions are considered when looking at similarity between
-/// Instructions.
-///
-/// Illegal Instructions cannot be considered when looking for similarity
-/// between Instructions. They act as boundaries between similarity regions.
-///
-/// Invisible Instructions are skipped over during analysis.
-// TODO: Shared with MachineOutliner
-enum InstrType { Legal, Illegal, Invisible };
-
-/// This provides the utilities for hashing an Instruction to an unsigned
-/// integer. Two IRInstructionDatas produce the same hash value when their
-/// underlying Instructions perform the same operation (even if they don't have
-/// the same input operands.)
-/// As a more concrete example, consider the following:
-///
-/// \code
-/// %add1 = add i32 %a, %b
-/// %add2 = add i32 %c, %d
-/// %add3 = add i64 %e, %f
-/// \endcode
-///
-// Then the IRInstructionData wrappers for these Instructions may be hashed like
-/// so:
-///
-/// \code
-/// ; These two adds have the same types and operand types, so they hash to the
-/// ; same number.
-/// %add1 = add i32 %a, %b ; Hash: 1
-/// %add2 = add i32 %c, %d ; Hash: 1
-/// ; This add produces an i64. This differentiates it from %add1 and %add2. So,
-/// ; it hashes to a different number.
-/// %add3 = add i64 %e, %f; Hash: 2
-/// \endcode
-///
-///
-/// This hashing scheme will be used to represent the program as a very long
-/// string. This string can then be placed in a data structure which can be used
-/// for similarity queries.
-///
-/// TODO: Handle types of Instructions which can be equal even with different
-/// operands. (E.g. comparisons with swapped predicates.)
-/// TODO: Handle CallInsts, which are only checked for function type
-/// by \ref isSameOperationAs.
-/// TODO: Handle GetElementPtrInsts, as some of the operands have to be the
-/// exact same, and some do not.
-struct IRInstructionData
-    : ilist_node<IRInstructionData, ilist_sentinel_tracking<true>> {
-
-  /// The source Instruction that is being wrapped.
-  Instruction *Inst = nullptr;
-  /// The values of the operands in the Instruction.
-  SmallVector<Value *, 4> OperVals;
-  /// The legality of the wrapped instruction. This is informed by InstrType,
-  /// and is used when checking when two instructions are considered similar.
-  /// If either instruction is not legal, the instructions are automatically not
-  /// considered similar.
-  bool Legal = false;
-
-  /// This is only relevant if we are wrapping a CmpInst where we needed to
-  /// change the predicate of a compare instruction from a greater than form
-  /// to a less than form.  It is std::nullopt otherwise.
-  std::optional<CmpInst::Predicate> RevisedPredicate;
-
-  /// This is only relevant if we are wrapping a CallInst. If we are requiring
-  /// that the function calls have matching names as well as types, and the
-  /// call is not an indirect call, this will hold the name of the function.  If
-  /// it is an indirect string, it will be the empty string.  However, if this
-  /// requirement is not in place it will be the empty string regardless of the
-  /// function call type.  The value held here is used to create the hash of the
-  /// instruction, and check to make sure two instructions are close to one
-  /// another.
-  std::optional<std::string> CalleeName;
-
-  /// This structure holds the distances of how far "ahead of" or "behind" the
-  /// target blocks of a branch, or the incoming blocks of a phi nodes are.
-  /// If the value is negative, it means that the block was registered before
-  /// the block of this instruction in terms of blocks in the function.
-  /// Code Example:
-  /// \code
-  /// block_1:
-  ///   br i1 %0, label %block_2, label %block_3
-  /// block_2:
-  ///   br i1 %1, label %block_1, label %block_2
-  /// block_3:
-  ///   br i1 %2, label %block_2, label %block_1
-  /// ; Replacing the labels with relative values, this becomes:
-  /// block_1:
-  ///   br i1 %0, distance 1, distance 2
-  /// block_2:
-  ///   br i1 %1, distance -1, distance 0
-  /// block_3:
-  ///   br i1 %2, distance -1, distance -2
-  /// \endcode
-  /// Taking block_2 as our example, block_1 is "behind" block_2, and block_2 is
-  /// "ahead" of block_2.
-  SmallVector<int, 4> RelativeBlockLocations;
-
-  /// Gather the information that is difficult to gather for an Instruction, or
-  /// is changed. i.e. the operands of an Instruction and the Types of those
-  /// operands. This extra information allows for similarity matching to make
-  /// assertions that allow for more flexibility when checking for whether an
-  /// Instruction performs the same operation.
-  LLVM_ABI IRInstructionData(Instruction &I, bool Legality,
-                             IRInstructionDataList &IDL);
-  LLVM_ABI IRInstructionData(IRInstructionDataList &IDL);
-
-  /// Fills data stuctures for IRInstructionData when it is constructed from a
-  // reference or a pointer.
-  LLVM_ABI void initializeInstruction();
-
-  /// Get the predicate that the compare instruction is using for hashing the
-  /// instruction. the IRInstructionData must be wrapping a CmpInst.
-  LLVM_ABI CmpInst::Predicate getPredicate() const;
-
-  /// Get the callee name that the call instruction is using for hashing the
-  /// instruction. The IRInstructionData must be wrapping a CallInst.
-  LLVM_ABI StringRef getCalleeName() const;
-
-  /// A function that swaps the predicates to their less than form if they are
-  /// in a greater than form. Otherwise, the predicate is unchanged.
-  ///
-  /// \param CI - The comparison operation to find a consistent preidcate for.
-  /// \return the consistent comparison predicate.
-  LLVM_ABI static CmpInst::Predicate predicateForConsistency(CmpInst *CI);
-
-  /// For an IRInstructionData containing a branch, finds the
-  /// relative distances from the source basic block to the target by taking
-  /// the difference of the number assigned to the current basic block and the
-  /// target basic block of the branch.
-  ///
-  /// \param BasicBlockToInteger - The mapping of basic blocks to their location
-  /// in the module.
-  LLVM_ABI void
-  setBranchSuccessors(DenseMap<BasicBlock *, unsigned> &BasicBlockToInteger);
-
-  /// For an IRInstructionData containing a CallInst, set the function name
-  /// appropriately.  This will be an empty string if it is an indirect call,
-  /// or we are not matching by name of the called function.  It will be the
-  /// name of the function if \p MatchByName is true and it is not an indirect
-  /// call.  We may decide not to match by name in order to expand the
-  /// size of the regions we can match.  If a function name has the same type
-  /// signature, but the different name, the region of code is still almost the
-  /// same.  Since function names can be treated as constants, the name itself
-  /// could be extrapolated away.  However, matching by name provides a
-  /// specificity and more "identical" code than not matching by name.
-  ///
-  /// \param MatchByName - A flag to mark whether we are using the called
-  /// function name as a differentiating parameter.
-  LLVM_ABI void setCalleeName(bool MatchByName = true);
-
-  /// For an IRInstructionData containing a PHINode, finds the
-  /// relative distances from the incoming basic block to the current block by
-  /// taking the difference of the number assigned to the current basic block
-  /// and the incoming basic block of the branch.
-  ///
-  /// \param BasicBlockToInteger - The mapping of basic blocks to their location
-  /// in the module.
-  LLVM_ABI void
-  setPHIPredecessors(DenseMap<BasicBlock *, unsigned> &BasicBlockToInteger);
-
-  /// Get the BasicBlock based operands for PHINodes and BranchInsts.
-  ///
-  /// \returns A list of relevant BasicBlocks.
-  LLVM_ABI ArrayRef<Value *> getBlockOperVals();
-
-  /// Hashes \p Value based on its opcode, types, and operand types.
-  /// Two IRInstructionData instances produce the same hash when they perform
-  /// the same operation.
-  ///
-  /// As a simple example, consider the following instructions.
-  ///
-  /// \code
-  /// %add1 = add i32 %x1, %y1
-  /// %add2 = add i32 %x2, %y2
-  ///
-  /// %sub = sub i32 %x1, %y1
-  ///
-  /// %add_i64 = add i64 %x2, %y2
-  /// \endcode
-  ///
-  /// Because the first two adds operate the same types, and are performing the
-  /// same action, they will be hashed to the same value.
-  ///
-  /// However, the subtraction instruction is not the same as an addition, and
-  /// will be hashed to a different value.
-  ///
-  /// Finally, the last add has a different type compared to the first two add
-  /// instructions, so it will also be hashed to a different value that any of
-  /// the previous instructions.
-  ///
-  /// \param [in] ID - The IRInstructionData instance to be hashed.
-  /// \returns A hash_value of the IRInstructionData.
-  friend hash_code hash_value(const IRInstructionData &ID) {
-    SmallVector<Type *, 4> OperTypes;
-    for (Value *V : ID.OperVals)
-      OperTypes.push_back(V->getType());
-
-    if (isa<CmpInst>(ID.Inst))
-      return llvm::hash_combine(llvm::hash_value(ID.Inst->getOpcode()),
-                                llvm::hash_value(ID.Inst->getType()),
-                                llvm::hash_value(ID.getPredicate()),
-                                llvm::hash_combine_range(OperTypes));
-
-    if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(ID.Inst)) {
-      // To hash intrinsics, we use the opcode, and types like the other
-      // instructions, but also, the Intrinsic ID, and the Name of the
-      // intrinsic.
-      Intrinsic::ID IntrinsicID = II->getIntrinsicID();
-      return llvm::hash_combine(llvm::hash_value(ID.Inst->getOpcode()),
-                                llvm::hash_value(ID.Inst->getType()),
-                                llvm::hash_value(IntrinsicID),
-                                llvm::hash_value(*ID.CalleeName),
-                                llvm::hash_combine_range(OperTypes));
-    }
-
-    if (isa<CallInst>(ID.Inst)) {
-      std::string FunctionName = *ID.CalleeName;
-      return llvm::hash_combine(llvm::hash_value(ID.Inst->getOpcode()),
-                                llvm::hash_value(ID.Inst->getType()),
-                                llvm::hash_value(ID.Inst->getType()),
-                                llvm::hash_value(FunctionName),
-                                llvm::hash_combine_range(OperTypes));
-    }
-
-    return llvm::hash_combine(llvm::hash_value(ID.Inst->getOpcode()),
-                              llvm::hash_value(ID.Inst->getType()),
-                              llvm::hash_combine_range(OperTypes));
-  }
-
-  IRInstructionDataList *IDL = nullptr;
-};
-
-struct IRInstructionDataList
-    : simple_ilist<IRInstructionData, ilist_sentinel_tracking<true>> {};
-
-/// Compare one IRInstructionData class to another IRInstructionData class for
-/// whether they are performing a the same operation, and can mapped to the
-/// same value. For regular instructions if the hash value is the same, then
-/// they will also be close.
-///
-/// \param A - The first IRInstructionData class to compare
-/// \param B - The second IRInstructionData class to compare
-/// \returns true if \p A and \p B are similar enough to be mapped to the same
-/// value.
-LLVM_ABI bool isClose(const IRInstructionData &A, const IRInstructionData &B);
-
-struct IRInstructionDataTraits : DenseMapInfo<IRInstructionData *> {
-  static unsigned getHashValue(const IRInstructionData *E) {
-    using llvm::hash_value;
-    assert(E && "IRInstructionData is a nullptr?");
-    return hash_value(*E);
-  }
-
-  static bool isEqual(const IRInstructionData *LHS,
-                      const IRInstructionData *RHS) {
-    assert(LHS && RHS && "nullptr is not expected as a key");
-    return isClose(*LHS, *RHS);
-  }
-};
-
-/// Helper struct for converting the Instructions in a Module into a vector of
-/// unsigned integers. This vector of unsigned integers can be thought of as a
-/// "numeric string". This numeric string can then be queried by, for example,
-/// data structures that find repeated substrings.
-///
-/// This hashing is done per BasicBlock in the module. To hash Instructions
-/// based off of their operations, each Instruction is wrapped in an
-/// IRInstructionData struct. The unsigned integer for an IRInstructionData
-/// depends on:
-/// - The hash provided by the IRInstructionData.
-/// - Which member of InstrType the IRInstructionData is classified as.
-// See InstrType for more details on the possible classifications, and how they
-// manifest in the numeric string.
-///
-/// The numeric string for an individual BasicBlock is terminated by an unique
-/// unsigned integer. This prevents data structures which rely on repetition
-/// from matching across BasicBlocks. (For example, the SuffixTree.)
-/// As a concrete example, if we have the following two BasicBlocks:
-/// \code
-/// bb0:
-/// %add1 = add i32 %a, %b
-/// %add2 = add i32 %c, %d
-/// %add3 = add i64 %e, %f
-/// bb1:
-/// %sub = sub i32 %c, %d
-/// \endcode
-/// We may hash the Instructions like this (via IRInstructionData):
-/// \code
-/// bb0:
-/// %add1 = add i32 %a, %b ; Hash: 1
-/// %add2 = add i32 %c, %d; Hash: 1
-/// %add3 = add i64 %e, %f; Hash: 2
-/// bb1:
-/// %sub = sub i32 %c, %d; Hash: 3
-/// %add4 = add i32 %c, %d ; Hash: 1
-/// \endcode
-/// And produce a "numeric string representation" like so:
-/// 1, 1, 2, unique_integer_1, 3, 1, unique_integer_2
-///
-/// TODO: This is very similar to the MachineOutliner, and should be
-/// consolidated into the same interface.
-struct IRInstructionMapper {
-  /// The starting illegal instruction number to map to.
-  ///
-  /// Set to -3 for compatibility with DenseMapInfo<unsigned>.
-  unsigned IllegalInstrNumber = static_cast<unsigned>(-3);
-
-  /// The next available integer to assign to a legal Instruction to.
-  unsigned LegalInstrNumber = 0;
-
-  /// Correspondence from IRInstructionData to unsigned integers.
-  DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>
-      InstructionIntegerMap;
-
-  /// A mapping for a basic block in a module to its assigned number/location
-  /// in the module.
-  DenseMap<BasicBlock *, unsigned> BasicBlockToInteger;
-
-  /// Set if we added an illegal number in the previous step.
-  /// Since each illegal number is unique, we only need one of them between
-  /// each range of legal numbers. This lets us make sure we don't add more
-  /// than one illegal number per range.
-  bool AddedIllegalLastTime = false;
-
-  /// Marks whether we found a illegal instruction in the previous step.
-  bool CanCombineWithPrevInstr = false;
-
-  /// Marks whether we have found a set of instructions that is long enough
-  /// to be considered for similarity.
-  bool HaveLegalRange = false;
-
-  /// Marks whether we should use exact function names, as well as types to
-  /// find similarity between calls.
-  bool EnableMatchCallsByName = false;
-
-  /// This allocator pointer is in charge of holding on to the IRInstructionData
-  /// so it is not deallocated until whatever external tool is using it is done
-  /// with the information.
-  SpecificBumpPtrAllocator<IRInstructionData> *InstDataAllocator = nullptr;
-
-  /// This allocator pointer is in charge of creating the IRInstructionDataList
-  /// so it is not deallocated until whatever external tool is using it is done
-  /// with the information.
-  SpecificBumpPtrAllocator<IRInstructionDataList> *IDLAllocator = nullptr;
-
-  /// Get an allocated IRInstructionData struct using the InstDataAllocator.
-  ///
-  /// \param I - The Instruction to wrap with IRInstructionData.
-  /// \param Legality - A boolean value that is true if the instruction is to
-  /// be considered for similarity, and false if not.
-  /// \param IDL - The InstructionDataList that the IRInstructionData is
-  /// inserted into.
-  /// \returns An allocated IRInstructionData struct.
-  LLVM_ABI IRInstructionData *
-  allocateIRInstructionData(Instruction &I, bool Legality,
-                            IRInstructionDataList &IDL);
-
-  /// Get an empty allocated IRInstructionData struct using the
-  /// InstDataAllocator.
-  ///
-  /// \param IDL - The InstructionDataList that the IRInstructionData is
-  /// inserted into.
-  /// \returns An allocated IRInstructionData struct.
-  LLVM_ABI IRInstructionData *
-  allocateIRInstructionData(IRInstructionDataList &IDL);
-
-  /// Get an allocated IRInstructionDataList object using the IDLAllocator.
-  ///
-  /// \returns An allocated IRInstructionDataList object.
-  LLVM_ABI IRInstructionDataList *allocateIRInstructionDataList();
-
-  IRInstructionDataList *IDL = nullptr;
-
-  /// Assigns values to all the basic blocks in function \p F starting from
-  /// integer \p BBNumber.
-  ///
-  /// \param F - The function containing the basic blocks to assign numbers to.
-  /// \param BBNumber - The number to start from.
-  void initializeForBBs(Function &F, unsigned &BBNumber) {
-    for (BasicBlock &BB : F)
-      BasicBlockToInteger.insert(std::make_pair(&BB, BBNumber++));
-  }
-
-  /// Assigns values to all the basic blocks in Module \p M.
-  /// \param M - The module containing the basic blocks to assign numbers to.
-  void initializeForBBs(Module &M) {
-    unsigned BBNumber = 0;
-    for (Function &F : M)
-      initializeForBBs(F, BBNumber);
-  }
-
-  /// Maps the Instructions in a BasicBlock \p BB to legal or illegal integers
-  /// determined by \p InstrType. Two Instructions are mapped to the same value
-  /// if they are close as defined by the InstructionData class above.
-  ///
-  /// \param [in] BB - The BasicBlock to be mapped to integers.
-  /// \param [in,out] InstrList - Vector of IRInstructionData to append to.
-  /// \param [in,out] IntegerMapping - Vector of unsigned integers to append to.
-  LLVM_ABI void
-  convertToUnsignedVec(BasicBlock &BB,
-                       std::vector<IRInstructionData *> &InstrList,
-                       std::vector<unsigned> &IntegerMapping);
-
-  /// Maps an Instruction to a legal integer.
-  ///
-  /// \param [in] It - The Instruction to be mapped to an integer.
-  /// \param [in,out] IntegerMappingForBB - Vector of unsigned integers to
-  /// append to.
-  /// \param [in,out] InstrListForBB - Vector of InstructionData to append to.
-  /// \returns The integer \p It was mapped to.
-  LLVM_ABI unsigned
-  mapToLegalUnsigned(BasicBlock::iterator &It,
-                     std::vector<unsigned> &IntegerMappingForBB,
-                     std::vector<IRInstructionData *> &InstrListForBB);
-
-  /// Maps an Instruction to an illegal integer.
-  ///
-  /// \param [in] It - The \p Instruction to be mapped to an integer.
-  /// \param [in,out] IntegerMappingForBB - Vector of unsigned integers to
-  /// append to.
-  /// \param [in,out] InstrListForBB - Vector of IRInstructionData to append to.
-  /// \param End - true if creating a dummy IRInstructionData at the end of a
-  /// basic block.
-  /// \returns The integer \p It was mapped to.
-  LLVM_ABI unsigned mapToIllegalUnsigned(
-      BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
-      std::vector<IRInstructionData *> &InstrListForBB, bool End = false);
-
-  IRInstructionMapper(SpecificBumpPtrAllocator<IRInstructionData> *IDA,
-                      SpecificBumpPtrAllocator<IRInstructionDataList> *IDLA)
-      : InstDataAllocator(IDA), IDLAllocator(IDLA) {
-    IDL = new (IDLAllocator->Allocate())
-        IRInstructionDataList();
-  }
-
-  /// Custom InstVisitor to classify different instructions for whether it can
-  /// be analyzed for similarity.
-  struct InstructionClassification
-      : public InstVisitor<InstructionClassification, InstrType> {
-    InstructionClassification() = default;
-
-    // TODO: Determine a scheme to resolve when the label is similar enough.
-    InstrType visitUncondBrInst(UncondBrInst &BI) {
-      if (EnableBranches)
-        return Legal;
-      return Illegal;
-    }
-    InstrType visitCondBrInst(CondBrInst &BI) {
-      if (EnableBranches)
-        return Legal;
-      return Illegal;
-    }
-    InstrType visitPHINode(PHINode &PN) { 
-      if (EnableBranches)
-        return Legal;
-      return Illegal;
-    }
-    // TODO: Handle allocas.
-    InstrType visitAllocaInst(AllocaInst &AI) { return Illegal; }
-    // We exclude variable argument instructions since variable arguments
-    // requires extra checking of the argument list.
-    InstrType visitVAArgInst(VAArgInst &VI) { return Illegal; }
-    // We exclude all exception handling cases since they are so context
-    // dependent.
-    InstrType visitLandingPadInst(LandingPadInst &LPI) { return Illegal; }
-    InstrType visitFuncletPadInst(FuncletPadInst &FPI) { return Illegal; }
-    InstrType visitIntrinsicInst(IntrinsicInst &II) {
-      // These are disabled due to complications in the CodeExtractor when
-      // outlining these instructions.  For instance, It is unclear what we
-      // should do when moving only the start or end lifetime instruction into
-      // an outlined function. Also, assume-like intrinsics could be removed
-      // from the region, removing arguments, causing discrepencies in the
-      // number of inputs between different regions.
-      if (II.isAssumeLikeIntrinsic())
-        return Illegal;
-      return EnableIntrinsics ? Legal : Illegal;
-    }
-    // We only allow call instructions where the function has a name and
-    // is not an indirect call.
-    InstrType visitCallInst(CallInst &CI) {
-      Function *F = CI.getCalledFunction();
-      bool IsIndirectCall = CI.isIndirectCall();
-      if (IsIndirectCall && !EnableIndirectCalls)
-        return Illegal;
-      if (!F && !IsIndirectCall)
-        return Illegal;
-      // Functions marked with the swifttailcc and tailcc calling conventions
-      // require special handling when outlining musttail functions.  The
-      // calling convention must be passed down to the outlined function as
-      // well. Further, there is special handling for musttail calls as well,
-      // requiring a return call directly after.  For now, the outliner does not
-      // support this, so we do not handle matching this case either.
-      if ((CI.getCallingConv() == CallingConv::SwiftTail ||
-           CI.getCallingConv() == CallingConv::Tail) &&
-          !EnableMustTailCalls)
-        return Illegal;
-      if (CI.isMustTailCall() && !EnableMustTailCalls)
-        return Illegal;
-      return Legal;
-    }
-    // TODO: We do not current handle similarity that changes the control flow.
-    InstrType visitInvokeInst(InvokeInst &II) { return Illegal; }
-    // TODO: We do not current handle similarity that changes the control flow.
-    InstrType visitCallBrInst(CallBrInst &CBI) { return Illegal; }
-    // TODO: Handle interblock similarity.
-    InstrType visitTerminator(Instruction &I) { return Illegal; }
-    InstrType visitInstruction(Instruction &I) { return Legal; }
-
-    // The flag variable that lets the classifier know whether we should
-    // allow branches to be checked for similarity.
-    bool EnableBranches = false;
-
-    // The flag variable that lets the classifier know whether we should
-    // allow indirect calls to be considered legal instructions.
-    bool EnableIndirectCalls = false;
-
-    // Flag that lets the classifier know whether we should allow intrinsics to
-    // be checked for similarity.
-    bool EnableIntrinsics = false;
-  
-    // Flag that lets the classifier know whether we should allow tail calls to
-    // be checked for similarity.
-    bool EnableMustTailCalls = false;
-  };
-
-  /// Maps an Instruction to a member of InstrType.
-  InstructionClassification InstClassifier;
-};
-
-/// This is a class that wraps a range of IRInstructionData from one point to
-/// another in the vector of IRInstructionData, which is a region of the
-/// program.  It is also responsible for defining the structure within this
-/// region of instructions.
-///
-/// The structure of a region is defined through a value numbering system
-/// assigned to each unique value in a region at the creation of the
-/// IRSimilarityCandidate.
-///
-/// For example, for each Instruction we add a mapping for each new
-/// value seen in that Instruction.
-/// IR:                    Mapping Added:
-/// %add1 = add i32 %a, c1    %add1 -> 3, %a -> 1, c1 -> 2
-/// %add2 = add i32 %a, %1    %add2 -> 4
-/// %add3 = add i32 c2, c1    %add3 -> 6, c2 -> 5
-///
-/// We can compare IRSimilarityCandidates against one another.
-/// The \ref isSimilar function compares each IRInstructionData against one
-/// another and if we have the same sequences of IRInstructionData that would
-/// create the same hash, we have similar IRSimilarityCandidates.
-///
-/// We can also compare the structure of IRSimilarityCandidates. If we can
-/// create a mapping of registers in the region contained by one
-/// IRSimilarityCandidate to the region contained by different
-/// IRSimilarityCandidate, they can be considered structurally similar.
-///
-/// IRSimilarityCandidate1:   IRSimilarityCandidate2:
-/// %add1 = add i32 %a, %b    %add1 = add i32 %d, %e
-/// %add2 = add i32 %a, %c    %add2 = add i32 %d, %f
-/// %add3 = add i32 c1, c2    %add3 = add i32 c3, c4
-///
-/// Can have the following mapping from candidate to candidate of:
-/// %a -> %d, %b -> %e, %c -> %f, c1 -> c3, c2 -> c4
-/// and can be considered similar.
-///
-/// IRSimilarityCandidate1:   IRSimilarityCandidate2:
-/// %add1 = add i32 %a, %b    %add1 = add i32 %d, c4
-/// %add2 = add i32 %a, %c    %add2 = add i32 %d, %f
-/// %add3 = add i32 c1, c2    %add3 = add i32 c3, c4
-///
-/// We cannot create the same mapping since the use of c4 is not used in the
-/// same way as %b or c2.
-class IRSimilarityCandidate {
-private:
-  /// The start index of this IRSimilarityCandidate in the instruction list.
-  unsigned StartIdx = 0;
-
-  /// The number of instructions in this IRSimilarityCandidate.
-  unsigned Len = 0;
-
-  /// The first instruction in this IRSimilarityCandidate.
-  IRInstructionData *FirstInst = nullptr;
-
-  /// The last instruction in this IRSimilarityCandidate.
-  IRInstructionData *LastInst = nullptr;
-
-  /// Global Value Numbering structures
-  /// @{
-  /// Stores the mapping of the value to the number assigned to it in the
-  /// IRSimilarityCandidate.
-  DenseMap<Value *, unsigned> ValueToNumber;
-  /// Stores the mapping of the number to the value assigned this number.
-  DenseMap<unsigned, Value *> NumberToValue;
-  /// Stores the mapping of a value's number to canonical numbering in the
-  /// candidate's respective similarity group.
-  DenseMap<unsigned, unsigned> NumberToCanonNum;
-  /// Stores the mapping of canonical number in the candidate's respective
-  /// similarity group to a value number.
-  DenseMap<unsigned, unsigned> CanonNumToNumber;
-  /// @}
-
-public:
-  /// \param StartIdx - The starting location of the region.
-  /// \param Len - The length of the region.
-  /// \param FirstInstIt - The starting IRInstructionData of the region.
-  /// \param LastInstIt - The ending IRInstructionData of the region.
-  LLVM_ABI IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
-                                 IRInstructionData *FirstInstIt,
-                                 IRInstructionData *LastInstIt);
-
-  /// \param A - The first IRInstructionCandidate to compare.
-  /// \param B - The second IRInstructionCandidate to compare.
-  /// \returns True when every IRInstructionData in \p A is similar to every
-  /// IRInstructionData in \p B.
-  LLVM_ABI static bool isSimilar(const IRSimilarityCandidate &A,
-                                 const IRSimilarityCandidate &B);
-
-  /// \param [in] A - The first IRInstructionCandidate to compare.
-  /// \param [in] B - The second IRInstructionCandidate to compare.
-  /// \returns True when every IRInstructionData in \p A is structurally similar
-  /// to \p B.
-  LLVM_ABI static bool compareStructure(const IRSimilarityCandidate &A,
-                                        const IRSimilarityCandidate &B);
-
-  /// \param [in] A - The first IRInstructionCandidate to compare.
-  /// \param [in] B - The second IRInstructionCandidate to compare.
-  /// \param [in,out] ValueNumberMappingA - A mapping of value numbers from
-  /// candidate \p A to candidate \B.
-  /// \param [in,out] ValueNumberMappingB - A mapping of value numbers from
-  /// candidate \p B to candidate \A.
-  /// \returns True when every IRInstructionData in \p A is structurally similar
-  /// to \p B.
-  LLVM_ABI static bool
-  compareStructure(const IRSimilarityCandidate &A,
-                   const IRSimilarityCandidate &B,
-                   DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingA,
-                   DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingB);
-
-  struct OperandMapping {
-    /// The IRSimilarityCandidate that holds the instruction the OperVals were
-    /// pulled from.
-    const IRSimilarityCandidate &IRSC;
-
-    /// The operand values to be analyzed.
-    ArrayRef<Value *> &OperVals;
-
-    /// The current mapping of global value numbers from one IRSimilarityCandidate
-    /// to another IRSimilarityCandidate.
-    DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMapping;
-  };
-
-  /// A helper struct to hold the candidate, for a branch instruction, the
-  /// relative location of a label, and the label itself.  This is mostly to
-  /// group the values together before passing them as a bundle to a function.
-  struct RelativeLocMapping {
-    /// The IRSimilarityCandidate that holds the instruction the relative
-    /// location was pulled from.
-    const IRSimilarityCandidate &IRSC;
-
-    /// The relative location to be analyzed.
-    int RelativeLocation;
-
-    /// The corresponding value.
-    Value *OperVal;
-  };
-
-  /// Compare the operands in \p A and \p B and check that the current mapping
-  /// of global value numbers from \p A to \p B and \p B to \A is consistent.
-  ///
-  /// \param A - The first IRInstructionCandidate, operand values, and current
-  /// operand mappings to compare.
-  /// \param B - The second IRInstructionCandidate, operand values, and current
-  /// operand mappings to compare.
-  /// \returns true if the IRSimilarityCandidates operands are compatible.
-  LLVM_ABI static bool compareNonCommutativeOperandMapping(OperandMapping A,
-                                                           OperandMapping B);
-
-  /// Compare the operands in \p A and \p B and check that the current mapping
-  /// of global value numbers from \p A to \p B and \p B to \A is consistent
-  /// given that the operands are commutative.
-  ///
-  /// \param A - The first IRInstructionCandidate, operand values, and current
-  /// operand mappings to compare.
-  /// \param B - The second IRInstructionCandidate, operand values, and current
-  /// operand mappings to compare.
-  /// \returns true if the IRSimilarityCandidates operands are compatible.
-  LLVM_ABI static bool compareCommutativeOperandMapping(OperandMapping A,
-                                                        OperandMapping B);
-
-  /// Compare the GVN of the assignment value in corresponding instructions in
-  /// IRSimilarityCandidates \p A and \p B and check that there exists a mapping
-  /// between the values and replaces the mapping with a one-to-one value if
-  /// needed.
-  ///
-  /// \param InstValA - The assignment GVN from the first IRSimilarityCandidate.
-  /// \param InstValB - The assignment GVN from the second
-  /// IRSimilarityCandidate.
-  /// \param [in,out] ValueNumberMappingA - A mapping of value numbers from 
-  /// candidate \p A to candidate \B.
-  /// \param [in,out] ValueNumberMappingB - A mapping of value numbers from 
-  /// candidate \p B to candidate \A.
-  /// \returns true if the IRSimilarityCandidates assignments are compatible.
-  LLVM_ABI static bool compareAssignmentMapping(
-      const unsigned InstValA, const unsigned &InstValB,
-      DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingA,
-      DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingB);
-
-  /// Compare the relative locations in \p A and \p B and check that the
-  /// distances match if both locations are contained in the region, and that
-  /// the branches both point outside the region if they do not.
-  /// Example Region:
-  /// \code
-  /// entry:
-  ///   br i1 %0, label %block_1, label %block_3
-  /// block_0:
-  ///   br i1 %0, label %block_1, label %block_2
-  /// block_1:
-  ///   br i1 %0, label %block_2, label %block_3
-  /// block_2:
-  ///   br i1 %1, label %block_1, label %block_4
-  /// block_3:
-  ///   br i1 %2, label %block_2, label %block_5
-  /// \endcode
-  /// If we compare the branches in block_0 and block_1 the relative values are
-  /// 1 and 2 for both, so we consider this a match.
-  ///
-  /// If we compare the branches in entry and block_0 the relative values are
-  /// 2 and 3, and 1 and 2 respectively.  Since these are not the same we do not
-  /// consider them a match.
-  ///
-  /// If we compare the branches in block_1 and block_2 the relative values are
-  /// 1 and 2, and -1 and None respectively.  As a result we do not consider
-  /// these to be the same
-  ///
-  /// If we compare the branches in block_2 and block_3 the relative values are
-  /// -1 and None for both.  We do consider these to be a match.
-  ///
-  /// \param A - The first IRInstructionCandidate, relative location value,
-  /// and incoming block.
-  /// \param B - The second IRInstructionCandidate, relative location value,
-  /// and incoming block.
-  /// \returns true if the relative locations match.
-  LLVM_ABI static bool checkRelativeLocations(RelativeLocMapping A,
-                                              RelativeLocMapping B);
-
-  /// Create a mapping from the value numbering to a different separate set of
-  /// numbers. This will serve as a guide for relating one candidate to another.
-  /// The canonical number gives use the ability identify which global value
-  /// number in one candidate relates to the global value number in the other.
-  ///
-  /// \param [in, out] CurrCand - The IRSimilarityCandidate to create a
-  /// canonical numbering for.
-  LLVM_ABI static void
-  createCanonicalMappingFor(IRSimilarityCandidate &CurrCand);
-
-  /// Create a mapping for the value numbering of the calling
-  /// IRSimilarityCandidate, to a different separate set of numbers, based on
-  /// the canonical ordering in \p SourceCand. These are defined based on the
-  /// found mappings in \p ToSourceMapping and \p FromSourceMapping.  Both of
-  /// these relationships should have the same information, just in opposite
-  /// directions.
-  ///
-  /// \param [in, out] SourceCand - The IRSimilarityCandidate to create a
-  /// canonical numbering from.
-  /// \param ToSourceMapping - The mapping of value numbers from this candidate
-  /// to \p SourceCand.
-  /// \param FromSourceMapping - The mapping of value numbers from \p SoureCand
-  /// to this candidate.
-  LLVM_ABI void createCanonicalRelationFrom(
-      IRSimilarityCandidate &SourceCand,
-      DenseMap<unsigned, DenseSet<unsigned>> &ToSourceMapping,
-      DenseMap<unsigned, DenseSet<unsigned>> &FromSourceMapping);
-
-  /// Create a mapping for the value numbering of the calling
-  /// IRSimilarityCandidate, to a different separate set of numbers, based on
-  /// the canonical ordering in \p SourceCand. These are defined based on the
-  /// found mappings in \p ToSourceMapping and \p FromSourceMapping.  Both of
-  /// these relationships should have the same information, just in opposite
-  /// directions.  Uses the \p OneToOne mapping from target candidate to \p
-  /// SourceCand GVNs to determine the mapping first for values with multiple
-  /// mappings.  This mapping is created by the ordering of operands in the
-  /// instruction they are first seen in the candidates.
-  ///
-  /// \param [in, out] SourceCand - The IRSimilarityCandidate to create a
-  /// canonical numbering from.
-  /// \param [in,out] OneToOne - A mapping of value numbers from candidate
-  /// \p A to candidate \B using the structure of the original instructions.
-  /// \param ToSourceMapping - The mapping of value numbers from this candidate
-  /// to \p SourceCand.
-  /// \param FromSourceMapping - The mapping of value numbers from \p SoureCand
-  /// to this candidate.
-  LLVM_ABI void createCanonicalRelationFrom(
-      IRSimilarityCandidate &SourceCand, DenseMap<unsigned, unsigned> &OneToOne,
-      DenseMap<unsigned, DenseSet<unsigned>> &ToSourceMapping,
-      DenseMap<unsigned, DenseSet<unsigned>> &FromSourceMapping);
-
-  /// Create a mapping for the value numbering of the calling
-  /// IRSimilarityCandidate, to a different separate set of numbers, based on
-  /// the canonical ordering in \p SourceCand. These are defined based on the
-  /// canonical mapping defined between \p SoureCandLarge and
-  /// \p TargetCandLarge.  These IRSimilarityCandidates are already structurally
-  /// similar, and fully encapsulate the IRSimilarityCandidates in question.
-  /// These are used as a "bridge" from the \p SourceCand to the target.
-  ///
-  /// \param [in, out] SourceCand - The IRSimilarityCandidate to create a
-  /// canonical numbering from.
-  /// \param SoureCandLarge - The IRSimilarityCandidate fully containing
-  /// \p SourceCand.
-  /// \param TargetCandLarge -  The IRSimilarityCandidate fully containing
-  /// this Candidate.
-  LLVM_ABI void
-  createCanonicalRelationFrom(IRSimilarityCandidate &SourceCand,
-                              IRSimilarityCandidate &SourceCandLarge,
-                              IRSimilarityCandidate &TargetCandLarge);
-
-  /// \param [in,out] BBSet - The set to track the basic blocks.
-  void getBasicBlocks(DenseSet<BasicBlock *> &BBSet) const {
-    for (IRInstructionData &ID : *this) {
-      BasicBlock *BB = ID.Inst->getParent();
-      BBSet.insert(BB);
-    }
-  }
-
-  /// \param [in,out] BBSet - The set to track the basic blocks.
-  /// \param [in,out] BBList - A list in order of use to track the basic blocks.
-  void getBasicBlocks(DenseSet<BasicBlock *> &BBSet,
-                      SmallVector<BasicBlock *> &BBList) const {
-    for (IRInstructionData &ID : *this) {
-      BasicBlock *BB = ID.Inst->getParent();
-      if (BBSet.insert(BB).second)
-        BBList.push_back(BB);
-    }
-  }
-
-  /// Compare the start and end indices of the two IRSimilarityCandidates for
-  /// whether they overlap. If the start instruction of one
-  /// IRSimilarityCandidate is less than the end instruction of the other, and
-  /// the start instruction of one is greater than the start instruction of the
-  /// other, they overlap.
-  ///
-  /// \returns true if the IRSimilarityCandidates do not have overlapping
-  /// instructions.
-  LLVM_ABI static bool overlap(const IRSimilarityCandidate &A,
-                               const IRSimilarityCandidate &B);
-
-  /// \returns the number of instructions in this Candidate.
-  unsigned getLength() const { return Len; }
-
-  /// \returns the start index of this IRSimilarityCandidate.
-  unsigned getStartIdx() const { return StartIdx; }
-
-  /// \returns the end index of this IRSimilarityCandidate.
-  unsigned getEndIdx() const { return StartIdx + Len - 1; }
-
-  /// \returns The first IRInstructionData.
-  IRInstructionData *front() const { return FirstInst; }
-  /// \returns The last IRInstructionData.
-  IRInstructionData *back() const { return LastInst; }
-
-  /// \returns The first Instruction.
-  Instruction *frontInstruction() { return FirstInst->Inst; }
-  /// \returns The last Instruction
-  Instruction *backInstruction() { return LastInst->Inst; }
-
-  /// \returns The BasicBlock the IRSimilarityCandidate starts in.
-  BasicBlock *getStartBB() { return FirstInst->Inst->getParent(); }
-  /// \returns The BasicBlock the IRSimilarityCandidate ends in.
-  BasicBlock *getEndBB() { return LastInst->Inst->getParent(); }
-
-  /// \returns The Function that the IRSimilarityCandidate is located in.
-  Function *getFunction() { return getStartBB()->getParent(); }
-
-  /// Finds the positive number associated with \p V if it has been mapped.
-  /// \param [in] V - the Value to find.
-  /// \returns The positive number corresponding to the value.
-  /// \returns std::nullopt if not present.
-  std::optional<unsigned> getGVN(Value *V) {
-    assert(V != nullptr && "Value is a nullptr?");
-    auto VNIt = ValueToNumber.find(V);
-    if (VNIt == ValueToNumber.end())
-      return std::nullopt;
-    return VNIt->second;
-  }
-
-  /// Finds the Value associate with \p Num if it exists.
-  /// \param [in] Num - the number to find.
-  /// \returns The Value associated with the number.
-  /// \returns std::nullopt if not present.
-  std::optional<Value *> fromGVN(unsigned Num) {
-    auto VNIt = NumberToValue.find(Num);
-    if (VNIt == NumberToValue.end())
-      return std::nullopt;
-    assert(VNIt->second != nullptr && "Found value is a nullptr!");
-    return VNIt->second;
-  }
-
-  /// Find the canonical number from the global value number \p N stored in the
-  /// candidate.
-  ///
-  /// \param N - The global value number to find the canonical number for.
-  /// \returns An optional containing the value, and std::nullopt if it could
-  /// not be found.
-  std::optional<unsigned> getCanonicalNum(unsigned N) {
-    auto NCIt = NumberToCanonNum.find(N);
-    if (NCIt == NumberToCanonNum.end())
-      return std::nullopt;
-    return NCIt->second;
-  }
-
-  /// Find the global value number from the canonical number \p N stored in the
-  /// candidate.
-  ///
-  /// \param N - The canonical number to find the global vlaue number for.
-  /// \returns An optional containing the value, and std::nullopt if it could
-  /// not be found.
-  std::optional<unsigned> fromCanonicalNum(unsigned N) {
-    auto CNIt = CanonNumToNumber.find(N);
-    if (CNIt == CanonNumToNumber.end())
-      return std::nullopt;
-    return CNIt->second;
-  }
-
-  /// \param RHS -The IRSimilarityCandidate to compare against
-  /// \returns true if the IRSimilarityCandidate is occurs after the
-  /// IRSimilarityCandidate in the program.
-  bool operator<(const IRSimilarityCandidate &RHS) const {
-    return getStartIdx() > RHS.getStartIdx();
-  }
-
-  using iterator = IRInstructionDataList::iterator;
-  iterator begin() const { return iterator(front()); }
-  iterator end() const { return std::next(iterator(back())); }
-};
-
-typedef DenseMap<IRSimilarityCandidate *,
-                 DenseMap<unsigned, DenseSet<unsigned>>>
-    CandidateGVNMapping;
-typedef std::vector<IRSimilarityCandidate> SimilarityGroup;
-typedef std::vector<SimilarityGroup> SimilarityGroupList;
-
-/// This class puts all the pieces of the IRInstructionData,
-/// IRInstructionMapper, IRSimilarityCandidate together.
-///
-/// It first feeds the Module or vector of Modules into the IRInstructionMapper,
-/// and puts all the mapped instructions into a single long list of
-/// IRInstructionData.
-///
-/// The list of unsigned integers is given to the Suffix Tree or similar data
-/// structure to find repeated subsequences.  We construct an
-/// IRSimilarityCandidate for each instance of the subsequence.  We compare them
-/// against one another since  These repeated subsequences can have different
-/// structure.  For each different kind of structure found, we create a
-/// similarity group.
-///
-/// If we had four IRSimilarityCandidates A, B, C, and D where A, B and D are
-/// structurally similar to one another, while C is different we would have two
-/// SimilarityGroups:
-///
-/// SimilarityGroup 1:  SimilarityGroup 2
-/// A, B, D             C
-///
-/// A list of the different similarity groups is then returned after
-/// analyzing the module.
-class IRSimilarityIdentifier {
-public:
-  IRSimilarityIdentifier(bool MatchBranches = true,
-                         bool MatchIndirectCalls = true,
-                         bool MatchCallsWithName = false,
-                         bool MatchIntrinsics = true,
-                         bool MatchMustTailCalls = true)
-      : Mapper(&InstDataAllocator, &InstDataListAllocator),
-        EnableBranches(MatchBranches), EnableIndirectCalls(MatchIndirectCalls),
-        EnableMatchingCallsByName(MatchCallsWithName),
-        EnableIntrinsics(MatchIntrinsics),
-        EnableMustTailCalls(MatchMustTailCalls) {}
-
-private:
-  /// Map the instructions in the module to unsigned integers, using mapping
-  /// already present in the Mapper if possible.
-  ///
-  /// \param [in] M Module - To map to integers.
-  /// \param [in,out] InstrList - The vector to append IRInstructionData to.
-  /// \param [in,out] IntegerMapping - The vector to append integers to.
-  void populateMapper(Module &M, std::vector<IRInstructionData *> &InstrList,
-                      std::vector<unsigned> &IntegerMapping);
-
-  /// Map the instructions in the modules vector to unsigned integers, using
-  /// mapping already present in the mapper if possible.
-  ///
-  /// \param [in] Modules - The list of modules to use to populate the mapper
-  /// \param [in,out] InstrList - The vector to append IRInstructionData to.
-  /// \param [in,out] IntegerMapping - The vector to append integers to.
-  void populateMapper(ArrayRef<std::unique_ptr<Module>> &Modules,
-                      std::vector<IRInstructionData *> &InstrList,
-                      std::vector<unsigned> &IntegerMapping);
-
-  /// Find the similarity candidates in \p InstrList and corresponding
-  /// \p UnsignedVec
-  ///
-  /// \param [in,out] InstrList - The vector to append IRInstructionData to.
-  /// \param [in,out] IntegerMapping - The vector to append integers to.
-  /// candidates found in the program.
-  void findCandidates(std::vector<IRInstructionData *> &InstrList,
-                      std::vector<unsigned> &IntegerMapping);
-
-public:
-  // Find the IRSimilarityCandidates in the \p Modules and group by structural
-  // similarity in a SimilarityGroup, each group is returned in a
-  // SimilarityGroupList.
-  //
-  // \param [in] Modules - the modules to analyze.
-  // \returns The groups of similarity ranges found in the modules.
-  LLVM_ABI SimilarityGroupList &
-  findSimilarity(ArrayRef<std::unique_ptr<Module>> Modules);
-
-  // Find the IRSimilarityCandidates in the given Module grouped by structural
-  // similarity in a SimilarityGroup, contained inside a SimilarityGroupList.
-  //
-  // \param [in] M - the module to analyze.
-  // \returns The groups of similarity ranges found in the module.
-  LLVM_ABI SimilarityGroupList &findSimilarity(Module &M);
-
-  // Clears \ref SimilarityCandidates if it is already filled by a previous run.
-  void resetSimilarityCandidates() {
-    // If we've already analyzed a Module or set of Modules, so we must clear
-    // the SimilarityCandidates to make sure we do not have only old values
-    // hanging around.
-    if (SimilarityCandidates)
-      SimilarityCandidates->clear();
-    else
-      SimilarityCandidates = SimilarityGroupList();
-  }
-
-  // \returns The groups of similarity ranges found in the most recently passed
-  // set of modules.
-  std::optional<SimilarityGroupList> &getSimilarity() {
-    return SimilarityCandidates;
-  }
-
-private:
-  /// The allocator for IRInstructionData.
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-
-  /// The allocator for IRInstructionDataLists.
-  SpecificBumpPtrAllocator<IRInstructionDataList> InstDataListAllocator;
-
-  /// Map Instructions to unsigned integers and wraps the Instruction in an
-  /// instance of IRInstructionData.
-  IRInstructionMapper Mapper;
-
-  /// The flag variable that marks whether we should check branches for
-  /// similarity, or only look within basic blocks.
-  bool EnableBranches = true;
-
-  /// The flag variable that marks whether we allow indirect calls to be checked
-  /// for similarity, or exclude them as a legal instruction.
-  bool EnableIndirectCalls = true;
-
-  /// The flag variable that marks whether we allow calls to be marked as
-  /// similar if they do not have the same name, only the same calling
-  /// convention, attributes and type signature.
-  bool EnableMatchingCallsByName = true;
-
-  /// The flag variable that marks whether we should check intrinsics for
-  /// similarity.
-  bool EnableIntrinsics = true;
-
-  // The flag variable that marks whether we should allow tailcalls
-  // to be checked for similarity.
-  bool EnableMustTailCalls = false;
-
-  /// The SimilarityGroups found with the most recent run of \ref
-  /// findSimilarity. std::nullopt if there is no recent run.
-  std::optional<SimilarityGroupList> SimilarityCandidates;
-};
-
-} // end namespace IRSimilarity
-
-/// An analysis pass based on legacy pass manager that runs and returns
-/// IRSimilarityIdentifier run on the Module.
-class LLVM_ABI IRSimilarityIdentifierWrapperPass : public ModulePass {
-  std::unique_ptr<IRSimilarity::IRSimilarityIdentifier> IRSI;
-
-public:
-  static char ID;
-  IRSimilarityIdentifierWrapperPass();
-
-  IRSimilarity::IRSimilarityIdentifier &getIRSI() { return *IRSI; }
-  const IRSimilarity::IRSimilarityIdentifier &getIRSI() const { return *IRSI; }
-
-  bool doInitialization(Module &M) override;
-  bool doFinalization(Module &M) override;
-  bool runOnModule(Module &M) override;
-  void getAnalysisUsage(AnalysisUsage &AU) const override {
-    AU.setPreservesAll();
-  }
-};
-
-/// An analysis pass that runs and returns the IRSimilarityIdentifier run on the
-/// Module.
-class IRSimilarityAnalysis : public AnalysisInfoMixin<IRSimilarityAnalysis> {
-public:
-  typedef IRSimilarity::IRSimilarityIdentifier Result;
-
-  LLVM_ABI Result run(Module &M, ModuleAnalysisManager &);
-
-private:
-  friend AnalysisInfoMixin<IRSimilarityAnalysis>;
-  LLVM_ABI static AnalysisKey Key;
-};
-
-/// Printer pass that uses \c IRSimilarityAnalysis.
-class IRSimilarityAnalysisPrinterPass
-    : public RequiredPassInfoMixin<IRSimilarityAnalysisPrinterPass> {
-  raw_ostream &OS;
-
-public:
-  explicit IRSimilarityAnalysisPrinterPass(raw_ostream &OS) : OS(OS) {}
-  LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_ANALYSIS_IRSIMILARITYIDENTIFIER_H
diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h
index 55b54913d6d70..d80e02dcb356f 100644
--- a/llvm/include/llvm/InitializePasses.h
+++ b/llvm/include/llvm/InitializePasses.h
@@ -134,7 +134,6 @@ LLVM_ABI void initializeGlobalsAAWrapperPassPass(PassRegistry &);
 LLVM_ABI void initializeHardwareLoopsLegacyPass(PassRegistry &);
 LLVM_ABI void initializeLibcallLoweringInfoWrapperPass(PassRegistry &);
 LLVM_ABI void initializeMIRProfileLoaderPassPass(PassRegistry &);
-LLVM_ABI void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry &);
 LLVM_ABI void initializeIRTranslatorPass(PassRegistry &);
 LLVM_ABI void initializeIVUsersWrapperPassPass(PassRegistry &);
 LLVM_ABI void initializeIfConverterPass(PassRegistry &);
diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h
deleted file mode 100644
index e7cc728124a9a..0000000000000
--- a/llvm/include/llvm/Transforms/IPO/IROutliner.h
+++ /dev/null
@@ -1,469 +0,0 @@
-//===- IROutliner.h - Extract similar IR regions into functions --*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// The interface file for the IROutliner which is used by the IROutliner Pass.
-//
-// The outliner uses the IRSimilarityIdentifier to identify the similar regions
-// of code.  It evaluates each set of IRSimilarityCandidates with an estimate of
-// whether it will provide code size reduction.  Each region is extracted using
-// the code extractor.  These extracted functions are consolidated into a single
-// function and called from the extracted call site.
-//
-// For example:
-// \code
-//   %1 = add i32 %a, %b
-//   %2 = add i32 %b, %a
-//   %3 = add i32 %b, %a
-//   %4 = add i32 %a, %b
-// \endcode
-// would become function
-// \code
-// define internal void outlined_ir_function(i32 %0, i32 %1) {
-//   %1 = add i32 %0, %1
-//   %2 = add i32 %1, %0
-//   ret void
-// }
-// \endcode
-// with calls:
-// \code
-//   call void outlined_ir_function(i32 %a, i32 %b)
-//   call void outlined_ir_function(i32 %b, i32 %a)
-// \endcode
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_IPO_IROUTLINER_H
-#define LLVM_TRANSFORMS_IPO_IROUTLINER_H
-
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Support/InstructionCost.h"
-#include "llvm/Transforms/Utils/CodeExtractor.h"
-
-struct OutlinableGroup;
-
-namespace llvm {
-using namespace CallingConv;
-using namespace IRSimilarity;
-
-class Module;
-class TargetTransformInfo;
-class OptimizationRemarkEmitter;
-
-/// The OutlinableRegion holds all the information for a specific region, or
-/// sequence of instructions. This includes what values need to be hoisted to
-/// arguments from the extracted function, inputs and outputs to the region, and
-/// mapping from the extracted function arguments to overall function arguments.
-struct OutlinableRegion {
-  /// Describes the region of code.
-  IRSimilarityCandidate *Candidate = nullptr;
-
-  /// If this region is outlined, the front and back IRInstructionData could
-  /// potentially become invalidated if the only new instruction is a call.
-  /// This ensures that we replace in the instruction in the IRInstructionData.
-  IRInstructionData *NewFront = nullptr;
-  IRInstructionData *NewBack = nullptr;
-
-  /// The number of extracted inputs from the CodeExtractor.
-  unsigned NumExtractedInputs = 0;
-
-  /// The corresponding BasicBlock with the appropriate stores for this
-  /// OutlinableRegion in the overall function.
-  unsigned OutputBlockNum = -1;
-
-  /// Mapping the extracted argument number to the argument number in the
-  /// overall function.  Since there will be inputs, such as elevated constants
-  /// that are not the same in each region in a SimilarityGroup, or values that
-  /// cannot be sunk into the extracted section in every region, we must keep
-  /// track of which extracted argument maps to which overall argument.
-  DenseMap<unsigned, unsigned> ExtractedArgToAgg;
-  DenseMap<unsigned, unsigned> AggArgToExtracted;
-
-  /// Values in the outlined functions will often be replaced by arguments. When
-  /// finding corresponding values from one region to another, the found value
-  /// will be the value the argument previously replaced.  This structure maps
-  /// any replaced values for the region to the aggregate aggregate argument
-  /// in the overall function.
-  DenseMap<Value *, Value *> RemappedArguments;
-
-  /// Marks whether we need to change the order of the arguments when mapping
-  /// the old extracted function call to the new aggregate outlined function
-  /// call.
-  bool ChangedArgOrder = false;
-
-  /// Marks whether this region ends in a branch, there is special handling
-  /// required for the following basic blocks in this case.
-  bool EndsInBranch = false;
-
-  /// The PHIBlocks with their corresponding return block based on the return
-  /// value as the key.
-  DenseMap<Value *, BasicBlock *> PHIBlocks;
-
-  /// Mapping of the argument number in the deduplicated function
-  /// to a given constant, which is used when creating the arguments to the call
-  /// to the newly created deduplicated function.  This is handled separately
-  /// since the CodeExtractor does not recognize constants.
-  DenseMap<unsigned, Constant *> AggArgToConstant;
-
-  /// The global value numbers that are used as outputs for this section. Once
-  /// extracted, each output will be stored to an output register.  This
-  /// documents the global value numbers that are used in this pattern.
-  SmallVector<unsigned, 4> GVNStores;
-
-  /// Used to create an outlined function.
-  CodeExtractor *CE = nullptr;
-
-  /// The call site of the extracted region.
-  CallInst *Call = nullptr;
-
-  /// The function for the extracted region.
-  Function *ExtractedFunction = nullptr;
-
-  /// Flag for whether we have split out the IRSimilarityCanidate. That is,
-  /// make the region contained the IRSimilarityCandidate its own BasicBlock.
-  bool CandidateSplit = false;
-
-  /// Flag for whether we should not consider this region for extraction.
-  bool IgnoreRegion = false;
-
-  /// The BasicBlock that is before the start of the region BasicBlock,
-  /// only defined when the region has been split.
-  BasicBlock *PrevBB = nullptr;
-
-  /// The BasicBlock that contains the starting instruction of the region.
-  BasicBlock *StartBB = nullptr;
-
-  /// The BasicBlock that contains the ending instruction of the region.
-  BasicBlock *EndBB = nullptr;
-
-  /// The BasicBlock that is after the start of the region BasicBlock,
-  /// only defined when the region has been split.
-  BasicBlock *FollowBB = nullptr;
-
-  /// The Outlinable Group that contains this region and structurally similar
-  /// regions to this region.
-  OutlinableGroup *Parent = nullptr;
-
-  OutlinableRegion(IRSimilarityCandidate &C, OutlinableGroup &Group)
-      : Candidate(&C), Parent(&Group) {
-    StartBB = C.getStartBB();
-    EndBB = C.getEndBB();
-  }
-
-  /// For the contained region, split the parent BasicBlock at the starting and
-  /// ending instructions of the contained IRSimilarityCandidate.
-  LLVM_ABI void splitCandidate();
-
-  /// For the contained region, reattach the BasicBlock at the starting and
-  /// ending instructions of the contained IRSimilarityCandidate, or if the
-  /// function has been extracted, the start and end of the BasicBlock
-  /// containing the called function.
-  LLVM_ABI void reattachCandidate();
-
-  /// Find a corresponding value for \p V in similar OutlinableRegion \p Other.
-  ///
-  /// \param Other [in] - The OutlinableRegion to find the corresponding Value
-  /// in.
-  /// \param V [in] - The Value to look for in the other region.
-  /// \return The corresponding Value to \p V if it exists, otherwise nullptr.
-  LLVM_ABI Value *findCorrespondingValueIn(const OutlinableRegion &Other,
-                                           Value *V);
-
-  /// Find a corresponding BasicBlock for \p BB in similar OutlinableRegion \p Other.
-  ///
-  /// \param Other [in] - The OutlinableRegion to find the corresponding
-  /// BasicBlock in.
-  /// \param BB [in] - The BasicBlock to look for in the other region.
-  /// \return The corresponding Value to \p V if it exists, otherwise nullptr.
-  LLVM_ABI BasicBlock *findCorrespondingBlockIn(const OutlinableRegion &Other,
-                                                BasicBlock *BB);
-
-  /// Get the size of the code removed from the region.
-  ///
-  /// \param [in] TTI - The TargetTransformInfo for the parent function.
-  /// \returns the code size of the region
-  LLVM_ABI InstructionCost getBenefit(TargetTransformInfo &TTI);
-};
-
-/// This class is a pass that identifies similarity in a Module, extracts
-/// instances of the similarity, and then consolidating the similar regions
-/// in an effort to reduce code size.  It uses the IRSimilarityIdentifier pass
-/// to identify the similar regions of code, and then extracts the similar
-/// sections into a single function.  See the above for an example as to
-/// how code is extracted and consolidated into a single function.
-class IROutliner {
-public:
-  IROutliner(function_ref<TargetTransformInfo &(Function &)> GTTI,
-             function_ref<IRSimilarityIdentifier &(Module &)> GIRSI,
-             function_ref<OptimizationRemarkEmitter &(Function &)> GORE)
-      : getTTI(GTTI), getIRSI(GIRSI), getORE(GORE) {}
-  LLVM_ABI bool run(Module &M);
-
-private:
-  /// Find repeated similar code sequences in \p M and outline them into new
-  /// Functions.
-  ///
-  /// \param [in] M - The module to outline from.
-  /// \returns The number of Functions created.
-  unsigned doOutline(Module &M);
-
-  /// Check whether an OutlinableRegion is incompatible with code already
-  /// outlined. OutlinableRegions are incomptaible when there are overlapping
-  /// instructions, or code that has not been recorded has been added to the
-  /// instructions.
-  ///
-  /// \param [in] Region - The OutlinableRegion to check for conflicts with
-  /// already outlined code.
-  /// \returns whether the region can safely be outlined.
-  bool isCompatibleWithAlreadyOutlinedCode(const OutlinableRegion &Region);
-
-  /// Remove all the IRSimilarityCandidates from \p CandidateVec that have
-  /// instructions contained in a previously outlined region and put the
-  /// remaining regions in \p CurrentGroup.
-  ///
-  /// \param [in] CandidateVec - List of similarity candidates for regions with
-  /// the same similarity structure.
-  /// \param [in,out] CurrentGroup - Contains the potential sections to
-  /// be outlined.
-  void
-  pruneIncompatibleRegions(std::vector<IRSimilarityCandidate> &CandidateVec,
-                           OutlinableGroup &CurrentGroup);
-
-  /// Create the function based on the overall types found in the current
-  /// regions being outlined.
-  ///
-  /// \param M - The module to outline from.
-  /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined.
-  /// \param [in] FunctionNameSuffix - How many functions have we previously
-  /// created.
-  /// \returns the newly created function.
-  Function *createFunction(Module &M, OutlinableGroup &CG,
-                           unsigned FunctionNameSuffix);
-
-  /// Identify the needed extracted inputs in a section, and add to the overall
-  /// function if needed.
-  ///
-  /// \param [in] M - The module to outline from.
-  /// \param [in,out] Region - The region to be extracted.
-  /// \param [in] NotSame - The global value numbers of the Values in the region
-  /// that do not have the same Constant in each strucutrally similar region.
-  void findAddInputsOutputs(Module &M, OutlinableRegion &Region,
-                            DenseSet<unsigned> &NotSame);
-
-  /// Find the number of instructions that will be removed by extracting the
-  /// OutlinableRegions in \p CurrentGroup.
-  ///
-  /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
-  /// analyzed.
-  /// \returns the number of outlined instructions across all regions.
-  InstructionCost findBenefitFromAllRegions(OutlinableGroup &CurrentGroup);
-
-  /// Find the number of instructions that will be added by reloading arguments.
-  ///
-  /// \param [in] CurrentGroup - The collection of OutlinableRegions to be
-  /// analyzed.
-  /// \returns the number of added reload instructions across all regions.
-  InstructionCost findCostOutputReloads(OutlinableGroup &CurrentGroup);
-
-  /// Find the cost and the benefit of \p CurrentGroup and save it back to
-  /// \p CurrentGroup.
-  ///
-  /// \param [in] M - The module being analyzed
-  /// \param [in,out] CurrentGroup - The overall outlined section
-  void findCostBenefit(Module &M, OutlinableGroup &CurrentGroup);
-
-  /// Update the output mapping based on the load instruction, and the outputs
-  /// of the extracted function.
-  ///
-  /// \param Region - The region extracted
-  /// \param Outputs - The outputs from the extracted function.
-  /// \param LI - The load instruction used to update the mapping.
-  void updateOutputMapping(OutlinableRegion &Region,
-                           ArrayRef<Value *> Outputs, LoadInst *LI);
-
-  /// Extract \p Region into its own function.
-  ///
-  /// \param [in] Region - The region to be extracted into its own function.
-  /// \returns True if it was successfully outlined.
-  bool extractSection(OutlinableRegion &Region);
-
-  /// For the similarities found, and the extracted sections, create a single
-  /// outlined function with appropriate output blocks as necessary.
-  ///
-  /// \param [in] M - The module to outline from
-  /// \param [in] CurrentGroup - The set of extracted sections to consolidate.
-  /// \param [in,out] FuncsToRemove - List of functions to remove from the
-  /// module after outlining is completed.
-  /// \param [in,out] OutlinedFunctionNum - the number of new outlined
-  /// functions.
-  void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup,
-                                    std::vector<Function *> &FuncsToRemove,
-                                    unsigned &OutlinedFunctionNum);
-
-  /// Fill the new function that will serve as the replacement function for all
-  /// of the extracted regions of a certain structure from the first region in
-  /// the list of regions.  Replace this first region's extracted function with
-  /// the new overall function.
-  ///
-  /// \param [in] M - The module we are outlining from.
-  /// \param [in] CurrentGroup - The group of regions to be outlined.
-  /// \param [in,out] OutputStoreBBs - The output blocks for each different
-  /// set of stores needed for the different functions.
-  /// \param [in,out] FuncsToRemove - Extracted functions to erase from module
-  /// once outlining is complete.
-  void fillOverallFunction(
-      Module &M, OutlinableGroup &CurrentGroup,
-      std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs,
-      std::vector<Function *> &FuncsToRemove);
-
-  /// If true, enables us to outline from functions that have LinkOnceFromODR
-  /// linkages.
-  bool OutlineFromLinkODRs = false;
-
-  /// If false, we do not worry if the cost is greater than the benefit.  This
-  /// is for debugging and testing, so that we can test small cases to ensure
-  /// that the outlining is being done correctly.
-  bool CostModel = true;
-
-  /// The set of outlined Instructions, identified by their location in the
-  /// sequential ordering of instructions in a Module.
-  DenseSet<unsigned> Outlined;
-
-  /// TargetTransformInfo lambda for target specific information.
-  function_ref<TargetTransformInfo &(Function &)> getTTI;
-
-  /// A mapping from newly created reloaded output values to the original value.
-  /// If an value is replace by an output from an outlined region, this maps
-  /// that Value, back to its original Value.
-  DenseMap<Value *, Value *> OutputMappings;
-
-  /// IRSimilarityIdentifier lambda to retrieve IRSimilarityIdentifier.
-  function_ref<IRSimilarityIdentifier &(Module &)> getIRSI;
-
-  /// The optimization remark emitter for the pass.
-  function_ref<OptimizationRemarkEmitter &(Function &)> getORE;
-
-  /// The memory allocator used to allocate the CodeExtractors.
-  SpecificBumpPtrAllocator<CodeExtractor> ExtractorAllocator;
-
-  /// The memory allocator used to allocate the OutlinableRegions.
-  SpecificBumpPtrAllocator<OutlinableRegion> RegionAllocator;
-
-  /// The memory allocator used to allocate new IRInstructionData.
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-
-  /// Custom InstVisitor to classify different instructions for whether it can
-  /// be analyzed for similarity.  This is needed as there may be instruction we
-  /// can identify as having similarity, but are more complicated to outline.
-  struct InstructionAllowed : public InstVisitor<InstructionAllowed, bool> {
-    InstructionAllowed() = default;
-
-    bool visitUncondBrInst(UncondBrInst &BI) { return EnableBranches; }
-    bool visitCondBrInst(CondBrInst &BI) { return EnableBranches; }
-    bool visitPHINode(PHINode &PN) { return EnableBranches; }
-    // TODO: Handle allocas.
-    bool visitAllocaInst(AllocaInst &AI) { return false; }
-    // VAArg instructions are not allowed since this could cause difficulty when
-    // differentiating between different sets of variable instructions in
-    // the deduplicated outlined regions.
-    bool visitVAArgInst(VAArgInst &VI) { return false; }
-    // We exclude all exception handling cases since they are so context
-    // dependent.
-    bool visitLandingPadInst(LandingPadInst &LPI) { return false; }
-    bool visitFuncletPadInst(FuncletPadInst &FPI) { return false; }
-    // DebugInfo should be included in the regions, but should not be
-    // analyzed for similarity as it has no bearing on the outcome of the
-    // program.
-    bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return true; }
-    // TODO: Handle specific intrinsics individually from those that can be
-    // handled.
-    bool IntrinsicInst(IntrinsicInst &II) { return EnableIntrinsics; }
-    // We only handle CallInsts that are not indirect, since we cannot guarantee
-    // that they have a name in these cases.
-    bool visitCallInst(CallInst &CI) {
-      Function *F = CI.getCalledFunction();
-      bool IsIndirectCall = CI.isIndirectCall();
-      if (IsIndirectCall && !EnableIndirectCalls)
-        return false;
-      if (!F && !IsIndirectCall)
-        return false;
-      // Returning twice can cause issues with the state of the function call
-      // that were not expected when the function was used, so we do not include
-      // the call in outlined functions.
-      if (CI.canReturnTwice())
-        return false;
-      // TODO: Update the outliner to capture whether the outlined function
-      // needs these extra attributes.
-
-      // `nomerge` states that calls to this function should never be merged
-      // during optimisation. Outlining would have the effect of merging
-      // callsites from separate functions into a single callsite in the
-      // outlined function.
-      if (CI.hasFnAttr(Attribute::NoMerge))
-        return false;
-
-      // Functions marked with the swifttailcc and tailcc calling conventions
-      // require special handling when outlining musttail functions.  The
-      // calling convention must be passed down to the outlined function as
-      // well. Further, there is special handling for musttail calls as well,
-      // requiring a return call directly after.  For now, the outliner does not
-      // support this.
-      bool IsTailCC = CI.getCallingConv() == CallingConv::SwiftTail ||
-                      CI.getCallingConv() == CallingConv::Tail;
-      if (IsTailCC && !EnableMustTailCalls)
-        return false;
-      if (CI.isMustTailCall() && !EnableMustTailCalls)
-        return false;
-      // The outliner can only handle musttail items if it is also accompanied
-      // by the tailcc or swifttailcc calling convention.
-      if (CI.isMustTailCall() && !IsTailCC)
-        return false;
-      return true;
-    }
-    // TODO: Handle FreezeInsts.  Since a frozen value could be frozen inside
-    // the outlined region, and then returned as an output, this will have to be
-    // handled differently.
-    bool visitFreezeInst(FreezeInst &CI) { return false; }
-    // TODO: We do not current handle similarity that changes the control flow.
-    bool visitInvokeInst(InvokeInst &II) { return false; }
-    // TODO: We do not current handle similarity that changes the control flow.
-    bool visitCallBrInst(CallBrInst &CBI) { return false; }
-    // TODO: Handle interblock similarity.
-    bool visitTerminator(Instruction &I) { return false; }
-    bool visitInstruction(Instruction &I) { return true; }
-
-    // The flag variable that marks whether we should allow branch instructions
-    // to be outlined.
-    bool EnableBranches = false;
-
-    // The flag variable that marks whether we should allow indirect calls
-    // to be outlined.
-    bool EnableIndirectCalls = true;
-
-    // The flag variable that marks whether we should allow intrinsics
-    // instructions to be outlined.
-    bool EnableIntrinsics = false;
-
-    // The flag variable that marks whether we should allow musttail calls.
-    bool EnableMustTailCalls = false;
-  };
-
-  /// A InstVisitor used to exclude certain instructions from being outlined.
-  InstructionAllowed InstructionClassifier;
-};
-
-/// Pass to outline similar regions.
-class IROutlinerPass : public OptionalPassInfoMixin<IROutlinerPass> {
-public:
-  LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
-};
-
-} // end namespace llvm
-
-#endif // LLVM_TRANSFORMS_IPO_IROUTLINER_H
diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp
index aaac2cf187281..0e978723ad52a 100644
--- a/llvm/lib/Analysis/Analysis.cpp
+++ b/llvm/lib/Analysis/Analysis.cpp
@@ -46,7 +46,6 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
   initializeExternalAAWrapperPassPass(Registry);
   initializeImmutableModuleSummaryIndexWrapperPassPass(Registry);
   initializeIVUsersWrapperPassPass(Registry);
-  initializeIRSimilarityIdentifierWrapperPassPass(Registry);
   initializeLazyBranchProbabilityInfoPassPass(Registry);
   initializeLazyBFIPassPass(Registry);
   initializeLazyBlockFrequencyInfoPassPass(Registry);
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index f3586c66cb056..aecea1bb92a1f 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -85,7 +85,6 @@ add_llvm_component_library(LLVMAnalysis
   HashRecognize.cpp
   HeatUtils.cpp
   IR2Vec.cpp
-  IRSimilarityIdentifier.cpp
   IVDescriptors.cpp
   IVUsers.cpp
   ImportedFunctionsInliningStatistics.cpp
diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp
deleted file mode 100644
index 256835bdba474..0000000000000
--- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp
+++ /dev/null
@@ -1,1519 +0,0 @@
-//===- IRSimilarityIdentifier.cpp - Find similarity in a module -----------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// \file
-// Implementation file for the IRSimilarityIdentifier for identifying
-// similarities in IR including the IRInstructionMapper.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SetOperations.h"
-#include "llvm/IR/Intrinsics.h"
-#include "llvm/IR/Operator.h"
-#include "llvm/IR/User.h"
-#include "llvm/InitializePasses.h"
-#include "llvm/Support/SuffixTree.h"
-
-using namespace llvm;
-using namespace IRSimilarity;
-
-namespace llvm {
-cl::opt<bool>
-    DisableBranches("no-ir-sim-branch-matching", cl::init(false),
-                    cl::ReallyHidden,
-                    cl::desc("disable similarity matching, and outlining, "
-                             "across branches for debugging purposes."));
-
-cl::opt<bool>
-    DisableIndirectCalls("no-ir-sim-indirect-calls", cl::init(false),
-                         cl::ReallyHidden,
-                         cl::desc("disable outlining indirect calls."));
-
-static cl::opt<bool>
-    MatchCallsByName("ir-sim-calls-by-name", cl::init(false), cl::ReallyHidden,
-                     cl::desc("only allow matching call instructions if the "
-                              "name and type signature match."));
-
-cl::opt<bool>
-    DisableIntrinsics("no-ir-sim-intrinsics", cl::init(false), cl::ReallyHidden,
-                      cl::desc("Don't match or outline intrinsics"));
-} // namespace llvm
-
-IRInstructionData::IRInstructionData(Instruction &I, bool Legality,
-                                     IRInstructionDataList &IDList)
-    : Inst(&I), Legal(Legality), IDL(&IDList) {
-  initializeInstruction();
-}
-
-void IRInstructionData::initializeInstruction() {
-  // We check for whether we have a comparison instruction.  If it is, we
-  // find the "less than" version of the predicate for consistency for
-  // comparison instructions throught the program.
-  if (CmpInst *C = dyn_cast<CmpInst>(Inst)) {
-    CmpInst::Predicate Predicate = predicateForConsistency(C);
-    if (Predicate != C->getPredicate())
-      RevisedPredicate = Predicate;
-  }
-
-  // Here we collect the operands and their types for determining whether
-  // the structure of the operand use matches between two different candidates.
-  for (Use &OI : Inst->operands()) {
-    if (isa<CmpInst>(Inst) && RevisedPredicate) {
-      // If we have a CmpInst where the predicate is reversed, it means the
-      // operands must be reversed as well.
-      OperVals.insert(OperVals.begin(), OI.get());
-      continue;
-    }
-
-    OperVals.push_back(OI.get());
-  }
-
-  // We capture the incoming BasicBlocks as values as well as the incoming
-  // Values in order to check for structural similarity.
-  if (PHINode *PN = dyn_cast<PHINode>(Inst))
-    llvm::append_range(OperVals, PN->blocks());
-}
-
-IRInstructionData::IRInstructionData(IRInstructionDataList &IDList)
-    : IDL(&IDList) {}
-
-void IRInstructionData::setBranchSuccessors(
-    DenseMap<BasicBlock *, unsigned> &BasicBlockToInteger) {
-  assert((isa<UncondBrInst, CondBrInst>(Inst)) && "Instruction must be branch");
-
-  DenseMap<BasicBlock *, unsigned>::iterator BBNumIt;
-
-  BBNumIt = BasicBlockToInteger.find(Inst->getParent());
-  assert(BBNumIt != BasicBlockToInteger.end() &&
-         "Could not find location for BasicBlock!");
-
-  int CurrentBlockNumber = static_cast<int>(BBNumIt->second);
-
-  for (Value *V : getBlockOperVals()) {
-    BasicBlock *Successor = cast<BasicBlock>(V);
-    BBNumIt = BasicBlockToInteger.find(Successor);
-    assert(BBNumIt != BasicBlockToInteger.end() &&
-           "Could not find number for BasicBlock!");
-    int OtherBlockNumber = static_cast<int>(BBNumIt->second);
-
-    int Relative = OtherBlockNumber - CurrentBlockNumber;
-    RelativeBlockLocations.push_back(Relative);
-  }
-}
-
-ArrayRef<Value *> IRInstructionData::getBlockOperVals() {
-  if (isa<UncondBrInst>(Inst))
-    return OperVals;
-  if (isa<CondBrInst>(Inst))
-    return ArrayRef<Value *>(OperVals).drop_front(1);
-
-  if (PHINode *PN = dyn_cast<PHINode>(Inst))
-    return ArrayRef<Value *>(
-      std::next(OperVals.begin(), PN->getNumIncomingValues()),
-      OperVals.end()
-    );
-
-  llvm_unreachable("Instruction must be branch or PHINode");
-}
-
-void IRInstructionData::setCalleeName(bool MatchByName) {
-  CallInst *CI = dyn_cast<CallInst>(Inst);
-  assert(CI && "Instruction must be call");
-
-  CalleeName = "";
-  if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(Inst)) {
-    // To hash intrinsics, we use the opcode, and types like the other
-    // instructions, but also, the Intrinsic ID, and the Name of the
-    // intrinsic.
-    Intrinsic::ID IntrinsicID = II->getIntrinsicID();
-    FunctionType *FT = II->getFunctionType();
-    // If there is an overloaded name, we have to use the complex version
-    // of getName to get the entire string.
-    if (Intrinsic::isOverloaded(IntrinsicID))
-      CalleeName =
-          Intrinsic::getName(IntrinsicID, FT->params(), II->getModule(), FT);
-    // If there is not an overloaded name, we only need to use this version.
-    else
-      CalleeName = Intrinsic::getName(IntrinsicID).str();
-
-    return;
-  }
-
-  if (!CI->isIndirectCall() && MatchByName)
-    CalleeName = CI->getCalledFunction()->getName().str();
-}
-
-void IRInstructionData::setPHIPredecessors(
-    DenseMap<BasicBlock *, unsigned> &BasicBlockToInteger) {
-  assert(isa<PHINode>(Inst) && "Instruction must be phi node");
-
-  PHINode *PN = cast<PHINode>(Inst);
-  DenseMap<BasicBlock *, unsigned>::iterator BBNumIt;
-
-  BBNumIt = BasicBlockToInteger.find(PN->getParent());
-  assert(BBNumIt != BasicBlockToInteger.end() &&
-         "Could not find location for BasicBlock!");
-
-  int CurrentBlockNumber = static_cast<int>(BBNumIt->second);
-
-  // Convert the incoming blocks of the PHINode to an integer value, based on
-  // the relative distances between the current block and the incoming block.
-  for (unsigned Idx = 0; Idx < PN->getNumIncomingValues(); Idx++) {
-    BasicBlock *Incoming = PN->getIncomingBlock(Idx);
-    BBNumIt = BasicBlockToInteger.find(Incoming);
-    assert(BBNumIt != BasicBlockToInteger.end() &&
-           "Could not find number for BasicBlock!");
-    int OtherBlockNumber = static_cast<int>(BBNumIt->second);
-
-    int Relative = OtherBlockNumber - CurrentBlockNumber;
-    RelativeBlockLocations.push_back(Relative);
-  }
-}
-
-CmpInst::Predicate IRInstructionData::predicateForConsistency(CmpInst *CI) {
-  switch (CI->getPredicate()) {
-  case CmpInst::FCMP_OGT:
-  case CmpInst::FCMP_UGT:
-  case CmpInst::FCMP_OGE:
-  case CmpInst::FCMP_UGE:
-  case CmpInst::ICMP_SGT:
-  case CmpInst::ICMP_UGT:
-  case CmpInst::ICMP_SGE:
-  case CmpInst::ICMP_UGE:
-    return CI->getSwappedPredicate();
-  default:
-    return CI->getPredicate();
-  }
-}
-
-CmpInst::Predicate IRInstructionData::getPredicate() const {
-  assert(isa<CmpInst>(Inst) &&
-         "Can only get a predicate from a compare instruction");
-
-  if (RevisedPredicate)
-    return *RevisedPredicate;
-
-  return cast<CmpInst>(Inst)->getPredicate();
-}
-
-StringRef IRInstructionData::getCalleeName() const {
-  assert(isa<CallInst>(Inst) &&
-         "Can only get a name from a call instruction");
-
-  assert(CalleeName && "CalleeName has not been set");
-
-  return *CalleeName;
-}
-
-bool IRSimilarity::isClose(const IRInstructionData &A,
-                           const IRInstructionData &B) {
-
-  if (!A.Legal || !B.Legal)
-    return false;
-
-  // Check if we are performing the same sort of operation on the same types
-  // but not on the same values.
-  if (!A.Inst->isSameOperationAs(B.Inst)) {
-    // If there is a predicate, this means that either there is a swapped
-    // predicate, or that the types are different, we want to make sure that
-    // the predicates are equivalent via swapping.
-    if (isa<CmpInst>(A.Inst) && isa<CmpInst>(B.Inst)) {
-
-      if (A.getPredicate() != B.getPredicate())
-        return false;
-
-      // If the predicates are the same via swap, make sure that the types are
-      // still the same.
-      auto ZippedTypes = zip(A.OperVals, B.OperVals);
-
-      return all_of(
-          ZippedTypes, [](std::tuple<llvm::Value *, llvm::Value *> R) {
-            return std::get<0>(R)->getType() == std::get<1>(R)->getType();
-          });
-    }
-
-    return false;
-  }
-
-  // Since any GEP Instruction operands after the first operand cannot be
-  // defined by a register, we must make sure that the operands after the first
-  // are the same in the two instructions
-  if (auto *GEP = dyn_cast<GetElementPtrInst>(A.Inst)) {
-    auto *OtherGEP = cast<GetElementPtrInst>(B.Inst);
-
-    // If the instructions do not have the same inbounds restrictions, we do
-    // not consider them the same.
-    if (GEP->isInBounds() != OtherGEP->isInBounds())
-      return false;
-
-    auto ZippedOperands = zip(GEP->indices(), OtherGEP->indices());
-
-    // We increment here since we do not care about the first instruction,
-    // we only care about the following operands since they must be the
-    // exact same to be considered similar.
-    return all_of(drop_begin(ZippedOperands),
-                  [](std::tuple<llvm::Use &, llvm::Use &> R) {
-                    return std::get<0>(R) == std::get<1>(R);
-                  });
-  }
-
-  // If the instructions are functions calls, we make sure that the function
-  // name is the same.  We already know that the types are since is
-  // isSameOperationAs is true.
-  if (isa<CallInst>(A.Inst) && isa<CallInst>(B.Inst)) {
-    if (A.getCalleeName() != B.getCalleeName())
-      return false;
-  }
-
-  if (isa<UncondBrInst, CondBrInst>(A.Inst) &&
-      isa<UncondBrInst, CondBrInst>(B.Inst) &&
-      A.RelativeBlockLocations.size() != B.RelativeBlockLocations.size())
-    return false;
-
-  return true;
-}
-
-// TODO: This is the same as the MachineOutliner, and should be consolidated
-// into the same interface.
-void IRInstructionMapper::convertToUnsignedVec(
-    BasicBlock &BB, std::vector<IRInstructionData *> &InstrList,
-    std::vector<unsigned> &IntegerMapping) {
-  BasicBlock::iterator It = BB.begin();
-
-  std::vector<unsigned> IntegerMappingForBB;
-  std::vector<IRInstructionData *> InstrListForBB;
-
-  for (BasicBlock::iterator Et = BB.end(); It != Et; ++It) {
-    switch (InstClassifier.visit(*It)) {
-    case InstrType::Legal:
-      mapToLegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
-      break;
-    case InstrType::Illegal:
-      mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB);
-      break;
-    case InstrType::Invisible:
-      AddedIllegalLastTime = false;
-      break;
-    }
-  }
-
-  if (AddedIllegalLastTime)
-    mapToIllegalUnsigned(It, IntegerMappingForBB, InstrListForBB, true);
-  for (IRInstructionData *ID : InstrListForBB)
-    this->IDL->push_back(*ID);
-  llvm::append_range(InstrList, InstrListForBB);
-  llvm::append_range(IntegerMapping, IntegerMappingForBB);
-}
-
-// TODO: This is the same as the MachineOutliner, and should be consolidated
-// into the same interface.
-unsigned IRInstructionMapper::mapToLegalUnsigned(
-    BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
-    std::vector<IRInstructionData *> &InstrListForBB) {
-  // We added something legal, so we should unset the AddedLegalLastTime
-  // flag.
-  AddedIllegalLastTime = false;
-
-  // If we have at least two adjacent legal instructions (which may have
-  // invisible instructions in between), remember that.
-  if (CanCombineWithPrevInstr)
-    HaveLegalRange = true;
-  CanCombineWithPrevInstr = true;
-
-  // Get the integer for this instruction or give it the current
-  // LegalInstrNumber.
-  IRInstructionData *ID = allocateIRInstructionData(*It, true, *IDL);
-  InstrListForBB.push_back(ID);
-
-  if (isa<UncondBrInst, CondBrInst>(*It))
-    ID->setBranchSuccessors(BasicBlockToInteger);
-
-  if (isa<CallInst>(*It))
-    ID->setCalleeName(EnableMatchCallsByName);
-
-  if (isa<PHINode>(*It))
-    ID->setPHIPredecessors(BasicBlockToInteger);
-
-  // Add to the instruction list
-  bool WasInserted;
-  DenseMap<IRInstructionData *, unsigned, IRInstructionDataTraits>::iterator
-      ResultIt;
-  std::tie(ResultIt, WasInserted) =
-      InstructionIntegerMap.insert(std::make_pair(ID, LegalInstrNumber));
-  unsigned INumber = ResultIt->second;
-
-  // There was an insertion.
-  if (WasInserted)
-    LegalInstrNumber++;
-
-  IntegerMappingForBB.push_back(INumber);
-
-  // Make sure we don't overflow or use any integers reserved by the DenseMap.
-  assert(LegalInstrNumber < IllegalInstrNumber &&
-         "Instruction mapping overflow!");
-
-  return INumber;
-}
-
-IRInstructionData *
-IRInstructionMapper::allocateIRInstructionData(Instruction &I, bool Legality,
-                                               IRInstructionDataList &IDL) {
-  return new (InstDataAllocator->Allocate()) IRInstructionData(I, Legality, IDL);
-}
-
-IRInstructionData *
-IRInstructionMapper::allocateIRInstructionData(IRInstructionDataList &IDL) {
-  return new (InstDataAllocator->Allocate()) IRInstructionData(IDL);
-}
-
-IRInstructionDataList *
-IRInstructionMapper::allocateIRInstructionDataList() {
-  return new (IDLAllocator->Allocate()) IRInstructionDataList();
-}
-
-// TODO: This is the same as the MachineOutliner, and should be consolidated
-// into the same interface.
-unsigned IRInstructionMapper::mapToIllegalUnsigned(
-    BasicBlock::iterator &It, std::vector<unsigned> &IntegerMappingForBB,
-    std::vector<IRInstructionData *> &InstrListForBB, bool End) {
-  // Can't combine an illegal instruction. Set the flag.
-  CanCombineWithPrevInstr = false;
-
-  // Only add one illegal number per range of legal numbers.
-  if (AddedIllegalLastTime)
-    return IllegalInstrNumber;
-
-  IRInstructionData *ID = nullptr;
-  if (!End)
-    ID = allocateIRInstructionData(*It, false, *IDL);
-  else
-    ID = allocateIRInstructionData(*IDL);
-  InstrListForBB.push_back(ID);
-
-  // Remember that we added an illegal number last time.
-  AddedIllegalLastTime = true;
-  unsigned INumber = IllegalInstrNumber;
-  IntegerMappingForBB.push_back(IllegalInstrNumber--);
-
-  assert(LegalInstrNumber < IllegalInstrNumber &&
-         "Instruction mapping overflow!");
-
-  return INumber;
-}
-
-IRSimilarityCandidate::IRSimilarityCandidate(unsigned StartIdx, unsigned Len,
-                                             IRInstructionData *FirstInstIt,
-                                             IRInstructionData *LastInstIt)
-    : StartIdx(StartIdx), Len(Len) {
-
-  assert(FirstInstIt != nullptr && "Instruction is nullptr!");
-  assert(LastInstIt != nullptr && "Instruction is nullptr!");
-  assert(StartIdx + Len > StartIdx &&
-         "Overflow for IRSimilarityCandidate range?");
-  assert(Len - 1 == static_cast<unsigned>(std::distance(
-                        iterator(FirstInstIt), iterator(LastInstIt))) &&
-         "Length of the first and last IRInstructionData do not match the "
-         "given length");
-
-  // We iterate over the given instructions, and map each unique value
-  // to a unique number in the IRSimilarityCandidate ValueToNumber and
-  // NumberToValue maps.  A constant get its own value globally, the individual
-  // uses of the constants are not considered to be unique.
-  //
-  // IR:                    Mapping Added:
-  // %add1 = add i32 %a, c1    %add1 -> 3, %a -> 1, c1 -> 2
-  // %add2 = add i32 %a, %1    %add2 -> 4
-  // %add3 = add i32 c2, c1    %add3 -> 6, c2 -> 5
-  //
-  // when replace with global values, starting from 1, would be
-  //
-  // 3 = add i32 1, 2
-  // 4 = add i32 1, 3
-  // 6 = add i32 5, 2
-  unsigned LocalValNumber = 1;
-  IRInstructionDataList::iterator ID = iterator(*FirstInstIt);
-  for (unsigned Loc = StartIdx; Loc < StartIdx + Len; Loc++, ID++) {
-    // Map the operand values to an unsigned integer if it does not already
-    // have an unsigned integer assigned to it.
-    for (Value *Arg : ID->OperVals)
-      if (ValueToNumber.try_emplace(Arg, LocalValNumber).second) {
-        NumberToValue.try_emplace(LocalValNumber, Arg);
-        LocalValNumber++;
-      }
-
-    // Mapping the instructions to an unsigned integer if it is not already
-    // exist in the mapping.
-    if (ValueToNumber.try_emplace(ID->Inst, LocalValNumber).second) {
-      NumberToValue.try_emplace(LocalValNumber, ID->Inst);
-      LocalValNumber++;
-    }
-  }
-
-  // Setting the first and last instruction data pointers for the candidate.  If
-  // we got through the entire for loop without hitting an assert, we know
-  // that both of these instructions are not nullptrs.
-  FirstInst = FirstInstIt;
-  LastInst = LastInstIt;
-
-  // Add the basic blocks contained in the set into the global value numbering.
-  DenseSet<BasicBlock *> BBSet;
-  getBasicBlocks(BBSet);
-  for (BasicBlock *BB : BBSet) {
-    if (ValueToNumber.try_emplace(BB, LocalValNumber).second) {
-      NumberToValue.try_emplace(LocalValNumber, BB);
-      LocalValNumber++;
-    }
-  }
-}
-
-bool IRSimilarityCandidate::isSimilar(const IRSimilarityCandidate &A,
-                                      const IRSimilarityCandidate &B) {
-  if (A.getLength() != B.getLength())
-    return false;
-
-  auto InstrDataForBoth =
-      zip(make_range(A.begin(), A.end()), make_range(B.begin(), B.end()));
-
-  return all_of(InstrDataForBoth,
-                [](std::tuple<IRInstructionData &, IRInstructionData &> R) {
-                  IRInstructionData &A = std::get<0>(R);
-                  IRInstructionData &B = std::get<1>(R);
-                  if (!A.Legal || !B.Legal)
-                    return false;
-                  return isClose(A, B);
-                });
-}
-
-/// Determine if one or more of the assigned global value numbers for the
-/// operands in \p TargetValueNumbers is in the current mapping set for operand
-/// numbers in \p SourceOperands.  The set of possible corresponding global
-/// value numbers are replaced with the most recent version of compatible
-/// values.
-///
-/// \param [in] SourceValueToNumberMapping - The mapping of a Value to global
-/// value number for the source IRInstructionCandidate.
-/// \param [in, out] CurrentSrcTgtNumberMapping - The current mapping of source
-/// IRSimilarityCandidate global value numbers to a set of possible numbers in
-/// the target.
-/// \param [in] SourceOperands - The operands in the original
-/// IRSimilarityCandidate in the current instruction.
-/// \param [in] TargetValueNumbers - The global value numbers of the operands in
-/// the corresponding Instruction in the other IRSimilarityCandidate.
-/// \returns true if there exists a possible mapping between the source
-/// Instruction operands and the target Instruction operands, and false if not.
-static bool checkNumberingAndReplaceCommutative(
-  const DenseMap<Value *, unsigned> &SourceValueToNumberMapping,
-  DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
-  ArrayRef<Value *> &SourceOperands,
-  DenseSet<unsigned> &TargetValueNumbers){
-
-  DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
-
-  unsigned ArgVal;
-  bool WasInserted;
-
-  // Iterate over the operands in the source IRSimilarityCandidate to determine
-  // whether there exists an operand in the other IRSimilarityCandidate that
-  // creates a valid mapping of Value to Value between the
-  // IRSimilarityCaniddates.
-  for (Value *V : SourceOperands) {
-    ArgVal = SourceValueToNumberMapping.find(V)->second;
-
-    // Instead of finding a current mapping, we attempt to insert a set.
-    std::tie(ValueMappingIt, WasInserted) = CurrentSrcTgtNumberMapping.insert(
-        std::make_pair(ArgVal, TargetValueNumbers));
-
-    // We need to iterate over the items in other IRSimilarityCandidate's
-    // Instruction to determine whether there is a valid mapping of
-    // Value to Value.
-    DenseSet<unsigned> NewSet;
-    for (unsigned &Curr : ValueMappingIt->second)
-      // If we can find the value in the mapping, we add it to the new set.
-      if (TargetValueNumbers.contains(Curr))
-        NewSet.insert(Curr);
-
-    // If we could not find a Value, return 0.
-    if (NewSet.empty())
-      return false;
-    
-    // Otherwise replace the old mapping with the newly constructed one.
-    if (NewSet.size() != ValueMappingIt->second.size())
-      ValueMappingIt->second.swap(NewSet);
-
-    // We have reached no conclusions about the mapping, and cannot remove
-    // any items from the other operands, so we move to check the next operand.
-    if (ValueMappingIt->second.size() != 1)
-      continue;
-
-    unsigned ValToRemove = *ValueMappingIt->second.begin();
-    // When there is only one item left in the mapping for and operand, remove
-    // the value from the other operands.  If it results in there being no
-    // mapping, return false, it means the mapping is wrong
-    for (Value *InnerV : SourceOperands) {
-      if (V == InnerV)
-        continue;
-
-      unsigned InnerVal = SourceValueToNumberMapping.find(InnerV)->second;
-      ValueMappingIt = CurrentSrcTgtNumberMapping.find(InnerVal);
-      if (ValueMappingIt == CurrentSrcTgtNumberMapping.end())
-        continue;
-
-      ValueMappingIt->second.erase(ValToRemove);
-      if (ValueMappingIt->second.empty())
-        return false;
-    }
-  }
-
-  return true;
-}
-
-/// Determine if operand number \p TargetArgVal is in the current mapping set
-/// for operand number \p SourceArgVal.
-///
-/// \param [in, out] CurrentSrcTgtNumberMapping current mapping of global
-/// value numbers from source IRSimilarityCandidate to target
-/// IRSimilarityCandidate.
-/// \param [in] SourceArgVal The global value number for an operand in the
-/// in the original candidate.
-/// \param [in] TargetArgVal The global value number for the corresponding
-/// operand in the other candidate.
-/// \returns True if there exists a mapping and false if not.
-bool checkNumberingAndReplace(
-    DenseMap<unsigned, DenseSet<unsigned>> &CurrentSrcTgtNumberMapping,
-    unsigned SourceArgVal, unsigned TargetArgVal) {
-  // We are given two unsigned integers representing the global values of
-  // the operands in different IRSimilarityCandidates and a current mapping
-  // between the two.
-  //
-  // Source Operand GVN: 1
-  // Target Operand GVN: 2
-  // CurrentMapping: {1: {1, 2}}
-  //
-  // Since we have mapping, and the target operand is contained in the set, we
-  // update it to:
-  // CurrentMapping: {1: {2}}
-  // and can return true. But, if the mapping was
-  // CurrentMapping: {1: {3}}
-  // we would return false.
-
-  bool WasInserted;
-  DenseMap<unsigned, DenseSet<unsigned>>::iterator Val;
-
-  std::tie(Val, WasInserted) = CurrentSrcTgtNumberMapping.insert(
-      std::make_pair(SourceArgVal, DenseSet<unsigned>({TargetArgVal})));
-
-  // If we created a new mapping, then we are done.
-  if (WasInserted)
-    return true;
-
-  // If there is more than one option in the mapping set, and the target value
-  // is included in the mapping set replace that set with one that only includes
-  // the target value, as it is the only valid mapping via the non commutative
-  // instruction.
-
-  DenseSet<unsigned> &TargetSet = Val->second;
-  if (TargetSet.size() > 1 && TargetSet.contains(TargetArgVal)) {
-    TargetSet.clear();
-    TargetSet.insert(TargetArgVal);
-    return true;
-  }
-
-  // Return true if we can find the value in the set.
-  return TargetSet.contains(TargetArgVal);
-}
-
-bool IRSimilarityCandidate::compareNonCommutativeOperandMapping(
-    OperandMapping A, OperandMapping B) {
-  // Iterators to keep track of where we are in the operands for each
-  // Instruction.
-  ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
-  ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
-  unsigned OperandLength = A.OperVals.size();
-
-  // For each operand, get the value numbering and ensure it is consistent.
-  for (unsigned Idx = 0; Idx < OperandLength; Idx++, VItA++, VItB++) {
-    unsigned OperValA = A.IRSC.ValueToNumber.find(*VItA)->second;
-    unsigned OperValB = B.IRSC.ValueToNumber.find(*VItB)->second;
-
-    // Attempt to add a set with only the target value.  If there is no mapping
-    // we can create it here.
-    //
-    // For an instruction like a subtraction:
-    // IRSimilarityCandidateA:  IRSimilarityCandidateB:
-    // %resultA = sub %a, %b    %resultB = sub %d, %e
-    //
-    // We map %a -> %d and %b -> %e.
-    //
-    // And check to see whether their mapping is consistent in
-    // checkNumberingAndReplace.
-
-    if (!checkNumberingAndReplace(A.ValueNumberMapping, OperValA, OperValB))
-      return false;
-
-    if (!checkNumberingAndReplace(B.ValueNumberMapping, OperValB, OperValA))
-      return false;
-  }
-  return true;
-}
-
-bool IRSimilarityCandidate::compareCommutativeOperandMapping(
-    OperandMapping A, OperandMapping B) {
-  DenseSet<unsigned> ValueNumbersA;      
-  DenseSet<unsigned> ValueNumbersB;
-
-  ArrayRef<Value *>::iterator VItA = A.OperVals.begin();
-  ArrayRef<Value *>::iterator VItB = B.OperVals.begin();
-  unsigned OperandLength = A.OperVals.size();
-
-  // Find the value number sets for the operands.
-  for (unsigned Idx = 0; Idx < OperandLength;
-       Idx++, VItA++, VItB++) {
-    ValueNumbersA.insert(A.IRSC.ValueToNumber.find(*VItA)->second);
-    ValueNumbersB.insert(B.IRSC.ValueToNumber.find(*VItB)->second);
-  }
-
-  // Iterate over the operands in the first IRSimilarityCandidate and make sure
-  // there exists a possible mapping with the operands in the second
-  // IRSimilarityCandidate.
-  if (!checkNumberingAndReplaceCommutative(A.IRSC.ValueToNumber,
-                                           A.ValueNumberMapping, A.OperVals,
-                                           ValueNumbersB))
-    return false;
-
-  // Iterate over the operands in the second IRSimilarityCandidate and make sure
-  // there exists a possible mapping with the operands in the first
-  // IRSimilarityCandidate.
-  if (!checkNumberingAndReplaceCommutative(B.IRSC.ValueToNumber,
-                                           B.ValueNumberMapping, B.OperVals,
-                                           ValueNumbersA))
-    return false;
-
-  return true;
-}
-
-bool IRSimilarityCandidate::compareAssignmentMapping(
-    const unsigned InstValA, const unsigned &InstValB,
-    DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingA,
-    DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingB) {
-  DenseMap<unsigned, DenseSet<unsigned>>::iterator ValueMappingIt;
-  bool WasInserted;
-  std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingA.insert(
-      std::make_pair(InstValA, DenseSet<unsigned>({InstValB})));
-  if (!WasInserted && !ValueMappingIt->second.contains(InstValB))
-    return false;
-  else if (ValueMappingIt->second.size() != 1) {
-    // Snapshot the set before iterating: when InstValA maps to itself the
-    // erase below removes InstValA from the very set being iterated, which
-    // invalidates the range iterator under backward-shift deletion.
-    SmallVector<unsigned> OtherVals(ValueMappingIt->second.begin(),
-                                    ValueMappingIt->second.end());
-    for (unsigned OtherVal : OtherVals) {
-      if (OtherVal == InstValB)
-        continue;
-      auto OtherValIt = ValueNumberMappingA.find(OtherVal);
-      if (OtherValIt == ValueNumberMappingA.end())
-        continue;
-      OtherValIt->second.erase(InstValA);
-    }
-    ValueNumberMappingA.erase(ValueMappingIt);
-    std::tie(ValueMappingIt, WasInserted) = ValueNumberMappingA.insert(
-      std::make_pair(InstValA, DenseSet<unsigned>({InstValB})));
-  }
-
-  return true;
-}
-
-bool IRSimilarityCandidate::checkRelativeLocations(RelativeLocMapping A,
-                                                   RelativeLocMapping B) {
-  // Get the basic blocks the label refers to.
-  BasicBlock *ABB = cast<BasicBlock>(A.OperVal);
-  BasicBlock *BBB = cast<BasicBlock>(B.OperVal);
-
-  // Get the basic blocks contained in each region.
-  DenseSet<BasicBlock *> BasicBlockA;
-  DenseSet<BasicBlock *> BasicBlockB;
-  A.IRSC.getBasicBlocks(BasicBlockA);
-  B.IRSC.getBasicBlocks(BasicBlockB);
-  
-  // Determine if the block is contained in the region.
-  bool AContained = BasicBlockA.contains(ABB);
-  bool BContained = BasicBlockB.contains(BBB);
-
-  // Both blocks need to be contained in the region, or both need to be outside
-  // the region.
-  if (AContained != BContained)
-    return false;
-  
-  // If both are contained, then we need to make sure that the relative
-  // distance to the target blocks are the same.
-  if (AContained)
-    return A.RelativeLocation == B.RelativeLocation;
-  return true;
-}
-
-bool IRSimilarityCandidate::compareStructure(const IRSimilarityCandidate &A,
-                                             const IRSimilarityCandidate &B) {
-  DenseMap<unsigned, DenseSet<unsigned>> MappingA;
-  DenseMap<unsigned, DenseSet<unsigned>> MappingB;
-  return IRSimilarityCandidate::compareStructure(A, B, MappingA, MappingB);
-}
-
-typedef detail::zippy<detail::zip_shortest, SmallVector<int, 4> &,
-                      SmallVector<int, 4> &, ArrayRef<Value *> &,
-                      ArrayRef<Value *> &>
-    ZippedRelativeLocationsT;
-
-bool IRSimilarityCandidate::compareStructure(
-    const IRSimilarityCandidate &A, const IRSimilarityCandidate &B,
-    DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingA,
-    DenseMap<unsigned, DenseSet<unsigned>> &ValueNumberMappingB) {
-  if (A.getLength() != B.getLength())
-    return false;
-
-  if (A.ValueToNumber.size() != B.ValueToNumber.size())
-    return false;
-
-  iterator ItA = A.begin();
-  iterator ItB = B.begin();
-
-  // These ValueNumber Mapping sets create a create a mapping between the values
-  // in one candidate to values in the other candidate.  If we create a set with
-  // one element, and that same element maps to the original element in the
-  // candidate we have a good mapping.
-
-  // Iterate over the instructions contained in each candidate
-  unsigned SectionLength = A.getStartIdx() + A.getLength();
-  for (unsigned Loc = A.getStartIdx(); Loc < SectionLength;
-       ItA++, ItB++, Loc++) {
-    // Make sure the instructions are similar to one another.
-    if (!isClose(*ItA, *ItB))
-      return false;
-
-    Instruction *IA = ItA->Inst;
-    Instruction *IB = ItB->Inst;
-
-    if (!ItA->Legal || !ItB->Legal)
-      return false;
-
-    // Get the operand sets for the instructions.
-    ArrayRef<Value *> OperValsA = ItA->OperVals;
-    ArrayRef<Value *> OperValsB = ItB->OperVals;
-
-    unsigned InstValA = A.ValueToNumber.find(IA)->second;
-    unsigned InstValB = B.ValueToNumber.find(IB)->second;
-
-    // Ensure that the mappings for the instructions exists.
-    if (!compareAssignmentMapping(InstValA, InstValB, ValueNumberMappingA,
-                                  ValueNumberMappingB))
-      return false;
-    
-    if (!compareAssignmentMapping(InstValB, InstValA, ValueNumberMappingB,
-                                  ValueNumberMappingA))
-      return false;
-
-    // We have different paths for commutative instructions and non-commutative
-    // instructions since commutative instructions could allow multiple mappings
-    // to certain values.
-    if (IA->isCommutative() && !isa<FPMathOperator>(IA) &&
-        !isa<IntrinsicInst>(IA)) {
-      if (!compareCommutativeOperandMapping(
-              {A, OperValsA, ValueNumberMappingA},
-              {B, OperValsB, ValueNumberMappingB}))
-        return false;
-      continue;
-    }
-
-    // Handle the non-commutative cases.
-    if (!compareNonCommutativeOperandMapping(
-            {A, OperValsA, ValueNumberMappingA},
-            {B, OperValsB, ValueNumberMappingB}))
-      return false;
-
-    // Here we check that between two corresponding instructions,
-    // when referring to a basic block in the same region, the
-    // relative locations are the same. And, that the instructions refer to
-    // basic blocks outside the region in the same corresponding locations.
-
-    // We are able to make the assumption about blocks outside of the region
-    // since the target block labels are considered values and will follow the
-    // same number matching that we defined for the other instructions in the
-    // region.  So, at this point, in each location we target a specific block
-    // outside the region, we are targeting a corresponding block in each
-    // analagous location in the region we are comparing to.
-    if (!isa<UncondBrInst, CondBrInst, PHINode>(IA) ||
-        IA->getOpcode() != IB->getOpcode())
-      continue;
-
-    SmallVector<int, 4> &RelBlockLocsA = ItA->RelativeBlockLocations;
-    SmallVector<int, 4> &RelBlockLocsB = ItB->RelativeBlockLocations;
-    ArrayRef<Value *> ABL = ItA->getBlockOperVals();
-    ArrayRef<Value *> BBL = ItB->getBlockOperVals();
-
-    // Check to make sure that the number of operands, and branching locations
-    // between BranchInsts is the same.
-    if (RelBlockLocsA.size() != RelBlockLocsB.size() &&
-        ABL.size() != BBL.size())
-      return false;
-
-    assert(RelBlockLocsA.size() == ABL.size() &&
-           "Block information vectors not the same size.");
-    assert(RelBlockLocsB.size() == BBL.size() &&
-           "Block information vectors not the same size.");
-
-    ZippedRelativeLocationsT ZippedRelativeLocations =
-        zip(RelBlockLocsA, RelBlockLocsB, ABL, BBL);
-    if (any_of(ZippedRelativeLocations,
-               [&A, &B](std::tuple<int, int, Value *, Value *> R) {
-                 return !checkRelativeLocations(
-                     {A, std::get<0>(R), std::get<2>(R)},
-                     {B, std::get<1>(R), std::get<3>(R)});
-               }))
-      return false;
-  }
-  return true;
-}
-
-bool IRSimilarityCandidate::overlap(const IRSimilarityCandidate &A,
-                                    const IRSimilarityCandidate &B) {
-  auto DoesOverlap = [](const IRSimilarityCandidate &X,
-                        const IRSimilarityCandidate &Y) {
-    // Check:
-    // XXXXXX        X starts before Y ends
-    //      YYYYYYY  Y starts after X starts
-    return X.StartIdx <= Y.getEndIdx() && Y.StartIdx >= X.StartIdx;
-  };
-
-  return DoesOverlap(A, B) || DoesOverlap(B, A);
-}
-
-void IRSimilarityIdentifier::populateMapper(
-    Module &M, std::vector<IRInstructionData *> &InstrList,
-    std::vector<unsigned> &IntegerMapping) {
-
-  std::vector<IRInstructionData *> InstrListForModule;
-  std::vector<unsigned> IntegerMappingForModule;
-  // Iterate over the functions in the module to map each Instruction in each
-  // BasicBlock to an unsigned integer.
-  Mapper.initializeForBBs(M);
-
-  for (Function &F : M) {
-
-    if (F.empty())
-      continue;
-
-    for (BasicBlock &BB : F) {
-
-      // BB has potential to have similarity since it has a size greater than 2
-      // and can therefore match other regions greater than 2. Map it to a list
-      // of unsigned integers.
-      Mapper.convertToUnsignedVec(BB, InstrListForModule,
-                                  IntegerMappingForModule);
-    }
-
-    BasicBlock::iterator It = F.begin()->end();
-    Mapper.mapToIllegalUnsigned(It, IntegerMappingForModule, InstrListForModule,
-                                true);
-    if (InstrListForModule.size() > 0)
-      Mapper.IDL->push_back(*InstrListForModule.back());
-  }
-
-  // Insert the InstrListForModule at the end of the overall InstrList so that
-  // we can have a long InstrList for the entire set of Modules being analyzed.
-  llvm::append_range(InstrList, InstrListForModule);
-  // Do the same as above, but for IntegerMapping.
-  llvm::append_range(IntegerMapping, IntegerMappingForModule);
-}
-
-void IRSimilarityIdentifier::populateMapper(
-    ArrayRef<std::unique_ptr<Module>> &Modules,
-    std::vector<IRInstructionData *> &InstrList,
-    std::vector<unsigned> &IntegerMapping) {
-
-  // Iterate over, and map the instructions in each module.
-  for (const std::unique_ptr<Module> &M : Modules)
-    populateMapper(*M, InstrList, IntegerMapping);
-}
-
-/// From a repeated subsequence, find all the different instances of the
-/// subsequence from the \p InstrList, and create an IRSimilarityCandidate from
-/// the IRInstructionData in subsequence.
-///
-/// \param [in] Mapper - The instruction mapper for basic correctness checks.
-/// \param [in] InstrList - The vector that holds the instruction data.
-/// \param [in] IntegerMapping - The vector that holds the mapped integers.
-/// \param [out] CandsForRepSubstring - The vector to store the generated
-/// IRSimilarityCandidates.
-static void createCandidatesFromSuffixTree(
-    const IRInstructionMapper& Mapper, std::vector<IRInstructionData *> &InstrList,
-    std::vector<unsigned> &IntegerMapping, SuffixTree::RepeatedSubstring &RS,
-    std::vector<IRSimilarityCandidate> &CandsForRepSubstring) {
-
-  unsigned StringLen = RS.Length;
-  if (StringLen < 2)
-    return;
-
-  // Create an IRSimilarityCandidate for instance of this subsequence \p RS.
-  for (const unsigned &StartIdx : RS.StartIndices) {
-    unsigned EndIdx = StartIdx + StringLen - 1;
-
-    // Check that this subsequence does not contain an illegal instruction.
-    bool ContainsIllegal = false;
-    for (unsigned CurrIdx = StartIdx; CurrIdx <= EndIdx; CurrIdx++) {
-      unsigned Key = IntegerMapping[CurrIdx];
-      if (Key > Mapper.IllegalInstrNumber) {
-        ContainsIllegal = true;
-        break;
-      }
-    }
-
-    // If we have an illegal instruction, we should not create an
-    // IRSimilarityCandidate for this region.
-    if (ContainsIllegal)
-      continue;
-
-    // We are getting iterators to the instructions in this region of code
-    // by advancing the start and end indices from the start of the
-    // InstrList.
-    std::vector<IRInstructionData *>::iterator StartIt = InstrList.begin();
-    std::advance(StartIt, StartIdx);
-    std::vector<IRInstructionData *>::iterator EndIt = InstrList.begin();
-    std::advance(EndIt, EndIdx);
-
-    CandsForRepSubstring.emplace_back(StartIdx, StringLen, *StartIt, *EndIt);
-  }
-}
-
-void IRSimilarityCandidate::createCanonicalRelationFrom(
-    IRSimilarityCandidate &SourceCand,
-    DenseMap<unsigned, DenseSet<unsigned>> &ToSourceMapping,
-    DenseMap<unsigned, DenseSet<unsigned>> &FromSourceMapping) {
-  assert(SourceCand.CanonNumToNumber.size() != 0 &&
-         "Base canonical relationship is empty!");
-  assert(SourceCand.NumberToCanonNum.size() != 0 &&
-         "Base canonical relationship is empty!");
-
-  assert(CanonNumToNumber.size() == 0 && "Canonical Relationship is non-empty");
-  assert(NumberToCanonNum.size() == 0 && "Canonical Relationship is non-empty");
-
-  DenseSet<unsigned> UsedGVNs;
-  // Iterate over the mappings provided from this candidate to SourceCand.  We
-  // are then able to map the GVN in this candidate to the same canonical number
-  // given to the corresponding GVN in SourceCand.
-  for (std::pair<unsigned, DenseSet<unsigned>> &GVNMapping : ToSourceMapping) {
-    unsigned SourceGVN = GVNMapping.first;
-
-    assert(GVNMapping.second.size() != 0 && "Possible GVNs is 0!");
-
-    unsigned ResultGVN;
-    // We need special handling if we have more than one potential value.  This
-    // means that there are at least two GVNs that could correspond to this GVN.
-    // This could lead to potential swapping later on, so we make a decision
-    // here to ensure a one-to-one mapping.
-    if (GVNMapping.second.size() > 1) {
-      bool Found = false;
-      for (unsigned Val : GVNMapping.second) {
-        // We make sure the target value number hasn't already been reserved.
-        if (UsedGVNs.contains(Val))
-          continue;
-
-        // We make sure that the opposite mapping is still consistent.
-        DenseMap<unsigned, DenseSet<unsigned>>::iterator It =
-            FromSourceMapping.find(Val);
-
-        if (!It->second.contains(SourceGVN))
-          continue;
-
-        // We pick the first item that satisfies these conditions.
-        Found = true;
-        ResultGVN = Val;
-        break;
-      }
-
-      assert(Found && "Could not find matching value for source GVN");
-      (void)Found;
-
-    } else
-      ResultGVN = *GVNMapping.second.begin();
-
-    // Whatever GVN is found, we mark it as used.
-    UsedGVNs.insert(ResultGVN);
-
-    unsigned CanonNum = *SourceCand.getCanonicalNum(ResultGVN);
-    CanonNumToNumber.insert(std::make_pair(CanonNum, SourceGVN));
-    NumberToCanonNum.insert(std::make_pair(SourceGVN, CanonNum));
-  }
-
-  DenseSet<BasicBlock *> BBSet;
-  getBasicBlocks(BBSet);
-  // Find canonical numbers for the BasicBlocks in the current candidate.
-  // This is done by finding the corresponding value for the first instruction
-  // in the block in the current candidate, finding the matching value in the
-  // source candidate.  Then by finding the parent of this value, use the
-  // canonical number of the block in the source candidate for the canonical
-  // number in the current candidate.
-  for (BasicBlock *BB : BBSet) {
-    unsigned BBGVNForCurrCand = ValueToNumber.find(BB)->second;
-
-    // We can skip the BasicBlock if the canonical numbering has already been
-    // found in a separate instruction.
-    if (NumberToCanonNum.contains(BBGVNForCurrCand))
-      continue;
-
-    // If the basic block is the starting block, then the shared instruction may
-    // not be the first instruction in the block, it will be the first
-    // instruction in the similarity region.
-    Value *FirstOutlineInst =
-        BB == getStartBB() ? frontInstruction() : &*BB->begin();
-
-    unsigned FirstInstGVN = *getGVN(FirstOutlineInst);
-    unsigned FirstInstCanonNum = *getCanonicalNum(FirstInstGVN);
-    unsigned SourceGVN = *SourceCand.fromCanonicalNum(FirstInstCanonNum);
-    Value *SourceV = *SourceCand.fromGVN(SourceGVN);
-    BasicBlock *SourceBB = cast<Instruction>(SourceV)->getParent();
-    unsigned SourceBBGVN = *SourceCand.getGVN(SourceBB);
-    unsigned SourceCanonBBGVN = *SourceCand.getCanonicalNum(SourceBBGVN);
-    CanonNumToNumber.insert(std::make_pair(SourceCanonBBGVN, BBGVNForCurrCand));
-    NumberToCanonNum.insert(std::make_pair(BBGVNForCurrCand, SourceCanonBBGVN));
-  }
-}
-
-void IRSimilarityCandidate::createCanonicalRelationFrom(
-    IRSimilarityCandidate &SourceCand, IRSimilarityCandidate &SourceCandLarge,
-    IRSimilarityCandidate &TargetCandLarge) {
-  assert(!SourceCand.CanonNumToNumber.empty() &&
-         "Canonical Relationship is non-empty");
-  assert(!SourceCand.NumberToCanonNum.empty() &&
-         "Canonical Relationship is non-empty");
-
-  assert(!SourceCandLarge.CanonNumToNumber.empty() &&
-         "Canonical Relationship is non-empty");
-  assert(!SourceCandLarge.NumberToCanonNum.empty() &&
-         "Canonical Relationship is non-empty");
-  
-  assert(!TargetCandLarge.CanonNumToNumber.empty() &&
-         "Canonical Relationship is non-empty");
-  assert(!TargetCandLarge.NumberToCanonNum.empty() &&
-         "Canonical Relationship is non-empty");
-
-  assert(CanonNumToNumber.empty() && "Canonical Relationship is non-empty");
-  assert(NumberToCanonNum.empty() && "Canonical Relationship is non-empty");
-
-  // We're going to use the larger candidates as a "bridge" to create the
-  // canonical number for the target candidate since we have idetified two
-  // candidates as subsequences of larger sequences, and therefore must be
-  // structurally similar.
-  for (std::pair<Value *, unsigned> &ValueNumPair : ValueToNumber) {
-    Value *CurrVal = ValueNumPair.first;
-    unsigned TargetCandGVN = ValueNumPair.second;
-
-    // Find the numbering in the large candidate that surrounds the 
-    // current candidate.
-    std::optional<unsigned> OLargeTargetGVN = TargetCandLarge.getGVN(CurrVal);
-    assert(OLargeTargetGVN.has_value() && "GVN not found for Value");
-
-    // Get the canonical numbering in the large target candidate.
-    std::optional<unsigned> OTargetCandCanon =
-        TargetCandLarge.getCanonicalNum(OLargeTargetGVN.value());
-    assert(OTargetCandCanon.has_value() &&
-           "Canononical Number not found for GVN");
-    
-    // Get the GVN in the large source candidate from the canonical numbering.
-    std::optional<unsigned> OLargeSourceGVN =
-        SourceCandLarge.fromCanonicalNum(OTargetCandCanon.value());
-    assert(OLargeSourceGVN.has_value() &&
-           "GVN Number not found for Canonical Number");
-    
-    // Get the Value from the GVN in the large source candidate.
-    std::optional<Value *> OLargeSourceV =
-        SourceCandLarge.fromGVN(OLargeSourceGVN.value());
-    assert(OLargeSourceV.has_value() && "Value not found for GVN");
-
-    // Get the GVN number for the Value in the source candidate.
-    std::optional<unsigned> OSourceGVN =
-        SourceCand.getGVN(OLargeSourceV.value());
-    assert(OSourceGVN.has_value() && "GVN Number not found for Value");
-
-    // Get the canonical numbering from the GVN/
-    std::optional<unsigned> OSourceCanon =
-        SourceCand.getCanonicalNum(OSourceGVN.value());
-    assert(OSourceCanon.has_value() && "Canon Number not found for GVN");
-
-    // Insert the canonical numbering and GVN pair into their respective
-    // mappings.
-    CanonNumToNumber.insert(
-        std::make_pair(OSourceCanon.value(), TargetCandGVN));
-    NumberToCanonNum.insert(
-        std::make_pair(TargetCandGVN, OSourceCanon.value()));
-  }
-}
-
-void IRSimilarityCandidate::createCanonicalMappingFor(
-    IRSimilarityCandidate &CurrCand) {
-  assert(CurrCand.CanonNumToNumber.size() == 0 &&
-         "Canonical Relationship is non-empty");
-  assert(CurrCand.NumberToCanonNum.size() == 0 &&
-         "Canonical Relationship is non-empty");
-
-  unsigned CanonNum = 0;
-  // Iterate over the value numbers found, the order does not matter in this
-  // case.
-  for (std::pair<unsigned, Value *> &NumToVal : CurrCand.NumberToValue) {
-    CurrCand.NumberToCanonNum.insert(std::make_pair(NumToVal.first, CanonNum));
-    CurrCand.CanonNumToNumber.insert(std::make_pair(CanonNum, NumToVal.first));
-    CanonNum++;
-  }
-}
-
-/// Look for larger IRSimilarityCandidates From the previously matched
-/// IRSimilarityCandidates that fully contain \p CandA or \p CandB.  If there is
-/// an overlap, return a pair of structurally similar, larger
-/// IRSimilarityCandidates.
-///
-/// \param [in] CandA - The first candidate we are trying to determine the
-/// structure of.
-/// \param [in] CandB - The second candidate we are trying to determine the
-/// structure of.
-/// \param [in] IndexToIncludedCand - Mapping of index of the an instruction in
-/// a circuit to the IRSimilarityCandidates that include this instruction.
-/// \param [in] CandToOverallGroup - Mapping of IRSimilarityCandidate to a
-/// number representing the structural group assigned to it.
-static std::optional<
-    std::pair<IRSimilarityCandidate *, IRSimilarityCandidate *>>
-CheckLargerCands(
-    IRSimilarityCandidate &CandA, IRSimilarityCandidate &CandB,
-    DenseMap<unsigned, DenseSet<IRSimilarityCandidate *>> &IndexToIncludedCand,
-    DenseMap<IRSimilarityCandidate *, unsigned> &CandToGroup) {
-  DenseMap<unsigned, IRSimilarityCandidate *> IncludedGroupAndCandA;
-  DenseMap<unsigned, IRSimilarityCandidate *> IncludedGroupAndCandB;
-  DenseSet<unsigned> IncludedGroupsA;
-  DenseSet<unsigned> IncludedGroupsB;
-
-  // Find the overall similarity group numbers that fully contain the candidate,
-  // and record the larger candidate for each group.
-  auto IdxToCandidateIt = IndexToIncludedCand.find(CandA.getStartIdx());
-  std::optional<std::pair<IRSimilarityCandidate *, IRSimilarityCandidate *>>
-      Result;
-
-  unsigned CandAStart = CandA.getStartIdx();
-  unsigned CandAEnd = CandA.getEndIdx();
-  unsigned CandBStart = CandB.getStartIdx();
-  unsigned CandBEnd = CandB.getEndIdx();
-  if (IdxToCandidateIt == IndexToIncludedCand.end())
-    return Result;
-  for (IRSimilarityCandidate *MatchedCand : IdxToCandidateIt->second) {
-    if (MatchedCand->getStartIdx() > CandAStart ||
-        (MatchedCand->getEndIdx() < CandAEnd))
-      continue;
-    unsigned GroupNum = CandToGroup.find(MatchedCand)->second;
-    IncludedGroupAndCandA.insert(std::make_pair(GroupNum, MatchedCand));
-    IncludedGroupsA.insert(GroupNum);
-  }
-
-  // Find the overall similarity group numbers that fully contain the next
-  // candidate, and record the larger candidate for each group.
-  IdxToCandidateIt = IndexToIncludedCand.find(CandBStart);
-  if (IdxToCandidateIt == IndexToIncludedCand.end())
-    return Result;
-  for (IRSimilarityCandidate *MatchedCand : IdxToCandidateIt->second) {
-    if (MatchedCand->getStartIdx() > CandBStart ||
-        MatchedCand->getEndIdx() < CandBEnd)
-      continue;
-    unsigned GroupNum = CandToGroup.find(MatchedCand)->second;
-    IncludedGroupAndCandB.insert(std::make_pair(GroupNum, MatchedCand));
-    IncludedGroupsB.insert(GroupNum);
-  }
-
-  // Find the intersection between the two groups, these are the groups where
-  // the larger candidates exist.
-  set_intersect(IncludedGroupsA, IncludedGroupsB);
-
-  // If there is no intersection between the sets, then we cannot determine
-  // whether or not there is a match.
-  if (IncludedGroupsA.empty())
-    return Result;
-  
-  // Create a pair that contains the larger candidates.
-  auto ItA = IncludedGroupAndCandA.find(*IncludedGroupsA.begin());
-  auto ItB = IncludedGroupAndCandB.find(*IncludedGroupsA.begin());
-  Result = std::make_pair(ItA->second, ItB->second);
-  return Result;
-}
-
-/// From the list of IRSimilarityCandidates, perform a comparison between each
-/// IRSimilarityCandidate to determine if there are overlapping
-/// IRInstructionData, or if they do not have the same structure.
-///
-/// \param [in] CandsForRepSubstring - The vector containing the
-/// IRSimilarityCandidates.
-/// \param [out] StructuralGroups - the mapping of unsigned integers to vector
-/// of IRSimilarityCandidates where each of the IRSimilarityCandidates in the
-/// vector are structurally similar to one another.
-/// \param [in] IndexToIncludedCand - Mapping of index of the an instruction in
-/// a circuit to the IRSimilarityCandidates that include this instruction.
-/// \param [in] CandToOverallGroup - Mapping of IRSimilarityCandidate to a
-/// number representing the structural group assigned to it.
-static void findCandidateStructures(
-    std::vector<IRSimilarityCandidate> &CandsForRepSubstring,
-    DenseMap<unsigned, SimilarityGroup> &StructuralGroups,
-    DenseMap<unsigned,  DenseSet<IRSimilarityCandidate *>> &IndexToIncludedCand,
-    DenseMap<IRSimilarityCandidate *, unsigned> &CandToOverallGroup
-    ) {
-  std::vector<IRSimilarityCandidate>::iterator CandIt, CandEndIt, InnerCandIt,
-      InnerCandEndIt;
-
-  // IRSimilarityCandidates each have a structure for operand use.  It is
-  // possible that two instances of the same subsequences have different
-  // structure. Each type of structure found is assigned a number.  This
-  // DenseMap maps an IRSimilarityCandidate to which type of similarity
-  // discovered it fits within.
-  DenseMap<IRSimilarityCandidate *, unsigned> CandToGroup;
-
-  // Find the compatibility from each candidate to the others to determine
-  // which candidates overlap and which have the same structure by mapping
-  // each structure to a different group.
-  bool SameStructure;
-  bool Inserted;
-  unsigned CurrentGroupNum = 0;
-  unsigned OuterGroupNum;
-  DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupIt;
-  DenseMap<IRSimilarityCandidate *, unsigned>::iterator CandToGroupItInner;
-  DenseMap<unsigned, SimilarityGroup>::iterator CurrentGroupPair;
-
-  // Iterate over the candidates to determine its structural and overlapping
-  // compatibility with other instructions
-  DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingA;
-  DenseMap<unsigned, DenseSet<unsigned>> ValueNumberMappingB;
-  for (CandIt = CandsForRepSubstring.begin(),
-      CandEndIt = CandsForRepSubstring.end();
-       CandIt != CandEndIt; CandIt++) {
-
-    // Determine if it has an assigned structural group already.
-    // If not, we assign it one, and add it to our mapping.
-    std::tie(CandToGroupIt, Inserted) =
-        CandToGroup.try_emplace(&*CandIt, CurrentGroupNum);
-    if (Inserted)
-      ++CurrentGroupNum;
-
-    // Get the structural group number from the iterator.
-    OuterGroupNum = CandToGroupIt->second;
-
-    // Check if we already have a list of IRSimilarityCandidates for the current
-    // structural group.  Create one if one does not exist.
-    CurrentGroupPair = StructuralGroups.find(OuterGroupNum);
-    if (CurrentGroupPair == StructuralGroups.end()) {
-      IRSimilarityCandidate::createCanonicalMappingFor(*CandIt);
-      std::tie(CurrentGroupPair, Inserted) = StructuralGroups.insert(
-          std::make_pair(OuterGroupNum, SimilarityGroup({*CandIt})));
-    }
-
-    // Iterate over the IRSimilarityCandidates following the current
-    // IRSimilarityCandidate in the list to determine whether the two
-    // IRSimilarityCandidates are compatible.  This is so we do not repeat pairs
-    // of IRSimilarityCandidates.
-    for (InnerCandIt = std::next(CandIt),
-        InnerCandEndIt = CandsForRepSubstring.end();
-         InnerCandIt != InnerCandEndIt; InnerCandIt++) {
-
-      // We check if the inner item has a group already, if it does, we skip it.
-      CandToGroupItInner = CandToGroup.find(&*InnerCandIt);
-      if (CandToGroupItInner != CandToGroup.end())
-        continue;
-
-      // Check if we have found structural similarity between two candidates
-      // that fully contains the first and second candidates.
-      std::optional<std::pair<IRSimilarityCandidate *, IRSimilarityCandidate *>>
-          LargerPair = CheckLargerCands(
-              *CandIt, *InnerCandIt, IndexToIncludedCand, CandToOverallGroup);
-
-      // If a pair was found, it means that we can assume that these smaller
-      // substrings are also structurally similar.  Use the larger candidates to
-      // determine the canonical mapping between the two sections.
-      if (LargerPair.has_value()) {
-        SameStructure = true;
-        InnerCandIt->createCanonicalRelationFrom(
-            *CandIt, *LargerPair.value().first, *LargerPair.value().second);
-        CandToGroup.insert(std::make_pair(&*InnerCandIt, OuterGroupNum));
-        CurrentGroupPair->second.push_back(*InnerCandIt);
-        continue;
-      }
-
-      // Otherwise we determine if they have the same structure and add it to
-      // vector if they match.
-      ValueNumberMappingA.clear();
-      ValueNumberMappingB.clear();
-      SameStructure = IRSimilarityCandidate::compareStructure(
-          *CandIt, *InnerCandIt, ValueNumberMappingA, ValueNumberMappingB);
-      if (!SameStructure)
-        continue;
-
-      InnerCandIt->createCanonicalRelationFrom(*CandIt, ValueNumberMappingA,
-                                               ValueNumberMappingB);
-      CandToGroup.insert(std::make_pair(&*InnerCandIt, OuterGroupNum));
-      CurrentGroupPair->second.push_back(*InnerCandIt);
-    }
-  }
-}
-
-void IRSimilarityIdentifier::findCandidates(
-    std::vector<IRInstructionData *> &InstrList,
-    std::vector<unsigned> &IntegerMapping) {
-  SuffixTree ST(IntegerMapping);
-
-  std::vector<IRSimilarityCandidate> CandsForRepSubstring;
-  std::vector<SimilarityGroup> NewCandidateGroups;
-
-  DenseMap<unsigned, SimilarityGroup> StructuralGroups;
-  DenseMap<unsigned, DenseSet<IRSimilarityCandidate *>> IndexToIncludedCand;
-  DenseMap<IRSimilarityCandidate *, unsigned> CandToGroup; 
-
-  // Iterate over the subsequences found by the Suffix Tree to create
-  // IRSimilarityCandidates for each repeated subsequence and determine which
-  // instances are structurally similar to one another.
-
-  // Sort the suffix tree from longest substring to shortest.
-  std::vector<SuffixTree::RepeatedSubstring> RSes;
-  for (SuffixTree::RepeatedSubstring &RS : ST)
-    RSes.push_back(RS);
-
-  llvm::stable_sort(RSes, [](const SuffixTree::RepeatedSubstring &LHS,
-                             const SuffixTree::RepeatedSubstring &RHS) {
-    return LHS.Length > RHS.Length;
-  });
-  for (SuffixTree::RepeatedSubstring &RS : RSes) {
-    createCandidatesFromSuffixTree(Mapper, InstrList, IntegerMapping, RS,
-                                   CandsForRepSubstring);
-
-    if (CandsForRepSubstring.size() < 2)
-      continue;
-
-    findCandidateStructures(CandsForRepSubstring, StructuralGroups,
-                            IndexToIncludedCand, CandToGroup);
-    for (std::pair<unsigned, SimilarityGroup> &Group : StructuralGroups) {
-      // We only add the group if it contains more than one
-      // IRSimilarityCandidate.  If there is only one, that means there is no
-      // other repeated subsequence with the same structure.
-      if (Group.second.size() > 1) {
-        SimilarityCandidates->push_back(Group.second);
-        // Iterate over each candidate in the group, and add an entry for each
-        // instruction included with a mapping to a set of
-        // IRSimilarityCandidates that include that instruction.
-        for (IRSimilarityCandidate &IRCand : SimilarityCandidates->back()) {
-          for (unsigned Idx = IRCand.getStartIdx(), Edx = IRCand.getEndIdx();
-               Idx <= Edx; ++Idx)
-            IndexToIncludedCand[Idx].insert(&IRCand);
-          // Add mapping of candidate to the overall similarity group number.
-          CandToGroup.insert(
-              std::make_pair(&IRCand, SimilarityCandidates->size() - 1));
-        }
-      }
-    }
-
-    CandsForRepSubstring.clear();
-    StructuralGroups.clear();
-    NewCandidateGroups.clear();
-  }
-}
-
-SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(
-    ArrayRef<std::unique_ptr<Module>> Modules) {
-  resetSimilarityCandidates();
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> IntegerMapping;
-  Mapper.InstClassifier.EnableBranches = this->EnableBranches;
-  Mapper.InstClassifier.EnableIndirectCalls = EnableIndirectCalls;
-  Mapper.EnableMatchCallsByName = EnableMatchingCallsByName;
-  Mapper.InstClassifier.EnableIntrinsics = EnableIntrinsics;
-  Mapper.InstClassifier.EnableMustTailCalls = EnableMustTailCalls;
-
-  populateMapper(Modules, InstrList, IntegerMapping);
-  findCandidates(InstrList, IntegerMapping);
-
-  return *SimilarityCandidates;
-}
-
-SimilarityGroupList &IRSimilarityIdentifier::findSimilarity(Module &M) {
-  resetSimilarityCandidates();
-  Mapper.InstClassifier.EnableBranches = this->EnableBranches;
-  Mapper.InstClassifier.EnableIndirectCalls = EnableIndirectCalls;
-  Mapper.EnableMatchCallsByName = EnableMatchingCallsByName;
-  Mapper.InstClassifier.EnableIntrinsics = EnableIntrinsics;
-  Mapper.InstClassifier.EnableMustTailCalls = EnableMustTailCalls;
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> IntegerMapping;
-
-  populateMapper(M, InstrList, IntegerMapping);
-  findCandidates(InstrList, IntegerMapping);
-
-  return *SimilarityCandidates;
-}
-
-INITIALIZE_PASS(IRSimilarityIdentifierWrapperPass, "ir-similarity-identifier",
-                "ir-similarity-identifier", false, true)
-
-IRSimilarityIdentifierWrapperPass::IRSimilarityIdentifierWrapperPass()
-    : ModulePass(ID) {}
-
-bool IRSimilarityIdentifierWrapperPass::doInitialization(Module &M) {
-  IRSI.reset(new IRSimilarityIdentifier(!DisableBranches, !DisableIndirectCalls,
-                                        MatchCallsByName, !DisableIntrinsics,
-                                        false));
-  return false;
-}
-
-bool IRSimilarityIdentifierWrapperPass::doFinalization(Module &M) {
-  IRSI.reset();
-  return false;
-}
-
-bool IRSimilarityIdentifierWrapperPass::runOnModule(Module &M) {
-  IRSI->findSimilarity(M);
-  return false;
-}
-
-AnalysisKey IRSimilarityAnalysis::Key;
-IRSimilarityIdentifier IRSimilarityAnalysis::run(Module &M,
-                                                 ModuleAnalysisManager &) {
-  auto IRSI = IRSimilarityIdentifier(!DisableBranches, !DisableIndirectCalls,
-                                     MatchCallsByName, !DisableIntrinsics,
-                                     false);
-  IRSI.findSimilarity(M);
-  return IRSI;
-}
-
-PreservedAnalyses
-IRSimilarityAnalysisPrinterPass::run(Module &M, ModuleAnalysisManager &AM) {
-  IRSimilarityIdentifier &IRSI = AM.getResult<IRSimilarityAnalysis>(M);
-  std::optional<SimilarityGroupList> &SimilarityCandidatesOpt =
-      IRSI.getSimilarity();
-
-  for (std::vector<IRSimilarityCandidate> &CandVec : *SimilarityCandidatesOpt) {
-    OS << CandVec.size() << " candidates of length "
-       << CandVec.begin()->getLength() << ".  Found in: \n";
-    for (IRSimilarityCandidate &Cand : CandVec) {
-      OS << "  Function: " << Cand.front()->Inst->getFunction()->getName().str()
-         << ", Basic Block: ";
-      if (Cand.front()->Inst->getParent()->getName().str() == "")
-        OS << "(unnamed)";
-      else
-        OS << Cand.front()->Inst->getParent()->getName().str();
-      OS << "\n    Start Instruction: ";
-      Cand.frontInstruction()->print(OS);
-      OS << "\n      End Instruction: ";
-      Cand.backInstruction()->print(OS);
-      OS << "\n";
-    }
-  }
-
-  return PreservedAnalyses::all();
-}
-
-char IRSimilarityIdentifierWrapperPass::ID = 0;
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index b8b5507447fd4..f758469dd8ebb 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -240,7 +240,6 @@
 #include "llvm/Transforms/IPO/GlobalOpt.h"
 #include "llvm/Transforms/IPO/GlobalSplit.h"
 #include "llvm/Transforms/IPO/HotColdSplitting.h"
-#include "llvm/Transforms/IPO/IROutliner.h"
 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
 #include "llvm/Transforms/IPO/Instrumentor.h"
 #include "llvm/Transforms/IPO/Internalize.h"
diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index d62828c78bfe4..b8c5b1eab2f97 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -62,7 +62,6 @@
 #include "llvm/Transforms/IPO/GlobalOpt.h"
 #include "llvm/Transforms/IPO/GlobalSplit.h"
 #include "llvm/Transforms/IPO/HotColdSplitting.h"
-#include "llvm/Transforms/IPO/IROutliner.h"
 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
 #include "llvm/Transforms/IPO/Inliner.h"
 #include "llvm/Transforms/IPO/Instrumentor.h"
@@ -243,10 +242,6 @@ static cl::opt<bool>
     EnableHotColdSplit("hot-cold-split",
                        cl::desc("Enable hot-cold splitting pass"));
 
-static cl::opt<bool> EnableIROutliner("ir-outliner", cl::init(false),
-                                      cl::Hidden,
-                                      cl::desc("Enable ir outliner pass"));
-
 static cl::opt<bool>
     DisablePreInliner("disable-preinline", cl::init(false), cl::Hidden,
                       cl::desc("Disable pre-instrumentation inliner"));
@@ -1701,13 +1696,6 @@ PassBuilder::buildModuleOptimizationPipeline(OptimizationLevel Level,
   if (EnableHotColdSplit && !isLTOPreLink(LTOPhase))
     MPM.addPass(HotColdSplittingPass());
 
-  // Search the code for similar regions of code. If enough similar regions can
-  // be found where extracting the regions into their own function will decrease
-  // the size of the program, we extract the regions, a deduplicate the
-  // structurally similar regions.
-  if (EnableIROutliner)
-    MPM.addPass(IROutlinerPass());
-
   // Now we need to do some global optimization transforms.
   // FIXME: It would seem like these should come first in the optimization
   // pipeline and maybe be the bottom of the canonicalization pipeline? Weird
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index cba01aab49963..0955bfdb3246c 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -27,7 +27,6 @@ MODULE_ANALYSIS("dxil-resource-type", DXILResourceTypeAnalysis())
 MODULE_ANALYSIS("dxil-resource-bindings", DXILResourceBindingAnalysis())
 MODULE_ANALYSIS("inline-advisor", InlineAdvisorAnalysis())
 MODULE_ANALYSIS("ir2vec-vocab", IR2VecVocabAnalysis())
-MODULE_ANALYSIS("ir-similarity", IRSimilarityAnalysis())
 MODULE_ANALYSIS("last-run-tracking", LastRunTrackingAnalysis())
 MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
 MODULE_ANALYSIS("libcall-lowering-info", LibcallLoweringModuleAnalysis())
@@ -108,7 +107,6 @@ MODULE_PASS("ctx-instr-lower", PGOCtxProfLoweringPass())
 MODULE_PASS("print<ctx-prof-analysis>", CtxProfAnalysisPrinterPass(errs()))
 MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
 MODULE_PASS("instrumentor", InstrumentorPass())
-MODULE_PASS("iroutliner", IROutlinerPass())
 MODULE_PASS("jmc-instrumenter", JMCInstrumenterPass())
 MODULE_PASS("lower-emutls", LowerEmuTLSPass())
 MODULE_PASS("lower-global-dtors", LowerGlobalDtorsPass())
@@ -144,7 +142,6 @@ MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass(TM))
 MODULE_PASS("print", PrintModulePass(errs()))
 MODULE_PASS("print-callgraph", CallGraphPrinterPass(errs()))
 MODULE_PASS("print-callgraph-sccs", CallGraphSCCsPrinterPass(errs()))
-MODULE_PASS("print-ir-similarity", IRSimilarityAnalysisPrinterPass(errs()))
 MODULE_PASS("print-lcg", LazyCallGraphPrinterPass(errs()))
 MODULE_PASS("print-lcg-dot", LazyCallGraphDOTPrinterPass(errs()))
 MODULE_PASS("print-must-be-executed-contexts",
diff --git a/llvm/lib/Transforms/IPO/CMakeLists.txt b/llvm/lib/Transforms/IPO/CMakeLists.txt
index a986b9485f563..23c610f1c15e6 100644
--- a/llvm/lib/Transforms/IPO/CMakeLists.txt
+++ b/llvm/lib/Transforms/IPO/CMakeLists.txt
@@ -24,7 +24,6 @@ add_llvm_component_library(LLVMipo
   GlobalSplit.cpp
   HotColdSplitting.cpp
   IPO.cpp
-  IROutliner.cpp
   InferFunctionAttrs.cpp
   Inliner.cpp
   Instrumentor.cpp
diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp
deleted file mode 100644
index 0e780d41c93ed..0000000000000
--- a/llvm/lib/Transforms/IPO/IROutliner.cpp
+++ /dev/null
@@ -1,2975 +0,0 @@
-//===- IROutliner.cpp -- Outline Similar Regions ----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-// Implementation for the IROutliner which is used by the IROutliner Pass.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/IPO/IROutliner.h"
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/Analysis/OptimizationRemarkEmitter.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/DIBuilder.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/DebugInfoMetadata.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Mangler.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Utils/ValueMapper.h"
-#include <optional>
-#include <vector>
-
-#define DEBUG_TYPE "iroutliner"
-
-using namespace llvm;
-using namespace IRSimilarity;
-
-// A command flag to be used for debugging to exclude branches from similarity
-// matching and outlining.
-namespace llvm {
-extern cl::opt<bool> DisableBranches;
-
-// A command flag to be used for debugging to indirect calls from similarity
-// matching and outlining.
-extern cl::opt<bool> DisableIndirectCalls;
-
-// A command flag to be used for debugging to exclude intrinsics from similarity
-// matching and outlining.
-extern cl::opt<bool> DisableIntrinsics;
-
-} // namespace llvm
-
-// Set to true if the user wants the ir outliner to run on linkonceodr linkage
-// functions. This is false by default because the linker can dedupe linkonceodr
-// functions. Since the outliner is confined to a single module (modulo LTO),
-// this is off by default. It should, however, be the default behavior in
-// LTO.
-static cl::opt<bool> EnableLinkOnceODRIROutlining(
-    "enable-linkonceodr-ir-outlining", cl::Hidden,
-    cl::desc("Enable the IR outliner on linkonceodr functions"),
-    cl::init(false));
-
-// This is a debug option to test small pieces of code to ensure that outlining
-// works correctly.
-static cl::opt<bool> NoCostModel(
-    "ir-outlining-no-cost", cl::init(false), cl::ReallyHidden,
-    cl::desc("Debug option to outline greedily, without restriction that "
-             "calculated benefit outweighs cost"));
-
-/// The OutlinableGroup holds all the overarching information for outlining
-/// a set of regions that are structurally similar to one another, such as the
-/// types of the overall function, the output blocks, the sets of stores needed
-/// and a list of the different regions. This information is used in the
-/// deduplication of extracted regions with the same structure.
-struct OutlinableGroup {
-  /// The sections that could be outlined
-  std::vector<OutlinableRegion *> Regions;
-
-  /// The argument types for the function created as the overall function to
-  /// replace the extracted function for each region.
-  std::vector<Type *> ArgumentTypes;
-  /// The FunctionType for the overall function.
-  FunctionType *OutlinedFunctionType = nullptr;
-  /// The Function for the collective overall function.
-  Function *OutlinedFunction = nullptr;
-
-  /// Flag for whether we should not consider this group of OutlinableRegions
-  /// for extraction.
-  bool IgnoreGroup = false;
-
-  /// The return blocks for the overall function.
-  DenseMap<Value *, BasicBlock *> EndBBs;
-
-  /// The PHIBlocks with their corresponding return block based on the return
-  /// value as the key.
-  DenseMap<Value *, BasicBlock *> PHIBlocks;
-
-  /// A set containing the different GVN store sets needed. Each array contains
-  /// a sorted list of the different values that need to be stored into output
-  /// registers.
-  DenseSet<ArrayRef<unsigned>> OutputGVNCombinations;
-
-  /// Flag for whether the \ref ArgumentTypes have been defined after the
-  /// extraction of the first region.
-  bool InputTypesSet = false;
-
-  /// The number of input values in \ref ArgumentTypes.  Anything after this
-  /// index in ArgumentTypes is an output argument.
-  unsigned NumAggregateInputs = 0;
-
-  /// The mapping of the canonical numbering of the values in outlined sections
-  /// to specific arguments.
-  DenseMap<unsigned, unsigned> CanonicalNumberToAggArg;
-
-  /// The number of branches in the region target a basic block that is outside
-  /// of the region.
-  unsigned BranchesToOutside = 0;
-
-  /// Tracker counting backwards from the highest unsigned value possible to
-  /// avoid conflicting with the GVNs of assigned values.  We start at -3 since
-  /// -2 and -1 are assigned by the DenseMap.
-  unsigned PHINodeGVNTracker = -3;
-
-  DenseMap<unsigned,
-           std::pair<std::pair<unsigned, unsigned>, SmallVector<unsigned, 2>>>
-      PHINodeGVNToGVNs;
-  DenseMap<hash_code, unsigned> GVNsToPHINodeGVN;
-
-  /// The number of instructions that will be outlined by extracting \ref
-  /// Regions.
-  InstructionCost Benefit = 0;
-  /// The number of added instructions needed for the outlining of the \ref
-  /// Regions.
-  InstructionCost Cost = 0;
-
-  /// The argument that needs to be marked with the swifterr attribute.  If not
-  /// needed, there is no value.
-  std::optional<unsigned> SwiftErrorArgument;
-
-  /// For the \ref Regions, we look at every Value.  If it is a constant,
-  /// we check whether it is the same in Region.
-  ///
-  /// \param [in,out] NotSame contains the global value numbers where the
-  /// constant is not always the same, and must be passed in as an argument.
-  void findSameConstants(DenseSet<unsigned> &NotSame);
-
-  /// For the regions, look at each set of GVN stores needed and account for
-  /// each combination.  Add an argument to the argument types if there is
-  /// more than one combination.
-  ///
-  /// \param [in] M - The module we are outlining from.
-  void collectGVNStoreSets(Module &M);
-};
-
-/// Move the contents of \p SourceBB to before the last instruction of \p
-/// TargetBB.
-/// \param SourceBB - the BasicBlock to pull Instructions from.
-/// \param TargetBB - the BasicBlock to put Instruction into.
-static void moveBBContents(BasicBlock &SourceBB, BasicBlock &TargetBB) {
-  TargetBB.splice(TargetBB.end(), &SourceBB);
-}
-
-/// A function to sort the keys of \p Map, which must be a mapping of constant
-/// values to basic blocks and return it in \p SortedKeys
-///
-/// \param SortedKeys - The vector the keys will be return in and sorted.
-/// \param Map - The DenseMap containing keys to sort.
-static void getSortedConstantKeys(std::vector<Value *> &SortedKeys,
-                                  DenseMap<Value *, BasicBlock *> &Map) {
-  for (auto &VtoBB : Map)
-    SortedKeys.push_back(VtoBB.first);
-
-  // Here we expect to have either 1 value that is void (nullptr) or multiple
-  // values that are all constant integers.
-  if (SortedKeys.size() == 1) {
-    assert(!SortedKeys[0] && "Expected a single void value.");
-    return;
-  }
-
-  stable_sort(SortedKeys, [](const Value *LHS, const Value *RHS) {
-    assert(LHS && RHS && "Expected non void values.");
-    const ConstantInt *LHSC = cast<ConstantInt>(LHS);
-    const ConstantInt *RHSC = cast<ConstantInt>(RHS);
-
-    return LHSC->getLimitedValue() < RHSC->getLimitedValue();
-  });
-}
-
-Value *OutlinableRegion::findCorrespondingValueIn(const OutlinableRegion &Other,
-                                                  Value *V) {
-  std::optional<unsigned> GVN = Candidate->getGVN(V);
-  assert(GVN && "No GVN for incoming value");
-  std::optional<unsigned> CanonNum = Candidate->getCanonicalNum(*GVN);
-  std::optional<unsigned> FirstGVN =
-      Other.Candidate->fromCanonicalNum(*CanonNum);
-  std::optional<Value *> FoundValueOpt = Other.Candidate->fromGVN(*FirstGVN);
-  return FoundValueOpt.value_or(nullptr);
-}
-
-BasicBlock *
-OutlinableRegion::findCorrespondingBlockIn(const OutlinableRegion &Other,
-                                           BasicBlock *BB) {
-  Instruction *FirstNonPHI = &*BB->getFirstNonPHIOrDbg();
-  assert(FirstNonPHI && "block is empty?");
-  Value *CorrespondingVal = findCorrespondingValueIn(Other, FirstNonPHI);
-  if (!CorrespondingVal)
-    return nullptr;
-  BasicBlock *CorrespondingBlock =
-      cast<Instruction>(CorrespondingVal)->getParent();
-  return CorrespondingBlock;
-}
-
-/// Rewrite the BranchInsts in the incoming blocks to \p PHIBlock that are found
-/// in \p Included to branch to BasicBlock \p Replace if they currently branch
-/// to the BasicBlock \p Find.  This is used to fix up the incoming basic blocks
-/// when PHINodes are included in outlined regions.
-///
-/// \param PHIBlock - The BasicBlock containing the PHINodes that need to be
-/// checked.
-/// \param Find - The successor block to be replaced.
-/// \param Replace - The new succesor block to branch to.
-/// \param Included - The set of blocks about to be outlined.
-static void replaceTargetsFromPHINode(BasicBlock *PHIBlock, BasicBlock *Find,
-                                      BasicBlock *Replace,
-                                      DenseSet<BasicBlock *> &Included) {
-  for (PHINode &PN : PHIBlock->phis())
-    for (BasicBlock *Incoming : PN.blocks())
-      // Check if the incoming block is included in the set of blocks being
-      // outlined.
-      if (Included.contains(Incoming))
-        Incoming->getTerminator()->replaceSuccessorWith(Find, Replace);
-}
-
-
-void OutlinableRegion::splitCandidate() {
-  assert(!CandidateSplit && "Candidate already split!");
-
-  Instruction *BackInst = Candidate->backInstruction();
-
-  Instruction *EndInst = nullptr;
-  // Check whether the last instruction is a terminator, if it is, we do
-  // not split on the following instruction. We leave the block as it is.  We
-  // also check that this is not the last instruction in the Module, otherwise
-  // the check for whether the current following instruction matches the
-  // previously recorded instruction will be incorrect.
-  if (!BackInst->isTerminator() ||
-      BackInst->getParent() != &BackInst->getFunction()->back()) {
-    EndInst = Candidate->end()->Inst;
-    assert(EndInst && "Expected an end instruction?");
-  }
-
-  // We check if the current instruction following the last instruction in the
-  // region is the same as the recorded instruction following the last
-  // instruction. If they do not match, there could be problems in rewriting
-  // the program after outlining, so we ignore it.
-  if (!BackInst->isTerminator() && EndInst != BackInst->getNextNode())
-    return;
-
-  Instruction *StartInst = (*Candidate->begin()).Inst;
-  assert(StartInst && "Expected a start instruction?");
-  StartBB = StartInst->getParent();
-  PrevBB = StartBB;
-
-  DenseSet<BasicBlock *> BBSet;
-  Candidate->getBasicBlocks(BBSet);
-
-  // We iterate over the instructions in the region, if we find a PHINode, we
-  // check if there are predecessors outside of the region, if there are,
-  // we ignore this region since we are unable to handle the severing of the
-  // phi node right now.
-
-  // TODO: Handle extraneous inputs for PHINodes through variable number of
-  // inputs, similar to how outputs are handled.
-  BasicBlock::iterator It = StartInst->getIterator();
-  EndBB = BackInst->getParent();
-  BasicBlock *IBlock;
-  BasicBlock *PHIPredBlock = nullptr;
-  bool EndBBTermAndBackInstDifferent = EndBB->getTerminator() != BackInst;
-  while (PHINode *PN = dyn_cast<PHINode>(&*It)) {
-    unsigned NumPredsOutsideRegion = 0;
-    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
-      if (!BBSet.contains(PN->getIncomingBlock(i))) {
-        PHIPredBlock = PN->getIncomingBlock(i);
-        ++NumPredsOutsideRegion;
-        continue;
-      }
-
-      // We must consider the case there the incoming block to the PHINode is
-      // the same as the final block of the OutlinableRegion.  If this is the
-      // case, the branch from this block must also be outlined to be valid.
-      IBlock = PN->getIncomingBlock(i);
-      if (IBlock == EndBB && EndBBTermAndBackInstDifferent) {
-        PHIPredBlock = PN->getIncomingBlock(i);
-        ++NumPredsOutsideRegion;
-      }
-    }
-
-    if (NumPredsOutsideRegion > 1)
-      return;
-    
-    It++;
-  }
-
-  // If the region starts with a PHINode, but is not the initial instruction of
-  // the BasicBlock, we ignore this region for now.
-  if (isa<PHINode>(StartInst) && StartInst != &*StartBB->begin())
-    return;
-  
-  // If the region ends with a PHINode, but does not contain all of the phi node
-  // instructions of the region, we ignore it for now.
-  if (isa<PHINode>(BackInst) &&
-      BackInst != &*std::prev(EndBB->getFirstInsertionPt()))
-    return;
-
-  // The basic block gets split like so:
-  // block:                 block:
-  //   inst1                  inst1
-  //   inst2                  inst2
-  //   region1               br block_to_outline
-  //   region2              block_to_outline:
-  //   region3          ->    region1
-  //   region4                region2
-  //   inst3                  region3
-  //   inst4                  region4
-  //                          br block_after_outline
-  //                        block_after_outline:
-  //                          inst3
-  //                          inst4
-
-  std::string OriginalName = PrevBB->getName().str();
-
-  StartBB = PrevBB->splitBasicBlock(StartInst, OriginalName + "_to_outline");
-  PrevBB->replaceSuccessorsPhiUsesWith(PrevBB, StartBB);
-  // If there was a PHINode with an incoming block outside the region,
-  // make sure is correctly updated in the newly split block.
-  if (PHIPredBlock)
-    PrevBB->replaceSuccessorsPhiUsesWith(PHIPredBlock, PrevBB);
-
-  CandidateSplit = true;
-  if (!BackInst->isTerminator()) {
-    EndBB = EndInst->getParent();
-    FollowBB = EndBB->splitBasicBlock(EndInst, OriginalName + "_after_outline");
-    EndBB->replaceSuccessorsPhiUsesWith(EndBB, FollowBB);
-    FollowBB->replaceSuccessorsPhiUsesWith(PrevBB, FollowBB);
-  } else {
-    EndBB = BackInst->getParent();
-    EndsInBranch = true;
-    FollowBB = nullptr;
-  }
-
-  // Refind the basic block set.
-  BBSet.clear();
-  Candidate->getBasicBlocks(BBSet);
-  // For the phi nodes in the new starting basic block of the region, we
-  // reassign the targets of the basic blocks branching instructions.
-  replaceTargetsFromPHINode(StartBB, PrevBB, StartBB, BBSet);
-  if (FollowBB)
-    replaceTargetsFromPHINode(FollowBB, EndBB, FollowBB, BBSet);
-}
-
-void OutlinableRegion::reattachCandidate() {
-  assert(CandidateSplit && "Candidate is not split!");
-
-  // The basic block gets reattached like so:
-  // block:                        block:
-  //   inst1                         inst1
-  //   inst2                         inst2
-  //   br block_to_outline           region1
-  // block_to_outline:        ->     region2
-  //   region1                       region3
-  //   region2                       region4
-  //   region3                       inst3
-  //   region4                       inst4
-  //   br block_after_outline
-  // block_after_outline:
-  //   inst3
-  //   inst4
-  assert(StartBB != nullptr && "StartBB for Candidate is not defined!");
-
-  assert(PrevBB->getTerminator() && "Terminator removed from PrevBB!");
-  // Make sure PHINode references to the block we are merging into are
-  // updated to be incoming blocks from the predecessor to the current block.
-
-  // NOTE: If this is updated such that the outlined block can have more than
-  // one incoming block to a PHINode, this logic will have to updated
-  // to handle multiple precessors instead.
-
-  // We only need to update this if the outlined section contains a PHINode, if
-  // it does not, then the incoming block was never changed in the first place.
-  // On the other hand, if PrevBB has no predecessors, it means that all
-  // incoming blocks to the first block are contained in the region, and there
-  // will be nothing to update.
-  Instruction *StartInst = (*Candidate->begin()).Inst;
-  if (isa<PHINode>(StartInst) && !PrevBB->hasNPredecessors(0)) {
-    assert(!PrevBB->hasNPredecessorsOrMore(2) &&
-         "PrevBB has more than one predecessor. Should be 0 or 1.");
-    BasicBlock *BeforePrevBB = PrevBB->getSinglePredecessor();
-    PrevBB->replaceSuccessorsPhiUsesWith(PrevBB, BeforePrevBB);
-  }
-  PrevBB->getTerminator()->eraseFromParent();
-
-  // If we reattaching after outlining, we iterate over the phi nodes to
-  // the initial block, and reassign the branch instructions of the incoming
-  // blocks to the block we are remerging into.
-  if (!ExtractedFunction) {
-    DenseSet<BasicBlock *> BBSet;
-    Candidate->getBasicBlocks(BBSet);
-
-    replaceTargetsFromPHINode(StartBB, StartBB, PrevBB, BBSet);
-    if (!EndsInBranch)
-      replaceTargetsFromPHINode(FollowBB, FollowBB, EndBB, BBSet);
-  }
-
-  moveBBContents(*StartBB, *PrevBB);
-
-  BasicBlock *PlacementBB = PrevBB;
-  if (StartBB != EndBB)
-    PlacementBB = EndBB;
-  if (!EndsInBranch && PlacementBB->getUniqueSuccessor() != nullptr) {
-    assert(FollowBB != nullptr && "FollowBB for Candidate is not defined!");
-    assert(PlacementBB->getTerminator() && "Terminator removed from EndBB!");
-    PlacementBB->getTerminator()->eraseFromParent();
-    moveBBContents(*FollowBB, *PlacementBB);
-    PlacementBB->replaceSuccessorsPhiUsesWith(FollowBB, PlacementBB);
-    FollowBB->eraseFromParent();
-  }
-
-  PrevBB->replaceSuccessorsPhiUsesWith(StartBB, PrevBB);
-  StartBB->eraseFromParent();
-
-  // Make sure to save changes back to the StartBB.
-  StartBB = PrevBB;
-  EndBB = nullptr;
-  PrevBB = nullptr;
-  FollowBB = nullptr;
-
-  CandidateSplit = false;
-}
-
-/// Find whether \p V matches the Constants previously found for the \p GVN.
-///
-/// \param V - The value to check for consistency.
-/// \param GVN - The global value number assigned to \p V.
-/// \param GVNToConstant - The mapping of global value number to Constants.
-/// \returns true if the Value matches the Constant mapped to by V and false if
-/// it \p V is a Constant but does not match.
-/// \returns std::nullopt if \p V is not a Constant.
-static std::optional<bool>
-constantMatches(Value *V, unsigned GVN,
-                DenseMap<unsigned, Constant *> &GVNToConstant) {
-  // See if we have a constants
-  Constant *CST = dyn_cast<Constant>(V);
-  if (!CST)
-    return std::nullopt;
-
-  // Holds a mapping from a global value number to a Constant.
-  DenseMap<unsigned, Constant *>::iterator GVNToConstantIt;
-  bool Inserted;
-
-
-  // If we have a constant, try to make a new entry in the GVNToConstant.
-  std::tie(GVNToConstantIt, Inserted) =
-      GVNToConstant.insert(std::make_pair(GVN, CST));
-  // If it was found and is not equal, it is not the same. We do not
-  // handle this case yet, and exit early.
-  if (Inserted || (GVNToConstantIt->second == CST))
-    return true;
-
-  return false;
-}
-
-InstructionCost OutlinableRegion::getBenefit(TargetTransformInfo &TTI) {
-  InstructionCost Benefit = 0;
-
-  // Estimate the benefit of outlining a specific sections of the program.  We
-  // delegate mostly this task to the TargetTransformInfo so that if the target
-  // has specific changes, we can have a more accurate estimate.
-
-  // However, getInstructionCost delegates the code size calculation for
-  // arithmetic instructions to getArithmeticInstrCost in
-  // include/Analysis/TargetTransformImpl.h, where it always estimates that the
-  // code size for a division and remainder instruction to be equal to 4, and
-  // everything else to 1.  This is not an accurate representation of the
-  // division instruction for targets that have a native division instruction.
-  // To be overly conservative, we only add 1 to the number of instructions for
-  // each division instruction.
-  for (IRInstructionData &ID : *Candidate) {
-    Instruction *I = ID.Inst;
-    switch (I->getOpcode()) {
-    case Instruction::FDiv:
-    case Instruction::FRem:
-    case Instruction::SDiv:
-    case Instruction::SRem:
-    case Instruction::UDiv:
-    case Instruction::URem:
-      Benefit += 1;
-      break;
-    default:
-      Benefit += TTI.getInstructionCost(I, TargetTransformInfo::TCK_CodeSize);
-      break;
-    }
-  }
-
-  return Benefit;
-}
-
-/// Check the \p OutputMappings structure for value \p Input, if it exists
-/// it has been used as an output for outlining, and has been renamed, and we
-/// return the new value, otherwise, we return the same value.
-///
-/// \param OutputMappings [in] - The mapping of values to their renamed value
-/// after being used as an output for an outlined region.
-/// \param Input [in] - The value to find the remapped value of, if it exists.
-/// \return The remapped value if it has been renamed, and the same value if has
-/// not.
-static Value *findOutputMapping(const DenseMap<Value *, Value *> OutputMappings,
-                                Value *Input) {
-  auto OutputMapping = OutputMappings.find(Input);
-  if (OutputMapping != OutputMappings.end())
-    return OutputMapping->second;
-  return Input;
-}
-
-/// Find whether \p Region matches the global value numbering to Constant
-/// mapping found so far.
-///
-/// \param Region - The OutlinableRegion we are checking for constants
-/// \param GVNToConstant - The mapping of global value number to Constants.
-/// \param NotSame - The set of global value numbers that do not have the same
-/// constant in each region.
-/// \returns true if all Constants are the same in every use of a Constant in \p
-/// Region and false if not
-static bool
-collectRegionsConstants(OutlinableRegion &Region,
-                        DenseMap<unsigned, Constant *> &GVNToConstant,
-                        DenseSet<unsigned> &NotSame) {
-  bool ConstantsTheSame = true;
-
-  IRSimilarityCandidate &C = *Region.Candidate;
-  for (IRInstructionData &ID : C) {
-
-    // Iterate over the operands in an instruction. If the global value number,
-    // assigned by the IRSimilarityCandidate, has been seen before, we check if
-    // the number has been found to be not the same value in each instance.
-    for (Value *V : ID.OperVals) {
-      std::optional<unsigned> GVNOpt = C.getGVN(V);
-      assert(GVNOpt && "Expected a GVN for operand?");
-      unsigned GVN = *GVNOpt;
-
-      // Check if this global value has been found to not be the same already.
-      if (NotSame.contains(GVN)) {
-        if (isa<Constant>(V))
-          ConstantsTheSame = false;
-        continue;
-      }
-
-      // If it has been the same so far, we check the value for if the
-      // associated Constant value match the previous instances of the same
-      // global value number.  If the global value does not map to a Constant,
-      // it is considered to not be the same value.
-      std::optional<bool> ConstantMatches =
-          constantMatches(V, GVN, GVNToConstant);
-      if (ConstantMatches) {
-        if (*ConstantMatches)
-          continue;
-        else
-          ConstantsTheSame = false;
-      }
-
-      // While this value is a register, it might not have been previously,
-      // make sure we don't already have a constant mapped to this global value
-      // number.
-      if (GVNToConstant.contains(GVN))
-        ConstantsTheSame = false;
-
-      NotSame.insert(GVN);
-    }
-  }
-
-  return ConstantsTheSame;
-}
-
-void OutlinableGroup::findSameConstants(DenseSet<unsigned> &NotSame) {
-  DenseMap<unsigned, Constant *> GVNToConstant;
-
-  for (OutlinableRegion *Region : Regions)
-    collectRegionsConstants(*Region, GVNToConstant, NotSame);
-}
-
-void OutlinableGroup::collectGVNStoreSets(Module &M) {
-  for (OutlinableRegion *OS : Regions)
-    OutputGVNCombinations.insert(OS->GVNStores);
-
-  // We are adding an extracted argument to decide between which output path
-  // to use in the basic block.  It is used in a switch statement and only
-  // needs to be an integer.
-  if (OutputGVNCombinations.size() > 1)
-    ArgumentTypes.push_back(Type::getInt32Ty(M.getContext()));
-}
-
-/// Get the subprogram if it exists for one of the outlined regions.
-///
-/// \param [in] Group - The set of regions to find a subprogram for.
-/// \returns the subprogram if it exists, or nullptr.
-static DISubprogram *getSubprogramOrNull(OutlinableGroup &Group) {
-  for (OutlinableRegion *OS : Group.Regions)
-    if (Function *F = OS->Call->getFunction())
-      if (DISubprogram *SP = F->getSubprogram())
-        return SP;
-
-  return nullptr;
-}
-
-Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group,
-                                     unsigned FunctionNameSuffix) {
-  assert(!Group.OutlinedFunction && "Function is already defined!");
-
-  Type *RetTy = Type::getVoidTy(M.getContext());
-  // All extracted functions _should_ have the same return type at this point
-  // since the similarity identifier ensures that all branches outside of the
-  // region occur in the same place.
-
-  // NOTE: Should we ever move to the model that uses a switch at every point
-  // needed, meaning that we could branch within the region or out, it is
-  // possible that we will need to switch to using the most general case all of
-  // the time.
-  for (OutlinableRegion *R : Group.Regions) {
-    Type *ExtractedFuncType = R->ExtractedFunction->getReturnType();
-    if ((RetTy->isVoidTy() && !ExtractedFuncType->isVoidTy()) ||
-        (RetTy->isIntegerTy(1) && ExtractedFuncType->isIntegerTy(16)))
-      RetTy = ExtractedFuncType;
-  }
-
-  Group.OutlinedFunctionType = FunctionType::get(
-      RetTy, Group.ArgumentTypes, false);
-
-  // These functions will only be called from within the same module, so
-  // we can set an internal linkage.
-  Group.OutlinedFunction = Function::Create(
-      Group.OutlinedFunctionType, GlobalValue::InternalLinkage,
-      "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M);
-
-  // Transfer the swifterr attribute to the correct function parameter.
-  if (Group.SwiftErrorArgument)
-    Group.OutlinedFunction->addParamAttr(*Group.SwiftErrorArgument,
-                                         Attribute::SwiftError);
-
-  Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize);
-  Group.OutlinedFunction->addFnAttr(Attribute::MinSize);
-
-  // If there's a DISubprogram associated with this outlined function, then
-  // emit debug info for the outlined function.
-  if (DISubprogram *SP = getSubprogramOrNull(Group)) {
-    Function *F = Group.OutlinedFunction;
-    // We have a DISubprogram. Get its DICompileUnit.
-    DICompileUnit *CU = SP->getUnit();
-    DIBuilder DB(M, true, CU);
-    DIFile *Unit = SP->getFile();
-    Mangler Mg;
-    // Get the mangled name of the function for the linkage name.
-    std::string Dummy;
-    llvm::raw_string_ostream MangledNameStream(Dummy);
-    Mg.getNameWithPrefix(MangledNameStream, F, false);
-
-    DISubprogram *OutlinedSP = DB.createFunction(
-        Unit /* Context */, F->getName(), Dummy, Unit /* File */,
-        0 /* Line 0 is reserved for compiler-generated code. */,
-        DB.createSubroutineType(DB.getOrCreateTypeArray({})), /* void type */
-        0, /* Line 0 is reserved for compiler-generated code. */
-        DINode::DIFlags::FlagArtificial /* Compiler-generated code. */,
-        /* Outlined code is optimized code by definition. */
-        DISubprogram::SPFlagDefinition | DISubprogram::SPFlagOptimized);
-
-    // Attach subprogram to the function.
-    F->setSubprogram(OutlinedSP);
-    // We're done with the DIBuilder.
-    DB.finalize();
-  }
-
-  return Group.OutlinedFunction;
-}
-
-/// Move each BasicBlock in \p Old to \p New.
-///
-/// \param [in] Old - The function to move the basic blocks from.
-/// \param [in] New - The function to move the basic blocks to.
-/// \param [out] NewEnds - The return blocks of the new overall function.
-static void moveFunctionData(Function &Old, Function &New,
-                             DenseMap<Value *, BasicBlock *> &NewEnds) {
-  for (BasicBlock &CurrBB : llvm::make_early_inc_range(Old)) {
-    CurrBB.removeFromParent();
-    CurrBB.insertInto(&New);
-    Instruction *I = CurrBB.getTerminator();
-
-    // For each block we find a return instruction is, it is a potential exit
-    // path for the function.  We keep track of each block based on the return
-    // value here.
-    if (ReturnInst *RI = dyn_cast<ReturnInst>(I))
-      NewEnds.insert(std::make_pair(RI->getReturnValue(), &CurrBB));
-
-    for (Instruction &Val : CurrBB) {
-      // Since debug-info originates from many different locations in the
-      // program, it will cause incorrect reporting from a debugger if we keep
-      // the same debug instructions. Drop non-intrinsic DbgVariableRecords
-      // here, collect intrinsics for removal later.
-      Val.dropDbgRecords();
-
-      // We must handle the scoping of called functions differently than
-      // other outlined instructions.
-      if (!isa<CallInst>(&Val)) {
-        // Remove the debug information for outlined functions.
-        Val.setDebugLoc(DebugLoc::getDropped());
-
-        // Loop info metadata may contain line locations. Update them to have no
-        // value in the new subprogram since the outlined code could be from
-        // several locations.
-        auto updateLoopInfoLoc = [&New](Metadata *MD) -> Metadata * {
-          if (DISubprogram *SP = New.getSubprogram())
-            if (auto *Loc = dyn_cast_or_null<DILocation>(MD))
-              return DILocation::get(New.getContext(), Loc->getLine(),
-                                     Loc->getColumn(), SP, nullptr);
-          return MD;
-        };
-        updateLoopMetadataDebugLocations(Val, updateLoopInfoLoc);
-        continue;
-      }
-
-      // Edit the scope of called functions inside of outlined functions.
-      if (DISubprogram *SP = New.getSubprogram()) {
-        DILocation *DI = DILocation::get(New.getContext(), 0, 0, SP);
-        Val.setDebugLoc(DI);
-      }
-    }
-  }
-}
-
-/// Find the constants that will need to be lifted into arguments
-/// as they are not the same in each instance of the region.
-///
-/// \param [in] C - The IRSimilarityCandidate containing the region we are
-/// analyzing.
-/// \param [in] NotSame - The set of global value numbers that do not have a
-/// single Constant across all OutlinableRegions similar to \p C.
-/// \param [out] Inputs - The list containing the global value numbers of the
-/// arguments needed for the region of code.
-static void findConstants(IRSimilarityCandidate &C, DenseSet<unsigned> &NotSame,
-                          std::vector<unsigned> &Inputs) {
-  DenseSet<unsigned> Seen;
-  // Iterate over the instructions, and find what constants will need to be
-  // extracted into arguments.
-  for (IRInstructionDataList::iterator IDIt = C.begin(), EndIDIt = C.end();
-       IDIt != EndIDIt; IDIt++) {
-    for (Value *V : (*IDIt).OperVals) {
-      // Since these are stored before any outlining, they will be in the
-      // global value numbering.
-      unsigned GVN = *C.getGVN(V);
-      if (isa<Constant>(V))
-        if (NotSame.contains(GVN) && Seen.insert(GVN).second)
-          Inputs.push_back(GVN);
-    }
-  }
-}
-
-/// Find the GVN for the inputs that have been found by the CodeExtractor.
-///
-/// \param [in] C - The IRSimilarityCandidate containing the region we are
-/// analyzing.
-/// \param [in] CurrentInputs - The set of inputs found by the
-/// CodeExtractor.
-/// \param [in] OutputMappings - The mapping of values that have been replaced
-/// by a new output value.
-/// \param [out] EndInputNumbers - The global value numbers for the extracted
-/// arguments.
-static void mapInputsToGVNs(IRSimilarityCandidate &C,
-                            SetVector<Value *> &CurrentInputs,
-                            const DenseMap<Value *, Value *> &OutputMappings,
-                            std::vector<unsigned> &EndInputNumbers) {
-  // Get the Global Value Number for each input.  We check if the Value has been
-  // replaced by a different value at output, and use the original value before
-  // replacement.
-  for (Value *Input : CurrentInputs) {
-    assert(Input && "Have a nullptr as an input");
-    auto It = OutputMappings.find(Input);
-    if (It != OutputMappings.end())
-      Input = It->second;
-    assert(C.getGVN(Input) && "Could not find a numbering for the given input");
-    EndInputNumbers.push_back(*C.getGVN(Input));
-  }
-}
-
-/// Find the original value for the \p ArgInput values if any one of them was
-/// replaced during a previous extraction.
-///
-/// \param [in] ArgInputs - The inputs to be extracted by the code extractor.
-/// \param [in] OutputMappings - The mapping of values that have been replaced
-/// by a new output value.
-/// \param [out] RemappedArgInputs - The remapped values according to
-/// \p OutputMappings that will be extracted.
-static void
-remapExtractedInputs(const ArrayRef<Value *> ArgInputs,
-                     const DenseMap<Value *, Value *> &OutputMappings,
-                     SetVector<Value *> &RemappedArgInputs) {
-  // Get the global value number for each input that will be extracted as an
-  // argument by the code extractor, remapping if needed for reloaded values.
-  for (Value *Input : ArgInputs) {
-    auto It = OutputMappings.find(Input);
-    if (It != OutputMappings.end())
-      Input = It->second;
-    RemappedArgInputs.insert(Input);
-  }
-}
-
-/// Find the input GVNs and the output values for a region of Instructions.
-/// Using the code extractor, we collect the inputs to the extracted function.
-///
-/// The \p Region can be identified as needing to be ignored in this function.
-/// It should be checked whether it should be ignored after a call to this
-/// function.
-///
-/// \param [in,out] Region - The region of code to be analyzed.
-/// \param [out] InputGVNs - The global value numbers for the extracted
-/// arguments.
-/// \param [in] NotSame - The global value numbers in the region that do not
-/// have the same constant value in the regions structurally similar to
-/// \p Region.
-/// \param [in] OutputMappings - The mapping of values that have been replaced
-/// by a new output value after extraction.
-/// \param [out] ArgInputs - The values of the inputs to the extracted function.
-/// \param [out] Outputs - The set of values extracted by the CodeExtractor
-/// as outputs.
-static void getCodeExtractorArguments(
-    OutlinableRegion &Region, std::vector<unsigned> &InputGVNs,
-    DenseSet<unsigned> &NotSame, DenseMap<Value *, Value *> &OutputMappings,
-    SetVector<Value *> &ArgInputs, SetVector<Value *> &Outputs) {
-  IRSimilarityCandidate &C = *Region.Candidate;
-
-  // OverallInputs are the inputs to the region found by the CodeExtractor,
-  // SinkCands and HoistCands are used by the CodeExtractor to find sunken
-  // allocas of values whose lifetimes are contained completely within the
-  // outlined region. PremappedInputs are the arguments found by the
-  // CodeExtractor, removing conditions such as sunken allocas, but that
-  // may need to be remapped due to the extracted output values replacing
-  // the original values. We use DummyOutputs for this first run of finding
-  // inputs and outputs since the outputs could change during findAllocas,
-  // the correct set of extracted outputs will be in the final Outputs ValueSet.
-  SetVector<Value *> OverallInputs, PremappedInputs, SinkCands, HoistCands,
-      DummyOutputs;
-
-  // Use the code extractor to get the inputs and outputs, without sunken
-  // allocas or removing llvm.assumes.
-  CodeExtractor *CE = Region.CE;
-  CE->findInputsOutputs(OverallInputs, DummyOutputs, SinkCands);
-  assert(Region.StartBB && "Region must have a start BasicBlock!");
-  Function *OrigF = Region.StartBB->getParent();
-  CodeExtractorAnalysisCache CEAC(*OrigF);
-  BasicBlock *Dummy = nullptr;
-
-  // The region may be ineligible due to VarArgs in the parent function. In this
-  // case we ignore the region.
-  if (!CE->isEligible()) {
-    Region.IgnoreRegion = true;
-    return;
-  }
-
-  // Find if any values are going to be sunk into the function when extracted
-  CE->findAllocas(CEAC, SinkCands, HoistCands, Dummy);
-  CE->findInputsOutputs(PremappedInputs, Outputs, SinkCands);
-
-  // TODO: Support regions with sunken allocas: values whose lifetimes are
-  // contained completely within the outlined region.  These are not guaranteed
-  // to be the same in every region, so we must elevate them all to arguments
-  // when they appear.  If these values are not equal, it means there is some
-  // Input in OverallInputs that was removed for ArgInputs.
-  if (OverallInputs.size() != PremappedInputs.size()) {
-    Region.IgnoreRegion = true;
-    return;
-  }
-
-  findConstants(C, NotSame, InputGVNs);
-
-  mapInputsToGVNs(C, OverallInputs, OutputMappings, InputGVNs);
-
-  remapExtractedInputs(PremappedInputs.getArrayRef(), OutputMappings,
-                       ArgInputs);
-
-  // Sort the GVNs, since we now have constants included in the \ref InputGVNs
-  // we need to make sure they are in a deterministic order.
-  stable_sort(InputGVNs);
-}
-
-/// Look over the inputs and map each input argument to an argument in the
-/// overall function for the OutlinableRegions.  This creates a way to replace
-/// the arguments of the extracted function with the arguments of the new
-/// overall function.
-///
-/// \param [in,out] Region - The region of code to be analyzed.
-/// \param [in] InputGVNs - The global value numbering of the input values
-/// collected.
-/// \param [in] ArgInputs - The values of the arguments to the extracted
-/// function.
-static void
-findExtractedInputToOverallInputMapping(OutlinableRegion &Region,
-                                        std::vector<unsigned> &InputGVNs,
-                                        SetVector<Value *> &ArgInputs) {
-
-  IRSimilarityCandidate &C = *Region.Candidate;
-  OutlinableGroup &Group = *Region.Parent;
-
-  // This counts the argument number in the overall function.
-  unsigned TypeIndex = 0;
-
-  // This counts the argument number in the extracted function.
-  unsigned OriginalIndex = 0;
-
-  // Find the mapping of the extracted arguments to the arguments for the
-  // overall function. Since there may be extra arguments in the overall
-  // function to account for the extracted constants, we have two different
-  // counters as we find extracted arguments, and as we come across overall
-  // arguments.
-
-  // Additionally, in our first pass, for the first extracted function,
-  // we find argument locations for the canonical value numbering.  This
-  // numbering overrides any discovered location for the extracted code.
-  for (unsigned InputVal : InputGVNs) {
-    std::optional<unsigned> CanonicalNumberOpt = C.getCanonicalNum(InputVal);
-    assert(CanonicalNumberOpt && "Canonical number not found?");
-    unsigned CanonicalNumber = *CanonicalNumberOpt;
-
-    std::optional<Value *> InputOpt = C.fromGVN(InputVal);
-    assert(InputOpt && "Global value number not found?");
-    Value *Input = *InputOpt;
-
-    auto AggArgIt = Group.CanonicalNumberToAggArg.find(CanonicalNumber);
-
-    if (!Group.InputTypesSet) {
-      Group.ArgumentTypes.push_back(Input->getType());
-      // If the input value has a swifterr attribute, make sure to mark the
-      // argument in the overall function.
-      if (Input->isSwiftError()) {
-        assert(
-            !Group.SwiftErrorArgument &&
-            "Argument already marked with swifterr for this OutlinableGroup!");
-        Group.SwiftErrorArgument = TypeIndex;
-      }
-    }
-
-    // Check if we have a constant. If we do add it to the overall argument
-    // number to Constant map for the region, and continue to the next input.
-    if (Constant *CST = dyn_cast<Constant>(Input)) {
-      if (AggArgIt != Group.CanonicalNumberToAggArg.end())
-        Region.AggArgToConstant.insert(std::make_pair(AggArgIt->second, CST));
-      else {
-        Group.CanonicalNumberToAggArg.insert(
-            std::make_pair(CanonicalNumber, TypeIndex));
-        Region.AggArgToConstant.insert(std::make_pair(TypeIndex, CST));
-      }
-      TypeIndex++;
-      continue;
-    }
-
-    // It is not a constant, we create the mapping from extracted argument list
-    // to the overall argument list, using the canonical location, if it exists.
-    assert(ArgInputs.count(Input) && "Input cannot be found!");
-
-    if (AggArgIt != Group.CanonicalNumberToAggArg.end()) {
-      if (OriginalIndex != AggArgIt->second)
-        Region.ChangedArgOrder = true;
-      Region.ExtractedArgToAgg.insert(
-          std::make_pair(OriginalIndex, AggArgIt->second));
-      Region.AggArgToExtracted.insert(
-          std::make_pair(AggArgIt->second, OriginalIndex));
-    } else {
-      Group.CanonicalNumberToAggArg.insert(
-          std::make_pair(CanonicalNumber, TypeIndex));
-      Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, TypeIndex));
-      Region.AggArgToExtracted.insert(std::make_pair(TypeIndex, OriginalIndex));
-    }
-    OriginalIndex++;
-    TypeIndex++;
-  }
-
-  // If the function type definitions for the OutlinableGroup holding the region
-  // have not been set, set the length of the inputs here.  We should have the
-  // same inputs for all of the different regions contained in the
-  // OutlinableGroup since they are all structurally similar to one another.
-  if (!Group.InputTypesSet) {
-    Group.NumAggregateInputs = TypeIndex;
-    Group.InputTypesSet = true;
-  }
-
-  Region.NumExtractedInputs = OriginalIndex;
-}
-
-/// Check if the \p V has any uses outside of the region other than \p PN.
-///
-/// \param V [in] - The value to check.
-/// \param PHILoc [in] - The location in the PHINode of \p V.
-/// \param PN [in] - The PHINode using \p V.
-/// \param Exits [in] - The potential blocks we exit to from the outlined
-/// region.
-/// \param BlocksInRegion [in] - The basic blocks contained in the region.
-/// \returns true if \p V has any use soutside its region other than \p PN.
-static bool outputHasNonPHI(Value *V, unsigned PHILoc, PHINode &PN,
-                            SmallPtrSet<BasicBlock *, 1> &Exits,
-                            DenseSet<BasicBlock *> &BlocksInRegion) {
-  // We check to see if the value is used by the PHINode from some other
-  // predecessor not included in the region.  If it is, we make sure
-  // to keep it as an output.
-  if (any_of(llvm::seq<unsigned>(0, PN.getNumIncomingValues()),
-             [PHILoc, &PN, V, &BlocksInRegion](unsigned Idx) {
-               return (Idx != PHILoc && V == PN.getIncomingValue(Idx) &&
-                       !BlocksInRegion.contains(PN.getIncomingBlock(Idx)));
-             }))
-    return true;
-
-  // Check if the value is used by any other instructions outside the region.
-  return any_of(V->users(), [&Exits, &BlocksInRegion](User *U) {
-    Instruction *I = dyn_cast<Instruction>(U);
-    if (!I)
-      return false;
-
-    // If the use of the item is inside the region, we skip it.  Uses
-    // inside the region give us useful information about how the item could be
-    // used as an output.
-    BasicBlock *Parent = I->getParent();
-    if (BlocksInRegion.contains(Parent))
-      return false;
-
-    // If it's not a PHINode then we definitely know the use matters.  This
-    // output value will not completely combined with another item in a PHINode
-    // as it is directly reference by another non-phi instruction
-    if (!isa<PHINode>(I))
-      return true;
-
-    // If we have a PHINode outside one of the exit locations, then it
-    // can be considered an outside use as well.  If there is a PHINode
-    // contained in the Exit where this values use matters, it will be
-    // caught when we analyze that PHINode.
-    if (!Exits.contains(Parent))
-      return true;
-
-    return false;
-  });
-}
-
-/// Test whether \p CurrentExitFromRegion contains any PhiNodes that should be
-/// considered outputs. A PHINodes is an output when more than one incoming
-/// value has been marked by the CodeExtractor as an output.
-///
-/// \param CurrentExitFromRegion [in] - The block to analyze.
-/// \param PotentialExitsFromRegion [in] - The potential exit blocks from the
-/// region.
-/// \param RegionBlocks [in] - The basic blocks in the region.
-/// \param Outputs [in, out] - The existing outputs for the region, we may add
-/// PHINodes to this as we find that they replace output values.
-/// \param OutputsReplacedByPHINode [out] - A set containing outputs that are
-/// totally replaced  by a PHINode.
-/// \param OutputsWithNonPhiUses [out] - A set containing outputs that are used
-/// in PHINodes, but have other uses, and should still be considered outputs.
-static void analyzeExitPHIsForOutputUses(
-    BasicBlock *CurrentExitFromRegion,
-    SmallPtrSet<BasicBlock *, 1> &PotentialExitsFromRegion,
-    DenseSet<BasicBlock *> &RegionBlocks, SetVector<Value *> &Outputs,
-    DenseSet<Value *> &OutputsReplacedByPHINode,
-    DenseSet<Value *> &OutputsWithNonPhiUses) {
-  for (PHINode &PN : CurrentExitFromRegion->phis()) {
-    // Find all incoming values from the outlining region.
-    SmallVector<unsigned, 2> IncomingVals;
-    for (unsigned I = 0, E = PN.getNumIncomingValues(); I < E; ++I)
-      if (RegionBlocks.contains(PN.getIncomingBlock(I)))
-        IncomingVals.push_back(I);
-
-    // Do not process PHI if there are no predecessors from region.
-    unsigned NumIncomingVals = IncomingVals.size();
-    if (NumIncomingVals == 0)
-      continue;
-
-    // If there is one predecessor, we mark it as a value that needs to be kept
-    // as an output.
-    if (NumIncomingVals == 1) {
-      Value *V = PN.getIncomingValue(*IncomingVals.begin());
-      OutputsWithNonPhiUses.insert(V);
-      OutputsReplacedByPHINode.erase(V);
-      continue;
-    }
-
-    // This PHINode will be used as an output value, so we add it to our list.
-    Outputs.insert(&PN);
-
-    // Not all of the incoming values should be ignored as other inputs and
-    // outputs may have uses in outlined region.  If they have other uses
-    // outside of the single PHINode we should not skip over it.
-    for (unsigned Idx : IncomingVals) {
-      Value *V = PN.getIncomingValue(Idx);
-      if (!isa<Constant>(V) &&
-          outputHasNonPHI(V, Idx, PN, PotentialExitsFromRegion, RegionBlocks)) {
-        OutputsWithNonPhiUses.insert(V);
-        OutputsReplacedByPHINode.erase(V);
-        continue;
-      }
-      if (!OutputsWithNonPhiUses.contains(V))
-        OutputsReplacedByPHINode.insert(V);
-    }
-  }
-}
-
-// Represents the type for the unsigned number denoting the output number for
-// phi node, along with the canonical number for the exit block.
-using ArgLocWithBBCanon = std::pair<unsigned, unsigned>;
-// The list of canonical numbers for the incoming values to a PHINode.
-using CanonList = SmallVector<unsigned, 2>;
-// The pair type representing the set of canonical values being combined in the
-// PHINode, along with the location data for the PHINode.
-using PHINodeData = std::pair<ArgLocWithBBCanon, CanonList>;
-
-/// Encode \p PND as an integer for easy lookup based on the argument location,
-/// the parent BasicBlock canonical numbering, and the canonical numbering of
-/// the values stored in the PHINode.
-///
-/// \param PND - The data to hash.
-/// \returns The hash code of \p PND.
-static hash_code encodePHINodeData(PHINodeData &PND) {
-  return llvm::hash_combine(llvm::hash_value(PND.first.first),
-                            llvm::hash_value(PND.first.second),
-                            llvm::hash_combine_range(PND.second));
-}
-
-/// Create a special GVN for PHINodes that will be used outside of
-/// the region.  We create a hash code based on the Canonical number of the
-/// parent BasicBlock, the canonical numbering of the values stored in the
-/// PHINode and the aggregate argument location.  This is used to find whether
-/// this PHINode type has been given a canonical numbering already.  If not, we
-/// assign it a value and store it for later use.  The value is returned to
-/// identify different output schemes for the set of regions.
-///
-/// \param Region - The region that \p PN is an output for.
-/// \param PN - The PHINode we are analyzing.
-/// \param Blocks - The blocks for the region we are analyzing.
-/// \param AggArgIdx - The argument \p PN will be stored into.
-/// \returns An optional holding the assigned canonical number, or std::nullopt
-/// if there is some attribute of the PHINode blocking it from being used.
-static std::optional<unsigned> getGVNForPHINode(OutlinableRegion &Region,
-                                                PHINode *PN,
-                                                DenseSet<BasicBlock *> &Blocks,
-                                                unsigned AggArgIdx) {
-  OutlinableGroup &Group = *Region.Parent;
-  IRSimilarityCandidate &Cand = *Region.Candidate;
-  BasicBlock *PHIBB = PN->getParent();
-  CanonList PHIGVNs;
-  Value *Incoming;
-  BasicBlock *IncomingBlock;
-  for (unsigned Idx = 0, EIdx = PN->getNumIncomingValues(); Idx < EIdx; Idx++) {
-    Incoming = PN->getIncomingValue(Idx);
-    IncomingBlock = PN->getIncomingBlock(Idx);
-    // If the incoming block isn't in the region, we don't have to worry about
-    // this incoming value.
-    if (!Blocks.contains(IncomingBlock))
-      continue;
-
-    // If we cannot find a GVN, and the incoming block is included in the region
-    // this means that the input to the PHINode is not included in the region we
-    // are trying to analyze, meaning, that if it was outlined, we would be
-    // adding an extra input.  We ignore this case for now, and so ignore the
-    // region.
-    std::optional<unsigned> OGVN = Cand.getGVN(Incoming);
-    if (!OGVN) {
-      Region.IgnoreRegion = true;
-      return std::nullopt;
-    }
-
-    // Collect the canonical numbers of the values in the PHINode.
-    unsigned GVN = *OGVN;
-    OGVN = Cand.getCanonicalNum(GVN);
-    assert(OGVN && "No GVN found for incoming value?");
-    PHIGVNs.push_back(*OGVN);
-
-    // Find the incoming block and use the canonical numbering as well to define
-    // the hash for the PHINode.
-    OGVN = Cand.getGVN(IncomingBlock);
-
-    // If there is no number for the incoming block, it is because we have
-    // split the candidate basic blocks.  So we use the previous block that it
-    // was split from to find the valid global value numbering for the PHINode.
-    if (!OGVN) {
-      assert(Cand.getStartBB() == IncomingBlock &&
-             "Unknown basic block used in exit path PHINode.");
-
-      BasicBlock *PrevBlock = nullptr;
-      // Iterate over the predecessors to the incoming block of the
-      // PHINode, when we find a block that is not contained in the region
-      // we know that this is the first block that we split from, and should
-      // have a valid global value numbering.
-      for (BasicBlock *Pred : predecessors(IncomingBlock))
-        if (!Blocks.contains(Pred)) {
-          PrevBlock = Pred;
-          break;
-        }
-      assert(PrevBlock && "Expected a predecessor not in the reigon!");
-      OGVN = Cand.getGVN(PrevBlock);
-    }
-    GVN = *OGVN;
-    OGVN = Cand.getCanonicalNum(GVN);
-    assert(OGVN && "No GVN found for incoming block?");
-    PHIGVNs.push_back(*OGVN);
-  }
-
-  // Now that we have the GVNs for the incoming values, we are going to combine
-  // them with the GVN of the incoming bock, and the output location of the
-  // PHINode to generate a hash value representing this instance of the PHINode.
-  DenseMap<hash_code, unsigned>::iterator GVNToPHIIt;
-  DenseMap<unsigned, PHINodeData>::iterator PHIToGVNIt;
-  std::optional<unsigned> BBGVN = Cand.getGVN(PHIBB);
-  assert(BBGVN && "Could not find GVN for the incoming block!");
-
-  BBGVN = Cand.getCanonicalNum(*BBGVN);
-  assert(BBGVN && "Could not find canonical number for the incoming block!");
-  // Create a pair of the exit block canonical value, and the aggregate
-  // argument location, connected to the canonical numbers stored in the
-  // PHINode.
-  PHINodeData TemporaryPair =
-      std::make_pair(std::make_pair(*BBGVN, AggArgIdx), PHIGVNs);
-  hash_code PHINodeDataHash = encodePHINodeData(TemporaryPair);
-
-  // Look for and create a new entry in our connection between canonical
-  // numbers for PHINodes, and the set of objects we just created.
-  GVNToPHIIt = Group.GVNsToPHINodeGVN.find(PHINodeDataHash);
-  if (GVNToPHIIt == Group.GVNsToPHINodeGVN.end()) {
-    bool Inserted = false;
-    std::tie(PHIToGVNIt, Inserted) = Group.PHINodeGVNToGVNs.insert(
-        std::make_pair(Group.PHINodeGVNTracker, TemporaryPair));
-    std::tie(GVNToPHIIt, Inserted) = Group.GVNsToPHINodeGVN.insert(
-        std::make_pair(PHINodeDataHash, Group.PHINodeGVNTracker--));
-  }
-
-  return GVNToPHIIt->second;
-}
-
-/// Create a mapping of the output arguments for the \p Region to the output
-/// arguments of the overall outlined function.
-///
-/// \param [in,out] Region - The region of code to be analyzed.
-/// \param [in] Outputs - The values found by the code extractor.
-static void
-findExtractedOutputToOverallOutputMapping(Module &M, OutlinableRegion &Region,
-                                          SetVector<Value *> &Outputs) {
-  OutlinableGroup &Group = *Region.Parent;
-  IRSimilarityCandidate &C = *Region.Candidate;
-
-  SmallVector<BasicBlock *> BE;
-  DenseSet<BasicBlock *> BlocksInRegion;
-  C.getBasicBlocks(BlocksInRegion, BE);
-
-  // Find the exits to the region.
-  SmallPtrSet<BasicBlock *, 1> Exits;
-  for (BasicBlock *Block : BE)
-    for (BasicBlock *Succ : successors(Block))
-      if (!BlocksInRegion.contains(Succ))
-        Exits.insert(Succ);
-
-  // After determining which blocks exit to PHINodes, we add these PHINodes to
-  // the set of outputs to be processed.  We also check the incoming values of
-  // the PHINodes for whether they should no longer be considered outputs.
-  DenseSet<Value *> OutputsReplacedByPHINode;
-  DenseSet<Value *> OutputsWithNonPhiUses;
-  for (BasicBlock *ExitBB : Exits)
-    analyzeExitPHIsForOutputUses(ExitBB, Exits, BlocksInRegion, Outputs,
-                                 OutputsReplacedByPHINode,
-                                 OutputsWithNonPhiUses);
-
-  // This counts the argument number in the extracted function.
-  unsigned OriginalIndex = Region.NumExtractedInputs;
-
-  // This counts the argument number in the overall function.
-  unsigned TypeIndex = Group.NumAggregateInputs;
-  bool TypeFound;
-  DenseSet<unsigned> AggArgsUsed;
-
-  // Iterate over the output types and identify if there is an aggregate pointer
-  // type whose base type matches the current output type. If there is, we mark
-  // that we will use this output register for this value. If not we add another
-  // type to the overall argument type list. We also store the GVNs used for
-  // stores to identify which values will need to be moved into an special
-  // block that holds the stores to the output registers.
-  for (Value *Output : Outputs) {
-    TypeFound = false;
-    // We can do this since it is a result value, and will have a number
-    // that is necessarily the same. BUT if in the future, the instructions
-    // do not have to be in same order, but are functionally the same, we will
-    // have to use a different scheme, as one-to-one correspondence is not
-    // guaranteed.
-    unsigned ArgumentSize = Group.ArgumentTypes.size();
-
-    // If the output is combined in a PHINode, we make sure to skip over it.
-    if (OutputsReplacedByPHINode.contains(Output))
-      continue;
-
-    unsigned AggArgIdx = 0;
-    for (unsigned Jdx = TypeIndex; Jdx < ArgumentSize; Jdx++) {
-      if (!isa<PointerType>(Group.ArgumentTypes[Jdx]))
-        continue;
-
-      if (!AggArgsUsed.insert(Jdx).second)
-        continue;
-
-      TypeFound = true;
-      Region.ExtractedArgToAgg.insert(std::make_pair(OriginalIndex, Jdx));
-      Region.AggArgToExtracted.insert(std::make_pair(Jdx, OriginalIndex));
-      AggArgIdx = Jdx;
-      break;
-    }
-
-    // We were unable to find an unused type in the output type set that matches
-    // the output, so we add a pointer type to the argument types of the overall
-    // function to handle this output and create a mapping to it.
-    if (!TypeFound) {
-      Group.ArgumentTypes.push_back(PointerType::get(Output->getContext(),
-          M.getDataLayout().getAllocaAddrSpace()));
-      // Mark the new pointer type as the last value in the aggregate argument
-      // list.
-      unsigned ArgTypeIdx = Group.ArgumentTypes.size() - 1;
-      AggArgsUsed.insert(ArgTypeIdx);
-      Region.ExtractedArgToAgg.insert(
-          std::make_pair(OriginalIndex, ArgTypeIdx));
-      Region.AggArgToExtracted.insert(
-          std::make_pair(ArgTypeIdx, OriginalIndex));
-      AggArgIdx = ArgTypeIdx;
-    }
-
-    // TODO: Adapt to the extra input from the PHINode.
-    PHINode *PN = dyn_cast<PHINode>(Output);
-
-    std::optional<unsigned> GVN;
-    if (PN && !BlocksInRegion.contains(PN->getParent())) {
-      // Values outside the region can be combined into PHINode when we
-      // have multiple exits. We collect both of these into a list to identify
-      // which values are being used in the PHINode. Each list identifies a
-      // different PHINode, and a different output. We store the PHINode as it's
-      // own canonical value.  These canonical values are also dependent on the
-      // output argument it is saved to.
-
-      // If two PHINodes have the same canonical values, but different aggregate
-      // argument locations, then they will have distinct Canonical Values.
-      GVN = getGVNForPHINode(Region, PN, BlocksInRegion, AggArgIdx);
-      if (!GVN)
-        return;
-    } else {
-      // If we do not have a PHINode we use the global value numbering for the
-      // output value, to find the canonical number to add to the set of stored
-      // values.
-      GVN = C.getGVN(Output);
-      GVN = C.getCanonicalNum(*GVN);
-    }
-
-    // Each region has a potentially unique set of outputs.  We save which
-    // values are output in a list of canonical values so we can differentiate
-    // among the different store schemes.
-    Region.GVNStores.push_back(*GVN);
-
-    OriginalIndex++;
-    TypeIndex++;
-  }
-
-  // We sort the stored values to make sure that we are not affected by analysis
-  // order when determining what combination of items were stored.
-  stable_sort(Region.GVNStores);
-}
-
-void IROutliner::findAddInputsOutputs(Module &M, OutlinableRegion &Region,
-                                      DenseSet<unsigned> &NotSame) {
-  std::vector<unsigned> Inputs;
-  SetVector<Value *> ArgInputs, Outputs;
-
-  getCodeExtractorArguments(Region, Inputs, NotSame, OutputMappings, ArgInputs,
-                            Outputs);
-
-  if (Region.IgnoreRegion)
-    return;
-
-  // Map the inputs found by the CodeExtractor to the arguments found for
-  // the overall function.
-  findExtractedInputToOverallInputMapping(Region, Inputs, ArgInputs);
-
-  // Map the outputs found by the CodeExtractor to the arguments found for
-  // the overall function.
-  findExtractedOutputToOverallOutputMapping(M, Region, Outputs);
-}
-
-/// Replace the extracted function in the Region with a call to the overall
-/// function constructed from the deduplicated similar regions, replacing and
-/// remapping the values passed to the extracted function as arguments to the
-/// new arguments of the overall function.
-///
-/// \param [in] M - The module to outline from.
-/// \param [in] Region - The regions of extracted code to be replaced with a new
-/// function.
-/// \returns a call instruction with the replaced function.
-CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) {
-  std::vector<Value *> NewCallArgs;
-  DenseMap<unsigned, unsigned>::iterator ArgPair;
-
-  OutlinableGroup &Group = *Region.Parent;
-  CallInst *Call = Region.Call;
-  assert(Call && "Call to replace is nullptr?");
-  Function *AggFunc = Group.OutlinedFunction;
-  assert(AggFunc && "Function to replace with is nullptr?");
-
-  // If the arguments are the same size, there are not values that need to be
-  // made into an argument, the argument ordering has not been change, or
-  // different output registers to handle.  We can simply replace the called
-  // function in this case.
-  if (!Region.ChangedArgOrder && AggFunc->arg_size() == Call->arg_size()) {
-    LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
-                      << *AggFunc << " with same number of arguments\n");
-    Call->setCalledFunction(AggFunc);
-    return Call;
-  }
-
-  // We have a different number of arguments than the new function, so
-  // we need to use our previously mappings off extracted argument to overall
-  // function argument, and constants to overall function argument to create the
-  // new argument list.
-  for (unsigned AggArgIdx = 0; AggArgIdx < AggFunc->arg_size(); AggArgIdx++) {
-
-    if (AggArgIdx == AggFunc->arg_size() - 1 &&
-        Group.OutputGVNCombinations.size() > 1) {
-      // If we are on the last argument, and we need to differentiate between
-      // output blocks, add an integer to the argument list to determine
-      // what block to take
-      LLVM_DEBUG(dbgs() << "Set switch block argument to "
-                        << Region.OutputBlockNum << "\n");
-      NewCallArgs.push_back(ConstantInt::get(Type::getInt32Ty(M.getContext()),
-                                             Region.OutputBlockNum));
-      continue;
-    }
-
-    ArgPair = Region.AggArgToExtracted.find(AggArgIdx);
-    if (ArgPair != Region.AggArgToExtracted.end()) {
-      Value *ArgumentValue = Call->getArgOperand(ArgPair->second);
-      // If we found the mapping from the extracted function to the overall
-      // function, we simply add it to the argument list.  We use the same
-      // value, it just needs to honor the new order of arguments.
-      LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
-                        << *ArgumentValue << "\n");
-      NewCallArgs.push_back(ArgumentValue);
-      continue;
-    }
-
-    // If it is a constant, we simply add it to the argument list as a value.
-    if (auto It = Region.AggArgToConstant.find(AggArgIdx);
-        It != Region.AggArgToConstant.end()) {
-      Constant *CST = It->second;
-      LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to value "
-                        << *CST << "\n");
-      NewCallArgs.push_back(CST);
-      continue;
-    }
-
-    // Add a nullptr value if the argument is not found in the extracted
-    // function.  If we cannot find a value, it means it is not in use
-    // for the region, so we should not pass anything to it.
-    LLVM_DEBUG(dbgs() << "Setting argument " << AggArgIdx << " to nullptr\n");
-    NewCallArgs.push_back(ConstantPointerNull::get(
-        static_cast<PointerType *>(AggFunc->getArg(AggArgIdx)->getType())));
-  }
-
-  LLVM_DEBUG(dbgs() << "Replace call to " << *Call << " with call to "
-                    << *AggFunc << " with new set of arguments\n");
-  // Create the new call instruction and erase the old one.
-  Call = CallInst::Create(AggFunc->getFunctionType(), AggFunc, NewCallArgs, "",
-                          Call->getIterator());
-
-  // It is possible that the call to the outlined function is either the first
-  // instruction is in the new block, the last instruction, or both.  If either
-  // of these is the case, we need to make sure that we replace the instruction
-  // in the IRInstructionData struct with the new call.
-  CallInst *OldCall = Region.Call;
-  if (Region.NewFront->Inst == OldCall)
-    Region.NewFront->Inst = Call;
-  if (Region.NewBack->Inst == OldCall)
-    Region.NewBack->Inst = Call;
-
-  // Transfer any debug information.
-  Call->setDebugLoc(Region.Call->getDebugLoc());
-  // Since our output may determine which branch we go to, we make sure to
-  // propagate this new call value through the module.
-  OldCall->replaceAllUsesWith(Call);
-
-  // Remove the old instruction.
-  OldCall->eraseFromParent();
-  Region.Call = Call;
-
-  // Make sure that the argument in the new function has the SwiftError
-  // argument.
-  if (Group.SwiftErrorArgument)
-    Call->addParamAttr(*Group.SwiftErrorArgument, Attribute::SwiftError);
-
-  return Call;
-}
-
-/// Find or create a BasicBlock in the outlined function containing PhiBlocks
-/// for \p RetVal.
-///
-/// \param Group - The OutlinableGroup containing the information about the
-/// overall outlined function.
-/// \param RetVal - The return value or exit option that we are currently
-/// evaluating.
-/// \returns The found or newly created BasicBlock to contain the needed
-/// PHINodes to be used as outputs.
-static BasicBlock *findOrCreatePHIBlock(OutlinableGroup &Group, Value *RetVal) {
-  // Find if a PHIBlock exists for this return value already.  If it is
-  // the first time we are analyzing this, we will not, so we record it.
-  auto [PhiBlockForRetVal, Inserted] = Group.PHIBlocks.try_emplace(RetVal);
-  if (!Inserted)
-    return PhiBlockForRetVal->second;
-
-  auto ReturnBlockForRetVal = Group.EndBBs.find(RetVal);
-  assert(ReturnBlockForRetVal != Group.EndBBs.end() &&
-         "Could not find output value!");
-  BasicBlock *ReturnBB = ReturnBlockForRetVal->second;
-
-  // If we did not find a block, we create one, and insert it into the
-  // overall function and record it.
-  BasicBlock *PHIBlock = BasicBlock::Create(ReturnBB->getContext(), "phi_block",
-                                            ReturnBB->getParent());
-  PhiBlockForRetVal->second = PHIBlock;
-
-  // We replace all branches to the return block in the newly created outlined
-  // function to point to the new PHIBlock.
-  ReturnBB->replaceAllUsesWith(PHIBlock);
-
-  UncondBrInst::Create(ReturnBB, PHIBlock);
-
-  return PhiBlockForRetVal->second;
-}
-
-/// For the function call now representing the \p Region, find the passed value
-/// to that call that represents Argument \p A at the call location if the
-/// call has already been replaced with a call to the  overall, aggregate
-/// function.
-///
-/// \param A - The Argument to get the passed value for.
-/// \param Region - The extracted Region corresponding to the outlined function.
-/// \returns The Value representing \p A at the call site.
-static Value *
-getPassedArgumentInAlreadyOutlinedFunction(const Argument *A,
-                                           const OutlinableRegion &Region) {
-  // If we don't need to adjust the argument number at all (since the call
-  // has already been replaced by a call to the overall outlined function)
-  // we can just get the specified argument.
-  return Region.Call->getArgOperand(A->getArgNo());
-}
-
-/// For the function call now representing the \p Region, find the passed value
-/// to that call that represents Argument \p A at the call location if the
-/// call has only been replaced by the call to the aggregate function.
-///
-/// \param A - The Argument to get the passed value for.
-/// \param Region - The extracted Region corresponding to the outlined function.
-/// \returns The Value representing \p A at the call site.
-static Value *
-getPassedArgumentAndAdjustArgumentLocation(const Argument *A,
-                                           const OutlinableRegion &Region) {
-  unsigned ArgNum = A->getArgNo();
-  
-  // If it is a constant, we can look at our mapping from when we created
-  // the outputs to figure out what the constant value is.
-  if (auto It = Region.AggArgToConstant.find(ArgNum);
-      It != Region.AggArgToConstant.end())
-    return It->second;
-
-  // If it is not a constant, and we are not looking at the overall function, we
-  // need to adjust which argument we are looking at.
-  ArgNum = Region.AggArgToExtracted.find(ArgNum)->second;
-  return Region.Call->getArgOperand(ArgNum);
-}
-
-/// Find the canonical numbering for the incoming Values into the PHINode \p PN.
-///
-/// \param PN [in] - The PHINode that we are finding the canonical numbers for.
-/// \param Region [in] - The OutlinableRegion containing \p PN.
-/// \param OutputMappings [in] - The mapping of output values from outlined
-/// region to their original values.
-/// \param CanonNums [out] - The canonical numbering for the incoming values to
-/// \p PN paired with their incoming block.
-/// \param ReplacedWithOutlinedCall - A flag to use the extracted function call
-/// of \p Region rather than the overall function's call.
-static void findCanonNumsForPHI(
-    PHINode *PN, OutlinableRegion &Region,
-    const DenseMap<Value *, Value *> &OutputMappings,
-    SmallVector<std::pair<unsigned, BasicBlock *>> &CanonNums,
-    bool ReplacedWithOutlinedCall = true) {
-  // Iterate over the incoming values.
-  for (unsigned Idx = 0, EIdx = PN->getNumIncomingValues(); Idx < EIdx; Idx++) {
-    Value *IVal = PN->getIncomingValue(Idx);
-    BasicBlock *IBlock = PN->getIncomingBlock(Idx);
-    // If we have an argument as incoming value, we need to grab the passed
-    // value from the call itself.
-    if (Argument *A = dyn_cast<Argument>(IVal)) {
-      if (ReplacedWithOutlinedCall)
-        IVal = getPassedArgumentInAlreadyOutlinedFunction(A, Region);
-      else
-        IVal = getPassedArgumentAndAdjustArgumentLocation(A, Region);
-    }
-
-    // Get the original value if it has been replaced by an output value.
-    IVal = findOutputMapping(OutputMappings, IVal);
-
-    // Find and add the canonical number for the incoming value.
-    std::optional<unsigned> GVN = Region.Candidate->getGVN(IVal);
-    assert(GVN && "No GVN for incoming value");
-    std::optional<unsigned> CanonNum = Region.Candidate->getCanonicalNum(*GVN);
-    assert(CanonNum && "No Canonical Number for GVN");
-    CanonNums.push_back(std::make_pair(*CanonNum, IBlock));
-  }
-}
-
-/// Find, or add PHINode \p PN to the combined PHINode Block \p OverallPHIBlock
-/// in order to condense the number of instructions added to the outlined
-/// function.
-///
-/// \param PN [in] - The PHINode that we are finding the canonical numbers for.
-/// \param Region [in] - The OutlinableRegion containing \p PN.
-/// \param OverallPhiBlock [in] - The overall PHIBlock we are trying to find
-/// \p PN in.
-/// \param OutputMappings [in] - The mapping of output values from outlined
-/// region to their original values.
-/// \param UsedPHIs [in, out] - The PHINodes in the block that have already been
-/// matched.
-/// \return the newly found or created PHINode in \p OverallPhiBlock.
-static PHINode*
-findOrCreatePHIInBlock(PHINode &PN, OutlinableRegion &Region,
-                       BasicBlock *OverallPhiBlock,
-                       const DenseMap<Value *, Value *> &OutputMappings,
-                       DenseSet<PHINode *> &UsedPHIs) {
-  OutlinableGroup &Group = *Region.Parent;
-  
-  
-  // A list of the canonical numbering assigned to each incoming value, paired
-  // with the incoming block for the PHINode passed into this function.
-  SmallVector<std::pair<unsigned, BasicBlock *>> PNCanonNums;
-
-  // We have to use the extracted function since we have merged this region into
-  // the overall function yet.  We make sure to reassign the argument numbering
-  // since it is possible that the argument ordering is different between the
-  // functions.
-  findCanonNumsForPHI(&PN, Region, OutputMappings, PNCanonNums,
-                      /* ReplacedWithOutlinedCall = */ false);
-
-  OutlinableRegion *FirstRegion = Group.Regions[0];
-
-  // A list of the canonical numbering assigned to each incoming value, paired
-  // with the incoming block for the PHINode that we are currently comparing
-  // the passed PHINode to.
-  SmallVector<std::pair<unsigned, BasicBlock *>> CurrentCanonNums;
-
-  // Find the Canonical Numbering for each PHINode, if it matches, we replace
-  // the uses of the PHINode we are searching for, with the found PHINode.
-  for (PHINode &CurrPN : OverallPhiBlock->phis()) {
-    // If this PHINode has already been matched to another PHINode to be merged,
-    // we skip it.
-    if (UsedPHIs.contains(&CurrPN))
-      continue;
-
-    CurrentCanonNums.clear();
-    findCanonNumsForPHI(&CurrPN, *FirstRegion, OutputMappings, CurrentCanonNums,
-                        /* ReplacedWithOutlinedCall = */ true);
-
-    // If the list of incoming values is not the same length, then they cannot
-    // match since there is not an analogue for each incoming value.
-    if (PNCanonNums.size() != CurrentCanonNums.size())
-      continue;
-
-    bool FoundMatch = true;
-
-    // We compare the canonical value for each incoming value in the passed
-    // in PHINode to one already present in the outlined region.  If the
-    // incoming values do not match, then the PHINodes do not match.
-
-    // We also check to make sure that the incoming block matches as well by
-    // finding the corresponding incoming block in the combined outlined region
-    // for the current outlined region.
-    for (unsigned Idx = 0, Edx = PNCanonNums.size(); Idx < Edx; ++Idx) {
-      std::pair<unsigned, BasicBlock *> ToCompareTo = CurrentCanonNums[Idx];
-      std::pair<unsigned, BasicBlock *> ToAdd = PNCanonNums[Idx];
-      if (ToCompareTo.first != ToAdd.first) {
-        FoundMatch = false;
-        break;
-      }
-
-      BasicBlock *CorrespondingBlock =
-          Region.findCorrespondingBlockIn(*FirstRegion, ToAdd.second);
-      assert(CorrespondingBlock && "Found block is nullptr");
-      if (CorrespondingBlock != ToCompareTo.second) {
-        FoundMatch = false;
-        break;
-      }
-    }
-
-    // If all incoming values and branches matched, then we can merge
-    // into the found PHINode.
-    if (FoundMatch) {
-      UsedPHIs.insert(&CurrPN);
-      return &CurrPN;
-    }
-  }
-
-  // If we've made it here, it means we weren't able to replace the PHINode, so
-  // we must insert it ourselves.
-  PHINode *NewPN = cast<PHINode>(PN.clone());
-  NewPN->insertBefore(OverallPhiBlock->begin());
-  for (unsigned Idx = 0, Edx = NewPN->getNumIncomingValues(); Idx < Edx;
-       Idx++) {
-    Value *IncomingVal = NewPN->getIncomingValue(Idx);
-    BasicBlock *IncomingBlock = NewPN->getIncomingBlock(Idx);
-
-    // Find corresponding basic block in the overall function for the incoming
-    // block.
-    BasicBlock *BlockToUse =
-        Region.findCorrespondingBlockIn(*FirstRegion, IncomingBlock);
-    NewPN->setIncomingBlock(Idx, BlockToUse);
-
-    // If we have an argument we make sure we replace using the argument from
-    // the correct function.
-    if (Argument *A = dyn_cast<Argument>(IncomingVal)) {
-      Value *Val = Group.OutlinedFunction->getArg(A->getArgNo());
-      NewPN->setIncomingValue(Idx, Val);
-      continue;
-    }
-    
-    // Find the corresponding value in the overall function.
-    IncomingVal = findOutputMapping(OutputMappings, IncomingVal);
-    Value *Val = Region.findCorrespondingValueIn(*FirstRegion, IncomingVal);
-    assert(Val && "Value is nullptr?");
-    auto RemappedIt = FirstRegion->RemappedArguments.find(Val);
-    if (RemappedIt != FirstRegion->RemappedArguments.end())
-      Val = RemappedIt->second;
-    NewPN->setIncomingValue(Idx, Val);
-  }
-  return NewPN;
-}
-
-// Within an extracted function, replace the argument uses of the extracted
-// region with the arguments of the function for an OutlinableGroup.
-//
-/// \param [in] Region - The region of extracted code to be changed.
-/// \param [in,out] OutputBBs - The BasicBlock for the output stores for this
-/// region.
-/// \param [in] FirstFunction - A flag to indicate whether we are using this
-/// function to define the overall outlined function for all the regions, or
-/// if we are operating on one of the following regions.
-static void
-replaceArgumentUses(OutlinableRegion &Region,
-                    DenseMap<Value *, BasicBlock *> &OutputBBs,
-                    const DenseMap<Value *, Value *> &OutputMappings,
-                    bool FirstFunction = false) {
-  OutlinableGroup &Group = *Region.Parent;
-  assert(Region.ExtractedFunction && "Region has no extracted function?");
-
-  Function *DominatingFunction = Region.ExtractedFunction;
-  if (FirstFunction)
-    DominatingFunction = Group.OutlinedFunction;
-  DominatorTree DT(*DominatingFunction);
-  DenseSet<PHINode *> UsedPHIs;
-
-  for (unsigned ArgIdx = 0; ArgIdx < Region.ExtractedFunction->arg_size();
-       ArgIdx++) {
-    assert(Region.ExtractedArgToAgg.contains(ArgIdx) &&
-           "No mapping from extracted to outlined?");
-    unsigned AggArgIdx = Region.ExtractedArgToAgg.find(ArgIdx)->second;
-    Argument *AggArg = Group.OutlinedFunction->getArg(AggArgIdx);
-    Argument *Arg = Region.ExtractedFunction->getArg(ArgIdx);
-    // The argument is an input, so we can simply replace it with the overall
-    // argument value
-    if (ArgIdx < Region.NumExtractedInputs) {
-      LLVM_DEBUG(dbgs() << "Replacing uses of input " << *Arg << " in function "
-                        << *Region.ExtractedFunction << " with " << *AggArg
-                        << " in function " << *Group.OutlinedFunction << "\n");
-      Arg->replaceAllUsesWith(AggArg);
-      Value *V = Region.Call->getArgOperand(ArgIdx);
-      Region.RemappedArguments.insert(std::make_pair(V, AggArg));
-      continue;
-    }
-
-    // If we are replacing an output, we place the store value in its own
-    // block inside the overall function before replacing the use of the output
-    // in the function.
-    assert(Arg->hasOneUse() && "Output argument can only have one use");
-    User *InstAsUser = Arg->user_back();
-    assert(InstAsUser && "User is nullptr!");
-
-    Instruction *I = cast<Instruction>(InstAsUser);
-    BasicBlock *BB = I->getParent();
-    SmallVector<BasicBlock *, 4> Descendants;
-    DT.getDescendants(BB, Descendants);
-    bool EdgeAdded = false;
-    if (Descendants.size() == 0) {
-      EdgeAdded = true;
-      DT.insertEdge(&DominatingFunction->getEntryBlock(), BB);
-      DT.getDescendants(BB, Descendants);
-    }
-
-    // Iterate over the following blocks, looking for return instructions,
-    // if we find one, find the corresponding output block for the return value
-    // and move our store instruction there.
-    for (BasicBlock *DescendBB : Descendants) {
-      ReturnInst *RI = dyn_cast<ReturnInst>(DescendBB->getTerminator());
-      if (!RI)
-        continue;
-      Value *RetVal = RI->getReturnValue();
-      auto VBBIt = OutputBBs.find(RetVal);
-      assert(VBBIt != OutputBBs.end() && "Could not find output value!");
-
-      // If this is storing a PHINode, we must make sure it is included in the
-      // overall function.
-      StoreInst *SI = cast<StoreInst>(I);
-
-      Value *ValueOperand = SI->getValueOperand();
-
-      StoreInst *NewI = cast<StoreInst>(I->clone());
-      NewI->setDebugLoc(DebugLoc::getDropped());
-      BasicBlock *OutputBB = VBBIt->second;
-      NewI->insertInto(OutputBB, OutputBB->end());
-      LLVM_DEBUG(dbgs() << "Move store for instruction " << *I << " to "
-                        << *OutputBB << "\n");
-
-      // If this is storing a PHINode, we must make sure it is included in the
-      // overall function.
-      if (!isa<PHINode>(ValueOperand) ||
-          Region.Candidate->getGVN(ValueOperand).has_value()) {
-        if (FirstFunction)
-          continue;
-        Value *CorrVal =
-            Region.findCorrespondingValueIn(*Group.Regions[0], ValueOperand);
-        assert(CorrVal && "Value is nullptr?");
-        NewI->setOperand(0, CorrVal);
-        continue;
-      }
-      PHINode *PN = cast<PHINode>(SI->getValueOperand());
-      // If it has a value, it was not split by the code extractor, which
-      // is what we are looking for.
-      if (Region.Candidate->getGVN(PN))
-        continue;
-
-      // We record the parent block for the PHINode in the Region so that
-      // we can exclude it from checks later on.
-      Region.PHIBlocks.insert(std::make_pair(RetVal, PN->getParent()));
-
-      // If this is the first function, we do not need to worry about mergiing
-      // this with any other block in the overall outlined function, so we can
-      // just continue.
-      if (FirstFunction) {
-        BasicBlock *PHIBlock = PN->getParent();
-        Group.PHIBlocks.insert(std::make_pair(RetVal, PHIBlock));
-        continue;
-      }
-
-      // We look for the aggregate block that contains the PHINodes leading into
-      // this exit path. If we can't find one, we create one.
-      BasicBlock *OverallPhiBlock = findOrCreatePHIBlock(Group, RetVal);
-
-      // For our PHINode, we find the combined canonical numbering, and
-      // attempt to find a matching PHINode in the overall PHIBlock.  If we
-      // cannot, we copy the PHINode and move it into this new block.
-      PHINode *NewPN = findOrCreatePHIInBlock(*PN, Region, OverallPhiBlock,
-                                              OutputMappings, UsedPHIs);
-      NewI->setOperand(0, NewPN);
-    }
-
-    // If we added an edge for basic blocks without a predecessor, we remove it
-    // here.
-    if (EdgeAdded)
-      DT.deleteEdge(&DominatingFunction->getEntryBlock(), BB);
-    I->eraseFromParent();
-
-    LLVM_DEBUG(dbgs() << "Replacing uses of output " << *Arg << " in function "
-                      << *Region.ExtractedFunction << " with " << *AggArg
-                      << " in function " << *Group.OutlinedFunction << "\n");
-    Arg->replaceAllUsesWith(AggArg);
-  }
-}
-
-/// Within an extracted function, replace the constants that need to be lifted
-/// into arguments with the actual argument.
-///
-/// \param Region [in] - The region of extracted code to be changed.
-void replaceConstants(OutlinableRegion &Region) {
-  OutlinableGroup &Group = *Region.Parent;
-  Function *OutlinedFunction = Group.OutlinedFunction;
-  ValueToValueMapTy VMap;
-
-  // Iterate over the constants that need to be elevated into arguments
-  for (std::pair<unsigned, Constant *> &Const : Region.AggArgToConstant) {
-    unsigned AggArgIdx = Const.first;
-    assert(OutlinedFunction && "Overall Function is not defined?");
-    Constant *CST = Const.second;
-    Argument *Arg = Group.OutlinedFunction->getArg(AggArgIdx);
-    // Identify the argument it will be elevated to, and replace instances of
-    // that constant in the function.
-    VMap[CST] = Arg;
-    LLVM_DEBUG(dbgs() << "Replacing uses of constant " << *CST
-                      << " in function " << *OutlinedFunction << " with "
-                      << *Arg << '\n');
-  }
-
-  RemapFunction(*OutlinedFunction, VMap,
-                RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
-}
-
-/// It is possible that there is a basic block that already performs the same
-/// stores. This returns a duplicate block, if it exists
-///
-/// \param OutputBBs [in] the blocks we are looking for a duplicate of.
-/// \param OutputStoreBBs [in] The existing output blocks.
-/// \returns an optional value with the number output block if there is a match.
-std::optional<unsigned> findDuplicateOutputBlock(
-    DenseMap<Value *, BasicBlock *> &OutputBBs,
-    std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs) {
-
-  bool Mismatch = false;
-  unsigned MatchingNum = 0;
-  // We compare the new set output blocks to the other sets of output blocks.
-  // If they are the same number, and have identical instructions, they are
-  // considered to be the same.
-  for (DenseMap<Value *, BasicBlock *> &CompBBs : OutputStoreBBs) {
-    Mismatch = false;
-    for (std::pair<Value *, BasicBlock *> &VToB : CompBBs) {
-      auto OutputBBIt = OutputBBs.find(VToB.first);
-      if (OutputBBIt == OutputBBs.end()) {
-        Mismatch = true;
-        break;
-      }
-
-      BasicBlock *CompBB = VToB.second;
-      BasicBlock *OutputBB = OutputBBIt->second;
-      if (CompBB->size() - 1 != OutputBB->size()) {
-        Mismatch = true;
-        break;
-      }
-
-      BasicBlock::iterator NIt = OutputBB->begin();
-      for (Instruction &I : *CompBB) {
-        if (isa<UncondBrInst, CondBrInst>(&I))
-          continue;
-
-        if (!I.isIdenticalTo(&(*NIt))) {
-          Mismatch = true;
-          break;
-        }
-
-        NIt++;
-      }
-    }
-
-    if (!Mismatch)
-      return MatchingNum;
-
-    MatchingNum++;
-  }
-
-  return std::nullopt;
-}
-
-/// Remove empty output blocks from the outlined region.
-///
-/// \param BlocksToPrune - Mapping of return values output blocks for the \p
-/// Region.
-/// \param Region - The OutlinableRegion we are analyzing.
-static bool
-analyzeAndPruneOutputBlocks(DenseMap<Value *, BasicBlock *> &BlocksToPrune,
-                            OutlinableRegion &Region) {
-  bool AllRemoved = true;
-  Value *RetValueForBB;
-  BasicBlock *NewBB;
-  SmallVector<Value *, 4> ToRemove;
-  // Iterate over the output blocks created in the outlined section.
-  for (std::pair<Value *, BasicBlock *> &VtoBB : BlocksToPrune) {
-    RetValueForBB = VtoBB.first;
-    NewBB = VtoBB.second;
-  
-    // If there are no instructions, we remove it from the module, and also
-    // mark the value for removal from the return value to output block mapping.
-    if (NewBB->size() == 0) {
-      NewBB->eraseFromParent();
-      ToRemove.push_back(RetValueForBB);
-      continue;
-    }
-    
-    // Mark that we could not remove all the blocks since they were not all
-    // empty.
-    AllRemoved = false;
-  }
-
-  // Remove the return value from the mapping.
-  for (Value *V : ToRemove)
-    BlocksToPrune.erase(V);
-
-  // Mark the region as having the no output scheme.
-  if (AllRemoved)
-    Region.OutputBlockNum = -1;
-  
-  return AllRemoved;
-}
-
-/// For the outlined section, move needed the StoreInsts for the output
-/// registers into their own block. Then, determine if there is a duplicate
-/// output block already created.
-///
-/// \param [in] OG - The OutlinableGroup of regions to be outlined.
-/// \param [in] Region - The OutlinableRegion that is being analyzed.
-/// \param [in,out] OutputBBs - the blocks that stores for this region will be
-/// placed in.
-/// \param [in] EndBBs - the final blocks of the extracted function.
-/// \param [in] OutputMappings - OutputMappings the mapping of values that have
-/// been replaced by a new output value.
-/// \param [in,out] OutputStoreBBs - The existing output blocks.
-static void alignOutputBlockWithAggFunc(
-    OutlinableGroup &OG, OutlinableRegion &Region,
-    DenseMap<Value *, BasicBlock *> &OutputBBs,
-    DenseMap<Value *, BasicBlock *> &EndBBs,
-    const DenseMap<Value *, Value *> &OutputMappings,
-    std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs) {
-  // If none of the output blocks have any instructions, this means that we do
-  // not have to determine if it matches any of the other output schemes, and we
-  // don't have to do anything else.
-  if (analyzeAndPruneOutputBlocks(OutputBBs, Region))
-    return;
-
-  // Determine is there is a duplicate set of blocks.
-  std::optional<unsigned> MatchingBB =
-      findDuplicateOutputBlock(OutputBBs, OutputStoreBBs);
-
-  // If there is, we remove the new output blocks.  If it does not,
-  // we add it to our list of sets of output blocks.
-  if (MatchingBB) {
-    LLVM_DEBUG(dbgs() << "Set output block for region in function"
-                      << Region.ExtractedFunction << " to " << *MatchingBB);
-
-    Region.OutputBlockNum = *MatchingBB;
-    for (std::pair<Value *, BasicBlock *> &VtoBB : OutputBBs)
-      VtoBB.second->eraseFromParent();
-    return;
-  }
-
-  Region.OutputBlockNum = OutputStoreBBs.size();
-
-  Value *RetValueForBB;
-  BasicBlock *NewBB;
-  OutputStoreBBs.push_back(DenseMap<Value *, BasicBlock *>());
-  for (std::pair<Value *, BasicBlock *> &VtoBB : OutputBBs) {
-    RetValueForBB = VtoBB.first;
-    NewBB = VtoBB.second;
-    auto VBBIt = EndBBs.find(RetValueForBB);
-    LLVM_DEBUG(dbgs() << "Create output block for region in"
-                      << Region.ExtractedFunction << " to "
-                      << *NewBB);
-    UncondBrInst::Create(VBBIt->second, NewBB);
-    OutputStoreBBs.back().insert(std::make_pair(RetValueForBB, NewBB));
-  }
-}
-
-/// Takes in a mapping, \p OldMap of ConstantValues to BasicBlocks, sorts keys,
-/// before creating a basic block for each \p NewMap, and inserting into the new
-/// block. Each BasicBlock is named with the scheme "<basename>_<key_idx>".
-///
-/// \param OldMap [in] - The mapping to base the new mapping off of.
-/// \param NewMap [out] - The output mapping using the keys of \p OldMap.
-/// \param ParentFunc [in] - The function to put the new basic block in.
-/// \param BaseName [in] - The start of the BasicBlock names to be appended to
-/// by an index value.
-static void createAndInsertBasicBlocks(DenseMap<Value *, BasicBlock *> &OldMap,
-                                       DenseMap<Value *, BasicBlock *> &NewMap,
-                                       Function *ParentFunc, Twine BaseName) {
-  unsigned Idx = 0;
-  std::vector<Value *> SortedKeys;
-  
-  getSortedConstantKeys(SortedKeys, OldMap);
-
-  for (Value *RetVal : SortedKeys) {
-    BasicBlock *NewBB = BasicBlock::Create(
-        ParentFunc->getContext(), Twine(BaseName) + Twine("_") + Twine(Idx++),
-        ParentFunc);
-    NewMap.insert(std::make_pair(RetVal, NewBB));
-  }
-}
-
-/// Create the switch statement for outlined function to differentiate between
-/// all the output blocks.
-///
-/// For the outlined section, determine if an outlined block already exists that
-/// matches the needed stores for the extracted section.
-/// \param [in] M - The module we are outlining from.
-/// \param [in] OG - The group of regions to be outlined.
-/// \param [in] EndBBs - The final blocks of the extracted function.
-/// \param [in,out] OutputStoreBBs - The existing output blocks.
-void createSwitchStatement(
-    Module &M, OutlinableGroup &OG, DenseMap<Value *, BasicBlock *> &EndBBs,
-    std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs) {
-  // We only need the switch statement if there is more than one store
-  // combination, or there is more than one set of output blocks.  The first
-  // will occur when we store different sets of values for two different
-  // regions.  The second will occur when we have two outputs that are combined
-  // in a PHINode outside of the region in one outlined instance, and are used
-  // seaparately in another. This will create the same set of OutputGVNs, but
-  // will generate two different output schemes.
-  if (OG.OutputGVNCombinations.size() > 1) {
-    Function *AggFunc = OG.OutlinedFunction;
-    // Create a final block for each different return block.
-    DenseMap<Value *, BasicBlock *> ReturnBBs;
-    createAndInsertBasicBlocks(OG.EndBBs, ReturnBBs, AggFunc, "final_block");
-
-    for (std::pair<Value *, BasicBlock *> &RetBlockPair : ReturnBBs) {
-      std::pair<Value *, BasicBlock *> &OutputBlock =
-          *OG.EndBBs.find(RetBlockPair.first);
-      BasicBlock *ReturnBlock = RetBlockPair.second;
-      BasicBlock *EndBB = OutputBlock.second;
-      Instruction *Term = EndBB->getTerminator();
-      // Move the return value to the final block instead of the original exit
-      // stub.
-      Term->moveBefore(*ReturnBlock, ReturnBlock->end());
-      // Put the switch statement in the old end basic block for the function
-      // with a fall through to the new return block.
-      LLVM_DEBUG(dbgs() << "Create switch statement in " << *AggFunc << " for "
-                        << OutputStoreBBs.size() << "\n");
-      SwitchInst *SwitchI =
-          SwitchInst::Create(AggFunc->getArg(AggFunc->arg_size() - 1),
-                             ReturnBlock, OutputStoreBBs.size(), EndBB);
-
-      unsigned Idx = 0;
-      for (DenseMap<Value *, BasicBlock *> &OutputStoreBB : OutputStoreBBs) {
-        auto OSBBIt = OutputStoreBB.find(OutputBlock.first);
-
-        if (OSBBIt == OutputStoreBB.end())
-          continue;
-
-        BasicBlock *BB = OSBBIt->second;
-        SwitchI->addCase(
-            ConstantInt::get(Type::getInt32Ty(M.getContext()), Idx), BB);
-        Term = BB->getTerminator();
-        Term->setSuccessor(0, ReturnBlock);
-        Idx++;
-      }
-    }
-    return;
-  }
-
-  assert(OutputStoreBBs.size() < 2 && "Different store sets not handled!");
-
-  // If there needs to be stores, move them from the output blocks to their
-  // corresponding ending block.  We do not check that the OutputGVNCombinations
-  // is equal to 1 here since that could just been the case where there are 0
-  // outputs. Instead, we check whether there is more than one set of output
-  // blocks since this is the only case where we would have to move the
-  // stores, and erase the extraneous blocks.
-  if (OutputStoreBBs.size() == 1) {
-    LLVM_DEBUG(dbgs() << "Move store instructions to the end block in "
-                      << *OG.OutlinedFunction << "\n");
-    DenseMap<Value *, BasicBlock *> OutputBlocks = OutputStoreBBs[0];
-    for (std::pair<Value *, BasicBlock *> &VBPair : OutputBlocks) {
-      auto EndBBIt = EndBBs.find(VBPair.first);
-      assert(EndBBIt != EndBBs.end() && "Could not find end block");
-      BasicBlock *EndBB = EndBBIt->second;
-      BasicBlock *OutputBB = VBPair.second;
-      Instruction *Term = OutputBB->getTerminator();
-      Term->eraseFromParent();
-      Term = EndBB->getTerminator();
-      moveBBContents(*OutputBB, *EndBB);
-      Term->moveBefore(*EndBB, EndBB->end());
-      OutputBB->eraseFromParent();
-    }
-  }
-}
-
-void IROutliner::fillOverallFunction(
-    Module &M, OutlinableGroup &CurrentGroup,
-    std::vector<DenseMap<Value *, BasicBlock *>> &OutputStoreBBs,
-    std::vector<Function *> &FuncsToRemove) {
-  OutlinableRegion *CurrentOS = CurrentGroup.Regions[0];
-
-  TargetTransformInfo &TTI = getTTI(*CurrentOS->StartBB->getParent());
-
-  // Move first extracted function's instructions into new function.
-  LLVM_DEBUG(dbgs() << "Move instructions from "
-                    << *CurrentOS->ExtractedFunction << " to instruction "
-                    << *CurrentGroup.OutlinedFunction << "\n");
-  moveFunctionData(*CurrentOS->ExtractedFunction,
-                   *CurrentGroup.OutlinedFunction, CurrentGroup.EndBBs);
-
-  // Transfer the attributes from the function to the new function.
-  for (Attribute A :
-       CurrentOS->ExtractedFunction->getAttributes().getFnAttrs()) {
-    if (!TTI.shouldCopyAttributeWhenOutliningFrom(CurrentOS->ExtractedFunction,
-                                                  A))
-      continue;
-
-    CurrentGroup.OutlinedFunction->addFnAttr(A);
-  }
-
-  // Create a new set of output blocks for the first extracted function.
-  DenseMap<Value *, BasicBlock *> NewBBs;
-  createAndInsertBasicBlocks(CurrentGroup.EndBBs, NewBBs,
-                             CurrentGroup.OutlinedFunction, "output_block_0");
-  CurrentOS->OutputBlockNum = 0;
-
-  replaceArgumentUses(*CurrentOS, NewBBs, OutputMappings, true);
-  replaceConstants(*CurrentOS);
-
-  // We first identify if any output blocks are empty, if they are we remove
-  // them. We then create a branch instruction to the basic block to the return
-  // block for the function for each non empty output block.
-  if (!analyzeAndPruneOutputBlocks(NewBBs, *CurrentOS)) {
-    OutputStoreBBs.push_back(DenseMap<Value *, BasicBlock *>());
-    for (std::pair<Value *, BasicBlock *> &VToBB : NewBBs) {
-      auto VBBIt = CurrentGroup.EndBBs.find(VToBB.first);
-      BasicBlock *EndBB = VBBIt->second;
-      UncondBrInst::Create(EndBB, VToBB.second);
-      OutputStoreBBs.back().insert(VToBB);
-    }
-  }
-
-  // Replace the call to the extracted function with the outlined function.
-  CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
-
-  // We only delete the extracted functions at the end since we may need to
-  // reference instructions contained in them for mapping purposes.
-  FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
-}
-
-void IROutliner::deduplicateExtractedSections(
-    Module &M, OutlinableGroup &CurrentGroup,
-    std::vector<Function *> &FuncsToRemove, unsigned &OutlinedFunctionNum) {
-  createFunction(M, CurrentGroup, OutlinedFunctionNum);
-
-  std::vector<DenseMap<Value *, BasicBlock *>> OutputStoreBBs;
-
-  OutlinableRegion *CurrentOS;
-
-  fillOverallFunction(M, CurrentGroup, OutputStoreBBs, FuncsToRemove);
-
-  for (unsigned Idx = 1; Idx < CurrentGroup.Regions.size(); Idx++) {
-    CurrentOS = CurrentGroup.Regions[Idx];
-    AttributeFuncs::mergeAttributesForOutlining(*CurrentGroup.OutlinedFunction,
-                                               *CurrentOS->ExtractedFunction);
-
-    // Create a set of BasicBlocks, one for each return block, to hold the
-    // needed store instructions.
-    DenseMap<Value *, BasicBlock *> NewBBs;
-    createAndInsertBasicBlocks(CurrentGroup.EndBBs, NewBBs,
-                               CurrentGroup.OutlinedFunction,
-                               "output_block_" + Twine(Idx));
-    replaceArgumentUses(*CurrentOS, NewBBs, OutputMappings);
-    alignOutputBlockWithAggFunc(CurrentGroup, *CurrentOS, NewBBs,
-                                CurrentGroup.EndBBs, OutputMappings,
-                                OutputStoreBBs);
-
-    CurrentOS->Call = replaceCalledFunction(M, *CurrentOS);
-    FuncsToRemove.push_back(CurrentOS->ExtractedFunction);
-  }
-
-  // Create a switch statement to handle the different output schemes.
-  createSwitchStatement(M, CurrentGroup, CurrentGroup.EndBBs, OutputStoreBBs);
-
-  OutlinedFunctionNum++;
-}
-
-/// Checks that the next instruction in the InstructionDataList matches the
-/// next instruction in the module.  If they do not, there could be the
-/// possibility that extra code has been inserted, and we must ignore it.
-///
-/// \param ID - The IRInstructionData to check the next instruction of.
-/// \returns true if the InstructionDataList and actual instruction match.
-static bool nextIRInstructionDataMatchesNextInst(IRInstructionData &ID) {
-  // We check if there is a discrepancy between the InstructionDataList
-  // and the actual next instruction in the module.  If there is, it means
-  // that an extra instruction was added, likely by the CodeExtractor.
-
-  // Since we do not have any similarity data about this particular
-  // instruction, we cannot confidently outline it, and must discard this
-  // candidate.
-  IRInstructionDataList::iterator NextIDIt = std::next(ID.getIterator());
-  Instruction *NextIDLInst = NextIDIt->Inst;
-  Instruction *NextModuleInst = nullptr;
-  if (!ID.Inst->isTerminator())
-    NextModuleInst = ID.Inst->getNextNode();
-  else if (NextIDLInst != nullptr)
-    NextModuleInst = &*NextIDIt->Inst->getParent()->begin();
-
-  if (NextIDLInst && NextIDLInst != NextModuleInst)
-    return false;
-
-  return true;
-}
-
-bool IROutliner::isCompatibleWithAlreadyOutlinedCode(
-    const OutlinableRegion &Region) {
-  IRSimilarityCandidate *IRSC = Region.Candidate;
-  unsigned StartIdx = IRSC->getStartIdx();
-  unsigned EndIdx = IRSC->getEndIdx();
-
-  // A check to make sure that we are not about to attempt to outline something
-  // that has already been outlined.
-  for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
-    if (Outlined.contains(Idx))
-      return false;
-
-  // We check if the recorded instruction matches the actual next instruction,
-  // if it does not, we fix it in the InstructionDataList.
-  if (!Region.Candidate->backInstruction()->isTerminator()) {
-    Instruction *NewEndInst =
-        Region.Candidate->backInstruction()->getNextNode();
-    assert(NewEndInst && "Next instruction is a nullptr?");
-    if (Region.Candidate->end()->Inst != NewEndInst) {
-      IRInstructionDataList *IDL = Region.Candidate->front()->IDL;
-      IRInstructionData *NewEndIRID = new (InstDataAllocator.Allocate())
-          IRInstructionData(*NewEndInst,
-                            InstructionClassifier.visit(*NewEndInst), *IDL);
-
-      // Insert the first IRInstructionData of the new region after the
-      // last IRInstructionData of the IRSimilarityCandidate.
-      IDL->insert(Region.Candidate->end(), *NewEndIRID);
-    }
-  }
-
-  return none_of(*IRSC, [this](IRInstructionData &ID) {
-    if (!nextIRInstructionDataMatchesNextInst(ID))
-      return true;
-
-    return !this->InstructionClassifier.visit(ID.Inst);
-  });
-}
-
-void IROutliner::pruneIncompatibleRegions(
-    std::vector<IRSimilarityCandidate> &CandidateVec,
-    OutlinableGroup &CurrentGroup) {
-  bool PreviouslyOutlined;
-
-  // Sort from beginning to end, so the IRSimilarityCandidates are in order.
-  stable_sort(CandidateVec, [](const IRSimilarityCandidate &LHS,
-                               const IRSimilarityCandidate &RHS) {
-    return LHS.getStartIdx() < RHS.getStartIdx();
-  });
-
-  IRSimilarityCandidate &FirstCandidate = CandidateVec[0];
-  // Since outlining a call and a branch instruction will be the same as only
-  // outlinining a call instruction, we ignore it as a space saving.
-  if (FirstCandidate.getLength() == 2) {
-    if (isa<CallInst>(FirstCandidate.front()->Inst) &&
-        isa<UncondBrInst, CondBrInst>(FirstCandidate.back()->Inst))
-      return;
-  }
-
-  unsigned CurrentEndIdx = 0;
-  for (IRSimilarityCandidate &IRSC : CandidateVec) {
-    PreviouslyOutlined = false;
-    unsigned StartIdx = IRSC.getStartIdx();
-    unsigned EndIdx = IRSC.getEndIdx();
-    const Function &FnForCurrCand = *IRSC.getFunction();
-
-    for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
-      if (Outlined.contains(Idx)) {
-        PreviouslyOutlined = true;
-        break;
-      }
-
-    if (PreviouslyOutlined)
-      continue;
-
-    // Check over the instructions, and if the basic block has its address
-    // taken for use somewhere else, we do not outline that block.
-    bool BBHasAddressTaken = any_of(IRSC, [](IRInstructionData &ID){
-      return ID.Inst->getParent()->hasAddressTaken();
-    });
-
-    if (BBHasAddressTaken)
-      continue;
-
-    if (FnForCurrCand.hasOptNone())
-      continue;
-
-    if (FnForCurrCand.hasFnAttribute(Attribute::NoOutline)) {
-      LLVM_DEBUG({
-        dbgs() << "... Skipping function with nooutline attribute: "
-               << FnForCurrCand.getName() << "\n";
-      });
-      continue;
-    }
-
-    if (IRSC.front()->Inst->getFunction()->hasLinkOnceODRLinkage() &&
-        !OutlineFromLinkODRs)
-      continue;
-
-    // Greedily prune out any regions that will overlap with already chosen
-    // regions.
-    if (CurrentEndIdx != 0 && StartIdx <= CurrentEndIdx)
-      continue;
-
-    bool BadInst = any_of(IRSC, [this](IRInstructionData &ID) {
-      if (!nextIRInstructionDataMatchesNextInst(ID))
-        return true;
-
-      return !this->InstructionClassifier.visit(ID.Inst);
-    });
-
-    if (BadInst)
-      continue;
-
-    OutlinableRegion *OS = new (RegionAllocator.Allocate())
-        OutlinableRegion(IRSC, CurrentGroup);
-    CurrentGroup.Regions.push_back(OS);
-
-    CurrentEndIdx = EndIdx;
-  }
-}
-
-InstructionCost
-IROutliner::findBenefitFromAllRegions(OutlinableGroup &CurrentGroup) {
-  InstructionCost RegionBenefit = 0;
-  for (OutlinableRegion *Region : CurrentGroup.Regions) {
-    TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
-    // We add the number of instructions in the region to the benefit as an
-    // estimate as to how much will be removed.
-    RegionBenefit += Region->getBenefit(TTI);
-    LLVM_DEBUG(dbgs() << "Adding: " << RegionBenefit
-                      << " saved instructions to overfall benefit.\n");
-  }
-
-  return RegionBenefit;
-}
-
-/// For the \p OutputCanon number passed in find the value represented by this
-/// canonical number. If it is from a PHINode, we pick the first incoming
-/// value and return that Value instead.
-///
-/// \param Region - The OutlinableRegion to get the Value from.
-/// \param OutputCanon - The canonical number to find the Value from.
-/// \returns The Value represented by a canonical number \p OutputCanon in \p
-/// Region.
-static Value *findOutputValueInRegion(OutlinableRegion &Region,
-                                      unsigned OutputCanon) {
-  OutlinableGroup &CurrentGroup = *Region.Parent;
-  // If the value is greater than the value in the tracker, we have a
-  // PHINode and will instead use one of the incoming values to find the
-  // type.
-  if (OutputCanon > CurrentGroup.PHINodeGVNTracker) {
-    auto It = CurrentGroup.PHINodeGVNToGVNs.find(OutputCanon);
-    assert(It != CurrentGroup.PHINodeGVNToGVNs.end() &&
-           "Could not find GVN set for PHINode number!");
-    assert(It->second.second.size() > 0 && "PHINode does not have any values!");
-    OutputCanon = *It->second.second.begin();
-  }
-  std::optional<unsigned> OGVN =
-      Region.Candidate->fromCanonicalNum(OutputCanon);
-  assert(OGVN && "Could not find GVN for Canonical Number?");
-  std::optional<Value *> OV = Region.Candidate->fromGVN(*OGVN);
-  assert(OV && "Could not find value for GVN?");
-  return *OV;
-}
-
-InstructionCost
-IROutliner::findCostOutputReloads(OutlinableGroup &CurrentGroup) {
-  InstructionCost OverallCost = 0;
-  for (OutlinableRegion *Region : CurrentGroup.Regions) {
-    TargetTransformInfo &TTI = getTTI(*Region->StartBB->getParent());
-
-    // Each output incurs a load after the call, so we add that to the cost.
-    for (unsigned OutputCanon : Region->GVNStores) {
-      Value *V = findOutputValueInRegion(*Region, OutputCanon);
-      InstructionCost LoadCost =
-          TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
-                              TargetTransformInfo::TCK_CodeSize);
-
-      LLVM_DEBUG(dbgs() << "Adding: " << LoadCost
-                        << " instructions to cost for output of type "
-                        << *V->getType() << "\n");
-      OverallCost += LoadCost;
-    }
-  }
-
-  return OverallCost;
-}
-
-/// Find the extra instructions needed to handle any output values for the
-/// region.
-///
-/// \param [in] M - The Module to outline from.
-/// \param [in] CurrentGroup - The collection of OutlinableRegions to analyze.
-/// \param [in] TTI - The TargetTransformInfo used to collect information for
-/// new instruction costs.
-/// \returns the additional cost to handle the outputs.
-static InstructionCost findCostForOutputBlocks(Module &M,
-                                               OutlinableGroup &CurrentGroup,
-                                               TargetTransformInfo &TTI) {
-  InstructionCost OutputCost = 0;
-  unsigned NumOutputBranches = 0;
-
-  OutlinableRegion &FirstRegion = *CurrentGroup.Regions[0];
-  IRSimilarityCandidate &Candidate = *CurrentGroup.Regions[0]->Candidate;
-  DenseSet<BasicBlock *> CandidateBlocks;
-  Candidate.getBasicBlocks(CandidateBlocks);
-
-  // Count the number of different output branches that point to blocks outside
-  // of the region.
-  DenseSet<BasicBlock *> FoundBlocks;
-  for (IRInstructionData &ID : Candidate) {
-    if (!isa<UncondBrInst, CondBrInst>(ID.Inst))
-      continue;
-
-    for (Value *V : ID.OperVals) {
-      BasicBlock *BB = static_cast<BasicBlock *>(V);
-      if (!CandidateBlocks.contains(BB) && FoundBlocks.insert(BB).second)
-        NumOutputBranches++;
-    }
-  }
-
-  CurrentGroup.BranchesToOutside = NumOutputBranches;
-
-  for (const ArrayRef<unsigned> &OutputUse :
-       CurrentGroup.OutputGVNCombinations) {
-    for (unsigned OutputCanon : OutputUse) {
-      Value *V = findOutputValueInRegion(FirstRegion, OutputCanon);
-      InstructionCost StoreCost =
-          TTI.getMemoryOpCost(Instruction::Load, V->getType(), Align(1), 0,
-                              TargetTransformInfo::TCK_CodeSize);
-
-      // An instruction cost is added for each store set that needs to occur for
-      // various output combinations inside the function, plus a branch to
-      // return to the exit block.
-      LLVM_DEBUG(dbgs() << "Adding: " << StoreCost
-                        << " instructions to cost for output of type "
-                        << *V->getType() << "\n");
-      OutputCost += StoreCost * NumOutputBranches;
-    }
-
-    InstructionCost BranchCost = TTI.getCFInstrCost(
-        Instruction::UncondBr, TargetTransformInfo::TCK_CodeSize);
-    LLVM_DEBUG(dbgs() << "Adding " << BranchCost << " to the current cost for"
-                      << " a branch instruction\n");
-    OutputCost += BranchCost * NumOutputBranches;
-  }
-
-  // If there is more than one output scheme, we must have a comparison and
-  // branch for each different item in the switch statement.
-  if (CurrentGroup.OutputGVNCombinations.size() > 1) {
-    InstructionCost ComparisonCost = TTI.getCmpSelInstrCost(
-        Instruction::ICmp, Type::getInt32Ty(M.getContext()),
-        Type::getInt32Ty(M.getContext()), CmpInst::BAD_ICMP_PREDICATE,
-        TargetTransformInfo::TCK_CodeSize);
-    InstructionCost BranchCost = TTI.getCFInstrCost(
-        Instruction::CondBr, TargetTransformInfo::TCK_CodeSize);
-
-    unsigned DifferentBlocks = CurrentGroup.OutputGVNCombinations.size();
-    InstructionCost TotalCost = ComparisonCost * BranchCost * DifferentBlocks;
-
-    LLVM_DEBUG(dbgs() << "Adding: " << TotalCost
-                      << " instructions for each switch case for each different"
-                      << " output path in a function\n");
-    OutputCost += TotalCost * NumOutputBranches;
-  }
-
-  return OutputCost;
-}
-
-void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) {
-  InstructionCost RegionBenefit = findBenefitFromAllRegions(CurrentGroup);
-  CurrentGroup.Benefit += RegionBenefit;
-  LLVM_DEBUG(dbgs() << "Current Benefit: " << CurrentGroup.Benefit << "\n");
-
-  InstructionCost OutputReloadCost = findCostOutputReloads(CurrentGroup);
-  CurrentGroup.Cost += OutputReloadCost;
-  LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
-  InstructionCost AverageRegionBenefit =
-      RegionBenefit / CurrentGroup.Regions.size();
-  unsigned OverallArgumentNum = CurrentGroup.ArgumentTypes.size();
-  unsigned NumRegions = CurrentGroup.Regions.size();
-  TargetTransformInfo &TTI =
-      getTTI(*CurrentGroup.Regions[0]->Candidate->getFunction());
-
-  // We add one region to the cost once, to account for the instructions added
-  // inside of the newly created function.
-  LLVM_DEBUG(dbgs() << "Adding: " << AverageRegionBenefit
-                    << " instructions to cost for body of new function.\n");
-  CurrentGroup.Cost += AverageRegionBenefit;
-  LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
-  // For each argument, we must add an instruction for loading the argument
-  // out of the register and into a value inside of the newly outlined function.
-  LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
-                    << " instructions to cost for each argument in the new"
-                    << " function.\n");
-  CurrentGroup.Cost +=
-      OverallArgumentNum * TargetTransformInfo::TCC_Basic;
-  LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
-  // Each argument needs to either be loaded into a register or onto the stack.
-  // Some arguments will only be loaded into the stack once the argument
-  // registers are filled.
-  LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum
-                    << " instructions to cost for each argument in the new"
-                    << " function " << NumRegions << " times for the "
-                    << "needed argument handling at the call site.\n");
-  CurrentGroup.Cost +=
-      2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions;
-  LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-
-  CurrentGroup.Cost += findCostForOutputBlocks(M, CurrentGroup, TTI);
-  LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n");
-}
-
-void IROutliner::updateOutputMapping(OutlinableRegion &Region,
-                                     ArrayRef<Value *> Outputs,
-                                     LoadInst *LI) {
-  // For and load instructions following the call
-  Value *Operand = LI->getPointerOperand();
-  std::optional<unsigned> OutputIdx;
-  // Find if the operand it is an output register.
-  for (unsigned ArgIdx = Region.NumExtractedInputs;
-       ArgIdx < Region.Call->arg_size(); ArgIdx++) {
-    if (Operand == Region.Call->getArgOperand(ArgIdx)) {
-      OutputIdx = ArgIdx - Region.NumExtractedInputs;
-      break;
-    }
-  }
-
-  // If we found an output register, place a mapping of the new value
-  // to the original in the mapping.
-  if (!OutputIdx)
-    return;
-
-  auto It = OutputMappings.find(Outputs[*OutputIdx]);
-  if (It == OutputMappings.end()) {
-    LLVM_DEBUG(dbgs() << "Mapping extracted output " << *LI << " to "
-                      << *Outputs[*OutputIdx] << "\n");
-    OutputMappings.insert(std::make_pair(LI, Outputs[*OutputIdx]));
-  } else {
-    Value *Orig = It->second;
-    LLVM_DEBUG(dbgs() << "Mapping extracted output " << *Orig << " to "
-                      << *Outputs[*OutputIdx] << "\n");
-    OutputMappings.insert(std::make_pair(LI, Orig));
-  }
-}
-
-bool IROutliner::extractSection(OutlinableRegion &Region) {
-  SetVector<Value *> ArgInputs, Outputs;
-  assert(Region.StartBB && "StartBB for the OutlinableRegion is nullptr!");
-  BasicBlock *InitialStart = Region.StartBB;
-  Function *OrigF = Region.StartBB->getParent();
-  CodeExtractorAnalysisCache CEAC(*OrigF);
-  Region.ExtractedFunction =
-      Region.CE->extractCodeRegion(CEAC, ArgInputs, Outputs);
-
-  // If the extraction was successful, find the BasicBlock, and reassign the
-  // OutlinableRegion blocks
-  if (!Region.ExtractedFunction) {
-    LLVM_DEBUG(dbgs() << "CodeExtractor failed to outline " << Region.StartBB
-                      << "\n");
-    Region.reattachCandidate();
-    return false;
-  }
-
-  // Get the block containing the called branch, and reassign the blocks as
-  // necessary.  If the original block still exists, it is because we ended on
-  // a branch instruction, and so we move the contents into the block before
-  // and assign the previous block correctly.
-  User *InstAsUser = Region.ExtractedFunction->user_back();
-  BasicBlock *RewrittenBB = cast<Instruction>(InstAsUser)->getParent();
-  Region.PrevBB = RewrittenBB->getSinglePredecessor();
-  assert(Region.PrevBB && "PrevBB is nullptr?");
-  if (Region.PrevBB == InitialStart) {
-    BasicBlock *NewPrev = InitialStart->getSinglePredecessor();
-    Instruction *BI = NewPrev->getTerminator();
-    BI->eraseFromParent();
-    moveBBContents(*InitialStart, *NewPrev);
-    Region.PrevBB = NewPrev;
-    InitialStart->eraseFromParent();
-  }
-
-  Region.StartBB = RewrittenBB;
-  Region.EndBB = RewrittenBB;
-
-  // The sequences of outlinable regions has now changed.  We must fix the
-  // IRInstructionDataList for consistency.  Although they may not be illegal
-  // instructions, they should not be compared with anything else as they
-  // should not be outlined in this round.  So marking these as illegal is
-  // allowed.
-  IRInstructionDataList *IDL = Region.Candidate->front()->IDL;
-  Instruction *BeginRewritten = &*RewrittenBB->begin();
-  Instruction *EndRewritten = &*RewrittenBB->begin();
-  Region.NewFront = new (InstDataAllocator.Allocate()) IRInstructionData(
-      *BeginRewritten, InstructionClassifier.visit(*BeginRewritten), *IDL);
-  Region.NewBack = new (InstDataAllocator.Allocate()) IRInstructionData(
-      *EndRewritten, InstructionClassifier.visit(*EndRewritten), *IDL);
-
-  // Insert the first IRInstructionData of the new region in front of the
-  // first IRInstructionData of the IRSimilarityCandidate.
-  IDL->insert(Region.Candidate->begin(), *Region.NewFront);
-  // Insert the first IRInstructionData of the new region after the
-  // last IRInstructionData of the IRSimilarityCandidate.
-  IDL->insert(Region.Candidate->end(), *Region.NewBack);
-  // Remove the IRInstructionData from the IRSimilarityCandidate.
-  IDL->erase(Region.Candidate->begin(), std::prev(Region.Candidate->end()));
-
-  assert(RewrittenBB != nullptr &&
-         "Could not find a predecessor after extraction!");
-
-  // Iterate over the new set of instructions to find the new call
-  // instruction.
-  for (Instruction &I : *RewrittenBB)
-    if (CallInst *CI = dyn_cast<CallInst>(&I)) {
-      if (Region.ExtractedFunction == CI->getCalledFunction())
-        Region.Call = CI;
-    } else if (LoadInst *LI = dyn_cast<LoadInst>(&I))
-      updateOutputMapping(Region, Outputs.getArrayRef(), LI);
-  Region.reattachCandidate();
-  return true;
-}
-
-unsigned IROutliner::doOutline(Module &M) {
-  // Find the possible similarity sections.
-  InstructionClassifier.EnableBranches = !DisableBranches;
-  InstructionClassifier.EnableIndirectCalls = !DisableIndirectCalls;
-  InstructionClassifier.EnableIntrinsics = !DisableIntrinsics;
-
-  IRSimilarityIdentifier &Identifier = getIRSI(M);
-  SimilarityGroupList &SimilarityCandidates = *Identifier.getSimilarity();
-
-  // Sort them by size of extracted sections
-  unsigned OutlinedFunctionNum = 0;
-  // If we only have one SimilarityGroup in SimilarityCandidates, we do not have
-  // to sort them by the potential number of instructions to be outlined
-  if (SimilarityCandidates.size() > 1)
-    llvm::stable_sort(SimilarityCandidates,
-                      [](const std::vector<IRSimilarityCandidate> &LHS,
-                         const std::vector<IRSimilarityCandidate> &RHS) {
-                        return LHS[0].getLength() * LHS.size() >
-                               RHS[0].getLength() * RHS.size();
-                      });
-  // Creating OutlinableGroups for each SimilarityCandidate to be used in
-  // each of the following for loops to avoid making an allocator.
-  std::vector<OutlinableGroup> PotentialGroups(SimilarityCandidates.size());
-
-  DenseSet<unsigned> NotSame;
-  std::vector<OutlinableGroup *> NegativeCostGroups;
-  std::vector<OutlinableRegion *> OutlinedRegions;
-  // Iterate over the possible sets of similarity.
-  unsigned PotentialGroupIdx = 0;
-  for (SimilarityGroup &CandidateVec : SimilarityCandidates) {
-    OutlinableGroup &CurrentGroup = PotentialGroups[PotentialGroupIdx++];
-
-    // Remove entries that were previously outlined
-    pruneIncompatibleRegions(CandidateVec, CurrentGroup);
-
-    // We pruned the number of regions to 0 to 1, meaning that it's not worth
-    // trying to outlined since there is no compatible similar instance of this
-    // code.
-    if (CurrentGroup.Regions.size() < 2)
-      continue;
-
-    // Determine if there are any values that are the same constant throughout
-    // each section in the set.
-    NotSame.clear();
-    CurrentGroup.findSameConstants(NotSame);
-
-    if (CurrentGroup.IgnoreGroup)
-      continue;
-
-    // Create a CodeExtractor for each outlinable region. Identify inputs and
-    // outputs for each section using the code extractor and create the argument
-    // types for the Aggregate Outlining Function.
-    OutlinedRegions.clear();
-    for (OutlinableRegion *OS : CurrentGroup.Regions) {
-      // Break the outlinable region out of its parent BasicBlock into its own
-      // BasicBlocks (see function implementation).
-      OS->splitCandidate();
-
-      // There's a chance that when the region is split, extra instructions are
-      // added to the region. This makes the region no longer viable
-      // to be split, so we ignore it for outlining.
-      if (!OS->CandidateSplit)
-        continue;
-
-      SmallVector<BasicBlock *> BE;
-      DenseSet<BasicBlock *> BlocksInRegion;
-      OS->Candidate->getBasicBlocks(BlocksInRegion, BE);
-      OS->CE = new (ExtractorAllocator.Allocate())
-          CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false,
-                        false, nullptr, {}, "outlined");
-      findAddInputsOutputs(M, *OS, NotSame);
-      if (!OS->IgnoreRegion)
-        OutlinedRegions.push_back(OS);
-
-      // We recombine the blocks together now that we have gathered all the
-      // needed information.
-      OS->reattachCandidate();
-    }
-
-    CurrentGroup.Regions = std::move(OutlinedRegions);
-
-    if (CurrentGroup.Regions.empty())
-      continue;
-
-    CurrentGroup.collectGVNStoreSets(M);
-
-    if (CostModel)
-      findCostBenefit(M, CurrentGroup);
-
-    // If we are adhering to the cost model, skip those groups where the cost
-    // outweighs the benefits.
-    if (CurrentGroup.Cost >= CurrentGroup.Benefit && CostModel) {
-      OptimizationRemarkEmitter &ORE =
-          getORE(*CurrentGroup.Regions[0]->Candidate->getFunction());
-      ORE.emit([&]() {
-        IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
-        OptimizationRemarkMissed R(DEBUG_TYPE, "WouldNotDecreaseSize",
-                                   C->frontInstruction());
-        R << "did not outline "
-          << ore::NV(std::to_string(CurrentGroup.Regions.size()))
-          << " regions due to estimated increase of "
-          << ore::NV("InstructionIncrease",
-                     CurrentGroup.Cost - CurrentGroup.Benefit)
-          << " instructions at locations ";
-        interleave(
-            CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
-            [&R](OutlinableRegion *Region) {
-              R << ore::NV(
-                  "DebugLoc",
-                  Region->Candidate->frontInstruction()->getDebugLoc());
-            },
-            [&R]() { R << " "; });
-        return R;
-      });
-      continue;
-    }
-
-    NegativeCostGroups.push_back(&CurrentGroup);
-  }
-
-  ExtractorAllocator.DestroyAll();
-
-  if (NegativeCostGroups.size() > 1)
-    stable_sort(NegativeCostGroups,
-                [](const OutlinableGroup *LHS, const OutlinableGroup *RHS) {
-                  return LHS->Benefit - LHS->Cost > RHS->Benefit - RHS->Cost;
-                });
-
-  std::vector<Function *> FuncsToRemove;
-  for (OutlinableGroup *CG : NegativeCostGroups) {
-    OutlinableGroup &CurrentGroup = *CG;
-
-    OutlinedRegions.clear();
-    for (OutlinableRegion *Region : CurrentGroup.Regions) {
-      // We check whether our region is compatible with what has already been
-      // outlined, and whether we need to ignore this item.
-      if (!isCompatibleWithAlreadyOutlinedCode(*Region))
-        continue;
-      OutlinedRegions.push_back(Region);
-    }
-
-    if (OutlinedRegions.size() < 2)
-      continue;
-
-    // Reestimate the cost and benefit of the OutlinableGroup. Continue only if
-    // we are still outlining enough regions to make up for the added cost.
-    CurrentGroup.Regions = std::move(OutlinedRegions);
-    if (CostModel) {
-      CurrentGroup.Benefit = 0;
-      CurrentGroup.Cost = 0;
-      findCostBenefit(M, CurrentGroup);
-      if (CurrentGroup.Cost >= CurrentGroup.Benefit)
-        continue;
-    }
-    OutlinedRegions.clear();
-    for (OutlinableRegion *Region : CurrentGroup.Regions) {
-      Region->splitCandidate();
-      if (!Region->CandidateSplit)
-        continue;
-      OutlinedRegions.push_back(Region);
-    }
-
-    CurrentGroup.Regions = std::move(OutlinedRegions);
-    if (CurrentGroup.Regions.size() < 2) {
-      for (OutlinableRegion *R : CurrentGroup.Regions)
-        R->reattachCandidate();
-      continue;
-    }
-
-    LLVM_DEBUG(dbgs() << "Outlining regions with cost " << CurrentGroup.Cost
-                      << " and benefit " << CurrentGroup.Benefit << "\n");
-
-    // Create functions out of all the sections, and mark them as outlined.
-    OutlinedRegions.clear();
-    for (OutlinableRegion *OS : CurrentGroup.Regions) {
-      SmallVector<BasicBlock *> BE;
-      DenseSet<BasicBlock *> BlocksInRegion;
-      OS->Candidate->getBasicBlocks(BlocksInRegion, BE);
-      OS->CE = new (ExtractorAllocator.Allocate())
-          CodeExtractor(BE, nullptr, false, nullptr, nullptr, nullptr, false,
-                        false, nullptr, {}, "outlined");
-      bool FunctionOutlined = extractSection(*OS);
-      if (FunctionOutlined) {
-        unsigned StartIdx = OS->Candidate->getStartIdx();
-        unsigned EndIdx = OS->Candidate->getEndIdx();
-        for (unsigned Idx = StartIdx; Idx <= EndIdx; Idx++)
-          Outlined.insert(Idx);
-
-        OutlinedRegions.push_back(OS);
-      }
-    }
-
-    LLVM_DEBUG(dbgs() << "Outlined " << OutlinedRegions.size()
-                      << " with benefit " << CurrentGroup.Benefit
-                      << " and cost " << CurrentGroup.Cost << "\n");
-
-    CurrentGroup.Regions = std::move(OutlinedRegions);
-
-    if (CurrentGroup.Regions.empty())
-      continue;
-
-    OptimizationRemarkEmitter &ORE =
-        getORE(*CurrentGroup.Regions[0]->Call->getFunction());
-    ORE.emit([&]() {
-      IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate;
-      OptimizationRemark R(DEBUG_TYPE, "Outlined", C->front()->Inst);
-      R << "outlined " << ore::NV(std::to_string(CurrentGroup.Regions.size()))
-        << " regions with decrease of "
-        << ore::NV("Benefit", CurrentGroup.Benefit - CurrentGroup.Cost)
-        << " instructions at locations ";
-      interleave(
-          CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(),
-          [&R](OutlinableRegion *Region) {
-            R << ore::NV("DebugLoc",
-                         Region->Candidate->frontInstruction()->getDebugLoc());
-          },
-          [&R]() { R << " "; });
-      return R;
-    });
-
-    deduplicateExtractedSections(M, CurrentGroup, FuncsToRemove,
-                                 OutlinedFunctionNum);
-  }
-
-  for (Function *F : FuncsToRemove)
-    F->eraseFromParent();
-
-  return OutlinedFunctionNum;
-}
-
-bool IROutliner::run(Module &M) {
-  CostModel = !NoCostModel;
-  OutlineFromLinkODRs = EnableLinkOnceODRIROutlining;
-
-  return doOutline(M) > 0;
-}
-
-PreservedAnalyses IROutlinerPass::run(Module &M, ModuleAnalysisManager &AM) {
-  auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
-
-  std::function<TargetTransformInfo &(Function &)> GTTI =
-      [&FAM](Function &F) -> TargetTransformInfo & {
-    return FAM.getResult<TargetIRAnalysis>(F);
-  };
-
-  std::function<IRSimilarityIdentifier &(Module &)> GIRSI =
-      [&AM](Module &M) -> IRSimilarityIdentifier & {
-    return AM.getResult<IRSimilarityAnalysis>(M);
-  };
-
-  std::unique_ptr<OptimizationRemarkEmitter> ORE;
-  std::function<OptimizationRemarkEmitter &(Function &)> GORE =
-      [&ORE](Function &F) -> OptimizationRemarkEmitter & {
-    ORE.reset(new OptimizationRemarkEmitter(&F));
-    return *ORE;
-  };
-
-  if (IROutliner(GTTI, GIRSI, GORE).run(M))
-    return PreservedAnalyses::none();
-  return PreservedAnalyses::all();
-}
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/basic.ll b/llvm/test/Analysis/IRSimilarityIdentifier/basic.ll
deleted file mode 100644
index 1c08cb407c2e3..0000000000000
--- a/llvm/test/Analysis/IRSimilarityIdentifier/basic.ll
+++ /dev/null
@@ -1,140 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck %s
-
-; This is a simple test to make sure the IRSimilarityIdentifier and
-; IRSimilarityPrinterPass is working.
-
-; CHECK: 4 candidates of length 6.  Found in: 
-; CHECK-NEXT:  Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:    Start Instruction:   store i32 1, ptr %1, align 4
-; CHECK-NEXT:      End Instruction:   store i32 6, ptr %6, align 4
-; CHECK-NEXT:  Function: cat, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 6, ptr %0, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: fish, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 6, ptr %0, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: dog, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 6, ptr %0, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:4 candidates of length 5.  Found in: 
-; CHECK-NEXT:  Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:    Start Instruction:   store i32 2, ptr %2, align 4
-; CHECK-NEXT:      End Instruction:   store i32 6, ptr %6, align 4
-; CHECK-NEXT:  Function: cat, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 1, ptr %1, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: fish, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 1, ptr %1, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: dog, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 1, ptr %1, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:4 candidates of length 4.  Found in: 
-; CHECK-NEXT:  Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:    Start Instruction:   store i32 3, ptr %3, align 4
-; CHECK-NEXT:      End Instruction:   store i32 6, ptr %6, align 4
-; CHECK-NEXT:  Function: cat, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 2, ptr %2, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: fish, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 2, ptr %2, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: dog, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 2, ptr %2, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:4 candidates of length 3.  Found in: 
-; CHECK-NEXT:  Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:    Start Instruction:   store i32 4, ptr %4, align 4
-; CHECK-NEXT:      End Instruction:   store i32 6, ptr %6, align 4
-; CHECK-NEXT:  Function: cat, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 3, ptr %3, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: fish, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 3, ptr %3, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: dog, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 3, ptr %3, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:4 candidates of length 2.  Found in: 
-; CHECK-NEXT:  Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:    Start Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:      End Instruction:   store i32 6, ptr %6, align 4
-; CHECK-NEXT:  Function: cat, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 4, ptr %4, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: fish, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 4, ptr %4, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT:  Function: dog, Basic Block: entry
-; CHECK-NEXT:    Start Instruction:   store i32 4, ptr %4, align 4
-; CHECK-NEXT:      End Instruction:   store i32 5, ptr %5, align 4
-
-define linkonce_odr void @fish() {
-entry:
-  %0 = alloca i32, align 4
-  %1 = alloca i32, align 4
-  %2 = alloca i32, align 4
-  %3 = alloca i32, align 4
-  %4 = alloca i32, align 4
-  %5 = alloca i32, align 4
-  store i32 6, ptr %0, align 4
-  store i32 1, ptr %1, align 4
-  store i32 2, ptr %2, align 4
-  store i32 3, ptr %3, align 4
-  store i32 4, ptr %4, align 4
-  store i32 5, ptr %5, align 4
-  ret void
-}
-
-define void @turtle() {
-  %1 = alloca i32, align 4
-  %2 = alloca i32, align 4
-  %3 = alloca i32, align 4
-  %4 = alloca i32, align 4
-  %5 = alloca i32, align 4
-  %6 = alloca i32, align 4
-  store i32 1, ptr %1, align 4
-  store i32 2, ptr %2, align 4
-  store i32 3, ptr %3, align 4
-  store i32 4, ptr %4, align 4
-  store i32 5, ptr %5, align 4
-  store i32 6, ptr %6, align 4
-  ret void
-}
-
-define void @cat() {
-entry:
-  %0 = alloca i32, align 4
-  %1 = alloca i32, align 4
-  %2 = alloca i32, align 4
-  %3 = alloca i32, align 4
-  %4 = alloca i32, align 4
-  %5 = alloca i32, align 4
-  store i32 6, ptr %0, align 4
-  store i32 1, ptr %1, align 4
-  store i32 2, ptr %2, align 4
-  store i32 3, ptr %3, align 4
-  store i32 4, ptr %4, align 4
-  store i32 5, ptr %5, align 4
-  ret void
-}
-
-define void @dog() {
-entry:
-  %0 = alloca i32, align 4
-  %1 = alloca i32, align 4
-  %2 = alloca i32, align 4
-  %3 = alloca i32, align 4
-  %4 = alloca i32, align 4
-  %5 = alloca i32, align 4
-  store i32 6, ptr %0, align 4
-  store i32 1, ptr %1, align 4
-  store i32 2, ptr %2, align 4
-  store i32 3, ptr %3, align 4
-  store i32 4, ptr %4, align 4
-  store i32 5, ptr %5, align 4
-  ret void
-}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/debug-inst-starts-block.ll b/llvm/test/Analysis/IRSimilarityIdentifier/debug-inst-starts-block.ll
deleted file mode 100644
index 78ecec92cc31a..0000000000000
--- a/llvm/test/Analysis/IRSimilarityIdentifier/debug-inst-starts-block.ll
+++ /dev/null
@@ -1,77 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2
-; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck %s
-
-; When a debug instruction is the first instruction in a block, when that block
-; has not been given a canonical numbering, since debug instructions are not
-; counted in similarity matching they must be ignored when creating canonical
-; relations from one region to another.  This checks that this is enforced.
-
-; CHECK: 2 candidates of length 4.  Found in:
-; CHECK-NEXT:   Function: main, Basic Block: entry
-; CHECK-NEXT:     Start Instruction:   %0 = add i32 1, 4
-; CHECK-NEXT:       End Instruction:   %1 = sub i32 1, 4
-; CHECK-NEXT:   Function: main, Basic Block: for.body169
-; CHECK-NEXT:     Start Instruction:   %2 = add i32 1, 4
-; CHECK-NEXT:       End Instruction:   %3 = sub i32 1, 4
-; CHECK-NEXT: 2 candidates of length 3.  Found in:
-; CHECK-NEXT:   Function: main, Basic Block: entry
-; CHECK-NEXT:     Start Instruction:   br label %for.body169
-; CHECK-NEXT:       End Instruction:   %1 = sub i32 1, 4
-; CHECK-NEXT:   Function: main, Basic Block: for.body169
-; CHECK-NEXT:     Start Instruction:   br label %for.end122
-; CHECK-NEXT:       End Instruction:   %3 = sub i32 1, 4
-; CHECK-NEXT: 2 candidates of length 2.  Found in:
-; CHECK-NEXT:   Function: main, Basic Block: for.end122
-; CHECK-NEXT:     Start Instruction:   store i32 30, ptr undef, align 1
-; CHECK-NEXT:       End Instruction:   %1 = sub i32 1, 4
-; CHECK-NEXT:   Function: main, Basic Block: for.end246
-; CHECK-NEXT:     Start Instruction:   store i32 0, ptr undef, align 1
-; CHECK-NEXT:       End Instruction:   %3 = sub i32 1, 4
-
-source_filename = "irsimilarity_crash.ll"
-
- at v_13 = external dso_local global ptr, align 1
-
-; Function Attrs: nocallback nofree nosync nounwind readnone speculatable willreturn
-declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
-
-define dso_local i16 @main() {
-entry:
-  %0 = add i32 1, 4
-  br label %for.body169
-
-for.end122:                                       ; preds = %for.cond108
-  store i32 30, ptr undef, align 1
-  %1 = sub i32 1, 4
-  ret i16 1
-
-for.body169:                                      ; preds = %for.cond167
-  %2 = add i32 1, 4
-  br label %for.end122
-
-for.end246:                                     ; preds = %for.cond167
-  call void @llvm.dbg.declare(metadata ptr undef, metadata !1, metadata !DIExpression()), !dbg !11
-  store i32 0, ptr undef, align 1
-  %3 = sub i32 1, 4
-  unreachable
-}
-
-attributes #0 = { nocallback nofree nosync nounwind readnone speculatable willreturn }
-
-!llvm.dbg.cu = !{}
-!llvm.module.flags = !{!0}
-
-!0 = !{i32 2, !"Debug Info Version", i32 3}
-!1 = !DILocalVariable(name: "v_68", scope: !2, file: !3, line: 522, type: !10)
-!2 = distinct !DILexicalBlock(scope: !4, file: !3, line: 522, column: 9)
-!3 = !DIFile(filename: "41097217.c", directory: "rt.outdir")
-!4 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 480, type: !5, scopeLine: 481, spFlags: DISPFlagDefinition, unit: !8, retainedNodes: !9)
-!5 = !DISubroutineType(types: !6)
-!6 = !{!7}
-!7 = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
-!8 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 15.0.0.prerel", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, retainedTypes: !9, globals: !9, splitDebugInlining: false, nameTableKind: None)
-!9 = !{}
-!10 = !DIBasicType(name: "long", size: 32, encoding: DW_ATE_signed)
-!11 = !DILocation(line: 522, column: 23, scope: !2)
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/different.ll b/llvm/test/Analysis/IRSimilarityIdentifier/different.ll
deleted file mode 100644
index e5c9970b159b9..0000000000000
--- a/llvm/test/Analysis/IRSimilarityIdentifier/different.ll
+++ /dev/null
@@ -1,48 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck --allow-empty %s
-
-; Check to make sure that the IRSimilarityIdentifier and IRSimilarityPrinterPass
-; return items only within the same function when there are different sets of
-; instructions in functions.
-
-; CHECK: 2 candidates of length 5.  Found in:
-; CHECK-NEXT:   Function: fish, Basic Block: entry
-; CHECK-NEXT:     Start Instruction:   store i32 6, ptr %0, align 4
-; CHECK-NEXT:       End Instruction:   store i32 4, ptr %4, align 4
-; CHECK-NEXT:   Function: fish, Basic Block: entry
-; CHECK-NEXT:     Start Instruction:   store i32 1, ptr %1, align 4
-; CHECK-NEXT:       End Instruction:   store i32 5, ptr %5, align 4
-; CHECK-NEXT: 2 candidates of length 3.  Found in:
-; CHECK-NEXT:   Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:     Start Instruction:   %b = load i32, ptr %1, align 4
-; CHECK-NEXT:       End Instruction:   %d = load i32, ptr %3, align 4
-; CHECK-NEXT:   Function: turtle, Basic Block: (unnamed)
-; CHECK-NEXT:     Start Instruction:   %a = load i32, ptr %0, align 4
-; CHECK-NEXT:       End Instruction:   %c = load i32, ptr %2, align 4
-
-define linkonce_odr void @fish() {
-entry:
-  %0 = alloca i32, align 4
-  %1 = alloca i32, align 4
-  %2 = alloca i32, align 4
-  %3 = alloca i32, align 4
-  %4 = alloca i32, align 4
-  %5 = alloca i32, align 4
-  store i32 6, ptr %0, align 4
-  store i32 1, ptr %1, align 4
-  store i32 2, ptr %2, align 4
-  store i32 3, ptr %3, align 4
-  store i32 4, ptr %4, align 4
-  store i32 5, ptr %5, align 4
-  ret void
-}
-
-define void @turtle(ptr %0, ptr %1, ptr %2, ptr %3) {
-  %a = load i32, ptr %0
-  %b = load i32, ptr %1
-  %c = load i32, ptr %2
-  %d = load i32, ptr %3
-  ret void
-}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
diff --git a/llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll b/llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll
deleted file mode 100644
index 4891a587d776f..0000000000000
--- a/llvm/test/Analysis/IRSimilarityIdentifier/nothing.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -disable-output -S -passes=print-ir-similarity < %s 2>&1 | FileCheck --allow-empty %s
-
-; This is a simple test to make sure the IRSimilarityPrinterPass returns
-; nothing when there is nothing to analyze.
-
-; CHECK-NOT: Found in
-
-define linkonce_odr void @fish() {
-entry:
-  ret void
-}
-;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
-; CHECK: {{.*}}
diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt
index 3f1ee7c18bde7..2a00a429e2626 100644
--- a/llvm/test/CMakeLists.txt
+++ b/llvm/test/CMakeLists.txt
@@ -140,7 +140,6 @@ set(LLVM_TEST_DEPENDS
   llvm-reduce
   llvm-remarkutil
   llvm-rtdyld
-  llvm-sim
   llvm-size
   llvm-split
   llvm-stress
diff --git a/llvm/test/DebugInfo/AArch64/ir-outliner.ll b/llvm/test/DebugInfo/AArch64/ir-outliner.ll
deleted file mode 100644
index 168232e215871..0000000000000
--- a/llvm/test/DebugInfo/AArch64/ir-outliner.ll
+++ /dev/null
@@ -1,162 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -passes=verify,iroutliner -ir-outlining-no-cost < %s | \
-; RUN: llc -filetype=obj -mtriple=aarch64-- | llvm-dwarfdump - | FileCheck %s
-
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck -check-prefix=IRDEBUG %s
-
-; Ensure that the IR Outliner produces valid DWARF debug information when
-; creating outlined functions.
-
-; CHECK: DW_TAG_compile_unit
-; CHECK-DAG: DW_AT_name ("outline_debug1")
-
-; Check the high address of bar. This is one past the end of bar. It should be
-; the beginning of the outlined function.
-; CHECK:      DW_AT_high_pc ([[ONE_PAST_BAR:0x[a-f0-9]+]])
-; CHECK-NEXT: DW_AT_frame_base  (DW_OP_reg31 WSP)
-; CHECK-NEXT: DW_AT_linkage_name  ("outline_debug2")
-; CHECK-NEXT: DW_AT_name  ("outline_debug2")
-
-; Check the outlined function's DWARF.
-; CHECK-DAG:  DW_TAG_subprogram
-; CHECK-NEXT: DW_AT_low_pc  ([[ONE_PAST_BAR]])
-; CHECK-NEXT: DW_AT_high_pc (0x{{[0-9a-f]+}})
-; CHECK-NEXT: DW_AT_frame_base  (DW_OP_reg31 WSP)
-; CHECK-NEXT: DW_AT_linkage_name ("[[NAME:outlined_ir_func_[0-9]+]]")
-; CHECK-NEXT: DW_AT_name  ("[[NAME]]")
-; CHECK-NEXT: DW_AT_artificial  (true)
-; CHECK-NEXT: DW_AT_external  (true)
-
-define void @outline_debug1() !dbg !6 {
-entry:
-  %a = alloca i32, align 4, !dbg !17
-  call void @llvm.dbg.value(metadata ptr %a, metadata !9, metadata !DIExpression()), !dbg !17
-  %b = alloca i32, align 4, !dbg !18
-  call void @llvm.dbg.value(metadata ptr %b, metadata !11, metadata !DIExpression()), !dbg !18
-  %c = alloca i32, align 4, !dbg !19
-  call void @llvm.dbg.value(metadata ptr %c, metadata !12, metadata !DIExpression()), !dbg !19
-  store i32 2, ptr %a, align 4, !dbg !20
-  store i32 3, ptr %b, align 4, !dbg !21
-  store i32 4, ptr %c, align 4, !dbg !22
-  %al = load i32, ptr %a, align 4, !dbg !23
-  call void @llvm.dbg.value(metadata i32 %al, metadata !13, metadata !DIExpression()), !dbg !23
-  %bl = load i32, ptr %b, align 4, !dbg !24
-  call void @llvm.dbg.value(metadata i32 %bl, metadata !15, metadata !DIExpression()), !dbg !24
-  %cl = load i32, ptr %c, align 4, !dbg !25
-  call void @llvm.dbg.value(metadata i32 %cl, metadata !16, metadata !DIExpression()), !dbg !25
-  ret void, !dbg !26
-}
-
-define void @outline_debug2() !dbg !27 {
-entry:
-  %a = alloca i32, align 4, !dbg !35
-  call void @llvm.dbg.value(metadata ptr %a, metadata !29, metadata !DIExpression()), !dbg !35
-  %b = alloca i32, align 4, !dbg !36
-  call void @llvm.dbg.value(metadata ptr %b, metadata !30, metadata !DIExpression()), !dbg !36
-  %c = alloca i32, align 4, !dbg !37
-  call void @llvm.dbg.value(metadata ptr %c, metadata !31, metadata !DIExpression()), !dbg !37
-  store i32 2, ptr %a, align 4, !dbg !38
-  store i32 3, ptr %b, align 4, !dbg !39
-  store i32 4, ptr %c, align 4, !dbg !40
-  %al = load i32, ptr %a, align 4, !dbg !41
-  call void @llvm.dbg.value(metadata i32 %al, metadata !32, metadata !DIExpression()), !dbg !41
-  %bl = load i32, ptr %b, align 4, !dbg !42
-  call void @llvm.dbg.value(metadata i32 %bl, metadata !33, metadata !DIExpression()), !dbg !42
-  %cl = load i32, ptr %c, align 4, !dbg !43
-  call void @llvm.dbg.value(metadata i32 %cl, metadata !34, metadata !DIExpression()), !dbg !43
-  ret void, !dbg !44
-}
-
-; Function Attrs: nounwind readnone speculatable willreturn
-declare void @llvm.dbg.value(metadata, metadata, metadata) #0
-
-attributes #0 = { nounwind readnone speculatable willreturn }
-
-!llvm.dbg.cu = !{!0}
-!llvm.debugify = !{!3, !4}
-!llvm.module.flags = !{!5}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
-!1 = !DIFile(filename: "llvm/test/DebugInfo/ir-outliner.ll", directory: "/")
-!2 = !{}
-!3 = !{i32 20}
-!4 = !{i32 12}
-!5 = !{i32 2, !"Debug Info Version", i32 3}
-!6 = distinct !DISubprogram(name: "outline_debug1", linkageName: "outline_debug1", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
-!7 = !DISubroutineType(types: !2)
-!8 = !{!9, !11, !12, !13, !15, !16}
-!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
-!10 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_unsigned)
-!11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !10)
-!12 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !10)
-!13 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 7, type: !14)
-!14 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
-!15 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 8, type: !14)
-!16 = !DILocalVariable(name: "6", scope: !6, file: !1, line: 9, type: !14)
-!17 = !DILocation(line: 1, column: 1, scope: !6)
-!18 = !DILocation(line: 2, column: 1, scope: !6)
-!19 = !DILocation(line: 3, column: 1, scope: !6)
-!20 = !DILocation(line: 4, column: 1, scope: !6)
-!21 = !DILocation(line: 5, column: 1, scope: !6)
-!22 = !DILocation(line: 6, column: 1, scope: !6)
-!23 = !DILocation(line: 7, column: 1, scope: !6)
-!24 = !DILocation(line: 8, column: 1, scope: !6)
-!25 = !DILocation(line: 9, column: 1, scope: !6)
-!26 = !DILocation(line: 10, column: 1, scope: !6)
-!27 = distinct !DISubprogram(name: "outline_debug2", linkageName: "outline_debug2", scope: null, file: !1, line: 11, type: !7, scopeLine: 11, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !28)
-!28 = !{!29, !30, !31, !32, !33, !34}
-!29 = !DILocalVariable(name: "7", scope: !27, file: !1, line: 11, type: !10)
-!30 = !DILocalVariable(name: "8", scope: !27, file: !1, line: 12, type: !10)
-!31 = !DILocalVariable(name: "9", scope: !27, file: !1, line: 13, type: !10)
-!32 = !DILocalVariable(name: "10", scope: !27, file: !1, line: 17, type: !14)
-!33 = !DILocalVariable(name: "11", scope: !27, file: !1, line: 18, type: !14)
-!34 = !DILocalVariable(name: "12", scope: !27, file: !1, line: 19, type: !14)
-!35 = !DILocation(line: 11, column: 1, scope: !27)
-!36 = !DILocation(line: 12, column: 1, scope: !27)
-!37 = !DILocation(line: 13, column: 1, scope: !27)
-!38 = !DILocation(line: 14, column: 1, scope: !27)
-!39 = !DILocation(line: 15, column: 1, scope: !27)
-!40 = !DILocation(line: 16, column: 1, scope: !27)
-!41 = !DILocation(line: 17, column: 1, scope: !27)
-!42 = !DILocation(line: 18, column: 1, scope: !27)
-!43 = !DILocation(line: 19, column: 1, scope: !27)
-!44 = !DILocation(line: 20, column: 1, scope: !27)
-
-; IRDEBUG-LABEL: @outline_debug1(
-; IRDEBUG-NEXT:  entry:
-; IRDEBUG-NEXT:    [[A:%.*]] = alloca i32, align 4, !dbg [[DBG17:![0-9]+]]
-; IRDEBUG-NEXT:      #dbg_value(ptr [[A]], [[META9:![0-9]+]], !DIExpression(), [[DBG17]])
-; IRDEBUG-NEXT:    [[B:%.*]] = alloca i32, align 4, !dbg [[DBG18:![0-9]+]]
-; IRDEBUG-NEXT:      #dbg_value(ptr [[B]], [[META11:![0-9]+]], !DIExpression(), [[DBG18]])
-; IRDEBUG-NEXT:    [[C:%.*]] = alloca i32, align 4, !dbg [[DBG19:![0-9]+]]
-; IRDEBUG-NEXT:      #dbg_value(ptr [[C]], [[META12:![0-9]+]], !DIExpression(), [[DBG19]])
-; IRDEBUG-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]]), !dbg [[DBG20:![0-9]+]]
-; IRDEBUG-NEXT:    ret void, !dbg [[DBG21:![0-9]+]]
-;
-;
-; IRDEBUG-LABEL: @outline_debug2(
-; IRDEBUG-NEXT:  entry:
-; IRDEBUG-NEXT:    [[A:%.*]] = alloca i32, align 4, !dbg [[DBG30:![0-9]+]]
-; IRDEBUG-NEXT:      #dbg_value(ptr [[A]], [[META24:![0-9]+]], !DIExpression(), [[DBG30]])
-; IRDEBUG-NEXT:    [[B:%.*]] = alloca i32, align 4, !dbg [[DBG31:![0-9]+]]
-; IRDEBUG-NEXT:      #dbg_value(ptr [[B]], [[META25:![0-9]+]], !DIExpression(), [[DBG31]])
-; IRDEBUG-NEXT:    [[C:%.*]] = alloca i32, align 4, !dbg [[DBG32:![0-9]+]]
-; IRDEBUG-NEXT:      #dbg_value(ptr [[C]], [[META26:![0-9]+]], !DIExpression(), [[DBG32]])
-; IRDEBUG-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]]), !dbg [[DBG33:![0-9]+]]
-; IRDEBUG-NEXT:    ret void, !dbg [[DBG34:![0-9]+]]
-;
-;
-; IRDEBUG-LABEL: define {{.+}} @outlined_ir_func_0(
-; IRDEBUG-NEXT:  newFuncRoot:
-; IRDEBUG-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; IRDEBUG:       entry_to_outline:
-; IRDEBUG-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; IRDEBUG-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; IRDEBUG-NEXT:    store i32 4, ptr [[TMP2:%.*]], align 4
-; IRDEBUG-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; IRDEBUG-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; IRDEBUG-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; IRDEBUG-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; IRDEBUG:       entry_after_outline.exitStub:
-; IRDEBUG-NEXT:    ret void
-;
diff --git a/llvm/test/Other/new-pm-defaults.ll b/llvm/test/Other/new-pm-defaults.ll
index 3d6b2b4b702c6..6b2edf339dfdf 100644
--- a/llvm/test/Other/new-pm-defaults.ll
+++ b/llvm/test/Other/new-pm-defaults.ll
@@ -77,10 +77,6 @@
 ; RUN:     -passes='default<O3>' -enable-merge-functions -S  %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,CHECK-O23,%llvmcheckext,CHECK-MERGE-FUNCS
 
-; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
-; RUN:     -passes='default<O3>' -ir-outliner -S  %s 2>&1 \
-; RUN:     | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,CHECK-O23,%llvmcheckext,CHECK-IR-OUTLINER
-
 ; RUN: opt -disable-verify -verify-analysis-invalidation=0 -eagerly-invalidate-analyses=0 -debug-pass-manager \
 ; RUN:     -passes='default<O3>' -hot-cold-split -S  %s 2>&1 \
 ; RUN:     | FileCheck %s --check-prefixes=CHECK-O,CHECK-DEFAULT,CHECK-O3,CHECK-O23,%llvmcheckext,CHECK-HOT-COLD-SPLIT
@@ -277,8 +273,6 @@
 ; CHECK-DEFAULT-NEXT: Running pass: AllocToken
 ; CHECK-EP-OPTIMIZER-LAST: Running pass: NoOpModulePass
 ; CHECK-HOT-COLD-SPLIT-NEXT: Running pass: HotColdSplittingPass
-; CHECK-IR-OUTLINER-NEXT: Running pass: IROutlinerPass
-; CHECK-IR-OUTLINER-NEXT: Running analysis: IRSimilarityAnalysis
 ; CHECK-O-NEXT: Running pass: GlobalDCEPass
 ; CHECK-O-NEXT: Running pass: ConstantMergePass
 ; CHECK-MERGE-FUNCS-NEXT: Running pass: MergeFunctionsPass
diff --git a/llvm/test/Transforms/IROutliner/alloca-addrspace-1.ll b/llvm/test/Transforms/IROutliner/alloca-addrspace-1.ll
deleted file mode 100644
index 73db71b6bafc9..0000000000000
--- a/llvm/test/Transforms/IROutliner/alloca-addrspace-1.ll
+++ /dev/null
@@ -1,46 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
-; RUN: opt -S -passes=iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-target datalayout = "A5"
-
-define i32 @func_with_outgoing_new_allocas() {
-bb:
-  %i = tail call i32 @func0(i32 0, i32 1)
-  %i1 = or i32 0, %i
-  %i2 = tail call i32 @func0(i32 %i1, i32 0)
-  %i3 = or i32 %i1, %i2
-  %i4 = tail call i32 @llvm.foo(i32 %i3, i32 0)
-  ret i32 0
-}
-
-declare i32 @func0(i32, i32)
-declare i32 @llvm.foo(i32, i32)
-
-; CHECK-LABEL: define {{[^@]+}}@func_with_outgoing_new_allocas() {
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I3_LOC:%.*]] = alloca i32, align 4, addrspace(5)
-; CHECK-NEXT:    [[I1_LOC:%.*]] = alloca i32, align 4, addrspace(5)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p5(ptr addrspace(5) [[I1_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 0, i32 1, ptr addrspace(5) [[I1_LOC]])
-; CHECK-NEXT:    [[I1_RELOAD:%.*]] = load i32, ptr addrspace(5) [[I1_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p5(ptr addrspace(5) [[I1_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p5(ptr addrspace(5) [[I3_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[I1_RELOAD]], i32 0, ptr addrspace(5) [[I3_LOC]])
-; CHECK-NEXT:    [[I3_RELOAD:%.*]] = load i32, ptr addrspace(5) [[I3_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p5(ptr addrspace(5) [[I3_LOC]])
-; CHECK-NEXT:    [[I4:%.*]] = tail call i32 @llvm.foo(i32 [[I3_RELOAD]], i32 0)
-; CHECK-NEXT:    ret i32 0
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outlined_ir_func_0
-; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], ptr addrspace(5) [[TMP2:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB_TO_OUTLINE:%.*]]
-; CHECK:       bb_to_outline:
-; CHECK-NEXT:    [[I:%.*]] = tail call i32 @func0(i32 [[TMP0]], i32 [[TMP1]])
-; CHECK-NEXT:    [[I1:%.*]] = or i32 [[TMP0]], [[I]]
-; CHECK-NEXT:    br label [[BB_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       bb_after_outline.exitStub:
-; CHECK-NEXT:    store i32 [[I1]], ptr addrspace(5) [[TMP2]], align 4
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/alloca-addrspace.ll b/llvm/test/Transforms/IROutliner/alloca-addrspace.ll
deleted file mode 100644
index ed7644426ffc0..0000000000000
--- a/llvm/test/Transforms/IROutliner/alloca-addrspace.ll
+++ /dev/null
@@ -1,46 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
-; RUN: opt -S -passes=iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Check alloca with non-0 address spaces works correctly.
-
-target datalayout = "A5"
-
-define i32 @outlineable() {
-bb:
-  %i = tail call i32 @func(i32 0, i32 1)
-  %i1 = or i32 0, %i
-  %i2 = tail call i32 @func(i32 %i1, i32 0)
-  %i3 = or i32 %i1, %i2
-  ret i32 0
-}
-
-declare i32 @func(i32, i32)
-; CHECK-LABEL: define {{[^@]+}}@outlineable() {
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    [[I1_LOC:%.*]] = alloca i32, align 4, addrspace(5)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p5(ptr addrspace(5) [[I1_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 0, i32 1, ptr addrspace(5) [[I1_LOC]], i32 0)
-; CHECK-NEXT:    [[I1_RELOAD:%.*]] = load i32, ptr addrspace(5) [[I1_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p5(ptr addrspace(5) [[I1_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[I1_RELOAD]], i32 0, ptr addrspace(5) null, i32 -1)
-; CHECK-NEXT:    ret i32 0
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outlined_ir_func_0
-; CHECK-SAME: (i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], ptr addrspace(5) [[TMP2:%.*]], i32 [[TMP3:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB_TO_OUTLINE:%.*]]
-; CHECK:       bb_to_outline:
-; CHECK-NEXT:    [[I:%.*]] = tail call i32 @func(i32 [[TMP0]], i32 [[TMP1]])
-; CHECK-NEXT:    [[I1:%.*]] = or i32 [[TMP0]], [[I]]
-; CHECK-NEXT:    br label [[BB_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       bb_after_outline.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP3]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[I1]], ptr addrspace(5) [[TMP2]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/different-intrinsics.ll b/llvm/test/Transforms/IROutliner/different-intrinsics.ll
deleted file mode 100644
index f0e43bb533fdc..0000000000000
--- a/llvm/test/Transforms/IROutliner/different-intrinsics.ll
+++ /dev/null
@@ -1,92 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do not outline different intrinsics as the same
-; function or as a value like we would for non-intrinsic functions.
-
-declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-declare void @llvm.memmove.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-
-define i8 @function1(ptr noalias %s, ptr noalias %d, i64 %len) {
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-define i8 @function2(ptr noalias %s, ptr noalias %d, i64 %len) {
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[A_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[S:%.*]], ptr [[D:%.*]], ptr [[A_LOC]], ptr [[B_LOC]])
-; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i8, ptr [[A_LOC]], align 1
-; CHECK-NEXT:    [[B_RELOAD:%.*]] = load i8, ptr [[B_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[D]], ptr [[S]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], ptr [[S]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[A_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[S:%.*]], ptr [[D:%.*]], ptr [[A_LOC]], ptr [[B_LOC]])
-; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i8, ptr [[A_LOC]], align 1
-; CHECK-NEXT:    [[B_RELOAD:%.*]] = load i8, ptr [[B_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[D]], ptr [[S]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], ptr [[S]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = add i8 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    [[RET:%.*]] = load i8, ptr [[TMP2:%.*]], align 1
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    store i8 [[RET]], ptr [[TMP3:%.*]], align 1
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_1(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[A:%.*]] = load i8, ptr [[TMP0:%.*]], align 1
-; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[TMP1:%.*]], align 1
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    store i8 [[A]], ptr [[TMP2:%.*]], align 1
-; CHECK-NEXT:    store i8 [[B]], ptr [[TMP3:%.*]], align 1
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/different-order-phi-merges.ll b/llvm/test/Transforms/IROutliner/different-order-phi-merges.ll
deleted file mode 100644
index 6730d1bda0f82..0000000000000
--- a/llvm/test/Transforms/IROutliner/different-order-phi-merges.ll
+++ /dev/null
@@ -1,113 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Check that differently ordered phi nodes are not matched when merged, instead
-; generating two output paths.
-
-define void @f1() {
-bb1:
-  %0 = add i32 1, 2
-  %1 = add i32 3, 4
-  %2 = add i32 5, 6
-  %3 = add i32 7, 8
-  br i1 true, label %bb2, label %bb5
-bb2:
-  %4 = mul i32 5, 4
-  br label %bb5
-
-placeholder:
-  %a = sub i32 5, 4
-  ret void
-
-bb5:
-  %phinode = phi i32 [%3, %bb1], [%2, %bb2]
-  ret void
-}
-
-define void @f2() {
-bb1:
-  %0 = add i32 1, 2
-  %1 = add i32 3, 4
-  %2 = add i32 5, 6
-  %3 = add i32 7, 8
-  br i1 true, label %bb2, label %bb5
-bb2:
-  %4 = mul i32 5, 4
-  br label %bb5
-
-placeholder:
-  %a = sub i32 5, 4
-  ret void
-
-bb5:
-  %phinode = phi i32 [%2, %bb1], [%3, %bb2]
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], i32 0)
-; CHECK-NEXT:    [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BB5:%.*]], label [[BB1_AFTER_OUTLINE:%.*]]
-; CHECK:       bb1_after_outline:
-; CHECK-NEXT:    ret void
-; CHECK:       bb5:
-; CHECK-NEXT:    [[PHINODE:%.*]] = phi i32 [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], i32 1)
-; CHECK-NEXT:    [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BB5:%.*]], label [[BB1_AFTER_OUTLINE:%.*]]
-; CHECK:       bb1_after_outline:
-; CHECK-NEXT:    ret void
-; CHECK:       bb5:
-; CHECK-NEXT:    [[PHINODE:%.*]] = phi i32 [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB1_TO_OUTLINE:%.*]]
-; CHECK:       bb1_to_outline:
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 1, 2
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 3, 4
-; CHECK-NEXT:    [[TMP4:%.*]] = add i32 5, 6
-; CHECK-NEXT:    [[TMP5:%.*]] = add i32 7, 8
-; CHECK-NEXT:    br i1 true, label [[BB2:%.*]], label [[BB5_SPLIT:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 5, 4
-; CHECK-NEXT:    br label [[BB5_SPLIT]]
-; CHECK:       placeholder:
-; CHECK-NEXT:    [[A:%.*]] = sub i32 5, 4
-; CHECK-NEXT:    br label [[BB1_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       bb5.split:
-; CHECK-NEXT:    [[TMP7:%.*]] = phi i32 [ [[TMP4]], [[BB1_TO_OUTLINE]] ], [ [[TMP5]], [[BB2]] ]
-; CHECK-NEXT:    [[PHINODE_CE:%.*]] = phi i32 [ [[TMP5]], [[BB1_TO_OUTLINE]] ], [ [[TMP4]], [[BB2]] ]
-; CHECK-NEXT:    br label [[BB5_EXITSTUB:%.*]]
-; CHECK:       bb5.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP1:%.*]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_1:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       bb1_after_outline.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP1]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_1:
-; CHECK-NEXT:    store i32 [[PHINODE_CE]], ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       output_block_1_1:
-; CHECK-NEXT:    store i32 [[TMP7]], ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
diff --git a/llvm/test/Transforms/IROutliner/duplicate-merging-phis.ll b/llvm/test/Transforms/IROutliner/duplicate-merging-phis.ll
deleted file mode 100644
index 53d52f51f7ad2..0000000000000
--- a/llvm/test/Transforms/IROutliner/duplicate-merging-phis.ll
+++ /dev/null
@@ -1,113 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Make sure that when we merge phi nodes, we do not merge two different PHINodes
-; as the same phi node.
-
-define void @f1() {
-bb1:
-  %0 = add i32 1, 2
-  %1 = add i32 3, 4
-  %2 = add i32 5, 6
-  %3 = add i32 7, 8
-  br label %bb5
-bb2:
-  %4 = mul i32 5, 4
-  br label %bb5
-
-placeholder:
-  %a = sub i32 5, 4
-  ret void
-
-bb5:
-  %phinode = phi i32 [5, %bb1], [5, %bb2]
-  %phinode1 = phi i32 [5, %bb1], [5, %bb2]
-  ret void
-}
-
-define void @f2() {
-bb1:
-  %0 = add i32 1, 2
-  %1 = add i32 3, 4
-  %2 = add i32 5, 6
-  %3 = add i32 7, 8
-  br label %bb5
-bb2:
-  %4 = mul i32 5, 4
-  br label %bb5
-
-placeholder:
-  %a = sub i32 5, 4
-  ret void
-
-bb5:
-  %phinode = phi i32 [5, %bb1], [5, %bb2]
-  %phinode1 = phi i32 [5, %bb1], [5, %bb2]
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[PHINODE1_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE1_CE_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], ptr [[PHINODE1_CE_LOC]])
-; CHECK-NEXT:    [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4
-; CHECK-NEXT:    [[PHINODE1_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE1_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE1_CE_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[BB5:%.*]], label [[BB1_AFTER_OUTLINE:%.*]]
-; CHECK:       bb1_after_outline:
-; CHECK-NEXT:    ret void
-; CHECK:       bb5:
-; CHECK-NEXT:    [[PHINODE:%.*]] = phi i32 [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ]
-; CHECK-NEXT:    [[PHINODE1:%.*]] = phi i32 [ [[PHINODE1_CE_RELOAD]], [[BB1]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[PHINODE1_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE1_CE_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], ptr [[PHINODE1_CE_LOC]])
-; CHECK-NEXT:    [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4
-; CHECK-NEXT:    [[PHINODE1_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE1_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE1_CE_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[BB5:%.*]], label [[BB1_AFTER_OUTLINE:%.*]]
-; CHECK:       bb1_after_outline:
-; CHECK-NEXT:    ret void
-; CHECK:       bb5:
-; CHECK-NEXT:    [[PHINODE:%.*]] = phi i32 [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ]
-; CHECK-NEXT:    [[PHINODE1:%.*]] = phi i32 [ [[PHINODE1_CE_RELOAD]], [[BB1]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB1_TO_OUTLINE:%.*]]
-; CHECK:       bb1_to_outline:
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 1, 2
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 3, 4
-; CHECK-NEXT:    [[TMP4:%.*]] = add i32 5, 6
-; CHECK-NEXT:    [[TMP5:%.*]] = add i32 7, 8
-; CHECK-NEXT:    br label [[BB5_SPLIT:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 5, 4
-; CHECK-NEXT:    br label [[BB5_SPLIT]]
-; CHECK:       placeholder:
-; CHECK-NEXT:    [[A:%.*]] = sub i32 5, 4
-; CHECK-NEXT:    br label [[BB1_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       bb5.split:
-; CHECK-NEXT:    [[PHINODE_CE:%.*]] = phi i32 [ 5, [[BB1_TO_OUTLINE]] ], [ 5, [[BB2:%.*]] ]
-; CHECK-NEXT:    [[PHINODE1_CE:%.*]] = phi i32 [ 5, [[BB1_TO_OUTLINE]] ], [ 5, [[BB2]] ]
-; CHECK-NEXT:    br label [[BB5_EXITSTUB:%.*]]
-; CHECK:       bb5.exitStub:
-; CHECK-NEXT:    store i32 [[PHINODE_CE]], ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 [[PHINODE1_CE]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    ret i1 true
-; CHECK:       bb1_after_outline.exitStub:
-; CHECK-NEXT:    ret i1 false
-;
diff --git a/llvm/test/Transforms/IROutliner/exit-block-phi-node-value-attribution.ll b/llvm/test/Transforms/IROutliner/exit-block-phi-node-value-attribution.ll
deleted file mode 100644
index 04ec9284ff5b6..0000000000000
--- a/llvm/test/Transforms/IROutliner/exit-block-phi-node-value-attribution.ll
+++ /dev/null
@@ -1,96 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Make sure that each outlined region only analyzes on the incoming values in exit
-; block phi nodes that come from the outlined region.  Without this, more incoming
-; values from the phi node would be considered if the incoming value is
-; included in the outlined region. This is particularly likely to happen for
-; constants.
-
-define void @f1() {
-bb1:
-  %0 = add i32 1, 2
-  %1 = add i32 3, 4
-  %2 = add i32 5, 6
-  %3 = add i32 7, 8
-  br label %bb5
-bb2:
-  %4 = mul i32 5, 4
-  br label %bb5
-placeholder:
-  %a = sub i32 5, 4
-  br label %bb5
-bb3:
-  %5 = add i32 1, 2
-  %6 = add i32 3, 4
-  %7 = add i32 5, 6
-  %8 = add i32 7, 8
-  br label %bb5
-bb4:
-  %9 = mul i32 5, 4
-  br label %bb5
-
-placeholder1:
-  %b = add i32 5, 4
-  ret void
-
-bb5:
-  %phinode = phi i32 [5, %placeholder], [5, %bb1], [5, %bb2], [4, %bb3], [4, %bb4]
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[PHINODE_CE_LOC1:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[PHINODE_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[PHINODE_CE_LOC]], i32 0)
-; CHECK-NEXT:    [[PHINODE_CE_RELOAD:%.*]] = load i32, ptr [[PHINODE_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE_CE_LOC]])
-; CHECK-NEXT:    br label [[BB5:%.*]]
-; CHECK:       placeholder:
-; CHECK-NEXT:    [[A:%.*]] = sub i32 5, 4
-; CHECK-NEXT:    br label [[BB5]]
-; CHECK:       bb3:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[PHINODE_CE_LOC1]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[PHINODE_CE_LOC1]], i32 1)
-; CHECK-NEXT:    [[PHINODE_CE_RELOAD2:%.*]] = load i32, ptr [[PHINODE_CE_LOC1]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[PHINODE_CE_LOC1]])
-; CHECK-NEXT:    br label [[BB5]]
-; CHECK:       placeholder1:
-; CHECK-NEXT:    [[B:%.*]] = add i32 5, 4
-; CHECK-NEXT:    ret void
-; CHECK:       bb5:
-; CHECK-NEXT:    [[PHINODE:%.*]] = phi i32 [ 5, [[PLACEHOLDER:%.*]] ], [ [[PHINODE_CE_RELOAD]], [[BB1:%.*]] ], [ [[PHINODE_CE_RELOAD2]], [[BB3:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB1_TO_OUTLINE:%.*]]
-; CHECK:       bb1_to_outline:
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 1, 2
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 3, 4
-; CHECK-NEXT:    [[TMP4:%.*]] = add i32 5, 6
-; CHECK-NEXT:    [[TMP5:%.*]] = add i32 7, 8
-; CHECK-NEXT:    br label [[BB5_SPLIT:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[TMP6:%.*]] = mul i32 5, 4
-; CHECK-NEXT:    br label [[BB5_SPLIT]]
-; CHECK:       bb5.split:
-; CHECK-NEXT:    [[TMP7:%.*]] = phi i32 [ 4, [[BB1_TO_OUTLINE]] ], [ 4, [[BB2:%.*]] ]
-; CHECK-NEXT:    [[PHINODE_CE:%.*]] = phi i32 [ 5, [[BB1_TO_OUTLINE]] ], [ 5, [[BB2]] ]
-; CHECK-NEXT:    br label [[BB5_EXITSTUB:%.*]]
-; CHECK:       bb5.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP1:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[PHINODE_CE]], ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[TMP7]], ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/exit-phi-nodes-incoming-value-constant-argument.ll b/llvm/test/Transforms/IROutliner/exit-phi-nodes-incoming-value-constant-argument.ll
deleted file mode 100644
index 0e82217708d14..0000000000000
--- a/llvm/test/Transforms/IROutliner/exit-phi-nodes-incoming-value-constant-argument.ll
+++ /dev/null
@@ -1,110 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; When consolidating PHINodes, the outliner replaces the incoming value with
-; a corresponding value from the first outlined section.  When this replaced
-; value is passed in as an argument, the corresponding value is found outside
-; of the outlined region, and must be replaced with an argument to avoid
-; dominating value errors. This checks that we use the argument to replace
-; the incoming value.
-
-define void @func1(i32 %0, i32 %1) local_unnamed_addr #0 {
-bb1:
-  br label %bb5
-
-bb2:
-  %a = add i32 %0, %1
-  %b = add i32 %0, %1
-  %c = icmp eq i32 %b, %a
-  br i1 %c, label %bb5, label %bb3
-
-bb3:
-  %d = add i32 %0, %1
-  br label %bb5
-
-bb4:
-  %e = sub i32 %0, %1
-  br label %bb2
-
-bb5:
-  ret void
-}
-
-define void @func2(i32 %0, i32 %1) local_unnamed_addr #0 {
-bb1:
-  br label %bb5
-
-bb2:
-  %a = sub i32 %0, %1
-  %b = add i32 %0, %1
-  %c = icmp eq i32 %b, 1
-  br i1 %c, label %bb5, label %bb3
-
-bb3:
-  %d = add i32 %0, %1
-  br label %bb5
-
-bb4:
-  %e = add i32 %0, %1
-  br label %bb2
-
-bb5:
-  %f = phi i32 [ 0, %bb1 ], [ 1, %bb2 ], [ 1, %bb3 ]
-  ret void
-}
-; CHECK-LABEL: @func1(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    br label [[BB5:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[A:%.*]] = add i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0]], i32 [[TMP1]], i32 [[A]], ptr null, i32 -1)
-; CHECK-NEXT:    br label [[BB5]]
-; CHECK:       bb4:
-; CHECK-NEXT:    [[E:%.*]] = sub i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb5:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @func2(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[F_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BB5:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[A:%.*]] = sub i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[F_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0]], i32 [[TMP1]], i32 1, ptr [[F_CE_LOC]], i32 0)
-; CHECK-NEXT:    [[F_CE_RELOAD:%.*]] = load i32, ptr [[F_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[F_CE_LOC]])
-; CHECK-NEXT:    br label [[BB5]]
-; CHECK:       bb4:
-; CHECK-NEXT:    [[E:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb5:
-; CHECK-NEXT:    [[F:%.*]] = phi i32 [ 0, [[BB1:%.*]] ], [ [[F_CE_RELOAD]], [[BB2]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB2_TO_OUTLINE:%.*]]
-; CHECK:       bb2_to_outline:
-; CHECK-NEXT:    [[B:%.*]] = add i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[B]], [[TMP2:%.*]]
-; CHECK-NEXT:    br i1 [[C]], label [[PHI_BLOCK:%.*]], label [[BB3:%.*]]
-; CHECK:       bb3:
-; CHECK-NEXT:    [[D:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br label [[PHI_BLOCK]]
-; CHECK:       bb5.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP4:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[TMP5:%.*]], ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       phi_block:
-; CHECK-NEXT:    [[TMP5]] = phi i32 [ [[TMP2]], [[BB2_TO_OUTLINE]] ], [ [[TMP2]], [[BB3]] ]
-; CHECK-NEXT:    br label [[BB5_EXITSTUB:%.*]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/extraction.ll b/llvm/test/Transforms/IROutliner/extraction.ll
deleted file mode 100644
index 77f904dd70861..0000000000000
--- a/llvm/test/Transforms/IROutliner/extraction.ll
+++ /dev/null
@@ -1,127 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test makes sure we are extracting the found similarity sections
-; correctly at the call site.
-
-define void @extract1() {
-; CHECK-LABEL: @extract1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @extract2() {
-; CHECK-LABEL: @extract2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; There are potential ouptuts in this sections, but we do not extract sections
-; with outputs right now, since they cannot be consolidated.
-define void @extract_outs1() #0 {
-; CHECK-LABEL: @extract_outs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_2(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-; There are potential ouptuts in this sections, but we do not extract sections
-; with outputs right now, since they cannot be consolidated.
-define void @extract_outs2() #0 {
-; CHECK-LABEL: @extract_outs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_2(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/gvn-output-set-overload.ll b/llvm/test/Transforms/IROutliner/gvn-output-set-overload.ll
deleted file mode 100644
index 54f013c5652e6..0000000000000
--- a/llvm/test/Transforms/IROutliner/gvn-output-set-overload.ll
+++ /dev/null
@@ -1,119 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do differentiate between outputs of the region stored in PHINodes
-; versus those stored outside of PHINodes.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-next:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  ret void
-next:
-  %1 = add i32 %c, 1
-  %2 = add i32 %e, 1
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]], ptr null, i32 0)
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[C_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], ptr [[C_LOC]], ptr [[E_LOC]], i32 1)
-; CHECK-NEXT:    [[C_RELOAD:%.*]] = load i32, ptr [[C_LOC]], align 4
-; CHECK-NEXT:    [[E_RELOAD:%.*]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[C_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[C_RELOAD]], 1
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[E_RELOAD]], 1
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT:%.*]], label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT]], label [[NEXT_EXITSTUB:%.*]]
-; CHECK:       first.split:
-; CHECK-NEXT:    [[DOTCE:%.*]] = phi i32 [ [[C]], [[TEST]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP3:%.*]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_1:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       next.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP3]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_1:
-; CHECK-NEXT:    store i32 [[DOTCE]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[C]], ptr [[TMP1]], align 4
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_1:
-; CHECK-NEXT:    store i32 [[C]], ptr [[TMP1]], align 4
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
diff --git a/llvm/test/Transforms/IROutliner/gvn-phi-debug.ll b/llvm/test/Transforms/IROutliner/gvn-phi-debug.ll
deleted file mode 100644
index 0c899dcd0339f..0000000000000
--- a/llvm/test/Transforms/IROutliner/gvn-phi-debug.ll
+++ /dev/null
@@ -1,175 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-target datalayout = "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
-target triple = "thumbv7-none-linux-android19"
-
-define i32 @r() {
-; CHECK-LABEL: define i32 @r() {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca ptr, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[DOTLOC]], i32 0)
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load ptr, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_END8:%.*]], label [[ENTRY_AFTER_OUTLINE:%.*]]
-; CHECK:       entry_after_outline:
-; CHECK-NEXT:    [[CALL7:%.*]] = call i32 [[DOTRELOAD]]()
-; CHECK-NEXT:    br label [[IF_END8]]
-; CHECK:       if.end8:
-; CHECK-NEXT:    ret i32 0
-;
-entry:
-  %.fca.2.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 2
-  %.fca.3.load = load i32, ptr null, align 4
-  %.fca.3.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 3
-  %.fca.4.load = load i32, ptr null, align 4
-  %.fca.4.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 4
-  %call = call i32 @p()
-  %tobool.not = icmp eq i32 0, 0
-  br i1 false, label %if.end8, label %if.then
-
-if.then:                                          ; preds = %entry
-  %0 = load i32, ptr null, align 4
-  %tobool1.not = icmp eq i32 0, 0
-  %1 = load i32, ptr null, align 4
-  %2 = load i32, ptr null, align 4
-  %cond = select i1 false, i32 0, i32 0
-  %tobool5.not = icmp eq i32 0, 0
-  br i1 false, label %if.end8, label %if.then6
-
-if.then6:                                         ; preds = %if.then
-  %3 = load ptr, ptr null, align 4
-  %call7 = call i32 %3()
-  br label %if.end8
-
-if.end8:                                          ; preds = %if.then6, %if.then, %entry
-  ret i32 0
-}
-
-declare i32 @p()
-
-define i32 @u() {
-; CHECK-LABEL: define i32 @u() {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr null, i32 -1)
-; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_END8:%.*]], label [[ENTRY_AFTER_OUTLINE:%.*]]
-; CHECK:       entry_after_outline:
-; CHECK-NEXT:    br label [[IF_END8]]
-; CHECK:       if.end8:
-; CHECK-NEXT:    ret i32 0
-;
-entry:
-  %.fca.2.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 2
-  %.fca.3.load = load i32, ptr null, align 4
-  %.fca.3.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 3
-  %.fca.4.load = load i32, ptr null, align 4
-  %.fca.4.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 4
-  %call = call i32 @p()
-  %tobool.not = icmp eq i32 0, 0
-  br i1 false, label %if.end8, label %if.then
-
-if.then:                                          ; preds = %entry
-  %0 = load i32, ptr null, align 4
-  %tobool1.not = icmp eq i32 0, 0
-  %1 = load i32, ptr null, align 4
-  %2 = load i32, ptr null, align 4
-  %cond = select i1 false, i32 0, i32 0
-  %tobool5.not = icmp eq i32 0, 0
-  br i1 false, label %if.end8, label %if.then6
-
-if.then6:                                         ; preds = %if.then
-  %3 = load ptr, ptr null, align 4
-  br label %if.end8
-
-if.end8:                                          ; preds = %if.then6, %if.then, %entry
-  ret i32 0
-}
-
-define i32 @w() !dbg !8 {
-; CHECK-LABEL: define i32 @w(
-; CHECK-SAME: ) !dbg [[DBG8:![0-9]+]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[RETVAL_1_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RETVAL_1_CE_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[RETVAL_1_CE_LOC]], i32 1), !dbg [[DBG11:![0-9]+]]
-; CHECK-NEXT:    [[RETVAL_1_CE_RELOAD:%.*]] = load i32, ptr [[RETVAL_1_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RETVAL_1_CE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[CLEANUP10:%.*]], label [[ENTRY_AFTER_OUTLINE:%.*]]
-; CHECK:       entry_after_outline:
-; CHECK-NEXT:    [[CALL8:%.*]] = call i32 @llvm.bswap.i32(i32 0)
-; CHECK-NEXT:    br label [[CLEANUP10]]
-; CHECK:       cleanup10:
-; CHECK-NEXT:    [[RETVAL_1:%.*]] = phi i32 [ 0, [[ENTRY_AFTER_OUTLINE]] ], [ [[RETVAL_1_CE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret i32 0
-;
-entry:
-  %.fca.2.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 2
-  %.fca.3.load = load i32, ptr null, align 4
-  %.fca.3.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 3
-  %.fca.4.load = load i32, ptr null, align 4
-  %.fca.4.insert = insertvalue [5 x i32] zeroinitializer, i32 0, 4
-  %call = call i32 @p()
-  %tobool.not = icmp eq i32 0, 0
-  br i1 false, label %cleanup10, label %if.then
-
-if.then:                                          ; preds = %entry
-  call void @llvm.dbg.value(metadata i32 0, metadata !11, metadata !DIExpression()), !dbg !15
-  %0 = load i32, ptr null, align 4
-  %tobool1.not = icmp eq i32 0, 0
-  %1 = load i32, ptr null, align 4
-  %2 = load i32, ptr null, align 4
-  %cond = select i1 false, i32 0, i32 0
-  %tobool5.not = icmp eq i32 0, 0
-  br i1 false, label %cleanup10, label %cleanup
-
-cleanup:                                          ; preds = %if.then
-  %3 = load ptr, ptr null, align 4
-  %call8 = call i32 @llvm.bswap.i32(i32 0)
-  br label %cleanup10
-
-cleanup10:                                        ; preds = %cleanup, %if.then, %entry
-  %retval.1 = phi i32 [ 0, %cleanup ], [ 0, %entry ], [ 0, %if.then ]
-  ret i32 0
-}
-
-; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
-declare void @llvm.dbg.value(metadata, metadata, metadata) #0
-
-; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
-declare i32 @llvm.bswap.i32(i32) #0
-
-attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memory(none) }
-
-!llvm.dbg.cu = !{!0}
-!llvm.module.flags = !{!7}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 18.0.0 (https://github.com/llvm/llvm-project.git 2ca028ce7c6de5f1350440012355a65383b8729a)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: !2, splitDebugInlining: false, nameTableKind: None)
-!1 = !DIFile(filename: "/tmp/foo.c", directory: "/home/davidino/llvm-build-upstream")
-!2 = !{!3}
-!3 = !DIGlobalVariableExpression(var: !4, expr: !DIExpression())
-!4 = distinct !DIGlobalVariable(name: "n", scope: !0, file: !5, line: 19, type: !6, isLocal: false, isDefinition: true)
-!5 = !DIFile(filename: "/tmp/foo.c", directory: "")
-!6 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!7 = !{i32 2, !"Debug Info Version", i32 3}
-!8 = distinct !DISubprogram(name: "w", scope: !5, file: !5, line: 54, type: !9, scopeLine: 54, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !10)
-!9 = !DISubroutineType(types: !10)
-!10 = !{}
-!11 = !DILocalVariable(name: "t", scope: !12, file: !5, line: 57, type: !14)
-!12 = distinct !DILexicalBlock(scope: !13, file: !5, line: 56, column: 17)
-!13 = distinct !DILexicalBlock(scope: !8, file: !5, line: 56, column: 11)
-!14 = !DIDerivedType(tag: DW_TAG_typedef, name: "a", file: !5, line: 2, baseType: !6)
-!15 = !DILocation(line: 0, scope: !12)
-;.
-; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, globals: [[META2:![0-9]+]], splitDebugInlining: false, nameTableKind: None)
-; CHECK: [[META1]] = !DIFile(filename: "/tmp/foo.c", directory: {{.*}})
-; CHECK: [[META2]] = !{[[META3:![0-9]+]]}
-; CHECK: [[META3]] = !DIGlobalVariableExpression(var: [[META4:![0-9]+]], expr: !DIExpression())
-; CHECK: [[META4]] = distinct !DIGlobalVariable(name: "n", scope: [[META0]], file: [[META5:![0-9]+]], line: 19, type: [[META6:![0-9]+]], isLocal: false, isDefinition: true)
-; CHECK: [[META5]] = !DIFile(filename: "/tmp/foo.c", directory: "")
-; CHECK: [[META6]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-; CHECK: [[DBG8]] = distinct !DISubprogram(name: "w", scope: [[META5]], file: [[META5]], line: 54, type: [[META9:![0-9]+]], scopeLine: 54, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META10:![0-9]+]])
-; CHECK: [[META9]] = !DISubroutineType(types: [[META10]])
-; CHECK: [[META10]] = !{}
-; CHECK: [[DBG11]] = !DILocation(line: 0, scope: [[DBG8]])
-;.
diff --git a/llvm/test/Transforms/IROutliner/illegal-allocas.ll b/llvm/test/Transforms/IROutliner/illegal-allocas.ll
deleted file mode 100644
index 7dee2f7b3efc3..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-allocas.ll
+++ /dev/null
@@ -1,36 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner  -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract allocas, as outlining allocas may cause
-; inconsistencies with the CodeExtractor's algorithm.
-
-define void @function1() {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-
-  ret void
-}
-
-define void @function2() {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-assumes.ll b/llvm/test/Transforms/IROutliner/illegal-assumes.ll
deleted file mode 100644
index c0c4e1aa42e34..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-assumes.ll
+++ /dev/null
@@ -1,143 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -p iroutliner,verify -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test ensures that we do not include llvm.assumes.  There are exceptions
-; in the CodeExtractor's algorithm for llvm.assumes, so we ignore it for now.
-
-define void @outline_assumes() {
-; CHECK-LABEL: @outline_assumes(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DL_LOC:%.*]] = alloca i1, align 1
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[D:%.*]] = alloca i1, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_4(i1 true, ptr [[D]], ptr [[DL_LOC]])
-; CHECK-NEXT:    [[DL_RELOAD:%.*]] = load i1, ptr [[DL_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    [[SPLIT_INST:%.*]] = sub i1 [[DL_RELOAD]], [[DL_RELOAD]]
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    call void @llvm.assume(i1 [[DL_RELOAD]])
-; CHECK-NEXT:    call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i1, align 4
-  store i1 1, ptr %d, align 4
-  %dl = load i1, ptr %d
-  %split_inst = sub i1 %dl, %dl
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @llvm.assume(i1 %dl)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_assumes2() {
-; CHECK-LABEL: @outline_assumes2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DL_LOC:%.*]] = alloca i1, align 1
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[D:%.*]] = alloca i1, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_4(i1 false, ptr [[D]], ptr [[DL_LOC]])
-; CHECK-NEXT:    [[DL_RELOAD:%.*]] = load i1, ptr [[DL_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    call void @llvm.assume(i1 [[DL_RELOAD]])
-; CHECK-NEXT:    call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i1, align 4
-  store i1 0, ptr %d, align 4
-  %dl = load i1, ptr %d
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @llvm.assume(i1 %dl)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_assumes3() {
-; CHECK-LABEL: @outline_assumes3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DL_LOC:%.*]] = alloca i1, align 1
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[D:%.*]] = alloca i1, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i1 true, ptr [[D]], ptr [[A]], ptr [[B]], ptr [[C]], ptr [[DL_LOC]])
-; CHECK-NEXT:    [[DL_RELOAD:%.*]] = load i1, ptr [[DL_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @llvm.assume(i1 [[DL_RELOAD]])
-; CHECK-NEXT:    call void @outlined_ir_func_3(ptr [[A]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i1, align 4
-  store i1 1, ptr %d, align 4
-  %dl = load i1, ptr %d
-  %split_inst = add i1 %dl, %dl
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @llvm.assume(i1 %dl)
-  %al = load i32, ptr %a
-  %bl = add i32 %al, %al
-  ret void
-}
-
-define void @outline_assumes4() {
-; CHECK-LABEL: @outline_assumes4(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DL_LOC:%.*]] = alloca i1, align 1
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[D:%.*]] = alloca i1, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i1 false, ptr [[D]], ptr [[A]], ptr [[B]], ptr [[C]], ptr [[DL_LOC]])
-; CHECK-NEXT:    [[DL_RELOAD:%.*]] = load i1, ptr [[DL_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DL_LOC]])
-; CHECK-NEXT:    call void @llvm.assume(i1 [[DL_RELOAD]])
-; CHECK-NEXT:    call void @outlined_ir_func_3(ptr [[A]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i1, align 4
-  store i1 0, ptr %d, align 4
-  %dl = load i1, ptr %d
-  %split_inst = add i1 %dl, %dl
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @llvm.assume(i1 %dl)
-  %al = load i32, ptr %a
-  %bl = add i32 %al, %al
-  ret void
-}
-
-declare void @llvm.assume(i1)
diff --git a/llvm/test/Transforms/IROutliner/illegal-branches.ll b/llvm/test/Transforms/IROutliner/illegal-branches.ll
deleted file mode 100644
index b70d22ab82d90..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-branches.ll
+++ /dev/null
@@ -1,51 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -no-ir-sim-branch-matching -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract sections with branches as it would require extra
-; label and control flow checking.
-
-define void @function1() {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    br label [[NEXT:%.*]]
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  br label %next
-next:
-  ret void
-}
-
-define void @function2() {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    br label [[NEXT:%.*]]
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  br label %next
-next:
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-callbr.ll b/llvm/test/Transforms/IROutliner/illegal-callbr.ll
deleted file mode 100644
index cece6b794d2eb..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-callbr.ll
+++ /dev/null
@@ -1,64 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do not outline callbr instruction since as we do not
-; outline any control flow change instructions.
-
-
-define i32 @function1(i32 %a, i32 %b) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  bb0:
-; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[A:%.*]], 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B:%.*]])
-; CHECK-NEXT:    callbr void asm "xorl $0, $0
-; CHECK-NEXT:    to label [[NORMAL:%.*]] [label %fail1]
-; CHECK:       normal:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
-; CHECK-NEXT:    ret i32 0
-; CHECK:       fail1:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
-; CHECK-NEXT:    ret i32 0
-;
-bb0:
-  %0 = add i32 %a, 4
-  %1 = add i32 %b, 1
-  %2 = add i32 %b, 1
-  callbr void asm "xorl $0, $0; jmp ${1:l}", "r,!i,~{dirflag},~{fpsr},~{flags}"(i32 %0) to label %normal [label %fail1]
-normal:
-  %3 = add i32 %b, 1
-  %4 = add i32 %b, 1
-  ret i32 0
-fail1:
-  %5 = add i32 %b, 1
-  %6 = add i32 %b, 1
-  ret i32 0
-}
-
-define i32 @function2(i32 %a, i32 %b) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  bb0:
-; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[A:%.*]], 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B:%.*]])
-; CHECK-NEXT:    callbr void asm "xorl $0, $0
-; CHECK-NEXT:    to label [[NORMAL:%.*]] [label %fail1]
-; CHECK:       normal:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
-; CHECK-NEXT:    ret i32 0
-; CHECK:       fail1:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
-; CHECK-NEXT:    ret i32 0
-;
-bb0:
-  %0 = add i32 %a, 4
-  %1 = add i32 %b, 1
-  %2 = add i32 %b, 1
-  callbr void asm "xorl $0, $0; jmp ${1:l}", "r,!i,~{dirflag},~{fpsr},~{flags}"(i32 %0) to label %normal [label %fail1]
-normal:
-  %3 = add i32 %b, 1
-  %4 = add i32 %b, 1
-  ret i32 0
-fail1:
-  %5 = add i32 %b, 1
-  %6 = add i32 %b, 1
-  ret i32 0
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-catchpad.ll b/llvm/test/Transforms/IROutliner/illegal-catchpad.ll
deleted file mode 100644
index a25007fd8034d..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-catchpad.ll
+++ /dev/null
@@ -1,70 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -no-ir-sim-branch-matching -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that catchpad instructions are not outlined even if they
-; in a similar section.  Dealing with exception handling inside of an outlined
-; function would require a lot of handling that is not implemented yet.
-
-declare void @llvm.donothing() nounwind readnone
-
-define void @function1() personality i8 3 {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catchpad1] unwind to caller
-; CHECK:       catchpad1:
-; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS1]] []
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %cs1 = catchswitch within none [label %catchpad1] unwind to caller
-catchpad1:
-  catchpad within %cs1 []
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %normal
-normal:
-  ret void
-}
-
-define void @function2() personality i8 3 {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CS1:%.*]] = catchswitch within none [label %catchpad1] unwind to caller
-; CHECK:       catchpad1:
-; CHECK-NEXT:    [[TMP0:%.*]] = catchpad within [[CS1]] []
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %cs1 = catchswitch within none [label %catchpad1] unwind to caller
-catchpad1:
-  catchpad within %cs1 []
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %normal
-normal:
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-cleanup.ll b/llvm/test/Transforms/IROutliner/illegal-cleanup.ll
deleted file mode 100644
index b9eeba911f578..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-cleanup.ll
+++ /dev/null
@@ -1,62 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -no-ir-sim-branch-matching -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that cleanuppad instructions are not outlined even if they
-; in a similar section.  Dealing with exception handling inside of an outlined
-; function would require a lot of handling that is not implemented yet.
-
-declare void @llvm.donothing() nounwind readnone
-
-define void @function1() personality i8 3 {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CLEAN:%.*]] = cleanuppad within none []
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %clean = cleanuppad within none []
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %normal
-normal:
-  ret void
-}
-
-define void @function2() personality i8 3 {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CLEAN:%.*]] = cleanuppad within none []
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %clean = cleanuppad within none []
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %normal
-normal:
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-frozen.ll b/llvm/test/Transforms/IROutliner/illegal-frozen.ll
deleted file mode 100644
index 293f433317bd3..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-frozen.ll
+++ /dev/null
@@ -1,49 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract freeze instructions, since extra handling is
-; required to mark any outputs used with freeze.
-
-define void @function1(ptr %a, ptr %b) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[C:%.*]] = freeze ptr [[A:%.*]]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[C]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    br label [[FIRST]]
-;
-entry:
-  br label %first
-first:
-  %c = freeze ptr %a
-  store i32 2, ptr %c, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-next:
-  br label %first
-}
-
-define void @function2(ptr %a, ptr %b) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[C:%.*]] = freeze ptr [[A:%.*]]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[C]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    br label [[FIRST]]
-;
-entry:
-  br label %first
-first:
-  %c = freeze ptr %a
-  store i32 2, ptr %c, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-next:
-  br label %first
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll b/llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll
deleted file mode 100644
index 76338569707a6..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll
+++ /dev/null
@@ -1,58 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost --no-ir-sim-indirect-calls < %s | FileCheck %s
-
-; This test checks that we do not outline indirect calls when it is specified
-; that we should not.
-
-declare void @f1(ptr, ptr);
-declare void @f2(ptr, ptr);
-
-define void @function1(ptr %func) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    call void [[FUNC:%.*]]()
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void %func()
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2(ptr %func) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    call void [[FUNC:%.*]]()
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void %func()
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-invoke.ll b/llvm/test/Transforms/IROutliner/illegal-invoke.ll
deleted file mode 100644
index 82d62b928a3f8..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-invoke.ll
+++ /dev/null
@@ -1,64 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that invoke instructions are not outlined even if they
-; in a similar section.  Outlining does not currently handle control flow
-; changes.
-
-declare void @llvm.donothing() nounwind readnone
-
-define void @function1() personality i8 3 {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
-; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %cleanup = landingpad i8 cleanup
-  br label %normal
-normal:
-  ret void
-}
-
-define void @function2() personality i8 3 {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
-; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %cleanup = landingpad i8 cleanup
-  br label %normal
-normal:
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-landingpad.ll b/llvm/test/Transforms/IROutliner/illegal-landingpad.ll
deleted file mode 100644
index 5d70d55ab6e4e..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-landingpad.ll
+++ /dev/null
@@ -1,64 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -no-ir-sim-branch-matching -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that landingpad instructions are not outlined even if they
-; in a similar section.  Dealing with exception handling inside of an outlined
-; function would require a lot of handling that is not implemented yet.
-
-declare void @llvm.donothing() nounwind readnone
-
-define void @function1() personality i8 3 {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
-; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %cleanup = landingpad i8 cleanup
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %normal
-normal:
-  ret void
-}
-
-define void @function2() personality i8 3 {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    invoke void @llvm.donothing()
-; CHECK-NEXT:    to label [[NORMAL:%.*]] unwind label [[EXCEPTION:%.*]]
-; CHECK:       exception:
-; CHECK-NEXT:    [[CLEANUP:%.*]] = landingpad i8
-; CHECK-NEXT:    cleanup
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    br label [[NORMAL]]
-; CHECK:       normal:
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  invoke void @llvm.donothing() to label %normal unwind label %exception
-exception:
-  %cleanup = landingpad i8 cleanup
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %normal
-normal:
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-memcpy.ll b/llvm/test/Transforms/IROutliner/illegal-memcpy.ll
deleted file mode 100644
index 523fd23230461..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-memcpy.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost -no-ir-sim-intrinsics < %s | FileCheck %s
-
-; This test checks that we do not outline memcpy intrinsics since it may require
-; extra address space checks.
-
-declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-
-define i8 @function1(ptr noalias %s, ptr noalias %d, i64 %len) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[A_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[S:%.*]], ptr [[D:%.*]], ptr [[A_LOC]], ptr [[B_LOC]])
-; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i8, ptr [[A_LOC]], align 1
-; CHECK-NEXT:    [[B_RELOAD:%.*]] = load i8, ptr [[B_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[D]], ptr [[S]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], ptr [[S]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-define i8 @function2(ptr noalias %s, ptr noalias %d, i64 %len) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[A_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[S:%.*]], ptr [[D:%.*]], ptr [[A_LOC]], ptr [[B_LOC]])
-; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i8, ptr [[A_LOC]], align 1
-; CHECK-NEXT:    [[B_RELOAD:%.*]] = load i8, ptr [[B_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[D]], ptr [[S]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], ptr [[S]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-memmove.ll b/llvm/test/Transforms/IROutliner/illegal-memmove.ll
deleted file mode 100644
index 7482405b9d04d..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-memmove.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost -no-ir-sim-intrinsics < %s | FileCheck %s
-
-; This test checks that we do not outline memcpy intrinsics since it may require
-; extra address space checks.
-
-declare void @llvm.memmove.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-
-define i8 @function1(ptr noalias %s, ptr noalias %d, i64 %len) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[A_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[S:%.*]], ptr [[D:%.*]], ptr [[A_LOC]], ptr [[B_LOC]])
-; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i8, ptr [[A_LOC]], align 1
-; CHECK-NEXT:    [[B_RELOAD:%.*]] = load i8, ptr [[B_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[D]], ptr [[S]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], ptr [[S]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-define i8 @function2(ptr noalias %s, ptr noalias %d, i64 %len) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[A_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[S:%.*]], ptr [[D:%.*]], ptr [[A_LOC]], ptr [[B_LOC]])
-; CHECK-NEXT:    [[A_RELOAD:%.*]] = load i8, ptr [[A_LOC]], align 1
-; CHECK-NEXT:    [[B_RELOAD:%.*]] = load i8, ptr [[B_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_LOC]])
-; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[D]], ptr [[S]], i64 [[LEN:%.*]], i1 false)
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i8 [[A_RELOAD]], i8 [[B_RELOAD]], ptr [[S]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-memset.ll b/llvm/test/Transforms/IROutliner/illegal-memset.ll
deleted file mode 100644
index 34658ec85fa5e..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-memset.ll
+++ /dev/null
@@ -1,41 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost -no-ir-sim-intrinsics < %s | FileCheck %s
-
-; This test checks that we do not outline memset intrinsics since it requires
-; extra address space checks.
-
-declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-
-define i64 @function1(i64 %x, i64 %z, i64 %n) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[POOL:%.*]] = alloca [59 x i64], align 4
-; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr nonnull align 4 [[POOL]], i8 0, i64 236, i1 false)
-; CHECK-NEXT:    call void @outlined_ir_func_0(i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
-; CHECK-NEXT:    ret i64 0
-;
-entry:
-  %pool = alloca [59 x i64], align 4
-  call void @llvm.memset.p0.i64(ptr nonnull %pool, i8 0, i64 236, i32 4, i1 false)
-  %cmp3 = icmp eq i64 %n, 0
-  %a = add i64 %x, %z
-  %c = add i64 %x, %z
-  ret i64 0
-}
-
-define i64 @function2(i64 %x, i64 %z, i64 %n) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[POOL:%.*]] = alloca [59 x i64], align 4
-; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr nonnull align 4 [[POOL]], i8 0, i64 236, i1 false)
-; CHECK-NEXT:    call void @outlined_ir_func_0(i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
-; CHECK-NEXT:    ret i64 0
-;
-entry:
-  %pool = alloca [59 x i64], align 4
-  call void @llvm.memset.p0.i64(ptr nonnull %pool, i8 0, i64 236, i32 4, i1 false)
-  %cmp3 = icmp eq i64 %n, 0
-  %a = add i64 %x, %z
-  %c = add i64 %x, %z
-  ret i64 0
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-nomerge.ll b/llvm/test/Transforms/IROutliner/illegal-nomerge.ll
deleted file mode 100644
index d0b367184dc96..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-nomerge.ll
+++ /dev/null
@@ -1,104 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 6
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Verify that the IR outliner refuses to outline regions that contain
-; callsites marked with `nomerge`.
-
-declare void @f1(ptr, ptr);
-declare void @f2(ptr, ptr);
-
-define void @function1() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1(ptr %a, ptr %b) nomerge
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1(ptr %a, ptr %b) nomerge
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function3() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f2(ptr %a, ptr %b) nomerge
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-; CHECK-LABEL: define void @function1() {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    call void @f1(ptr [[A]], ptr [[B]]) #[[ATTR1:[0-9]+]]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define void @function2() {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    call void @f1(ptr [[A]], ptr [[B]]) #[[ATTR1]]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define void @function3() {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    call void @f2(ptr [[A]], ptr [[B]]) #[[ATTR1]]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-SAME: ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:  [[NEWFUNCROOT:.*:]]
-; CHECK-NEXT:    br label %[[ENTRY_TO_OUTLINE:.*]]
-; CHECK:       [[ENTRY_TO_OUTLINE]]:
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label %[[ENTRY_AFTER_OUTLINE_EXITSTUB:.*]]
-; CHECK:       [[ENTRY_AFTER_OUTLINE_EXITSTUB]]:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll b/llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll
deleted file mode 100644
index 46d069d5afcc0..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll
+++ /dev/null
@@ -1,49 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract phi nodes as it would require extra label and
-; control flow checking.
-
-define void @function1(ptr %a, ptr %b) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 3, [[NEXT:%.*]] ]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A:%.*]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    br label [[FIRST]]
-;
-entry:
-  br label %first
-first:
-  %0 = phi i32 [ 0, %entry ], [ 3, %next ]
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-next:
-  br label %first
-}
-
-define void @function2(ptr %a, ptr %b) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ 3, [[NEXT:%.*]] ]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A:%.*]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    br label [[FIRST]]
-;
-entry:
-  br label %first
-first:
-  %0 = phi i32 [ 0, %entry ], [ 3, %next ]
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-next:
-  br label %first
-}
diff --git a/llvm/test/Transforms/IROutliner/illegal-returns-twice.ll b/llvm/test/Transforms/IROutliner/illegal-returns-twice.ll
deleted file mode 100644
index a520cb1b54cef..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-returns-twice.ll
+++ /dev/null
@@ -1,66 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do not outline functions that are marked as returns
-; twice, since these can alter the frame of the function and affect how the
-; outliner behaves, causing miscompiles.
-
-; Function Attrs: optsize returns_twice
-declare i32 @setjmp(ptr) local_unnamed_addr #1
- at tmp_jmpb = global [37 x i32] zeroinitializer, align 16
-
-define void @function1() {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    [[CALL:%.*]] = call i32 @setjmp(ptr @tmp_jmpb)
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %call = call i32 @setjmp(ptr @tmp_jmpb)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2() {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    [[CALL:%.*]] = call i32 @setjmp(ptr @tmp_jmpb)
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %call = call i32 @setjmp(ptr @tmp_jmpb)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-attributes #1 = { optsize returns_twice }
diff --git a/llvm/test/Transforms/IROutliner/illegal-typeid-for.ll b/llvm/test/Transforms/IROutliner/illegal-typeid-for.ll
deleted file mode 100644
index f15504cd10dae..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-typeid-for.ll
+++ /dev/null
@@ -1,127 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs --version 6
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost -no-ir-sim-intrinsics=0 < %s | FileCheck %s
-
-; Verify that @llvm.eh.typeid.for is not outlined
-
-%C6object9ClassInfo = type { ptr, ptr }
-%C6object9ClassInfo__vtbl = type { ptr }
-
- at C6object9ClassInfo__ClassInfo = linkonce_odr constant %C6object9ClassInfo { ptr @C6object9ClassInfo__vtblZ, ptr @C6object8TypeInfo__ClassInfo }
- at C6object9ClassInfo__vtblZ = linkonce_odr constant %C6object9ClassInfo__vtbl { ptr @C6object9ClassInfo__ClassInfo }
- at C6object8TypeInfo__ClassInfo = linkonce_odr constant %C6object9ClassInfo { ptr @C6object9ClassInfo__vtblZ, ptr @C6object6Object__ClassInfo }
- at C6object6Object__ClassInfo = linkonce_odr constant %C6object9ClassInfo { ptr @C6object9ClassInfo__vtblZ, ptr @C6object6Object__ClassInfo }
- at C6object9Throwable__ClassInfo = linkonce_odr constant %C6object9ClassInfo { ptr @C6object9ClassInfo__vtblZ, ptr @C6object6Object__ClassInfo }
-
-declare i32 @__sd_eh_personality(i32, i32, i64, ptr, ptr)
-
-declare void @test2(ptr)
-declare void @test3(ptr)
-declare void @test4(ptr)
-
-define i32 @test1(ptr %arg0) personality ptr @__sd_eh_personality {
-body:
-  invoke void @test2(ptr %arg0) to label %then1 unwind label %lpad1
-
-then1:
-  invoke void @test3(ptr %arg0) to label %then2 unwind label %lpad2
-
-then2:
-  invoke void @test4(ptr %arg0) to label %then3 unwind label %lpad3
-
-then3:
-  ret i32 0
-
-unwind:
-  %0 = phi { ptr, i32 } [ %1, %lpad1 ], [ %5, %lpad2 ], [ %9, %lpad3 ]
-  resume { ptr, i32 } %0
-
-lpad1:
-  %1 = landingpad { ptr, i32 } cleanup catch ptr @C6object9Throwable__ClassInfo
-  %2 = extractvalue { ptr, i32 } %1, 1
-  %3 = call i32 @llvm.eh.typeid.for(ptr nonnull @C6object9Throwable__ClassInfo)
-  %4 = icmp eq i32 %3, %2
-  br i1 %4, label %catch1, label %unwind
-
-catch1:
-  ret i32 1
-
-lpad2:
-  %5 = landingpad { ptr, i32 } cleanup catch ptr @C6object9Throwable__ClassInfo
-  %6 = extractvalue { ptr, i32 } %5, 1
-  %7 = call i32 @llvm.eh.typeid.for(ptr nonnull @C6object9Throwable__ClassInfo)
-  %8 = icmp eq i32 %7, %6
-  br i1 %8, label %catch2, label %unwind
-
-catch2:
-  ret i32 2
-
-lpad3:
-  %9 = landingpad { ptr, i32 } cleanup catch ptr @C6object9Throwable__ClassInfo
-  %10 = extractvalue { ptr, i32 } %9, 1
-  %11 = call i32 @llvm.eh.typeid.for(ptr nonnull @C6object9Throwable__ClassInfo)
-  %12 = icmp eq i32 %11, %10
-  br i1 %12, label %catch2, label %unwind
-
-catch3:
-  ret i32 3
-}
-; CHECK-LABEL: define i32 @test1(
-; CHECK-SAME: ptr [[ARG0:%.*]]) personality ptr @__sd_eh_personality {
-; CHECK-NEXT:  [[BODY:.*:]]
-; CHECK-NEXT:    invoke void @test2(ptr [[ARG0]])
-; CHECK-NEXT:            to label %[[THEN1:.*]] unwind label %[[LPAD1:.*]]
-; CHECK:       [[THEN1]]:
-; CHECK-NEXT:    invoke void @test3(ptr [[ARG0]])
-; CHECK-NEXT:            to label %[[THEN2:.*]] unwind label %[[LPAD2:.*]]
-; CHECK:       [[THEN2]]:
-; CHECK-NEXT:    invoke void @test4(ptr [[ARG0]])
-; CHECK-NEXT:            to label %[[THEN3:.*]] unwind label %[[UNWIND2:.*]]
-; CHECK:       [[THEN3]]:
-; CHECK-NEXT:    ret i32 0
-; CHECK:       [[UNWIND1:.*]]:
-; CHECK-NEXT:    [[TMP6:%.*]] = phi { ptr, i32 } [ [[TMP0:%.*]], %[[LPAD1]] ], [ [[TMP3:%.*]], %[[LPAD2]] ], [ [[TMP7:%.*]], %[[UNWIND2]] ]
-; CHECK-NEXT:    resume { ptr, i32 } [[TMP6]]
-; CHECK:       [[LPAD1]]:
-; CHECK-NEXT:    [[TMP0]] = landingpad { ptr, i32 }
-; CHECK-NEXT:            cleanup
-; CHECK-NEXT:            catch ptr @C6object9Throwable__ClassInfo
-; CHECK-NEXT:    [[TMP1:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr nonnull @C6object9Throwable__ClassInfo)
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(i32 [[TMP2]], i32 [[TMP1]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label %[[CATCH1:.*]], label %[[UNWIND1]]
-; CHECK:       [[CATCH1]]:
-; CHECK-NEXT:    ret i32 1
-; CHECK:       [[LPAD2]]:
-; CHECK-NEXT:    [[TMP3]] = landingpad { ptr, i32 }
-; CHECK-NEXT:            cleanup
-; CHECK-NEXT:            catch ptr @C6object9Throwable__ClassInfo
-; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP3]], 1
-; CHECK-NEXT:    [[TMP5:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr nonnull @C6object9Throwable__ClassInfo)
-; CHECK-NEXT:    [[TARGETBLOCK1:%.*]] = call i1 @outlined_ir_func_0(i32 [[TMP5]], i32 [[TMP4]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK1]], label %[[CATCH2:.*]], label %[[UNWIND1]]
-; CHECK:       [[CATCH2]]:
-; CHECK-NEXT:    ret i32 2
-; CHECK:       [[UNWIND2]]:
-; CHECK-NEXT:    [[TMP7]] = landingpad { ptr, i32 }
-; CHECK-NEXT:            cleanup
-; CHECK-NEXT:            catch ptr @C6object9Throwable__ClassInfo
-; CHECK-NEXT:    [[TMP8:%.*]] = extractvalue { ptr, i32 } [[TMP7]], 1
-; CHECK-NEXT:    [[TMP9:%.*]] = call i32 @llvm.eh.typeid.for.p0(ptr nonnull @C6object9Throwable__ClassInfo)
-; CHECK-NEXT:    [[TARGETBLOCK2:%.*]] = call i1 @outlined_ir_func_0(i32 [[TMP9]], i32 [[TMP8]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK2]], label %[[CATCH2]], label %[[UNWIND1]]
-; CHECK:       [[CATCH3:.*:]]
-; CHECK-NEXT:    ret i32 3
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-SAME: i32 [[TMP0:%.*]], i32 [[TMP1:%.*]]) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT:  [[NEWFUNCROOT:.*:]]
-; CHECK-NEXT:    br label %[[LPAD1_TO_OUTLINE:.*]]
-; CHECK:       [[LPAD1_TO_OUTLINE]]:
-; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br i1 [[TMP2]], label %[[CATCH1_EXITSTUB:.*]], label %[[UNWIND1_EXITSTUB:.*]]
-; CHECK:       [[CATCH1_EXITSTUB]]:
-; CHECK-NEXT:    ret i1 true
-; CHECK:       [[UNWIND1_EXITSTUB]]:
-; CHECK-NEXT:    ret i1 false
-;
diff --git a/llvm/test/Transforms/IROutliner/illegal-vaarg.ll b/llvm/test/Transforms/IROutliner/illegal-vaarg.ll
deleted file mode 100644
index 15f9aa2f5932a..0000000000000
--- a/llvm/test/Transforms/IROutliner/illegal-vaarg.ll
+++ /dev/null
@@ -1,79 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost -no-ir-sim-intrinsics < %s | FileCheck %s
-
-; This test ensures that we do not outline vararg instructions or intrinsics, as
-; they may cause inconsistencies when outlining.
-
-declare void @llvm.va_start(ptr)
-declare void @llvm.va_copy(ptr, ptr)
-declare void @llvm.va_end(ptr)
-
-define i32 @func1(i32 %a, double %b, ptr %v, ...) nounwind {
-; CHECK-LABEL: @func1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B_ADDR:%.*]] = alloca double, align 8
-; CHECK-NEXT:    [[AP:%.*]] = alloca ptr, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[A:%.*]], ptr [[A_ADDR]], double [[B:%.*]], ptr [[B_ADDR]])
-; CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[AP]])
-; CHECK-NEXT:    [[TMP0:%.*]] = va_arg ptr [[AP]], i32
-; CHECK-NEXT:    call void @llvm.va_copy.p0(ptr [[V:%.*]], ptr [[AP]])
-; CHECK-NEXT:    call void @llvm.va_end.p0(ptr [[AP]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[TMP0]], ptr [[C]], ptr [[TMP_LOC]])
-; CHECK-NEXT:    [[TMP_RELOAD:%.*]] = load i32, ptr [[TMP_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    ret i32 [[TMP_RELOAD]]
-;
-entry:
-  %a.addr = alloca i32, align 4
-  %b.addr = alloca double, align 8
-  %ap = alloca ptr, align 4
-  %c = alloca i32, align 4
-  store i32 %a, ptr %a.addr, align 4
-  store double %b, ptr %b.addr, align 8
-  call void @llvm.va_start(ptr %ap)
-  %0 = va_arg ptr %ap, i32
-  call void @llvm.va_copy(ptr %v, ptr %ap)
-  call void @llvm.va_end(ptr %ap)
-  store i32 %0, ptr %c, align 4
-  %tmp = load i32, ptr %c, align 4
-  ret i32 %tmp
-}
-
-define i32 @func2(i32 %a, double %b, ptr %v, ...) nounwind {
-; CHECK-LABEL: @func2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B_ADDR:%.*]] = alloca double, align 8
-; CHECK-NEXT:    [[AP:%.*]] = alloca ptr, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[A:%.*]], ptr [[A_ADDR]], double [[B:%.*]], ptr [[B_ADDR]])
-; CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[AP]])
-; CHECK-NEXT:    [[TMP0:%.*]] = va_arg ptr [[AP]], i32
-; CHECK-NEXT:    call void @llvm.va_copy.p0(ptr [[V:%.*]], ptr [[AP]])
-; CHECK-NEXT:    call void @llvm.va_end.p0(ptr [[AP]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[TMP0]], ptr [[C]], ptr [[TMP_LOC]])
-; CHECK-NEXT:    [[TMP_RELOAD:%.*]] = load i32, ptr [[TMP_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    ret i32 [[TMP_RELOAD]]
-;
-entry:
-  %a.addr = alloca i32, align 4
-  %b.addr = alloca double, align 8
-  %ap = alloca ptr, align 4
-  %c = alloca i32, align 4
-  store i32 %a, ptr %a.addr, align 4
-  store double %b, ptr %b.addr, align 8
-  call void @llvm.va_start(ptr %ap)
-  %0 = va_arg ptr %ap, i32
-  call void @llvm.va_copy(ptr %v, ptr %ap)
-  call void @llvm.va_end(ptr %ap)
-  store i32 %0, ptr %c, align 4
-  %tmp = load i32, ptr %c, align 4
-  ret i32 %tmp
-}
diff --git a/llvm/test/Transforms/IROutliner/included-phi-nodes-begin.ll b/llvm/test/Transforms/IROutliner/included-phi-nodes-begin.ll
deleted file mode 100644
index c788b61d18989..0000000000000
--- a/llvm/test/Transforms/IROutliner/included-phi-nodes-begin.ll
+++ /dev/null
@@ -1,93 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we are able to outline when all of the phi nodes in the starting
-; block are included in the region and there is no more than one predecessor
-; into those phi nodes from outside of the region.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %y = add i32 %c, %c
-  br label %test1
-dummy:
-  ret void
-test1:
-  %1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %2 = phi i32 [ %e, %test1 ], [ %y, %entry  ]
-  %e = load i32, ptr %0, align 4
-  %3 = add i32 %c, %c
-  br i1 true, label %test, label %test1
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %y = mul i32 %c, %c
-  br label %test1
-dummy:
-  ret void
-test1:
-  %1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %2 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %e = load i32, ptr %0, align 4
-  %3 = add i32 %c, %c
-  br i1 true, label %test, label %test1
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Y:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       dummy:
-; CHECK-NEXT:    ret void
-; CHECK:       test1:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[Y]], ptr [[TMP0]], i32 [[C]])
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Y:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       dummy:
-; CHECK-NEXT:    ret void
-; CHECK:       test1:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[Y]], ptr [[TMP0]], i32 [[C]])
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[TEST1_TO_OUTLINE:%.*]]
-; CHECK:       test1_to_outline:
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ [[E:%.*]], [[TEST1_TO_OUTLINE]] ], [ [[TMP0:%.*]], [[NEWFUNCROOT:%.*]] ]
-; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[E]], [[TEST1_TO_OUTLINE]] ], [ [[TMP0]], [[NEWFUNCROOT]] ]
-; CHECK-NEXT:    [[E]] = load i32, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[TMP2:%.*]], [[TMP2]]
-; CHECK-NEXT:    br i1 true, label [[TEST:%.*]], label [[TEST1_TO_OUTLINE]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/included-phi-nodes-end.ll b/llvm/test/Transforms/IROutliner/included-phi-nodes-end.ll
deleted file mode 100644
index d36c3dad41b3a..0000000000000
--- a/llvm/test/Transforms/IROutliner/included-phi-nodes-end.ll
+++ /dev/null
@@ -1,94 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we are able to propagate inputs to the region into the split PHINode
-; outside of the region if necessary.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %z = add i32 %c, %c
-  br i1 true, label %test1, label %first
-test1:
-  %e = load i32, ptr %0, align 4
-  %1 = add i32 %c, %c
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %2 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  %3 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  ret void
-next:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %z = mul i32 %c, %c
-  br i1 true, label %test1, label %first
-test1:
-  %e = load i32, ptr %0, align 4
-  %1 = add i32 %c, %c
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %2 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  %3 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  ret void
-next:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Z:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[NEXT:%.*]], label [[ENTRY_AFTER_OUTLINE:%.*]]
-; CHECK:       entry_after_outline:
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Z:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[NEXT:%.*]], label [[ENTRY_AFTER_OUTLINE:%.*]]
-; CHECK:       entry_after_outline:
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br i1 true, label [[TEST1:%.*]], label [[FIRST:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[TMP1:%.*]], [[TMP1]]
-; CHECK-NEXT:    br i1 true, label [[FIRST]], label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST]], label [[NEXT_EXITSTUB:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[E]], [[TEST1]] ], [ [[TMP1]], [[ENTRY_TO_OUTLINE]] ]
-; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[E]], [[TEST1]] ], [ [[TMP1]], [[ENTRY_TO_OUTLINE]] ]
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       next.exitStub:
-; CHECK-NEXT:    ret i1 true
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret i1 false
-;
diff --git a/llvm/test/Transforms/IROutliner/legal-debug.ll b/llvm/test/Transforms/IROutliner/legal-debug.ll
deleted file mode 100644
index 2e5f25bf756cf..0000000000000
--- a/llvm/test/Transforms/IROutliner/legal-debug.ll
+++ /dev/null
@@ -1,139 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that debug info is recognized as able to be extracted along
-; with the other instructions, but is not included in the consolidated function.
-
-define void @function1() !dbg !6 {
-entry:
-  %a = alloca i32, align 4, !dbg !17
-  call void @llvm.dbg.value(metadata ptr %a, metadata !9, metadata !DIExpression()), !dbg !17
-  %b = alloca i32, align 4, !dbg !18
-  call void @llvm.dbg.value(metadata ptr %b, metadata !11, metadata !DIExpression()), !dbg !18
-  %c = alloca i32, align 4, !dbg !19
-  call void @llvm.dbg.value(metadata ptr %c, metadata !12, metadata !DIExpression()), !dbg !19
-  store i32 2, ptr %a, align 4, !dbg !20
-  store i32 3, ptr %b, align 4, !dbg !21
-  store i32 4, ptr %c, align 4, !dbg !22
-  %al = load i32, ptr %a, align 4, !dbg !23
-  call void @llvm.dbg.value(metadata i32 %al, metadata !13, metadata !DIExpression()), !dbg !23
-  %bl = load i32, ptr %b, align 4, !dbg !24
-  call void @llvm.dbg.value(metadata i32 %bl, metadata !15, metadata !DIExpression()), !dbg !24
-  %cl = load i32, ptr %c, align 4, !dbg !25
-  call void @llvm.dbg.value(metadata i32 %cl, metadata !16, metadata !DIExpression()), !dbg !25
-  ret void, !dbg !26
-}
-
-define void @function2() !dbg !27 {
-entry:
-  %a = alloca i32, align 4, !dbg !35
-  call void @llvm.dbg.value(metadata ptr %a, metadata !29, metadata !DIExpression()), !dbg !35
-  %b = alloca i32, align 4, !dbg !36
-  call void @llvm.dbg.value(metadata ptr %b, metadata !30, metadata !DIExpression()), !dbg !36
-  %c = alloca i32, align 4, !dbg !37
-  call void @llvm.dbg.value(metadata ptr %c, metadata !31, metadata !DIExpression()), !dbg !37
-  store i32 2, ptr %a, align 4, !dbg !38
-  store i32 3, ptr %b, align 4, !dbg !39
-  store i32 4, ptr %c, align 4, !dbg !40
-  %al = load i32, ptr %a, align 4, !dbg !41
-  call void @llvm.dbg.value(metadata i32 %al, metadata !32, metadata !DIExpression()), !dbg !41
-  %bl = load i32, ptr %b, align 4, !dbg !42
-  call void @llvm.dbg.value(metadata i32 %bl, metadata !33, metadata !DIExpression()), !dbg !42
-  %cl = load i32, ptr %c, align 4, !dbg !43
-  call void @llvm.dbg.value(metadata i32 %cl, metadata !34, metadata !DIExpression()), !dbg !43
-  ret void, !dbg !44
-}
-
-
-; Function Attrs: nounwind readnone speculatable willreturn
-declare void @llvm.dbg.value(metadata, metadata, metadata) #0
-
-attributes #0 = { nounwind readnone speculatable willreturn }
-
-!llvm.dbg.cu = !{!0}
-!llvm.debugify = !{!3, !4}
-!llvm.module.flags = !{!5}
-
-!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
-!1 = !DIFile(filename: "legal-debug.ll", directory: "/")
-!2 = !{}
-!3 = !{i32 20}
-!4 = !{i32 12}
-!5 = !{i32 2, !"Debug Info Version", i32 3}
-!6 = distinct !DISubprogram(name: "function1", linkageName: "function1", scope: null, file: !1, line: 1, type: !7, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
-!7 = !DISubroutineType(types: !2)
-!8 = !{!9, !11, !12, !13, !15, !16}
-!9 = !DILocalVariable(name: "1", scope: !6, file: !1, line: 1, type: !10)
-!10 = !DIBasicType(name: "ty64", size: 64, encoding: DW_ATE_unsigned)
-!11 = !DILocalVariable(name: "2", scope: !6, file: !1, line: 2, type: !10)
-!12 = !DILocalVariable(name: "3", scope: !6, file: !1, line: 3, type: !10)
-!13 = !DILocalVariable(name: "4", scope: !6, file: !1, line: 7, type: !14)
-!14 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
-!15 = !DILocalVariable(name: "5", scope: !6, file: !1, line: 8, type: !14)
-!16 = !DILocalVariable(name: "6", scope: !6, file: !1, line: 9, type: !14)
-!17 = !DILocation(line: 1, column: 1, scope: !6)
-!18 = !DILocation(line: 2, column: 1, scope: !6)
-!19 = !DILocation(line: 3, column: 1, scope: !6)
-!20 = !DILocation(line: 4, column: 1, scope: !6)
-!21 = !DILocation(line: 5, column: 1, scope: !6)
-!22 = !DILocation(line: 6, column: 1, scope: !6)
-!23 = !DILocation(line: 7, column: 1, scope: !6)
-!24 = !DILocation(line: 8, column: 1, scope: !6)
-!25 = !DILocation(line: 9, column: 1, scope: !6)
-!26 = !DILocation(line: 10, column: 1, scope: !6)
-!27 = distinct !DISubprogram(name: "function2", linkageName: "function2", scope: null, file: !1, line: 11, type: !7, scopeLine: 11, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !28)
-!28 = !{!29, !30, !31, !32, !33, !34}
-!29 = !DILocalVariable(name: "7", scope: !27, file: !1, line: 11, type: !10)
-!30 = !DILocalVariable(name: "8", scope: !27, file: !1, line: 12, type: !10)
-!31 = !DILocalVariable(name: "9", scope: !27, file: !1, line: 13, type: !10)
-!32 = !DILocalVariable(name: "10", scope: !27, file: !1, line: 17, type: !14)
-!33 = !DILocalVariable(name: "11", scope: !27, file: !1, line: 18, type: !14)
-!34 = !DILocalVariable(name: "12", scope: !27, file: !1, line: 19, type: !14)
-!35 = !DILocation(line: 11, column: 1, scope: !27)
-!36 = !DILocation(line: 12, column: 1, scope: !27)
-!37 = !DILocation(line: 13, column: 1, scope: !27)
-!38 = !DILocation(line: 14, column: 1, scope: !27)
-!39 = !DILocation(line: 15, column: 1, scope: !27)
-!40 = !DILocation(line: 16, column: 1, scope: !27)
-!41 = !DILocation(line: 17, column: 1, scope: !27)
-!42 = !DILocation(line: 18, column: 1, scope: !27)
-!43 = !DILocation(line: 19, column: 1, scope: !27)
-!44 = !DILocation(line: 20, column: 1, scope: !27)
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4, !dbg [[DBG17:![0-9]+]]
-; CHECK-NEXT:      #dbg_value(ptr [[A]], [[META9:![0-9]+]], !DIExpression(), [[DBG17]])
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4, !dbg [[DBG18:![0-9]+]]
-; CHECK-NEXT:      #dbg_value(ptr [[B]], [[META11:![0-9]+]], !DIExpression(), [[DBG18]])
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4, !dbg [[DBG19:![0-9]+]]
-; CHECK-NEXT:      #dbg_value(ptr [[C]], [[META12:![0-9]+]], !DIExpression(), [[DBG19]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]]), !dbg [[DBG20:![0-9]+]]
-; CHECK-NEXT:    ret void, !dbg [[DBG21:![0-9]+]]
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4, !dbg [[DBG30:![0-9]+]]
-; CHECK-NEXT:      #dbg_value(ptr [[A]], [[META24:![0-9]+]], !DIExpression(), [[DBG30]])
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4, !dbg [[DBG31:![0-9]+]]
-; CHECK-NEXT:      #dbg_value(ptr [[B]], [[META25:![0-9]+]], !DIExpression(), [[DBG31]])
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4, !dbg [[DBG32:![0-9]+]]
-; CHECK-NEXT:      #dbg_value(ptr [[C]], [[META26:![0-9]+]], !DIExpression(), [[DBG32]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]]), !dbg [[DBG33:![0-9]+]]
-; CHECK-NEXT:    ret void, !dbg [[DBG34:![0-9]+]]
-;
-;
-; CHECK-LABEL: define {{.+}} @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/legal-indirect-calls.ll b/llvm/test/Transforms/IROutliner/legal-indirect-calls.ll
deleted file mode 100644
index 1733bdb508565..0000000000000
--- a/llvm/test/Transforms/IROutliner/legal-indirect-calls.ll
+++ /dev/null
@@ -1,71 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do outline indirect calls when it is not specified
-; that we should not.
-
-declare void @f1(ptr, ptr);
-declare void @f2(ptr, ptr);
-
-define void @function1(ptr %func) {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void %func()
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2(ptr %func) {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void %func()
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr [[FUNC:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr [[FUNC:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void  @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    call void [[TMP3:%.*]]()
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/mismatched-phi-exits-not-in-first-outlined.ll b/llvm/test/Transforms/IROutliner/mismatched-phi-exits-not-in-first-outlined.ll
deleted file mode 100644
index f9d49993b692d..0000000000000
--- a/llvm/test/Transforms/IROutliner/mismatched-phi-exits-not-in-first-outlined.ll
+++ /dev/null
@@ -1,84 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we are able to extract blocks that contain PHINodes, and selectively
-; store into it's respective block, creating a new block if needed.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr null, i32 -1)
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]], i32 0)
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[PHI_BLOCK:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[PHI_BLOCK]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP2:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[TMP3:%.*]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       phi_block:
-; CHECK-NEXT:    [[TMP3]] = phi i32 [ [[C]], [[TEST:%.*]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/mismatched-phi-exits.ll b/llvm/test/Transforms/IROutliner/mismatched-phi-exits.ll
deleted file mode 100644
index 7191c80534f1b..0000000000000
--- a/llvm/test/Transforms/IROutliner/mismatched-phi-exits.ll
+++ /dev/null
@@ -1,84 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we are able to extract blocks that contain PHINodes, and selectively
-; store into it's respective block, only using if needed.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]], i32 0)
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr null, i32 -1)
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void  @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST_SPLIT:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST_SPLIT]]
-; CHECK:       first.split:
-; CHECK-NEXT:    [[DOTCE:%.*]] = phi i32 [ [[C]], [[TEST:%.*]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP2:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[DOTCE]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/mismatched-phi-outputs-ordering.ll b/llvm/test/Transforms/IROutliner/mismatched-phi-outputs-ordering.ll
deleted file mode 100644
index 9085e7e507726..0000000000000
--- a/llvm/test/Transforms/IROutliner/mismatched-phi-outputs-ordering.ll
+++ /dev/null
@@ -1,145 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract similar regions that would involve the splitting
-; of phi nodes on exit.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-next:
-  %2 = add i32 %d, 1
-  %3 = add i32 %e, 1
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  ret void
-next:
-  %1 = add i32 %d, 1
-  %2 = add i32 %e, 1
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[D_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[D_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], ptr [[E_LOC]], ptr [[D_LOC]], ptr [[DOTCE_LOC]], i32 0)
-; CHECK-NEXT:    [[E_RELOAD:%.*]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    [[D_RELOAD:%.*]] = load i32, ptr [[D_LOC]], align 4
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[D_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[D_RELOAD]], i32 [[E_RELOAD]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[D_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[D_LOC]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], ptr [[E_LOC]], ptr [[D_LOC]], ptr null, i32 1)
-; CHECK-NEXT:    [[E_RELOAD:%.*]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    [[D_RELOAD:%.*]] = load i32, ptr [[D_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[D_LOC]])
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[D_RELOAD]], i32 [[E_RELOAD]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT:%.*]], label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT]], label [[NEXT_EXITSTUB:%.*]]
-; CHECK:       first.split:
-; CHECK-NEXT:    [[DOTCE:%.*]] = phi i32 [ [[C]], [[TEST]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP4:%.*]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_1:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       next.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP4]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 [[D]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_0_1:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP1]], align 4
-; CHECK-NEXT:    store i32 [[DOTCE]], ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP1]], align 4
-; CHECK-NEXT:    store i32 [[D]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_1:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP1]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
-;
-; CHECK-LABEL: @outlined_ir_func_1(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[NEXT_TO_OUTLINE:%.*]]
-; CHECK:       next_to_outline:
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[TMP0:%.*]], 1
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP1:%.*]], 1
-; CHECK-NEXT:    br label [[NEXT_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       next_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-begin.ll b/llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-begin.ll
deleted file mode 100644
index 3229f4255c31d..0000000000000
--- a/llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-begin.ll
+++ /dev/null
@@ -1,106 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not outline when all of the phi nodes in the beginning
-; block are included not in the region.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %y = add i32 %c, %c
-  br label %test1
-dummy:
-  ret void
-test1:
-  %1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %2 = phi i32 [ %e, %test1 ], [ %y, %entry  ]
-  %e = load i32, ptr %0, align 4
-  %3 = add i32 %c, %c
-  br i1 true, label %test, label %test1
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %y = mul i32 %c, %c
-  br label %test1
-dummy:
-  ret void
-test1:
-  %1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %2 = phi i32 [ %y, %entry ], [ %e, %test1 ]
-  %e = load i32, ptr %0, align 4
-  %3 = add i32 %c, %c
-  br i1 true, label %test, label %test1
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Y:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       dummy:
-; CHECK-NEXT:    ret void
-; CHECK:       test1:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[E_RELOAD:%.*]], [[TEST1]] ], [ [[Y]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[E_RELOAD]], [[TEST1]] ], [ [[Y]], [[ENTRY]] ]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]], ptr [[E_LOC]])
-; CHECK-NEXT:    [[E_RELOAD]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[TEST1]], label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Y:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       dummy:
-; CHECK-NEXT:    ret void
-; CHECK:       test1:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[E_RELOAD:%.*]], [[TEST1]] ], [ [[Y]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[Y]], [[ENTRY]] ], [ [[E_RELOAD]], [[TEST1]] ]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]], ptr [[E_LOC]])
-; CHECK-NEXT:    [[E_RELOAD]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[TEST1]], label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[TEST1_TO_OUTLINE:%.*]]
-; CHECK:       test1_to_outline:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP1:%.*]], [[TMP1]]
-; CHECK-NEXT:    br i1 true, label [[TEST:%.*]], label [[TEST1_EXITSTUB:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       test1.exitStub:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    ret i1 true
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    ret i1 false
-;
diff --git a/llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-end.ll b/llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-end.ll
deleted file mode 100644
index 6f64414640d4c..0000000000000
--- a/llvm/test/Transforms/IROutliner/must-capture-all-phi-nodes-end.ll
+++ /dev/null
@@ -1,88 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not  outline when all of the phi nodes in the end
-; block are not included in the region.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %z = add i32 %c, %c
-  br i1 true, label %test1, label %first
-test1:
-  %e = load i32, ptr %0, align 4
-  %1 = add i32 %c, %c
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %2 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  %3 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  ret void
-next:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %z = mul i32 %c, %c
-  br i1 true, label %test1, label %first
-test1:
-  %e = load i32, ptr %0, align 4
-  %1 = add i32 %c, %c
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %2 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  %3 = phi i32 [ %d, %test ], [ %c, %entry ], [ %e, %test1 ]
-  ret void
-next:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Z:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    br i1 true, label [[TEST1:%.*]], label [[FIRST:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    br i1 true, label [[FIRST]], label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[E]], [[TEST1]] ], [ [[C]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[E]], [[TEST1]] ], [ [[C]], [[ENTRY]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Z:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    br i1 true, label [[TEST1:%.*]], label [[FIRST:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    br i1 true, label [[FIRST]], label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[E]], [[TEST1]] ], [ [[C]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[C]], [[ENTRY]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/no-external-block-entries.ll b/llvm/test/Transforms/IROutliner/no-external-block-entries.ll
deleted file mode 100644
index fb2c5e9701f68..0000000000000
--- a/llvm/test/Transforms/IROutliner/no-external-block-entries.ll
+++ /dev/null
@@ -1,75 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; When the an outlined section contains a PHINode no incoming blocks outside
-; the region, we need to make sure that we do not try to reassign
-; the incoming blocks when splitting and reattaching the region.
-
-define void @fn1() local_unnamed_addr #0 {
-entry:
-  br label %block_2
-
-block_1:
-  %a = phi i32 [ 0, %block_2], [ 1, %intermediate_block_1 ]
-  br i1 0, label %block_3, label %block_2
-intermediate_block_1:
-  br label %block_1
-block_2:
-  br i1 0, label %block_3, label %block_1
-
-block_3:
-  %b = phi i32 [ 0, %block_2 ], [ 1, %block_1 ]
-  br label %block_5
-
-block_4:
-  %c = phi i32 [ 0, %block_5 ], [ 1, %intermediate_block_2 ]
-  br i1 0, label %block_6, label %block_5
-intermediate_block_2:
-  br label %block_4
-block_5:
-  br i1 0, label %block_6, label %block_4
-
-block_6:
-  unreachable
-}
-; CHECK-LABEL: @fn1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[B_CE_LOC]], i32 0)
-; CHECK-NEXT:    [[B_CE_RELOAD:%.*]] = load i32, ptr [[B_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_CE_LOC]])
-; CHECK-NEXT:    br label [[BLOCK_3:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[B:%.*]] = phi i32 [ [[B_CE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr null, i32 -1)
-; CHECK-NEXT:    br label [[BLOCK_6:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    unreachable
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[BLOCK_2]] ], [ 1, [[INTERMEDIATE_BLOCK_1:%.*]] ]
-; CHECK-NEXT:    br i1 false, label [[BLOCK_3_SPLIT:%.*]], label [[BLOCK_2]]
-; CHECK:       intermediate_block_1:
-; CHECK-NEXT:    br label [[BLOCK_1:%.*]]
-; CHECK:       block_2:
-; CHECK-NEXT:    br i1 false, label [[BLOCK_3_SPLIT]], label [[BLOCK_1]]
-; CHECK:       block_3.split:
-; CHECK-NEXT:    [[B_CE:%.*]] = phi i32 [ 0, [[BLOCK_2]] ], [ 1, [[BLOCK_1]] ]
-; CHECK-NEXT:    br label [[BLOCK_3_EXITSTUB:%.*]]
-; CHECK:       block_3.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP1:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[B_CE]], ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/no-outlining-optnone.ll b/llvm/test/Transforms/IROutliner/no-outlining-optnone.ll
deleted file mode 100644
index 4d1836b544c1e..0000000000000
--- a/llvm/test/Transforms/IROutliner/no-outlining-optnone.ll
+++ /dev/null
@@ -1,61 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Ensure that a function is not outlined if a function has the optnone
-; attribute.
-
-define void @outline_constants1() optnone noinline {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 3, ptr %a, align 4
-  store i32 4, ptr %b, align 4
-  store i32 5, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_constants2() optnone noinline {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK-LABEL: @outline_constants1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 3, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 5, ptr [[C]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_constants2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/nooutline-attribute.ll b/llvm/test/Transforms/IROutliner/nooutline-attribute.ll
deleted file mode 100644
index a61a1614a3115..0000000000000
--- a/llvm/test/Transforms/IROutliner/nooutline-attribute.ll
+++ /dev/null
@@ -1,30 +0,0 @@
-; RUN: opt -S -debug-only=iroutliner -p=iroutliner -ir-outlining-no-cost %s -o - 2>&1 | FileCheck %s
-; REQUIRES: asserts
-
-; CHECK-NOT: ... Skipping function with nooutline attribute: outlinable
-; CHECK-NOT: @outlined_ir_func
-; CHECK: ... Skipping function with nooutline attribute: nooutline1
-; CHECK: ... Skipping function with nooutline attribute: nooutline2
-
-define void @outlinable() { ret void }
-
-define i8 @nooutline1(ptr noalias %s, ptr noalias %d, i64 %len) nooutline {
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-define i8 @nooutline2(ptr noalias %s, ptr noalias %d, i64 %len) nooutline {
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-
diff --git a/llvm/test/Transforms/IROutliner/one-external-incoming-block-phi-node.ll b/llvm/test/Transforms/IROutliner/one-external-incoming-block-phi-node.ll
deleted file mode 100644
index 96272745df70b..0000000000000
--- a/llvm/test/Transforms/IROutliner/one-external-incoming-block-phi-node.ll
+++ /dev/null
@@ -1,71 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; When the an outlined section contains a PHINode with an incoming block
-; outside of the region, the predecessors to be handled specially to ensure that
-; a global value is properly assigned.  This ensures that there is no crash
-; in that situation.
-
-define void @fn1() local_unnamed_addr #0 {
-entry:
-  br label %block_1
-
-block_1:
-  %a = phi i32 [ 0, %block_2], [ 1, %entry ]
-  br i1 0, label %block_3, label %block_2
-block_2:
-  br i1 0, label %block_3, label %block_1
-
-block_3:
-  %b = phi i32 [ 0, %block_2 ], [ 1, %block_1 ]
-  br label %block_4
-
-block_4:
-  %c = phi i32 [ 0, %block_5 ], [ 1, %block_3 ]
-  br i1 0, label %block_6, label %block_5
-
-block_5:
-  br i1 0, label %block_6, label %block_4
-
-block_6:
-  unreachable
-}
-; CHECK-LABEL: @fn1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[B_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[B_CE_LOC]], i32 0)
-; CHECK-NEXT:    [[B_CE_RELOAD:%.*]] = load i32, ptr [[B_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B_CE_LOC]])
-; CHECK-NEXT:    br label [[BLOCK_3:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[B:%.*]] = phi i32 [ [[B_CE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr null, i32 -1)
-; CHECK-NEXT:    br label [[BLOCK_6:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    unreachable
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br label [[BLOCK_1:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A:%.*]] = phi i32 [ 0, [[BLOCK_2:%.*]] ], [ 1, [[ENTRY_TO_OUTLINE]] ]
-; CHECK-NEXT:    br i1 false, label [[BLOCK_3_SPLIT:%.*]], label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    br i1 false, label [[BLOCK_3_SPLIT]], label [[BLOCK_1]]
-; CHECK:       block_3.split:
-; CHECK-NEXT:    [[B_CE:%.*]] = phi i32 [ 0, [[BLOCK_2]] ], [ 1, [[BLOCK_1]] ]
-; CHECK-NEXT:    br label [[BLOCK_3_EXITSTUB:%.*]]
-; CHECK:       block_3.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP1:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[B_CE]], ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/opt-remarks.ll b/llvm/test/Transforms/IROutliner/opt-remarks.ll
deleted file mode 100644
index e0dc72bf8df59..0000000000000
--- a/llvm/test/Transforms/IROutliner/opt-remarks.ll
+++ /dev/null
@@ -1,405 +0,0 @@
-; RUN: opt -S -passes=verify,iroutliner -o /dev/null \
-; RUN: -pass-remarks=iroutliner -pass-remarks-missed=iroutliner < %s  \
-; RUN: 2>&1 | FileCheck -check-prefix=CHECK %s
-; RUN: opt -S -passes=verify,iroutliner -o /dev/null  \
-; RUN:  -pass-remarks-output=%t < %s
-; RUN: cat %t | FileCheck -check-prefix=YAML %s
-
-; CHECK: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 4 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 0 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 1 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 2 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 3 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 4 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 14 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 5 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 6 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 7 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 17 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: did not outline 2 regions due to estimated increase of 8 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-; CHECK-NEXT: remark: <unknown>:0:0: outlined 2 regions with decrease of 2 instructions at locations <UNKNOWN LOCATION> <UNKNOWN LOCATION>
-
-; YAML: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '10'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '4'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '0'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '10'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '1'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '11'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '12'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '2'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '3'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '13'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '4'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '14'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '5'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '10'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '11'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '6'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '7'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '17'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function1
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '13'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Missed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            WouldNotDecreaseSize
-; YAML-NEXT: Function:        function3
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'did not outline '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions due to estimated increase of '
-; YAML-NEXT:   - InstructionIncrease: '8'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-; YAML-NEXT: --- !Passed
-; YAML-NEXT: Pass:            iroutliner
-; YAML-NEXT: Name:            Outlined
-; YAML-NEXT: Function:        function3.outlined
-; YAML-NEXT: Args:
-; YAML-NEXT:   - String:          'outlined '
-; YAML-NEXT:   - String:          '2'
-; YAML-NEXT:   - String:          ' regions with decrease of '
-; YAML-NEXT:   - Benefit:         '2'
-; YAML-NEXT:   - String:          ' instructions at locations '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT:   - String:          ' '
-; YAML-NEXT:   - DebugLoc:        '<UNKNOWN LOCATION>'
-; YAML-NEXT: ...
-
-define void @function1() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-define void @function2() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-define void @function3() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  %mul = mul i32 %0, %1
-  %sub = sub i32 %0, %1
-  %div = sdiv i32 %0, %1
-  %add1 = add i32 %0, %1
-  %mul1 = mul i32 %0, %1
-  %sub1 = sub i32 %0, %1
-  %div1 = sdiv i32 %0, %1
-  %add2 = add i32 %0, %1
-  %mul2 = mul i32 %0, %1
-  %sub2 = sub i32 %0, %1
-  %div2 = sdiv i32 %0, %1
-  %mul3 = mul i32 %0, %1
-  ret void
-}
-
-define void @function4() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  %mul = mul i32 %0, %1
-  %sub = sub i32 %0, %1
-  %div = sdiv i32 %0, %1
-  %add1 = add i32 %0, %1
-  %mul1 = mul i32 %0, %1
-  %sub1 = sub i32 %0, %1
-  %div1 = sdiv i32 %0, %1
-  %add2 = add i32 %0, %1
-  %mul2 = mul i32 %0, %1
-  %sub2 = sub i32 %0, %1
-  %div2 = sdiv i32 %0, %1
-  %div3 = sdiv i32 %0, %1
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/outline-memcpy.ll b/llvm/test/Transforms/IROutliner/outline-memcpy.ll
deleted file mode 100644
index 83fd5f6af925c..0000000000000
--- a/llvm/test/Transforms/IROutliner/outline-memcpy.ll
+++ /dev/null
@@ -1,60 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we successfully outline identical memcpy instructions.
-
-declare void @llvm.memcpy.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-
-define i8 @function1(ptr noalias %s, ptr noalias %d, i64 %len) {
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-define i8 @function2(ptr noalias %s, ptr noalias %d, i64 %len) {
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memcpy.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[S:%.*]], ptr [[D:%.*]], i64 [[LEN:%.*]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[S:%.*]], ptr [[D:%.*]], i64 [[LEN:%.*]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[A:%.*]] = load i8, ptr [[TMP0:%.*]], align 1
-; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[TMP1:%.*]], align 1
-; CHECK-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr [[TMP1]], ptr [[TMP0]], i64 [[TMP2:%.*]], i1 false)
-; CHECK-NEXT:    [[C:%.*]] = add i8 [[A]], [[B]]
-; CHECK-NEXT:    [[RET:%.*]] = load i8, ptr [[TMP0]], align 1
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    store i8 [[RET]], ptr [[TMP3:%.*]], align 1
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outline-memmove.ll b/llvm/test/Transforms/IROutliner/outline-memmove.ll
deleted file mode 100644
index c512cd4a22e8f..0000000000000
--- a/llvm/test/Transforms/IROutliner/outline-memmove.ll
+++ /dev/null
@@ -1,60 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we sucecssfully outline identical memmove instructions.
-
-declare void @llvm.memmove.p0.p0.i64(ptr nocapture writeonly, ptr nocapture readonly, i64, i1)
-
-define i8 @function1(ptr noalias %s, ptr noalias %d, i64 %len) {
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-
-define i8 @function2(ptr noalias %s, ptr noalias %d, i64 %len) {
-entry:
-  %a = load i8, ptr %s
-  %b = load i8, ptr %d
-  call void @llvm.memmove.p0.p0.i64(ptr %d, ptr %s, i64 %len, i1 false)
-  %c = add i8 %a, %b
-  %ret = load i8, ptr %s
-  ret i8 %ret
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[S:%.*]], ptr [[D:%.*]], i64 [[LEN:%.*]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[RET_LOC:%.*]] = alloca i8, align 1
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[S:%.*]], ptr [[D:%.*]], i64 [[LEN:%.*]], ptr [[RET_LOC]])
-; CHECK-NEXT:    [[RET_RELOAD:%.*]] = load i8, ptr [[RET_LOC]], align 1
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[RET_LOC]])
-; CHECK-NEXT:    ret i8 [[RET_RELOAD]]
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[A:%.*]] = load i8, ptr [[TMP0:%.*]], align 1
-; CHECK-NEXT:    [[B:%.*]] = load i8, ptr [[TMP1:%.*]], align 1
-; CHECK-NEXT:    call void @llvm.memmove.p0.p0.i64(ptr [[TMP1]], ptr [[TMP0]], i64 [[TMP2:%.*]], i1 false)
-; CHECK-NEXT:    [[C:%.*]] = add i8 [[A]], [[B]]
-; CHECK-NEXT:    [[RET:%.*]] = load i8, ptr [[TMP0]], align 1
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    store i8 [[RET]], ptr [[TMP3:%.*]], align 1
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outline-memset.ll b/llvm/test/Transforms/IROutliner/outline-memset.ll
deleted file mode 100644
index 748256d74e736..0000000000000
--- a/llvm/test/Transforms/IROutliner/outline-memset.ll
+++ /dev/null
@@ -1,52 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we successfully outline identical memset instructions.
-
-declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-
-define i64 @function1(i64 %x, i64 %z, i64 %n) {
-entry:
-  %pool = alloca [59 x i64], align 4
-  call void @llvm.memset.p0.i64(ptr nonnull %pool, i8 0, i64 236, i32 4, i1 false)
-  %cmp3 = icmp eq i64 %n, 0
-  %a = add i64 %x, %z
-  %c = add i64 %x, %z
-  ret i64 0
-}
-
-define i64 @function2(i64 %x, i64 %z, i64 %n) {
-entry:
-  %pool = alloca [59 x i64], align 4
-  call void @llvm.memset.p0.i64(ptr nonnull %pool, i8 0, i64 236, i32 4, i1 false)
-  %cmp3 = icmp eq i64 %n, 0
-  %a = add i64 %x, %z
-  %c = add i64 %x, %z
-  ret i64 0
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[POOL:%.*]] = alloca [59 x i64], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[POOL]], i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
-; CHECK-NEXT:    ret i64 0
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[POOL:%.*]] = alloca [59 x i64], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[POOL]], i64 [[N:%.*]], i64 [[X:%.*]], i64 [[Z:%.*]])
-; CHECK-NEXT:    ret i64 0
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr nonnull align 4 [[TMP0:%.*]], i8 0, i64 236, i1 false)
-; CHECK-NEXT:    [[CMP3:%.*]] = icmp eq i64 [[TMP1:%.*]], 0
-; CHECK-NEXT:    [[A:%.*]] = add i64 [[TMP2:%.*]], [[TMP3:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = add i64 [[TMP2]], [[TMP3]]
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outline-vaarg-intrinsic.ll b/llvm/test/Transforms/IROutliner/outline-vaarg-intrinsic.ll
deleted file mode 100644
index 6a9cbca7dfddb..0000000000000
--- a/llvm/test/Transforms/IROutliner/outline-vaarg-intrinsic.ll
+++ /dev/null
@@ -1,95 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we sucessfully outline identical memcpy var arg
-; intrinsics, but not the var arg instruction itself.
-
-declare void @llvm.va_start(ptr)
-declare void @llvm.va_copy(ptr, ptr)
-declare void @llvm.va_end(ptr)
-
-define i32 @func1(i32 %a, double %b, ptr %v, ...) nounwind {
-entry:
-  %a.addr = alloca i32, align 4
-  %b.addr = alloca double, align 8
-  %ap = alloca ptr, align 4
-  %c = alloca i32, align 4
-  store i32 %a, ptr %a.addr, align 4
-  store double %b, ptr %b.addr, align 8
-  call void @llvm.va_start(ptr %ap)
-  %0 = va_arg ptr %ap, i32
-  call void @llvm.va_copy(ptr %v, ptr %ap)
-  call void @llvm.va_end(ptr %ap)
-  store i32 %0, ptr %c, align 4
-  %tmp = load i32, ptr %c, align 4
-  ret i32 %tmp
-}
-
-define i32 @func2(i32 %a, double %b, ptr %v, ...) nounwind {
-entry:
-  %a.addr = alloca i32, align 4
-  %b.addr = alloca double, align 8
-  %ap = alloca ptr, align 4
-  %c = alloca i32, align 4
-  store i32 %a, ptr %a.addr, align 4
-  store double %b, ptr %b.addr, align 8
-  call void @llvm.va_start(ptr %ap)
-  %0 = va_arg ptr %ap, i32
-  call void @llvm.va_copy(ptr %v, ptr %ap)
-  call void @llvm.va_end(ptr %ap)
-  store i32 %0, ptr %c, align 4
-  %tmp = load i32, ptr %c, align 4
-  ret i32 %tmp
-}
-; CHECK-LABEL: define {{[^@]+}}@func1
-; CHECK-SAME: (i32 [[A:%.*]], double [[B:%.*]], ptr [[V:%.*]], ...) #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B_ADDR:%.*]] = alloca double, align 8
-; CHECK-NEXT:    [[AP:%.*]] = alloca ptr, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 [[A]], ptr [[A_ADDR]], align 4
-; CHECK-NEXT:    store double [[B]], ptr [[B_ADDR]], align 8
-; CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[AP]])
-; CHECK-NEXT:    [[TMP0:%.*]] = va_arg ptr [[AP]], i32
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[V]], ptr [[AP]], i32 [[TMP0]], ptr [[C]], ptr [[TMP_LOC]])
-; CHECK-NEXT:    [[TMP_RELOAD:%.*]] = load i32, ptr [[TMP_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    ret i32 [[TMP_RELOAD]]
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@func2
-; CHECK-SAME: (i32 [[A:%.*]], double [[B:%.*]], ptr [[V:%.*]], ...) #[[ATTR1]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B_ADDR:%.*]] = alloca double, align 8
-; CHECK-NEXT:    [[AP:%.*]] = alloca ptr, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 [[A]], ptr [[A_ADDR]], align 4
-; CHECK-NEXT:    store double [[B]], ptr [[B_ADDR]], align 8
-; CHECK-NEXT:    call void @llvm.va_start.p0(ptr [[AP]])
-; CHECK-NEXT:    [[TMP0:%.*]] = va_arg ptr [[AP]], i32
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[V]], ptr [[AP]], i32 [[TMP0]], ptr [[C]], ptr [[TMP_LOC]])
-; CHECK-NEXT:    [[TMP_RELOAD:%.*]] = load i32, ptr [[TMP_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[TMP_LOC]])
-; CHECK-NEXT:    ret i32 [[TMP_RELOAD]]
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outlined_ir_func_0
-; CHECK-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], i32 [[TMP2:%.*]], ptr [[TMP3:%.*]], ptr [[TMP4:%.*]]) #[[ATTR3:[0-9]+]] {
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    call void @llvm.va_copy.p0(ptr [[TMP0]], ptr [[TMP1]])
-; CHECK-NEXT:    call void @llvm.va_end.p0(ptr [[TMP1]])
-; CHECK-NEXT:    store i32 [[TMP2]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    [[TMP:%.*]] = load i32, ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    store i32 [[TMP]], ptr [[TMP4]], align 4
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-across-branch.ll b/llvm/test/Transforms/IROutliner/outlining-across-branch.ll
deleted file mode 100644
index 4c1675908825c..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-across-branch.ll
+++ /dev/null
@@ -1,77 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This checks that we are able to outline exactly the same branch structure
-; while also outlining similar items on either side of the branch.
-
-define void @outline_outputs1() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %next
-next:
-  store i32 2, ptr %output, align 4
-  store i32 3, ptr %result, align 4
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  br label %next
-next:
-  store i32 2, ptr %output, align 4
-  store i32 3, ptr %result, align 4
-  ret void
-}
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    br label [[NEXT:%.*]]
-; CHECK:       next:
-; CHECK-NEXT:    store i32 2, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-address-taken.ll b/llvm/test/Transforms/IROutliner/outlining-address-taken.ll
deleted file mode 100644
index ce20e6d79b7f3..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-address-taken.ll
+++ /dev/null
@@ -1,91 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test shows that we do not outline from basic blocks with their address
-; taken.
-
- at ba1 = constant ptr blockaddress (@dontoutline, %new_block)
-
-define void @outline_1() {
-; CHECK-LABEL: @outline_1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @[[FUNCTION_1:.*]](ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_2() {
-; CHECK-LABEL: @outline_2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @[[FUNCTION_1]](ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @dontoutline() {
-; CHECK-LABEL: @dontoutline(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[NEW_BLOCK:%.*]]
-; CHECK:       new_block:
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  br label %new_block
-new_block:
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK: define internal void @[[FUNCTION_1]](ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-basic-branches.ll b/llvm/test/Transforms/IROutliner/outlining-basic-branches.ll
deleted file mode 100644
index 765c0b51c02ee..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-basic-branches.ll
+++ /dev/null
@@ -1,50 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This checks that we are able to outline exactly the same structure without
-; any other items to outline.
-
-define void @outline_outputs1() #0 {
-entry:
-  br label %next
-next:
-  br label %next2
-next2:
-  br label %next3
-next3:
-  %a = alloca i32, align 4
-  br label %next4
-next4:
-  br label %next5
-next5:
-  br label %next6
-next6:
-  %b = alloca i32, align 4
-  ret void
-}
-
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    br label [[NEXT3:%.*]]
-; CHECK:       next3:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    br label [[NEXT6:%.*]]
-; CHECK:       next6:
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br label [[NEXT:%.*]]
-; CHECK:       next:
-; CHECK-NEXT:    br label [[NEXT2:%.*]]
-; CHECK:       next2:
-; CHECK-NEXT:    br label [[NEXT3_EXITSTUB:%.*]]
-; CHECK:       next3.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll b/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll
deleted file mode 100644
index a8153a4fda446..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll
+++ /dev/null
@@ -1,127 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test ensures that an extra output is not added when there is a bitcast
-; that is relocated to outside of the extraction due to a starting lifetime
-; instruction outside of the extracted region.
-
-; Additionally, we check that the newly added bitcast instruction is excluded in
-; further extractions.
-
-declare void @llvm.lifetime.start.p0(ptr nocapture)
-declare void @llvm.lifetime.end.p0(ptr nocapture)
-
-define void @outline_bitcast_base() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_bitcast_removed() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %d = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  call void @llvm.lifetime.start.p0(ptr %d)
-  %am = load i32, ptr %b
-  %bm = load i32, ptr %a
-  %cm = load i32, ptr %c
-  call void @llvm.lifetime.end.p0(ptr %d)
-  ret void
-}
-
-; The first bitcast is moved down to lifetime start, and, since the original
-; endpoint does not match the new endpoint, we cannot extract and outline the
-; second bitcast and set of adds.  Outlining only occurs in this case due to
-; the lack of a cost model, as denoted by the debug command line argument.
-
-define void @outline_bitcast_base2(i32 %a, i32 %b, i32 %c) {
-entry:
-  %d = alloca i32, align 4
-  %al = add i32 %a, %b
-  %bl = add i32 %b, %a
-  %cl = add i32 %b, %c
-  %buffer = mul i32 %a, %b
-  %am = add i32 %a, %b
-  %bm = add i32 %b, %a
-  %cm = add i32 %b, %c
-  call void @llvm.lifetime.start.p0(ptr %d)
-  call void @llvm.lifetime.end.p0(ptr %d)
-  ret void
-}
-
-; CHECK-LABEL: @outline_bitcast_base(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_bitcast_removed(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    [[AM:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[BM:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[CM:%.*]] = load i32, ptr [[C]], align 4
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_bitcast_base2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]])
-; CHECK-NEXT:    [[BUFFER:%.*]] = mul i32 [[A]], [[B]]
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[A]], i32 [[B]], i32 [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outlined_ir_func_1(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    [[D:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[D]])
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[AL:%.*]] = add i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    [[BL:%.*]] = add i32 [[TMP1]], [[TMP0]]
-; CHECK-NEXT:    [[CL:%.*]] = add i32 [[TMP1]], [[TMP2:%.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[D]])
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-branches-phi-nodes.ll b/llvm/test/Transforms/IROutliner/outlining-branches-phi-nodes.ll
deleted file mode 100644
index bb6bf8f2e1454..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-branches-phi-nodes.ll
+++ /dev/null
@@ -1,171 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Here we have multiple exits, but the different sources, same outputs are
-; needed, this checks that they are compressed, and moved into the appropriate
-; output blocks.
-
-define void @outline_outputs1() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_6
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_6
-dummy:
-  ret void
-block_6:
-  %diff = phi i32 [%aval, %block_4], [%a2val, %block_5]
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_6
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_6
-dummy:
-  ret void
-block_6:
-  %diff = phi i32 [%aval, %block_4], [%a2val, %block_5]
-  ret void
-}
-
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DIFF_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DIFF_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[DIFF_CE_LOC]])
-; CHECK-NEXT:    [[DIFF_CE_RELOAD:%.*]] = load i32, ptr [[DIFF_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DIFF_CE_LOC]])
-; CHECK-NEXT:    br label [[BLOCK_6:%.*]]
-; CHECK: dummy:
-; CHECK-NEXT:  ret void
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIFF:%.*]] = phi i32 [ [[DIFF_CE_RELOAD]], [[BLOCK_2]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DIFF_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DIFF_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[DIFF_CE_LOC]])
-; CHECK-NEXT:    [[DIFF_CE_RELOAD:%.*]] = load i32, ptr [[DIFF_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DIFF_CE_LOC]])
-; CHECK-NEXT:    br label [[BLOCK_6:%.*]]
-; CHECK: dummy:
-; CHECK-NEXT:  ret void
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIFF:%.*]] = phi i32 [ [[DIFF_CE_RELOAD]], [[BLOCK_2]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK:  define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BLOCK_2_TO_OUTLINE:%.*]]
-; CHECK:       block_2_to_outline:
-; CHECK-NEXT:    [[A2VAL:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[B2VAL:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    [[ADD2:%.*]] = add i32 2, [[A2VAL]]
-; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 2, [[B2VAL]]
-; CHECK-NEXT:    br label [[BLOCK_5:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 2, [[AVAL]]
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 2, [[BVAL]]
-; CHECK-NEXT:    br label [[BLOCK_4:%.*]]
-; CHECK:       block_4:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[BLOCK_6_SPLIT:%.*]]
-; CHECK:       block_5:
-; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    store i32 [[MUL2]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[BLOCK_6_SPLIT]]
-; CHECK:       block_6.split:
-; CHECK-NEXT:    [[DIFF_CE:%.*]] = phi i32 [ [[AVAL]], [[BLOCK_4]] ], [ [[A2VAL]], [[BLOCK_5]] ]
-; CHECK-NEXT:    br label [[BLOCK_6_EXITSTUB:%.*]]
-; CHECK:       block_6.exitStub:
-; CHECK-NEXT:    store i32 [[DIFF_CE]], ptr [[TMP4:%.*]], align 4
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-call-and-indirect.ll b/llvm/test/Transforms/IROutliner/outlining-call-and-indirect.ll
deleted file mode 100644
index 2ba79cc9e6f90..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-call-and-indirect.ll
+++ /dev/null
@@ -1,70 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do can outline indirect and regular function calls
-; when the type matches when it is not specified that the names must match.
-
-declare void @f1();
-
-define void @function1(ptr %func) {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void %func()
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1()
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr [[FUNC:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr @f1)
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    call void [[TMP3:%.*]]()
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-calls-names-must-match.ll b/llvm/test/Transforms/IROutliner/outlining-calls-names-must-match.ll
deleted file mode 100644
index befc4896f7503..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-calls-names-must-match.ll
+++ /dev/null
@@ -1,93 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost -ir-sim-calls-by-name < %s | FileCheck %s
-
-; This test checks that we do can outline calls, but only if they have the same
-; function type and the same name.
-
-declare void @f1(ptr, ptr);
-declare void @f2(ptr, ptr);
-
-define void @function1() {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1(ptr %a, ptr %b)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2() {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1(ptr %a, ptr %b)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function3() {
-; CHECK-LABEL: @function3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    call void @f2(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f2(ptr %a, ptr %b)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    call void @f1(ptr [[ARG0]], ptr [[ARG1]])
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-calls.ll b/llvm/test/Transforms/IROutliner/outlining-calls.ll
deleted file mode 100644
index 8d4092727577a..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-calls.ll
+++ /dev/null
@@ -1,96 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do can outline calls, but only if they have the same
-; function type and the same name.
-
-declare void @f1(ptr, ptr);
-declare void @f2(ptr, ptr);
-
-define void @function1() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1(ptr %a, ptr %b)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function2() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f1(ptr %a, ptr %b)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @function3() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  call void @f2(ptr %a, ptr %b)
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr @f1)
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr @f1)
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]], ptr @f2)
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    call void [[TMP3:%.*]](ptr [[TMP0]], ptr [[TMP1]])
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll b/llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll
deleted file mode 100644
index 6b958b674bcb2..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll
+++ /dev/null
@@ -1,107 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that floating point commutative instructions are not treated
-; as commutative.  Even though an ffadd is technically commutative, the order
-; of operands still needs to be enforced since the process of fadding floating
-; point values requires the order to be the same.
-
-; We make sure that we outline the identical regions from the first two
-; functions, but not the third.  this is because the operands are in a different
-; order in a floating point instruction in this section.
-
-define void @outline_from_fadd1() {
-; CHECK-LABEL: @outline_from_fadd1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca double, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca double, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca double, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca double, align 4
-  %b = alloca double, align 4
-  %c = alloca double, align 4
-  store double 2.0, ptr %a, align 4
-  store double 3.0, ptr %b, align 4
-  store double 4.0, ptr %c, align 4
-  %al = load double, ptr %a
-  %bl = load double, ptr %b
-  %cl = load double, ptr %c
-  %0 = fadd double %al, %bl
-  %1 = fadd double %al, %cl
-  %2 = fadd double %bl, %cl
-  ret void
-}
-
-define void @outline_from_fadd2.0() {
-; CHECK-LABEL: @outline_from_fadd2.0(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca double, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca double, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca double, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca double, align 4
-  %b = alloca double, align 4
-  %c = alloca double, align 4
-  store double 2.0, ptr %a, align 4
-  store double 3.0, ptr %b, align 4
-  store double 4.0, ptr %c, align 4
-  %al = load double, ptr %a
-  %bl = load double, ptr %b
-  %cl = load double, ptr %c
-  %0 = fadd double %al, %bl
-  %1 = fadd double %al, %cl
-  %2 = fadd double %bl, %cl
-  ret void
-}
-
-define void @outline_from_flipped_fadd3.0() {
-; CHECK-LABEL: @outline_from_flipped_fadd3.0(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca double, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca double, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca double, align 4
-; CHECK-NEXT:    store double 2.000000e+00, ptr [[A]], align 4
-; CHECK-NEXT:    store double 3.000000e+00, ptr [[B]], align 4
-; CHECK-NEXT:    store double 4.000000e+00, ptr [[C]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load double, ptr [[A]], align 8
-; CHECK-NEXT:    [[BL:%.*]] = load double, ptr [[B]], align 8
-; CHECK-NEXT:    [[CL:%.*]] = load double, ptr [[C]], align 8
-; CHECK-NEXT:    [[TMP0:%.*]] = fadd double [[BL]], [[AL]]
-; CHECK-NEXT:    [[TMP1:%.*]] = fadd double [[CL]], [[AL]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fadd double [[CL]], [[BL]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca double, align 4
-  %b = alloca double, align 4
-  %c = alloca double, align 4
-  store double 2.0, ptr %a, align 4
-  store double 3.0, ptr %b, align 4
-  store double 4.0, ptr %c, align 4
-  %al = load double, ptr %a
-  %bl = load double, ptr %b
-  %cl = load double, ptr %c
-  %0 = fadd double %bl, %al
-  %1 = fadd double %cl, %al
-  %2 = fadd double %cl, %bl
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store double 2.000000e+00, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store double 3.000000e+00, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store double 4.000000e+00, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load double, ptr [[ARG0]], align 8
-; CHECK-NEXT:    [[BL:%.*]] = load double, ptr [[ARG1]], align 8
-; CHECK-NEXT:    [[CL:%.*]] = load double, ptr [[ARG2]], align 8
-; CHECK-NEXT:    [[TMP0:%.*]] = fadd double [[AL]], [[BL]]
-; CHECK-NEXT:    [[TMP1:%.*]] = fadd double [[AL]], [[CL]]
-; CHECK-NEXT:    [[TMP2:%.*]] = fadd double [[BL]], [[CL]]
-
diff --git a/llvm/test/Transforms/IROutliner/outlining-commutative-operands-opposite-order.ll b/llvm/test/Transforms/IROutliner/outlining-commutative-operands-opposite-order.ll
deleted file mode 100644
index 6eaa0ad8ef0f2..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-commutative-operands-opposite-order.ll
+++ /dev/null
@@ -1,40 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals --include-generated-funcs
-; RUN: opt -S -passes=iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This is a test to ensure that when the first instruction is a commutative
-; instruction, but the order of operands is reversed, we pass the arguments
-; in the correct order, such that we do not use the wrong arguments
-; later on in the computation.
-
-define void @fish(i32 %0, i32 %1, i32 %2) {
-entry:
-  %3 = add nsw i32 %0, %1
-  %4 = sub nsw i32 %1, %2
-  %5 = sub nsw i32 %0, %2
-  ret void
-}
-
-define void @turtle(i32 %0, i32 %1, i32 %2) {
-  %4 = add nsw i32 %1, %0
-  %5 = sub nsw i32 %1, %2
-  %6 = sub nsw i32 %0, %2
-  ret void
-}
-; CHECK-LABEL: @fish(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @turtle(
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: @outlined_ir_func_0(i32 [[TMP0:%.*]], i32 [[TMP1:%.*]], i32 [[TMP2:%.*]])
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[TMP3:%.*]] = add nsw i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    [[TMP4:%.*]] = sub nsw i32 [[TMP1]], [[TMP2]]
-; CHECK-NEXT:    [[TMP5:%.*]] = sub nsw i32 [[TMP0]], [[TMP2]]
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-commutative.ll b/llvm/test/Transforms/IROutliner/outlining-commutative.ll
deleted file mode 100644
index 8862dc295d435..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-commutative.ll
+++ /dev/null
@@ -1,254 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that commutative instructions where the operands are
-; swapped are outlined as the same function.
-
-; It also checks that non-commutative instructions outlined as different
-; functions when the operands are swapped;
-
-; These are identical functions, except that in the flipped functions,
-; the operands in the adds are commuted.  However, since add instructions
-; are commutative, we should still outline from all four as the same
-; instruction.
-
-define void @outline_from_add1() {
-; CHECK-LABEL: @outline_from_add1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = add i32 %al, %bl
-  %1 = add i32 %al, %cl
-  %2 = add i32 %bl, %cl
-  ret void
-}
-
-define void @outline_from_add2() {
-; CHECK-LABEL: @outline_from_add2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = add i32 %al, %bl
-  %1 = add i32 %al, %cl
-  %2 = add i32 %bl, %cl
-  ret void
-}
-
-define void @outline_from_flipped_add3() {
-; CHECK-LABEL: @outline_from_flipped_add3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = add i32 %bl, %al
-  %1 = add i32 %cl, %al
-  %2 = add i32 %cl, %bl
-  ret void
-}
-
-define void @outline_from_flipped_add4() {
-; CHECK-LABEL: @outline_from_flipped_add4(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = add i32 %bl, %al
-  %1 = add i32 %cl, %al
-  %2 = add i32 %cl, %bl
-  ret void
-}
-
-; These are identical functions, except that in the flipped functions,
-; the operands in the subtractions are commuted.  Since subtraction
-; instructions are not commutative, we should outline the first two functions
-; differently than the second two functions.
-
-define void @outline_from_sub1() {
-; CHECK-LABEL: @outline_from_sub1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = sub i32 %al, %bl
-  %1 = sub i32 %al, %cl
-  %2 = sub i32 %bl, %cl
-  ret void
-}
-
-define void @outline_from_sub2() {
-; CHECK-LABEL: @outline_from_sub2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_2(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = sub i32 %al, %bl
-  %1 = sub i32 %al, %cl
-  %2 = sub i32 %bl, %cl
-  ret void
-}
-
-define void @dontoutline_from_flipped_sub3() {
-; CHECK-LABEL: @dontoutline_from_flipped_sub3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = sub i32 %bl, %al
-  %1 = sub i32 %cl, %al
-  %2 = sub i32 %cl, %bl
-  ret void
-}
-
-define void @dontoutline_from_flipped_sub4() {
-; CHECK-LABEL: @dontoutline_from_flipped_sub4(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %0 = sub i32 %bl, %al
-  %1 = sub i32 %cl, %al
-  %2 = sub i32 %cl, %bl
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[AL]], [[BL]]
-; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[AL]], [[CL]]
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[BL]], [[CL]]
-
-; CHECK: define internal void @outlined_ir_func_1(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[BL]], [[AL]]
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[CL]], [[AL]]
-; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[CL]], [[BL]]
-
-; CHECK: define internal void @outlined_ir_func_2(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[AL]], [[BL]]
-; CHECK-NEXT:    [[TMP1:%.*]] = sub i32 [[AL]], [[CL]]
-; CHECK-NEXT:    [[TMP2:%.*]] = sub i32 [[BL]], [[CL]]
diff --git a/llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll b/llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll
deleted file mode 100644
index f13c646c25017..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll
+++ /dev/null
@@ -1,125 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This has two compatible regions based on function attributes.  We have
-; attributes that should be transferred only if it is on all of the regions.
-
-; This includes the attributes,
-; no-signed-zeros-fp-math, less-precise-fpmad, and
-; no-infs-fp-math.  Only when each instance of similarity has these attributes
-; can we say that the outlined function can have these attributes since that
-; is the more general case for these attributes.
-
-define void @outline_attrs1() #0 {
-; CHECK-LABEL: @outline_attrs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_attrs2() #0 {
-; CHECK-LABEL: @outline_attrs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_attrs3() #0 {
-; CHECK-LABEL: @outline_attrs3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca float, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca float, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca float, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca float, align 4
-  %b = alloca float, align 4
-  %c = alloca float, align 4
-  store float 2.0, ptr %a, align 4
-  store float 3.0, ptr %b, align 4
-  store float 4.0, ptr %c, align 4
-  %al = load float, ptr %a
-  %bl = load float, ptr %b
-  %cl = load float, ptr %c
-  %0 = fmul float %al, %bl
-  ret void
-}
-
-define void @outline_attrs4() {
-; CHECK-LABEL: @outline_attrs4(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca float, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca float, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca float, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca float, align 4
-  %b = alloca float, align 4
-  %c = alloca float, align 4
-  store float 2.0, ptr %a, align 4
-  store float 3.0, ptr %b, align 4
-  store float 4.0, ptr %c, align 4
-  %al = load float, ptr %a
-  %bl = load float, ptr %b
-  %cl = load float, ptr %c
-  %0 = fmul float %al, %bl
-  ret void
-}
-
-attributes #0 = { "no-signed-zeros-fp-math"="true" "less-precise-fpmad"="true" }
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) [[ATTR1:#[0-9]+]] {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store float 2.000000e+00, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store float 3.000000e+00, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store float 4.000000e+00, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load float, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load float, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load float, ptr [[ARG2]], align 4
-
-; CHECK: define internal void @outlined_ir_func_1(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) [[ATTR:#[0-9]+]] {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
-
-
-; CHECK: attributes [[ATTR1]] =   { minsize optsize "less-precise-fpmad"="false" "no-signed-zeros-fp-math"="false" }
-; CHECK: attributes [[ATTR]] = { minsize optsize "less-precise-fpmad"="true" "no-signed-zeros-fp-math"="true" }
diff --git a/llvm/test/Transforms/IROutliner/outlining-compatible-and-never-transfer-riscv.ll b/llvm/test/Transforms/IROutliner/outlining-compatible-and-never-transfer-riscv.ll
deleted file mode 100644
index d2751e12f355e..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-compatible-and-never-transfer-riscv.ll
+++ /dev/null
@@ -1,298 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --check-globals --include-generated-funcs
-; RUN: opt -mtriple=riscv32 -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; REQUIRES: riscv-registered-target
-
-; This has two compatible regions based on function attributes.  We have attributes
-; that should never be transferred to the outlined functions:
-; - `interrupt`=*
-
-; On RISC-V, the `interrupt` attribute only applies to the prolog and epilog of
-; the annotated function, and not any functions it calls. If this attribute is
-; preserved, there will be codegen errors because of restrictions on the
-; signatures of `interrupt` attributes.
-
-define void @outline_attrs1() #0 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_attrs2() #1 {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_attrs3() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_outputs1() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_6
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_7
-block_6:
-  ret void
-block_7:
-  ret void
-}
-
-define void @outline_outputs2() #1 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_7
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_6
-block_6:
-  %diff = sub i32 %a2val, %b2val
-  ret void
-block_7:
-  %quot = udiv i32 %add, %mul
-  ret void
-}
-
-attributes #0 = { "interrupt"="machine" optsize }
-attributes #1 = { "interrupt"="qci-nest" optsize }
-; CHECK-LABEL: define {{[^@]+}}@outline_attrs1
-; CHECK-SAME: () #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outline_attrs2
-; CHECK-SAME: () #[[ATTR1:[0-9]+]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outline_attrs3() {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outline_outputs1
-; CHECK-SAME: () #[[ATTR0]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr null, ptr null, ptr null, ptr null, i32 -1)
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_6:%.*]], label [[BLOCK_7:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outline_outputs2
-; CHECK-SAME: () #[[ATTR1]] {
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[MUL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[MUL_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[ADD_LOC]], ptr [[MUL_LOC]], i32 0)
-; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
-; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[MUL_RELOAD:%.*]] = load i32, ptr [[MUL_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[MUL_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_7:%.*]], label [[BLOCK_6:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    [[QUOT:%.*]] = udiv i32 [[ADD_RELOAD]], [[MUL_RELOAD]]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outlined_ir_func_0
-; CHECK-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]], ptr [[TMP3:%.*]], ptr [[TMP4:%.*]], ptr [[TMP5:%.*]], ptr [[TMP6:%.*]], ptr [[TMP7:%.*]], i32 [[TMP8:%.*]]) #[[ATTR3:[0-9]+]] {
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BLOCK_2_TO_OUTLINE:%.*]]
-; CHECK:       block_2_to_outline:
-; CHECK-NEXT:    [[A2VAL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[B2VAL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[ADD2:%.*]] = add i32 2, [[A2VAL]]
-; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 2, [[B2VAL]]
-; CHECK-NEXT:    br label [[BLOCK_5:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 2, [[AVAL]]
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 2, [[BVAL]]
-; CHECK-NEXT:    br label [[BLOCK_4:%.*]]
-; CHECK:       block_4:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[BLOCK_6_EXITSTUB:%.*]]
-; CHECK:       block_5:
-; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    store i32 [[MUL2]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[BLOCK_7_EXITSTUB:%.*]]
-; CHECK:       block_6.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP8]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:      i32 0, label [[OUTPUT_BLOCK_1_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       block_7.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP8]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:      i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[A2VAL]], ptr [[TMP4]], align 4
-; CHECK-NEXT:    store i32 [[B2VAL]], ptr [[TMP5]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_1:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP6]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP7]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
-;
-; CHECK-LABEL: define {{[^@]+}}@outlined_ir_func_1
-; CHECK-SAME: (ptr [[TMP0:%.*]], ptr [[TMP1:%.*]], ptr [[TMP2:%.*]]) #[[ATTR3]] {
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[TMP0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[TMP2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
-;.
-; CHECK: attributes #[[ATTR0]] = { optsize "interrupt"="machine" }
-; CHECK: attributes #[[ATTR1]] = { optsize "interrupt"="qci-nest" }
-; CHECK: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
-; CHECK: attributes #[[ATTR3]] = { minsize optsize }
-;.
diff --git a/llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll b/llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll
deleted file mode 100644
index a8c5ed1d85b08..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll
+++ /dev/null
@@ -1,67 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < "%s" | FileCheck "%s"
-
-; This has two compatible regions.  We have attributes that should be transferred
-; even if it is on only one of the regions.
-
-; This includes the attributes no-jump-tables, profile-sample-accurate,
-; speculative_load_hardening, and noimplicitfloat.  When instance of similarity
-; has these attributes can we say that the outlined function can have these
-; attributes since that is the more general case.
-
-define void @outline_attrs1() #0 {
-; CHECK-LABEL: @outline_attrs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_attrs2() {
-; CHECK-LABEL: @outline_attrs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-attributes #0 = { "no-jump-tables"="true" "profile-sample-accurate"="true" "speculative_load_hardening" "noimplicitfloat"="true" "use-sample-profile"="true"}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]]) [[ATTR:#[0-9]+]] {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
-
-; CHECK: attributes [[ATTR]] = { minsize optsize "no-jump-tables"="true" "noimplicitfloat"="true" "profile-sample-accurate"="true" "speculative_load_hardening" "use-sample-profile"="true" }
diff --git a/llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll b/llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll
deleted file mode 100644
index a5a163ac548b4..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll
+++ /dev/null
@@ -1,82 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test looks at instances of constants in the different regions. If there
-; is a register in the same place as a constant in a similar region of code, we
-; do not outline those regions.
-
-; The first function tests that we do not outline with the register is
-; seen first, and the second function checks that we do not outline when the
-; constant is seen first.
-
-define void @function_registers_first(i32 %0, i32 %1, i32 %2) {
-; CHECK-LABEL: @function_registers_first(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[TMP0:%.*]], ptr [[A]], i32 [[TMP1:%.*]], ptr [[B]], i32 [[TMP2:%.*]], ptr [[C]])
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 2, ptr [[A]], i32 3, ptr [[B]], i32 4, ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 %0, ptr %a, align 4
-  store i32 %1, ptr %b, align 4
-  store i32 %2, ptr %c, align 4
-  ret void
-next:
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  ret void
-}
-
-define void @function_with_constants_first(i32 %0, i32 %1, i32 %2) {
-; CHECK-LABEL: @function_with_constants_first(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 2, i32 [[AL]], i32 3, i32 [[BL]], i32 4, i32 [[CL]])
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0:%.*]], i32 [[AL]], i32 [[TMP1:%.*]], i32 [[BL]], i32 [[TMP2:%.*]], i32 [[CL]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  %3 = add i32 2, %al
-  %4 = add i32 3, %bl
-  %5 = add i32 4, %cl
-  ret void
-next:
-  %6 = add i32 %0, %al
-  %7 = add i32 %1, %bl
-  %8 = add i32 %2, %cl
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(i32 [[ARG0:%.*]], i32 [[ARG1:%.*]], i32 [[ARG2:%.*]], i32 [[ARG3:%.*]], i32 [[ARG4:%.*]], i32 [[ARG5:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT: add i32 [[ARG0]], [[ARG1]]
-; CHECK-NEXT: add i32 [[ARG2]], [[ARG3]]
-; CHECK-NEXT: add i32 [[ARG4]], [[ARG5]]
-
-; CHECK: define internal void @outlined_ir_func_1(i32 [[ARG0:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], ptr [[ARG3:%.*]], i32 [[ARG4:%.*]], ptr [[ARG5:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT: store i32 [[ARG0]], ptr [[ARG1]]
-; CHECK-NEXT: store i32 [[ARG2]], ptr [[ARG3]]
-; CHECK-NEXT: store i32 [[ARG4]], ptr [[ARG5]]
diff --git a/llvm/test/Transforms/IROutliner/outlining-cost-model.ll b/llvm/test/Transforms/IROutliner/outlining-cost-model.ll
deleted file mode 100644
index bb3163a7941fe..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-cost-model.ll
+++ /dev/null
@@ -1,187 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner < %s | FileCheck %s
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s -check-prefix=NOCOST
-
-; This test checks that we have different results from when the cost model
-; is on versus when it is off.  That is, if the number of instructions needed to
-; handle the arguments is greater than the number of instructions being added,
-; we do not outline.
-
-define void @function1() #0 {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-; NOCOST-LABEL: @function1(
-; NOCOST-NEXT:  entry:
-; NOCOST-NEXT:    [[A:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[B:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; NOCOST-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  %mul = mul i32 %0, %1
-  %sub = sub i32 %0, %1
-  %div = sdiv i32 %0, %1
-  %add1 = add i32 %0, %1
-  %mul1 = mul i32 %0, %1
-  %sub1 = sub i32 %0, %1
-  %div1 = sdiv i32 %0, %1
-  %add2 = add i32 %0, %1
-  %mul2 = mul i32 %0, %1
-  %sub2 = sub i32 %0, %1
-  %div2 = sdiv i32 %0, %1
-  ret void
-}
-
-define void @function2() #0 {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-; NOCOST-LABEL: @function2(
-; NOCOST-NEXT:  entry:
-; NOCOST-NEXT:    [[A:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[B:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; NOCOST-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  %mul = mul i32 %0, %1
-  %sub = sub i32 %0, %1
-  %div = sdiv i32 %0, %1
-  %add1 = add i32 %0, %1
-  %mul1 = mul i32 %0, %1
-  %sub1 = sub i32 %0, %1
-  %div1 = sdiv i32 %0, %1
-  %add2 = add i32 %0, %1
-  %mul2 = mul i32 %0, %1
-  %sub2 = sub i32 %0, %1
-  %div2 = sdiv i32 %0, %1
-  ret void
-}
-
-define void @function3() #0 {
-; CHECK-LABEL: @function3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    [[TMP3:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP2]], [[ADD]]
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[RESULT]], align 4
-; CHECK-NEXT:    ret void
-;
-; NOCOST-LABEL: @function3(
-; NOCOST-NEXT:  entry:
-; NOCOST-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[A:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[B:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; NOCOST-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; NOCOST-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; NOCOST-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; NOCOST-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; NOCOST-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; NOCOST-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; NOCOST-NEXT:    [[TMP0:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; NOCOST-NEXT:    call void @outlined_ir_func_2(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; NOCOST-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-define void @function4() #0 {
-; CHECK-LABEL: @function4(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP2]], [[ADD]]
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[RESULT]], align 4
-; CHECK-NEXT:    ret void
-;
-; NOCOST-LABEL: @function4(
-; NOCOST-NEXT:  entry:
-; NOCOST-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[A:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[B:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; NOCOST-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; NOCOST-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; NOCOST-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; NOCOST-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; NOCOST-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; NOCOST-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; NOCOST-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; NOCOST-NEXT:    call void @outlined_ir_func_2(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; NOCOST-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll b/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll
deleted file mode 100644
index c1140988fa916..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-debug-statements.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test makes sure that we do not include debug statements in outlined
-; functions.
-
-define void @outline_dbg1() {
-; CHECK-LABEL: @outline_dbg1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  call void @llvm.dbg.value(metadata i64 0, metadata !14, metadata !DIExpression()), !dbg !15
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-declare void @llvm.dbg.value(metadata, metadata, metadata)
-
-define void @outline_dbg2() {
-; CHECK-LABEL: @outline_dbg2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK: entry_to_outline:
-
-!0 = !DIFile(filename: "foo.c", directory: "/tmp")
-!1 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
-!5 = distinct !DICompileUnit(language: DW_LANG_C, file: !0, producer: "My Compiler", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !6, retainedTypes: !6, globals: !7)
-!6 = !{}
-!7 = !{}
-!11 = distinct !DISubprogram(name: "func_5", scope: !0, file: !0, line: 117, type: !12, isLocal: true, isDefinition: true, scopeLine: 118, isOptimized: false, unit: !5, retainedNodes: !6)
-!12 = !DISubroutineType(types: !13)
-!13 = !{}
-!14 = !DILocalVariable(name: "p_6", arg: 1, scope: !11, line: 117, type: !1)
-!15 = !DILocation(line: 1, scope: !11)
diff --git a/llvm/test/Transforms/IROutliner/outlining-different-constants.ll b/llvm/test/Transforms/IROutliner/outlining-different-constants.ll
deleted file mode 100644
index 1d887b330d78d..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-different-constants.ll
+++ /dev/null
@@ -1,58 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test looks at the constants in the regions, and if it they are the
-; differents it elevates the constants to arguments.
-
-define void @outline_constants1() {
-; CHECK-LABEL: @outline_constants1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 3, ptr [[A]], i32 4, ptr [[B]], i32 5, ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 3, ptr %a, align 4
-  store i32 4, ptr %b, align 4
-  store i32 5, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_constants2() {
-; CHECK-LABEL: @outline_constants2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 2, ptr [[A]], i32 3, ptr [[B]], i32 4, ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(i32 [[ARG0:%.*]], ptr [[ARG1:%.*]], i32 [[ARG2:%.*]], ptr [[ARG3:%.*]], i32 [[ARG4:%.*]], ptr [[ARG5:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 [[ARG0]], ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 [[ARG2]], ptr [[ARG3]], align 4
-; CHECK-NEXT:    store i32 [[ARG4]], ptr [[ARG5]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG3]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG5]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-different-globals.ll b/llvm/test/Transforms/IROutliner/outlining-different-globals.ll
deleted file mode 100644
index c4463be4b627f..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-different-globals.ll
+++ /dev/null
@@ -1,42 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test looks at the globals in the regions, and makes sure they are not
-; outlined if they are different values.
-
- at global1 = global i32 1, align 4
- at global2 = global i32 2, align 4
- at global3 = global i32 3, align 4
- at global4 = global i32 4, align 4
-
-define void @outline_globals1() {
-; CHECK-LABEL: @outline_globals1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr @global1, ptr @global2)
-; CHECK-NEXT:    ret void
-;
-entry:
-  %0 = load i32, ptr @global1
-  %1 = load i32, ptr @global2
-  %2 = add i32 %0, %1
-  ret void
-}
-
-define void @outline_globals2() {
-; CHECK-LABEL: @outline_globals2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr @global3, ptr @global4)
-; CHECK-NEXT:    ret void
-;
-entry:
-  %0 = load i32, ptr @global3
-  %1 = load i32, ptr @global4
-  %2 = add i32 %0, %1
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARG0]]
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARG1]]
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP1]]
diff --git a/llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll b/llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll
deleted file mode 100644
index 64e87fcf7fb75..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll
+++ /dev/null
@@ -1,106 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; These functions are constructed slightly differently so that they require
-; different output blocks for the values used outside of the region. We are
-; checking that two output blocks are created with different values.
-
-define void @outline_outputs1() #0 {
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]], i32 0)
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  %sub = sub i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[SUB_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[SUB_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[SUB_LOC]], ptr [[DOTLOC]], i32 1)
-; CHECK-NEXT:    [[SUB_RELOAD:%.*]] = load i32, ptr [[SUB_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[SUB_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[DOTRELOAD]], i32 [[SUB_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  %sub = sub i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %sub
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]], ptr [[ARG3:%.*]], ptr [[ARG4:%.*]], i32 [[ARG5:%.*]]) #1 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARG2]], align 4
-
-; CHECK: _after_outline.exitStub:
-; CHECK-NEXT:    switch i32 [[ARG5]], label [[BLOCK:%.*]] [
-; CHECK-NEXT:      i32 0, label %[[BLOCK_0:.*]]
-; CHECK-NEXT:      i32 1, label %[[BLOCK_1:.*]]
-
-; CHECK: [[BLOCK_0]]:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARG3]], align 4
-; CHECK-NEXT:    store i32 [[TMP2]], ptr [[ARG4]], align 4
-
-; CHECK: [[BLOCK_1]]:
-; CHECK-NEXT:    store i32 [[SUB]], ptr [[ARG3]], align 4
-; CHECK-NEXT:    store i32 [[TMP2]], ptr [[ARG4]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-different-structure.ll b/llvm/test/Transforms/IROutliner/outlining-different-structure.ll
deleted file mode 100644
index 45b33daa8e6c9..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-different-structure.ll
+++ /dev/null
@@ -1,62 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This is a negative case to show that when we have the same set of
-; instructions, but in a different order, they are not outlined in the same way.
-; In this case, the arguments passed into the function are in a different order.
-
-define void @outline_constants1() {
-; CHECK-LABEL: @outline_constants1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    call void @[[FUNCTION_0:.*]](ptr [[A]], ptr [[C]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %cl = load i32, ptr %c
-  %bl = load i32, ptr %b
-  ret void
-}
-
-define void @outline_constants2() {
-; CHECK-LABEL: @outline_constants2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    call void @[[FUNCTION_0]](ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK: define internal void @[[FUNCTION_0]](ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-exits-to-phi-node.ll b/llvm/test/Transforms/IROutliner/outlining-exits-to-phi-node.ll
deleted file mode 100644
index d901955caadfb..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-exits-to-phi-node.ll
+++ /dev/null
@@ -1,92 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract similar regions that would involve the splitting
-; of phi nodes on exit.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-dummy:
-  ret void
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-dummy:
-  ret void
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK: dummy:
-; CHECK-NEXT:  ret void
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK: dummy:
-; CHECK-NEXT:  ret void
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST_SPLIT:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST_SPLIT]]
-; CHECK:       first.split:
-; CHECK-NEXT:    [[DOTCE:%.*]] = phi i32 [ [[C]], [[TEST:%.*]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    store i32 [[DOTCE]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-first-instruction.ll b/llvm/test/Transforms/IROutliner/outlining-first-instruction.ll
deleted file mode 100644
index 53803ddcc95e5..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-first-instruction.ll
+++ /dev/null
@@ -1,67 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Make sure that we outline from all three of these functions, and that
-; the first instruction in the module is included when it is the only
-; instruction in the first basic block.
-
-define void @f1() {
-bb:
-  br label %bb1
-bb1:
-  br label %bb2
-bb2:
-  ret void
-}
-
-define void @f2() {
-bb:
-  br label %bb1
-bb1:
-  br label %bb2
-bb2:
-  ret void
-}
-
-define void @f3() {
-bb:
-  br label %bb1
-bb1:
-  br label %bb2
-bb2:
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f3(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB_TO_OUTLINE:%.*]]
-; CHECK:       bb_to_outline:
-; CHECK-NEXT:    br label [[BB1:%.*]]
-; CHECK:       bb1:
-; CHECK-NEXT:    br label [[BB2_EXITSTUB:%.*]]
-; CHECK:       bb2.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-gep.ll b/llvm/test/Transforms/IROutliner/outlining-gep.ll
deleted file mode 100644
index 78e2e19a4b788..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-gep.ll
+++ /dev/null
@@ -1,68 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks to make sure that we outline getelementptr instructions only
-; when all the operands after the first are the exact same. In this case, we
-; outline from the first two functions, but not the third.
-
-%struct.RT = type { i8, [10 x [20 x i32]], i8 }
-%struct.ST = type { i32, double, %struct.RT }
-
-define void @function1(ptr %s, i64 %t) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[S:%.*]], i64 [[T:%.*]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = getelementptr inbounds %struct.ST, ptr %s, i64 %t, i32 1
-  ret void
-}
-
-define void @function2(ptr %s, i64 %t) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[S:%.*]], i64 [[T:%.*]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = getelementptr inbounds %struct.ST, ptr %s, i64 %t, i32 1
-  ret void
-}
-
-define void @function3(ptr %s, i64 %t) {
-; CHECK-LABEL: @function3(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], ptr [[S:%.*]], i64 [[T:%.*]], i32 0
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = getelementptr inbounds %struct.ST, ptr %s, i64 %t, i32 0
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]], i64 [[ARG3:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds %struct.ST, ptr [[ARG2]], i64 [[ARG3]], i32 1
diff --git a/llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll b/llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll
deleted file mode 100644
index 2fe807e5d30c9..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll
+++ /dev/null
@@ -1,170 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks the isomorphic comparisons can be outlined together into one
-; function.
-
-; The following three function are identical, except that in the third, the
-; operand order, and predicate are swapped, meaning it is structurally the same
-; and should be outlined together.
-
-define void @outline_slt1() {
-; CHECK-LABEL: @outline_slt1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp slt i32 %al, %bl
-  ret void
-}
-
-define void @outline_slt2() {
-; CHECK-LABEL: @outline_slt2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp slt i32 %al, %bl
-  ret void
-}
-
-define void @outline_sgt() {
-; CHECK-LABEL: @outline_sgt(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp sgt i32 %bl, %al
-  ret void
-}
-
-; This has a swapped predicate, but not swapped operands, so it cannot use
-; the same outlined function as the ones above.
-
-define void @dontoutline_sgt() {
-; CHECK-LABEL: @dontoutline_sgt(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp sgt i32 [[AL]], [[BL]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp sgt i32 %al, %bl
-  ret void
-}
-
-; The below functions use a different kind of predicate that is not compatible
-; with the ones above, and should use a different outlined function.
-; The other difference here is that the predicate with swapped operands comes
-; first this time.
-
-define void @outline_ugt1() {
-; CHECK-LABEL: @outline_ugt1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp ugt i32 %al, %bl
-  ret void
-}
-
-define void @outline_ugt2() {
-; CHECK-LABEL: @outline_ugt2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp ugt i32 %al, %bl
-  ret void
-}
-
-define void @outline_ult() {
-; CHECK-LABEL: @outline_ult(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %0 = icmp ult i32 %bl, %al
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp ugt i32 [[AL]], [[BL]]
-
-; CHECK: define internal void @outlined_ir_func_1(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]]) #0 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = icmp slt i32 [[AL]], [[BL]]
diff --git a/llvm/test/Transforms/IROutliner/outlining-larger-size-commutative.ll b/llvm/test/Transforms/IROutliner/outlining-larger-size-commutative.ll
deleted file mode 100644
index 00098e6ba407d..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-larger-size-commutative.ll
+++ /dev/null
@@ -1,89 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -p iroutliner,verify -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that commutative instructions where the operands are
-; swapped are outlined as the same function.
-
-; It also checks that non-commutative instructions outlined as different
-; functions when the operands are swapped;
-
-; These are identical functions, except that in the flipped functions,
-; the operands in the adds are commuted.  However, since add instructions
-; are commutative, we should still outline from all four as the same
-; instruction.
-
-define void @function1(i32 %a, i32 %b) {
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[BLOCK_1:%.*]]
-; CHECK:       block_0:
-; CHECK-NEXT:    [[TMP0:%.*]] = add i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP4:%.*]], 1
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP0]]
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP0]]
-; CHECK-NEXT:    br i1 [[TMP3]], label [[BLOCK_1]], label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[TMP4]] = phi i32 [ [[TMP1]], [[BLOCK_0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
-; CHECK-NEXT:    br label [[BLOCK_0]]
-; CHECK:       block_2:
-; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[TMP2]], [[TMP2]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  br label %block_1
-
-block_0:
-  %0 = add i32 %a, %b
-  %1 = add i32 %4, 1
-  %2 = add i32 %0, %0
-  %3 = icmp sgt i32 %0, %0
-  br i1 %3, label %block_1, label %block_2
-
-block_1:
-  %4 = phi i32 [ %1, %block_0 ], [ 0, %entry ]
-  %5 = add i32 %b, %b
-  br label %block_0
-
-block_2:
-  %6 = add i32 %2, %2
-  ret void
-}
-
-define void @function2(i32 %a, i32 %b) {
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[BLOCK_1:%.*]]
-; CHECK:       block_0:
-; CHECK-NEXT:    [[TMP0:%.*]] = sub i32 [[A:%.*]], [[B:%.*]]
-; CHECK-NEXT:    [[TMP1:%.*]] = add i32 1, [[TMP4:%.*]]
-; CHECK-NEXT:    [[TMP2:%.*]] = add i32 [[TMP0]], [[TMP0]]
-; CHECK-NEXT:    [[TMP3:%.*]] = icmp sgt i32 [[TMP0]], [[TMP0]]
-; CHECK-NEXT:    br i1 [[TMP3]], label [[BLOCK_1]], label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[TMP4]] = phi i32 [ [[TMP1]], [[BLOCK_0:%.*]] ], [ 0, [[ENTRY:%.*]] ]
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[B]])
-; CHECK-NEXT:    br label [[BLOCK_0]]
-; CHECK:       block_2:
-; CHECK-NEXT:    [[TMP5:%.*]] = sub i32 [[TMP2]], [[TMP2]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  br label %block_1
-
-block_0:
-  %0 = sub i32 %a, %b
-  %1 = add i32 1, %4
-  %2 = add i32 %0, %0
-  %3 = icmp sgt i32 %0, %0
-  br i1 %3, label %block_1, label %block_2
-
-block_1:
-  %4 = phi i32 [ %1, %block_0 ], [ 0, %entry ]
-  %5 = add i32 %b, %b
-  br label %block_0
-
-block_2:
-  %6 = sub i32 %2, %2
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/outlining-multiple-exits-diff-outputs.ll b/llvm/test/Transforms/IROutliner/outlining-multiple-exits-diff-outputs.ll
deleted file mode 100644
index 9dbfa9ebd7e37..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-multiple-exits-diff-outputs.ll
+++ /dev/null
@@ -1,221 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Here we have multiple exits, but the different sources, different outputs are
-; needed, this checks that they are handled by separate switch statements.
-
-define void @outline_outputs1() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_6
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_7
-block_6:
-  %div = udiv i32 %aval, %bval
-  ret void
-block_7:
-  %sub = sub i32 %a2val, %b2val
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_7
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_6
-block_6:
-  %diff = sub i32 %a2val, %b2val
-  ret void
-block_7:
-  %quot = udiv i32 %add, %mul
-  ret void
-}
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[BVAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[AVAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[AVAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[BVAL_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[AVAL_LOC]], ptr [[BVAL_LOC]], i32 0)
-; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
-; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
-; CHECK-NEXT:    [[AVAL_RELOAD:%.*]] = load i32, ptr [[AVAL_LOC]], align 4
-; CHECK-NEXT:    [[BVAL_RELOAD:%.*]] = load i32, ptr [[BVAL_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[AVAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[BVAL_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_6:%.*]], label [[BLOCK_7:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[AVAL_RELOAD]], [[BVAL_RELOAD]]
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[MUL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[MUL_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[ADD_LOC]], ptr [[MUL_LOC]], i32 1)
-; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
-; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[MUL_RELOAD:%.*]] = load i32, ptr [[MUL_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[MUL_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_7:%.*]], label [[BLOCK_6:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    [[QUOT:%.*]] = udiv i32 [[ADD_RELOAD]], [[MUL_RELOAD]]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BLOCK_2_TO_OUTLINE:%.*]]
-; CHECK:       block_2_to_outline:
-; CHECK-NEXT:    [[A2VAL:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[B2VAL:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    [[ADD2:%.*]] = add i32 2, [[A2VAL]]
-; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 2, [[B2VAL]]
-; CHECK-NEXT:    br label [[BLOCK_5:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 2, [[AVAL]]
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 2, [[BVAL]]
-; CHECK-NEXT:    br label [[BLOCK_4:%.*]]
-; CHECK:       block_4:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[BLOCK_6_EXITSTUB:%.*]]
-; CHECK:       block_5:
-; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    store i32 [[MUL2]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[BLOCK_7_EXITSTUB:%.*]]
-; CHECK:       block_6.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP8:%.*]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_1:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       block_7.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP8]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[A2VAL]], ptr [[TMP4:%.*]], align 4
-; CHECK-NEXT:    store i32 [[B2VAL]], ptr [[TMP5:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_0_1:
-; CHECK-NEXT:    store i32 [[AVAL]], ptr [[TMP6:%.*]], align 4
-; CHECK-NEXT:    store i32 [[BVAL]], ptr [[TMP7:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[A2VAL]], ptr [[TMP4]], align 4
-; CHECK-NEXT:    store i32 [[B2VAL]], ptr [[TMP5]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_1:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP6]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP7]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-multiple-exits-one-output-set.ll b/llvm/test/Transforms/IROutliner/outlining-multiple-exits-one-output-set.ll
deleted file mode 100644
index f7897358a55bc..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-multiple-exits-one-output-set.ll
+++ /dev/null
@@ -1,192 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Here we have multiple exits, but different sources, and only one has an
-; output set.  We check to make sure that we do not generated extra output
-; blocks or entries in the switch statement.
-
-define void @outline_outputs1() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_6
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_7
-block_6:
-  ret void
-block_7:
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_7
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_6
-block_6:
-  %diff = sub i32 %a2val, %b2val
-  ret void
-block_7:
-  %quot = udiv i32 %add, %mul
-  ret void
-}
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr null, ptr null, ptr null, ptr null, i32 -1)
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_6:%.*]], label [[BLOCK_7:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[MUL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[MUL_LOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[ADD_LOC]], ptr [[MUL_LOC]], i32 0)
-; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
-; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[MUL_RELOAD:%.*]] = load i32, ptr [[MUL_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[MUL_LOC]])
-; CHECK-NEXT:    br i1 [[TMP0]], label [[BLOCK_7:%.*]], label [[BLOCK_6:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    [[QUOT:%.*]] = udiv i32 [[ADD_RELOAD]], [[MUL_RELOAD]]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BLOCK_2_TO_OUTLINE:%.*]]
-; CHECK:       block_2_to_outline:
-; CHECK-NEXT:    [[A2VAL:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[B2VAL:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    [[ADD2:%.*]] = add i32 2, [[A2VAL]]
-; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 2, [[B2VAL]]
-; CHECK-NEXT:    br label [[BLOCK_5:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 2, [[AVAL]]
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 2, [[BVAL]]
-; CHECK-NEXT:    br label [[BLOCK_4:%.*]]
-; CHECK:       block_4:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[BLOCK_6_EXITSTUB:%.*]]
-; CHECK:       block_5:
-; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    store i32 [[MUL2]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[BLOCK_7_EXITSTUB:%.*]]
-; CHECK:       block_6.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP8:%.*]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       block_7.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP8]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[A2VAL]], ptr [[TMP4:%.*]], align 4
-; CHECK-NEXT:    store i32 [[B2VAL]], ptr [[TMP5:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_1:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP6:%.*]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP7:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-multiple-exits.ll b/llvm/test/Transforms/IROutliner/outlining-multiple-exits.ll
deleted file mode 100644
index 1de13ebc3bc3a..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-multiple-exits.ll
+++ /dev/null
@@ -1,200 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Here we have multiple exits, but the different sources, same outputs are
-; needed, this checks that they are compressed, and moved into the appropriate
-; output blocks.
-
-define void @outline_outputs1() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_6
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_7
-block_6:
-  %div = udiv i32 %aval, %bval
-  ret void
-block_7:
-  %sub = sub i32 %a2val, %b2val
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-entry:
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  br label %block_2
-block_1:
-  %a2 = alloca i32, align 4
-  %b2 = alloca i32, align 4
-  br label %block_2
-block_2:
-  %a2val = load i32, ptr %a
-  %b2val = load i32, ptr %b
-  %add2 = add i32 2, %a2val
-  %mul2 = mul i32 2, %b2val
-  br label %block_5
-block_3:
-  %aval = load i32, ptr %a
-  %bval = load i32, ptr %b
-  %add = add i32 2, %aval
-  %mul = mul i32 2, %bval
-  br label %block_4
-block_4:
-  store i32 %add, ptr %output, align 4
-  store i32 %mul, ptr %result, align 4
-  br label %block_7
-block_5:
-  store i32 %add2, ptr %output, align 4
-  store i32 %mul2, ptr %result, align 4
-  br label %block_6
-block_6:
-  %diff = sub i32 %a2val, %b2val
-  ret void
-block_7:
-  %quot = udiv i32 %aval, %bval
-  ret void
-}
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[BVAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[AVAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[AVAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[BVAL_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[AVAL_LOC]], ptr [[BVAL_LOC]])
-; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
-; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
-; CHECK-NEXT:    [[AVAL_RELOAD:%.*]] = load i32, ptr [[AVAL_LOC]], align 4
-; CHECK-NEXT:    [[BVAL_RELOAD:%.*]] = load i32, ptr [[BVAL_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[AVAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[BVAL_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[BLOCK_6:%.*]], label [[BLOCK_7:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIV:%.*]] = udiv i32 [[AVAL_RELOAD]], [[BVAL_RELOAD]]
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[BVAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[AVAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A2VAL_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2:%.*]]
-; CHECK:       block_1:
-; CHECK-NEXT:    [[A2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BLOCK_2]]
-; CHECK:       block_2:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[AVAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[BVAL_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[A2VAL_LOC]], ptr [[B2VAL_LOC]], ptr [[AVAL_LOC]], ptr [[BVAL_LOC]])
-; CHECK-NEXT:    [[A2VAL_RELOAD:%.*]] = load i32, ptr [[A2VAL_LOC]], align 4
-; CHECK-NEXT:    [[B2VAL_RELOAD:%.*]] = load i32, ptr [[B2VAL_LOC]], align 4
-; CHECK-NEXT:    [[AVAL_RELOAD:%.*]] = load i32, ptr [[AVAL_LOC]], align 4
-; CHECK-NEXT:    [[BVAL_RELOAD:%.*]] = load i32, ptr [[BVAL_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[A2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[B2VAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[AVAL_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[BVAL_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[BLOCK_7:%.*]], label [[BLOCK_6:%.*]]
-; CHECK:       block_6:
-; CHECK-NEXT:    [[DIFF:%.*]] = sub i32 [[A2VAL_RELOAD]], [[B2VAL_RELOAD]]
-; CHECK-NEXT:    ret void
-; CHECK:       block_7:
-; CHECK-NEXT:    [[QUOT:%.*]] = udiv i32 [[AVAL_RELOAD]], [[BVAL_RELOAD]]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BLOCK_2_TO_OUTLINE:%.*]]
-; CHECK:       block_2_to_outline:
-; CHECK-NEXT:    [[A2VAL:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[B2VAL:%.*]] = load i32, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    [[ADD2:%.*]] = add i32 2, [[A2VAL]]
-; CHECK-NEXT:    [[MUL2:%.*]] = mul i32 2, [[B2VAL]]
-; CHECK-NEXT:    br label [[BLOCK_5:%.*]]
-; CHECK:       block_3:
-; CHECK-NEXT:    [[AVAL:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[BVAL:%.*]] = load i32, ptr [[TMP1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 2, [[AVAL]]
-; CHECK-NEXT:    [[MUL:%.*]] = mul i32 2, [[BVAL]]
-; CHECK-NEXT:    br label [[BLOCK_4:%.*]]
-; CHECK:       block_4:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    store i32 [[MUL]], ptr [[TMP3:%.*]], align 4
-; CHECK-NEXT:    br label [[BLOCK_6_EXITSTUB:%.*]]
-; CHECK:       block_5:
-; CHECK-NEXT:    store i32 [[ADD2]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    store i32 [[MUL2]], ptr [[TMP3]], align 4
-; CHECK-NEXT:    br label [[BLOCK_7_EXITSTUB:%.*]]
-; CHECK:       block_6.exitStub:
-; CHECK-NEXT:    store i32 [[AVAL]], ptr [[TMP6:%.*]], align 4
-; CHECK-NEXT:    store i32 [[BVAL]], ptr [[TMP7:%.*]], align 4
-; CHECK-NEXT:    ret i1 true
-; CHECK:       block_7.exitStub:
-; CHECK-NEXT:    store i32 [[A2VAL]], ptr [[TMP4:%.*]], align 4
-; CHECK-NEXT:    store i32 [[B2VAL]], ptr [[TMP5:%.*]], align 4
-; CHECK-NEXT:    ret i1 false
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-musttail.ll b/llvm/test/Transforms/IROutliner/outlining-musttail.ll
deleted file mode 100644
index 39f48a096c170..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-musttail.ll
+++ /dev/null
@@ -1,34 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Check that we do not outline musttail when swifttaill cc or tailcc
-; is not present.
-
-declare void @musttail()
-
-define void @f1() {
-  %a = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  musttail call void @musttail()
-  ret void
-}
-
-define void @f2() {
-  %a = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  musttail call void @musttail()
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    musttail call void @musttail()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    musttail call void @musttail()
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-no-return-functions.ll b/llvm/test/Transforms/IROutliner/outlining-no-return-functions.ll
deleted file mode 100644
index d2c41376f6b2c..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-no-return-functions.ll
+++ /dev/null
@@ -1,54 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Make sure that we outline safely from functions with no return instructions.
-
-; The code extractor will insert return instructions in the outer function
-; due to assumptions about the contents of the outlined region.
-
-define void @f1() {
-bb:
-  br label %bb1
-bb1:
-  br label %bb1
-}
-
-define void @f2() {
-bb:
-  br label %bb1
-bb1:
-  br label %bb1
-}
-
-define void @f3() {
-bb:
-  br label %bb1
-bb1:
-  br label %bb1
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    unreachable
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    unreachable
-;
-;
-; CHECK-LABEL: @f3(
-; CHECK-NEXT:  bb:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    unreachable
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB_TO_OUTLINE:%.*]]
-; CHECK:       bb_to_outline:
-; CHECK-NEXT:    br label [[BB1:%.*]]
-; CHECK:       bb1:
-; CHECK-NEXT:    br label [[BB1]]
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-odr.ll b/llvm/test/Transforms/IROutliner/outlining-odr.ll
deleted file mode 100644
index 6d6277ab6424d..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-odr.ll
+++ /dev/null
@@ -1,70 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner --ir-outlining-no-cost < %s | FileCheck %s
-; RUN: opt -S -passes=verify,iroutliner -enable-linkonceodr-ir-outlining --ir-outlining-no-cost < %s | FileCheck -check-prefix=ODR %s
-
-; This test looks at the constants in the regions, and if it they are the
-; same it outlines them as constants rather than elevating them to arguments.
-
-define linkonce_odr void @outline_odr1() {
-; ODR-LABEL: @outline_odr1(
-; ODR-NEXT:  entry:
-; ODR-NEXT:    [[A:%.*]] = alloca i32, align 4
-; ODR-NEXT:    [[B:%.*]] = alloca i32, align 4
-; ODR-NEXT:    [[C:%.*]] = alloca i32, align 4
-; ODR-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; ODR-NEXT:    ret void
-; CHECK-LABEL: @outline_odr1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_odr2() {
-; ODR-LABEL: @outline_odr2(
-; ODR-NEXT:  entry:
-; ODR-NEXT:    [[A:%.*]] = alloca i32, align 4
-; ODR-NEXT:    [[B:%.*]] = alloca i32, align 4
-; ODR-NEXT:    [[C:%.*]] = alloca i32, align 4
-; ODR-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[C]])
-; ODR-NEXT:    ret void
-; CHECK-LABEL: @outline_odr2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[B]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[C]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[A]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[C]], align 4
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll b/llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll
deleted file mode 100644
index 77f17c3162131..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll
+++ /dev/null
@@ -1,70 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test tests that inputs that are replaced with the output of an outlined
-; function is still recognized as the same value.
-
-define void @outline_outputs1() #0 {
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD2_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT2:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 2, ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    br label [[NEXT:%.*]]
-; CHECK:       next:
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD2_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC2]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[ADD_RELOAD]], ptr [[OUTPUT]], ptr [[RESULT]], ptr [[OUTPUT2]], ptr [[ADD2_LOC]], ptr [[DOTLOC2]])
-; CHECK-NEXT:    [[ADD2_RELOAD:%.*]] = load i32, ptr [[ADD2_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD3:%.*]] = load i32, ptr [[DOTLOC2]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD2_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC2]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[DOTRELOAD3]], i32 [[ADD2_RELOAD]], ptr [[RESULT2]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  %output2 = alloca i32, align 4
-  %result2 = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  br label %next
-next:
-  store i32 %add, ptr %output, align 4
-  store i32 3, ptr %result, align 4
-  %4 = load i32, ptr %output, align 4
-  %5 = load i32, ptr %result, align 4
-  %add2 = add i32 %4, %5
-  store i32 %add2, ptr %output2, align 4
-  %6 = load i32, ptr %output2, align 4
-  %mul2 = mul i32 %6, %add2
-  store i32 %mul2, ptr %result2, align 4
-  ret void
-}
diff --git a/llvm/test/Transforms/IROutliner/outlining-same-constants.ll b/llvm/test/Transforms/IROutliner/outlining-same-constants.ll
deleted file mode 100644
index d2cf221865893..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-same-constants.ll
+++ /dev/null
@@ -1,58 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test looks at the constants in the regions, and if it they are the
-; same it outlines them as constants rather than elevating them to arguments.
-
-define void @outline_constants1() {
-; CHECK-LABEL: @outline_constants1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @[[FUNCTION_0:.*]](ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @outline_constants2() {
-; CHECK-LABEL: @outline_constants2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @[[FUNCTION_0]](ptr [[A]], ptr [[B]], ptr [[C]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-; CHECK: define internal void @[[FUNCTION_0]](ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    store i32 4, ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[AL:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[BL:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[CL:%.*]] = load i32, ptr [[ARG2]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-same-globals.ll b/llvm/test/Transforms/IROutliner/outlining-same-globals.ll
deleted file mode 100644
index b16d743bbde20..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-same-globals.ll
+++ /dev/null
@@ -1,41 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
- at global1 = global i32 1, align 4
- at global2 = global i32 2, align 4
-
-; This test looks at the globals in the regions, and if it they are the
-; same it outlines the region without elevating the globals to arguments.
-
-define void @outline_globals1() {
-; CHECK-LABEL: @outline_globals1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    ret void
-;
-entry:
-  %0 = load i32, ptr @global1
-  %1 = load i32, ptr @global2
-  %2 = add i32 %0, %1
-  ret void
-}
-
-define void @outline_globals2() {
-; CHECK-LABEL: @outline_globals2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    ret void
-;
-entry:
-  %0 = load i32, ptr @global1
-  %1 = load i32, ptr @global2
-  %2 = add i32 %0, %1
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0()
-; CHECK: entry_to_outline:
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr @global1, align 4
-; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr @global2, align 4
-; CHECK-NEXT: [[ADD:%.*]] = add i32 [[TMP1]], [[TMP2]]
-
diff --git a/llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll b/llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll
deleted file mode 100644
index cc4f6ef6d7e07..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll
+++ /dev/null
@@ -1,94 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; These functions are constructed slightly differently so that they require
-; the same output blocks for the values used outside of the region. We are
-; checking that two output blocks are created with the same store instructions.
-
-define void @outline_outputs1() #0 {
-; CHECK-LABEL: @outline_outputs1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[OUTPUT]], align 4
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %3 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-define void @outline_outputs2() #0 {
-; CHECK-LABEL: @outline_outputs2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTLOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[ADD_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[B:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[OUTPUT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[RESULT:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A]], ptr [[B]], ptr [[OUTPUT]], ptr [[ADD_LOC]], ptr [[DOTLOC]])
-; CHECK-NEXT:    [[ADD_RELOAD:%.*]] = load i32, ptr [[ADD_LOC]], align 4
-; CHECK-NEXT:    [[DOTRELOAD:%.*]] = load i32, ptr [[DOTLOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[ADD_LOC]])
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTLOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_1(i32 [[DOTRELOAD]], i32 [[ADD_RELOAD]], ptr [[RESULT]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %output = alloca i32, align 4
-  %result = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  %0 = load i32, ptr %a, align 4
-  %1 = load i32, ptr %b, align 4
-  %add = add i32 %0, %1
-  store i32 %add, ptr %output, align 4
-  %2 = load i32, ptr %output, align 4
-  %mul = mul i32 %2, %add
-  store i32 %mul, ptr %result, align 4
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(ptr [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr [[ARG2:%.*]], ptr [[ARG3:%.*]], ptr [[ARG4:%.*]]) #1 {
-; CHECK: entry_to_outline:
-; CHECK-NEXT:    store i32 2, ptr [[ARG0]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[ARG0]], align 4
-; CHECK-NEXT:    [[TMP1:%.*]] = load i32, ptr [[ARG1]], align 4
-; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARG2]], align 4
-; CHECK-NEXT:    [[TMP2:%.*]] = load i32, ptr [[ARG2]], align 4
-
-; CHECK: entry_after_outline.exitStub:
-; CHECK-NEXT:    store i32 [[ADD]], ptr [[ARG3]], align 4
-; CHECK-NEXT:    store i32 [[TMP2]], ptr [[ARG4]], align 4
diff --git a/llvm/test/Transforms/IROutliner/outlining-special-state.ll b/llvm/test/Transforms/IROutliner/outlining-special-state.ll
deleted file mode 100644
index 9ceec51895351..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-special-state.ll
+++ /dev/null
@@ -1,163 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-declare void @foo();
-
-define void @atomicrmw_base(ptr %p) {
-entry:
-  %1 = atomicrmw add ptr %p, i32 1 acquire, align 8
-  call void @foo()
-  ret void
-}
-
-define void @atomicrmw_copy(ptr %p) {
-entry:
-  %1 = atomicrmw add ptr %p, i32 1 acquire, align 8
-  call void @foo()
-  ret void
-}
-
-define void @atomicrmw_wrong_type(ptr %p) {
-entry:
-  %1 = atomicrmw add ptr %p, i64 1 acquire, align 8
-  call void @foo()
-  ret void
-}
-
-define void @atomicrmw_wrong_align(ptr %p) {
-entry:
-  %1 = atomicrmw add ptr %p, i32 1 acquire, align 4
-  call void @foo()
-  ret void
-}
-
-define void @atomicrmw_wrong_volatile(ptr %p) {
-entry:
-  %1 = atomicrmw volatile add ptr %p, i32 1 acquire, align 8
-  call void @foo()
-  ret void
-}
-
-define void @cmpxchg_base(ptr %p) {
-entry:
-  %1 = cmpxchg ptr %p, i32 0, i32 1 monotonic monotonic, align 8
-  call void @foo()
-  ret void
-}
-
-define void @cmpxchg_copy(ptr %p) {
-entry:
-  %1 = cmpxchg ptr %p, i32 0, i32 1 monotonic monotonic, align 8
-  call void @foo()
-  ret void
-}
-
-define void @cmpxchg_wrong_type(ptr %p) {
-entry:
-  %1 = cmpxchg ptr %p, i64 0, i64 1 monotonic monotonic, align 8
-  call void @foo()
-  ret void
-}
-
-define void @cmpxchg_wrong_align(ptr %p) {
-entry:
-  %1 = cmpxchg ptr %p, i32 0, i32 1 monotonic monotonic, align 4
-  call void @foo()
-  ret void
-}
-
-define void @cmpxchg_wrong_volatile(ptr %p) {
-entry:
-  %1 = cmpxchg volatile ptr %p, i32 0, i32 1 monotonic monotonic, align 8
-  call void @foo()
-  ret void
-}
-
-
-; CHECK-LABEL: @atomicrmw_base(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[P:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @atomicrmw_copy(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_1(ptr [[P:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @atomicrmw_wrong_type(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr [[P:%.*]], i64 1 acquire, align 8
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @atomicrmw_wrong_align(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = atomicrmw add ptr [[P:%.*]], i32 1 acquire, align 4
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @atomicrmw_wrong_volatile(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = atomicrmw volatile add ptr [[P:%.*]], i32 1 acquire, align 8
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @cmpxchg_base(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[P:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @cmpxchg_copy(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[P:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @cmpxchg_wrong_type(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = cmpxchg ptr [[P:%.*]], i64 0, i64 1 monotonic monotonic, align 8
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @cmpxchg_wrong_align(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = cmpxchg ptr [[P:%.*]], i32 0, i32 1 monotonic monotonic, align 4
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @cmpxchg_wrong_volatile(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = cmpxchg volatile ptr [[P:%.*]], i32 0, i32 1 monotonic monotonic, align 8
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[TMP1:%.*]] = cmpxchg ptr [[TMP0:%.*]], i32 0, i32 1 monotonic monotonic, align 8
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @outlined_ir_func_1(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[TMP1:%.*]] = atomicrmw add ptr [[TMP0:%.*]], i32 1 acquire, align 8
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll b/llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll
deleted file mode 100644
index 47f3dae91a460..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-strip-loop-info.ll
+++ /dev/null
@@ -1,78 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Make sure that we strip loop debug info from instructions that are outlined as
-; well as regular debug info.
-
-define void @ham(i64 %arg0, i64 %arg1) !dbg !1 {
-bb0:
-  br label %bb1
-bb1:
-  %phi = phi i64 [ 0, %bb0 ], [ %arg1, %bb1 ]
-  %icmp = icmp ult i64 %phi, %arg0
-  br i1 %icmp, label %bb1, label %bb2, !dbg !7, !llvm.loop !11
-
-bb2:
-  ret void
-}
-
-define void @wombat(i64 %arg0, i64 %arg1) !dbg !13 {
-bb0:
-  br label %bb1
-bb1:
-  %phi = phi i64 [ 0, %bb0 ], [ %arg1, %bb1 ]
-  %icmp = icmp ult i64 %phi, %arg0
-  br i1 %icmp, label %bb1, label %bb2
-
-bb2:
-  ret void
-}
-
-!llvm.module.flags = !{!0}
-!llvm.dbg.cu = !{}
-
-!0 = !{i32 2, !"Debug Info Version", i32 3}
-!1 = distinct !DISubprogram(name: "ham", scope: !2, file: !2, line: 160, type: !3, scopeLine: 161, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5)
-!2 = !DIFile(filename: "file", directory: "dir")
-!3 = !DISubroutineType(types: !4)
-!4 = !{}
-!5 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !6, producer: "ver", isOptimized: true, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false, nameTableKind: None, sysroot: "sysroot", sdk: "sdk")
-!6 = !DIFile(filename: "file", directory: "dir")
-!7 = !DILocation(line: 354, column: 13, scope: !8, inlinedAt: !10)
-!8 = distinct !DISubprogram(name: "baz", scope: !9, file: !9, line: 345, type: !3, scopeLine: 346, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5)
-!9 = !DIFile(filename: "file", directory: "dir")
-!10 = distinct !DILocation(line: 164, column: 15, scope: !1)
-!11 = distinct !{!11, !7, !12}
-!12 = !DILocation(line: 355, column: 37, scope: !8, inlinedAt: !10)
-!13 = distinct !DISubprogram(name: "wombat", scope: !2, file: !2, line: 172, type: !3, scopeLine: 173, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5)
-!14 = distinct !DISubprogram(name: "bar", scope: !15, file: !15, line: 219, type: !3, scopeLine: 220, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !5)
-!15 = !DIFile(filename: "file", directory: "dir")
-
-; CHECK-LABEL: @ham(
-; CHECK-NEXT:  bb0:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i64 [[ARG1:%.*]], i64 [[ARG0:%.*]]), !dbg [[DBG6:![0-9]+]]
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @wombat(
-; CHECK-NEXT:  bb0:
-; CHECK-NEXT:    call void @outlined_ir_func_0(i64 [[ARG1:%.*]], i64 [[ARG0:%.*]]), !dbg [[DBG10:![0-9]+]]
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB0_TO_OUTLINE:%.*]]
-; CHECK:       bb0_to_outline:
-; CHECK-NEXT:    br label [[BB1:%.*]]
-; CHECK:       bb1:
-; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 0, [[BB0_TO_OUTLINE]] ], [ [[TMP0:%.*]], [[BB1]] ]
-; CHECK-NEXT:    [[ICMP:%.*]] = icmp ult i64 [[PHI]], [[TMP1:%.*]]
-; CHECK-NEXT:    br i1 [[ICMP]], label [[BB1]], label [[BB2_EXITSTUB:%.*]], !llvm.loop [[LOOP12:![0-9]+]]
-; CHECK:       bb2.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-swift-error.ll b/llvm/test/Transforms/IROutliner/outlining-swift-error.ll
deleted file mode 100644
index 68a87a1bc3cb4..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-swift-error.ll
+++ /dev/null
@@ -1,44 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-%swift.error = type opaque
-
-define void @outlining_swifterror1(ptr swifterror %err) {
-; CHECK-LABEL: @outlining_swifterror1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[X:%.*]] = alloca i64, align 8
-; CHECK-NEXT:    call void @outlined_ir_func_0(i64 5, ptr [[X]], ptr swifterror [[ERR:%.*]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %x = alloca i64
-  %0 = mul i64 5, 5
-  %1 = add i64 %0, %0
-  store i64 %1, ptr %x
-  store ptr %x, ptr %err
-  ret void
-}
-
-define void @outlining_swifterror2(ptr swifterror %err) {
-; CHECK-LABEL: @outlining_swifterror2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[X:%.*]] = alloca i64, align 8
-; CHECK-NEXT:    call void @outlined_ir_func_0(i64 3, ptr [[X]], ptr swifterror [[ERR:%.*]])
-; CHECK-NEXT:    ret void
-;
-entry:
-  %x = alloca i64
-  %0 = mul i64 3, 3
-  %1 = add i64 %0, %0
-  store i64 %1, ptr %x
-  store ptr %x, ptr %err
-  ret void
-}
-
-; CHECK: define internal void @outlined_ir_func_0(i64 [[ARG0:%.*]], ptr [[ARG1:%.*]], ptr swifterror [[ARG2:%.*]])
-; CHECK: entry_to_outline:
-; CHECK-NEXT:  [[TMP0:%.*]] = mul i64 [[ARG0]], [[ARG0]]
-; CHECK-NEXT:  [[TMP1:%.*]] = add i64 [[TMP0]], [[TMP0]]
-; CHECK-NEXT:  store i64 [[TMP1]], ptr [[ARG1]], align 4
-; CHECK-NEXT:  store ptr [[ARG1]], ptr [[ARG2]], align 8
-; CHECK-NEXT:  br label %entry_after_outline.exitStub
diff --git a/llvm/test/Transforms/IROutliner/outlining-swifttailcc.ll b/llvm/test/Transforms/IROutliner/outlining-swifttailcc.ll
deleted file mode 100644
index 48cc128ad68de..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-swifttailcc.ll
+++ /dev/null
@@ -1,33 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Check that we do not outline musttail calls when swifttailcc is present.
-
-declare swifttailcc void @musttail()
-
-define swifttailcc void @f1() {
-  %a = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  musttail call swifttailcc void @musttail()
-  ret void
-}
-
-define swifttailcc void @f2() {
-  %a = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  musttail call swifttailcc void @musttail()
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    musttail call swifttailcc void @musttail()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    musttail call swifttailcc void @musttail()
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/outlining-tailcc.ll b/llvm/test/Transforms/IROutliner/outlining-tailcc.ll
deleted file mode 100644
index 17ca8df4c67f0..0000000000000
--- a/llvm/test/Transforms/IROutliner/outlining-tailcc.ll
+++ /dev/null
@@ -1,33 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Check that we not do outline musttail calls when tailcc is present.
-
-declare tailcc void @musttail()
-
-define tailcc void @f1() {
-  %a = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  musttail call tailcc void @musttail()
-  ret void
-}
-
-define tailcc void @f2() {
-  %a = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  musttail call tailcc void @musttail()
-  ret void
-}
-; CHECK-LABEL: @f1(
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    musttail call tailcc void @musttail()
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @f2(
-; CHECK-NEXT:    [[A:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    store i32 2, ptr [[A]], align 4
-; CHECK-NEXT:    musttail call tailcc void @musttail()
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/phi-node-exit-path-order.ll b/llvm/test/Transforms/IROutliner/phi-node-exit-path-order.ll
deleted file mode 100644
index 15d313a41bf7c..0000000000000
--- a/llvm/test/Transforms/IROutliner/phi-node-exit-path-order.ll
+++ /dev/null
@@ -1,120 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; A PHINode defines the global value number of a split phi node for
-; an exit paths based on the canonical number for the incoming values, and
-; the canonical number for the basic block.  This checks that we accurately
-; capture a different numbering for the same incoming value but with different
-; blocks.
-
-define void @func1(i32 %0, i32 %1) local_unnamed_addr #0 {
-bb1:
-  br label %bb5
-
-bb2:
-  %a = add i32 %0, %1
-  %b = add i32 %0, %1
-  %c = icmp eq i32 %b, 1
-  br i1 %c, label %bb5, label %bb3
-
-bb3:
-  %d = add i32 %0, %1
-  br label %bb5
-
-bb4:
-  %e = sub i32 %0, %1
-  br label %bb2
-
-bb5:
-  %f = phi i32 [ 0, %bb1 ], [ 1, %bb2 ], [ 1, %bb3 ]
-  ret void
-}
-
-define void @func2(i32 %0, i32 %1) local_unnamed_addr #0 {
-bb1:
-  br label %bb5
-
-bb2:
-  %a = sub i32 %0, %1
-  %b = add i32 %0, %1
-  %c = icmp eq i32 %b, 1
-  br i1 %c, label %bb5, label %bb3
-
-bb3:
-  %d = add i32 %0, %1
-  br label %bb5
-
-bb4:
-  %e = add i32 %0, %1
-  br label %bb2
-
-bb5:
-  %f = phi i32 [ 0, %bb1 ], [ 1, %bb3 ], [ 1, %bb2 ]
-  ret void
-}
-; CHECK-LABEL: @func1(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[F_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BB5:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[A:%.*]] = add i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[F_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0]], i32 [[TMP1]], ptr [[F_CE_LOC]], i32 0)
-; CHECK-NEXT:    [[F_CE_RELOAD:%.*]] = load i32, ptr [[F_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[F_CE_LOC]])
-; CHECK-NEXT:    br label [[BB5]]
-; CHECK:       bb4:
-; CHECK-NEXT:    [[E:%.*]] = sub i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb5:
-; CHECK-NEXT:    [[F:%.*]] = phi i32 [ 0, [[BB1:%.*]] ], [ [[F_CE_RELOAD]], [[BB2]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @func2(
-; CHECK-NEXT:  bb1:
-; CHECK-NEXT:    [[F_CE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    br label [[BB5:%.*]]
-; CHECK:       bb2:
-; CHECK-NEXT:    [[A:%.*]] = sub i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[F_CE_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(i32 [[TMP0]], i32 [[TMP1]], ptr [[F_CE_LOC]], i32 1)
-; CHECK-NEXT:    [[F_CE_RELOAD:%.*]] = load i32, ptr [[F_CE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[F_CE_LOC]])
-; CHECK-NEXT:    br label [[BB5]]
-; CHECK:       bb4:
-; CHECK-NEXT:    [[E:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br label [[BB2:%.*]]
-; CHECK:       bb5:
-; CHECK-NEXT:    [[F:%.*]] = phi i32 [ 0, [[BB1:%.*]] ], [ [[F_CE_RELOAD]], [[BB2]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[BB2_TO_OUTLINE:%.*]]
-; CHECK:       bb2_to_outline:
-; CHECK-NEXT:    [[B:%.*]] = add i32 [[TMP0:%.*]], [[TMP1:%.*]]
-; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[B]], 1
-; CHECK-NEXT:    br i1 [[C]], label [[BB5_SPLIT:%.*]], label [[BB3:%.*]]
-; CHECK:       bb3:
-; CHECK-NEXT:    [[D:%.*]] = add i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT:    br label [[BB5_SPLIT]]
-; CHECK:       bb5.split:
-; CHECK-NEXT:    [[TMP4:%.*]] = phi i32 [ 1, [[BB3]] ], [ 1, [[BB2_TO_OUTLINE]] ]
-; CHECK-NEXT:    [[F_CE:%.*]] = phi i32 [ 1, [[BB2_TO_OUTLINE]] ], [ 1, [[BB3]] ]
-; CHECK-NEXT:    br label [[BB5_EXITSTUB:%.*]]
-; CHECK:       bb5.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP3:%.*]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_0:%.*]]
-; CHECK-NEXT:    i32 1, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_0:
-; CHECK-NEXT:    store i32 [[F_CE]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[TMP4]], ptr [[TMP2]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/phi-nodes-non-constant.ll b/llvm/test/Transforms/IROutliner/phi-nodes-non-constant.ll
deleted file mode 100644
index 5fc8684e2bd88..0000000000000
--- a/llvm/test/Transforms/IROutliner/phi-nodes-non-constant.ll
+++ /dev/null
@@ -1,74 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do extract phi nodes from the regions.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br label %first
-test:
-  %d = load i32, ptr %0, align 4
-  br label %first
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr [[A:%.*]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], ptr [[A:%.*]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br label [[FIRST]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP3:%.*]] = phi i32 [ [[C]], [[TEST:%.*]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    store i32 2, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/phi-nodes-output-overload.ll b/llvm/test/Transforms/IROutliner/phi-nodes-output-overload.ll
deleted file mode 100644
index 9e443abaaff50..0000000000000
--- a/llvm/test/Transforms/IROutliner/phi-nodes-output-overload.ll
+++ /dev/null
@@ -1,110 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not extract similar regions that would involve the splitting
-; of phi nodes on exit.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-next:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  br label %test1
-test1:
-  %e = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-first:
-  ret void
-next:
-  %1 = phi i32 [ %c, %test ], [ %e, %test1 ]
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]], i32 0)
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[TMP1:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], ptr [[DOTCE_LOC]], i32 1)
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br i1 [[TMP1]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT:%.*]], label [[PHI_BLOCK:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT]], label [[PHI_BLOCK]]
-; CHECK:       first.split:
-; CHECK-NEXT:    [[DOTCE:%.*]] = phi i32 [ [[C]], [[TEST:%.*]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP2:%.*]], label [[FINAL_BLOCK_1:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_0_1:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       next.exitStub:
-; CHECK-NEXT:    switch i32 [[TMP2]], label [[FINAL_BLOCK_0:%.*]] [
-; CHECK-NEXT:    i32 0, label [[OUTPUT_BLOCK_1_0:%.*]]
-; CHECK-NEXT:    ]
-; CHECK:       output_block_0_1:
-; CHECK-NEXT:    store i32 [[DOTCE]], ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_1]]
-; CHECK:       output_block_1_0:
-; CHECK-NEXT:    store i32 [[TMP3:%.*]], ptr [[TMP1]], align 4
-; CHECK-NEXT:    br label [[FINAL_BLOCK_0]]
-; CHECK:       phi_block:
-; CHECK-NEXT:    [[TMP3]] = phi i32 [ [[C]], [[TEST]] ], [ [[E]], [[TEST1]] ]
-; CHECK-NEXT:    br label [[NEXT_EXITSTUB:%.*]]
-; CHECK:       final_block_0:
-; CHECK-NEXT:    ret i1 false
-; CHECK:       final_block_1:
-; CHECK-NEXT:    ret i1 true
-;
diff --git a/llvm/test/Transforms/IROutliner/phi-nodes-parent-block-referential.ll b/llvm/test/Transforms/IROutliner/phi-nodes-parent-block-referential.ll
deleted file mode 100644
index 02930d77be3a8..0000000000000
--- a/llvm/test/Transforms/IROutliner/phi-nodes-parent-block-referential.ll
+++ /dev/null
@@ -1,98 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we do not outline when all of the phi nodes in the beginning
-; block are included not in the region.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %y = add i32 %c, %c
-  br label %test1
-dummy:
-  ret void
-test1:
-  %1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %2 = phi i32 [ %e, %test1 ], [ %y, %entry  ]
-  %e = load i32, ptr %0, align 4
-  %3 = add i32 %c, %c
-  %4 = sub i32 %c, %c
-  br i1 true, label %first, label %test1
-first:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %y = mul i32 %c, %c
-  br label %test1
-dummy:
-  ret void
-test1:
-  %1 = phi i32 [ %e, %test1 ], [ %y, %entry ]
-  %2 = phi i32 [ %y, %entry ], [ %e, %test1 ]
-  %e = load i32, ptr %0, align 4
-  %3 = add i32 %c, %c
-  %4 = mul i32 %c, %c
-  br i1 true, label %first, label %test1
-first:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Y:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       dummy:
-; CHECK-NEXT:    ret void
-; CHECK:       test1:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[E_RELOAD:%.*]], [[TEST1]] ], [ [[Y]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[E_RELOAD]], [[TEST1]] ], [ [[Y]], [[ENTRY]] ]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]], ptr [[E_LOC]])
-; CHECK-NEXT:    [[E_RELOAD]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    [[TMP3:%.*]] = sub i32 [[C]], [[C]]
-; CHECK-NEXT:    br i1 true, label [[FIRST:%.*]], label [[TEST1]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[E_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Y:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    br label [[TEST1:%.*]]
-; CHECK:       dummy:
-; CHECK-NEXT:    ret void
-; CHECK:       test1:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[E_RELOAD:%.*]], [[TEST1]] ], [ [[Y]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ [[Y]], [[ENTRY]] ], [ [[E_RELOAD]], [[TEST1]] ]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]], ptr [[E_LOC]])
-; CHECK-NEXT:    [[E_RELOAD]] = load i32, ptr [[E_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[E_LOC]])
-; CHECK-NEXT:    [[TMP3:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    br i1 true, label [[FIRST:%.*]], label [[TEST1]]
-; CHECK:       first:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[TEST1_TO_OUTLINE:%.*]]
-; CHECK:       test1_to_outline:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP1:%.*]], [[TMP1]]
-; CHECK-NEXT:    br label [[TEST1_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       test1_after_outline.exitStub:
-; CHECK-NEXT:    store i32 [[E]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/phi-nodes-simple.ll b/llvm/test/Transforms/IROutliner/phi-nodes-simple.ll
deleted file mode 100644
index 31cfe2ccea952..0000000000000
--- a/llvm/test/Transforms/IROutliner/phi-nodes-simple.ll
+++ /dev/null
@@ -1,56 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we are able to outline the simple phi node case of constants when
-; the corresponding labels match.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  br label %test
-test:
-  br label %first
-first:
-  %0 = phi i32 [ 0, %test ]
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  br label %test
-test:
-  br label %first
-first:
-  %0 = phi i32 [ 0, %test ]
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A:%.*]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0(ptr [[A:%.*]], ptr [[B:%.*]])
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    br label [[FIRST:%.*]]
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP2:%.*]] = phi i32 [ 0, [[TEST]] ]
-; CHECK-NEXT:    store i32 2, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    store i32 3, ptr [[TMP1:%.*]], align 4
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/region-end-of-module.ll b/llvm/test/Transforms/IROutliner/region-end-of-module.ll
deleted file mode 100644
index 2ad16078eed27..0000000000000
--- a/llvm/test/Transforms/IROutliner/region-end-of-module.ll
+++ /dev/null
@@ -1,112 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; This test checks that we do not fail when there is a similarity group with
-; an ending instruction that is also the end of the module.
-
- at a = global ptr null
-
-define void @foo() {
-entry:
-  br label %for.cond1
-
-for.cond1:
-  br label %for.body
-
-for.body:
-  %inc = add nsw i32 2, 1
-  br label %for.cond1
-
-for.end:
-  %inc3 = add nsw i32 2, 1
-  br label %for.cond1
-}
-
-; These are for testing if return instructions or unreachable instructions are
-; matched for similarity.
-define void @foo1() {
-entry:
-  br label %for.cond1
-
-for.cond1:
-  br label %for.body
-
-for.body:
-  %inc = add nsw i32 2, 1
-  ret void
-
-for.end:
-  %inc3 = add nsw i32 2, 1
-  ret void
-}
-
-define void @foo2() {
-entry:
-  br label %for.cond1
-
-for.cond1:
-  br label %for.body
-
-for.body:
-  %inc = add nsw i32 2, 1
-  unreachable
-
-for.end:
-  %inc3 = add nsw i32 2, 1
-  unreachable
-}
-
-; CHECK-LABEL: @foo(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    br label [[FOR_COND1:%.*]]
-; CHECK:       for.cond1:
-; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
-; CHECK:       for.body:
-; CHECK-NEXT:    call void @outlined_ir_func_1()
-; CHECK-NEXT:    br label [[FOR_COND1]]
-; CHECK:       for.end:
-; CHECK-NEXT:    call void @outlined_ir_func_1()
-; CHECK-NEXT:    br label [[FOR_COND1]]
-;
-;
-; CHECK-LABEL: @foo1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    ret void
-; CHECK:       for.end:
-; CHECK-NEXT:    [[INC3:%.*]] = add nsw i32 2, 1
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @foo2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    call void @outlined_ir_func_0()
-; CHECK-NEXT:    unreachable
-; CHECK:       for.end:
-; CHECK-NEXT:    [[INC3:%.*]] = add nsw i32 2, 1
-; CHECK-NEXT:    unreachable
-;
-;
-; CHECK: define internal void @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br label [[FOR_COND1:%.*]]
-; CHECK:       for.cond1:
-; CHECK-NEXT:    br label [[FOR_BODY:%.*]]
-; CHECK:       for.body:
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 2, 1
-; CHECK-NEXT:    br label [[ENTRY_AFTER_OUTLINE_EXITSTUB:%.*]]
-; CHECK:       entry_after_outline.exitStub:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK: define internal void @outlined_ir_func_1(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[FOR_BODY_TO_OUTLINE:%.*]]
-; CHECK:       for.body_to_outline:
-; CHECK-NEXT:    [[INC:%.*]] = add nsw i32 2, 1
-; CHECK-NEXT:    br label [[FOR_COND1_EXITSTUB:%.*]]
-; CHECK:       for.cond1.exitStub:
-; CHECK-NEXT:    ret void
-;
diff --git a/llvm/test/Transforms/IROutliner/region-inputs-in-phi-nodes.ll b/llvm/test/Transforms/IROutliner/region-inputs-in-phi-nodes.ll
deleted file mode 100644
index 25b1e8ee29f3c..0000000000000
--- a/llvm/test/Transforms/IROutliner/region-inputs-in-phi-nodes.ll
+++ /dev/null
@@ -1,110 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --include-generated-funcs
-; RUN: opt -S -passes=verify,iroutliner -ir-outlining-no-cost < %s | FileCheck %s
-
-; Show that we are able to propagate inputs to the region into the split PHINode
-; outside of the region if necessary.
-
-define void @function1(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %z = add i32 %c, %c
-  br i1 true, label %test1, label %first
-test1:
-  %e = load i32, ptr %0, align 4
-  %1 = add i32 %c, %c
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-dummy:
-  ret void
-first:
-  %2 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  ret void
-next:
-  ret void
-}
-
-define void @function2(ptr %a, ptr %b) {
-entry:
-  %0 = alloca i32, align 4
-  %c = load i32, ptr %0, align 4
-  %z = mul i32 %c, %c
-  br i1 true, label %test1, label %first
-test1:
-  %e = load i32, ptr %0, align 4
-  %1 = add i32 %c, %c
-  br i1 true, label %first, label %test
-test:
-  %d = load i32, ptr %0, align 4
-  br i1 true, label %first, label %next
-dummy:
-  ret void
-first:
-  %2 = phi i32 [ %d, %test ], [ %e, %test1 ], [ %c, %entry ]
-  ret void
-next:
-  ret void
-}
-; CHECK-LABEL: @function1(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Z:%.*]] = add i32 [[C]], [[C]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]], ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK: dummy:
-; CHECK-NEXT:  ret void
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: @function2(
-; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[DOTCE_LOC:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[TMP0:%.*]] = alloca i32, align 4
-; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    [[Z:%.*]] = mul i32 [[C]], [[C]]
-; CHECK-NEXT:    call void @llvm.lifetime.start.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[TARGETBLOCK:%.*]] = call i1 @outlined_ir_func_0(ptr [[TMP0]], i32 [[C]], ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    [[DOTCE_RELOAD:%.*]] = load i32, ptr [[DOTCE_LOC]], align 4
-; CHECK-NEXT:    call void @llvm.lifetime.end.p0(ptr [[DOTCE_LOC]])
-; CHECK-NEXT:    br i1 [[TARGETBLOCK]], label [[FIRST:%.*]], label [[NEXT:%.*]]
-; CHECK: dummy:
-; CHECK-NEXT:  ret void
-; CHECK:       first:
-; CHECK-NEXT:    [[TMP1:%.*]] = phi i32 [ [[DOTCE_RELOAD]], [[ENTRY:%.*]] ]
-; CHECK-NEXT:    ret void
-; CHECK:       next:
-; CHECK-NEXT:    ret void
-;
-;
-; CHECK-LABEL: define internal i1 @outlined_ir_func_0(
-; CHECK-NEXT:  newFuncRoot:
-; CHECK-NEXT:    br label [[ENTRY_TO_OUTLINE:%.*]]
-; CHECK:       entry_to_outline:
-; CHECK-NEXT:    br i1 true, label [[TEST1:%.*]], label [[FIRST_SPLIT:%.*]]
-; CHECK:       test1:
-; CHECK-NEXT:    [[E:%.*]] = load i32, ptr [[TMP0:%.*]], align 4
-; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP1:%.*]], [[TMP1]]
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT]], label [[TEST:%.*]]
-; CHECK:       test:
-; CHECK-NEXT:    [[D:%.*]] = load i32, ptr [[TMP0]], align 4
-; CHECK-NEXT:    br i1 true, label [[FIRST_SPLIT]], label [[NEXT_EXITSTUB:%.*]]
-; CHECK:       first.split:
-; CHECK-NEXT:    [[DOTCE:%.*]] = phi i32 [ [[D]], [[TEST]] ], [ [[E]], [[TEST1]] ], [ [[TMP1]], [[ENTRY_TO_OUTLINE]] ]
-; CHECK-NEXT:    br label [[FIRST_EXITSTUB:%.*]]
-; CHECK:       first.exitStub:
-; CHECK-NEXT:    store i32 [[DOTCE]], ptr [[TMP2:%.*]], align 4
-; CHECK-NEXT:    ret i1 true
-; CHECK:       next.exitStub:
-; CHECK-NEXT:    ret i1 false
-;
diff --git a/llvm/test/lit.cfg.py b/llvm/test/lit.cfg.py
index f48c3a57a89aa..6f04a855d8cb8 100644
--- a/llvm/test/lit.cfg.py
+++ b/llvm/test/lit.cfg.py
@@ -68,7 +68,6 @@
     config.excludes.extend(
         [
             "Attributor",
-            "IROutliner",
             "BlockExtractor",
             "CodeExtractor",
             "HotColdSplit",
@@ -296,7 +295,6 @@ def get_asan_rtlib():
         "llvm-readelf",
         "llvm-readobj",
         "llvm-rtdyld",
-        "llvm-sim",
         "llvm-size",
         "llvm-split",
         "llvm-stress",
diff --git a/llvm/test/tools/llvm-sim/Inputs/sim1.ll b/llvm/test/tools/llvm-sim/Inputs/sim1.ll
deleted file mode 100644
index 19cfe2fd6f298..0000000000000
--- a/llvm/test/tools/llvm-sim/Inputs/sim1.ll
+++ /dev/null
@@ -1,27 +0,0 @@
-define void @similar_func1() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
-
-define void @similar_func2() {
-entry:
-  %a = alloca i32, align 4
-  %b = alloca i32, align 4
-  %c = alloca i32, align 4
-  store i32 2, ptr %a, align 4
-  store i32 3, ptr %b, align 4
-  store i32 4, ptr %c, align 4
-  %al = load i32, ptr %a
-  %bl = load i32, ptr %b
-  %cl = load i32, ptr %c
-  ret void
-}
diff --git a/llvm/test/tools/llvm-sim/fail-cases.test b/llvm/test/tools/llvm-sim/fail-cases.test
deleted file mode 100644
index 8de658abe3ef0..0000000000000
--- a/llvm/test/tools/llvm-sim/fail-cases.test
+++ /dev/null
@@ -1,8 +0,0 @@
-# RUN: not llvm-sim %s 2>&1 | FileCheck %s
-# RUN: not llvm-sim %s.2 2>&1 | FileCheck -DMSG=%errc_ENOENT %s --check-prefix=EXIST
-
-# File reading error messaging tests.
-
-# CHECK: error: expected top-level entity
-
-# EXIST: error: Could not open input file: [[MSG]]
diff --git a/llvm/test/tools/llvm-sim/single-sim-file.test b/llvm/test/tools/llvm-sim/single-sim-file.test
deleted file mode 100644
index cef14b3608500..0000000000000
--- a/llvm/test/tools/llvm-sim/single-sim-file.test
+++ /dev/null
@@ -1,57 +0,0 @@
-# RUN: llvm-sim -o %t %S/Inputs/sim1.ll
-# RUN: FileCheck %s < %t
-
-# Checking the output of a single module test.
-
-# CHECK: {
-# CHECK-NEXT: "1": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 14,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 4,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "2": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 15,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 5,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "3": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 16,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 6,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "4": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 17,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 7,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "5": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 18,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 8,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ]
-# CHECK-NEXT:}
diff --git a/llvm/test/tools/llvm-sim/single-sim.test b/llvm/test/tools/llvm-sim/single-sim.test
deleted file mode 100644
index 0095ec6acbc58..0000000000000
--- a/llvm/test/tools/llvm-sim/single-sim.test
+++ /dev/null
@@ -1,56 +0,0 @@
-# RUN: llvm-sim -o - %S/Inputs/sim1.ll | FileCheck %s
-
-# Checking the output of a single module test.
-
-# CHECK: {
-# CHECK-NEXT: "1": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 14,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 4,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "2": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 15,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 5,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "3": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 16,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 6,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "4": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 17,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 7,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ],
-# CHECK-NEXT: "5": [
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 18,
-# CHECK-NEXT:   "end": 19
-# CHECK-NEXT:  },
-# CHECK-NEXT:  {
-# CHECK-NEXT:   "start": 8,
-# CHECK-NEXT:   "end": 9
-# CHECK-NEXT:  }
-# CHECK-NEXT: ]
-# CHECK-NEXT:}
diff --git a/llvm/tools/llvm-sim/CMakeLists.txt b/llvm/tools/llvm-sim/CMakeLists.txt
deleted file mode 100644
index 76299050392a2..0000000000000
--- a/llvm/tools/llvm-sim/CMakeLists.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  Core
-  Support
-  Analysis
-  IRReader)
-
-add_llvm_tool(llvm-sim
-  llvm-sim.cpp
-)
diff --git a/llvm/tools/llvm-sim/llvm-sim.cpp b/llvm/tools/llvm-sim/llvm-sim.cpp
deleted file mode 100644
index 6e86714ed4acd..0000000000000
--- a/llvm/tools/llvm-sim/llvm-sim.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-//===-- llvm-sim.cpp - Find  similar sections of programs -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This program finds similar sections of a Module, and exports them as a JSON
-// file.
-//
-// To find similarities contained across multiple modules, please use llvm-link
-// first to merge the modules.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/IRReader/IRReader.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/InitLLVM.h"
-#include "llvm/Support/JSON.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/ToolOutputFile.h"
-
-using namespace llvm;
-using namespace IRSimilarity;
-
-static cl::opt<std::string> OutputFilename("o", cl::desc("Output Filename"),
-                                           cl::init("-"),
-                                           cl::value_desc("filename"));
-
-static cl::opt<std::string> InputSourceFile(cl::Positional,
-                                            cl::desc("<Source file>"),
-                                            cl::init("-"),
-                                            cl::value_desc("filename"));
-
-/// Retrieve the unique number \p I was mapped to in parseBitcodeFile.
-///
-/// \param I - The Instruction to find the instruction number for.
-/// \param LLVMInstNum - The mapping of Instructions to their location in the
-/// module represented by an unsigned integer.
-/// \returns The instruction number for \p I if it exists.
-std::optional<unsigned>
-getPositionInModule(const Instruction *I,
-                    const DenseMap<Instruction *, unsigned> &LLVMInstNum) {
-  assert(I && "Instruction is nullptr!");
-  auto It = LLVMInstNum.find(I);
-  if (It == LLVMInstNum.end())
-    return std::nullopt;
-  return It->second;
-}
-
-/// Exports the given SimilarityGroups to a JSON file at \p FilePath.
-///
-/// \param FilePath - The path to the output location.
-/// \param SimSections - The similarity groups to process.
-/// \param LLVMInstNum - The mapping of Instructions to their location in the
-/// module represented by an unsigned integer.
-/// \returns A nonzero error code if there was a failure creating the file.
-std::error_code
-exportToFile(const StringRef FilePath,
-             const SimilarityGroupList &SimSections,
-             const DenseMap<Instruction *, unsigned> &LLVMInstNum) {
-  std::error_code EC;
-  std::unique_ptr<ToolOutputFile> Out(
-      new ToolOutputFile(FilePath, EC, sys::fs::OF_None));
-  if (EC)
-    return EC;
-
-  json::OStream J(Out->os(), 1);
-  J.objectBegin();
-
-  unsigned SimOption = 1;
-  // Process each list of SimilarityGroups organized by the Module.
-  for (const SimilarityGroup &G : SimSections) {
-    std::string SimOptionStr = std::to_string(SimOption);
-    J.attributeBegin(SimOptionStr);
-    J.arrayBegin();
-    // For each file there is a list of the range where the similarity
-    // exists.
-    for (const IRSimilarityCandidate &C : G) {
-      std::optional<unsigned> Start =
-          getPositionInModule((*C.front()).Inst, LLVMInstNum);
-      std::optional<unsigned> End =
-          getPositionInModule((*C.back()).Inst, LLVMInstNum);
-
-      assert(Start &&
-             "Could not find instruction number for first instruction");
-      assert(End && "Could not find instruction number for last instruction");
-
-      J.object([&] {
-        J.attribute("start", *Start);
-        J.attribute("end", *End);
-      });
-    }
-    J.arrayEnd();
-    J.attributeEnd();
-    SimOption++;
-  }
-  J.objectEnd();
-
-  Out->keep();
-
-  return EC;
-}
-
-int main(int argc, const char *argv[]) {
-  InitLLVM X(argc, argv);
-
-  cl::ParseCommandLineOptions(argc, argv, "LLVM IR Similarity Visualizer\n");
-
-  LLVMContext CurrContext;
-  SMDiagnostic Err;
-  std::unique_ptr<Module> ModuleToAnalyze =
-      parseIRFile(InputSourceFile, Err, CurrContext);
-
-  if (!ModuleToAnalyze) {
-    Err.print(argv[0], errs());
-    return 1;
-  }
-
-  // Mapping from an Instruction pointer to its occurrence in a sequential
-  // list of all the Instructions in a Module.
-  DenseMap<Instruction *, unsigned> LLVMInstNum;
-
-  // We give each instruction a number, which gives us a start and end value
-  // for the beginning and end of each IRSimilarityCandidate.
-  unsigned InstructionNumber = 1;
-  for (Function &F : *ModuleToAnalyze)
-    for (BasicBlock &BB : F)
-      for (Instruction &I : BB)
-        LLVMInstNum[&I]= InstructionNumber++;
-
-  // The similarity identifier we will use to find the similar sections.
-  IRSimilarityIdentifier SimIdent;
-  SimilarityGroupList SimilaritySections =
-      SimIdent.findSimilarity(*ModuleToAnalyze);
-
-  std::error_code E =
-      exportToFile(OutputFilename, SimilaritySections, LLVMInstNum);
-  if (E) {
-    errs() << argv[0] << ": " << E.message() << '\n';
-    return 2;
-  }
-
-  return 0;
-}
diff --git a/llvm/unittests/Analysis/CMakeLists.txt b/llvm/unittests/Analysis/CMakeLists.txt
index 50bf4539e7984..b1f8cb918d590 100644
--- a/llvm/unittests/Analysis/CMakeLists.txt
+++ b/llvm/unittests/Analysis/CMakeLists.txt
@@ -34,7 +34,6 @@ set(ANALYSIS_TEST_SOURCES
   FunctionPropertiesAnalysisTest.cpp
   InlineCostTest.cpp
   IR2VecTest.cpp
-  IRSimilarityIdentifierTest.cpp
   IVDescriptorsTest.cpp
   LastRunTrackingAnalysisTest.cpp
   LazyCallGraphTest.cpp
diff --git a/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp b/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp
deleted file mode 100644
index c74f9c63af219..0000000000000
--- a/llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp
+++ /dev/null
@@ -1,2850 +0,0 @@
-//===- IRSimilarityIdentifierTest.cpp - IRSimilarityIdentifier unit tests -===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for components for finding similarity such as the instruction mapper,
-// suffix tree usage, and structural analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Analysis/IRSimilarityIdentifier.h"
-#include "llvm/ADT/ScopeExit.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-using namespace IRSimilarity;
-
-static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
-                                              StringRef ModuleStr) {
-  SMDiagnostic Err;
-  std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
-  assert(M && "Bad LLVM IR?");
-  return M;
-}
-
-void getVectors(Module &M, IRInstructionMapper &Mapper,
-                std::vector<IRInstructionData *> &InstrList,
-                std::vector<unsigned> &UnsignedVec) {
-  for (Function &F : M)
-    for (BasicBlock &BB : F)
-      Mapper.convertToUnsignedVec(BB, InstrList, UnsignedVec);
-}
-
-void getSimilarities(
-    Module &M,
-    std::vector<std::vector<IRSimilarityCandidate>> &SimilarityCandidates) {
-  // In order to keep the size of the tests from becoming too large, we do not
-  // recognize similarity for branches unless explicitly needed.
-  IRSimilarityIdentifier Identifier(/*EnableBranchMatching = */false);
-  SimilarityCandidates = Identifier.findSimilarity(M);
-}
-
-// TODO: All these tests could probably become IR LIT tests like
-// IROutliner/outlining-special-state.ll
-
-// Checks that different opcodes are mapped to different values
-TEST(IRInstructionMapper, OpcodeDifferentiation) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = mul i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check that the size of the unsigned vector and the instruction list are the
-  // same as a safety check.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  // Make sure that the unsigned vector is the expected size.
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-
-  // Check whether the instructions are not mapped to the same value.
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that the same opcodes and types are mapped to the same values.
-TEST(IRInstructionMapper, OpcodeTypeSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-
-  // Check whether the instructions are mapped to the same value.
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that the same opcode and different types are mapped to different
-// values.
-TEST(IRInstructionMapper, TypeDifferentiation) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b, i64 %c, i64 %d) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i64 %c, %d
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that different predicates map to different values.
-TEST(IRInstructionMapper, PredicateDifferentiation) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp sge i32 %b, %a
-                             %1 = icmp slt i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that predicates where that can be considered the same when the
-// operands are swapped, i.e. greater than to less than are mapped to the same
-// unsigned integer.
-TEST(IRInstructionMapper, PredicateIsomorphism) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp sgt i32 %a, %b
-                             %1 = icmp slt i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that the same predicate maps to the same value.
-TEST(IRInstructionMapper, PredicateSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp slt i32 %a, %b
-                             %1 = icmp slt i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that the same predicate maps to the same value for floating point
-// CmpInsts.
-TEST(IRInstructionMapper, FPPredicateSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(double %a, double %b) {
-                          bb0:
-                             %0 = fcmp olt double %a, %b
-                             %1 = fcmp olt double %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that the different predicate maps to a different value for floating
-// point CmpInsts.
-TEST(IRInstructionMapper, FPPredicatDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(double %a, double %b) {
-                          bb0:
-                             %0 = fcmp olt double %a, %b
-                             %1 = fcmp oge double %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that the zexts that have the same type parameters map to the same
-// unsigned integer.
-TEST(IRInstructionMapper, ZextTypeSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a) {
-                          bb0:
-                             %0 = zext i32  %a to i64
-                             %1 = zext i32  %a to i64
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that the sexts that have the same type parameters map to the same
-// unsigned integer.
-TEST(IRInstructionMapper, SextTypeSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a) {
-                          bb0:
-                             %0 = sext i32  %a to i64
-                             %1 = sext i32  %a to i64
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that the zexts that have the different type parameters map to the
-// different unsigned integers.
-TEST(IRInstructionMapper, ZextTypeDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i8 %b) {
-                          bb0:
-                             %0 = zext i32 %a to i64
-                             %1 = zext i8 %b to i32
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that the sexts that have the different type parameters map to the
-// different unsigned integers.
-TEST(IRInstructionMapper, SextTypeDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i8 %b) {
-                          bb0:
-                             %0 = sext i32 %a to i64
-                             %1 = sext i8 %b to i32
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that loads that have the same type are mapped to the same unsigned
-// integer.
-TEST(IRInstructionMapper, LoadSimilarType) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load i32, ptr %a
-                             %1 = load i32, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that loads that have the different types are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, LoadDifferentType) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load i32, ptr %a
-                             %1 = load i64, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that loads that have the different aligns are mapped to different
-// unsigned integers.
-TEST(IRInstructionMapper, LoadDifferentAlign) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load i32, ptr %a, align 4
-                             %1 = load i32, ptr %b, align 8
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that loads that have the different volatile settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, LoadDifferentVolatile) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load volatile i32, ptr %a
-                             %1 = load i32, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that loads that have the same volatile settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, LoadSameVolatile) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load volatile i32, ptr %a
-                             %1 = load volatile i32, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that loads that have the different atomicity settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, LoadDifferentAtomic) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load atomic i32, ptr %a unordered, align 4
-                             %1 = load atomic i32, ptr %b monotonic, align 4
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that loads that have the same atomicity settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, LoadSameAtomic) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             %0 = load atomic i32, ptr %a unordered, align 4
-                             %1 = load atomic i32, ptr %b unordered, align 4
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that stores that have the same type are mapped to the same unsigned
-// integer.
-TEST(IRInstructionMapper, StoreSimilarType) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store i32 1, ptr %a
-                             store i32 2, ptr %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that stores that have the different types are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, StoreDifferentType) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store i32 1, ptr %a
-                             store i64 1, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that stores that have the different aligns are mapped to different
-// unsigned integers.
-TEST(IRInstructionMapper, StoreDifferentAlign) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store i32 1, ptr %a, align 4
-                             store i32 1, ptr %b, align 8
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that stores that have the different volatile settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, StoreDifferentVolatile) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store volatile i32 1, ptr %a
-                             store i32 1, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that stores that have the same volatile settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, StoreSameVolatile) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store volatile i32 1, ptr %a
-                             store volatile i32 1, ptr %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that loads that have the same atomicity settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, StoreSameAtomic) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store atomic i32 1, ptr %a unordered, align 4
-                             store atomic i32 1, ptr %b unordered, align 4
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] == UnsignedVec[1]);
-}
-
-// Checks that loads that have the different atomicity settings are mapped to
-// different unsigned integers.
-TEST(IRInstructionMapper, StoreDifferentAtomic) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %a, ptr %b) {
-                          bb0:
-                             store atomic i32 1, ptr %a unordered, align 4
-                             store atomic i32 1, ptr %b monotonic, align 4
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-  ASSERT_TRUE(UnsignedVec.size() == 3);
-  ASSERT_TRUE(UnsignedVec[0] != UnsignedVec[1]);
-}
-
-// Checks that the branch is mapped to legal when the option is set.
-TEST(IRInstructionMapper, BranchLegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp slt i32 %a, %b
-                             br i1 %0, label %bb0, label %bb1
-                          bb1:
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_TRUE(UnsignedVec[1] > UnsignedVec[0]);
-  ASSERT_TRUE(UnsignedVec[1] < UnsignedVec[2]);
-}
-
-// Checks that a PHINode is mapped to be legal.
-TEST(IRInstructionMapper, PhiLegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = phi i1 [ 0, %bb0 ], [ %0, %bb1 ]
-                             %1 = add i32 %a, %b
-                             ret i32 0
-                          bb1:
-                             ret i32 1
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-}
-
-// Checks that a PHINode is mapped to be legal.
-TEST(IRInstructionMapper, PhiIllegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = phi i1 [ 0, %bb0 ], [ %0, %bb1 ]
-                             %1 = add i32 %a, %b
-                             ret i32 0
-                          bb1:
-                             ret i32 1
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// In most cases, the illegal instructions we are collecting don't require any
-// sort of setup.  In these cases, we can just only have illegal instructions,
-// and the mapper will create 0 length vectors, and we can check that.
-
-// In cases where we have legal instructions needed to set up the illegal
-// instruction, to check illegal instructions are assigned unsigned integers
-// from the maximum value decreasing to 0, it will be greater than a legal
-// instruction that comes after.  So to check that we have an illegal
-// instruction, we place a legal instruction after an illegal instruction, and
-// check that the illegal unsigned integer is greater than the unsigned integer
-// of the legal instruction.
-
-// Checks that an alloca instruction is mapped to be illegal.
-TEST(IRInstructionMapper, AllocaIllegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = alloca i32
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that an getelementptr instruction is mapped to be legal.  And that
-// the operands in getelementpointer instructions are the exact same after the
-// first element operand, which only requires the same type.
-TEST(IRInstructionMapper, GetElementPtrSameEndOperands) {
-  StringRef ModuleString = R"(
-    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
-    %struct.ST = type { i32, double, %struct.RT }
-    define i32 @f(%struct.ST* %s, i64 %a, i64 %b) {
-    bb0:
-       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a, i32 0
-       %1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %b, i32 0
-       ret i32 0
-    })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Check that when the operands in getelementpointer instructions are not the
-// exact same after the first element operand, the instructions are mapped to
-// different values.
-TEST(IRInstructionMapper, GetElementPtrDifferentEndOperands) {
-  StringRef ModuleString = R"(
-    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
-    %struct.ST = type { i32, double, %struct.RT }
-    define i32 @f(%struct.ST* %s, i64 %a, i64 %b) {
-    bb0:
-       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a, i32 0
-       %1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %b, i32 2
-       ret i32 0
-    })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Check that when the operands in getelementpointer instructions are not the
-// same initial base type, each instruction is mapped to a different value.
-TEST(IRInstructionMapper, GetElementPtrDifferentBaseType) {
-  StringRef ModuleString = R"(
-    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
-    %struct.ST = type { i32, double, %struct.RT }
-    define i32 @f(%struct.ST* %s, %struct.RT* %r, i64 %a, i64 %b) {
-    bb0:
-       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a
-       %1 = getelementptr inbounds %struct.RT, %struct.RT* %r, i64 %b
-       ret i32 0
-    })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Check that when the operands in getelementpointer instructions do not have
-// the same inbounds modifier, they are not counted as the same.
-TEST(IRInstructionMapper, GetElementPtrDifferentInBounds) {
-  StringRef ModuleString = R"(
-    %struct.RT = type { i8, [10 x [20 x i32]], i8 }
-    %struct.ST = type { i32, double, %struct.RT }
-    define i32 @f(%struct.ST* %s, %struct.RT* %r, i64 %a, i64 %b) {
-    bb0:
-       %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %a, i32 0
-       %1 = getelementptr %struct.ST, %struct.ST* %s, i64 %b, i32 0
-       ret i32 0
-    })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Checks that indirect call instructions are mapped to be illegal when it is
-// specified to disallow them.
-TEST(IRInstructionMapper, CallsIllegalIndirect) {
-  StringRef ModuleString = R"(
-                          define i32 @f(void()* %func) {
-                          bb0:
-                             call void %func()
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIndirectCalls = false;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that indirect call instructions are mapped to be legal when it is not
-// specified to disallow them.
-TEST(IRInstructionMapper, CallsLegalIndirect) {
-  StringRef ModuleString = R"(
-                          define i32 @f(void()* %func) {
-                          bb0:
-                             call void %func()
-                             call void %func()
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIndirectCalls = true;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-}
-
-// Checks that a call instruction is mapped to be legal.  Here we check that
-// a call with the same name, and same types are mapped to the same
-// value.
-TEST(IRInstructionMapper, CallsSameTypeSameName) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = call i32 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f1(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that a calls with different names, but the same arguments types
-// are mapped to different value when specified that the name must match.
-TEST(IRInstructionMapper, CallsSameArgTypeDifferentNameDisallowed) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          declare i32 @f2(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = call i32 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f2(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.EnableMatchCallsByName = true;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that a calls with different names, but the same arguments types
-// are mapped to the same value when it is not specifed that they must match.
-TEST(IRInstructionMapper, CallsSameArgTypeDifferentName) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          declare i32 @f2(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = call i32 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f2(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.EnableMatchCallsByName = false;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that a calls with different names, and different arguments
-// types are mapped to different value.
-TEST(IRInstructionMapper, CallsDifferentArgTypeDifferentName) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          declare i32 @f2(i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = call i32 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f2(i32 %a)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that calls with different names, and different return
-// types are mapped to different value.
-TEST(IRInstructionMapper, CallsDifferentReturnTypeDifferentName) {
-  StringRef ModuleString = R"(
-                          declare i64 @f1(i32, i32)
-                          declare i32 @f2(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = call i64 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f2(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that calls with the same name, types, and parameters map to the
-// same unsigned integer.
-TEST(IRInstructionMapper, CallsSameParameters) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = tail call fastcc i32 @f1(i32 %a, i32 %b)
-                             %1 = tail call fastcc i32 @f1(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_EQ(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that calls with different tail call settings are mapped to
-// different values.
-TEST(IRInstructionMapper, CallsDifferentTails) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = tail call i32 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f1(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Here we check that calls with different calling convention settings are
-// mapped to different values.
-TEST(IRInstructionMapper, CallsDifferentCallingConventions) {
-  StringRef ModuleString = R"(
-                          declare i32 @f1(i32, i32)
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = call fastcc i32 @f1(i32 %a, i32 %b)
-                             %1 = call i32 @f1(i32 %a, i32 %b)
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-  ASSERT_NE(UnsignedVec[0], UnsignedVec[1]);
-}
-
-// Checks that an invoke instruction is mapped to be illegal. Invoke
-// instructions are considered to be illegal because of the change in the
-// control flow that is currently not recognized.
-TEST(IRInstructionMapper, InvokeIllegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(ptr %gep1, i32 %b) {
-                          then:
-                            invoke i32 undef(ptr undef)
-                               to label %invoke unwind label %lpad
-
-                          invoke:
-                            unreachable
-
-                          lpad:
-                            landingpad { ptr, i32 }
-                               catch ptr null
-                            unreachable
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that an callbr instructions are considered to be illegal.  Callbr
-// instructions are considered to be illegal because of the change in the
-// control flow that is currently not recognized.
-TEST(IRInstructionMapper, CallBrInstIllegal) {
-  StringRef ModuleString = R"(
-  define void @test() {
-    fail:
-      ret void
-  }
-
-  define i32 @f(i32 %a, i32 %b) {
-      bb0:
-        callbr void asm "xorl $0, $0; jmp ${1:l}", "r,X,~{dirflag},~{fpsr},~{flags}"(i32 %a, ptr blockaddress(@test, %fail)) to label %normal [label %fail]
-      fail:
-        ret i32 0
-      normal:
-        ret i32 0
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that an debuginfo records are mapped to be invisible. Since they
-// do not semantically change the program, they can be recognized as similar.
-TEST(IRInstructionMapper, DebugInfoInvisible) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          then:
-                            %0 = add i32 %a, %b
-                              #dbg_value(i32 0, !0, !0, !1)
-                            %1 = add i32 %a, %b
-                            ret i32 0
-                          }
-
-                          !0 = distinct !{!"test\00", i32 10}
-                          !1 = !DILocation(line: 1, column: 1, scope: !{}))";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(3));
-}
-
-// The following are all exception handling intrinsics.  We do not currently
-// handle these instruction because they are very context dependent.
-
-// Checks that an eh.typeid.for intrinsic is mapped to be illegal.
-TEST(IRInstructionMapper, ExceptionHandlingTypeIdIllegal) {
-  StringRef ModuleString = R"(
-    @_ZTIi = external constant ptr
-    define i32 @f() {
-    then:
-      %0 = call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
-      ret i32 0
-    }
-
-    declare i32 @llvm.eh.typeid.for(ptr))";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that an eh.exceptioncode intrinsic is mapped to be illegal.
-TEST(IRInstructionMapper, ExceptionHandlingExceptionCodeIllegal) {
-  StringRef ModuleString = R"(
-    define i32 @f(i32 %a, i32 %b) {
-    entry:
-      %0 = catchswitch within none [label %__except] unwind to caller
-
-    __except:
-      %1 = catchpad within %0 [ptr null]
-      catchret from %1 to label %__except
-
-    then:
-      %2 = call i32 @llvm.eh.exceptioncode(token %1)
-      ret i32 0
-    }
-
-    declare i32 @llvm.eh.exceptioncode(token))";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that an eh.unwind intrinsic is mapped to be illegal.
-TEST(IRInstructionMapper, ExceptionHandlingUnwindIllegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          entry:
-                            call void @llvm.eh.unwind.init()
-                            ret i32 0
-                          }
-
-                          declare void @llvm.eh.unwind.init())";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that an eh.exceptionpointer intrinsic is mapped to be illegal.
-TEST(IRInstructionMapper, ExceptionHandlingExceptionPointerIllegal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          entry:
-                            %0 = call ptr @llvm.eh.exceptionpointer.p0i8(i32 0)
-                            ret i32 0
-                          }
-
-                          declare ptr @llvm.eh.exceptionpointer.p0i8(i32))";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that a catchpad instruction is mapped to an illegal value.
-TEST(IRInstructionMapper, CatchpadIllegal) {
-  StringRef ModuleString = R"(
-    declare void @llvm.donothing() nounwind readnone
-
-    define void @function() personality i8 3 {
-      entry:
-        invoke void @llvm.donothing() to label %normal unwind label %exception
-      exception:
-        %cs1 = catchswitch within none [label %catchpad1] unwind to caller
-      catchpad1:
-        catchpad within %cs1 []
-        br label %normal
-      normal:
-        ret void
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// Checks that a cleanuppad instruction is mapped to an illegal value.
-TEST(IRInstructionMapper, CleanuppadIllegal) {
-  StringRef ModuleString = R"(
-    declare void @llvm.donothing() nounwind readnone
-
-    define void @function() personality i8 3 {
-      entry:
-        invoke void @llvm.donothing() to label %normal unwind label %exception
-      exception:
-        %cs1 = catchswitch within none [label %catchpad1] unwind to caller
-      catchpad1:
-        %clean = cleanuppad within none []
-        br label %normal
-      normal:
-        ret void
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(1));
-  ASSERT_GT(UnsignedVec[0], Mapper.IllegalInstrNumber);
-}
-
-// The following three instructions are memory transfer and setting based, which
-// are considered illegal since is extra checking needed to handle the address
-// space checking.
-
-// Checks that a memset instruction is mapped to an illegal value when
-// specified.
-TEST(IRInstructionMapper, MemSetIllegal) {
-  StringRef ModuleString = R"(
-  declare void @llvm.memset.p0i8.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-
-  define i64 @function(i64 %x, i64 %z, i64 %n) {
-  entry:
-    %pool = alloca [59 x i64], align 4
-    %tmp = bitcast ptr %pool to ptr
-    call void @llvm.memset.p0i8.i64(ptr nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
-    %cmp3 = icmp eq i64 %n, 0
-    %a = add i64 %x, %z
-    %c = add i64 %x, %z
-    ret i64 0
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIntrinsics = false;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(7));
-  ASSERT_TRUE(UnsignedVec[2] < UnsignedVec[0]);
-}
-
-// Checks that a memcpy instruction is mapped to an illegal value  when
-// specified.
-TEST(IRInstructionMapper, MemCpyIllegal) {
-  StringRef ModuleString = R"(
-  declare void @llvm.memcpy.p0i8.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-
-  define i64 @function(i64 %x, i64 %z, i64 %n) {
-  entry:
-    %pool = alloca [59 x i64], align 4
-    %tmp = bitcast ptr %pool to ptr
-    call void @llvm.memcpy.p0i8.i64(ptr nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
-    %cmp3 = icmp eq i64 %n, 0
-    %a = add i64 %x, %z
-    %c = add i64 %x, %z
-    ret i64 0
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIntrinsics = false;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(7));
-  ASSERT_GT(UnsignedVec[2], UnsignedVec[3]);
-  ASSERT_LT(UnsignedVec[2], UnsignedVec[0]);
-}
-
-// Checks that a memmove instruction is mapped to an illegal value  when
-// specified.
-TEST(IRInstructionMapper, MemMoveIllegal) {
-  StringRef ModuleString = R"(
-  declare void @llvm.memmove.p0i8.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-
-  define i64 @function(i64 %x, i64 %z, i64 %n) {
-  entry:
-    %pool = alloca [59 x i64], align 4
-    %tmp = bitcast ptr  %pool to ptr
-    call void @llvm.memmove.p0i8.i64(ptr nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
-    %cmp3 = icmp eq i64 %n, 0
-    %a = add i64 %x, %z
-    %c = add i64 %x, %z
-    ret i64 0
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIntrinsics = false;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(7));
-  ASSERT_LT(UnsignedVec[2], UnsignedVec[0]);
-}
-
-// Checks that mem* instructions are mapped to an legal value when not
-// specified, and that all the intrinsics are marked differently.
-TEST(IRInstructionMapper, MemOpsLegal) {
-  StringRef ModuleString = R"(
-  declare void @llvm.memmove.p0i8.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-  declare void @llvm.memcpy.p0i8.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-  declare void @llvm.memset.p0i8.i64(ptr nocapture writeonly, i8, i64, i32, i1)
-
-  define i64 @function(i64 %x, i64 %z, i64 %n) {
-  entry:
-    %pool = alloca [59 x i64], align 4
-    %tmp = bitcast ptr %pool to ptr
-    call void @llvm.memmove.p0i8.i64(ptr nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
-    call void @llvm.memcpy.p0i8.i64(ptr nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
-    call void @llvm.memset.p0i8.i64(ptr nonnull %tmp, i8 0, i64 236, i32 4, i1 false)
-    %cmp3 = icmp eq i64 %n, 0
-    %a = add i64 %x, %z
-    %c = add i64 %x, %z
-    ret i64 0
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIntrinsics = true;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(9));
-  ASSERT_LT(UnsignedVec[2], UnsignedVec[3]);
-  ASSERT_LT(UnsignedVec[3], UnsignedVec[4]);
-  ASSERT_LT(UnsignedVec[4], UnsignedVec[5]);
-}
-
-// Checks that a variable argument instructions are mapped to an illegal value.
-// We exclude variable argument instructions since variable arguments
-// requires extra checking of the argument list.
-TEST(IRInstructionMapper, VarArgsIllegal) {
-  StringRef ModuleString = R"(
-  declare void @llvm.va_start(ptr)
-  declare void @llvm.va_copy(ptr, ptr)
-  declare void @llvm.va_end(ptr)
-
-  define i32 @func1(i32 %a, double %b, ptr %v, ...) nounwind {
-  entry:
-    %a.addr = alloca i32, align 4
-    %b.addr = alloca double, align 8
-    %ap = alloca ptr, align 4
-    %c = alloca i32, align 4
-    store i32 %a, ptr %a.addr, align 4
-    store double %b, ptr %b.addr, align 8
-    %ap1 = bitcast ptr %ap to ptr
-    call void @llvm.va_start(ptr %ap1)
-    store double %b, ptr %b.addr, align 8
-    store double %b, ptr %b.addr, align 8
-    %0 = va_arg ptr %ap, i32
-    store double %b, ptr %b.addr, align 8
-    store double %b, ptr %b.addr, align 8
-    call void @llvm.va_copy(ptr %v, ptr %ap1)
-    store double %b, ptr %b.addr, align 8
-    store double %b, ptr %b.addr, align 8
-    call void @llvm.va_end(ptr %ap1)
-    store i32 %0, ptr %c, align 4
-    %tmp = load i32, ptr %c, align 4
-    ret i32 %tmp
-  })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableIntrinsics = false;
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-  ASSERT_EQ(UnsignedVec.size(), static_cast<unsigned>(17));
-  ASSERT_TRUE(UnsignedVec[7] < UnsignedVec[0]);
-  ASSERT_TRUE(UnsignedVec[13] < UnsignedVec[10]);
-  ASSERT_TRUE(UnsignedVec[16] < UnsignedVec[13]);
-}
-
-// Check the length of adding two illegal instructions one after th other.  We
-// should find that only one element is added for each illegal range.
-TEST(IRInstructionMapper, RepeatedIllegalLength) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = mul i32 %a, %b
-                             %2 = alloca i32
-                             %3 = alloca i32
-                             %4 = add i32 %a, %b
-                             %5 = mul i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check that the size of the unsigned vector and the instruction list are the
-  // same as a safety check.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  // Make sure that the unsigned vector is the expected size.
-  ASSERT_TRUE(UnsignedVec.size() == 6);
-}
-
-// A helper function that accepts an instruction list from a module made up of
-// two blocks of two legal instructions and terminator, and checks them for
-// instruction similarity.
-static bool longSimCandCompare(std::vector<IRInstructionData *> &InstrList,
-                               bool Structure = false, unsigned Length = 2,
-                               unsigned StartIdxOne = 0,
-                               unsigned StartIdxTwo = 3) {
-  std::vector<IRInstructionData *>::iterator Start, End;
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-
-  std::advance(End, StartIdxOne + Length - 1);
-  IRSimilarityCandidate Cand1(StartIdxOne, Length, *Start, *End);
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-
-  std::advance(Start, StartIdxTwo);
-  std::advance(End, StartIdxTwo + Length - 1);
-  IRSimilarityCandidate Cand2(StartIdxTwo, Length, *Start, *End);
-  if (Structure)
-    return IRSimilarityCandidate::compareStructure(Cand1, Cand2);
-  return IRSimilarityCandidate::isSimilar(Cand1, Cand2);
-}
-
-// Checks that two adds with commuted operands are considered to be the same
-// instructions.
-TEST(IRSimilarityCandidate, CheckIdenticalInstructions) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(3));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  std::vector<IRInstructionData *>::iterator Start, End;
-  Start = InstrList.begin();
-  End = InstrList.begin();
-  std::advance(End, 1);
-  IRSimilarityCandidate Cand1(0, 2, *Start, *End);
-  IRSimilarityCandidate Cand2(0, 2, *Start, *End);
-
-  ASSERT_TRUE(IRSimilarityCandidate::isSimilar(Cand1, Cand2));
-}
-
-// Checks that comparison instructions are found to be similar instructions
-// when the operands are flipped and the predicate is also swapped.
-TEST(IRSimilarityCandidate, PredicateIsomorphism) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp sgt i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = icmp slt i32 %a, %b
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() > 5);
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  std::vector<IRInstructionData *>::iterator Start, End;
-  Start = InstrList.begin();
-  End = InstrList.begin();
-  
-  std::advance(End, 1);
-  IRSimilarityCandidate Cand1(0, 2, *Start, *End);
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-  
-  std::advance(Start, 3);
-  std::advance(End, 4);
-  IRSimilarityCandidate Cand2(3, 2, *Start, *End);
-
-  ASSERT_TRUE(IRSimilarityCandidate::isSimilar(Cand1, Cand2));
-}
-
-// Checks that IRSimilarityCandidates wrapping these two regions of instructions
-// are able to differentiate between instructions that have different opcodes.
-TEST(IRSimilarityCandidate, CheckRegionsDifferentInstruction) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = sub i32 %a, %b
-                             %3 = add i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_FALSE(longSimCandCompare(InstrList));
-}
-
-// Checks that IRSimilarityCandidates wrapping these two regions of instructions
-// are able to differentiate between instructions that have different types.
-TEST(IRSimilarityCandidate, CheckRegionsDifferentTypes) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b, i64 %c, i64 %d) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = add i64 %c, %d
-                             %3 = add i64 %d, %c
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_FALSE(longSimCandCompare(InstrList));
-}
-
-// Check that debug records do not impact similarity. They are marked as
-// invisible.
-TEST(IRSimilarityCandidate, IdenticalWithDebug) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                               #dbg_value(i32 0, !0, !0, !2)
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = add i32 %a, %b
-                               #dbg_value(i32 1, !1, !1, !2)
-                             %3 = add i32 %b, %a
-                             ret i32 0
-                          bb2:
-                             %4 = add i32 %a, %b
-                             %5 = add i32 %b, %a
-                             ret i32 0       
-                          }
-
-                          !0 = distinct !{!"test\00", i32 10}
-                          !1 = distinct !{!"test\00", i32 11}
-                          !2 = !DILocation(line: 1, column: 1, scope: !{}))";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(9));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList));
-}
-
-// Checks that IRSimilarityCandidates that include illegal instructions, are not
-// considered to be the same set of instructions.  In these sets of instructions
-// the allocas are illegal.
-TEST(IRSimilarityCandidate, IllegalInCandidate) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %a, %b
-                             %2 = alloca i32
-                             ret i32 0
-                          bb1:
-                             %3 = add i32 %a, %b
-                             %4 = add i32 %a, %b
-                             %5 = alloca i32
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  std::vector<IRInstructionData *>::iterator Start, End;
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-
-  std::advance(End, 2);
-  IRSimilarityCandidate Cand1(0, 3, *Start, *End);
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-
-  std::advance(Start, 3);
-  std::advance(End, 5);
-  IRSimilarityCandidate Cand2(3, 3, *Start, *End);
-  ASSERT_FALSE(IRSimilarityCandidate::isSimilar(Cand1, Cand2));
-}
-
-// Checks that different structure, in this case, where we introduce a new
-// needed input in one region, is recognized as different.
-TEST(IRSimilarityCandidate, DifferentStructure) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = add i32 %b, %0
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_FALSE(longSimCandCompare(InstrList, true));
-}
-
-// Checks that comparison instructions are found to have the same structure
-// when the operands are flipped and the predicate is also swapped.
-TEST(IRSimilarityCandidate, PredicateIsomorphismStructure) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp sgt i32 %a, %b
-                             %1 = add i32 %a, %b
-                             br label %bb1
-                          bb1:
-                             %2 = icmp slt i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() > 5);
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true));
-}
-
-// Checks that different predicates are counted as diferent.
-TEST(IRSimilarityCandidate, PredicateDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = icmp sge i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = icmp slt i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  ASSERT_TRUE(InstrList.size() > 5);
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_FALSE(longSimCandCompare(InstrList));
-}
-
-// Checks that the same structure is recognized between two candidates. The
-// items %a and %b are used in the same way in both sets of instructions.
-TEST(IRSimilarityCandidate, SameStructure) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = sub i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = sub i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true));
-}
-
-// Checks that the canonical numbering between two candidates matches the found
-// mapping between two candidates.
-TEST(IRSimilarityCandidate, CanonicalNumbering) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = sub i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = sub i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_EQ(InstrList.size(), UnsignedVec.size());
-
-  std::vector<IRInstructionData *>::iterator Start, End;
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-
-  std::advance(End, 1);
-  IRSimilarityCandidate Cand1(0, 2, *Start, *End);
-
-  Start = InstrList.begin();
-  End = InstrList.begin();
-
-  std::advance(Start, 3);
-  std::advance(End, 4);
-  IRSimilarityCandidate Cand2(3, 2, *Start, *End);
-  DenseMap<unsigned, DenseSet<unsigned>> Mapping1;
-  DenseMap<unsigned, DenseSet<unsigned>> Mapping2;
-  ASSERT_TRUE(IRSimilarityCandidate::compareStructure(Cand1, Cand2, Mapping1,
-                                                      Mapping2));
-  IRSimilarityCandidate::createCanonicalMappingFor(Cand1);
-  Cand2.createCanonicalRelationFrom(Cand1, Mapping1, Mapping2);
-
-  for (std::pair<unsigned, DenseSet<unsigned>> &P : Mapping2) {
-    unsigned Source = P.first;
-
-    ASSERT_TRUE(Cand2.getCanonicalNum(Source).has_value());
-    unsigned Canon = *Cand2.getCanonicalNum(Source);
-    ASSERT_TRUE(Cand1.fromCanonicalNum(Canon).has_value());
-    unsigned Dest = *Cand1.fromCanonicalNum(Canon);
-
-    DenseSet<unsigned>::iterator It = P.second.find(Dest);
-    ASSERT_NE(It, P.second.end());
-  }
-}
-
-// Checks that the same structure is recognized between two candidates. While
-// the input names are reversed, they still perform the same overall operation.
-TEST(IRSimilarityCandidate, DifferentNameSameStructure) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             ret i32 0
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(6));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true));
-}
-
-// Checks that the same structure is recognized between two candidates when
-// the branches target other blocks inside the same region, the relative
-// distance between the blocks must be the same.
-TEST(IRSimilarityCandidate, SameBranchStructureInternal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          }
-                          
-                          define i32 @f2(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(12));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true, 5, 0, 6));
-}
-
-// Checks that the different structure is recognized between two candidates,
-// when the branches target other blocks inside the same region, the relative
-// distance between the blocks must be the same.
-TEST(IRSimilarityCandidate, DifferentBranchStructureInternal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb2
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             br label %bb2
-                          bb2:
-                             %4 = add i32 %b, %a
-                             %5 = add i32 %a, %b
-                             ret i32 0
-                          }
-                          
-                          define i32 @f2(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             br label %bb2
-                          bb2:
-                             %4 = add i32 %b, %a
-                             %5 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(18));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_FALSE(longSimCandCompare(InstrList, true, 6, 0, 9));
-}
-
-// Checks that the same structure is recognized between two candidates, when
-// the branches target other blocks outside region, the relative distance
-// does not need to be the same.
-TEST(IRSimilarityCandidate, SameBranchStructureOutside) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          }
-                          
-                          define i32 @f2(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(12));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true, 3, 0, 6));
-}
-
-// Checks that the same structure is recognized between two candidates, when
-// the branches target other blocks outside region, the relative distance
-// does not need to be the same.
-TEST(IRSimilarityCandidate, DifferentBranchStructureOutside) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          }
-                          
-                          define i32 @f2(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb2
-                          bb1:
-                             %2 = add i32 %b, %a
-                             %3 = add i32 %a, %b
-                             br label %bb2
-                          bb2:
-                             %4 = add i32 %b, %a
-                             %5 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(15));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true, 3, 0, 6));
-}
-
-// Checks that the same structure is recognized between two candidates,
-// when the phi predecessor are other blocks inside the same region,
-// the relative distance between the blocks must be the same.
-TEST(IRSimilarityCandidate, SamePHIStructureInternal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             br label %bb2
-                          bb1:
-                             br label %bb2
-                          bb2:
-                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb1 ] 
-                             %1 = add i32 %b, %a
-                             %2 = add i32 %a, %b
-                             ret i32 0
-                          }
-                          
-                          define i32 @f2(i32 %a, i32 %b) {
-                          bb0:
-                             br label %bb2
-                          bb1:
-                             br label %bb2
-                          bb2:
-                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb1 ]
-                             %1 = add i32 %b, %a
-                             %2 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(12));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_TRUE(longSimCandCompare(InstrList, true, 4, 0, 6));
-}
-
-// Checks that the different structure is recognized between two candidates,
-// when the phi predecessor are other blocks inside the same region,
-// the relative distance between the blocks must be the same.
-TEST(IRSimilarityCandidate, DifferentPHIStructureInternal) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             br label %bb2
-                          bb1:
-                             br label %bb2
-                          bb3:
-                             br label %bb2
-                          bb2:
-                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb1 ] 
-                             %1 = add i32 %b, %a
-                             %2 = add i32 %a, %b
-                             ret i32 0
-                          }
-                          
-                          define i32 @f2(i32 %a, i32 %b) {
-                          bb0:
-                             br label %bb2
-                          bb1:
-                             br label %bb2
-                          bb3:
-                             br label %bb2
-                          bb2:
-                             %0 = phi i32 [ %a, %bb0 ], [ %b, %bb3 ] 
-                             %1 = add i32 %b, %a
-                             %2 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<IRInstructionData *> InstrList;
-  std::vector<unsigned> UnsignedVec;
-
-  SpecificBumpPtrAllocator<IRInstructionData> InstDataAllocator;
-  SpecificBumpPtrAllocator<IRInstructionDataList> IDLAllocator;
-  IRInstructionMapper Mapper(&InstDataAllocator, &IDLAllocator);
-  Mapper.InstClassifier.EnableBranches = true;
-  Mapper.initializeForBBs(*M);
-  getVectors(*M, Mapper, InstrList, UnsignedVec);
-
-  // Check to make sure that we have a long enough region.
-  ASSERT_EQ(InstrList.size(), static_cast<unsigned>(14));
-  // Check that the instructions were added correctly to both vectors.
-  ASSERT_TRUE(InstrList.size() == UnsignedVec.size());
-
-  ASSERT_FALSE(longSimCandCompare(InstrList, true, 5, 0, 7));
-}
-
-// Checks that two sets of identical instructions are found to be the same.
-// Both sequences of adds have the same operand ordering, and the same
-// instructions, making them strcturally equivalent.
-TEST(IRSimilarityIdentifier, IdentitySimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = sub i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = sub i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 1);
-  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
-    ASSERT_TRUE(Cands.size() == 2);
-    unsigned InstIdx = 0;
-    for (IRSimilarityCandidate &Cand : Cands) {
-      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
-      InstIdx += 3;
-    }
-  }
-}
-
-// Checks that incorrect sequences are not found as similar.  In this case,
-// we have different sequences of instructions.
-TEST(IRSimilarityIdentifier, InstructionDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) {
-                          bb0:
-                             %0 = sub i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %c, %d
-                             %3 = sub i32 %d, %c
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.empty());
-}
-
-// This test checks to see whether we can detect similarity for commutative
-// instructions where the operands have been reversed.
-TEST(IRSimilarityIdentifier, CommutativeSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = add i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 1);
-  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
-    ASSERT_TRUE(Cands.size() == 2);
-    unsigned InstIdx = 0;
-    for (IRSimilarityCandidate &Cand : Cands) {
-      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
-      InstIdx += 3;
-    }
-  }
-}
-
-// This test ensures that when the first instruction in a sequence is
-// a commutative instruction with the same value (mcomm_inst_same_val), but the
-// corresponding instruction (comm_inst_diff_val) is not, we mark the regions
-// and not similar.
-TEST(IRSimilarityIdentifier, CommutativeSameValueFirstMisMatch) {
-  StringRef ModuleString = R"(
-                          define void @v_1_0(i64 %v_33) {
-                            entry:
-                              %comm_inst_same_val = mul i64 undef, undef
-                              %add = add i64 %comm_inst_same_val, %v_33
-                              %comm_inst_diff_val = mul i64 0, undef
-                              %mul.i = add i64 %comm_inst_diff_val, %comm_inst_diff_val
-                              unreachable
-                            })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 0);
-}
-
-// This test makes sure that intrinsic functions that are marked commutative
-// are still treated as non-commutative since they are function calls.
-TEST(IRSimilarityIdentifier, IntrinsicCommutative) {
-  // If treated as commutative, we will fail to find a valid mapping, causing
-  // an assertion error.
-  StringRef ModuleString = R"(
-  define void @foo() {
-    entry:
-      %0 = call i16 @llvm.smul.fix.i16(i16 16384, i16 16384, i32 15)
-      store i16 %0, i16* undef, align 1
-      %1 = icmp eq i16 undef, 8192
-      call void @bar()
-      %2 = call i16 @llvm.smul.fix.i16(i16 -16384, i16 16384, i32 15)
-      store i16 %2, i16* undef, align 1
-      %3 = icmp eq i16 undef, -8192
-      call void @bar()
-      %4 = call i16 @llvm.smul.fix.i16(i16 -16384, i16 -16384, i32 15)
-      ret void
-  }
-
-  declare void @bar()
-
-  ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn
-  declare i16 @llvm.smul.fix.i16(i16, i16, i32 immarg))";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 0);
-}
-
-// This test checks to see whether we can detect different structure in
-// commutative instructions.  In this case, the second operand in the second
-// add is different.
-TEST(IRSimilarityIdentifier, NoCommutativeSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = add i32 %1, %b
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = add i32 %2, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 0);
-}
-
-// Check that we are not finding similarity in non commutative
-// instructions.  That is, while the instruction and operands used are the same
-// in the two subtraction sequences, they are in a different order, and cannot
-// be counted as the same since a subtraction is not commutative.
-TEST(IRSimilarityIdentifier, NonCommutativeDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = sub i32 %a, %b
-                             %1 = sub i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = sub i32 %a, %b
-                             %3 = sub i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.empty());
-}
-
-// Check that we find similarity despite changing the register names.
-TEST(IRSimilarityIdentifier, MappingSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b, i32 %c, i32 %d) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = sub i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %c, %d
-                             %3 = sub i32 %d, %c
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 1);
-  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
-    ASSERT_TRUE(Cands.size() == 2);
-    unsigned InstIdx = 0;
-    for (IRSimilarityCandidate &Cand : Cands) {
-      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
-      InstIdx += 3;
-    }
-  }
-}
-
-// Check that we find instances of swapped predicate isomorphism.  That is,
-// for predicates that can be flipped, e.g. greater than to less than,
-// we can identify that instances of these different literal predicates, but are
-// the same within a single swap can be found.
-TEST(IRSimilarityIdentifier, PredicateIsomorphism) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 %a, %b
-                             %1 = icmp sgt i32 %b, %a
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = icmp slt i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 1);
-  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
-    ASSERT_TRUE(Cands.size() == 2);
-    unsigned InstIdx = 0;
-    for (IRSimilarityCandidate &Cand : Cands) {
-      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
-      InstIdx += 3;
-    }
-  }
-}
-
-// Checks that constants are detected as the same operand in each use in the
-// sequences of instructions.  Also checks that we can find structural
-// equivalence using constants.  In this case the 1 has the same use pattern as
-// %a.
-TEST(IRSimilarityIdentifier, ConstantMappingSimilarity) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 1, %b
-                             %1 = icmp sgt i32 %b, 1
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = icmp sgt i32 %b, %a
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.size() == 1);
-  for (std::vector<IRSimilarityCandidate> &Cands : SimilarityCandidates) {
-    ASSERT_TRUE(Cands.size() == 2);
-    unsigned InstIdx = 0;
-    for (IRSimilarityCandidate &Cand : Cands) {
-      ASSERT_TRUE(Cand.getStartIdx() == InstIdx);
-      InstIdx += 3;
-    }
-  }
-}
-
-// Check that constants are uniquely identified. i.e. two different constants
-// are not considered the same.  This means that this should not find any
-// structural similarity.
-TEST(IRSimilarityIdentifier, ConstantMappingDifference) {
-  StringRef ModuleString = R"(
-                          define i32 @f(i32 %a, i32 %b) {
-                          bb0:
-                             %0 = add i32 1, %b
-                             %1 = icmp sgt i32 %b, 2
-                             br label %bb1
-                          bb1:
-                             %2 = add i32 %a, %b
-                             %3 = icmp slt i32 %a, %b
-                             ret i32 0
-                          })";
-  LLVMContext Context;
-  std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
-
-  std::vector<std::vector<IRSimilarityCandidate>> SimilarityCandidates;
-  getSimilarities(*M, SimilarityCandidates);
-
-  ASSERT_TRUE(SimilarityCandidates.empty());
-}
diff --git a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
index 4c237ddfed396..d113cf118c8f2 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Analysis/BUILD.gn
@@ -64,7 +64,6 @@ static_library("Analysis") {
     "HashRecognize.cpp",
     "HeatUtils.cpp",
     "IR2Vec.cpp",
-    "IRSimilarityIdentifier.cpp",
     "IVDescriptors.cpp",
     "IVUsers.cpp",
     "ImportedFunctionsInliningStatistics.cpp",
diff --git a/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
index 1d82db40802d7..fec29861eedcb 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Transforms/IPO/BUILD.gn
@@ -58,7 +58,6 @@ static_library("IPO") {
     "GlobalSplit.cpp",
     "HotColdSplitting.cpp",
     "IPO.cpp",
-    "IROutliner.cpp",
     "InferFunctionAttrs.cpp",
     "Inliner.cpp",
     "Instrumentor.cpp",
diff --git a/llvm/utils/gn/secondary/llvm/test/BUILD.gn b/llvm/utils/gn/secondary/llvm/test/BUILD.gn
index d1767feaedc5c..cbc4f28bbaf65 100644
--- a/llvm/utils/gn/secondary/llvm/test/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/test/BUILD.gn
@@ -329,7 +329,6 @@ group("test") {
     "//llvm/tools/llvm-reduce",
     "//llvm/tools/llvm-remarkutil",
     "//llvm/tools/llvm-rtdyld",
-    "//llvm/tools/llvm-sim",
     "//llvm/tools/llvm-size",
     "//llvm/tools/llvm-split",
     "//llvm/tools/llvm-stress",
diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn
deleted file mode 100644
index a391c0e1c2fcd..0000000000000
--- a/llvm/utils/gn/secondary/llvm/tools/llvm-sim/BUILD.gn
+++ /dev/null
@@ -1,8 +0,0 @@
-executable("llvm-sim") {
-  deps = [
-    "//llvm/lib/Analysis",
-    "//llvm/lib/IRReader",
-    "//llvm/lib/Support",
-  ]
-  sources = [ "llvm-sim.cpp" ]
-}
diff --git a/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
index 51a1f3a78eee0..5e41310d16ce5 100644
--- a/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/unittests/Analysis/BUILD.gn
@@ -33,7 +33,6 @@ unittest("AnalysisTests") {
     "GlobalsModRefTest.cpp",
     "GraphWriterTest.cpp",
     "IR2VecTest.cpp",
-    "IRSimilarityIdentifierTest.cpp",
     "IVDescriptorsTest.cpp",
     "InlineCostTest.cpp",
     "LastRunTrackingAnalysisTest.cpp",
diff --git a/llvm/utils/profcheck-xfail.txt b/llvm/utils/profcheck-xfail.txt
index 2d80881a847a9..0e90386d0ffd3 100644
--- a/llvm/utils/profcheck-xfail.txt
+++ b/llvm/utils/profcheck-xfail.txt
@@ -4,7 +4,6 @@ CodeGen/WinEH/wineh-scope-statenumbering.ll
 CodeGen/WinEH/wineh-setjmp.ll
 CodeGen/WinEH/wineh-statenumbering-cleanups.ll
 CodeGen/WinEH/wineh-statenumbering.ll
-DebugInfo/AArch64/ir-outliner.ll
 DebugInfo/Generic/block-asan.ll
 Transforms/AtomicExpand/ARM/atomic-expansion-v7.ll
 Transforms/CrossDSOCFI/basic.ll
diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
index 3a591dad25570..940998fea0261 100644
--- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel
@@ -6965,23 +6965,6 @@ cc_binary(
     ],
 )
 
-cc_binary(
-    name = "llvm-sim",
-    testonly = True,
-    srcs = glob([
-        "tools/llvm-sim/*.cpp",
-    ]),
-    copts = llvm_copts,
-    stamp = 0,
-    deps = [
-        ":Analysis",
-        ":Core",
-        ":IRReader",
-        ":Support",
-        ":config",
-    ],
-)
-
 cc_binary(
     name = "llvm-ir2vec",
     testonly = True,

>From 245add0dc7da71393600b0e91704dad4eb926831 Mon Sep 17 00:00:00 2001
From: Simon Pilgrim <llvm-dev at redking.me.uk>
Date: Fri, 31 Jul 2026 23:17:07 +0100
Subject: [PATCH 33/43] [X86] getTargetConstantBitsFromNode - ensure constant
 data is from a vector type (#213360)

Fixes #213251
---
 llvm/lib/Target/X86/X86ISelLowering.cpp       | 32 +++++-----
 .../CodeGen/X86/vector-shuffle-combining.ll   | 60 ++++++++++++++++++-
 2 files changed, 75 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index c78af72f11d0a..44c847565cb69 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -5497,21 +5497,23 @@ static bool getTargetConstantBitsFromNode(SDValue Op, unsigned EltSizeInBits,
     }
     if (auto *CDS = dyn_cast<ConstantDataSequential>(Cst)) {
       Type *Ty = CDS->getType();
-      Mask = APInt::getZero(Ty->getPrimitiveSizeInBits());
-      Type *EltTy = CDS->getElementType();
-      bool IsInteger = EltTy->isIntegerTy();
-      bool IsFP =
-          EltTy->isHalfTy() || EltTy->isFloatTy() || EltTy->isDoubleTy();
-      if (!IsInteger && !IsFP)
-        return false;
-      unsigned EltBits = EltTy->getPrimitiveSizeInBits();
-      for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I)
-        if (IsInteger)
-          Mask.insertBits(CDS->getElementAsAPInt(I), I * EltBits);
-        else
-          Mask.insertBits(CDS->getElementAsAPFloat(I).bitcastToAPInt(),
-                          I * EltBits);
-      return true;
+      if (Ty->isVectorTy()) {
+        Mask = APInt::getZero(Ty->getPrimitiveSizeInBits());
+        Type *EltTy = CDS->getElementType();
+        bool IsInteger = EltTy->isIntegerTy();
+        bool IsFP =
+            EltTy->isHalfTy() || EltTy->isFloatTy() || EltTy->isDoubleTy();
+        if (!IsInteger && !IsFP)
+          return false;
+        unsigned EltBits = EltTy->getPrimitiveSizeInBits();
+        for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I)
+          if (IsInteger)
+            Mask.insertBits(CDS->getElementAsAPInt(I), I * EltBits);
+          else
+            Mask.insertBits(CDS->getElementAsAPFloat(I).bitcastToAPInt(),
+                            I * EltBits);
+        return true;
+      }
     }
     return false;
   };
diff --git a/llvm/test/CodeGen/X86/vector-shuffle-combining.ll b/llvm/test/CodeGen/X86/vector-shuffle-combining.ll
index 4e68a259a075b..b0667cb7bbb5c 100644
--- a/llvm/test/CodeGen/X86/vector-shuffle-combining.ll
+++ b/llvm/test/CodeGen/X86/vector-shuffle-combining.ll
@@ -3621,6 +3621,62 @@ define <2 x i1> @PR179112(<2 x i32> %load) {
   ret <2 x i1> %reverse.2
 }
 
+define <8 x float> @PR213251() {
+; SSE2-LABEL: PR213251:
+; SSE2:       # %bb.0:
+; SSE2-NEXT:    movl $1, (%rax)
+; SSE2-NEXT:    movd {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
+; SSE2-NEXT:    movq {{.*#+}} xmm0 = xmm0[0],zero
+; SSE2-NEXT:    xorps %xmm1, %xmm1
+; SSE2-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
+; SSE2-NEXT:    retq
+;
+; SSSE3-LABEL: PR213251:
+; SSSE3:       # %bb.0:
+; SSSE3-NEXT:    movl $1, (%rax)
+; SSSE3-NEXT:    movd {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
+; SSSE3-NEXT:    movq {{.*#+}} xmm0 = xmm0[0],zero
+; SSSE3-NEXT:    xorps %xmm1, %xmm1
+; SSSE3-NEXT:    shufps {{.*#+}} xmm0 = xmm0[2,0],xmm1[2,3]
+; SSSE3-NEXT:    retq
+;
+; SSE41-LABEL: PR213251:
+; SSE41:       # %bb.0:
+; SSE41-NEXT:    movl $1, (%rax)
+; SSE41-NEXT:    insertps {{.*#+}} xmm0 = zero,mem[0],zero,zero
+; SSE41-NEXT:    xorps %xmm1, %xmm1
+; SSE41-NEXT:    retq
+;
+; AVX1-LABEL: PR213251:
+; AVX1:       # %bb.0:
+; AVX1-NEXT:    movl $1, (%rax)
+; AVX1-NEXT:    vbroadcastss {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; AVX1-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; AVX1-NEXT:    vblendps {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3,4,5,6,7]
+; AVX1-NEXT:    retq
+;
+; AVX2-SLOW-LABEL: PR213251:
+; AVX2-SLOW:       # %bb.0:
+; AVX2-SLOW-NEXT:    movl $1, (%rax)
+; AVX2-SLOW-NEXT:    vbroadcastss {{.*#+}} xmm0 = [NaN,NaN,NaN,NaN]
+; AVX2-SLOW-NEXT:    vxorps %xmm1, %xmm1, %xmm1
+; AVX2-SLOW-NEXT:    vblendps {{.*#+}} ymm0 = ymm1[0],ymm0[1],ymm1[2,3,4,5,6,7]
+; AVX2-SLOW-NEXT:    retq
+;
+; AVX2-FAST-LABEL: PR213251:
+; AVX2-FAST:       # %bb.0:
+; AVX2-FAST-NEXT:    movl $1, (%rax)
+; AVX2-FAST-NEXT:    vmovd {{.*#+}} xmm0 = [NaN,0.0E+0,0.0E+0,0.0E+0]
+; AVX2-FAST-NEXT:    vpshufb {{.*#+}} ymm0 = zero,zero,zero,zero,ymm0[0,1,2,3],zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero,zero
+; AVX2-FAST-NEXT:    retq
+  store i32 1, ptr poison, align 4
+  %f.promoted = load i32, ptr poison, align 4
+  %tobool.not12 = icmp eq i32 %f.promoted, 0
+  %cond13 = select i1 %tobool.not12, float 1.000000e+00, float +qnan
+  %vecins14 = insertelement <8 x float> zeroinitializer, float %cond13, i64 1
+  ret <8 x float> %vecins14
+}
+
 ; Test case reported on D105827
 define void @SpinningCube() {
 ; SSE2-LABEL: SpinningCube:
@@ -3722,9 +3778,9 @@ define void @autogen_SD25931() {
 ; CHECK-LABEL: autogen_SD25931:
 ; CHECK:       # %bb.0: # %BB
 ; CHECK-NEXT:    .p2align 4
-; CHECK-NEXT:  .LBB144_1: # %CF242
+; CHECK-NEXT:  .LBB145_1: # %CF242
 ; CHECK-NEXT:    # =>This Inner Loop Header: Depth=1
-; CHECK-NEXT:    jmp .LBB144_1
+; CHECK-NEXT:    jmp .LBB145_1
 BB:
   %Cmp16 = icmp uge <2 x i1> zeroinitializer, zeroinitializer
   %Shuff19 = shufflevector <2 x i1> zeroinitializer, <2 x i1> %Cmp16, <2 x i32> <i32 3, i32 1>

>From 15cf68db14bbe9f6c90b0d7e76a0047b1b75104d Mon Sep 17 00:00:00 2001
From: "Moazin K." <mkhatti at nvidia.com>
Date: Fri, 31 Jul 2026 15:21:46 -0700
Subject: [PATCH 34/43] [OpenACC][NFC] Minor clean up in ACCRoutineLowering.
 (#213333)

Minor NFC clean up after recent changes to remove nohost handling from
ACCRoutineLowering.

Assisted-by: Codex
---
 .../OpenACC/Transforms/ACCRoutineLowering.cpp | 20 ++++++++-----------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/mlir/lib/Dialect/OpenACC/Transforms/ACCRoutineLowering.cpp b/mlir/lib/Dialect/OpenACC/Transforms/ACCRoutineLowering.cpp
index d082ef8be3d17..9d5f0fc434d7e 100644
--- a/mlir/lib/Dialect/OpenACC/Transforms/ACCRoutineLowering.cpp
+++ b/mlir/lib/Dialect/OpenACC/Transforms/ACCRoutineLowering.cpp
@@ -168,15 +168,13 @@ buildRoutineBody(func::FuncOp deviceFunc, func::FuncOp hostFunc,
 }
 
 /// Update acc.routine refs
-static LogicalResult finalizeRoutines(
-    SmallVectorImpl<std::tuple<func::FuncOp, func::FuncOp, RoutineOp>>
-        &accRoutineInfo,
-    ModuleOp mod, MLIRContext *ctx) {
-  for (auto &[hostFunc, deviceFunc, routineOp] : accRoutineInfo) {
+static void finalizeRoutines(
+    SmallVectorImpl<std::pair<func::FuncOp, RoutineOp>> &accRoutineInfo,
+    MLIRContext *ctx) {
+  for (auto &[deviceFunc, routineOp] : accRoutineInfo) {
     routineOp.setFuncNameAttr(SymbolRefAttr::get(ctx, deviceFunc.getName()));
     routineOp->moveBefore(deviceFunc);
   }
-  return success();
 }
 
 class ACCRoutineLowering
@@ -197,9 +195,8 @@ class ACCRoutineLowering
     IRRewriter rewriter(ctx);
     DefaultACCToGPUMappingPolicy policy;
 
-    // Tuple: host function, device function, routine operation
-    SmallVector<std::tuple<func::FuncOp, func::FuncOp, RoutineOp>, 4>
-        accRoutineInfo;
+    // Pair: device function, routine operation
+    SmallVector<std::pair<func::FuncOp, RoutineOp>, 4> accRoutineInfo;
 
     for (RoutineOp routineOp : mod.getOps<RoutineOp>()) {
       if (routineOp.getBindNameValue() ||
@@ -226,12 +223,11 @@ class ACCRoutineLowering
                                   parLevel, policy, rewriter)))
         return signalPassFailure();
 
-      accRoutineInfo.push_back({hostFunc, deviceFunc, routineOp});
+      accRoutineInfo.push_back({deviceFunc, routineOp});
       symTab.insert(deviceFunc);
     }
 
-    if (failed(finalizeRoutines(accRoutineInfo, mod, ctx)))
-      return signalPassFailure();
+    finalizeRoutines(accRoutineInfo, ctx);
   }
 };
 

>From 5b98324aa8108394ca79647eece868cc7d463275 Mon Sep 17 00:00:00 2001
From: Thurston Dang <thurston at google.com>
Date: Fri, 31 Jul 2026 15:28:13 -0700
Subject: [PATCH 35/43] [DropAssumes] Print drop-deref in pipeline where
 appropriate (#211905)

drop-deref was added as an option in #166947 and is parsed correctly,
but is not serialized. This can make it difficult to reduce test cases,
especially automatically with llvm/utils/reduce_pipeline.py.

This patch implements printPipeline() to serialize drop-deref where
appropriate.
---
 .../llvm/Transforms/Scalar/DropUnnecessaryAssumes.h       | 3 +++
 llvm/lib/Transforms/Scalar/DropUnnecessaryAssumes.cpp     | 8 ++++++++
 llvm/test/Other/new-pm-print-pipeline.ll                  | 3 +++
 3 files changed, 14 insertions(+)

diff --git a/llvm/include/llvm/Transforms/Scalar/DropUnnecessaryAssumes.h b/llvm/include/llvm/Transforms/Scalar/DropUnnecessaryAssumes.h
index e77fb437cf3ff..6b7e82276073f 100644
--- a/llvm/include/llvm/Transforms/Scalar/DropUnnecessaryAssumes.h
+++ b/llvm/include/llvm/Transforms/Scalar/DropUnnecessaryAssumes.h
@@ -23,6 +23,9 @@ struct DropUnnecessaryAssumesPass
       : DropDereferenceable(DropDereferenceable) {}
 
   LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+  LLVM_ABI void
+  printPipeline(raw_ostream &OS,
+                function_ref<StringRef(StringRef)> MapClassName2PassName);
 
 private:
   bool DropDereferenceable;
diff --git a/llvm/lib/Transforms/Scalar/DropUnnecessaryAssumes.cpp b/llvm/lib/Transforms/Scalar/DropUnnecessaryAssumes.cpp
index f1192db7538ac..d23dfb9331db3 100644
--- a/llvm/lib/Transforms/Scalar/DropUnnecessaryAssumes.cpp
+++ b/llvm/lib/Transforms/Scalar/DropUnnecessaryAssumes.cpp
@@ -152,3 +152,11 @@ DropUnnecessaryAssumesPass::run(Function &F, FunctionAnalysisManager &FAM) {
   }
   return PreservedAnalyses::all();
 }
+
+void DropUnnecessaryAssumesPass::printPipeline(
+    raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
+  static_cast<PassInfoMixin<DropUnnecessaryAssumesPass> *>(this)->printPipeline(
+      OS, MapClassName2PassName);
+  if (DropDereferenceable)
+    OS << "<drop-deref>";
+}
diff --git a/llvm/test/Other/new-pm-print-pipeline.ll b/llvm/test/Other/new-pm-print-pipeline.ll
index 2aaf7f182f9e1..110ff23131667 100644
--- a/llvm/test/Other/new-pm-print-pipeline.ll
+++ b/llvm/test/Other/new-pm-print-pipeline.ll
@@ -123,3 +123,6 @@
 
 ; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='module(asan<>,asan<kernel;use-after-scope>)' < %s | FileCheck %s --match-full-lines --check-prefixes=CHECK-37
 ; CHECK-37: asan<>,asan<kernel;use-after-scope>
+
+; RUN: opt -disable-output -disable-verify -print-pipeline-passes -passes='drop-unnecessary-assumes,drop-unnecessary-assumes<drop-deref>' < %s | FileCheck %s --check-prefixes=CHECK-38
+; CHECK-38: drop-unnecessary-assumes,drop-unnecessary-assumes<drop-deref>

>From 8cfce9a066716e14b8bd318927b614b87b18dcaa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Valentin=20Clement=20=28=E3=83=90=E3=83=AC=E3=83=B3?=
 =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=B3=20=E3=82=AF=E3=83=AC=E3=83=A1?=
 =?UTF-8?q?=E3=83=B3=29?= <clementval at gmail.com>
Date: Fri, 31 Jul 2026 16:02:09 -0700
Subject: [PATCH 36/43] [flang][NFC] Rename modfile84.f90 to modfile85.f90
 (#213371)

Avoid clash on case insensitive system
---
 flang/test/Semantics/{modfile84.f90 => modfile85.f90} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename flang/test/Semantics/{modfile84.f90 => modfile85.f90} (100%)

diff --git a/flang/test/Semantics/modfile84.f90 b/flang/test/Semantics/modfile85.f90
similarity index 100%
rename from flang/test/Semantics/modfile84.f90
rename to flang/test/Semantics/modfile85.f90

>From 2572ba033db759ce07d56bf2e2a599be347b5a2a Mon Sep 17 00:00:00 2001
From: Ayokunle Amodu <ayokunle321 at gmail.com>
Date: Fri, 31 Jul 2026 19:18:49 -0400
Subject: [PATCH 37/43] [CIR][AMDGPU] Add support for AMDGCN ldexp builtins
 (#198087)

Adds support for the following AMDGCN ldexp builtins:

- __builtin_amdgcn_ldexp (double)
- __builtin_amdgcn_ldexpf (float)
- __builtin_amdgcn_ldexph (half)

These are lowered to the `llvm.ldexp` intrinsic.
---
 clang/lib/CIR/CodeGen/CIRGenBuiltinAMDGPU.cpp  | 18 ++++++++++++++----
 .../CIR/CodeGenHIP/builtins-amdgcn-vi-f16.hip  | 10 ++++++++++
 clang/test/CIR/CodeGenHIP/builtins-amdgcn.hip  | 16 ++++++++++++++++
 3 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltinAMDGPU.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltinAMDGPU.cpp
index 861ec451e2bc0..e2a1c2b94dec4 100644
--- a/clang/lib/CIR/CodeGen/CIRGenBuiltinAMDGPU.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenBuiltinAMDGPU.cpp
@@ -296,10 +296,20 @@ CIRGenFunction::emitAMDGPUBuiltinExpr(unsigned builtinId,
   case AMDGPU::BI__builtin_amdgcn_ldexp:
   case AMDGPU::BI__builtin_amdgcn_ldexpf:
   case AMDGPU::BI__builtin_amdgcn_ldexph: {
-    cgm.errorNYI(expr->getSourceRange(),
-                 std::string("unimplemented AMDGPU builtin call: ") +
-                     getContext().BuiltinInfo.getName(builtinId));
-    return mlir::Value{};
+    mlir::Value src0 = emitScalarExpr(expr->getArg(0));
+    mlir::Value src1 = emitScalarExpr(expr->getArg(1));
+    // For ldexph, the raw instruction has different behavior for out-of-bounds
+    // exponent values (implicit truncation instead of saturate to
+    // short_min/short_max), so truncate the exponent to i16 first.
+    mlir::Value exp =
+        builtinId == AMDGPU::BI__builtin_amdgcn_ldexph
+            ? cir::CastOp::create(builder, getLoc(expr->getExprLoc()),
+                                  builder.getSInt16Ty(),
+                                  cir::CastKind::integral, src1)
+            : src1;
+    return builder.emitIntrinsicCallOp(getLoc(expr->getExprLoc()), "ldexp",
+                                       src0.getType(),
+                                       mlir::ValueRange{src0, exp});
   }
   case AMDGPU::BI__builtin_amdgcn_frexp_mant:
   case AMDGPU::BI__builtin_amdgcn_frexp_mantf:
diff --git a/clang/test/CIR/CodeGenHIP/builtins-amdgcn-vi-f16.hip b/clang/test/CIR/CodeGenHIP/builtins-amdgcn-vi-f16.hip
index 11a97c9befa9d..e298056ab6d9d 100644
--- a/clang/test/CIR/CodeGenHIP/builtins-amdgcn-vi-f16.hip
+++ b/clang/test/CIR/CodeGenHIP/builtins-amdgcn-vi-f16.hip
@@ -111,3 +111,13 @@ __device__ void test_cos_f16(_Float16* out, _Float16 a) {
 __device__ void test_frexp_mant_f16(_Float16* out, _Float16 a) {
   *out = __builtin_amdgcn_frexp_manth(a);
 }
+
+// CIR-LABEL: @_Z14test_ldexp_f16PDF16_DF16_i
+// CIR: [[TRUNC:%.*]] = cir.cast integral {{.*}} : !s32i -> !s16i
+// CIR: cir.call_llvm_intrinsic "ldexp" {{.*}}, [[TRUNC]] : (!cir.f16, !s16i) -> !cir.f16
+// LLVM: define{{.*}} void @_Z14test_ldexp_f16PDF16_DF16_i
+// LLVM: [[TRUNC:%.*]] = trunc i32 {{.*}} to i16
+// LLVM: call{{.*}} half @llvm.ldexp.f16.i16(half %{{.*}}, i16 [[TRUNC]])
+__device__ void test_ldexp_f16(_Float16* out, _Float16 a, int b) {
+    *out = __builtin_amdgcn_ldexph(a, b);
+}
diff --git a/clang/test/CIR/CodeGenHIP/builtins-amdgcn.hip b/clang/test/CIR/CodeGenHIP/builtins-amdgcn.hip
index 759f981f3fa12..8ba5a354cfefa 100644
--- a/clang/test/CIR/CodeGenHIP/builtins-amdgcn.hip
+++ b/clang/test/CIR/CodeGenHIP/builtins-amdgcn.hip
@@ -239,3 +239,19 @@ __device__ void test_trig_preop_f32(float* out, float a, int b) {
 __device__ void test_trig_preop_f64(double* out, double a, int b) {
   *out = __builtin_amdgcn_trig_preop(a, b);
 }
+
+// CIR-LABEL: @_Z14test_ldexp_f32Pffi
+// CIR: cir.call_llvm_intrinsic "ldexp" {{.*}} : (!cir.float, !s32i) -> !cir.float
+// LLVM: define{{.*}} void @_Z14test_ldexp_f32Pffi
+// LLVM: call{{.*}} float @llvm.ldexp.f32.i32(float %{{.*}}, i32 %{{.*}})
+__device__ void test_ldexp_f32(float* out, float a, int b) {
+  *out = __builtin_amdgcn_ldexpf(a, b);
+}
+
+// CIR-LABEL: @_Z14test_ldexp_f64Pddi
+// CIR: cir.call_llvm_intrinsic "ldexp" {{.*}} : (!cir.double, !s32i) -> !cir.double
+// LLVM: define{{.*}} void @_Z14test_ldexp_f64Pddi
+// LLVM: call{{.*}} double @llvm.ldexp.f64.i32(double %{{.*}}, i32 %{{.*}})
+__device__ void test_ldexp_f64(double* out, double a, int b) {
+  *out = __builtin_amdgcn_ldexp(a, b);
+}

>From 24c801c69f6fe5cbada1eb4548886e861e08ae05 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 16:32:37 -0700
Subject: [PATCH 38/43] workflows/llvm-abi-tests: Cache the baseline abi
 (#211968)

This way we don't need to recompute it for every workflow.
---
 .github/workflows/llvm-abi-tests.yml | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/.github/workflows/llvm-abi-tests.yml b/.github/workflows/llvm-abi-tests.yml
index ebd5037998b98..70175b0f39163 100644
--- a/.github/workflows/llvm-abi-tests.yml
+++ b/.github/workflows/llvm-abi-tests.yml
@@ -93,23 +93,37 @@ jobs:
             ref: ${{ github.sha }}
             repo: ${{ github.repository }}
     steps:
+      - name: Check for cached baseline ABI
+        if: ${{ matrix.name == 'build-baseline' }}
+        id: cache
+        uses: actions/cache/restore at 55cc8345863c7cc4c66a329aec7e433d2d1c52a9 #v6.1.0
+        with:
+          key: ${{ matrix.ref}}.abi
+          path: |
+            ${{ matrix.ref }}.abi
+            llvm.symbols
+
       - name: Download source code
         uses: actions/checkout at df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
+        if: steps.cache.outputs.cache-hit != 'true'
         with:
           persist-credentials: false
           ref: ${{ matrix.ref }}
           repository: ${{ matrix.repo }}
       - name: Configure
+        if: steps.cache.outputs.cache-hit != 'true'
         run: |
           mkdir install
           cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DLLVM_TARGETS_TO_BUILD="" -DLLVM_BUILD_LLVM_DYLIB=ON -DCMAKE_INSTALL_PREFIX="$(pwd)"/install llvm
       - name: Build
+        if: steps.cache.outputs.cache-hit != 'true'
         # Need to run install-LLVM twice to ensure the symlink is installed (this is a bug).
         run: |
           ninja -C build install-LLVM
           ninja -C build install-LLVM
           ninja -C build install-llvm-headers
       - name: Dump ABI
+        if: steps.cache.outputs.cache-hit != 'true'
         env:
           REF: ${{ matrix.ref }}
           ABI_HEADERS: ${{ needs.abi-dump-setup.outputs.ABI_HEADERS }}
@@ -138,6 +152,15 @@ jobs:
           name: symbol-list
           path: llvm.symbols
 
+      - name: Cache baseline ABI
+        if: ${{ matrix.name == 'build-baseline' }}
+        uses: actions/cache/save at 55cc8345863c7cc4c66a329aec7e433d2d1c52a9 #v6.1.0
+        with:
+          key: ${{ matrix.ref }}.abi
+          path: |
+            ${{ matrix.ref }}.abi
+            llvm.symbols
+
   abi-compare:
     if: github.repository_owner == 'llvm'
     runs-on: ubuntu-24.04

>From 4d985f59da739bcb558bfb9faffdaab59b45f7ba Mon Sep 17 00:00:00 2001
From: Michael Jones <michaelrj at google.com>
Date: Fri, 31 Jul 2026 16:37:32 -0700
Subject: [PATCH 39/43] [libc] Move generated elf header to include (#211428)

The fact that `hdr/elf_proxy.h` was generated with headergen was causing
dependency issues. This shouldn't be necessary, and this PR moves it out
into `include` to avoid needing headergen for an overlay build.

Assisted-by: Automated tooling, human reviewed.
---
 libc/cmake/modules/LLVMLibCHeaderRules.cmake  |   4 +-
 libc/hdr/CMakeLists.txt                       |  56 +-
 libc/hdr/elf_proxy.h                          |  27 +
 libc/include/CMakeLists.txt                   |  52 +-
 libc/include/elf.yaml                         | 666 +----------------
 libc/include/llvm-libc-proxy/CMakeLists.txt   |  59 ++
 libc/include/llvm-libc-proxy/elf_proxy.yaml   | 667 ++++++++++++++++++
 .../llvm-project-overlay/libc/BUILD.bazel     |  17 +-
 .../libc/libc_build_rules.bzl                 |   2 +
 9 files changed, 773 insertions(+), 777 deletions(-)
 create mode 100644 libc/hdr/elf_proxy.h
 create mode 100644 libc/include/llvm-libc-proxy/CMakeLists.txt
 create mode 100644 libc/include/llvm-libc-proxy/elf_proxy.yaml

diff --git a/libc/cmake/modules/LLVMLibCHeaderRules.cmake b/libc/cmake/modules/LLVMLibCHeaderRules.cmake
index d7e996be9e854..88e183d8f4ec4 100644
--- a/libc/cmake/modules/LLVMLibCHeaderRules.cmake
+++ b/libc/cmake/modules/LLVMLibCHeaderRules.cmake
@@ -94,11 +94,9 @@ function(add_gen_header target_name)
 
   set(absolute_path ${CMAKE_CURRENT_SOURCE_DIR}/${ADD_GEN_HDR_GEN_HDR})
   file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_SOURCE_DIR} ${absolute_path})
+  set(out_file ${LIBC_INCLUDE_DIR}/${relative_path})
   if (ADD_GEN_HDR_PROXY)
-    set(out_file ${LIBC_BUILD_DIR}/hdr/${relative_path})
     set(proxy_arg "--proxy")
-  else()
-    set(out_file ${LIBC_INCLUDE_DIR}/${relative_path})
   endif()
   set(dep_file "${out_file}.d")
   set(yaml_file ${CMAKE_SOURCE_DIR}/${ADD_GEN_HDR_YAML_FILE})
diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt
index f2979866eafbe..a3eb7769e3c91 100644
--- a/libc/hdr/CMakeLists.txt
+++ b/libc/hdr/CMakeLists.txt
@@ -357,60 +357,12 @@ add_proxy_header_library(
     libc.include.llvm-libc-macros.elf_macros
 )
 
-add_gen_header(
+add_proxy_header_library(
   elf_proxy
-  YAML_FILE
-    ../libc/include/elf.yaml
-  GEN_HDR
+  HDRS
     elf_proxy.h
-  DEPENDS
-    libc.include.llvm_libc_common_h
-    libc.include.llvm-libc-types.Elf32_Addr
-    libc.include.llvm-libc-types.Elf32_Chdr
-    libc.include.llvm-libc-types.Elf32_Dyn
-    libc.include.llvm-libc-types.Elf32_Ehdr
-    libc.include.llvm-libc-types.Elf32_Half
-    libc.include.llvm-libc-types.Elf32_Lword
-    libc.include.llvm-libc-types.Elf32_Nhdr
-    libc.include.llvm-libc-types.Elf32_Off
-    libc.include.llvm-libc-types.Elf32_Phdr
-    libc.include.llvm-libc-types.Elf32_Rel
-    libc.include.llvm-libc-types.Elf32_Rela
-    libc.include.llvm-libc-types.Elf32_Shdr
-    libc.include.llvm-libc-types.Elf32_Sword
-    libc.include.llvm-libc-types.Elf32_Sym
-    libc.include.llvm-libc-types.Elf32_Verdaux
-    libc.include.llvm-libc-types.Elf32_Verdef
-    libc.include.llvm-libc-types.Elf32_Vernaux
-    libc.include.llvm-libc-types.Elf32_Verneed
-    libc.include.llvm-libc-types.Elf32_Versym
-    libc.include.llvm-libc-types.Elf32_Word
-    libc.include.llvm-libc-types.Elf32_Xword
-    libc.include.llvm-libc-types.Elf32_auxv_t
-    libc.include.llvm-libc-types.Elf64_Addr
-    libc.include.llvm-libc-types.Elf64_Chdr
-    libc.include.llvm-libc-types.Elf64_Dyn
-    libc.include.llvm-libc-types.Elf64_Ehdr
-    libc.include.llvm-libc-types.Elf64_Half
-    libc.include.llvm-libc-types.Elf64_Lword
-    libc.include.llvm-libc-types.Elf64_Nhdr
-    libc.include.llvm-libc-types.Elf64_Off
-    libc.include.llvm-libc-types.Elf64_Phdr
-    libc.include.llvm-libc-types.Elf64_Rel
-    libc.include.llvm-libc-types.Elf64_Rela
-    libc.include.llvm-libc-types.Elf64_Shdr
-    libc.include.llvm-libc-types.Elf64_Sword
-    libc.include.llvm-libc-types.Elf64_Sxword
-    libc.include.llvm-libc-types.Elf64_Sym
-    libc.include.llvm-libc-types.Elf64_Verdaux
-    libc.include.llvm-libc-types.Elf64_Verdef
-    libc.include.llvm-libc-types.Elf64_Vernaux
-    libc.include.llvm-libc-types.Elf64_Verneed
-    libc.include.llvm-libc-types.Elf64_Versym
-    libc.include.llvm-libc-types.Elf64_Word
-    libc.include.llvm-libc-types.Elf64_Xword
-    libc.include.llvm-libc-types.Elf64_auxv_t
-  PROXY
+  FULL_BUILD_DEPENDS
+    libc.include.llvm-libc-proxy.elf_proxy
 )
 
 add_proxy_header_library(
diff --git a/libc/hdr/elf_proxy.h b/libc/hdr/elf_proxy.h
new file mode 100644
index 0000000000000..23e42ddff12f0
--- /dev/null
+++ b/libc/hdr/elf_proxy.h
@@ -0,0 +1,27 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// Proxy header for elf.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_HDR_ELF_PROXY_H
+#define LLVM_LIBC_HDR_HDR_ELF_PROXY_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "llvm-libc-proxy/elf_proxy.h"
+
+#else // Overlay mode
+
+#include <elf.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_HDR_ELF_PROXY_H
diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt
index cf8bfb02c3931..196490dcfdcc1 100644
--- a/libc/include/CMakeLists.txt
+++ b/libc/include/CMakeLists.txt
@@ -17,6 +17,9 @@ add_header(
     __llvm-libc-common.h
 )
 
+# Has to be after common since elf_proxy depends on common.
+add_subdirectory(llvm-libc-proxy)
+
 # TODO: Can we simplify this macro expansion?
 # https://github.com/llvm/llvm-project/issues/117254
 macro(add_header_macro TARGET_NAME YAML_FILE GEN_HDR DEPENDS)
@@ -604,53 +607,8 @@ add_header_macro(
   ../libc/include/elf.yaml
   elf.h
   DEPENDS
-    .llvm-libc-macros.elf_macros
-    .llvm-libc-macros.sys_auxv_macros
-    .llvm-libc-types.Elf32_Addr
-    .llvm-libc-types.Elf32_Chdr
-    .llvm-libc-types.Elf32_Dyn
-    .llvm-libc-types.Elf32_Ehdr
-    .llvm-libc-types.Elf32_Half
-    .llvm-libc-types.Elf32_Lword
-    .llvm-libc-types.Elf32_Nhdr
-    .llvm-libc-types.Elf32_Off
-    .llvm-libc-types.Elf32_Phdr
-    .llvm-libc-types.Elf32_Rel
-    .llvm-libc-types.Elf32_Rela
-    .llvm-libc-types.Elf32_Shdr
-    .llvm-libc-types.Elf32_Sword
-    .llvm-libc-types.Elf32_Sym
-    .llvm-libc-types.Elf32_Verdaux
-    .llvm-libc-types.Elf32_Verdef
-    .llvm-libc-types.Elf32_Vernaux
-    .llvm-libc-types.Elf32_Verneed
-    .llvm-libc-types.Elf32_Versym
-    .llvm-libc-types.Elf32_Word
-    .llvm-libc-types.Elf32_Xword
-    .llvm-libc-types.Elf32_auxv_t
-    .llvm-libc-types.Elf64_Addr
-    .llvm-libc-types.Elf64_Chdr
-    .llvm-libc-types.Elf64_Dyn
-    .llvm-libc-types.Elf64_Ehdr
-    .llvm-libc-types.Elf64_Half
-    .llvm-libc-types.Elf64_Lword
-    .llvm-libc-types.Elf64_Nhdr
-    .llvm-libc-types.Elf64_Off
-    .llvm-libc-types.Elf64_Phdr
-    .llvm-libc-types.Elf64_Rel
-    .llvm-libc-types.Elf64_Rela
-    .llvm-libc-types.Elf64_Shdr
-    .llvm-libc-types.Elf64_Sword
-    .llvm-libc-types.Elf64_Sxword
-    .llvm-libc-types.Elf64_Sym
-    .llvm-libc-types.Elf64_Verdaux
-    .llvm-libc-types.Elf64_Verdef
-    .llvm-libc-types.Elf64_Vernaux
-    .llvm-libc-types.Elf64_Verneed
-    .llvm-libc-types.Elf64_Versym
-    .llvm-libc-types.Elf64_Word
-    .llvm-libc-types.Elf64_Xword
-    .llvm-libc-types.Elf64_auxv_t
+    .llvm-libc-proxy.elf_proxy
+    .llvm_libc_common_h
 )
 
 # TODO: Not all platforms will have a include/sys directory. Add the sys
diff --git a/libc/include/elf.yaml b/libc/include/elf.yaml
index 2b11dfe2a343f..f86463b2f4aa0 100644
--- a/libc/include/elf.yaml
+++ b/libc/include/elf.yaml
@@ -1,667 +1,5 @@
 header: elf.h
+public_includes:
+  - llvm-libc-proxy/elf_proxy.h
 standards:
   - svid
-macros:
-  # ELF Header
-  - macro_name: EI_NIDENT
-    macro_value: 16
-  - macro_name: EI_MAG0
-    macro_value: 0
-  - macro_name: EI_MAG1
-    macro_value: 1
-  - macro_name: EI_MAG2
-    macro_value: 2
-  - macro_name: EI_MAG3
-    macro_value: 3
-  - macro_name: EI_CLASS
-    macro_value: 4
-  - macro_name: EI_DATA
-    macro_value: 5
-  - macro_name: EI_VERSION
-    macro_value: 6
-  - macro_name: EI_OSABI
-    macro_value: 7
-  - macro_name: EI_ABIVERSION
-    macro_value: 8
-  - macro_name: EI_PAD
-    macro_value: 9
-  - macro_name: EI_NIDENT
-    macro_value: 16
-  - macro_name: ELFMAG0
-    macro_value: '0x7f'
-  - macro_name: ELFMAG1
-    macro_value: "'E'"
-  - macro_name: ELFMAG2
-    macro_value: "'L'"
-  - macro_name: ELFMAG3
-    macro_value: "'F'"
-  - macro_name: ELFMAG
-    macro_value: '"\177ELF"'
-  - macro_name: SELFMAG
-    macro_value: 4
-  - macro_name: ELFCLASSNONE
-    macro_value: 0
-  - macro_name: ELFCLASS32
-    macro_value: 1
-  - macro_name: ELFCLASS64
-    macro_value: 2
-  - macro_name: ELFDATANONE
-    macro_value: 0
-  - macro_name: ELFDATA2LSB
-    macro_value: 1
-  - macro_name: ELFDATA2MSB
-    macro_value: 2
-  - macro_name: ELFOSABI_NONE
-    macro_value: 0
-  - macro_name: ELFOSABI_LINUX
-    macro_value: 3
-  - macro_name: ET_NONE
-    macro_value: 0
-  - macro_name: ET_REL
-    macro_value: 1
-  - macro_name: ET_EXEC
-    macro_value: 2
-  - macro_name: ET_DYN
-    macro_value: 3
-  - macro_name: ET_CORE
-    macro_value: 4
-  - macro_name: ET_LOOS
-    macro_value: '0xfe00'
-  - macro_name: ET_HIOS
-    macro_value: '0xfeff'
-  - macro_name: ET_LOPROC
-    macro_value: '0xff00'
-  - macro_name: ET_HIPROC
-    macro_value: '0xffff'
-  - macro_name: EM_NONE
-    macro_value: 0
-  - macro_name: EM_386
-    macro_value: 3
-  - macro_name: EM_ARM
-    macro_value: 40
-  - macro_name: EM_X86_64
-    macro_value: 62
-  - macro_name: EM_AARCH64
-    macro_value: 183
-  - macro_name: EM_RISCV
-    macro_value: 243
-  - macro_name: EV_NONE
-    macro_value: 0
-  - macro_name: EV_CURRENT
-    macro_value: 1
-  # Sections
-  - macro_name: SHN_UNDEF
-    macro_value: 0
-  - macro_name: SHN_LORESERVE
-    macro_value: '0xff00'
-  - macro_name: SHN_LOPROC
-    macro_value: '0xff00'
-  - macro_name: SHN_HIPROC
-    macro_value: '0xff1f'
-  - macro_name: SHN_LOOS
-    macro_value: '0xff20'
-  - macro_name: SHN_HIOS
-    macro_value: '0xff3f'
-  - macro_name: SHN_ABS
-    macro_value: '0xfff1'
-  - macro_name: SHN_COMMON
-    macro_value: '0xfff2'
-  - macro_name: SHN_XINDEX
-    macro_value: '0xffff'
-  - macro_name: SHN_HIRESERVE
-    macro_value: '0xffff'
-  - macro_name: SHT_NULL
-    macro_value: 0
-  - macro_name: SHT_PROGBITS
-    macro_value: 1
-  - macro_name: SHT_SYMTAB
-    macro_value: 2
-  - macro_name: SHT_STRTAB
-    macro_value: 3
-  - macro_name: SHT_RELA
-    macro_value: 4
-  - macro_name: SHT_HASH
-    macro_value: 5
-  - macro_name: SHT_DYNAMIC
-    macro_value: 6
-  - macro_name: SHT_NOTE
-    macro_value: 7
-  - macro_name: SHT_NOBITS
-    macro_value: 8
-  - macro_name: SHT_REL
-    macro_value: 9
-  - macro_name: SHT_SHLIB
-    macro_value: 10
-  - macro_name: SHT_DYNSYM
-    macro_value: 11
-  - macro_name: SHT_INIT_ARRAY
-    macro_value: 14
-  - macro_name: SHT_FINI_ARRAY
-    macro_value: 15
-  - macro_name: SHT_PREINIT_ARRAY
-    macro_value: 16
-  - macro_name: SHT_GROUP
-    macro_value: 17
-  - macro_name: SHT_SYMTAB_SHNDX
-    macro_value: 18
-  - macro_name: SHT_LOOS
-    macro_value: '0x60000000'
-  - macro_name: SHT_HIOS
-    macro_value: '0x6fffffff'
-  - macro_name: SHT_LOPROC
-    macro_value: '0x70000000'
-  - macro_name: SHT_HIPROC
-    macro_value: '0x7fffffff'
-  - macro_name: SHT_LOUSER
-    macro_value: '0x80000000'
-  - macro_name: SHT_HIUSER
-    macro_value: '0xffffffff'
-  - macro_name: SHF_WRITE
-    macro_value: '0x1'
-  - macro_name: SHF_ALLOC
-    macro_value: '0x2'
-  - macro_name: SHF_EXECINSTR
-    macro_value: '0x4'
-  - macro_name: SHF_MERGE
-    macro_value: '0x10'
-  - macro_name: SHF_STRINGS
-    macro_value: '0x20'
-  - macro_name: SHF_INFO_LINK
-    macro_value: '0x40'
-  - macro_name: SHF_LINK_ORDER
-    macro_value: '0x80'
-  - macro_name: SHF_OS_NONCONFORMING
-    macro_value: '0x100'
-  - macro_name: SHF_GROUP
-    macro_value: '0x200'
-  - macro_name: SHF_TLS
-    macro_value: '0x400'
-  - macro_name: SHF_COMPRESSED
-    macro_value: '0x800'
-  - macro_name: SHF_MASKOS
-    macro_value: '0x0ff00000'
-  - macro_name: SHF_MASKPROC
-    macro_value: '0xf0000000'
-  - macro_name: ELFCOMPRESS_ZLIB
-    macro_value: 1
-  - macro_name: ELFCOMPRESS_ZSTD
-    macro_value: 2
-  - macro_name: ELFCOMPRESS_LOOS
-    macro_value: '0x60000000'
-  - macro_name: ELFCOMPRESS_HIOS
-    macro_value: '0x6fffffff'
-  - macro_name: ELFCOMPRESS_LOPROC
-    macro_value: '0x70000000'
-  - macro_name: ELFCOMPRESS_HIPROC
-    macro_value: '0x7fffffff'
-  # Symbol Table
-  - macro_name: STN_UNDEF
-    macro_value: 0
-  - macro_name: STB_LOCAL
-    macro_value: 0
-  - macro_name: STB_GLOBAL
-    macro_value: 1
-  - macro_name: STB_WEAK
-    macro_value: 2
-  - macro_name: STB_LOOS
-    macro_value: 10
-  - macro_name: STB_HIOS
-    macro_value: 12
-  - macro_name: STB_LOPROC
-    macro_value: 13
-  - macro_name: STB_HIPROC
-    macro_value: 15
-  - macro_name: STT_NOTYPE
-    macro_value: 0
-  - macro_name: STT_OBJECT
-    macro_value: 1
-  - macro_name: STT_FUNC
-    macro_value: 2
-  - macro_name: STT_SECTION
-    macro_value: 3
-  - macro_name: STT_FILE
-    macro_value: 4
-  - macro_name: STT_COMMON
-    macro_value: 5
-  - macro_name: STT_TLS
-    macro_value: 6
-  - macro_name: STT_LOOS
-    macro_value: 10
-  - macro_name: STT_HIOS
-    macro_value: 12
-  - macro_name: STT_LOPROC
-    macro_value: 13
-  - macro_name: STT_HIPROC
-    macro_value: 15
-  - macro_name: STV_DEFAULT
-    macro_value: 0
-  - macro_name: STV_INTERNAL
-    macro_value: 1
-  - macro_name: STV_HIDDEN
-    macro_value: 2
-  - macro_name: STV_PROTECTED
-    macro_value: 3
-  # Program Loading
-  - macro_name: PT_NULL
-    macro_value: 0
-  - macro_name: PT_LOAD
-    macro_value: 1
-  - macro_name: PT_DYNAMIC
-    macro_value: 2
-  - macro_name: PT_INTERP
-    macro_value: 3
-  - macro_name: PT_NOTE
-    macro_value: 4
-  - macro_name: PT_SHLIB
-    macro_value: 5
-  - macro_name: PT_PHDR
-    macro_value: 6
-  - macro_name: PT_TLS
-    macro_value: 7
-  - macro_name: PT_LOOS
-    macro_value: '0x60000000'
-  - macro_name: PT_HIOS
-    macro_value: '0x6fffffff'
-  - macro_name: PT_LOPROC
-    macro_value: '0x70000000'
-  - macro_name: PT_HIPROC
-    macro_value: '0x7fffffff'
-  - macro_name: PT_GNU_EH_FRAME
-    macro_value: '0x6474e550'
-    standards:
-      - gnu
-  - macro_name: PT_GNU_STACK
-    macro_value: '0x6474e551'
-    standards:
-      - gnu
-  - macro_name: PT_GNU_RELRO
-    macro_value: '0x6474e552'
-    standards:
-      - gnu
-  - macro_name: PT_GNU_PROPERTY
-    macro_value: '0x6474e553'
-  - macro_name: PF_X
-    macro_value: '0x1'
-  - macro_name: PF_W
-    macro_value: '0x2'
-  - macro_name: PF_R
-    macro_value: '0x4'
-  - macro_name: PF_MASKOS
-    macro_value: '0x0ff00000'
-  - macro_name: PF_MASKPROC
-    macro_value: '0xf0000000'
-  # Dynamic Linking
-  - macro_name: DT_NULL
-    macro_value: 0
-  - macro_name: DT_NEEDED
-    macro_value: 1
-  - macro_name: DT_PLTRELSZ
-    macro_value: 2
-  - macro_name: DT_PLTGOT
-    macro_value: 3
-  - macro_name: DT_HASH
-    macro_value: 4
-  - macro_name: DT_STRTAB
-    macro_value: 5
-  - macro_name: DT_SYMTAB
-    macro_value: 6
-  - macro_name: DT_RELA
-    macro_value: 7
-  - macro_name: DT_RELASZ
-    macro_value: 8
-  - macro_name: DT_RELAENT
-    macro_value: 9
-  - macro_name: DT_STRSZ
-    macro_value: 10
-  - macro_name: DT_SYMENT
-    macro_value: 11
-  - macro_name: DT_INIT
-    macro_value: 12
-  - macro_name: DT_FINI
-    macro_value: 13
-  - macro_name: DT_SONAME
-    macro_value: 14
-  - macro_name: DT_RPATH
-    macro_value: 15
-  - macro_name: DT_SYMBOLIC
-    macro_value: 16
-  - macro_name: DT_REL
-    macro_value: 17
-  - macro_name: DT_RELSZ
-    macro_value: 18
-  - macro_name: DT_RELENT
-    macro_value: 19
-  - macro_name: DT_PLTREL
-    macro_value: 20
-  - macro_name: DT_DEBUG
-    macro_value: 21
-  - macro_name: DT_TEXTREL
-    macro_value: 22
-  - macro_name: DT_JMPREL
-    macro_value: 23
-  - macro_name: DT_BIND_NOW
-    macro_value: 24
-  - macro_name: DT_INIT_ARRAY
-    macro_value: 25
-  - macro_name: DT_FINI_ARRAY
-    macro_value: 26
-  - macro_name: DT_INIT_ARRAYSZ
-    macro_value: 27
-  - macro_name: DT_FINI_ARRAYSZ
-    macro_value: 28
-  - macro_name: DT_RUNPATH
-    macro_value: 29
-  - macro_name: DT_FLAGS
-    macro_value: 30
-  - macro_name: DT_ENCODING
-    macro_value: 32
-  - macro_name: DT_PREINIT_ARRAY
-    macro_value: 32
-  - macro_name: DT_PREINIT_ARRAYSZ
-    macro_value: 33
-  - macro_name: DT_SYMTAB_SHNDX
-    macro_value: 34
-  - macro_name: DT_LOOS
-    macro_value: '0x6000000D'
-  - macro_name: DT_HIOS
-    macro_value: '0x6ffff000'
-  - macro_name: DT_LOPROC
-    macro_value: '0x70000000'
-  - macro_name: DT_HIPROC
-    macro_value: '0x7fffffff'
-  - macro_name: DT_ADDRRNGLO
-    macro_value: '0x6ffffe00'
-  - macro_name: DT_GNU_HASH
-    macro_value: '0x6ffffef5'
-    standards:
-      - gnu
-  - macro_name: DT_TLSDESC_PLT
-    macro_value: '0x6ffffef6'
-    standards:
-      - gnu
-  - macro_name: DT_TLSDESC_GOT
-    macro_value: '0x6ffffef7'
-    standards:
-      - gnu
-  - macro_name: DT_GNU_CONFLICT
-    macro_value: '0x6ffffef8'
-    standards:
-      - gnu
-  - macro_name: DT_GNU_LIBLIST
-    macro_value: '0x6ffffef9'
-    standards:
-      - gnu
-  - macro_name: DT_CONFIG
-    macro_value: '0x6ffffefa'
-  - macro_name: DT_DEPAUDIT
-    macro_value: '0x6ffffefb'
-  - macro_name: DT_AUDIT
-    macro_value: '0x6ffffefc'
-  - macro_name: DT_PLTPAD
-    macro_value: '0x6ffffefd'
-  - macro_name: DT_MOVETAB
-    macro_value: '0x6ffffefe'
-  - macro_name: DT_SYMINFO
-    macro_value: '0x6ffffeff'
-  - macro_name: DT_ADDRRNGHI
-    macro_value: '0x6ffffeff'
-  - macro_name: DT_VERSYM
-    macro_value: '0x6ffffff0'
-  - macro_name: DT_RELACOUNT
-    macro_value: '0x6ffffff9'
-  - macro_name: DT_RELCOUNT
-    macro_value: '0x6ffffffa'
-  - macro_name: DT_VERDEF
-    macro_value: '0x6ffffffc'
-  - macro_name: DT_VERDEFNUM
-    macro_value: '0x6ffffffd'
-  - macro_name: DT_VERNEED
-    macro_value: '0x6ffffffe'
-  - macro_name: DT_VERNEEDNUM
-    macro_value: '0x6fffffff'
-  - macro_name: DF_ORIGIN
-    macro_value: '0x1'
-  - macro_name: DF_SYMBOLIC
-    macro_value: '0x2'
-  - macro_name: DF_TEXTREL
-    macro_value: '0x4'
-  - macro_name: DF_BIND_NOW
-    macro_value: '0x8'
-  - macro_name: DF_STATIC_TLS
-    macro_value: '0x10'
-  # Notes used in ET_CORE.
-  - macro_name: NN_PRSTATUS
-    macro_value: '"CORE"'
-  - macro_name: NT_PRSTATUS
-    macro_value: 1
-  - macro_name: NN_PRFPREG
-    macro_value: '"CORE"'
-  - macro_name: NT_PRFPREG
-    macro_value: 2
-  - macro_name: NT_FPREGSET
-    macro_value: 2
-  - macro_name: NN_PRPSINFO
-    macro_value: '"CORE"'
-  - macro_name: NT_PRPSINFO
-    macro_value: 3
-  - macro_name: NN_TASKSTRUCT
-    macro_value: '"CORE"'
-  - macro_name: NT_TASKSTRUCT
-    macro_value: 4
-  - macro_name: NT_PRXREG
-    macro_value: 4
-  - macro_name: NT_PLATFORM
-    macro_value: 5
-  - macro_name: NN_AUXV
-    macro_value: '"CORE"'
-  - macro_name: NT_AUXV
-    macro_value: 6
-  - macro_name: NN_SIGINFO
-    macro_value: '"CORE"'
-  - macro_name: NT_SIGINFO
-    macro_value: '0x53494749'
-  - macro_name: NN_FILE
-    macro_value: '"CORE"'
-  - macro_name: NT_FILE
-    macro_value: '0x46494c45'
-  - macro_name: NT_PRFPXREG
-    macro_value: 20
-  # Notes used by GNU toolchain.
-  - macro_name: NT_GNU_ABI_TAG
-    macro_value: 1
-    standards:
-      - gnu
-  - macro_name: NT_GNU_HWCAP
-    macro_value: 2
-    standards:
-      - gnu
-  - macro_name: NT_GNU_BUILD_ID
-    macro_value: 3
-    standards:
-      - gnu
-  - macro_name: NT_GNU_GOLD_VERSION
-    macro_value: 4
-    standards:
-      - gnu
-  - macro_name: NT_GNU_PROPERTY_TYPE_0
-    macro_value: 5
-    standards:
-      - gnu
-  # Symbol Versioning
-  - macro_name: VER_DEF_NONE
-    macro_value: 0
-  - macro_name: VER_DEF_CURRENT
-    macro_value: 1
-  - macro_name: VER_DEF_NUM
-    macro_value: 2
-  - macro_name: VER_FLG_BASE
-    macro_value: '0x1'
-  - macro_name: VER_FLG_WEAK
-    macro_value: '0x2'
-  - macro_name: VER_NDX_LOCAL
-    macro_value: 0
-  - macro_name: VER_NDX_GLOBAL
-    macro_value: 1
-  - macro_name: VER_NDX_LORESERVE
-    macro_value: '0xff00'
-  - macro_name: VER_NDX_ELIMINATE
-    macro_value: '0xff01'
-  # Values used in the .note.gnu.property section.
-  - macro_name: GNU_PROPERTY_X86_FEATURE_1_AND
-    macro_value: '0xc0000002'
-  - macro_name: GNU_PROPERTY_X86_FEATURE_1_SHSTK
-    macro_value: '0x00000002'
-  # Architecture-specific IRELATIVE relocation types
-  - macro_name: R_AARCH64_IRELATIVE
-    macro_value: 1032
-  - macro_name: R_ARM_IRELATIVE
-    macro_value: 160
-  - macro_name: R_RISCV_IRELATIVE
-    macro_value: 58
-  - macro_name: R_X86_64_IRELATIVE
-    macro_value: 37
-  - macro_name: ELF32_ST_BIND
-    macro_header: elf-macros.h
-  - macro_name: ELF32_ST_TYPE
-    macro_header: elf-macros.h
-  - macro_name: ELF32_ST_INFO
-    macro_header: elf-macros.h
-  - macro_name: ELF64_ST_BIND
-    macro_header: elf-macros.h
-  - macro_name: ELF64_ST_TYPE
-    macro_header: elf-macros.h
-  - macro_name: ELF64_ST_INFO
-    macro_header: elf-macros.h
-  - macro_name: ELF32_ST_VISIBILITY
-    macro_header: elf-macros.h
-  - macro_name: ELF64_ST_VISIBILITY
-    macro_header: elf-macros.h
-  - macro_name: ELF32_R_SYM
-    macro_header: elf-macros.h
-  - macro_name: ELF32_R_TYPE
-    macro_header: elf-macros.h
-  - macro_name: ELF32_R_INFO
-    macro_header: elf-macros.h
-  - macro_name: ELF64_R_SYM
-    macro_header: elf-macros.h
-  - macro_name: ELF64_R_TYPE
-    macro_header: elf-macros.h
-  - macro_name: ELF64_R_INFO
-    macro_header: elf-macros.h
-  - macro_name: PT_AARCH64_MEMTAG_MTE
-    macro_value: '0x70000002'
-  - macro_name: PN_XNUM
-    macro_value: '0xffff'
-  - macro_name: ELFCLASSNUM
-    macro_value: 3
-  - macro_name: EV_NUM
-    macro_value: 2
-  - macro_name: AT_NULL
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_IGNORE
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_EXECFD
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_PHDR
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_PHENT
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_PHNUM
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_PAGESZ
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_BASE
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_FLAGS
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_ENTRY
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_NOTELF
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_UID
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_EUID
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_GID
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_EGID
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_PLATFORM
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_HWCAP
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_CLKTCK
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_SECURE
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_BASE_PLATFORM
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_RANDOM
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_HWCAP2
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_RSEQ_FEATURE_SIZE
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_RSEQ_ALIGN
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_HWCAP3
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_HWCAP4
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_EXECFN
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_SYSINFO
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_SYSINFO_EHDR
-    macro_header: sys-auxv-macros.h
-  - macro_name: AT_MINSIGSTKSZ
-    macro_header: sys-auxv-macros.h
-types:
-  - type_name: Elf32_Addr
-  - type_name: Elf32_Chdr
-  - type_name: Elf32_Dyn
-  - type_name: Elf32_Ehdr
-  - type_name: Elf32_Half
-  - type_name: Elf32_Lword
-  - type_name: Elf32_Nhdr
-  - type_name: Elf32_Off
-  - type_name: Elf32_Phdr
-  - type_name: Elf32_Rel
-  - type_name: Elf32_Rela
-  - type_name: Elf32_Shdr
-  - type_name: Elf32_Sword
-  - type_name: Elf32_Sym
-  - type_name: Elf32_Verdaux
-  - type_name: Elf32_Verdef
-  - type_name: Elf32_Vernaux
-  - type_name: Elf32_Verneed
-  - type_name: Elf32_Versym
-  - type_name: Elf32_Word
-  - type_name: Elf32_Xword
-  - type_name: Elf32_auxv_t
-  - type_name: Elf64_Addr
-  - type_name: Elf64_Chdr
-  - type_name: Elf64_Dyn
-  - type_name: Elf64_Ehdr
-  - type_name: Elf64_Half
-  - type_name: Elf64_Lword
-  - type_name: Elf64_Nhdr
-  - type_name: Elf64_Off
-  - type_name: Elf64_Phdr
-  - type_name: Elf64_Rel
-  - type_name: Elf64_Rela
-  - type_name: Elf64_Shdr
-  - type_name: Elf64_Sword
-  - type_name: Elf64_Sxword
-  - type_name: Elf64_Sym
-  - type_name: Elf64_Verdaux
-  - type_name: Elf64_Verdef
-  - type_name: Elf64_Vernaux
-  - type_name: Elf64_Verneed
-  - type_name: Elf64_Versym
-  - type_name: Elf64_Word
-  - type_name: Elf64_Xword
-  - type_name: Elf64_auxv_t
-enums: []
-objects: []
-functions: []
diff --git a/libc/include/llvm-libc-proxy/CMakeLists.txt b/libc/include/llvm-libc-proxy/CMakeLists.txt
new file mode 100644
index 0000000000000..56409c8f1e627
--- /dev/null
+++ b/libc/include/llvm-libc-proxy/CMakeLists.txt
@@ -0,0 +1,59 @@
+file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-proxy)
+
+add_gen_header(
+  elf_proxy
+  YAML_FILE
+    ../libc/include/llvm-libc-proxy/elf_proxy.yaml
+  GEN_HDR
+    elf_proxy.h
+  DEPENDS
+    libc.include.llvm_libc_common_h
+    libc.include.llvm-libc-macros.elf_macros
+    libc.include.llvm-libc-macros.sys_auxv_macros
+    libc.include.llvm-libc-types.Elf32_Addr
+    libc.include.llvm-libc-types.Elf32_Chdr
+    libc.include.llvm-libc-types.Elf32_Dyn
+    libc.include.llvm-libc-types.Elf32_Ehdr
+    libc.include.llvm-libc-types.Elf32_Half
+    libc.include.llvm-libc-types.Elf32_Lword
+    libc.include.llvm-libc-types.Elf32_Nhdr
+    libc.include.llvm-libc-types.Elf32_Off
+    libc.include.llvm-libc-types.Elf32_Phdr
+    libc.include.llvm-libc-types.Elf32_Rel
+    libc.include.llvm-libc-types.Elf32_Rela
+    libc.include.llvm-libc-types.Elf32_Shdr
+    libc.include.llvm-libc-types.Elf32_Sword
+    libc.include.llvm-libc-types.Elf32_Sym
+    libc.include.llvm-libc-types.Elf32_Verdaux
+    libc.include.llvm-libc-types.Elf32_Verdef
+    libc.include.llvm-libc-types.Elf32_Vernaux
+    libc.include.llvm-libc-types.Elf32_Verneed
+    libc.include.llvm-libc-types.Elf32_Versym
+    libc.include.llvm-libc-types.Elf32_Word
+    libc.include.llvm-libc-types.Elf32_Xword
+    libc.include.llvm-libc-types.Elf32_auxv_t
+    libc.include.llvm-libc-types.Elf64_Addr
+    libc.include.llvm-libc-types.Elf64_Chdr
+    libc.include.llvm-libc-types.Elf64_Dyn
+    libc.include.llvm-libc-types.Elf64_Ehdr
+    libc.include.llvm-libc-types.Elf64_Half
+    libc.include.llvm-libc-types.Elf64_Lword
+    libc.include.llvm-libc-types.Elf64_Nhdr
+    libc.include.llvm-libc-types.Elf64_Off
+    libc.include.llvm-libc-types.Elf64_Phdr
+    libc.include.llvm-libc-types.Elf64_Rel
+    libc.include.llvm-libc-types.Elf64_Rela
+    libc.include.llvm-libc-types.Elf64_Shdr
+    libc.include.llvm-libc-types.Elf64_Sword
+    libc.include.llvm-libc-types.Elf64_Sxword
+    libc.include.llvm-libc-types.Elf64_Sym
+    libc.include.llvm-libc-types.Elf64_Verdaux
+    libc.include.llvm-libc-types.Elf64_Verdef
+    libc.include.llvm-libc-types.Elf64_Vernaux
+    libc.include.llvm-libc-types.Elf64_Verneed
+    libc.include.llvm-libc-types.Elf64_Versym
+    libc.include.llvm-libc-types.Elf64_Word
+    libc.include.llvm-libc-types.Elf64_Xword
+    libc.include.llvm-libc-types.Elf64_auxv_t
+  PROXY
+)
diff --git a/libc/include/llvm-libc-proxy/elf_proxy.yaml b/libc/include/llvm-libc-proxy/elf_proxy.yaml
new file mode 100644
index 0000000000000..2b11dfe2a343f
--- /dev/null
+++ b/libc/include/llvm-libc-proxy/elf_proxy.yaml
@@ -0,0 +1,667 @@
+header: elf.h
+standards:
+  - svid
+macros:
+  # ELF Header
+  - macro_name: EI_NIDENT
+    macro_value: 16
+  - macro_name: EI_MAG0
+    macro_value: 0
+  - macro_name: EI_MAG1
+    macro_value: 1
+  - macro_name: EI_MAG2
+    macro_value: 2
+  - macro_name: EI_MAG3
+    macro_value: 3
+  - macro_name: EI_CLASS
+    macro_value: 4
+  - macro_name: EI_DATA
+    macro_value: 5
+  - macro_name: EI_VERSION
+    macro_value: 6
+  - macro_name: EI_OSABI
+    macro_value: 7
+  - macro_name: EI_ABIVERSION
+    macro_value: 8
+  - macro_name: EI_PAD
+    macro_value: 9
+  - macro_name: EI_NIDENT
+    macro_value: 16
+  - macro_name: ELFMAG0
+    macro_value: '0x7f'
+  - macro_name: ELFMAG1
+    macro_value: "'E'"
+  - macro_name: ELFMAG2
+    macro_value: "'L'"
+  - macro_name: ELFMAG3
+    macro_value: "'F'"
+  - macro_name: ELFMAG
+    macro_value: '"\177ELF"'
+  - macro_name: SELFMAG
+    macro_value: 4
+  - macro_name: ELFCLASSNONE
+    macro_value: 0
+  - macro_name: ELFCLASS32
+    macro_value: 1
+  - macro_name: ELFCLASS64
+    macro_value: 2
+  - macro_name: ELFDATANONE
+    macro_value: 0
+  - macro_name: ELFDATA2LSB
+    macro_value: 1
+  - macro_name: ELFDATA2MSB
+    macro_value: 2
+  - macro_name: ELFOSABI_NONE
+    macro_value: 0
+  - macro_name: ELFOSABI_LINUX
+    macro_value: 3
+  - macro_name: ET_NONE
+    macro_value: 0
+  - macro_name: ET_REL
+    macro_value: 1
+  - macro_name: ET_EXEC
+    macro_value: 2
+  - macro_name: ET_DYN
+    macro_value: 3
+  - macro_name: ET_CORE
+    macro_value: 4
+  - macro_name: ET_LOOS
+    macro_value: '0xfe00'
+  - macro_name: ET_HIOS
+    macro_value: '0xfeff'
+  - macro_name: ET_LOPROC
+    macro_value: '0xff00'
+  - macro_name: ET_HIPROC
+    macro_value: '0xffff'
+  - macro_name: EM_NONE
+    macro_value: 0
+  - macro_name: EM_386
+    macro_value: 3
+  - macro_name: EM_ARM
+    macro_value: 40
+  - macro_name: EM_X86_64
+    macro_value: 62
+  - macro_name: EM_AARCH64
+    macro_value: 183
+  - macro_name: EM_RISCV
+    macro_value: 243
+  - macro_name: EV_NONE
+    macro_value: 0
+  - macro_name: EV_CURRENT
+    macro_value: 1
+  # Sections
+  - macro_name: SHN_UNDEF
+    macro_value: 0
+  - macro_name: SHN_LORESERVE
+    macro_value: '0xff00'
+  - macro_name: SHN_LOPROC
+    macro_value: '0xff00'
+  - macro_name: SHN_HIPROC
+    macro_value: '0xff1f'
+  - macro_name: SHN_LOOS
+    macro_value: '0xff20'
+  - macro_name: SHN_HIOS
+    macro_value: '0xff3f'
+  - macro_name: SHN_ABS
+    macro_value: '0xfff1'
+  - macro_name: SHN_COMMON
+    macro_value: '0xfff2'
+  - macro_name: SHN_XINDEX
+    macro_value: '0xffff'
+  - macro_name: SHN_HIRESERVE
+    macro_value: '0xffff'
+  - macro_name: SHT_NULL
+    macro_value: 0
+  - macro_name: SHT_PROGBITS
+    macro_value: 1
+  - macro_name: SHT_SYMTAB
+    macro_value: 2
+  - macro_name: SHT_STRTAB
+    macro_value: 3
+  - macro_name: SHT_RELA
+    macro_value: 4
+  - macro_name: SHT_HASH
+    macro_value: 5
+  - macro_name: SHT_DYNAMIC
+    macro_value: 6
+  - macro_name: SHT_NOTE
+    macro_value: 7
+  - macro_name: SHT_NOBITS
+    macro_value: 8
+  - macro_name: SHT_REL
+    macro_value: 9
+  - macro_name: SHT_SHLIB
+    macro_value: 10
+  - macro_name: SHT_DYNSYM
+    macro_value: 11
+  - macro_name: SHT_INIT_ARRAY
+    macro_value: 14
+  - macro_name: SHT_FINI_ARRAY
+    macro_value: 15
+  - macro_name: SHT_PREINIT_ARRAY
+    macro_value: 16
+  - macro_name: SHT_GROUP
+    macro_value: 17
+  - macro_name: SHT_SYMTAB_SHNDX
+    macro_value: 18
+  - macro_name: SHT_LOOS
+    macro_value: '0x60000000'
+  - macro_name: SHT_HIOS
+    macro_value: '0x6fffffff'
+  - macro_name: SHT_LOPROC
+    macro_value: '0x70000000'
+  - macro_name: SHT_HIPROC
+    macro_value: '0x7fffffff'
+  - macro_name: SHT_LOUSER
+    macro_value: '0x80000000'
+  - macro_name: SHT_HIUSER
+    macro_value: '0xffffffff'
+  - macro_name: SHF_WRITE
+    macro_value: '0x1'
+  - macro_name: SHF_ALLOC
+    macro_value: '0x2'
+  - macro_name: SHF_EXECINSTR
+    macro_value: '0x4'
+  - macro_name: SHF_MERGE
+    macro_value: '0x10'
+  - macro_name: SHF_STRINGS
+    macro_value: '0x20'
+  - macro_name: SHF_INFO_LINK
+    macro_value: '0x40'
+  - macro_name: SHF_LINK_ORDER
+    macro_value: '0x80'
+  - macro_name: SHF_OS_NONCONFORMING
+    macro_value: '0x100'
+  - macro_name: SHF_GROUP
+    macro_value: '0x200'
+  - macro_name: SHF_TLS
+    macro_value: '0x400'
+  - macro_name: SHF_COMPRESSED
+    macro_value: '0x800'
+  - macro_name: SHF_MASKOS
+    macro_value: '0x0ff00000'
+  - macro_name: SHF_MASKPROC
+    macro_value: '0xf0000000'
+  - macro_name: ELFCOMPRESS_ZLIB
+    macro_value: 1
+  - macro_name: ELFCOMPRESS_ZSTD
+    macro_value: 2
+  - macro_name: ELFCOMPRESS_LOOS
+    macro_value: '0x60000000'
+  - macro_name: ELFCOMPRESS_HIOS
+    macro_value: '0x6fffffff'
+  - macro_name: ELFCOMPRESS_LOPROC
+    macro_value: '0x70000000'
+  - macro_name: ELFCOMPRESS_HIPROC
+    macro_value: '0x7fffffff'
+  # Symbol Table
+  - macro_name: STN_UNDEF
+    macro_value: 0
+  - macro_name: STB_LOCAL
+    macro_value: 0
+  - macro_name: STB_GLOBAL
+    macro_value: 1
+  - macro_name: STB_WEAK
+    macro_value: 2
+  - macro_name: STB_LOOS
+    macro_value: 10
+  - macro_name: STB_HIOS
+    macro_value: 12
+  - macro_name: STB_LOPROC
+    macro_value: 13
+  - macro_name: STB_HIPROC
+    macro_value: 15
+  - macro_name: STT_NOTYPE
+    macro_value: 0
+  - macro_name: STT_OBJECT
+    macro_value: 1
+  - macro_name: STT_FUNC
+    macro_value: 2
+  - macro_name: STT_SECTION
+    macro_value: 3
+  - macro_name: STT_FILE
+    macro_value: 4
+  - macro_name: STT_COMMON
+    macro_value: 5
+  - macro_name: STT_TLS
+    macro_value: 6
+  - macro_name: STT_LOOS
+    macro_value: 10
+  - macro_name: STT_HIOS
+    macro_value: 12
+  - macro_name: STT_LOPROC
+    macro_value: 13
+  - macro_name: STT_HIPROC
+    macro_value: 15
+  - macro_name: STV_DEFAULT
+    macro_value: 0
+  - macro_name: STV_INTERNAL
+    macro_value: 1
+  - macro_name: STV_HIDDEN
+    macro_value: 2
+  - macro_name: STV_PROTECTED
+    macro_value: 3
+  # Program Loading
+  - macro_name: PT_NULL
+    macro_value: 0
+  - macro_name: PT_LOAD
+    macro_value: 1
+  - macro_name: PT_DYNAMIC
+    macro_value: 2
+  - macro_name: PT_INTERP
+    macro_value: 3
+  - macro_name: PT_NOTE
+    macro_value: 4
+  - macro_name: PT_SHLIB
+    macro_value: 5
+  - macro_name: PT_PHDR
+    macro_value: 6
+  - macro_name: PT_TLS
+    macro_value: 7
+  - macro_name: PT_LOOS
+    macro_value: '0x60000000'
+  - macro_name: PT_HIOS
+    macro_value: '0x6fffffff'
+  - macro_name: PT_LOPROC
+    macro_value: '0x70000000'
+  - macro_name: PT_HIPROC
+    macro_value: '0x7fffffff'
+  - macro_name: PT_GNU_EH_FRAME
+    macro_value: '0x6474e550'
+    standards:
+      - gnu
+  - macro_name: PT_GNU_STACK
+    macro_value: '0x6474e551'
+    standards:
+      - gnu
+  - macro_name: PT_GNU_RELRO
+    macro_value: '0x6474e552'
+    standards:
+      - gnu
+  - macro_name: PT_GNU_PROPERTY
+    macro_value: '0x6474e553'
+  - macro_name: PF_X
+    macro_value: '0x1'
+  - macro_name: PF_W
+    macro_value: '0x2'
+  - macro_name: PF_R
+    macro_value: '0x4'
+  - macro_name: PF_MASKOS
+    macro_value: '0x0ff00000'
+  - macro_name: PF_MASKPROC
+    macro_value: '0xf0000000'
+  # Dynamic Linking
+  - macro_name: DT_NULL
+    macro_value: 0
+  - macro_name: DT_NEEDED
+    macro_value: 1
+  - macro_name: DT_PLTRELSZ
+    macro_value: 2
+  - macro_name: DT_PLTGOT
+    macro_value: 3
+  - macro_name: DT_HASH
+    macro_value: 4
+  - macro_name: DT_STRTAB
+    macro_value: 5
+  - macro_name: DT_SYMTAB
+    macro_value: 6
+  - macro_name: DT_RELA
+    macro_value: 7
+  - macro_name: DT_RELASZ
+    macro_value: 8
+  - macro_name: DT_RELAENT
+    macro_value: 9
+  - macro_name: DT_STRSZ
+    macro_value: 10
+  - macro_name: DT_SYMENT
+    macro_value: 11
+  - macro_name: DT_INIT
+    macro_value: 12
+  - macro_name: DT_FINI
+    macro_value: 13
+  - macro_name: DT_SONAME
+    macro_value: 14
+  - macro_name: DT_RPATH
+    macro_value: 15
+  - macro_name: DT_SYMBOLIC
+    macro_value: 16
+  - macro_name: DT_REL
+    macro_value: 17
+  - macro_name: DT_RELSZ
+    macro_value: 18
+  - macro_name: DT_RELENT
+    macro_value: 19
+  - macro_name: DT_PLTREL
+    macro_value: 20
+  - macro_name: DT_DEBUG
+    macro_value: 21
+  - macro_name: DT_TEXTREL
+    macro_value: 22
+  - macro_name: DT_JMPREL
+    macro_value: 23
+  - macro_name: DT_BIND_NOW
+    macro_value: 24
+  - macro_name: DT_INIT_ARRAY
+    macro_value: 25
+  - macro_name: DT_FINI_ARRAY
+    macro_value: 26
+  - macro_name: DT_INIT_ARRAYSZ
+    macro_value: 27
+  - macro_name: DT_FINI_ARRAYSZ
+    macro_value: 28
+  - macro_name: DT_RUNPATH
+    macro_value: 29
+  - macro_name: DT_FLAGS
+    macro_value: 30
+  - macro_name: DT_ENCODING
+    macro_value: 32
+  - macro_name: DT_PREINIT_ARRAY
+    macro_value: 32
+  - macro_name: DT_PREINIT_ARRAYSZ
+    macro_value: 33
+  - macro_name: DT_SYMTAB_SHNDX
+    macro_value: 34
+  - macro_name: DT_LOOS
+    macro_value: '0x6000000D'
+  - macro_name: DT_HIOS
+    macro_value: '0x6ffff000'
+  - macro_name: DT_LOPROC
+    macro_value: '0x70000000'
+  - macro_name: DT_HIPROC
+    macro_value: '0x7fffffff'
+  - macro_name: DT_ADDRRNGLO
+    macro_value: '0x6ffffe00'
+  - macro_name: DT_GNU_HASH
+    macro_value: '0x6ffffef5'
+    standards:
+      - gnu
+  - macro_name: DT_TLSDESC_PLT
+    macro_value: '0x6ffffef6'
+    standards:
+      - gnu
+  - macro_name: DT_TLSDESC_GOT
+    macro_value: '0x6ffffef7'
+    standards:
+      - gnu
+  - macro_name: DT_GNU_CONFLICT
+    macro_value: '0x6ffffef8'
+    standards:
+      - gnu
+  - macro_name: DT_GNU_LIBLIST
+    macro_value: '0x6ffffef9'
+    standards:
+      - gnu
+  - macro_name: DT_CONFIG
+    macro_value: '0x6ffffefa'
+  - macro_name: DT_DEPAUDIT
+    macro_value: '0x6ffffefb'
+  - macro_name: DT_AUDIT
+    macro_value: '0x6ffffefc'
+  - macro_name: DT_PLTPAD
+    macro_value: '0x6ffffefd'
+  - macro_name: DT_MOVETAB
+    macro_value: '0x6ffffefe'
+  - macro_name: DT_SYMINFO
+    macro_value: '0x6ffffeff'
+  - macro_name: DT_ADDRRNGHI
+    macro_value: '0x6ffffeff'
+  - macro_name: DT_VERSYM
+    macro_value: '0x6ffffff0'
+  - macro_name: DT_RELACOUNT
+    macro_value: '0x6ffffff9'
+  - macro_name: DT_RELCOUNT
+    macro_value: '0x6ffffffa'
+  - macro_name: DT_VERDEF
+    macro_value: '0x6ffffffc'
+  - macro_name: DT_VERDEFNUM
+    macro_value: '0x6ffffffd'
+  - macro_name: DT_VERNEED
+    macro_value: '0x6ffffffe'
+  - macro_name: DT_VERNEEDNUM
+    macro_value: '0x6fffffff'
+  - macro_name: DF_ORIGIN
+    macro_value: '0x1'
+  - macro_name: DF_SYMBOLIC
+    macro_value: '0x2'
+  - macro_name: DF_TEXTREL
+    macro_value: '0x4'
+  - macro_name: DF_BIND_NOW
+    macro_value: '0x8'
+  - macro_name: DF_STATIC_TLS
+    macro_value: '0x10'
+  # Notes used in ET_CORE.
+  - macro_name: NN_PRSTATUS
+    macro_value: '"CORE"'
+  - macro_name: NT_PRSTATUS
+    macro_value: 1
+  - macro_name: NN_PRFPREG
+    macro_value: '"CORE"'
+  - macro_name: NT_PRFPREG
+    macro_value: 2
+  - macro_name: NT_FPREGSET
+    macro_value: 2
+  - macro_name: NN_PRPSINFO
+    macro_value: '"CORE"'
+  - macro_name: NT_PRPSINFO
+    macro_value: 3
+  - macro_name: NN_TASKSTRUCT
+    macro_value: '"CORE"'
+  - macro_name: NT_TASKSTRUCT
+    macro_value: 4
+  - macro_name: NT_PRXREG
+    macro_value: 4
+  - macro_name: NT_PLATFORM
+    macro_value: 5
+  - macro_name: NN_AUXV
+    macro_value: '"CORE"'
+  - macro_name: NT_AUXV
+    macro_value: 6
+  - macro_name: NN_SIGINFO
+    macro_value: '"CORE"'
+  - macro_name: NT_SIGINFO
+    macro_value: '0x53494749'
+  - macro_name: NN_FILE
+    macro_value: '"CORE"'
+  - macro_name: NT_FILE
+    macro_value: '0x46494c45'
+  - macro_name: NT_PRFPXREG
+    macro_value: 20
+  # Notes used by GNU toolchain.
+  - macro_name: NT_GNU_ABI_TAG
+    macro_value: 1
+    standards:
+      - gnu
+  - macro_name: NT_GNU_HWCAP
+    macro_value: 2
+    standards:
+      - gnu
+  - macro_name: NT_GNU_BUILD_ID
+    macro_value: 3
+    standards:
+      - gnu
+  - macro_name: NT_GNU_GOLD_VERSION
+    macro_value: 4
+    standards:
+      - gnu
+  - macro_name: NT_GNU_PROPERTY_TYPE_0
+    macro_value: 5
+    standards:
+      - gnu
+  # Symbol Versioning
+  - macro_name: VER_DEF_NONE
+    macro_value: 0
+  - macro_name: VER_DEF_CURRENT
+    macro_value: 1
+  - macro_name: VER_DEF_NUM
+    macro_value: 2
+  - macro_name: VER_FLG_BASE
+    macro_value: '0x1'
+  - macro_name: VER_FLG_WEAK
+    macro_value: '0x2'
+  - macro_name: VER_NDX_LOCAL
+    macro_value: 0
+  - macro_name: VER_NDX_GLOBAL
+    macro_value: 1
+  - macro_name: VER_NDX_LORESERVE
+    macro_value: '0xff00'
+  - macro_name: VER_NDX_ELIMINATE
+    macro_value: '0xff01'
+  # Values used in the .note.gnu.property section.
+  - macro_name: GNU_PROPERTY_X86_FEATURE_1_AND
+    macro_value: '0xc0000002'
+  - macro_name: GNU_PROPERTY_X86_FEATURE_1_SHSTK
+    macro_value: '0x00000002'
+  # Architecture-specific IRELATIVE relocation types
+  - macro_name: R_AARCH64_IRELATIVE
+    macro_value: 1032
+  - macro_name: R_ARM_IRELATIVE
+    macro_value: 160
+  - macro_name: R_RISCV_IRELATIVE
+    macro_value: 58
+  - macro_name: R_X86_64_IRELATIVE
+    macro_value: 37
+  - macro_name: ELF32_ST_BIND
+    macro_header: elf-macros.h
+  - macro_name: ELF32_ST_TYPE
+    macro_header: elf-macros.h
+  - macro_name: ELF32_ST_INFO
+    macro_header: elf-macros.h
+  - macro_name: ELF64_ST_BIND
+    macro_header: elf-macros.h
+  - macro_name: ELF64_ST_TYPE
+    macro_header: elf-macros.h
+  - macro_name: ELF64_ST_INFO
+    macro_header: elf-macros.h
+  - macro_name: ELF32_ST_VISIBILITY
+    macro_header: elf-macros.h
+  - macro_name: ELF64_ST_VISIBILITY
+    macro_header: elf-macros.h
+  - macro_name: ELF32_R_SYM
+    macro_header: elf-macros.h
+  - macro_name: ELF32_R_TYPE
+    macro_header: elf-macros.h
+  - macro_name: ELF32_R_INFO
+    macro_header: elf-macros.h
+  - macro_name: ELF64_R_SYM
+    macro_header: elf-macros.h
+  - macro_name: ELF64_R_TYPE
+    macro_header: elf-macros.h
+  - macro_name: ELF64_R_INFO
+    macro_header: elf-macros.h
+  - macro_name: PT_AARCH64_MEMTAG_MTE
+    macro_value: '0x70000002'
+  - macro_name: PN_XNUM
+    macro_value: '0xffff'
+  - macro_name: ELFCLASSNUM
+    macro_value: 3
+  - macro_name: EV_NUM
+    macro_value: 2
+  - macro_name: AT_NULL
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_IGNORE
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_EXECFD
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_PHDR
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_PHENT
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_PHNUM
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_PAGESZ
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_BASE
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_FLAGS
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_ENTRY
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_NOTELF
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_UID
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_EUID
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_GID
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_EGID
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_PLATFORM
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_HWCAP
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_CLKTCK
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_SECURE
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_BASE_PLATFORM
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_RANDOM
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_HWCAP2
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_RSEQ_FEATURE_SIZE
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_RSEQ_ALIGN
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_HWCAP3
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_HWCAP4
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_EXECFN
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_SYSINFO
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_SYSINFO_EHDR
+    macro_header: sys-auxv-macros.h
+  - macro_name: AT_MINSIGSTKSZ
+    macro_header: sys-auxv-macros.h
+types:
+  - type_name: Elf32_Addr
+  - type_name: Elf32_Chdr
+  - type_name: Elf32_Dyn
+  - type_name: Elf32_Ehdr
+  - type_name: Elf32_Half
+  - type_name: Elf32_Lword
+  - type_name: Elf32_Nhdr
+  - type_name: Elf32_Off
+  - type_name: Elf32_Phdr
+  - type_name: Elf32_Rel
+  - type_name: Elf32_Rela
+  - type_name: Elf32_Shdr
+  - type_name: Elf32_Sword
+  - type_name: Elf32_Sym
+  - type_name: Elf32_Verdaux
+  - type_name: Elf32_Verdef
+  - type_name: Elf32_Vernaux
+  - type_name: Elf32_Verneed
+  - type_name: Elf32_Versym
+  - type_name: Elf32_Word
+  - type_name: Elf32_Xword
+  - type_name: Elf32_auxv_t
+  - type_name: Elf64_Addr
+  - type_name: Elf64_Chdr
+  - type_name: Elf64_Dyn
+  - type_name: Elf64_Ehdr
+  - type_name: Elf64_Half
+  - type_name: Elf64_Lword
+  - type_name: Elf64_Nhdr
+  - type_name: Elf64_Off
+  - type_name: Elf64_Phdr
+  - type_name: Elf64_Rel
+  - type_name: Elf64_Rela
+  - type_name: Elf64_Shdr
+  - type_name: Elf64_Sword
+  - type_name: Elf64_Sxword
+  - type_name: Elf64_Sym
+  - type_name: Elf64_Verdaux
+  - type_name: Elf64_Verdef
+  - type_name: Elf64_Vernaux
+  - type_name: Elf64_Verneed
+  - type_name: Elf64_Versym
+  - type_name: Elf64_Word
+  - type_name: Elf64_Xword
+  - type_name: Elf64_auxv_t
+enums: []
+objects: []
+functions: []
diff --git a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
index ce42bd9cf8b02..19bf918783073 100644
--- a/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/libc/BUILD.bazel
@@ -190,6 +190,10 @@ LLVM_LIBC_HEADERS = [
     ),
     libc_header_info("nl_types"),
     libc_header_info("poll"),
+    libc_header_info(
+        "llvm-libc-proxy/elf_proxy",
+        proxy = True,
+    ),
     libc_header_info("pthread"),
     libc_header_info("sched"),
     libc_header_info("search"),
@@ -241,19 +245,12 @@ LLVM_LIBC_HEADERS = [
         name = info.target_name,
         hdr = info.staging_path,
         other_srcs = info.other_srcs,
+        proxy = info.proxy,
         yaml_template = info.yaml_template,
     )
     for info in LLVM_LIBC_HEADERS
 ]
 
-# needed for startup and VDSO. Doesn't get placed in /include so is handled separately.
-libc_generated_header(
-    name = "hdr_elf_proxy_h",
-    hdr = "staging/hdr/elf_proxy.h",
-    proxy = True,
-    yaml_template = "include/elf.yaml",
-)
-
 # Static headers that need to be in staging/include
 STATIC_HEADERS = glob(
     ["include/llvm-libc-types/**/*.h"],
@@ -617,9 +614,7 @@ libc_support_library(
 
 libc_support_library(
     name = "hdr_elf_proxy",
-    hdrs = ["staging/hdr/elf_proxy.h"],
-    includes = ["staging"],
-    deps = [":hdr_elf_proxy_h"],
+    hdrs = ["hdr/elf_proxy.h"],
 )
 
 libc_support_library(
diff --git a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
index 9056f9e384b26..da454e84843e5 100644
--- a/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
+++ b/utils/bazel/llvm-project-overlay/libc/libc_build_rules.bzl
@@ -291,11 +291,13 @@ def libc_generated_header(name, hdr, yaml_template, other_srcs = [], proxy = Fal
 def libc_header_info(
         name,
         has_def_template = False,
+        proxy = False,
         other_srcs = []):
     return struct(
         target_name = "include_{}_h".format(name.replace("/", "_")),
         staging_path = "staging/include/{}.h".format(name),
         yaml_template = "include/{}.yaml".format(name),
+        proxy = proxy,
         other_srcs = other_srcs + (["include/{}.h.def".format(name)] if has_def_template else []),
     )
 

>From 3a32fe981c0fe446177d7e1191a58a0fc1cacbb7 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 17:08:49 -0700
Subject: [PATCH 40/43] Fix matrix

---
 .github/workflows/release-documentation.yml | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index ca4c7ab6312aa..9bd43a7e7384a 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -201,14 +201,15 @@ jobs:
       contents: write     # For man page uploads
       id-token: write     # For artifact attestations
       attestations: write # For artifact attestations
-    matrix:
-      include:
-        - artifact-id: ${{ needs.release-documentation.outputs.man-page-artifact-id }}
-          attestation-name: release-man-page-attestation
-          digest: ${{ needs.release-documentation.outputs.man-page-digest }}
-        - artifact-id: ${{ needs.release-documentation.outputs.doxygen-artifact-id }}
-          attestation-name: release-doxygen-attestation
-          digest: ${{ needs.release-documentation.outputs.doxygen-digest }}
+    strategy:
+      matrix:
+        include:
+          - artifact-id: ${{ needs.release-documentation.outputs.man-page-artifact-id }}
+            attestation-name: release-man-page-attestation
+            digest: ${{ needs.release-documentation.outputs.man-page-digest }}
+          - artifact-id: ${{ needs.release-documentation.outputs.doxygen-artifact-id }}
+            attestation-name: release-doxygen-attestation
+            digest: ${{ needs.release-documentation.outputs.doxygen-digest }}
     steps:
      - name: Upload Man Page Artifacts
        id: man-page-artifact-upload

>From 91186afbab45006d25b5c4f4599e9fcb5ecf9998 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 20:44:31 -0700
Subject: [PATCH 41/43] Fix

---
 .github/workflows/release-documentation.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 9bd43a7e7384a..271c276046165 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -112,7 +112,7 @@ jobs:
           ./llvm/utils/release/build-docs.sh \
             $(test -n "$INPUTS_RELEASE_VERSION" && echo -release "$INPUTS_RELEASE_VERSION" || echo -srcdir llvm)
           echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*.tar.xz'))" >> "$GITHUB_OUTPUT"
-          echo "doxygen-tarball-name=$(baename $(find . -iname '*doxygen*.tar.xz')) >> "$GITHUB_OUTPUT"
+          echo "doxygen-tarball-name=$(baename $(find . -iname '*doxygen*.tar.xz'))" >> "$GITHUB_OUTPUT"
 
 
       - name: Generate sha256 digest for tarballs

>From 66da6d0507100376886748b07191a82abbdfb367 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 21:07:04 -0700
Subject: [PATCH 42/43] Fixes

---
 .github/workflows/release-documentation.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 271c276046165..153bba056dcd3 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -112,7 +112,7 @@ jobs:
           ./llvm/utils/release/build-docs.sh \
             $(test -n "$INPUTS_RELEASE_VERSION" && echo -release "$INPUTS_RELEASE_VERSION" || echo -srcdir llvm)
           echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*.tar.xz'))" >> "$GITHUB_OUTPUT"
-          echo "doxygen-tarball-name=$(baename $(find . -iname '*doxygen*.tar.xz'))" >> "$GITHUB_OUTPUT"
+          echo "doxygen-tarball-name=$(basename $(find . -iname '*doxygen*.tar.xz'))" >> "$GITHUB_OUTPUT"
 
 
       - name: Generate sha256 digest for tarballs
@@ -120,7 +120,7 @@ jobs:
         shell: bash
         env:
           MAN_PAGE_TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
-          DOXYGEN_TARBALL_NAME: ${{ steps.build.outputs.man-page-tarball-name }}
+          DOXYGEN_TARBALL_NAME: ${{ steps.build.outputs.doxygen-tarball-name }}
         run: |
             echo "man-page-digest=$(cat "$MAN_PAGE_TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
             echo "doxygen-digest=$(cat "$DOXYGEN_TARBALL_NAME" | sha256sum | cut -d ' ' -f 1)" >> "$GITHUB_OUTPUT"
@@ -217,7 +217,7 @@ jobs:
        with:
          release-version: ${{ inputs.release-version }}
          artifact-id: ${{ matrix.artifact-id }}
-         attestation-name: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.attestation_name }}
+         attestation-name: ${{ runner.os }}-${{ runner.arch }}-${{ matrix.attestation-name }}
          digest: ${{ matrix.digest }}
          upload: ${{ inputs.upload }}
          LLVM_TOKEN_GENERATOR_CLIENT_ID: ${{ secrets.LLVM_TOKEN_GENERATOR_CLIENT_ID }}

>From db7adbddd6d5555701ba7efd609744cd4589b268 Mon Sep 17 00:00:00 2001
From: Tom Stellard <tstellar at redhat.com>
Date: Fri, 31 Jul 2026 21:36:31 -0700
Subject: [PATCH 43/43] Debug

---
 .github/workflows/release-documentation.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.github/workflows/release-documentation.yml b/.github/workflows/release-documentation.yml
index 153bba056dcd3..2d550c536a528 100644
--- a/.github/workflows/release-documentation.yml
+++ b/.github/workflows/release-documentation.yml
@@ -111,6 +111,7 @@ jobs:
         run: |
           ./llvm/utils/release/build-docs.sh \
             $(test -n "$INPUTS_RELEASE_VERSION" && echo -release "$INPUTS_RELEASE_VERSION" || echo -srcdir llvm)
+            ls -ltr
           echo "man-page-tarball-name=$(basename $(find . -iname 'llvm_man_pages-*.tar.xz'))" >> "$GITHUB_OUTPUT"
           echo "doxygen-tarball-name=$(basename $(find . -iname '*doxygen*.tar.xz'))" >> "$GITHUB_OUTPUT"
 



More information about the llvm-branch-commits mailing list