[llvm] [SandboxIR] Delete SandboxIR/SandboxVectorizer (PR #166417)

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 4 11:24:15 PST 2025


https://github.com/boomanaiden154 created https://github.com/llvm/llvm-project/pull/166417

These components are still experimental, have not recieved commit traffic beyond basic maintenance since May, and it was decided that the people at Google working on the project should focus on other priorities. Given the lack of investment, delete the code for now. If someone wants to revive this, they can revert this patch. For now, delete it so that upstream does not have to bear the maintenance cost.

>From de7ede53dd9d1eebd239a6dffe0d399b19c78c57 Mon Sep 17 00:00:00 2001
From: Aiden Grossman <aidengrossman at google.com>
Date: Tue, 4 Nov 2025 19:17:13 +0000
Subject: [PATCH] [SandboxIR] Delete SandboxIR/SandboxVectorizer

These components are still experimental, have not recieved commit
traffic beyond basic maintenance since May, and it was decided that the
people at Google working on the project should focus on other
priorities. Given the lack of investment, delete the code for now. If
someone wants to revive this, they can revert this patch. For now,
delete it so that upstream does not have to bear the maintenance cost.
---
 llvm/Maintainers.md                           |   14 -
 llvm/benchmarks/CMakeLists.txt                |    2 -
 llvm/benchmarks/SandboxIRBench.cpp            |  243 -
 llvm/docs/SandboxIR.md                        |  109 -
 llvm/docs/SandboxVectorizer.md                |  280 -
 llvm/docs/UserGuides.rst                      |    4 -
 llvm/docs/Vectorizers.rst                     |    9 -
 llvm/include/llvm/SandboxIR/Argument.h        |   38 -
 llvm/include/llvm/SandboxIR/BasicBlock.h      |  113 -
 llvm/include/llvm/SandboxIR/Constant.h        | 1519 ----
 llvm/include/llvm/SandboxIR/Context.h         |  334 -
 llvm/include/llvm/SandboxIR/Function.h        |   83 -
 llvm/include/llvm/SandboxIR/Instruction.h     | 2632 -------
 llvm/include/llvm/SandboxIR/IntrinsicInst.h   |   44 -
 llvm/include/llvm/SandboxIR/Module.h          |   94 -
 llvm/include/llvm/SandboxIR/Operator.h        |   99 -
 llvm/include/llvm/SandboxIR/Pass.h            |   95 -
 llvm/include/llvm/SandboxIR/PassManager.h     |  227 -
 llvm/include/llvm/SandboxIR/Region.h          |  193 -
 llvm/include/llvm/SandboxIR/Tracker.h         |  529 --
 llvm/include/llvm/SandboxIR/Type.h            |  480 --
 llvm/include/llvm/SandboxIR/Use.h             |   72 -
 llvm/include/llvm/SandboxIR/User.h            |  151 -
 llvm/include/llvm/SandboxIR/Utils.h           |  138 -
 llvm/include/llvm/SandboxIR/Value.h           |  316 -
 llvm/include/llvm/SandboxIR/Values.def        |  154 -
 .../Vectorize/SandboxVectorizer/Debug.h       |   21 -
 .../SandboxVectorizer/DependencyGraph.h       |  469 --
 .../Vectorize/SandboxVectorizer/InstrMaps.h   |  110 -
 .../Vectorize/SandboxVectorizer/Interval.h    |  244 -
 .../Vectorize/SandboxVectorizer/Legality.h    |  362 -
 .../SandboxVectorizer/Passes/BottomUpVec.h    |  104 -
 .../SandboxVectorizer/Passes/NullPass.h       |   30 -
 .../SandboxVectorizer/Passes/PackReuse.h      |   36 -
 .../Passes/PrintInstructionCount.h            |   23 -
 .../SandboxVectorizer/Passes/PrintRegion.h    |   29 -
 .../SandboxVectorizer/Passes/RegionsFromBBs.h |   38 -
 .../Passes/RegionsFromMetadata.h              |   38 -
 .../SandboxVectorizer/Passes/SeedCollection.h |   40 -
 .../Passes/TransactionAcceptOrRevert.h        |   30 -
 .../Passes/TransactionAlwaysAccept.h          |   34 -
 .../Passes/TransactionAlwaysRevert.h          |   34 -
 .../Passes/TransactionSave.h                  |   28 -
 .../SandboxVectorizer/SandboxVectorizer.h     |   62 -
 .../SandboxVectorizerPassBuilder.h            |   32 -
 .../Vectorize/SandboxVectorizer/Scheduler.h   |  268 -
 .../SandboxVectorizer/SeedCollector.h         |  331 -
 .../Vectorize/SandboxVectorizer/VecUtils.h    |  276 -
 llvm/include/module.modulemap                 |    9 -
 llvm/lib/CMakeLists.txt                       |    1 -
 llvm/lib/Passes/PassBuilder.cpp               |    1 -
 llvm/lib/Passes/PassRegistry.def              |    1 -
 llvm/lib/SandboxIR/Argument.cpp               |   23 -
 llvm/lib/SandboxIR/BasicBlock.cpp             |  158 -
 llvm/lib/SandboxIR/CMakeLists.txt             |   26 -
 llvm/lib/SandboxIR/Constant.cpp               |  484 --
 llvm/lib/SandboxIR/Context.cpp                |  781 --
 llvm/lib/SandboxIR/Function.cpp               |   62 -
 llvm/lib/SandboxIR/Instruction.cpp            | 1562 ----
 llvm/lib/SandboxIR/Module.cpp                 |   43 -
 llvm/lib/SandboxIR/Pass.cpp                   |   19 -
 llvm/lib/SandboxIR/PassManager.cpp            |   33 -
 llvm/lib/SandboxIR/Region.cpp                 |  192 -
 llvm/lib/SandboxIR/Tracker.cpp                |  378 -
 llvm/lib/SandboxIR/Type.cpp                   |  127 -
 llvm/lib/SandboxIR/Use.cpp                    |   61 -
 llvm/lib/SandboxIR/User.cpp                   |  121 -
 llvm/lib/SandboxIR/Value.cpp                  |  124 -
 llvm/lib/Transforms/Vectorize/CMakeLists.txt  |   18 -
 .../SandboxVectorizer/DependencyGraph.cpp     |  665 --
 .../Vectorize/SandboxVectorizer/InstrMaps.cpp |   34 -
 .../Vectorize/SandboxVectorizer/Interval.cpp  |   49 -
 .../Vectorize/SandboxVectorizer/Legality.cpp  |  259 -
 .../SandboxVectorizer/Passes/BottomUpVec.cpp  |  518 --
 .../SandboxVectorizer/Passes/PackReuse.cpp    |   53 -
 .../SandboxVectorizer/Passes/PassRegistry.def |   40 -
 .../Passes/RegionsFromBBs.cpp                 |   35 -
 .../Passes/RegionsFromMetadata.cpp            |   30 -
 .../Passes/SeedCollection.cpp                 |  105 -
 .../Passes/TransactionAcceptOrRevert.cpp      |   45 -
 .../Passes/TransactionSave.cpp                |   21 -
 .../SandboxVectorizer/SandboxVectorizer.cpp   |  144 -
 .../SandboxVectorizerPassBuilder.cpp          |   40 -
 .../Vectorize/SandboxVectorizer/Scheduler.cpp |  360 -
 .../SandboxVectorizer/SeedCollector.cpp       |  212 -
 .../Vectorize/SandboxVectorizer/VecUtils.cpp  |   32 -
 .../SandboxVectorizer/X86/lit.local.cfg       |    2 -
 .../X86/no_implicit_float.ll                  |   23 -
 .../SandboxVectorizer/X86/simple_cost_test.ll |   91 -
 .../SandboxVectorizer/allow_files.ll          |   39 -
 .../SandboxVectorizer/boilerplate.ll          |   11 -
 .../SandboxVectorizer/bottomup_basic.ll       |  743 --
 .../SandboxVectorizer/bottomup_seed_slice.ll  |   32 -
 .../bottomup_seed_slice_pow2.ll               |   34 -
 .../Transforms/SandboxVectorizer/cross_bbs.ll |   28 -
 .../default_pass_pipeline.ll                  |   14 -
 .../test/Transforms/SandboxVectorizer/pack.ll |  117 -
 .../SandboxVectorizer/pack_reuse_basic.ll     |   71 -
 .../pack_reuse_end_to_end.ll                  |   45 -
 .../SandboxVectorizer/print_region_pass.ll    |   26 -
 .../SandboxVectorizer/regions-from-bbs.ll     |   31 -
 .../regions-from-metadata.ll                  |   15 -
 .../SandboxVectorizer/repeated_instrs.ll      |   65 -
 .../Transforms/SandboxVectorizer/scheduler.ll |   76 -
 .../SandboxVectorizer/special_opcodes.ll      |   97 -
 .../Transforms/SandboxVectorizer/stop_at.ll   |   61 -
 .../Transforms/SandboxVectorizer/stop_bndl.ll |   71 -
 .../SandboxVectorizer/user_pass_pipeline.ll   |   28 -
 llvm/unittests/CMakeLists.txt                 |    1 -
 llvm/unittests/SandboxIR/CMakeLists.txt       |   17 -
 .../unittests/SandboxIR/IntrinsicInstTest.cpp |   88 -
 llvm/unittests/SandboxIR/OperatorTest.cpp     |  141 -
 llvm/unittests/SandboxIR/PassTest.cpp         |  351 -
 llvm/unittests/SandboxIR/RegionTest.cpp       |  512 --
 llvm/unittests/SandboxIR/SandboxIRTest.cpp    | 6419 -----------------
 llvm/unittests/SandboxIR/TrackerTest.cpp      | 1920 -----
 llvm/unittests/SandboxIR/TypesTest.cpp        |  469 --
 llvm/unittests/SandboxIR/UtilsTest.cpp        |  249 -
 .../Transforms/Vectorize/CMakeLists.txt       |    2 -
 .../SandboxVectorizer/CMakeLists.txt          |   19 -
 .../SandboxVectorizer/DependencyGraphTest.cpp | 1192 ---
 .../SandboxVectorizer/InstrMapsTest.cpp       |  119 -
 .../SandboxVectorizer/IntervalTest.cpp        |  449 --
 .../SandboxVectorizer/LegalityTest.cpp        |  506 --
 .../SandboxVectorizerTest.cpp                 |   63 -
 .../SandboxVectorizer/SchedulerTest.cpp       |  881 ---
 .../SandboxVectorizer/SeedCollectorTest.cpp   |  565 --
 .../SandboxVectorizer/VecUtilsTest.cpp        |  619 --
 128 files changed, 33779 deletions(-)
 delete mode 100644 llvm/benchmarks/SandboxIRBench.cpp
 delete mode 100644 llvm/docs/SandboxIR.md
 delete mode 100644 llvm/docs/SandboxVectorizer.md
 delete mode 100644 llvm/include/llvm/SandboxIR/Argument.h
 delete mode 100644 llvm/include/llvm/SandboxIR/BasicBlock.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Constant.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Context.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Function.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Instruction.h
 delete mode 100644 llvm/include/llvm/SandboxIR/IntrinsicInst.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Module.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Operator.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Pass.h
 delete mode 100644 llvm/include/llvm/SandboxIR/PassManager.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Region.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Tracker.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Type.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Use.h
 delete mode 100644 llvm/include/llvm/SandboxIR/User.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Utils.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Value.h
 delete mode 100644 llvm/include/llvm/SandboxIR/Values.def
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCount.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintRegion.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysRevert.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h
 delete mode 100644 llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
 delete mode 100644 llvm/lib/SandboxIR/Argument.cpp
 delete mode 100644 llvm/lib/SandboxIR/BasicBlock.cpp
 delete mode 100644 llvm/lib/SandboxIR/CMakeLists.txt
 delete mode 100644 llvm/lib/SandboxIR/Constant.cpp
 delete mode 100644 llvm/lib/SandboxIR/Context.cpp
 delete mode 100644 llvm/lib/SandboxIR/Function.cpp
 delete mode 100644 llvm/lib/SandboxIR/Instruction.cpp
 delete mode 100644 llvm/lib/SandboxIR/Module.cpp
 delete mode 100644 llvm/lib/SandboxIR/Pass.cpp
 delete mode 100644 llvm/lib/SandboxIR/PassManager.cpp
 delete mode 100644 llvm/lib/SandboxIR/Region.cpp
 delete mode 100644 llvm/lib/SandboxIR/Tracker.cpp
 delete mode 100644 llvm/lib/SandboxIR/Type.cpp
 delete mode 100644 llvm/lib/SandboxIR/Use.cpp
 delete mode 100644 llvm/lib/SandboxIR/User.cpp
 delete mode 100644 llvm/lib/SandboxIR/Value.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/InstrMaps.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Interval.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/Scheduler.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/SeedCollector.cpp
 delete mode 100644 llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/X86/lit.local.cfg
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/X86/no_implicit_float.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/allow_files.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/boilerplate.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/pack.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/pack_reuse_basic.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/pack_reuse_end_to_end.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/print_region_pass.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/regions-from-bbs.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/scheduler.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/stop_at.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/stop_bndl.ll
 delete mode 100644 llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll
 delete mode 100644 llvm/unittests/SandboxIR/CMakeLists.txt
 delete mode 100644 llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/OperatorTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/PassTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/RegionTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/SandboxIRTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/TrackerTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/TypesTest.cpp
 delete mode 100644 llvm/unittests/SandboxIR/UtilsTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrMapsTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SeedCollectorTest.cpp
 delete mode 100644 llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp

diff --git a/llvm/Maintainers.md b/llvm/Maintainers.md
index 1eba955f9d6ed..d6d69aaf81532 100644
--- a/llvm/Maintainers.md
+++ b/llvm/Maintainers.md
@@ -101,13 +101,6 @@ asbirlea at google.com (email), [alinas](https://github.com/alinas) (GitHub)
 Madhur Amilkanthwar \
 madhura at nvidia.com (email), [madhur13490](https://github.com/madhur13490) (GitHub)
 
-#### SandboxVectorizer
-
-Vasileios Porpodas \
-vporpodas at google.com (email), [vporpo](https://github.com/vporpo) (GitHub) \
-Jorge Gorbe Moya \
-jgorbe at google.com (email), [slackito](https://github.com/slackito) (GitHub)
-
 #### ScalarEvolution, IndVarSimplify
 
 Philip Reames \
@@ -397,13 +390,6 @@ geek4civic at gmail.com (email), [chapuni](https://github.com/chapuni) (GitHub)
 Lang Hames \
 lhames at gmail.com (email), [lhames](https://github.com/lhames) (GitHub)
 
-#### SandboxIR
-
-Vasileios Porpodas \
-vporpodas at google.com (email), [vporpo](https://github.com/vporpo) (GitHub) \
-Jorge Gorbe Moya \
-jgorbe at google.com (email), [slackito](https://github.com/slackito) (GitHub)
-
 #### TableGen
 
 Rahul Joshi \
diff --git a/llvm/benchmarks/CMakeLists.txt b/llvm/benchmarks/CMakeLists.txt
index e411ed4326a36..40a11dc4ed16f 100644
--- a/llvm/benchmarks/CMakeLists.txt
+++ b/llvm/benchmarks/CMakeLists.txt
@@ -1,7 +1,6 @@
 set(LLVM_LINK_COMPONENTS
   AsmParser
   Core
-  SandboxIR
   Support)
 
 add_benchmark(DummyYAML DummyYAML.cpp PARTIAL_SOURCES_INTENDED)
@@ -9,7 +8,6 @@ add_benchmark(xxhash xxhash.cpp PARTIAL_SOURCES_INTENDED)
 add_benchmark(GetIntrinsicForClangBuiltin GetIntrinsicForClangBuiltin.cpp PARTIAL_SOURCES_INTENDED)
 add_benchmark(FormatVariadicBM FormatVariadicBM.cpp PARTIAL_SOURCES_INTENDED)
 add_benchmark(GetIntrinsicInfoTableEntriesBM GetIntrinsicInfoTableEntriesBM.cpp PARTIAL_SOURCES_INTENDED)
-add_benchmark(SandboxIRBench SandboxIRBench.cpp PARTIAL_SOURCES_INTENDED)
 add_benchmark(MustacheBench Mustache.cpp PARTIAL_SOURCES_INTENDED)
 add_benchmark(SpecialCaseListBM SpecialCaseListBM.cpp PARTIAL_SOURCES_INTENDED)
 
diff --git a/llvm/benchmarks/SandboxIRBench.cpp b/llvm/benchmarks/SandboxIRBench.cpp
deleted file mode 100644
index 45f352697868b..0000000000000
--- a/llvm/benchmarks/SandboxIRBench.cpp
+++ /dev/null
@@ -1,243 +0,0 @@
-//===- SandboxIRBench.cpp -------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// These tests measure the performance of some core SandboxIR functions and
-// compare them against LLVM IR.
-//
-//===----------------------------------------------------------------------===//
-
-#include "benchmark/benchmark.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Module.h"
-#include "llvm/Support/SourceMgr.h"
-#include <memory>
-#include <sstream>
-
-using namespace llvm;
-
-static std::unique_ptr<Module> parseIR(LLVMContext &C, const char *IR) {
-  SMDiagnostic Err;
-  std::unique_ptr<Module> M = parseAssemblyString(IR, Err, C);
-  if (!M)
-    Err.print("SandboxIRBench", errs());
-  return M;
-}
-
-enum class IR {
-  LLVM,           ///> LLVM IR
-  SBoxNoTracking, ///> Sandbox IR with tracking disabled
-  SBoxTracking,   ///> Sandbox IR with tracking enabled
-};
-// Traits to get llvm::BasicBlock/sandboxir::BasicBlock from IR::LLVM/IR::SBox.
-template <IR IRTy> struct TypeSelect {};
-template <> struct TypeSelect<IR::LLVM> {
-  using BasicBlock = llvm::BasicBlock;
-};
-template <> struct TypeSelect<IR::SBoxNoTracking> {
-  using BasicBlock = sandboxir::BasicBlock;
-};
-template <> struct TypeSelect<IR::SBoxTracking> {
-  using BasicBlock = sandboxir::BasicBlock;
-};
-
-template <IR IRTy>
-static typename TypeSelect<IRTy>::BasicBlock *
-genIR(std::unique_ptr<llvm::Module> &LLVMM, LLVMContext &LLVMCtx,
-      sandboxir::Context &Ctx,
-      std::function<std::string(unsigned)> GenerateIRStr,
-      unsigned NumInstrs = 0u) {
-  std::string IRStr = GenerateIRStr(NumInstrs);
-  LLVMM = parseIR(LLVMCtx, IRStr.c_str());
-  llvm::Function *LLVMF = &*LLVMM->getFunction("foo");
-  llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
-
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  sandboxir::BasicBlock *BB = &*F->begin();
-  // Start tracking if we are testing with tracking enabled.
-  if constexpr (IRTy == IR::SBoxTracking)
-    Ctx.save();
-
-  if constexpr (IRTy == IR::LLVM)
-    return LLVMBB;
-  else
-    return BB;
-}
-
-template <IR IRTy> static void finalize(sandboxir::Context &Ctx) {
-  // Accept changes if we are tracking.
-  if constexpr (IRTy == IR::SBoxTracking)
-    Ctx.accept();
-}
-
-static std::string generateBBWalkIR(unsigned Size) {
-  std::stringstream SS;
-  SS << "define void @foo(i32 %v1, i32 %v2) {\n";
-  for (auto Cnt : seq<unsigned>(0, Size))
-    SS << "  %add" << Cnt << " = add i32 %v1, %v2\n";
-  SS << "ret void";
-  SS << "}";
-  return SS.str();
-}
-
-template <IR IRTy> static void SBoxIRCreation(benchmark::State &State) {
-  static_assert(IRTy != IR::LLVM, "Expected SBoxTracking or SBoxNoTracking");
-  LLVMContext LLVMCtx;
-  unsigned NumInstrs = State.range(0);
-  std::unique_ptr<llvm::Module> LLVMM;
-  std::string IRStr = generateBBWalkIR(NumInstrs);
-  LLVMM = parseIR(LLVMCtx, IRStr.c_str());
-  llvm::Function *LLVMF = &*LLVMM->getFunction("foo");
-
-  for (auto _ : State) {
-    State.PauseTiming();
-    sandboxir::Context Ctx(LLVMCtx);
-    if constexpr (IRTy == IR::SBoxTracking)
-      Ctx.save();
-    State.ResumeTiming();
-
-    sandboxir::Function *F = Ctx.createFunction(LLVMF);
-    benchmark::DoNotOptimize(F);
-    State.PauseTiming();
-    if constexpr (IRTy == IR::SBoxTracking)
-      Ctx.accept();
-    State.ResumeTiming();
-  }
-}
-
-template <IR IRTy> static void BBWalk(benchmark::State &State) {
-  LLVMContext LLVMCtx;
-  sandboxir::Context Ctx(LLVMCtx);
-  unsigned NumInstrs = State.range(0);
-  std::unique_ptr<llvm::Module> LLVMM;
-  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateBBWalkIR, NumInstrs);
-  for (auto _ : State) {
-    // Walk LLVM Instructions.
-    for (auto &I : *BB)
-      benchmark::DoNotOptimize(I);
-  }
-}
-
-static std::string generateGetTypeIR(unsigned Size) {
-  return R"IR(
-define void @foo(i32 %v1, i32 %v2) {
-  %add = add i32 %v1, %v2
-  ret void
-}
-)IR";
-}
-
-template <IR IRTy> static void GetType(benchmark::State &State) {
-  LLVMContext LLVMCtx;
-  sandboxir::Context Ctx(LLVMCtx);
-  std::unique_ptr<llvm::Module> LLVMM;
-  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateGetTypeIR);
-  auto *I = &*BB->begin();
-  for (auto _ : State)
-    benchmark::DoNotOptimize(I->getType());
-}
-
-static std::string generateRAUWIR(unsigned Size) {
-  std::stringstream SS;
-  SS << "define void @foo(i32 %v1, i32 %v2) {\n";
-  SS << "  %def1 = add i32 %v1, %v2\n";
-  SS << "  %def2 = add i32 %v1, %v2\n";
-  for (auto Cnt : seq<unsigned>(0, Size))
-    SS << "  %add" << Cnt << " = add i32 %def1, %def1\n";
-  SS << "ret void";
-  SS << "}";
-  return SS.str();
-}
-
-template <IR IRTy> static void RAUW(benchmark::State &State) {
-  LLVMContext LLVMCtx;
-  sandboxir::Context Ctx(LLVMCtx);
-  std::unique_ptr<llvm::Module> LLVMM;
-  unsigned NumInstrs = State.range(0);
-  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateRAUWIR, NumInstrs);
-  auto It = BB->begin();
-  auto *Def1 = &*It++;
-  auto *Def2 = &*It++;
-  for (auto _ : State) {
-    Def1->replaceAllUsesWith(Def2);
-    Def2->replaceAllUsesWith(Def1);
-  }
-  finalize<IRTy>(Ctx);
-}
-
-static std::string generateRUOWIR(unsigned NumOperands) {
-  std::stringstream SS;
-  auto GenOps = [&SS, NumOperands]() {
-    for (auto Cnt : seq<unsigned>(0, NumOperands)) {
-      SS << "i8 %arg" << Cnt;
-      bool IsLast = Cnt + 1 == NumOperands;
-      if (!IsLast)
-        SS << ", ";
-    }
-  };
-
-  SS << "define void @foo(";
-  GenOps();
-  SS << ") {\n";
-
-  SS << "   call void @foo(";
-  GenOps();
-  SS << ")\n";
-  SS << "ret void";
-  SS << "}";
-  return SS.str();
-}
-
-template <IR IRTy> static void RUOW(benchmark::State &State) {
-  LLVMContext LLVMCtx;
-  sandboxir::Context Ctx(LLVMCtx);
-  std::unique_ptr<llvm::Module> LLVMM;
-  unsigned NumOperands = State.range(0);
-  auto *BB = genIR<IRTy>(LLVMM, LLVMCtx, Ctx, generateRUOWIR, NumOperands);
-
-  auto It = BB->begin();
-  auto *F = BB->getParent();
-  auto *Arg0 = F->getArg(0);
-  auto *Arg1 = F->getArg(1);
-  auto *Call = &*It++;
-  for (auto _ : State)
-    Call->replaceUsesOfWith(Arg0, Arg1);
-  finalize<IRTy>(Ctx);
-}
-
-// Measure the time it takes to create Sandbox IR without/with tracking.
-BENCHMARK(SBoxIRCreation<IR::SBoxNoTracking>)
-    ->Args({10})
-    ->Args({100})
-    ->Args({1000});
-BENCHMARK(SBoxIRCreation<IR::SBoxTracking>)
-    ->Args({10})
-    ->Args({100})
-    ->Args({1000});
-
-BENCHMARK(GetType<IR::LLVM>);
-BENCHMARK(GetType<IR::SBoxNoTracking>);
-
-BENCHMARK(BBWalk<IR::LLVM>)->Args({1024});
-BENCHMARK(BBWalk<IR::SBoxTracking>)->Args({1024});
-
-BENCHMARK(RAUW<IR::LLVM>)->Args({512});
-BENCHMARK(RAUW<IR::SBoxNoTracking>)->Args({512});
-BENCHMARK(RAUW<IR::SBoxTracking>)->Args({512});
-
-BENCHMARK(RUOW<IR::LLVM>)->Args({4096});
-BENCHMARK(RUOW<IR::SBoxNoTracking>)->Args({4096});
-BENCHMARK(RUOW<IR::SBoxTracking>)->Args({4096});
-
-BENCHMARK_MAIN();
diff --git a/llvm/docs/SandboxIR.md b/llvm/docs/SandboxIR.md
deleted file mode 100644
index d2b612ba95ef1..0000000000000
--- a/llvm/docs/SandboxIR.md
+++ /dev/null
@@ -1,109 +0,0 @@
-# Sandbox IR: A transactional layer over LLVM IR
-
-Sandbox IR is an IR layer on top of LLVM IR that allows you to save/restore its state.
-
-# Quick Start Notes
-
-Within your LLVM pass:
-
-``` C++
-// 1. Include the necessary Sandbox IR header files.
-#include "llvm/SandboxIR/Context.h
-#include "llvm/SandboxIR/Function.h
-
-// 2. Create a sandboxir::Context using LLVMContext `LLVMCtx`.
-sandboxir::Context Ctx(LLVMCtx);
-
-// 3. Create a sandboxir::Function using LLVM IR Function `LLVMF`.
-auto *F = Ctx.createFunction(LLVMF);
-
-// ... Use Sandbox IR in `F` as usual, e.g., iterating, modifying it etc. ...
-
-// 4. Save state when needed.
-Ctx.save();
-
-// ... Modify Sandbox IR ...
-
-// 5. Revert to the saved state.
-Ctx.revert();
-```
-
-Make sure you link against `SandboxIR` in `CMakeLists.txt`:
-
-```
-LINK_COMPONENTS
-...
-SandboxIR
-...
-```
-
-# API
-The Sandbox IR API is designed to feel like LLVM, replicating many common API classes and functions to mirror the LLVM API.
-The class hierarchy is similar (but in the `llvm::sandboxir` namespace).
-For example here is a small part of it:
-```
-namespace sandboxir {
-              Value
-              /  \
-            User BasicBlock ...
-           /   \
-  Instruction Constant
-        /
-     ...
-}
-```
-
-# Design
-
-## Sandbox IR Value <-> LLVM IR Value Mapping
-Each LLVM IR Value maps to a single Sandbox IR Value.
-The reverse is also true in most cases, except for Sandbox IR Instructions that map to more than one LLVM IR Instruction.
-Such instructions can be defined in extensions of the base Sandbox IR.
-
-- Forward mapping: Sandbox IR Value -> LLVM IR Value
-Each Sandbox IR Value contains an `llvm::Value *Val` member variable that points to the corresponding LLVM IR Value.
-
-- Reverse mapping: LLVM IR Value -> Sandbox IR Value
-This mapping is stored in `sandboxir::Context::LLVMValueToValue`.
-
-For example `sandboxir::User::getOperand(OpIdx)` for a `sandboxir::User *U` works as follows:
-- First we find the LLVM User: `llvm::User *LLVMU = U->Val`.
-- Next we get the LLVM Value operand: `llvm::Value *LLVMOp = LLVMU->getOperand(OpIdx)`
-- Finally we get the Sandbox IR operand that corresponds to `LLVMOp` by querying the map in the Sandbox IR context: `retrun Ctx.getValue(LLVMOp)`.
-
-## Sandbox IR is Write-Through
-Sandbox IR is designed to rely on LLVM IR for its state.
-So any change made to Sandbox IR objects directly updates the corresponding LLVM IR.
-
-This has the following benefits:
-- It minimizes the replication of state, and
-- It makes sure that Sandbox IR and LLVM IR are always in sync, which helps avoid bugs and removes the need for a lowering step.
-- No need for serialization/de-serialization infrastructure as we can rely on LLVM IR for it.
-- One can pass actual `llvm::Instruction`s to cost modeling APIs.
-
-Sandbox IR API functions that modify the IR state call the corresponding LLVM IR function that modifies the LLVM IR's state.
-For example, for `sandboxir::User::setOperand(OpIdx, sandboxir::Value *Op)`:
-- We get the corresponding LLVM User: `llvm::User *LLVMU = cast<llvm::User>(Val)`
-- Next we get the corresponding LLVM Operand: `llvm::Value *LLVMOp = Op->Val`
-- Finally we modify `LLVMU`'s operand: `LLVMU->setOperand(OpIdx, LLVMOp)
-
-## IR Change Tracking
-Sandbox IR's state can be saved and restored.
-This is done with the help of the tracker component that is tightly coupled to the public Sandbox IR API functions.
-Please note that nested saves/restores are currently not supported.
-
-To save the state and enable tracking the user needs to call `sandboxir::Context::save()`.
-From this point on any change made to the Sandbox IR state will automatically create a change object and register it with the tracker, without any intervention from the user.
-The changes are accumulated in a vector within the tracker.
-
-To rollback to the saved state the user needs to call `sandboxir::Context::revert()`.
-Reverting back to the saved state is a matter of going over all the accumulated changes in reverse and undoing each individual change.
-
-To accept the changes made to the IR the user needs to call `sandboxir::Context::accept()`.
-Internally this will go through the changes and run any finalization required.
-
-Please note that after a call to `revert()` or `accept()` tracking will stop.
-To start tracking again, the user needs to call `save()`.
-
-# Users of Sandbox IR
-- [The Sandbox Vectorizer](project:SandboxVectorizer.md)
diff --git a/llvm/docs/SandboxVectorizer.md b/llvm/docs/SandboxVectorizer.md
deleted file mode 100644
index 2b2401a4bf92b..0000000000000
--- a/llvm/docs/SandboxVectorizer.md
+++ /dev/null
@@ -1,280 +0,0 @@
-# The Sandbox Vectorizer
-
-```{contents}
-:depth: 4
-```
-
-The Sandbox Vectorizer is a framework for building modular vectorization pipelines on top of [Sandbox IR](#SandboxIR) transactional IR, with a focus on ease of development and testing.
-The default pipeline currently implements a simple SLP-style bottom-up vectorization pipeline.
-
-The transactional IR helps in several ways:
-- It enables a modular design where:
-  - Each vectorization transformation/optimization can be implemented as a separate internal pass that uses actual IR as its input and output.
-  - You can still make end-to-end profitability decisions (i.e., across multiple internal passes), even when the transformations are implemented as separate internal passes.
-  - Each transformation/optimization internal pass can be tested in isolation with lit-tests, as opposed to end-to-end tests.
-- It enables a simpler design by enabling each internal pass commit its state to the IR itself rather than updating helper data-structures that live across the pipeline.
-- Its extensive callback interface helps remove the burden of manually maintaining the vectorizer's components while the IR is being modified.
-
-## Usage
-
-The Sandbox Vectorizer is currently under development and is not enabled by default.
-So in order to use it you have to explicitly run the pass with `opt` like so:
-
-```shell
-$ opt -p=sandbox-vectorizer file.ll
-```
-
-## Internal Pass Pipeline
-
-The Sandbox Vectorizer is designed to be modular and as such it has its own internal pass-pipeline that operates on Sandbox IR.
-Each vectorization phase is implemented as a separate internal pass that runs by the Sandbox Vectorizer's internal pass manager.
-The Sandbox Vectorizer pass itself is an LLVM Function pass.
-
-The following figure shows the basic structure of the Sandbox Vectorizer LLVM Function pass.
-The first component is the conversion of `LLVM IR to Sandbox IR` which converts the LLVM Function to a `sandboxir::Function`.
-From this point on the pass operates on Sandbox IR.
-The main entry point to the internal pass pipeline is the `Sandbox IR Function Pass Manger`, which runs all registered function passes.
-The following figure lists only a single Sandbox IR function pass, the `Seed Collection Pass` which goes over the instructions in the function and collects vectorization candidates, like Stores to consecutive memory addresses, and forms a [Region](#region).
-The `Seed Collection Pass` itself contains its own Region pass pipeline, which in the following example contains a `Transaction Save` pass, a `Bottom-Up Vectorization` pass, a `Pack Reuse` pass and a `Transaction Accept/Revert` pass.
-
-```
-┌────────────────────────────────── Sandbox Vectorizer LLVM Function Pass ─────────────────────────────┐
-│                                                                                                      │
-│ ┌───────┐ ┌────────────────────────── sandboxir::Function Pass Manager ────────────────────────────┐ │
-│ │       │ │                                                                                        │ │
-│ │       │ │ ┌────────────────────────────── Seed Collection Pass ──────────────────────────────┐   │ │
-│ │       │ │ │                                                                                  │   │ │
-│ │       │ │ │ ┌───────┐  For   ┌─────────────── sanboxir::Region Pass Manager ───────────────┐ │   │ │
-│ │LLVM IR│ │ │ │Collect│  each  │ ┌───────────┐ ┌────────────────┐ ┌───────┐ ┌──────────────┐ │ │   │ │
-│ │  to   │ │ │ │ Seeds │ Region │ │Transaction│ │   Bottom─Up    │ │ Pack  │ │ Transaction  │ │ │   │ │
-│ │Sandbox│ │ │ │Create │ ─────> │ │   Save    │ │ Vectorization  │ │ Reuse │ │Accept/Revert │ │ │   │ │
-│ │  IR   │ │ │ │Regions│        │ └───────────┘ └────────────────┘ └───────┘ └──────────────┘ │ │   │ │
-│ │       │ │ │ └───────┘        └─────────────────────────────────────────────────────────────┘ │   │ │
-│ │       │ │ │                                                                                  │...│ │
-│ │       │ │ └──────────────────────────────────────────────────────────────────────────────────┘   │ │
-│ │       │ │                                                                                        │ │
-│ └───────┘ └────────────────────────────────────────────────────────────────────────────────────────┘ │
-│                                                                                                      │
-└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
-```
-
-You can specify your own custom pipeline with the `-sbvec-passes=` argument to `opt`.
-The pipeline shown above is equivalent to this:
-
-```shell
-$ opt -p=sandbox-vectorizer -sbvec-passes='seed-collection<tr-save,bottom-up-vec,pack-reuse,tr-accept>' file.ll
-```
-
-If the user does not define a pipeline, the Sandbox Vectorizer will run its default pass-pipeline, which is set in the constructor of the `SandboxVectorizerPass`.
-
-## Sandbox Vectorizer Passes
-
-The passes in the vectorization pipeline can be found in `Transforms/Vectorize/SandboxVectorizer/Passes` and they are registered in `lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def`.
-
-There are two types of passes: [Transformation Passes](#transformation-passes) that do the actual vectorization-related transformations and optimizations, and [Helper Passes](#helper-passes) that are helping with things like managing the IR transactions, and test-specific things like building regions.
-
-### Transformation Passes
-
-|  **Pass Name**            |         **File Name**       | **Type** |                     **Description**                     |
-|---------------------------|-----------------------------|----------|---------------------------------------------------------|
-| `seed-collection`         | SeedCollection.h            | Function | Collects the instructions to start vectorizing from, creates a region and runs the region-pass pipeline |
-| `bottom-up-vec`           | BottomUpVec.h               | Region   | An SLP-style bottom-up vectorizer. It can vectorize both scalars and vectors |
-| `pack-reuse`              | PackReuse.h                 | Region   | A pass that de-duplicates packs                         |
-
-### Helper Passes
-
-|  **Pass Name**            |         **File Name**       | **Type** |                     **Description**                     |
-|---------------------------|-----------------------------|----------|---------------------------------------------------------|
-| `tr-save`                 | TransactionSave.h           | Region   | Creates a checkpoint of the IR (i.e., saves state)      |
-| `tr-accept`               | TransactionAlwaysAccept.h   | Region   | Unconditionally accepts the IR state                    |
-| `tr-revert`               | TransactionAlwaysRevert.h   | Region   | Unconditionally rejects the IR state                    |
-| `tr-accept-or-revert`     | TransactionAcceptOrRevert.h | Region   | Checks cost model and either accepts or reverts the IR  |
-| `null`                    | NullPass.h                  | Region   | A dummy test pass that just returns                     |
-| `print-region`            | PrintRegion.h               | Region   | A test pass that prints the region's IR                 |
-| `print-instruction-count` | PrintInstructionCount.h     | Region   | A test pass that counts instructions                    |
-| `regions-from-metadata`   | RegionsFromMetadata.h       | Function | Builds regions from IR metadata and runs a pipeline of region passes for each one of them. Used in lit tests for testing region passes in isolation |
-| `regions-from-bbs`        | RegionsFromBBs.h            | Function | Builds a region for each BB, adding all BB instructions into each region. Used in lit tests for stress-testing region passes in isolation |
-
-## Region
-
-In a traditional compiler pass pipeline, transformations usually operate at a function level with function passes.
-This introduces an issue in passes like the vectorizer that operate on small sections of a function (that we refer to as "Regions") but apply a pipeline of transformations on each section horizontally, and evaluate profitability end-to-end on each region as shown below:
-
-```
- Function
-┌─────────┐    Transform    Transform  ...    Transform
-│         │        A            B                 Z
-│┌───────┐│    ┌───────┐    ┌───────┐         ┌───────┐     Evaluate
-││Region1││ ─> │       │ ─> │       │  ... ─> │       │   Profitability
-│└───────┘│    └───────┘    └───────┘         └───────┘
-│         │
-│┌───────┐│    ┌───────┐    ┌───────┐         ┌───────┐     Evaluate
-││Region2││ ─> │       │ ─> │       │  ... ─> │       │   Profitability
-│└───────┘│    └───────┘    └───────┘         └───────┘
-│         │
-│         │
-└─────────┘
-```
-
-If transformations like `A`, `B`, etc. are implemented as function passes, then they will apply their transformations across the whole function, spanning multiple regions, as they have not been designed to stay within a region.
-The problem is that profitability evaluation will average out the profitability across all regions within the function, leading to a sub-optimal outcome.
-
-This is the problem that the "Region" structure is solving.
-It provides a way of tagging the instructions within a Region with metadata and also provides the necessary APIs for iterating through the Region instructions and operating on them.
-
-The Region allows us to implement the vectorization pipeline as a pipeline of Region passes, each one operating on a specific code section.
-At the end of the region pass pipeline we can evaluate profitability across multiple region passes in the pipeline (if needed) but within a Region, and either accept or revert the transformations.
-
-### Adding Instructions to the Region
-
-The Region grows automatically and is maintained transparently:
-Whenever you create a new instruction it is automatically added to the Region, and whenever an instruction is deleted it gets removed from the Region.
-The reasoning is that vectorization passes work: (i) by creating new vector instructions, (ii) by adding necessary packing/unpacking instructions, or (iii) by deleting the original instructions that got replaced by the vectorized ones.
-
-Internally this is done with the help of the callback API of Sandbox IR.
-The current Region gets notified that either an instruction got created or removed and the Region is maintained accordingly.
-
-### Region Example
-
-The following example defines a Region (with `!0 = distinct !{!"sandboxregion"}`), containing two instructions: `%i1 = add i8 %v, 1` and `%i2 = add i8 %v, 2` in no particular order.
-
-```llvm
-   define void @region_example(i8 %v) {
-     %i0 = add i8 %v, 0
-     %i1 = add i8 %v, 1, !sandboxvec !0
-     %i2 = add i8 %v, 2, !sandboxvec !0
-     ret void
-   }
-   !0 = distinct !{!"sandboxregion"}
-```
-
-The Region class API allows you to iterate through the region instructions like with a range loop:
-
-```c++
-   for (auto *I : Rgn)
-     // Do something with `I`
-```
-
-### Region Auxiliary Vector
-
-On top of tagging instructions the Region has a second functionality: it also supports a way of defining an ordered list of instructions.
-This helps passes communicate such instruction lists from one pass to another, if needed, in an explicit way that is encoded in IR metadata.
-This removes the need for sharing helper data-structures across passes.
-The end result is that you can fully describe such ordered list of instructions in IR and can reproduce the pass behavior using just IR as input, allowing you to test it with lit tests.
-
-The Region API for the auxiliary vector is straightforward.
-It provides the `getAux()` getter method that simply returns the auxiliary vector.
-
-The auxiliary vector instructions are marked with `!sandboxaux` followed by an index, which in the following example are `!1`and `!2` which correspond to 0 and 1 respectively.
-So the following example defines one region (region `!0`) containing all three `add` instructions, two of which belong to the auxiliary vector: `[%i1 = add i8 %v, 1, %i2 = add i8 %v, 2]`.
-
-```llvm
-   define void @region_aux_example(i8 %v) {
-     %i0 = add i8 %v, 0  !sandboxvec !0
-     %i1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !1
-     %i2 = add i8 %v, 2, !sandboxvec !0, !sandboxaux !2
-     ret void
-   }
-   !0 = distinct !{!"sandboxregion"}
-   !1 = !{i32 0}
-   !2 = !{i32 1}
-```
-
-The auxiliary vector is currently used by the Seed Collection pass to communicate a group of seed instructions to the Bottom-Up-Vectorizer pass.
-
-## Testing Sandbox Vectorizer Passes In Isolation
-
-One of the great things about the Sandbox Vectorizer is that it allows you to test each internal pass in isolation with lit-tests.
-
-Testing Function passes is straightforward, just run `FUNCTION_PASS` in isolation with `-sbvec-passes`, like so:
-```shell
-$ opt -p=sandbox-vectorizer -sbvec-passes='FUNCTION_PASS'
-```
-
-Testing [Region](#region) passes is also possible, since a Region can be defined with IR using metadata, as described in [Region Example](#region-example).
-We need to run the `regions-from-metadata` helper pass before the Region pass to be tested.
-This helper pass parses the IR metadata looking for Region metadata, then it creates the corresponding Regions and finally runs a Region pass pipeline on each Region.
-
-So here is what we need to do for a working lit-test of a Region pass:
-
-1. Define the region with metadata as explained in [Region Example](#region-example).
-2. Define the pass pipeline which should include the following passes:
-   - The `regions-from-metadata` pass that will form a region and will build a Region pass-manager.
-   - The `REGION_PASS` being tested enclosed in `< >`, as the only pass in the region pass pipeline owned by the `regions-from-metadata` pass.
-
-So overall the pipeline looks like:
-```shell
-$ opt -p=sandbox-vectorizer -sbvec-passes='regions-from-metadata<REGION_PASS>'
-```
-
-The reason for enclosing the pass in `< >` is that `regions-from-metadata` is a Region pass manager function pass that accepts string arguments within `< >`.
-It will parse the string argument, looking for a comma-separated list of Region pass names, and will populate the pipeline with these passes.
-So in this case `REGION_PASS` is the only pass name found, so it will be the only pass added to the region pass pipeline.
-
-For example, `'regions-from-metadata<region_pass1,region_pass2>'` would create regions from metadata, and for each one of them it would run the pipeline: `region_pass1` followed by `region_pass2`.
-
-## Stress-testing a Region Pass in Isolation
-
-A region pass can be stress-tested in isolation using with BB-sized Regions, using the `regions-from-bbs` helper pass.
-The pass will go through the BBs in the function, create a region including all BB instructions for each one of them.
-Then it will run the region pass pipeline for each BB-sized Region.
-
-For example:
-```shell
-$ opt -p=sandbox-vectorizer -sbvec-passes='regions-from-bbs<REGION_PASS>'
-```
-
-## Components
-
-The Sandbox Vectorizer implements several components that are used by one or more internal passes.
-These components are designed as standalone components, which makes them easy to use when needed.
-They are the building blocks for the vectorization passes, providing things like vectorization legality checks.
-
-### Legality Analysis
-
-This is the main entry point for vectorization legality checks.
-It checks if a bundle of instructions is legal to vectorize and returns how the vectorizer should generate code for it, i.e., whether it should trivially widen it, whether it should reuse an existing vector, whether it should pack scalars into vectors and so on.
-Legality testing includes tests like checking the instruction types, the opcodes etc. but it also checks for dependency violations by querying the [Scheduler](#scheduler).
-
-The main API function is `LegalityAnalysis::canVectorize()`.
-
-### Scheduler
-
-This component is an lazy list-scheduler that relies on a [Dependency Graph (DAG)](#dependency-graph) for representing the dependencies.
-It is "lazy" in the sense that it does not operate on a whole BB, but instead only on the instructions spanning the bundle we are attempting to schedule.
-The main interface to the scheduler is `Scheduler::trySchedule()`.
-
-Please note that the current implementation does not use a separate "staging" instruction list for the scheduled instructions.
-Instead it physically moves the instructions in the IR chain, which is fine since we are working with a transactional IR.
-This is not a requirement though for correct operation.
-A more traditional scheduler with a separate instruction list would also work fine.
-
-### Dependency Graph
-
-This is a lazily-built Directed Acyclic Graph (DAG) that encodes both memory and def-use dependencies.
-Each node of the graph points to a Sandbox IR Instruction.
-An edge between two nodes `A->B` suggests that `A`'s instruction should come before `B`'s instruction in the program.
-The DAG uses [Alias Analysis](#AliasAnalysis) for finding the memory dependencies.
-Note that even though the DAG Node provides an API for iterating over both memory and use-def dependencies, it actually relies on the LLVM IR use-def edges internally and won't replicate them to save memory.
-
-The graph is built lazily, meaning that it won't be built for the whole BB in one go.
-Instead it will span only the range of instruction needed by the scheduler.
-As we keep scheduling more instructions, the graph will grow on-demand following the needs of the scheduler.
-The main interface function for the Dependency Graph is `DependencyGraph::extend()`.
-
-### InstrMaps
-
-Instruction Maps is a helper data structure that maintains a mapping between the original (often scalar) instructions and their corresponding vector instructions and the reverse.
-It is used by the `bottom-up-vec` region pass for tracing vector instructions back to the original instructions and the reverse.
-
-
-## Debugging
-
-There are a couple of useful `cl::opt` options for debugging the vectorizer, that are particularly useful for bisection debugging:
-
-| **Option**                      | **Description**                                    |
-|---------------------------------|----------------------------------------------------|
-| `-sbvec-allow-files=<regex>`    | Enables the Sandbox Vectorizer as a whole only for source files matching the comma-separated list of regular expressions. |
-| `-sbvec-passes=<pass-pipeline>` | Allows you to change the internal pass pipeline and skip any potentially broken passes. |
-| `-sbvec-stop-at=<num>`          | Will stop invoking the bottom-up-vectorizer if the invocation count is greater or equal to `<num>`. |
-| `-sbvec-stop-bndl=<num>`        | Limits the vectorization depth of the bottom-up vectorizer to `<num>`. This means that the vectorizer will emit a pack and stop vectorizing further. |
diff --git a/llvm/docs/UserGuides.rst b/llvm/docs/UserGuides.rst
index 0551c8b60a62d..0a299ce6fce00 100644
--- a/llvm/docs/UserGuides.rst
+++ b/llvm/docs/UserGuides.rst
@@ -70,7 +70,6 @@ intermediate LLVM representation.
    RISCV/RISCVVectorExtension
    SourceLevelDebugging
    SPIRVUsage
-   SandboxIR
    StackSafetyAnalysis
    SupportLibrary
    TableGen/index
@@ -304,8 +303,5 @@ Additional Topics
 :doc:`RISCV/RISCVVectorExtension`
    This document describes how the RISC-V Vector extension can be expressed in LLVM IR and how code is generated for it in the backend.
 
-:doc:`Sandbox IR <SandboxIR>`
-   This document describes the design and usage of Sandbox IR, a transactional layer over LLVM IR.
-
 :doc:`Telemetry`
    This document describes the Telemetry framework in LLVM.
diff --git a/llvm/docs/Vectorizers.rst b/llvm/docs/Vectorizers.rst
index ed11dfe10b471..deddf1012c005 100644
--- a/llvm/docs/Vectorizers.rst
+++ b/llvm/docs/Vectorizers.rst
@@ -479,12 +479,3 @@ through clang using the command line flag:
 .. code-block:: console
 
    $ clang -fno-slp-vectorize file.c
-
-The Sandbox Vectorizer
-======================
-.. toctree::
-   :hidden:
-
-   SandboxVectorizer
-
-The :doc:`Sandbox Vectorizer <SandboxVectorizer>` is an experimental framework for building modular vectorization pipelines on top of :doc:`Sandbox IR <SandboxIR>`, with a focus on ease of testing and ease of development.
diff --git a/llvm/include/llvm/SandboxIR/Argument.h b/llvm/include/llvm/SandboxIR/Argument.h
deleted file mode 100644
index aed886e8f22f2..0000000000000
--- a/llvm/include/llvm/SandboxIR/Argument.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- Argument.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_ARGUMENT_H
-#define LLVM_SANDBOXIR_ARGUMENT_H
-
-#include "llvm/IR/Argument.h"
-#include "llvm/SandboxIR/Value.h"
-
-namespace llvm::sandboxir {
-
-/// Argument of a sandboxir::Function.
-class Argument : public sandboxir::Value {
-  Argument(llvm::Argument *Arg, sandboxir::Context &Ctx)
-      : Value(ClassID::Argument, Arg, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::Argument;
-  }
-#ifndef NDEBUG
-  void verify() const final {
-    assert(isa<llvm::Argument>(Val) && "Expected Argument!");
-  }
-  void printAsOperand(raw_ostream &OS) const;
-  void dumpOS(raw_ostream &OS) const final;
-#endif
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_ARGUMENT_H
diff --git a/llvm/include/llvm/SandboxIR/BasicBlock.h b/llvm/include/llvm/SandboxIR/BasicBlock.h
deleted file mode 100644
index a8dd5085e809a..0000000000000
--- a/llvm/include/llvm/SandboxIR/BasicBlock.h
+++ /dev/null
@@ -1,113 +0,0 @@
-//===- BasicBlock.h ---------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_BASICBLOCK_H
-#define LLVM_SANDBOXIR_BASICBLOCK_H
-
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-class BasicBlock;
-class Function;
-class Instruction;
-
-/// Iterator for `Instruction`s in a `BasicBlock.
-/// \Returns an sandboxir::Instruction & when derereferenced.
-class BBIterator {
-public:
-  using difference_type = std::ptrdiff_t;
-  using value_type = Instruction;
-  using pointer = value_type *;
-  using reference = value_type &;
-  using iterator_category = std::bidirectional_iterator_tag;
-
-private:
-  llvm::BasicBlock *BB;
-  llvm::BasicBlock::iterator It;
-  Context *Ctx;
-  LLVM_ABI pointer getInstr(llvm::BasicBlock::iterator It) const;
-
-public:
-  BBIterator() : BB(nullptr), Ctx(nullptr) {}
-  BBIterator(llvm::BasicBlock *BB, llvm::BasicBlock::iterator It, Context *Ctx)
-      : BB(BB), It(It), Ctx(Ctx) {}
-  reference operator*() const { return *getInstr(It); }
-  LLVM_ABI BBIterator &operator++();
-  BBIterator operator++(int) {
-    auto Copy = *this;
-    ++*this;
-    return Copy;
-  }
-  LLVM_ABI BBIterator &operator--();
-  BBIterator operator--(int) {
-    auto Copy = *this;
-    --*this;
-    return Copy;
-  }
-  bool operator==(const BBIterator &Other) const {
-    assert(Ctx == Other.Ctx && "BBIterators in different context!");
-    return It == Other.It;
-  }
-  bool operator!=(const BBIterator &Other) const { return !(*this == Other); }
-  /// \Returns the SBInstruction that corresponds to this iterator, or null if
-  /// the instruction is not found in the IR-to-SandboxIR tables.
-  pointer get() const { return getInstr(It); }
-  /// \Returns the parent BB.
-  LLVM_ABI BasicBlock *getNodeParent() const;
-};
-
-/// Contains a list of sandboxir::Instruction's.
-class BasicBlock : public Value {
-  /// Builds a graph that contains all values in \p BB in their original form
-  /// i.e., no vectorization is taking place here.
-  LLVM_ABI void buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB);
-  friend class Context;     // For `buildBasicBlockFromIR`
-  friend class Instruction; // For LLVM Val.
-
-  BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
-      : Value(ClassID::Block, BB, SBCtx) {
-    buildBasicBlockFromLLVMIR(BB);
-  }
-
-public:
-  ~BasicBlock() override = default;
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == Value::ClassID::Block;
-  }
-  LLVM_ABI Function *getParent() const;
-  using iterator = BBIterator;
-  LLVM_ABI iterator begin() const;
-  iterator end() const {
-    auto *BB = cast<llvm::BasicBlock>(Val);
-    return iterator(BB, BB->end(), &Ctx);
-  }
-  std::reverse_iterator<iterator> rbegin() const {
-    return std::make_reverse_iterator(end());
-  }
-  std::reverse_iterator<iterator> rend() const {
-    return std::make_reverse_iterator(begin());
-  }
-  Context &getContext() const { return Ctx; }
-  LLVM_ABI Instruction *getTerminator() const;
-  bool empty() const { return begin() == end(); }
-  LLVM_ABI Instruction &front() const;
-  LLVM_ABI Instruction &back() const;
-
-#ifndef NDEBUG
-  void verify() const final;
-  void dumpOS(raw_ostream &OS) const final;
-#endif
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_BASICBLOCK_H
diff --git a/llvm/include/llvm/SandboxIR/Constant.h b/llvm/include/llvm/SandboxIR/Constant.h
deleted file mode 100644
index 6f682a7059d10..0000000000000
--- a/llvm/include/llvm/SandboxIR/Constant.h
+++ /dev/null
@@ -1,1519 +0,0 @@
-//===- Constant.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_CONSTANT_H
-#define LLVM_SANDBOXIR_CONSTANT_H
-
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constant.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/GlobalAlias.h"
-#include "llvm/IR/GlobalIFunc.h"
-#include "llvm/IR/GlobalObject.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/GlobalVariable.h"
-#include "llvm/SandboxIR/Argument.h"
-#include "llvm/SandboxIR/BasicBlock.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Type.h"
-#include "llvm/SandboxIR/User.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-class BasicBlock;
-class Function;
-
-class Constant : public sandboxir::User {
-protected:
-  Constant(llvm::Constant *C, sandboxir::Context &SBCtx)
-      : sandboxir::User(ClassID::Constant, C, SBCtx) {}
-  Constant(ClassID ID, llvm::Constant *C, sandboxir::Context &SBCtx)
-      : sandboxir::User(ID, C, SBCtx) {}
-  friend class ConstantInt; // For constructor.
-  friend class Function;    // For constructor
-  friend class Context;     // For constructor.
-  Use getOperandUseInternal(unsigned OpIdx, bool Verify) const override {
-    return getOperandUseDefault(OpIdx, Verify);
-  }
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    switch (From->getSubclassID()) {
-#define DEF_CONST(ID, CLASS) case ClassID::ID:
-#include "llvm/SandboxIR/Values.def"
-      return true;
-    default:
-      return false;
-    }
-  }
-  sandboxir::Context &getParent() const { return getContext(); }
-  unsigned getUseOperandNo(const Use &Use) const override {
-    return getUseOperandNoDefault(Use);
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::Constant>(Val) && "Expected Constant!");
-  }
-  void dumpOS(raw_ostream &OS) const override;
-#endif
-};
-
-// TODO: This should inherit from ConstantData.
-class ConstantInt : public Constant {
-  ConstantInt(llvm::ConstantInt *C, Context &Ctx)
-      : Constant(ClassID::ConstantInt, C, Ctx) {}
-  friend class Context; // For constructor.
-
-  Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
-    llvm_unreachable("ConstantInt has no operands!");
-  }
-
-public:
-  LLVM_ABI static ConstantInt *getTrue(Context &Ctx);
-  LLVM_ABI static ConstantInt *getFalse(Context &Ctx);
-  LLVM_ABI static ConstantInt *getBool(Context &Ctx, bool V);
-  LLVM_ABI static Constant *getTrue(Type *Ty);
-  LLVM_ABI static Constant *getFalse(Type *Ty);
-  LLVM_ABI static Constant *getBool(Type *Ty, bool V);
-
-  /// If Ty is a vector type, return a Constant with a splat of the given
-  /// value. Otherwise return a ConstantInt for the given value.
-  LLVM_ABI static ConstantInt *get(Type *Ty, uint64_t V, bool IsSigned = false);
-
-  /// Return a ConstantInt with the specified integer value for the specified
-  /// type. If the type is wider than 64 bits, the value will be zero-extended
-  /// to fit the type, unless IsSigned is true, in which case the value will
-  /// be interpreted as a 64-bit signed integer and sign-extended to fit
-  /// the type.
-  /// Get a ConstantInt for a specific value.
-  LLVM_ABI static ConstantInt *get(IntegerType *Ty, uint64_t V,
-                                   bool IsSigned = false);
-
-  /// Return a ConstantInt with the specified value for the specified type. The
-  /// value V will be canonicalized to a an unsigned APInt. Accessing it with
-  /// either getSExtValue() or getZExtValue() will yield a correctly sized and
-  /// signed value for the type Ty.
-  /// Get a ConstantInt for a specific signed value.
-  LLVM_ABI static ConstantInt *getSigned(IntegerType *Ty, int64_t V);
-  LLVM_ABI static Constant *getSigned(Type *Ty, int64_t V);
-
-  /// Return a ConstantInt with the specified value and an implied Type. The
-  /// type is the integer type that corresponds to the bit width of the value.
-  LLVM_ABI static ConstantInt *get(Context &Ctx, const APInt &V);
-
-  /// Return a ConstantInt constructed from the string strStart with the given
-  /// radix.
-  LLVM_ABI static ConstantInt *get(IntegerType *Ty, StringRef Str,
-                                   uint8_t Radix);
-
-  /// If Ty is a vector type, return a Constant with a splat of the given
-  /// value. Otherwise return a ConstantInt for the given value.
-  LLVM_ABI static Constant *get(Type *Ty, const APInt &V);
-
-  /// Return the constant as an APInt value reference. This allows clients to
-  /// obtain a full-precision copy of the value.
-  /// Return the constant's value.
-  inline const APInt &getValue() const {
-    return cast<llvm::ConstantInt>(Val)->getValue();
-  }
-
-  /// getBitWidth - Return the scalar bitwidth of this constant.
-  unsigned getBitWidth() const {
-    return cast<llvm::ConstantInt>(Val)->getBitWidth();
-  }
-  /// Return the constant as a 64-bit unsigned integer value after it
-  /// has been zero extended as appropriate for the type of this constant. Note
-  /// that this method can assert if the value does not fit in 64 bits.
-  /// Return the zero extended value.
-  inline uint64_t getZExtValue() const {
-    return cast<llvm::ConstantInt>(Val)->getZExtValue();
-  }
-
-  /// Return the constant as a 64-bit integer value after it has been sign
-  /// extended as appropriate for the type of this constant. Note that
-  /// this method can assert if the value does not fit in 64 bits.
-  /// Return the sign extended value.
-  inline int64_t getSExtValue() const {
-    return cast<llvm::ConstantInt>(Val)->getSExtValue();
-  }
-
-  /// Return the constant as an llvm::MaybeAlign.
-  /// Note that this method can assert if the value does not fit in 64 bits or
-  /// is not a power of two.
-  inline MaybeAlign getMaybeAlignValue() const {
-    return cast<llvm::ConstantInt>(Val)->getMaybeAlignValue();
-  }
-
-  /// Return the constant as an llvm::Align, interpreting `0` as `Align(1)`.
-  /// Note that this method can assert if the value does not fit in 64 bits or
-  /// is not a power of two.
-  inline Align getAlignValue() const {
-    return cast<llvm::ConstantInt>(Val)->getAlignValue();
-  }
-
-  /// A helper method that can be used to determine if the constant contained
-  /// within is equal to a constant.  This only works for very small values,
-  /// because this is all that can be represented with all types.
-  /// Determine if this constant's value is same as an unsigned char.
-  bool equalsInt(uint64_t V) const {
-    return cast<llvm::ConstantInt>(Val)->equalsInt(V);
-  }
-
-  /// Variant of the getType() method to always return an IntegerType, which
-  /// reduces the amount of casting needed in parts of the compiler.
-  LLVM_ABI IntegerType *getIntegerType() const;
-
-  /// This static method returns true if the type Ty is big enough to
-  /// represent the value V. This can be used to avoid having the get method
-  /// assert when V is larger than Ty can represent. Note that there are two
-  /// versions of this method, one for unsigned and one for signed integers.
-  /// Although ConstantInt canonicalizes everything to an unsigned integer,
-  /// the signed version avoids callers having to convert a signed quantity
-  /// to the appropriate unsigned type before calling the method.
-  /// @returns true if V is a valid value for type Ty
-  /// Determine if the value is in range for the given type.
-  LLVM_ABI static bool isValueValidForType(Type *Ty, uint64_t V);
-  LLVM_ABI static bool isValueValidForType(Type *Ty, int64_t V);
-
-  bool isNegative() const { return cast<llvm::ConstantInt>(Val)->isNegative(); }
-
-  /// This is just a convenience method to make client code smaller for a
-  /// common code. It also correctly performs the comparison without the
-  /// potential for an assertion from getZExtValue().
-  bool isZero() const { return cast<llvm::ConstantInt>(Val)->isZero(); }
-
-  /// This is just a convenience method to make client code smaller for a
-  /// common case. It also correctly performs the comparison without the
-  /// potential for an assertion from getZExtValue().
-  /// Determine if the value is one.
-  bool isOne() const { return cast<llvm::ConstantInt>(Val)->isOne(); }
-
-  /// This function will return true iff every bit in this constant is set
-  /// to true.
-  /// @returns true iff this constant's bits are all set to true.
-  /// Determine if the value is all ones.
-  bool isMinusOne() const { return cast<llvm::ConstantInt>(Val)->isMinusOne(); }
-
-  /// This function will return true iff this constant represents the largest
-  /// value that may be represented by the constant's type.
-  /// @returns true iff this is the largest value that may be represented
-  /// by this type.
-  /// Determine if the value is maximal.
-  bool isMaxValue(bool IsSigned) const {
-    return cast<llvm::ConstantInt>(Val)->isMaxValue(IsSigned);
-  }
-
-  /// This function will return true iff this constant represents the smallest
-  /// value that may be represented by this constant's type.
-  /// @returns true if this is the smallest value that may be represented by
-  /// this type.
-  /// Determine if the value is minimal.
-  bool isMinValue(bool IsSigned) const {
-    return cast<llvm::ConstantInt>(Val)->isMinValue(IsSigned);
-  }
-
-  /// This function will return true iff this constant represents a value with
-  /// active bits bigger than 64 bits or a value greater than the given uint64_t
-  /// value.
-  /// @returns true iff this constant is greater or equal to the given number.
-  /// Determine if the value is greater or equal to the given number.
-  bool uge(uint64_t Num) const {
-    return cast<llvm::ConstantInt>(Val)->uge(Num);
-  }
-
-  /// getLimitedValue - If the value is smaller than the specified limit,
-  /// return it, otherwise return the limit value.  This causes the value
-  /// to saturate to the limit.
-  /// @returns the min of the value of the constant and the specified value
-  /// Get the constant's value with a saturation limit
-  uint64_t getLimitedValue(uint64_t Limit = ~0ULL) const {
-    return cast<llvm::ConstantInt>(Val)->getLimitedValue(Limit);
-  }
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantInt;
-  }
-  unsigned getUseOperandNo(const Use &Use) const override {
-    llvm_unreachable("ConstantInt has no operands!");
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::ConstantInt>(Val) && "Expected a ConstantInst!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-// TODO: This should inherit from ConstantData.
-class ConstantFP final : public Constant {
-  ConstantFP(llvm::ConstantFP *C, Context &Ctx)
-      : Constant(ClassID::ConstantFP, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// This returns a ConstantFP, or a vector containing a splat of a ConstantFP,
-  /// for the specified value in the specified type. This should only be used
-  /// for simple constant values like 2.0/1.0 etc, that are known-valid both as
-  /// host double and as the target format.
-  LLVM_ABI static Constant *get(Type *Ty, double V);
-
-  /// If Ty is a vector type, return a Constant with a splat of the given
-  /// value. Otherwise return a ConstantFP for the given value.
-  LLVM_ABI static Constant *get(Type *Ty, const APFloat &V);
-
-  LLVM_ABI static Constant *get(Type *Ty, StringRef Str);
-
-  LLVM_ABI static ConstantFP *get(const APFloat &V, Context &Ctx);
-
-  LLVM_ABI static Constant *getNaN(Type *Ty, bool Negative = false,
-                                   uint64_t Payload = 0);
-  LLVM_ABI static Constant *getQNaN(Type *Ty, bool Negative = false,
-                                    APInt *Payload = nullptr);
-  LLVM_ABI static Constant *getSNaN(Type *Ty, bool Negative = false,
-                                    APInt *Payload = nullptr);
-  LLVM_ABI static Constant *getZero(Type *Ty, bool Negative = false);
-
-  LLVM_ABI static Constant *getNegativeZero(Type *Ty);
-  LLVM_ABI static Constant *getInfinity(Type *Ty, bool Negative = false);
-
-  /// Return true if Ty is big enough to represent V.
-  LLVM_ABI static bool isValueValidForType(Type *Ty, const APFloat &V);
-
-  inline const APFloat &getValueAPF() const {
-    return cast<llvm::ConstantFP>(Val)->getValueAPF();
-  }
-  inline const APFloat &getValue() const {
-    return cast<llvm::ConstantFP>(Val)->getValue();
-  }
-
-  /// Return true if the value is positive or negative zero.
-  bool isZero() const { return cast<llvm::ConstantFP>(Val)->isZero(); }
-
-  /// Return true if the sign bit is set.
-  bool isNegative() const { return cast<llvm::ConstantFP>(Val)->isNegative(); }
-
-  /// Return true if the value is infinity
-  bool isInfinity() const { return cast<llvm::ConstantFP>(Val)->isInfinity(); }
-
-  /// Return true if the value is a NaN.
-  bool isNaN() const { return cast<llvm::ConstantFP>(Val)->isNaN(); }
-
-  /// We don't rely on operator== working on double values, as it returns true
-  /// for things that are clearly not equal, like -0.0 and 0.0.
-  /// As such, this method can be used to do an exact bit-for-bit comparison of
-  /// two floating point values.  The version with a double operand is retained
-  /// because it's so convenient to write isExactlyValue(2.0), but please use
-  /// it only for simple constants.
-  bool isExactlyValue(const APFloat &V) const {
-    return cast<llvm::ConstantFP>(Val)->isExactlyValue(V);
-  }
-
-  bool isExactlyValue(double V) const {
-    return cast<llvm::ConstantFP>(Val)->isExactlyValue(V);
-  }
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantFP;
-  }
-
-  // TODO: Better name: getOperandNo(const Use&). Should be private.
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("ConstantFP has no operands!");
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::ConstantFP>(Val) && "Expected a ConstantFP!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-/// Base class for aggregate constants (with operands).
-class ConstantAggregate : public Constant {
-protected:
-  ConstantAggregate(ClassID ID, llvm::Constant *C, Context &Ctx)
-      : Constant(ID, C, Ctx) {}
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    auto ID = From->getSubclassID();
-    return ID == ClassID::ConstantVector || ID == ClassID::ConstantStruct ||
-           ID == ClassID::ConstantArray;
-  }
-};
-
-class ConstantArray final : public ConstantAggregate {
-  ConstantArray(llvm::ConstantArray *C, Context &Ctx)
-      : ConstantAggregate(ClassID::ConstantArray, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static Constant *get(ArrayType *T, ArrayRef<Constant *> V);
-  LLVM_ABI ArrayType *getType() const;
-
-  // TODO: Missing functions: getType(), getTypeForElements(), getAnon(), get().
-
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ConstantArray;
-  }
-};
-
-class ConstantStruct final : public ConstantAggregate {
-  ConstantStruct(llvm::ConstantStruct *C, Context &Ctx)
-      : ConstantAggregate(ClassID::ConstantStruct, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static Constant *get(StructType *T, ArrayRef<Constant *> V);
-
-  template <typename... Csts>
-  static std::enable_if_t<are_base_of<Constant, Csts...>::value, Constant *>
-  get(StructType *T, Csts *...Vs) {
-    return get(T, ArrayRef<Constant *>({Vs...}));
-  }
-  /// Return an anonymous struct that has the specified elements.
-  /// If the struct is possibly empty, then you must specify a context.
-  static Constant *getAnon(ArrayRef<Constant *> V, bool Packed = false) {
-    return get(getTypeForElements(V, Packed), V);
-  }
-  static Constant *getAnon(Context &Ctx, ArrayRef<Constant *> V,
-                           bool Packed = false) {
-    return get(getTypeForElements(Ctx, V, Packed), V);
-  }
-  /// This version of the method allows an empty list.
-  LLVM_ABI static StructType *
-  getTypeForElements(Context &Ctx, ArrayRef<Constant *> V, bool Packed = false);
-  /// Return an anonymous struct type to use for a constant with the specified
-  /// set of elements. The list must not be empty.
-  static StructType *getTypeForElements(ArrayRef<Constant *> V,
-                                        bool Packed = false) {
-    assert(!V.empty() &&
-           "ConstantStruct::getTypeForElements cannot be called on empty list");
-    return getTypeForElements(V[0]->getContext(), V, Packed);
-  }
-
-  /// Specialization - reduce amount of casting.
-  inline StructType *getType() const {
-    return cast<StructType>(Value::getType());
-  }
-
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ConstantStruct;
-  }
-};
-
-class ConstantVector final : public ConstantAggregate {
-  ConstantVector(llvm::ConstantVector *C, Context &Ctx)
-      : ConstantAggregate(ClassID::ConstantVector, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static Constant *get(ArrayRef<Constant *> V);
-  /// Return a ConstantVector with the specified constant in each element.
-  /// Note that this might not return an instance of ConstantVector
-  LLVM_ABI static Constant *getSplat(ElementCount EC, Constant *Elt);
-  /// Specialize the getType() method to always return a FixedVectorType,
-  /// which reduces the amount of casting needed in parts of the compiler.
-  inline FixedVectorType *getType() const {
-    return cast<FixedVectorType>(Value::getType());
-  }
-  /// If all elements of the vector constant have the same value, return that
-  /// value. Otherwise, return nullptr. Ignore poison elements by setting
-  /// AllowPoison to true.
-  LLVM_ABI Constant *getSplatValue(bool AllowPoison = false) const;
-
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ConstantVector;
-  }
-};
-
-// TODO: Inherit from ConstantData.
-class ConstantAggregateZero final : public Constant {
-  ConstantAggregateZero(llvm::ConstantAggregateZero *C, Context &Ctx)
-      : Constant(ClassID::ConstantAggregateZero, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static ConstantAggregateZero *get(Type *Ty);
-  /// If this CAZ has array or vector type, return a zero with the right element
-  /// type.
-  LLVM_ABI Constant *getSequentialElement() const;
-  /// If this CAZ has struct type, return a zero with the right element type for
-  /// the specified element.
-  LLVM_ABI Constant *getStructElement(unsigned Elt) const;
-  /// Return a zero of the right value for the specified GEP index if we can,
-  /// otherwise return null (e.g. if C is a ConstantExpr).
-  LLVM_ABI Constant *getElementValue(Constant *C) const;
-  /// Return a zero of the right value for the specified GEP index.
-  LLVM_ABI Constant *getElementValue(unsigned Idx) const;
-  /// Return the number of elements in the array, vector, or struct.
-  ElementCount getElementCount() const {
-    return cast<llvm::ConstantAggregateZero>(Val)->getElementCount();
-  }
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantAggregateZero;
-  }
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("ConstantAggregateZero has no operands!");
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::ConstantAggregateZero>(Val) && "Expected a CAZ!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-/// ConstantDataSequential - A vector or array constant whose element type is a
-/// simple 1/2/4/8-byte integer or half/bfloat/float/double, and whose elements
-/// are just simple data values (i.e. ConstantInt/ConstantFP).  This Constant
-/// node has no operands because it stores all of the elements of the constant
-/// as densely packed data, instead of as Value*'s.
-///
-/// This is the common base class of ConstantDataArray and ConstantDataVector.
-class ConstantDataSequential : public Constant {
-protected:
-  ConstantDataSequential(ClassID ID, llvm::ConstantDataSequential *C,
-                         Context &Ctx)
-      : Constant(ID, C, Ctx) {}
-
-public:
-  /// Return true if a ConstantDataSequential can be formed with a vector or
-  /// array of the specified element type.
-  /// ConstantDataArray only works with normal float and int types that are
-  /// stored densely in memory, not with things like i42 or x86_f80.
-  static bool isElementTypeCompatible(Type *Ty) {
-    return llvm::ConstantDataSequential::isElementTypeCompatible(Ty->LLVMTy);
-  }
-  /// If this is a sequential container of integers (of any size), return the
-  /// specified element in the low bits of a uint64_t.
-  uint64_t getElementAsInteger(unsigned ElmIdx) const {
-    return cast<llvm::ConstantDataSequential>(Val)->getElementAsInteger(ElmIdx);
-  }
-  /// If this is a sequential container of integers (of any size), return the
-  /// specified element as an APInt.
-  APInt getElementAsAPInt(unsigned ElmIdx) const {
-    return cast<llvm::ConstantDataSequential>(Val)->getElementAsAPInt(ElmIdx);
-  }
-  /// If this is a sequential container of floating point type, return the
-  /// specified element as an APFloat.
-  APFloat getElementAsAPFloat(unsigned ElmIdx) const {
-    return cast<llvm::ConstantDataSequential>(Val)->getElementAsAPFloat(ElmIdx);
-  }
-  /// If this is an sequential container of floats, return the specified element
-  /// as a float.
-  float getElementAsFloat(unsigned ElmIdx) const {
-    return cast<llvm::ConstantDataSequential>(Val)->getElementAsFloat(ElmIdx);
-  }
-  /// If this is an sequential container of doubles, return the specified
-  /// element as a double.
-  double getElementAsDouble(unsigned ElmIdx) const {
-    return cast<llvm::ConstantDataSequential>(Val)->getElementAsDouble(ElmIdx);
-  }
-  /// Return a Constant for a specified index's element.
-  /// Note that this has to compute a new constant to return, so it isn't as
-  /// efficient as getElementAsInteger/Float/Double.
-  Constant *getElementAsConstant(unsigned ElmIdx) const {
-    return Ctx.getOrCreateConstant(
-        cast<llvm::ConstantDataSequential>(Val)->getElementAsConstant(ElmIdx));
-  }
-  /// Return the element type of the array/vector.
-  Type *getElementType() const {
-    return Ctx.getType(
-        cast<llvm::ConstantDataSequential>(Val)->getElementType());
-  }
-  /// Return the number of elements in the array or vector.
-  unsigned getNumElements() const {
-    return cast<llvm::ConstantDataSequential>(Val)->getNumElements();
-  }
-  /// Return the size (in bytes) of each element in the array/vector.
-  /// The size of the elements is known to be a multiple of one byte.
-  uint64_t getElementByteSize() const {
-    return cast<llvm::ConstantDataSequential>(Val)->getElementByteSize();
-  }
-  /// This method returns true if this is an array of \p CharSize integers.
-  bool isString(unsigned CharSize = 8) const {
-    return cast<llvm::ConstantDataSequential>(Val)->isString(CharSize);
-  }
-  /// This method returns true if the array "isString", ends with a null byte,
-  /// and does not contains any other null bytes.
-  bool isCString() const {
-    return cast<llvm::ConstantDataSequential>(Val)->isCString();
-  }
-  /// If this array is isString(), then this method returns the array as a
-  /// StringRef. Otherwise, it asserts out.
-  StringRef getAsString() const {
-    return cast<llvm::ConstantDataSequential>(Val)->getAsString();
-  }
-  /// If this array is isCString(), then this method returns the array (without
-  /// the trailing null byte) as a StringRef. Otherwise, it asserts out.
-  StringRef getAsCString() const {
-    return cast<llvm::ConstantDataSequential>(Val)->getAsCString();
-  }
-  /// Return the raw, underlying, bytes of this data. Note that this is an
-  /// extremely tricky thing to work with, as it exposes the host endianness of
-  /// the data elements.
-  StringRef getRawDataValues() const {
-    return cast<llvm::ConstantDataSequential>(Val)->getRawDataValues();
-  }
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ConstantDataArray ||
-           From->getSubclassID() == ClassID::ConstantDataVector;
-  }
-};
-
-class ConstantDataArray final : public ConstantDataSequential {
-  ConstantDataArray(llvm::ConstantDataArray *C, Context &Ctx)
-      : ConstantDataSequential(ClassID::ConstantDataArray, C, Ctx) {}
-  friend class Context;
-
-public:
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ConstantDataArray;
-  }
-  /// get() constructor - Return a constant with array type with an element
-  /// count and element type matching the ArrayRef passed in.  Note that this
-  /// can return a ConstantAggregateZero object.
-  template <typename ElementTy>
-  static Constant *get(Context &Ctx, ArrayRef<ElementTy> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataArray::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-
-  /// get() constructor - ArrayTy needs to be compatible with
-  /// ArrayRef<ElementTy>.
-  template <typename ArrayTy>
-  static Constant *get(Context &Ctx, ArrayTy &Elts) {
-    return ConstantDataArray::get(Ctx, ArrayRef(Elts));
-  }
-
-  /// getRaw() constructor - Return a constant with array type with an element
-  /// count and element type matching the NumElements and ElementTy parameters
-  /// passed in. Note that this can return a ConstantAggregateZero object.
-  /// ElementTy must be one of i8/i16/i32/i64/half/bfloat/float/double. Data is
-  /// the buffer containing the elements. Be careful to make sure Data uses the
-  /// right endianness, the buffer will be used as-is.
-  static Constant *getRaw(StringRef Data, uint64_t NumElements,
-                          Type *ElementTy) {
-    auto *LLVMC =
-        llvm::ConstantDataArray::getRaw(Data, NumElements, ElementTy->LLVMTy);
-    return ElementTy->getContext().getOrCreateConstant(LLVMC);
-  }
-  /// getFP() constructors - Return a constant of array type with a float
-  /// element type taken from argument `ElementType', and count taken from
-  /// argument `Elts'.  The amount of bits of the contained type must match the
-  /// number of bits of the type contained in the passed in ArrayRef.
-  /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
-  /// that this can return a ConstantAggregateZero object.
-  static Constant *getFP(Type *ElementType, ArrayRef<uint16_t> Elts) {
-    auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
-    return ElementType->getContext().getOrCreateConstant(LLVMC);
-  }
-  static Constant *getFP(Type *ElementType, ArrayRef<uint32_t> Elts) {
-    auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
-    return ElementType->getContext().getOrCreateConstant(LLVMC);
-  }
-  static Constant *getFP(Type *ElementType, ArrayRef<uint64_t> Elts) {
-    auto *LLVMC = llvm::ConstantDataArray::getFP(ElementType->LLVMTy, Elts);
-    return ElementType->getContext().getOrCreateConstant(LLVMC);
-  }
-  /// This method constructs a CDS and initializes it with a text string.
-  /// The default behavior (AddNull==true) causes a null terminator to
-  /// be placed at the end of the array (increasing the length of the string by
-  /// one more than the StringRef would normally indicate.  Pass AddNull=false
-  /// to disable this behavior.
-  static Constant *getString(Context &Ctx, StringRef Initializer,
-                             bool AddNull = true) {
-    auto *LLVMC =
-        llvm::ConstantDataArray::getString(Ctx.LLVMCtx, Initializer, AddNull);
-    return Ctx.getOrCreateConstant(LLVMC);
-  }
-
-  /// Specialize the getType() method to always return an ArrayType,
-  /// which reduces the amount of casting needed in parts of the compiler.
-  inline ArrayType *getType() const {
-    return cast<ArrayType>(Value::getType());
-  }
-};
-
-/// A vector constant whose element type is a simple 1/2/4/8-byte integer or
-/// float/double, and whose elements are just simple data values
-/// (i.e. ConstantInt/ConstantFP). This Constant node has no operands because it
-/// stores all of the elements of the constant as densely packed data, instead
-/// of as Value*'s.
-class ConstantDataVector final : public ConstantDataSequential {
-  ConstantDataVector(llvm::ConstantDataVector *C, Context &Ctx)
-      : ConstantDataSequential(ClassID::ConstantDataVector, C, Ctx) {}
-  friend class Context;
-
-public:
-  /// Methods for support type inquiry through isa, cast, and dyn_cast:
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ConstantDataVector;
-  }
-  /// get() constructors - Return a constant with vector type with an element
-  /// count and element type matching the ArrayRef passed in.  Note that this
-  /// can return a ConstantAggregateZero object.
-  static Constant *get(Context &Ctx, ArrayRef<uint8_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *get(Context &Ctx, ArrayRef<uint16_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *get(Context &Ctx, ArrayRef<uint32_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *get(Context &Ctx, ArrayRef<uint64_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *get(Context &Ctx, ArrayRef<float> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *get(Context &Ctx, ArrayRef<double> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::get(Ctx.LLVMCtx, Elts);
-    return Ctx.getOrCreateConstant(NewLLVMC);
-  }
-
-  /// getRaw() constructor - Return a constant with vector type with an element
-  /// count and element type matching the NumElements and ElementTy parameters
-  /// passed in. Note that this can return a ConstantAggregateZero object.
-  /// ElementTy must be one of i8/i16/i32/i64/half/bfloat/float/double. Data is
-  /// the buffer containing the elements. Be careful to make sure Data uses the
-  /// right endianness, the buffer will be used as-is.
-  static Constant *getRaw(StringRef Data, uint64_t NumElements,
-                          Type *ElementTy) {
-    auto *NewLLVMC =
-        llvm::ConstantDataVector::getRaw(Data, NumElements, ElementTy->LLVMTy);
-    return ElementTy->getContext().getOrCreateConstant(NewLLVMC);
-  }
-  /// getFP() constructors - Return a constant of vector type with a float
-  /// element type taken from argument `ElementType', and count taken from
-  /// argument `Elts'.  The amount of bits of the contained type must match the
-  /// number of bits of the type contained in the passed in ArrayRef.
-  /// (i.e. half or bfloat for 16bits, float for 32bits, double for 64bits) Note
-  /// that this can return a ConstantAggregateZero object.
-  static Constant *getFP(Type *ElementType, ArrayRef<uint16_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::getFP(ElementType->LLVMTy, Elts);
-    return ElementType->getContext().getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *getFP(Type *ElementType, ArrayRef<uint32_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::getFP(ElementType->LLVMTy, Elts);
-    return ElementType->getContext().getOrCreateConstant(NewLLVMC);
-  }
-  static Constant *getFP(Type *ElementType, ArrayRef<uint64_t> Elts) {
-    auto *NewLLVMC = llvm::ConstantDataVector::getFP(ElementType->LLVMTy, Elts);
-    return ElementType->getContext().getOrCreateConstant(NewLLVMC);
-  }
-
-  /// Return a ConstantVector with the specified constant in each element.
-  /// The specified constant has to be a of a compatible type (i8/i16/
-  /// i32/i64/half/bfloat/float/double) and must be a ConstantFP or ConstantInt.
-  static Constant *getSplat(unsigned NumElts, Constant *Elt) {
-    auto *NewLLVMC = llvm::ConstantDataVector::getSplat(
-        NumElts, cast<llvm::Constant>(Elt->Val));
-    return Elt->getContext().getOrCreateConstant(NewLLVMC);
-  }
-
-  /// Returns true if this is a splat constant, meaning that all elements have
-  /// the same value.
-  bool isSplat() const {
-    return cast<llvm::ConstantDataVector>(Val)->isSplat();
-  }
-
-  /// If this is a splat constant, meaning that all of the elements have the
-  /// same value, return that value. Otherwise return NULL.
-  Constant *getSplatValue() const {
-    return Ctx.getOrCreateConstant(
-        cast<llvm::ConstantDataVector>(Val)->getSplatValue());
-  }
-
-  /// Specialize the getType() method to always return a FixedVectorType,
-  /// which reduces the amount of casting needed in parts of the compiler.
-  inline FixedVectorType *getType() const {
-    return cast<FixedVectorType>(Value::getType());
-  }
-};
-
-// TODO: Inherit from ConstantData.
-class ConstantPointerNull final : public Constant {
-  ConstantPointerNull(llvm::ConstantPointerNull *C, Context &Ctx)
-      : Constant(ClassID::ConstantPointerNull, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static ConstantPointerNull *get(PointerType *Ty);
-
-  LLVM_ABI PointerType *getType() const;
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantPointerNull;
-  }
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("ConstantPointerNull has no operands!");
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::ConstantPointerNull>(Val) && "Expected a CPNull!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-// TODO: Inherit from ConstantData.
-class UndefValue : public Constant {
-protected:
-  UndefValue(llvm::UndefValue *C, Context &Ctx)
-      : Constant(ClassID::UndefValue, C, Ctx) {}
-  UndefValue(ClassID ID, llvm::Constant *C, Context &Ctx)
-      : Constant(ID, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Static factory methods - Return an 'undef' object of the specified type.
-  LLVM_ABI static UndefValue *get(Type *T);
-
-  /// If this Undef has array or vector type, return a undef with the right
-  /// element type.
-  LLVM_ABI UndefValue *getSequentialElement() const;
-
-  /// If this undef has struct type, return a undef with the right element type
-  /// for the specified element.
-  LLVM_ABI UndefValue *getStructElement(unsigned Elt) const;
-
-  /// Return an undef of the right value for the specified GEP index if we can,
-  /// otherwise return null (e.g. if C is a ConstantExpr).
-  LLVM_ABI UndefValue *getElementValue(Constant *C) const;
-
-  /// Return an undef of the right value for the specified GEP index.
-  LLVM_ABI UndefValue *getElementValue(unsigned Idx) const;
-
-  /// Return the number of elements in the array, vector, or struct.
-  unsigned getNumElements() const {
-    return cast<llvm::UndefValue>(Val)->getNumElements();
-  }
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::UndefValue ||
-           From->getSubclassID() == ClassID::PoisonValue;
-  }
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("UndefValue has no operands!");
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::UndefValue>(Val) && "Expected an UndefValue!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-class PoisonValue final : public UndefValue {
-  PoisonValue(llvm::PoisonValue *C, Context &Ctx)
-      : UndefValue(ClassID::PoisonValue, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Static factory methods - Return an 'poison' object of the specified type.
-  LLVM_ABI static PoisonValue *get(Type *T);
-
-  /// If this poison has array or vector type, return a poison with the right
-  /// element type.
-  LLVM_ABI PoisonValue *getSequentialElement() const;
-
-  /// If this poison has struct type, return a poison with the right element
-  /// type for the specified element.
-  LLVM_ABI PoisonValue *getStructElement(unsigned Elt) const;
-
-  /// Return an poison of the right value for the specified GEP index if we can,
-  /// otherwise return null (e.g. if C is a ConstantExpr).
-  LLVM_ABI PoisonValue *getElementValue(Constant *C) const;
-
-  /// Return an poison of the right value for the specified GEP index.
-  LLVM_ABI PoisonValue *getElementValue(unsigned Idx) const;
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::PoisonValue;
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::PoisonValue>(Val) && "Expected a PoisonValue!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-class GlobalValue : public Constant {
-protected:
-  GlobalValue(ClassID ID, llvm::GlobalValue *C, Context &Ctx)
-      : Constant(ID, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  using LinkageTypes = llvm::GlobalValue::LinkageTypes;
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    switch (From->getSubclassID()) {
-    case ClassID::Function:
-    case ClassID::GlobalVariable:
-    case ClassID::GlobalAlias:
-    case ClassID::GlobalIFunc:
-      return true;
-    default:
-      return false;
-    }
-  }
-
-  unsigned getAddressSpace() const {
-    return cast<llvm::GlobalValue>(Val)->getAddressSpace();
-  }
-  bool hasGlobalUnnamedAddr() const {
-    return cast<llvm::GlobalValue>(Val)->hasGlobalUnnamedAddr();
-  }
-
-  /// Returns true if this value's address is not significant in this module.
-  /// This attribute is intended to be used only by the code generator and LTO
-  /// to allow the linker to decide whether the global needs to be in the symbol
-  /// table. It should probably not be used in optimizations, as the value may
-  /// have uses outside the module; use hasGlobalUnnamedAddr() instead.
-  bool hasAtLeastLocalUnnamedAddr() const {
-    return cast<llvm::GlobalValue>(Val)->hasAtLeastLocalUnnamedAddr();
-  }
-
-  using UnnamedAddr = llvm::GlobalValue::UnnamedAddr;
-
-  UnnamedAddr getUnnamedAddr() const {
-    return cast<llvm::GlobalValue>(Val)->getUnnamedAddr();
-  }
-  LLVM_ABI void setUnnamedAddr(UnnamedAddr V);
-
-  static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B) {
-    return llvm::GlobalValue::getMinUnnamedAddr(A, B);
-  }
-
-  bool hasComdat() const { return cast<llvm::GlobalValue>(Val)->hasComdat(); }
-
-  // TODO: We need a SandboxIR Comdat if we want to implement getComdat().
-  using VisibilityTypes = llvm::GlobalValue::VisibilityTypes;
-  VisibilityTypes getVisibility() const {
-    return cast<llvm::GlobalValue>(Val)->getVisibility();
-  }
-  bool hasDefaultVisibility() const {
-    return cast<llvm::GlobalValue>(Val)->hasDefaultVisibility();
-  }
-  bool hasHiddenVisibility() const {
-    return cast<llvm::GlobalValue>(Val)->hasHiddenVisibility();
-  }
-  bool hasProtectedVisibility() const {
-    return cast<llvm::GlobalValue>(Val)->hasProtectedVisibility();
-  }
-  LLVM_ABI void setVisibility(VisibilityTypes V);
-
-  // TODO: Add missing functions.
-};
-
-class GlobalObject : public GlobalValue {
-protected:
-  GlobalObject(ClassID ID, llvm::GlobalObject *C, Context &Ctx)
-      : GlobalValue(ID, C, Ctx) {}
-  friend class Context; // For constructor.
-  Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
-    return getOperandUseDefault(OpIdx, Verify);
-  }
-
-public:
-  unsigned getUseOperandNo(const Use &Use) const final {
-    return getUseOperandNoDefault(Use);
-  }
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    switch (From->getSubclassID()) {
-    case ClassID::Function:
-    case ClassID::GlobalVariable:
-    case ClassID::GlobalIFunc:
-      return true;
-    default:
-      return false;
-    }
-  }
-
-  /// Check if this global has a custom object file section.
-  ///
-  /// This is more efficient than calling getSection() and checking for an empty
-  /// string.
-  bool hasSection() const {
-    return cast<llvm::GlobalObject>(Val)->hasSection();
-  }
-
-  /// Get the custom section of this global if it has one.
-  ///
-  /// If this global does not have a custom section, this will be empty and the
-  /// default object file section (.text, .data, etc) will be used.
-  StringRef getSection() const {
-    return cast<llvm::GlobalObject>(Val)->getSection();
-  }
-
-  /// Change the section for this global.
-  ///
-  /// Setting the section to the empty string tells LLVM to choose an
-  /// appropriate default object file section.
-  LLVM_ABI void setSection(StringRef S);
-
-  bool hasComdat() const { return cast<llvm::GlobalObject>(Val)->hasComdat(); }
-
-  // TODO: implement get/setComdat(), etc. once we have a sandboxir::Comdat.
-
-  // TODO: We currently don't support Metadata in sandboxir so all
-  // Metadata-related functions are missing.
-
-  using VCallVisibility = llvm::GlobalObject::VCallVisibility;
-
-  VCallVisibility getVCallVisibility() const {
-    return cast<llvm::GlobalObject>(Val)->getVCallVisibility();
-  }
-
-  /// Returns true if the alignment of the value can be unilaterally
-  /// increased.
-  ///
-  /// Note that for functions this is the alignment of the code, not the
-  /// alignment of a function pointer.
-  bool canIncreaseAlignment() const {
-    return cast<llvm::GlobalObject>(Val)->canIncreaseAlignment();
-  }
-};
-
-/// Provides API functions, like getIterator() and getReverseIterator() to
-/// GlobalIFunc, Function, GlobalVariable and GlobalAlias. In LLVM IR these are
-/// provided by ilist_node.
-template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
-          typename LLVMParentT>
-class GlobalWithNodeAPI : public ParentT {
-  /// Helper for mapped_iterator.
-  struct LLVMGVToGV {
-    Context &Ctx;
-    LLVMGVToGV(Context &Ctx) : Ctx(Ctx) {}
-    LLVM_ABI GlobalT &operator()(LLVMGlobalT &LLVMGV) const;
-  };
-
-public:
-  GlobalWithNodeAPI(Value::ClassID ID, LLVMParentT *C, Context &Ctx)
-      : ParentT(ID, C, Ctx) {}
-
-  Module *getParent() const {
-    llvm::Module *LLVMM = cast<LLVMGlobalT>(this->Val)->getParent();
-    return this->Ctx.getModule(LLVMM);
-  }
-
-  using iterator = mapped_iterator<
-      decltype(static_cast<LLVMGlobalT *>(nullptr)->getIterator()), LLVMGVToGV>;
-  using reverse_iterator = mapped_iterator<
-      decltype(static_cast<LLVMGlobalT *>(nullptr)->getReverseIterator()),
-      LLVMGVToGV>;
-  iterator getIterator() const {
-    auto *LLVMGV = cast<LLVMGlobalT>(this->Val);
-    LLVMGVToGV ToGV(this->Ctx);
-    return map_iterator(LLVMGV->getIterator(), ToGV);
-  }
-  reverse_iterator getReverseIterator() const {
-    auto *LLVMGV = cast<LLVMGlobalT>(this->Val);
-    LLVMGVToGV ToGV(this->Ctx);
-    return map_iterator(LLVMGV->getReverseIterator(), ToGV);
-  }
-};
-
-// Explicit instantiations.
-extern template class LLVM_TEMPLATE_ABI GlobalWithNodeAPI<
-    GlobalIFunc, llvm::GlobalIFunc, GlobalObject, llvm::GlobalObject>;
-extern template class LLVM_TEMPLATE_ABI GlobalWithNodeAPI<
-    Function, llvm::Function, GlobalObject, llvm::GlobalObject>;
-extern template class LLVM_TEMPLATE_ABI GlobalWithNodeAPI<
-    GlobalVariable, llvm::GlobalVariable, GlobalObject, llvm::GlobalObject>;
-extern template class LLVM_TEMPLATE_ABI GlobalWithNodeAPI<
-    GlobalAlias, llvm::GlobalAlias, GlobalValue, llvm::GlobalValue>;
-
-class GlobalIFunc final
-    : public GlobalWithNodeAPI<GlobalIFunc, llvm::GlobalIFunc, GlobalObject,
-                               llvm::GlobalObject> {
-  GlobalIFunc(llvm::GlobalObject *C, Context &Ctx)
-      : GlobalWithNodeAPI(ClassID::GlobalIFunc, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::GlobalIFunc;
-  }
-
-  // TODO: Missing create() because we don't have a sandboxir::Module yet.
-
-  // TODO: Missing functions: copyAttributesFrom(), removeFromParent(),
-  // eraseFromParent()
-
-  LLVM_ABI void setResolver(Constant *Resolver);
-
-  LLVM_ABI Constant *getResolver() const;
-
-  // Return the resolver function after peeling off potential ConstantExpr
-  // indirection.
-  LLVM_ABI Function *getResolverFunction();
-  const Function *getResolverFunction() const {
-    return const_cast<GlobalIFunc *>(this)->getResolverFunction();
-  }
-
-  static bool isValidLinkage(LinkageTypes L) {
-    return llvm::GlobalIFunc::isValidLinkage(L);
-  }
-
-  // TODO: Missing applyAlongResolverPath().
-
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::GlobalIFunc>(Val) && "Expected a GlobalIFunc!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-class GlobalVariable final
-    : public GlobalWithNodeAPI<GlobalVariable, llvm::GlobalVariable,
-                               GlobalObject, llvm::GlobalObject> {
-  GlobalVariable(llvm::GlobalObject *C, Context &Ctx)
-      : GlobalWithNodeAPI(ClassID::GlobalVariable, C, Ctx) {}
-  friend class Context; // For constructor.
-
-  /// Helper for mapped_iterator.
-  struct LLVMGVToGV {
-    Context &Ctx;
-    LLVMGVToGV(Context &Ctx) : Ctx(Ctx) {}
-    LLVM_ABI GlobalVariable &operator()(llvm::GlobalVariable &LLVMGV) const;
-  };
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::GlobalVariable;
-  }
-
-  /// Definitions have initializers, declarations don't.
-  ///
-  inline bool hasInitializer() const {
-    return cast<llvm::GlobalVariable>(Val)->hasInitializer();
-  }
-
-  /// hasDefinitiveInitializer - Whether the global variable has an initializer,
-  /// and any other instances of the global (this can happen due to weak
-  /// linkage) are guaranteed to have the same initializer.
-  ///
-  /// Note that if you want to transform a global, you must use
-  /// hasUniqueInitializer() instead, because of the *_odr linkage type.
-  ///
-  /// Example:
-  ///
-  /// @a = global SomeType* null - Initializer is both definitive and unique.
-  ///
-  /// @b = global weak SomeType* null - Initializer is neither definitive nor
-  /// unique.
-  ///
-  /// @c = global weak_odr SomeType* null - Initializer is definitive, but not
-  /// unique.
-  inline bool hasDefinitiveInitializer() const {
-    return cast<llvm::GlobalVariable>(Val)->hasDefinitiveInitializer();
-  }
-
-  /// hasUniqueInitializer - Whether the global variable has an initializer, and
-  /// any changes made to the initializer will turn up in the final executable.
-  inline bool hasUniqueInitializer() const {
-    return cast<llvm::GlobalVariable>(Val)->hasUniqueInitializer();
-  }
-
-  /// getInitializer - Return the initializer for this global variable.  It is
-  /// illegal to call this method if the global is external, because we cannot
-  /// tell what the value is initialized to!
-  ///
-  LLVM_ABI Constant *getInitializer() const;
-  /// setInitializer - Sets the initializer for this global variable, removing
-  /// any existing initializer if InitVal==NULL. The initializer must have the
-  /// type getValueType().
-  LLVM_ABI void setInitializer(Constant *InitVal);
-
-  // TODO: Add missing replaceInitializer(). Requires special tracker
-
-  /// If the value is a global constant, its value is immutable throughout the
-  /// runtime execution of the program.  Assigning a value into the constant
-  /// leads to undefined behavior.
-  ///
-  bool isConstant() const {
-    return cast<llvm::GlobalVariable>(Val)->isConstant();
-  }
-  LLVM_ABI void setConstant(bool V);
-
-  bool isExternallyInitialized() const {
-    return cast<llvm::GlobalVariable>(Val)->isExternallyInitialized();
-  }
-  LLVM_ABI void setExternallyInitialized(bool Val);
-
-  // TODO: Missing copyAttributesFrom()
-
-  // TODO: Missing removeFromParent(), eraseFromParent(), dropAllReferences()
-
-  // TODO: Missing addDebugInfo(), getDebugInfo()
-
-  // TODO: Missing attribute setter functions: addAttribute(), setAttributes().
-  //       There seems to be no removeAttribute() so we can't undo them.
-
-  /// Return true if the attribute exists.
-  bool hasAttribute(Attribute::AttrKind Kind) const {
-    return cast<llvm::GlobalVariable>(Val)->hasAttribute(Kind);
-  }
-
-  /// Return true if the attribute exists.
-  bool hasAttribute(StringRef Kind) const {
-    return cast<llvm::GlobalVariable>(Val)->hasAttribute(Kind);
-  }
-
-  /// Return true if any attributes exist.
-  bool hasAttributes() const {
-    return cast<llvm::GlobalVariable>(Val)->hasAttributes();
-  }
-
-  /// Return the attribute object.
-  Attribute getAttribute(Attribute::AttrKind Kind) const {
-    return cast<llvm::GlobalVariable>(Val)->getAttribute(Kind);
-  }
-
-  /// Return the attribute object.
-  Attribute getAttribute(StringRef Kind) const {
-    return cast<llvm::GlobalVariable>(Val)->getAttribute(Kind);
-  }
-
-  /// Return the attribute set for this global
-  AttributeSet getAttributes() const {
-    return cast<llvm::GlobalVariable>(Val)->getAttributes();
-  }
-
-  /// Return attribute set as list with index.
-  /// FIXME: This may not be required once ValueEnumerators
-  /// in bitcode-writer can enumerate attribute-set.
-  AttributeList getAttributesAsList(unsigned Index) const {
-    return cast<llvm::GlobalVariable>(Val)->getAttributesAsList(Index);
-  }
-
-  /// Check if section name is present
-  bool hasImplicitSection() const {
-    return cast<llvm::GlobalVariable>(Val)->hasImplicitSection();
-  }
-
-  /// Get the custom code model raw value of this global.
-  ///
-  unsigned getCodeModelRaw() const {
-    return cast<llvm::GlobalVariable>(Val)->getCodeModelRaw();
-  }
-
-  /// Get the custom code model of this global if it has one.
-  ///
-  /// If this global does not have a custom code model, the empty instance
-  /// will be returned.
-  std::optional<CodeModel::Model> getCodeModel() const {
-    return cast<llvm::GlobalVariable>(Val)->getCodeModel();
-  }
-
-  /// Returns the alignment of the given variable.
-  MaybeAlign getAlign() const {
-    return cast<llvm::GlobalVariable>(Val)->getAlign();
-  }
-
-  // TODO: Add missing: setAligment(Align)
-
-  /// Sets the alignment attribute of the GlobalVariable.
-  /// This method will be deprecated as the alignment property should always be
-  /// defined.
-  LLVM_ABI void setAlignment(MaybeAlign Align);
-
-  // TODO: Missing setCodeModel(). Requires custom tracker.
-
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::GlobalVariable>(Val) && "Expected a GlobalVariable!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-class GlobalAlias final
-    : public GlobalWithNodeAPI<GlobalAlias, llvm::GlobalAlias, GlobalValue,
-                               llvm::GlobalValue> {
-  GlobalAlias(llvm::GlobalAlias *C, Context &Ctx)
-      : GlobalWithNodeAPI(ClassID::GlobalAlias, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::GlobalAlias;
-  }
-
-  // TODO: Missing create() due to unimplemented sandboxir::Module.
-
-  // TODO: Missing copyAttributresFrom().
-  // TODO: Missing removeFromParent(), eraseFromParent().
-
-  LLVM_ABI void setAliasee(Constant *Aliasee);
-  LLVM_ABI Constant *getAliasee() const;
-
-  LLVM_ABI const GlobalObject *getAliaseeObject() const;
-  GlobalObject *getAliaseeObject() {
-    return const_cast<GlobalObject *>(
-        static_cast<const GlobalAlias *>(this)->getAliaseeObject());
-  }
-
-  static bool isValidLinkage(LinkageTypes L) {
-    return llvm::GlobalAlias::isValidLinkage(L);
-  }
-};
-
-class NoCFIValue final : public Constant {
-  NoCFIValue(llvm::NoCFIValue *C, Context &Ctx)
-      : Constant(ClassID::NoCFIValue, C, Ctx) {}
-  friend class Context; // For constructor.
-
-  Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
-    return getOperandUseDefault(OpIdx, Verify);
-  }
-
-public:
-  /// Return a NoCFIValue for the specified function.
-  LLVM_ABI static NoCFIValue *get(GlobalValue *GV);
-
-  LLVM_ABI GlobalValue *getGlobalValue() const;
-
-  /// NoCFIValue is always a pointer.
-  LLVM_ABI PointerType *getType() const;
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::NoCFIValue;
-  }
-
-  unsigned getUseOperandNo(const Use &Use) const final {
-    return getUseOperandNoDefault(Use);
-  }
-
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::NoCFIValue>(Val) && "Expected a NoCFIValue!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-class ConstantPtrAuth final : public Constant {
-  ConstantPtrAuth(llvm::ConstantPtrAuth *C, Context &Ctx)
-      : Constant(ClassID::ConstantPtrAuth, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Return a pointer signed with the specified parameters.
-  LLVM_ABI static ConstantPtrAuth *get(Constant *Ptr, ConstantInt *Key,
-                                       ConstantInt *Disc, Constant *AddrDisc);
-  /// The pointer that is signed in this ptrauth signed pointer.
-  LLVM_ABI Constant *getPointer() const;
-
-  /// The Key ID, an i32 constant.
-  LLVM_ABI ConstantInt *getKey() const;
-
-  /// The integer discriminator, an i64 constant, or 0.
-  LLVM_ABI ConstantInt *getDiscriminator() const;
-
-  /// The address discriminator if any, or the null constant.
-  /// If present, this must be a value equivalent to the storage location of
-  /// the only global-initializer user of the ptrauth signed pointer.
-  LLVM_ABI Constant *getAddrDiscriminator() const;
-
-  /// Whether there is any non-null address discriminator.
-  bool hasAddressDiscriminator() const {
-    return cast<llvm::ConstantPtrAuth>(Val)->hasAddressDiscriminator();
-  }
-
-  /// Whether the address uses a special address discriminator.
-  /// These discriminators can't be used in real pointer-auth values; they
-  /// can only be used in "prototype" values that indicate how some real
-  /// schema is supposed to be produced.
-  bool hasSpecialAddressDiscriminator(uint64_t Value) const {
-    return cast<llvm::ConstantPtrAuth>(Val)->hasSpecialAddressDiscriminator(
-        Value);
-  }
-
-  /// Check whether an authentication operation with key \p Key and (possibly
-  /// blended) discriminator \p Discriminator is known to be compatible with
-  /// this ptrauth signed pointer.
-  bool isKnownCompatibleWith(const Value *Key, const Value *Discriminator,
-                             const DataLayout &DL) const {
-    return cast<llvm::ConstantPtrAuth>(Val)->isKnownCompatibleWith(
-        Key->Val, Discriminator->Val, DL);
-  }
-
-  /// Produce a new ptrauth expression signing the given value using
-  /// the same schema as is stored in one.
-  LLVM_ABI ConstantPtrAuth *getWithSameSchema(Constant *Pointer) const;
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantPtrAuth;
-  }
-};
-
-class ConstantExpr : public Constant {
-  ConstantExpr(llvm::ConstantExpr *C, Context &Ctx)
-      : Constant(ClassID::ConstantExpr, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantExpr;
-  }
-  // TODO: Missing functions.
-};
-
-class BlockAddress final : public Constant {
-  BlockAddress(llvm::BlockAddress *C, Context &Ctx)
-      : Constant(ClassID::BlockAddress, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Return a BlockAddress for the specified function and basic block.
-  LLVM_ABI static BlockAddress *get(Function *F, BasicBlock *BB);
-
-  /// Return a BlockAddress for the specified basic block.  The basic
-  /// block must be embedded into a function.
-  LLVM_ABI static BlockAddress *get(BasicBlock *BB);
-
-  /// Lookup an existing \c BlockAddress constant for the given BasicBlock.
-  ///
-  /// \returns 0 if \c !BB->hasAddressTaken(), otherwise the \c BlockAddress.
-  LLVM_ABI static BlockAddress *lookup(const BasicBlock *BB);
-
-  LLVM_ABI Function *getFunction() const;
-  LLVM_ABI BasicBlock *getBasicBlock() const;
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::BlockAddress;
-  }
-};
-
-class DSOLocalEquivalent final : public Constant {
-  DSOLocalEquivalent(llvm::DSOLocalEquivalent *C, Context &Ctx)
-      : Constant(ClassID::DSOLocalEquivalent, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Return a DSOLocalEquivalent for the specified global value.
-  LLVM_ABI static DSOLocalEquivalent *get(GlobalValue *GV);
-
-  LLVM_ABI GlobalValue *getGlobalValue() const;
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::DSOLocalEquivalent;
-  }
-
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("DSOLocalEquivalent has no operands!");
-  }
-
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::DSOLocalEquivalent>(Val) &&
-           "Expected a DSOLocalEquivalent!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-// TODO: This should inherit from ConstantData.
-class ConstantTokenNone final : public Constant {
-  ConstantTokenNone(llvm::ConstantTokenNone *C, Context &Ctx)
-      : Constant(ClassID::ConstantTokenNone, C, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Return the ConstantTokenNone.
-  LLVM_ABI static ConstantTokenNone *get(Context &Ctx);
-
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::ConstantTokenNone;
-  }
-
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("ConstantTokenNone has no operands!");
-  }
-
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::ConstantTokenNone>(Val) &&
-           "Expected a ConstantTokenNone!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_CONSTANT_H
diff --git a/llvm/include/llvm/SandboxIR/Context.h b/llvm/include/llvm/SandboxIR/Context.h
deleted file mode 100644
index a8966db29ab26..0000000000000
--- a/llvm/include/llvm/SandboxIR/Context.h
+++ /dev/null
@@ -1,334 +0,0 @@
-//===- Context.h ------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_CONTEXT_H
-#define LLVM_SANDBOXIR_CONTEXT_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/MapVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/LLVMContext.h"
-#include "llvm/SandboxIR/Tracker.h"
-#include "llvm/SandboxIR/Type.h"
-#include "llvm/Support/Compiler.h"
-
-#include <cstdint>
-
-namespace llvm {
-namespace sandboxir {
-
-class Argument;
-class BBIterator;
-class Constant;
-class Module;
-class Region;
-class Value;
-class Use;
-
-class Context {
-public:
-  // A EraseInstrCallback receives the instruction about to be erased.
-  using EraseInstrCallback = std::function<void(Instruction *)>;
-  // A CreateInstrCallback receives the instruction about to be created.
-  using CreateInstrCallback = std::function<void(Instruction *)>;
-  // A MoveInstrCallback receives the instruction about to be moved, the
-  // destination BB and an iterator pointing to the insertion position.
-  using MoveInstrCallback =
-      std::function<void(Instruction *, const BBIterator &)>;
-  // A SetUseCallback receives the Use that is about to get its source set.
-  using SetUseCallback = std::function<void(const Use &, Value *)>;
-
-  /// An ID for a registered callback. Used for deregistration. A dedicated type
-  /// is employed so as to keep IDs opaque to the end user; only Context should
-  /// deal with its underlying representation.
-  class CallbackID {
-  public:
-    // Uses a 64-bit integer so we don't have to worry about the unlikely case
-    // of overflowing a 32-bit counter.
-    using ValTy = uint64_t;
-    static constexpr ValTy InvalidVal = 0;
-
-  private:
-    // Default initialization results in an invalid ID.
-    ValTy Val = InvalidVal;
-    explicit CallbackID(ValTy Val) : Val{Val} {
-      assert(Val != InvalidVal && "newly-created ID is invalid!");
-    }
-
-  public:
-    CallbackID() = default;
-    friend class Context;
-    friend struct DenseMapInfo<CallbackID>;
-  };
-
-protected:
-  LLVMContext &LLVMCtx;
-  friend class Type;              // For LLVMCtx.
-  friend class PointerType;       // For LLVMCtx.
-  friend class IntegerType;       // For LLVMCtx.
-  friend class StructType;        // For LLVMCtx.
-  friend class Region;            // For LLVMCtx.
-  friend class IRSnapshotChecker; // To snapshot LLVMModuleToModuleMap.
-
-  Tracker IRTracker;
-
-  /// Maps LLVM Value to the corresponding sandboxir::Value. Owns all
-  /// SandboxIR objects.
-  DenseMap<llvm::Value *, std::unique_ptr<Value>> LLVMValueToValueMap;
-
-  /// Maps an LLVM Module to the corresponding sandboxir::Module.
-  DenseMap<llvm::Module *, std::unique_ptr<Module>> LLVMModuleToModuleMap;
-
-  /// Type has a protected destructor to prohibit the user from managing the
-  /// lifetime of the Type objects. Context is friend of Type, and this custom
-  /// deleter can destroy Type.
-  struct TypeDeleter {
-    void operator()(Type *Ty) { delete Ty; }
-  };
-  /// Maps LLVM Type to the corresonding sandboxir::Type. Owns all Sandbox IR
-  /// Type objects.
-  DenseMap<llvm::Type *, std::unique_ptr<Type, TypeDeleter>> LLVMTypeToTypeMap;
-
-  /// Callbacks called when an IR instruction is about to get erased. Keys are
-  /// used as IDs for deregistration.
-  MapVector<CallbackID, EraseInstrCallback> EraseInstrCallbacks;
-  /// Callbacks called when an IR instruction is about to get created. Keys are
-  /// used as IDs for deregistration.
-  MapVector<CallbackID, CreateInstrCallback> CreateInstrCallbacks;
-  /// Callbacks called when an IR instruction is about to get moved. Keys are
-  /// used as IDs for deregistration.
-  MapVector<CallbackID, MoveInstrCallback> MoveInstrCallbacks;
-  /// Callbacks called when a Use gets its source set. Keys are used as IDs for
-  /// deregistration.
-  MapVector<CallbackID, SetUseCallback> SetUseCallbacks;
-
-  /// A counter used for assigning callback IDs during registration. The same
-  /// counter is used for all kinds of callbacks so we can detect mismatched
-  /// registration/deregistration.
-  CallbackID::ValTy NextCallbackID = 1;
-
-  /// Remove \p V from the maps and returns the unique_ptr.
-  LLVM_ABI std::unique_ptr<Value> detachLLVMValue(llvm::Value *V);
-  /// Remove \p SBV from all SandboxIR maps and stop owning it. This effectively
-  /// detaches \p V from the underlying IR.
-  LLVM_ABI std::unique_ptr<Value> detach(Value *V);
-  friend class Instruction; // For detach().
-  /// Take ownership of VPtr and store it in `LLVMValueToValueMap`.
-  LLVM_ABI Value *registerValue(std::unique_ptr<Value> &&VPtr);
-  friend class EraseFromParent; // For registerValue().
-  /// This is the actual function that creates sandboxir values for \p V,
-  /// and among others handles all instruction types.
-  LLVM_ABI Value *getOrCreateValueInternal(llvm::Value *V,
-                                           llvm::User *U = nullptr);
-  /// Get or create a sandboxir::Argument for an existing LLVM IR \p LLVMArg.
-  LLVM_ABI Argument *getOrCreateArgument(llvm::Argument *LLVMArg);
-  /// Get or create a sandboxir::Value for an existing LLVM IR \p LLVMV.
-  Value *getOrCreateValue(llvm::Value *LLVMV) {
-    return getOrCreateValueInternal(LLVMV, 0);
-  }
-  /// Get or create a sandboxir::Constant from an existing LLVM IR \p LLVMC.
-  LLVM_ABI Constant *getOrCreateConstant(llvm::Constant *LLVMC);
-  friend class ConstantDataSequential; // For getOrCreateConstant().
-  friend class Utils; // For getMemoryBase
-
-  LLVM_ABI void runEraseInstrCallbacks(Instruction *I);
-  LLVM_ABI void runCreateInstrCallbacks(Instruction *I);
-  LLVM_ABI void runMoveInstrCallbacks(Instruction *I, const BBIterator &Where);
-  LLVM_ABI void runSetUseCallbacks(const Use &U, Value *NewSrc);
-
-  friend class User;  // For runSetUseCallbacks().
-  friend class Value; // For runSetUseCallbacks().
-
-  // Friends for getOrCreateConstant().
-#define DEF_CONST(ID, CLASS) friend class CLASS;
-#include "llvm/SandboxIR/Values.def"
-
-  /// Create a sandboxir::BasicBlock for an existing LLVM IR \p BB. This will
-  /// also create all contents of the block.
-  LLVM_ABI BasicBlock *createBasicBlock(llvm::BasicBlock *BB);
-  friend class BasicBlock; // For getOrCreateValue().
-
-  IRBuilder<ConstantFolder> LLVMIRBuilder;
-  auto &getLLVMIRBuilder() { return LLVMIRBuilder; }
-
-  LLVM_ABI VAArgInst *createVAArgInst(llvm::VAArgInst *SI);
-  friend VAArgInst; // For createVAArgInst()
-  LLVM_ABI FreezeInst *createFreezeInst(llvm::FreezeInst *SI);
-  friend FreezeInst; // For createFreezeInst()
-  LLVM_ABI FenceInst *createFenceInst(llvm::FenceInst *SI);
-  friend FenceInst; // For createFenceInst()
-  LLVM_ABI SelectInst *createSelectInst(llvm::SelectInst *SI);
-  friend SelectInst; // For createSelectInst()
-  LLVM_ABI InsertElementInst *
-  createInsertElementInst(llvm::InsertElementInst *IEI);
-  friend InsertElementInst; // For createInsertElementInst()
-  LLVM_ABI ExtractElementInst *
-  createExtractElementInst(llvm::ExtractElementInst *EEI);
-  friend ExtractElementInst; // For createExtractElementInst()
-  LLVM_ABI ShuffleVectorInst *
-  createShuffleVectorInst(llvm::ShuffleVectorInst *SVI);
-  friend ShuffleVectorInst; // For createShuffleVectorInst()
-  LLVM_ABI ExtractValueInst *
-  createExtractValueInst(llvm::ExtractValueInst *IVI);
-  friend ExtractValueInst; // For createExtractValueInst()
-  LLVM_ABI InsertValueInst *createInsertValueInst(llvm::InsertValueInst *IVI);
-  friend InsertValueInst; // For createInsertValueInst()
-  LLVM_ABI BranchInst *createBranchInst(llvm::BranchInst *I);
-  friend BranchInst; // For createBranchInst()
-  LLVM_ABI LoadInst *createLoadInst(llvm::LoadInst *LI);
-  friend LoadInst; // For createLoadInst()
-  LLVM_ABI StoreInst *createStoreInst(llvm::StoreInst *SI);
-  friend StoreInst; // For createStoreInst()
-  LLVM_ABI ReturnInst *createReturnInst(llvm::ReturnInst *I);
-  friend ReturnInst; // For createReturnInst()
-  LLVM_ABI CallInst *createCallInst(llvm::CallInst *I);
-  friend CallInst; // For createCallInst()
-  LLVM_ABI InvokeInst *createInvokeInst(llvm::InvokeInst *I);
-  friend InvokeInst; // For createInvokeInst()
-  LLVM_ABI CallBrInst *createCallBrInst(llvm::CallBrInst *I);
-  friend CallBrInst; // For createCallBrInst()
-  LLVM_ABI LandingPadInst *createLandingPadInst(llvm::LandingPadInst *I);
-  friend LandingPadInst; // For createLandingPadInst()
-  LLVM_ABI CatchPadInst *createCatchPadInst(llvm::CatchPadInst *I);
-  friend CatchPadInst; // For createCatchPadInst()
-  LLVM_ABI CleanupPadInst *createCleanupPadInst(llvm::CleanupPadInst *I);
-  friend CleanupPadInst; // For createCleanupPadInst()
-  LLVM_ABI CatchReturnInst *createCatchReturnInst(llvm::CatchReturnInst *I);
-  friend CatchReturnInst; // For createCatchReturnInst()
-  LLVM_ABI CleanupReturnInst *
-  createCleanupReturnInst(llvm::CleanupReturnInst *I);
-  friend CleanupReturnInst; // For createCleanupReturnInst()
-  LLVM_ABI GetElementPtrInst *
-  createGetElementPtrInst(llvm::GetElementPtrInst *I);
-  friend GetElementPtrInst; // For createGetElementPtrInst()
-  LLVM_ABI CatchSwitchInst *createCatchSwitchInst(llvm::CatchSwitchInst *I);
-  friend CatchSwitchInst; // For createCatchSwitchInst()
-  LLVM_ABI ResumeInst *createResumeInst(llvm::ResumeInst *I);
-  friend ResumeInst; // For createResumeInst()
-  LLVM_ABI SwitchInst *createSwitchInst(llvm::SwitchInst *I);
-  friend SwitchInst; // For createSwitchInst()
-  LLVM_ABI UnaryOperator *createUnaryOperator(llvm::UnaryOperator *I);
-  friend UnaryOperator; // For createUnaryOperator()
-  LLVM_ABI BinaryOperator *createBinaryOperator(llvm::BinaryOperator *I);
-  friend BinaryOperator; // For createBinaryOperator()
-  LLVM_ABI AtomicRMWInst *createAtomicRMWInst(llvm::AtomicRMWInst *I);
-  friend AtomicRMWInst; // For createAtomicRMWInst()
-  LLVM_ABI AtomicCmpXchgInst *
-  createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I);
-  friend AtomicCmpXchgInst; // For createAtomicCmpXchgInst()
-  LLVM_ABI AllocaInst *createAllocaInst(llvm::AllocaInst *I);
-  friend AllocaInst; // For createAllocaInst()
-  LLVM_ABI CastInst *createCastInst(llvm::CastInst *I);
-  friend CastInst; // For createCastInst()
-  LLVM_ABI PHINode *createPHINode(llvm::PHINode *I);
-  friend PHINode; // For createPHINode()
-  LLVM_ABI UnreachableInst *createUnreachableInst(llvm::UnreachableInst *UI);
-  friend UnreachableInst; // For createUnreachableInst()
-  LLVM_ABI CmpInst *createCmpInst(llvm::CmpInst *I);
-  friend CmpInst; // For createCmpInst()
-  LLVM_ABI ICmpInst *createICmpInst(llvm::ICmpInst *I);
-  friend ICmpInst; // For createICmpInst()
-  LLVM_ABI FCmpInst *createFCmpInst(llvm::FCmpInst *I);
-  friend FCmpInst; // For createFCmpInst()
-
-public:
-  LLVM_ABI Context(LLVMContext &LLVMCtx);
-  LLVM_ABI ~Context();
-  /// Clears function-level state.
-  LLVM_ABI void clear();
-
-  Tracker &getTracker() { return IRTracker; }
-  /// Convenience function for `getTracker().save()`
-  void save() { IRTracker.save(); }
-  /// Convenience function for `getTracker().revert()`
-  void revert() { IRTracker.revert(); }
-  /// Convenience function for `getTracker().accept()`
-  void accept() { IRTracker.accept(); }
-
-  LLVM_ABI sandboxir::Value *getValue(llvm::Value *V) const;
-  const sandboxir::Value *getValue(const llvm::Value *V) const {
-    return getValue(const_cast<llvm::Value *>(V));
-  }
-
-  LLVM_ABI Module *getModule(llvm::Module *LLVMM) const;
-
-  LLVM_ABI Module *getOrCreateModule(llvm::Module *LLVMM);
-
-  Type *getType(llvm::Type *LLVMTy) {
-    if (LLVMTy == nullptr)
-      return nullptr;
-    auto Pair = LLVMTypeToTypeMap.try_emplace(LLVMTy);
-    auto It = Pair.first;
-    if (Pair.second)
-      It->second = std::unique_ptr<Type, TypeDeleter>(new Type(LLVMTy, *this));
-    return It->second.get();
-  }
-
-  /// Create a sandboxir::Function for an existing LLVM IR \p F, including all
-  /// blocks and instructions.
-  /// This is the main API function for creating Sandbox IR.
-  /// Note: this will not fully populate its parent module. The only globals
-  /// that will be available are those used within the function.
-  LLVM_ABI Function *createFunction(llvm::Function *F);
-
-  /// Create a sandboxir::Module corresponding to \p LLVMM.
-  LLVM_ABI Module *createModule(llvm::Module *LLVMM);
-
-  /// \Returns the number of values registered with Context.
-  size_t getNumValues() const { return LLVMValueToValueMap.size(); }
-
-  /// Register a callback that gets called when a SandboxIR instruction is about
-  /// to be removed from its parent. Note that this will also be called when
-  /// reverting the creation of an instruction.
-  /// \Returns a callback ID for later deregistration.
-  LLVM_ABI CallbackID registerEraseInstrCallback(EraseInstrCallback CB);
-  LLVM_ABI void unregisterEraseInstrCallback(CallbackID ID);
-
-  /// Register a callback that gets called right after a SandboxIR instruction
-  /// is created. Note that this will also be called when reverting the removal
-  /// of an instruction.
-  /// \Returns a callback ID for later deregistration.
-  LLVM_ABI CallbackID registerCreateInstrCallback(CreateInstrCallback CB);
-  LLVM_ABI void unregisterCreateInstrCallback(CallbackID ID);
-
-  /// Register a callback that gets called when a SandboxIR instruction is about
-  /// to be moved. Note that this will also be called when reverting a move.
-  /// \Returns a callback ID for later deregistration.
-  LLVM_ABI CallbackID registerMoveInstrCallback(MoveInstrCallback CB);
-  LLVM_ABI void unregisterMoveInstrCallback(CallbackID ID);
-
-  /// Register a callback that gets called when a Use gets set.
-  /// \Returns a callback ID for later deregistration.
-  LLVM_ABI CallbackID registerSetUseCallback(SetUseCallback CB);
-  LLVM_ABI void unregisterSetUseCallback(CallbackID ID);
-};
-
-} // namespace sandboxir
-
-// DenseMap info for CallbackIDs
-template <> struct DenseMapInfo<sandboxir::Context::CallbackID> {
-  using CallbackID = sandboxir::Context::CallbackID;
-  using ReprInfo = DenseMapInfo<CallbackID::ValTy>;
-
-  static CallbackID getEmptyKey() {
-    return CallbackID{ReprInfo::getEmptyKey()};
-  }
-  static CallbackID getTombstoneKey() {
-    return CallbackID{ReprInfo::getTombstoneKey()};
-  }
-  static unsigned getHashValue(const CallbackID &ID) {
-    return ReprInfo::getHashValue(ID.Val);
-  }
-  static bool isEqual(const CallbackID &LHS, const CallbackID &RHS) {
-    return ReprInfo::isEqual(LHS.Val, RHS.Val);
-  }
-};
-
-} // namespace llvm
-
-#endif // LLVM_SANDBOXIR_CONTEXT_H
diff --git a/llvm/include/llvm/SandboxIR/Function.h b/llvm/include/llvm/SandboxIR/Function.h
deleted file mode 100644
index 28c69112b2b7e..0000000000000
--- a/llvm/include/llvm/SandboxIR/Function.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//===- Function.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_FUNCTION_H
-#define LLVM_SANDBOXIR_FUNCTION_H
-
-#include "llvm/IR/Function.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-class Function : public GlobalWithNodeAPI<Function, llvm::Function,
-                                          GlobalObject, llvm::GlobalObject> {
-  /// Helper for mapped_iterator.
-  struct LLVMBBToBB {
-    Context &Ctx;
-    LLVMBBToBB(Context &Ctx) : Ctx(Ctx) {}
-    BasicBlock &operator()(llvm::BasicBlock &LLVMBB) const {
-      return *cast<BasicBlock>(Ctx.getValue(&LLVMBB));
-    }
-  };
-  /// Use Context::createFunction() instead.
-  Function(llvm::Function *F, sandboxir::Context &Ctx)
-      : GlobalWithNodeAPI(ClassID::Function, F, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::Function;
-  }
-
-  Module *getParent() {
-    return Ctx.getModule(cast<llvm::Function>(Val)->getParent());
-  }
-
-  Argument *getArg(unsigned Idx) const {
-    llvm::Argument *Arg = cast<llvm::Function>(Val)->getArg(Idx);
-    return cast<Argument>(Ctx.getValue(Arg));
-  }
-
-  size_t arg_size() const { return cast<llvm::Function>(Val)->arg_size(); }
-  bool arg_empty() const { return cast<llvm::Function>(Val)->arg_empty(); }
-
-  using iterator = mapped_iterator<llvm::Function::iterator, LLVMBBToBB>;
-  iterator begin() const {
-    LLVMBBToBB BBGetter(Ctx);
-    return iterator(cast<llvm::Function>(Val)->begin(), BBGetter);
-  }
-  iterator end() const {
-    LLVMBBToBB BBGetter(Ctx);
-    return iterator(cast<llvm::Function>(Val)->end(), BBGetter);
-  }
-  LLVM_ABI FunctionType *getFunctionType() const;
-
-  /// Returns the alignment of the given function.
-  MaybeAlign getAlign() const { return cast<llvm::Function>(Val)->getAlign(); }
-
-  // TODO: Add missing: setAligment(Align)
-
-  /// Sets the alignment attribute of the Function.
-  /// This method will be deprecated as the alignment property should always be
-  /// defined.
-  LLVM_ABI void setAlignment(MaybeAlign Align);
-
-#ifndef NDEBUG
-  void verify() const final {
-    assert(isa<llvm::Function>(Val) && "Expected Function!");
-  }
-  void dumpNameAndArgs(raw_ostream &OS) const;
-  void dumpOS(raw_ostream &OS) const final;
-#endif
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_FUNCTION_H
diff --git a/llvm/include/llvm/SandboxIR/Instruction.h b/llvm/include/llvm/SandboxIR/Instruction.h
deleted file mode 100644
index 5e369a482be57..0000000000000
--- a/llvm/include/llvm/SandboxIR/Instruction.h
+++ /dev/null
@@ -1,2632 +0,0 @@
-//===- Instruction.h --------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_INSTRUCTION_H
-#define LLVM_SANDBOXIR_INSTRUCTION_H
-
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instructions.h"
-#include "llvm/IR/Module.h"
-#include "llvm/IR/PatternMatch.h"
-#include "llvm/SandboxIR/BasicBlock.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/User.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-// Forward declaration for MSVC.
-class IntrinsicInst;
-
-class InsertPosition {
-  BBIterator InsertAt;
-
-public:
-  InsertPosition(BasicBlock *InsertAtEnd) {
-    assert(InsertAtEnd != nullptr && "Expected non-null!");
-    InsertAt = InsertAtEnd->end();
-  }
-  InsertPosition(BBIterator InsertAt) : InsertAt(InsertAt) {}
-  operator BBIterator() { return InsertAt; }
-  const BBIterator &getIterator() const { return InsertAt; }
-  Instruction &operator*() { return *InsertAt; }
-  BasicBlock *getBasicBlock() const { return InsertAt.getNodeParent(); }
-};
-
-/// A sandboxir::User with operands, opcode and linked with previous/next
-/// instructions in an instruction list.
-class Instruction : public User {
-public:
-  enum class Opcode {
-#define OP(OPC) OPC,
-#define OPCODES(...) __VA_ARGS__
-#define DEF_INSTR(ID, OPC, CLASS) OPC
-#include "llvm/SandboxIR/Values.def"
-  };
-
-protected:
-  Instruction(ClassID ID, Opcode Opc, llvm::Instruction *I,
-              sandboxir::Context &SBCtx)
-      : User(ID, I, SBCtx), Opc(Opc) {}
-
-  Opcode Opc;
-
-  /// A SandboxIR Instruction may map to multiple LLVM IR Instruction. This
-  /// returns its topmost LLVM IR instruction.
-  LLVM_ABI llvm::Instruction *getTopmostLLVMInstruction() const;
-  friend class VAArgInst;          // For getTopmostLLVMInstruction().
-  friend class FreezeInst;         // For getTopmostLLVMInstruction().
-  friend class FenceInst;          // For getTopmostLLVMInstruction().
-  friend class SelectInst;         // For getTopmostLLVMInstruction().
-  friend class ExtractElementInst; // For getTopmostLLVMInstruction().
-  friend class InsertElementInst;  // For getTopmostLLVMInstruction().
-  friend class ShuffleVectorInst;  // For getTopmostLLVMInstruction().
-  friend class ExtractValueInst;   // For getTopmostLLVMInstruction().
-  friend class InsertValueInst;    // For getTopmostLLVMInstruction().
-  friend class BranchInst;         // For getTopmostLLVMInstruction().
-  friend class LoadInst;           // For getTopmostLLVMInstruction().
-  friend class StoreInst;          // For getTopmostLLVMInstruction().
-  friend class ReturnInst;         // For getTopmostLLVMInstruction().
-  friend class CallInst;           // For getTopmostLLVMInstruction().
-  friend class InvokeInst;         // For getTopmostLLVMInstruction().
-  friend class CallBrInst;         // For getTopmostLLVMInstruction().
-  friend class LandingPadInst;     // For getTopmostLLVMInstruction().
-  friend class CatchPadInst;       // For getTopmostLLVMInstruction().
-  friend class CleanupPadInst;     // For getTopmostLLVMInstruction().
-  friend class CatchReturnInst;    // For getTopmostLLVMInstruction().
-  friend class CleanupReturnInst;  // For getTopmostLLVMInstruction().
-  friend class GetElementPtrInst;  // For getTopmostLLVMInstruction().
-  friend class ResumeInst;         // For getTopmostLLVMInstruction().
-  friend class CatchSwitchInst;    // For getTopmostLLVMInstruction().
-  friend class SwitchInst;         // For getTopmostLLVMInstruction().
-  friend class UnaryOperator;      // For getTopmostLLVMInstruction().
-  friend class BinaryOperator;     // For getTopmostLLVMInstruction().
-  friend class AtomicRMWInst;      // For getTopmostLLVMInstruction().
-  friend class AtomicCmpXchgInst;  // For getTopmostLLVMInstruction().
-  friend class AllocaInst;         // For getTopmostLLVMInstruction().
-  friend class CastInst;           // For getTopmostLLVMInstruction().
-  friend class PHINode;            // For getTopmostLLVMInstruction().
-  friend class UnreachableInst;    // For getTopmostLLVMInstruction().
-  friend class CmpInst;            // For getTopmostLLVMInstruction().
-
-  /// \Returns the LLVM IR Instructions that this SandboxIR maps to in program
-  /// order.
-  virtual SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const = 0;
-  friend class EraseFromParent; // For getLLVMInstrs().
-
-  /// Helper function for create(). It sets the builder's insert position
-  /// according to \p Pos.
-  static IRBuilder<> &setInsertPos(InsertPosition Pos) {
-    auto *WhereBB = Pos.getBasicBlock();
-    auto WhereIt = Pos.getIterator();
-    auto &Ctx = WhereBB->getContext();
-    auto &Builder = Ctx.getLLVMIRBuilder();
-    if (WhereIt != WhereBB->end())
-      Builder.SetInsertPoint((*Pos).getTopmostLLVMInstruction());
-    else
-      Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
-    return Builder;
-  }
-
-public:
-  LLVM_ABI static const char *getOpcodeName(Opcode Opc);
-  /// This is used by BasicBlock::iterator.
-  virtual unsigned getNumOfIRInstrs() const = 0;
-  /// \Returns a BasicBlock::iterator for this Instruction.
-  LLVM_ABI BBIterator getIterator() const;
-  /// \Returns the next sandboxir::Instruction in the block, or nullptr if at
-  /// the end of the block.
-  LLVM_ABI Instruction *getNextNode() const;
-  /// \Returns the previous sandboxir::Instruction in the block, or nullptr if
-  /// at the beginning of the block.
-  LLVM_ABI Instruction *getPrevNode() const;
-  /// \Returns this Instruction's opcode. Note that SandboxIR has its own opcode
-  /// state to allow for new SandboxIR-specific instructions.
-  Opcode getOpcode() const { return Opc; }
-
-  const char *getOpcodeName() const { return getOpcodeName(Opc); }
-
-  const DataLayout &getDataLayout() const {
-    return cast<llvm::Instruction>(Val)->getModule()->getDataLayout();
-  }
-  // Note that these functions below are calling into llvm::Instruction.
-  // A sandbox IR instruction could introduce a new opcode that could change the
-  // behavior of one of these functions. It is better that these functions are
-  // only added as needed and new sandbox IR instructions must explicitly check
-  // if any of these functions could have a different behavior.
-
-  bool isTerminator() const {
-    return cast<llvm::Instruction>(Val)->isTerminator();
-  }
-  bool isUnaryOp() const { return cast<llvm::Instruction>(Val)->isUnaryOp(); }
-  bool isBinaryOp() const { return cast<llvm::Instruction>(Val)->isBinaryOp(); }
-  bool isIntDivRem() const {
-    return cast<llvm::Instruction>(Val)->isIntDivRem();
-  }
-  bool isShift() const { return cast<llvm::Instruction>(Val)->isShift(); }
-  bool isCast() const { return cast<llvm::Instruction>(Val)->isCast(); }
-  bool isFuncletPad() const {
-    return cast<llvm::Instruction>(Val)->isFuncletPad();
-  }
-  bool isSpecialTerminator() const {
-    return cast<llvm::Instruction>(Val)->isSpecialTerminator();
-  }
-  bool isOnlyUserOfAnyOperand() const {
-    return cast<llvm::Instruction>(Val)->isOnlyUserOfAnyOperand();
-  }
-  bool isLogicalShift() const {
-    return cast<llvm::Instruction>(Val)->isLogicalShift();
-  }
-
-  //===--------------------------------------------------------------------===//
-  // Metadata manipulation.
-  //===--------------------------------------------------------------------===//
-
-  /// Return true if the instruction has any metadata attached to it.
-  bool hasMetadata() const {
-    return cast<llvm::Instruction>(Val)->hasMetadata();
-  }
-
-  /// Return true if this instruction has metadata attached to it other than a
-  /// debug location.
-  bool hasMetadataOtherThanDebugLoc() const {
-    return cast<llvm::Instruction>(Val)->hasMetadataOtherThanDebugLoc();
-  }
-
-  /// Return true if this instruction has the given type of metadata attached.
-  bool hasMetadata(unsigned KindID) const {
-    return cast<llvm::Instruction>(Val)->hasMetadata(KindID);
-  }
-
-  // TODO: Implement getMetadata and getAllMetadata after sandboxir::MDNode is
-  // available.
-
-  // TODO: More missing functions
-
-  /// Detach this from its parent BasicBlock without deleting it.
-  LLVM_ABI void removeFromParent();
-  /// Detach this Value from its parent and delete it.
-  LLVM_ABI void eraseFromParent();
-  /// Insert this detached instruction before \p BeforeI.
-  LLVM_ABI void insertBefore(Instruction *BeforeI);
-  /// Insert this detached instruction after \p AfterI.
-  LLVM_ABI void insertAfter(Instruction *AfterI);
-  /// Insert this detached instruction into \p BB at \p WhereIt.
-  LLVM_ABI void insertInto(BasicBlock *BB, const BBIterator &WhereIt);
-  /// Move this instruction to \p WhereIt.
-  LLVM_ABI void moveBefore(BasicBlock &BB, const BBIterator &WhereIt);
-  /// Move this instruction before \p Before.
-  void moveBefore(Instruction *Before) {
-    moveBefore(*Before->getParent(), Before->getIterator());
-  }
-  /// Move this instruction after \p After.
-  void moveAfter(Instruction *After) {
-    moveBefore(*After->getParent(), std::next(After->getIterator()));
-  }
-  // TODO: This currently relies on LLVM IR Instruction::comesBefore which is
-  // can be linear-time.
-  /// Given an instruction Other in the same basic block as this instruction,
-  /// return true if this instruction comes before Other.
-  bool comesBefore(const Instruction *Other) const {
-    return cast<llvm::Instruction>(Val)->comesBefore(
-        cast<llvm::Instruction>(Other->Val));
-  }
-  /// \Returns the BasicBlock containing this Instruction, or null if it is
-  /// detached.
-  LLVM_ABI BasicBlock *getParent() const;
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const sandboxir::Value *From);
-
-  /// Determine whether the no signed wrap flag is set.
-  bool hasNoUnsignedWrap() const {
-    return cast<llvm::Instruction>(Val)->hasNoUnsignedWrap();
-  }
-  /// Set or clear the nuw flag on this instruction, which must be an operator
-  /// which supports this flag. See LangRef.html for the meaning of this flag.
-  LLVM_ABI void setHasNoUnsignedWrap(bool B = true);
-  /// Determine whether the no signed wrap flag is set.
-  bool hasNoSignedWrap() const {
-    return cast<llvm::Instruction>(Val)->hasNoSignedWrap();
-  }
-  /// Set or clear the nsw flag on this instruction, which must be an operator
-  /// which supports this flag. See LangRef.html for the meaning of this flag.
-  LLVM_ABI void setHasNoSignedWrap(bool B = true);
-  /// Determine whether all fast-math-flags are set.
-  bool isFast() const { return cast<llvm::Instruction>(Val)->isFast(); }
-  /// Set or clear all fast-math-flags on this instruction, which must be an
-  /// operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setFast(bool B);
-  /// Determine whether the allow-reassociation flag is set.
-  bool hasAllowReassoc() const {
-    return cast<llvm::Instruction>(Val)->hasAllowReassoc();
-  }
-  /// Set or clear the reassociation flag on this instruction, which must be
-  /// an operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setHasAllowReassoc(bool B);
-  /// Determine whether the exact flag is set.
-  bool isExact() const { return cast<llvm::Instruction>(Val)->isExact(); }
-  /// Set or clear the exact flag on this instruction, which must be an operator
-  /// which supports this flag. See LangRef.html for the meaning of this flag.
-  LLVM_ABI void setIsExact(bool B = true);
-  /// Determine whether the no-NaNs flag is set.
-  bool hasNoNaNs() const { return cast<llvm::Instruction>(Val)->hasNoNaNs(); }
-  /// Set or clear the no-nans flag on this instruction, which must be an
-  /// operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setHasNoNaNs(bool B);
-  /// Determine whether the no-infs flag is set.
-  bool hasNoInfs() const { return cast<llvm::Instruction>(Val)->hasNoInfs(); }
-  /// Set or clear the no-infs flag on this instruction, which must be an
-  /// operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setHasNoInfs(bool B);
-  /// Determine whether the no-signed-zeros flag is set.
-  bool hasNoSignedZeros() const {
-    return cast<llvm::Instruction>(Val)->hasNoSignedZeros();
-  }
-  /// Set or clear the no-signed-zeros flag on this instruction, which must be
-  /// an operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setHasNoSignedZeros(bool B);
-  /// Determine whether the allow-reciprocal flag is set.
-  bool hasAllowReciprocal() const {
-    return cast<llvm::Instruction>(Val)->hasAllowReciprocal();
-  }
-  /// Set or clear the allow-reciprocal flag on this instruction, which must be
-  /// an operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setHasAllowReciprocal(bool B);
-  /// Determine whether the allow-contract flag is set.
-  bool hasAllowContract() const {
-    return cast<llvm::Instruction>(Val)->hasAllowContract();
-  }
-  /// Set or clear the allow-contract flag on this instruction, which must be
-  /// an operator which supports this flag. See LangRef.html for the meaning of
-  /// this flag.
-  LLVM_ABI void setHasAllowContract(bool B);
-  /// Determine whether the approximate-math-functions flag is set.
-  bool hasApproxFunc() const {
-    return cast<llvm::Instruction>(Val)->hasApproxFunc();
-  }
-  /// Set or clear the approximate-math-functions flag on this instruction,
-  /// which must be an operator which supports this flag. See LangRef.html for
-  /// the meaning of this flag.
-  LLVM_ABI void setHasApproxFunc(bool B);
-  /// Convenience function for getting all the fast-math flags, which must be an
-  /// operator which supports these flags. See LangRef.html for the meaning of
-  /// these flags.
-  FastMathFlags getFastMathFlags() const {
-    return cast<llvm::Instruction>(Val)->getFastMathFlags();
-  }
-  /// Convenience function for setting multiple fast-math flags on this
-  /// instruction, which must be an operator which supports these flags. See
-  /// LangRef.html for the meaning of these flags.
-  LLVM_ABI void setFastMathFlags(FastMathFlags FMF);
-  /// Convenience function for transferring all fast-math flag values to this
-  /// instruction, which must be an operator which supports these flags. See
-  /// LangRef.html for the meaning of these flags.
-  LLVM_ABI void copyFastMathFlags(FastMathFlags FMF);
-
-  bool isAssociative() const {
-    return cast<llvm::Instruction>(Val)->isAssociative();
-  }
-
-  bool isCommutative() const {
-    return cast<llvm::Instruction>(Val)->isCommutative();
-  }
-
-  bool isIdempotent() const {
-    return cast<llvm::Instruction>(Val)->isIdempotent();
-  }
-
-  bool isNilpotent() const {
-    return cast<llvm::Instruction>(Val)->isNilpotent();
-  }
-
-  bool mayWriteToMemory() const {
-    return cast<llvm::Instruction>(Val)->mayWriteToMemory();
-  }
-
-  bool mayReadFromMemory() const {
-    return cast<llvm::Instruction>(Val)->mayReadFromMemory();
-  }
-  bool mayReadOrWriteMemory() const {
-    return cast<llvm::Instruction>(Val)->mayReadOrWriteMemory();
-  }
-
-  bool isAtomic() const { return cast<llvm::Instruction>(Val)->isAtomic(); }
-
-  bool hasAtomicLoad() const {
-    return cast<llvm::Instruction>(Val)->hasAtomicLoad();
-  }
-
-  bool hasAtomicStore() const {
-    return cast<llvm::Instruction>(Val)->hasAtomicStore();
-  }
-
-  bool isVolatile() const { return cast<llvm::Instruction>(Val)->isVolatile(); }
-
-  LLVM_ABI Type *getAccessType() const;
-
-  bool mayThrow(bool IncludePhaseOneUnwind = false) const {
-    return cast<llvm::Instruction>(Val)->mayThrow(IncludePhaseOneUnwind);
-  }
-
-  bool isFenceLike() const {
-    return cast<llvm::Instruction>(Val)->isFenceLike();
-  }
-
-  bool mayHaveSideEffects() const {
-    return cast<llvm::Instruction>(Val)->mayHaveSideEffects();
-  }
-
-  // TODO: Missing functions.
-
-#ifndef NDEBUG
-  void dumpOS(raw_ostream &OS) const override;
-#endif
-};
-
-/// Instructions that contain a single LLVM Instruction can inherit from this.
-template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {
-  SingleLLVMInstructionImpl(ClassID ID, Opcode Opc, llvm::Instruction *I,
-                            sandboxir::Context &SBCtx)
-      : Instruction(ID, Opc, I, SBCtx) {}
-
-  // All instructions are friends with this so they can call the constructor.
-#define DEF_INSTR(ID, OPC, CLASS) friend class CLASS;
-#include "llvm/SandboxIR/Values.def"
-  friend class UnaryInstruction;
-  friend class CallBase;
-  friend class FuncletPadInst;
-  friend class CmpInst;
-
-  Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
-    return getOperandUseDefault(OpIdx, Verify);
-  }
-  SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
-    return {cast<llvm::Instruction>(Val)};
-  }
-
-public:
-  unsigned getUseOperandNo(const Use &Use) const final {
-    return getUseOperandNoDefault(Use);
-  }
-  unsigned getNumOfIRInstrs() const final { return 1u; }
-#ifndef NDEBUG
-  void verify() const final { assert(isa<LLVMT>(Val) && "Expected LLVMT!"); }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif
-};
-
-class FenceInst : public SingleLLVMInstructionImpl<llvm::FenceInst> {
-  FenceInst(llvm::FenceInst *FI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Fence, Opcode::Fence, FI, Ctx) {}
-  friend Context; // For constructor;
-
-public:
-  LLVM_ABI static FenceInst *create(AtomicOrdering Ordering, InsertPosition Pos,
-                                    Context &Ctx,
-                                    SyncScope::ID SSID = SyncScope::System);
-  /// Returns the ordering constraint of this fence instruction.
-  AtomicOrdering getOrdering() const {
-    return cast<llvm::FenceInst>(Val)->getOrdering();
-  }
-  /// Sets the ordering constraint of this fence instruction.  May only be
-  /// Acquire, Release, AcquireRelease, or SequentiallyConsistent.
-  LLVM_ABI void setOrdering(AtomicOrdering Ordering);
-  /// Returns the synchronization scope ID of this fence instruction.
-  SyncScope::ID getSyncScopeID() const {
-    return cast<llvm::FenceInst>(Val)->getSyncScopeID();
-  }
-  /// Sets the synchronization scope ID of this fence instruction.
-  LLVM_ABI void setSyncScopeID(SyncScope::ID SSID);
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Fence;
-  }
-};
-
-class SelectInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {
-  /// Use Context::createSelectInst(). Don't call the
-  /// constructor directly.
-  SelectInst(llvm::SelectInst *CI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Select, Opcode::Select, CI, Ctx) {}
-  friend Context; // for SelectInst()
-
-public:
-  LLVM_ABI static Value *create(Value *Cond, Value *True, Value *False,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-
-  const Value *getCondition() const { return getOperand(0); }
-  const Value *getTrueValue() const { return getOperand(1); }
-  const Value *getFalseValue() const { return getOperand(2); }
-  Value *getCondition() { return getOperand(0); }
-  Value *getTrueValue() { return getOperand(1); }
-  Value *getFalseValue() { return getOperand(2); }
-
-  void setCondition(Value *New) { setOperand(0, New); }
-  void setTrueValue(Value *New) { setOperand(1, New); }
-  void setFalseValue(Value *New) { setOperand(2, New); }
-  LLVM_ABI void swapValues();
-
-  /// Return a string if the specified operands are invalid for a select
-  /// operation, otherwise return null.
-  static const char *areInvalidOperands(Value *Cond, Value *True,
-                                        Value *False) {
-    return llvm::SelectInst::areInvalidOperands(Cond->Val, True->Val,
-                                                False->Val);
-  }
-
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const Value *From);
-};
-
-class InsertElementInst final
-    : public SingleLLVMInstructionImpl<llvm::InsertElementInst> {
-  /// Use Context::createInsertElementInst() instead.
-  InsertElementInst(llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::InsertElement, Opcode::InsertElement,
-                                  I, Ctx) {}
-  friend class Context; // For accessing the constructor in create*()
-
-public:
-  LLVM_ABI static Value *create(Value *Vec, Value *NewElt, Value *Idx,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::InsertElement;
-  }
-  static bool isValidOperands(const Value *Vec, const Value *NewElt,
-                              const Value *Idx) {
-    return llvm::InsertElementInst::isValidOperands(Vec->Val, NewElt->Val,
-                                                    Idx->Val);
-  }
-};
-
-class ExtractElementInst final
-    : public SingleLLVMInstructionImpl<llvm::ExtractElementInst> {
-  /// Use Context::createExtractElementInst() instead.
-  ExtractElementInst(llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::ExtractElement,
-                                  Opcode::ExtractElement, I, Ctx) {}
-  friend class Context; // For accessing the constructor in
-                        // create*()
-
-public:
-  LLVM_ABI static Value *create(Value *Vec, Value *Idx, InsertPosition Pos,
-                                Context &Ctx, const Twine &Name = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ExtractElement;
-  }
-
-  static bool isValidOperands(const Value *Vec, const Value *Idx) {
-    return llvm::ExtractElementInst::isValidOperands(Vec->Val, Idx->Val);
-  }
-  Value *getVectorOperand() { return getOperand(0); }
-  Value *getIndexOperand() { return getOperand(1); }
-  const Value *getVectorOperand() const { return getOperand(0); }
-  const Value *getIndexOperand() const { return getOperand(1); }
-  LLVM_ABI VectorType *getVectorOperandType() const;
-};
-
-class ShuffleVectorInst final
-    : public SingleLLVMInstructionImpl<llvm::ShuffleVectorInst> {
-  /// Use Context::createShuffleVectorInst() instead.
-  ShuffleVectorInst(llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::ShuffleVector, Opcode::ShuffleVector,
-                                  I, Ctx) {}
-  friend class Context; // For accessing the constructor in create*()
-
-public:
-  LLVM_ABI static Value *create(Value *V1, Value *V2, Value *Mask,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-  LLVM_ABI static Value *create(Value *V1, Value *V2, ArrayRef<int> Mask,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ShuffleVector;
-  }
-
-  /// Swap the operands and adjust the mask to preserve the semantics of the
-  /// instruction.
-  LLVM_ABI void commute();
-
-  /// Return true if a shufflevector instruction can be formed with the
-  /// specified operands.
-  static bool isValidOperands(const Value *V1, const Value *V2,
-                              const Value *Mask) {
-    return llvm::ShuffleVectorInst::isValidOperands(V1->Val, V2->Val,
-                                                    Mask->Val);
-  }
-  static bool isValidOperands(const Value *V1, const Value *V2,
-                              ArrayRef<int> Mask) {
-    return llvm::ShuffleVectorInst::isValidOperands(V1->Val, V2->Val, Mask);
-  }
-
-  /// Overload to return most specific vector type.
-  LLVM_ABI VectorType *getType() const;
-
-  /// Return the shuffle mask value of this instruction for the given element
-  /// index. Return PoisonMaskElem if the element is undef.
-  int getMaskValue(unsigned Elt) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->getMaskValue(Elt);
-  }
-
-  /// Convert the input shuffle mask operand to a vector of integers. Undefined
-  /// elements of the mask are returned as PoisonMaskElem.
-  static void getShuffleMask(const Constant *Mask,
-                             SmallVectorImpl<int> &Result) {
-    llvm::ShuffleVectorInst::getShuffleMask(cast<llvm::Constant>(Mask->Val),
-                                            Result);
-  }
-
-  /// Return the mask for this instruction as a vector of integers. Undefined
-  /// elements of the mask are returned as PoisonMaskElem.
-  void getShuffleMask(SmallVectorImpl<int> &Result) const {
-    cast<llvm::ShuffleVectorInst>(Val)->getShuffleMask(Result);
-  }
-
-  /// Return the mask for this instruction, for use in bitcode.
-  LLVM_ABI Constant *getShuffleMaskForBitcode() const;
-
-  LLVM_ABI static Constant *convertShuffleMaskForBitcode(ArrayRef<int> Mask,
-                                                         Type *ResultTy);
-
-  LLVM_ABI void setShuffleMask(ArrayRef<int> Mask);
-
-  ArrayRef<int> getShuffleMask() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->getShuffleMask();
-  }
-
-  /// Return true if this shuffle returns a vector with a different number of
-  /// elements than its source vectors.
-  /// Examples: shufflevector <4 x n> A, <4 x n> B, <1,2,3>
-  ///           shufflevector <4 x n> A, <4 x n> B, <1,2,3,4,5>
-  bool changesLength() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->changesLength();
-  }
-
-  /// Return true if this shuffle returns a vector with a greater number of
-  /// elements than its source vectors.
-  /// Example: shufflevector <2 x n> A, <2 x n> B, <1,2,3>
-  bool increasesLength() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->increasesLength();
-  }
-
-  /// Return true if this shuffle mask chooses elements from exactly one source
-  /// vector.
-  /// Example: <7,5,undef,7>
-  /// This assumes that vector operands (of length \p NumSrcElts) are the same
-  /// length as the mask.
-  static bool isSingleSourceMask(ArrayRef<int> Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isSingleSourceMask(Mask, NumSrcElts);
-  }
-  static bool isSingleSourceMask(const Constant *Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isSingleSourceMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts);
-  }
-
-  /// Return true if this shuffle chooses elements from exactly one source
-  /// vector without changing the length of that vector.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <3,0,undef,3>
-  bool isSingleSource() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isSingleSource();
-  }
-
-  /// Return true if this shuffle mask chooses elements from exactly one source
-  /// vector without lane crossings. A shuffle using this mask is not
-  /// necessarily a no-op because it may change the number of elements from its
-  /// input vectors or it may provide demanded bits knowledge via undef lanes.
-  /// Example: <undef,undef,2,3>
-  static bool isIdentityMask(ArrayRef<int> Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts);
-  }
-  static bool isIdentityMask(const Constant *Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isIdentityMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts);
-  }
-
-  /// Return true if this shuffle chooses elements from exactly one source
-  /// vector without lane crossings and does not change the number of elements
-  /// from its input vectors.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <4,undef,6,undef>
-  bool isIdentity() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isIdentity();
-  }
-
-  /// Return true if this shuffle lengthens exactly one source vector with
-  /// undefs in the high elements.
-  bool isIdentityWithPadding() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isIdentityWithPadding();
-  }
-
-  /// Return true if this shuffle extracts the first N elements of exactly one
-  /// source vector.
-  bool isIdentityWithExtract() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isIdentityWithExtract();
-  }
-
-  /// Return true if this shuffle concatenates its 2 source vectors. This
-  /// returns false if either input is undefined. In that case, the shuffle is
-  /// is better classified as an identity with padding operation.
-  bool isConcat() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isConcat();
-  }
-
-  /// Return true if this shuffle mask chooses elements from its source vectors
-  /// without lane crossings. A shuffle using this mask would be
-  /// equivalent to a vector select with a constant condition operand.
-  /// Example: <4,1,6,undef>
-  /// This returns false if the mask does not choose from both input vectors.
-  /// In that case, the shuffle is better classified as an identity shuffle.
-  /// This assumes that vector operands are the same length as the mask
-  /// (a length-changing shuffle can never be equivalent to a vector select).
-  static bool isSelectMask(ArrayRef<int> Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isSelectMask(Mask, NumSrcElts);
-  }
-  static bool isSelectMask(const Constant *Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isSelectMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts);
-  }
-
-  /// Return true if this shuffle chooses elements from its source vectors
-  /// without lane crossings and all operands have the same number of elements.
-  /// In other words, this shuffle is equivalent to a vector select with a
-  /// constant condition operand.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <undef,1,6,3>
-  /// This returns false if the mask does not choose from both input vectors.
-  /// In that case, the shuffle is better classified as an identity shuffle.
-  bool isSelect() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isSelect();
-  }
-
-  /// Return true if this shuffle mask swaps the order of elements from exactly
-  /// one source vector.
-  /// Example: <7,6,undef,4>
-  /// This assumes that vector operands (of length \p NumSrcElts) are the same
-  /// length as the mask.
-  static bool isReverseMask(ArrayRef<int> Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isReverseMask(Mask, NumSrcElts);
-  }
-  static bool isReverseMask(const Constant *Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isReverseMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts);
-  }
-
-  /// Return true if this shuffle swaps the order of elements from exactly
-  /// one source vector.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <3,undef,1,undef>
-  bool isReverse() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isReverse();
-  }
-
-  /// Return true if this shuffle mask chooses all elements with the same value
-  /// as the first element of exactly one source vector.
-  /// Example: <4,undef,undef,4>
-  /// This assumes that vector operands (of length \p NumSrcElts) are the same
-  /// length as the mask.
-  static bool isZeroEltSplatMask(ArrayRef<int> Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isZeroEltSplatMask(Mask, NumSrcElts);
-  }
-  static bool isZeroEltSplatMask(const Constant *Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isZeroEltSplatMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts);
-  }
-
-  /// Return true if all elements of this shuffle are the same value as the
-  /// first element of exactly one source vector without changing the length
-  /// of that vector.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <undef,0,undef,0>
-  bool isZeroEltSplat() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isZeroEltSplat();
-  }
-
-  /// Return true if this shuffle mask is a transpose mask.
-  /// Transpose vector masks transpose a 2xn matrix. They read corresponding
-  /// even- or odd-numbered vector elements from two n-dimensional source
-  /// vectors and write each result into consecutive elements of an
-  /// n-dimensional destination vector. Two shuffles are necessary to complete
-  /// the transpose, one for the even elements and another for the odd elements.
-  /// This description closely follows how the TRN1 and TRN2 AArch64
-  /// instructions operate.
-  ///
-  /// For example, a simple 2x2 matrix can be transposed with:
-  ///
-  ///   ; Original matrix
-  ///   m0 = < a, b >
-  ///   m1 = < c, d >
-  ///
-  ///   ; Transposed matrix
-  ///   t0 = < a, c > = shufflevector m0, m1, < 0, 2 >
-  ///   t1 = < b, d > = shufflevector m0, m1, < 1, 3 >
-  ///
-  /// For matrices having greater than n columns, the resulting nx2 transposed
-  /// matrix is stored in two result vectors such that one vector contains
-  /// interleaved elements from all the even-numbered rows and the other vector
-  /// contains interleaved elements from all the odd-numbered rows. For example,
-  /// a 2x4 matrix can be transposed with:
-  ///
-  ///   ; Original matrix
-  ///   m0 = < a, b, c, d >
-  ///   m1 = < e, f, g, h >
-  ///
-  ///   ; Transposed matrix
-  ///   t0 = < a, e, c, g > = shufflevector m0, m1 < 0, 4, 2, 6 >
-  ///   t1 = < b, f, d, h > = shufflevector m0, m1 < 1, 5, 3, 7 >
-  static bool isTransposeMask(ArrayRef<int> Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isTransposeMask(Mask, NumSrcElts);
-  }
-  static bool isTransposeMask(const Constant *Mask, int NumSrcElts) {
-    return llvm::ShuffleVectorInst::isTransposeMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts);
-  }
-
-  /// Return true if this shuffle transposes the elements of its inputs without
-  /// changing the length of the vectors. This operation may also be known as a
-  /// merge or interleave. See the description for isTransposeMask() for the
-  /// exact specification.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <0,4,2,6>
-  bool isTranspose() const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isTranspose();
-  }
-
-  /// Return true if this shuffle mask is a splice mask, concatenating the two
-  /// inputs together and then extracts an original width vector starting from
-  /// the splice index.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
-  /// This assumes that vector operands (of length \p NumSrcElts) are the same
-  /// length as the mask.
-  static bool isSpliceMask(ArrayRef<int> Mask, int NumSrcElts, int &Index) {
-    return llvm::ShuffleVectorInst::isSpliceMask(Mask, NumSrcElts, Index);
-  }
-  static bool isSpliceMask(const Constant *Mask, int NumSrcElts, int &Index) {
-    return llvm::ShuffleVectorInst::isSpliceMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts, Index);
-  }
-
-  /// Return true if this shuffle splices two inputs without changing the length
-  /// of the vectors. This operation concatenates the two inputs together and
-  /// then extracts an original width vector starting from the splice index.
-  /// Example: shufflevector <4 x n> A, <4 x n> B, <1,2,3,4>
-  bool isSplice(int &Index) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isSplice(Index);
-  }
-
-  /// Return true if this shuffle mask is an extract subvector mask.
-  /// A valid extract subvector mask returns a smaller vector from a single
-  /// source operand. The base extraction index is returned as well.
-  static bool isExtractSubvectorMask(ArrayRef<int> Mask, int NumSrcElts,
-                                     int &Index) {
-    return llvm::ShuffleVectorInst::isExtractSubvectorMask(Mask, NumSrcElts,
-                                                           Index);
-  }
-  static bool isExtractSubvectorMask(const Constant *Mask, int NumSrcElts,
-                                     int &Index) {
-    return llvm::ShuffleVectorInst::isExtractSubvectorMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts, Index);
-  }
-
-  /// Return true if this shuffle mask is an extract subvector mask.
-  bool isExtractSubvectorMask(int &Index) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isExtractSubvectorMask(Index);
-  }
-
-  /// Return true if this shuffle mask is an insert subvector mask.
-  /// A valid insert subvector mask inserts the lowest elements of a second
-  /// source operand into an in-place first source operand.
-  /// Both the sub vector width and the insertion index is returned.
-  static bool isInsertSubvectorMask(ArrayRef<int> Mask, int NumSrcElts,
-                                    int &NumSubElts, int &Index) {
-    return llvm::ShuffleVectorInst::isInsertSubvectorMask(Mask, NumSrcElts,
-                                                          NumSubElts, Index);
-  }
-  static bool isInsertSubvectorMask(const Constant *Mask, int NumSrcElts,
-                                    int &NumSubElts, int &Index) {
-    return llvm::ShuffleVectorInst::isInsertSubvectorMask(
-        cast<llvm::Constant>(Mask->Val), NumSrcElts, NumSubElts, Index);
-  }
-
-  /// Return true if this shuffle mask is an insert subvector mask.
-  bool isInsertSubvectorMask(int &NumSubElts, int &Index) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isInsertSubvectorMask(NumSubElts,
-                                                                     Index);
-  }
-
-  /// Return true if this shuffle mask replicates each of the \p VF elements
-  /// in a vector \p ReplicationFactor times.
-  /// For example, the mask for \p ReplicationFactor=3 and \p VF=4 is:
-  ///   <0,0,0,1,1,1,2,2,2,3,3,3>
-  static bool isReplicationMask(ArrayRef<int> Mask, int &ReplicationFactor,
-                                int &VF) {
-    return llvm::ShuffleVectorInst::isReplicationMask(Mask, ReplicationFactor,
-                                                      VF);
-  }
-  static bool isReplicationMask(const Constant *Mask, int &ReplicationFactor,
-                                int &VF) {
-    return llvm::ShuffleVectorInst::isReplicationMask(
-        cast<llvm::Constant>(Mask->Val), ReplicationFactor, VF);
-  }
-
-  /// Return true if this shuffle mask is a replication mask.
-  bool isReplicationMask(int &ReplicationFactor, int &VF) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isReplicationMask(
-        ReplicationFactor, VF);
-  }
-
-  /// Return true if this shuffle mask represents "clustered" mask of size VF,
-  /// i.e. each index between [0..VF) is used exactly once in each submask of
-  /// size VF.
-  /// For example, the mask for \p VF=4 is:
-  /// 0, 1, 2, 3, 3, 2, 0, 1 - "clustered", because each submask of size 4
-  /// (0,1,2,3 and 3,2,0,1) uses indices [0..VF) exactly one time.
-  /// 0, 1, 2, 3, 3, 3, 1, 0 - not "clustered", because
-  ///                          element 3 is used twice in the second submask
-  ///                          (3,3,1,0) and index 2 is not used at all.
-  static bool isOneUseSingleSourceMask(ArrayRef<int> Mask, int VF) {
-    return llvm::ShuffleVectorInst::isOneUseSingleSourceMask(Mask, VF);
-  }
-
-  /// Return true if this shuffle mask is a one-use-single-source("clustered")
-  /// mask.
-  bool isOneUseSingleSourceMask(int VF) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isOneUseSingleSourceMask(VF);
-  }
-
-  /// Change values in a shuffle permute mask assuming the two vector operands
-  /// of length InVecNumElts have swapped position.
-  static void commuteShuffleMask(MutableArrayRef<int> Mask,
-                                 unsigned InVecNumElts) {
-    llvm::ShuffleVectorInst::commuteShuffleMask(Mask, InVecNumElts);
-  }
-
-  /// Return if this shuffle interleaves its two input vectors together.
-  bool isInterleave(unsigned Factor) const {
-    return cast<llvm::ShuffleVectorInst>(Val)->isInterleave(Factor);
-  }
-
-  /// Return true if the mask interleaves one or more input vectors together.
-  ///
-  /// I.e. <0, LaneLen, ... , LaneLen*(Factor - 1), 1, LaneLen + 1, ...>
-  /// E.g. For a Factor of 2 (LaneLen=4):
-  ///   <0, 4, 1, 5, 2, 6, 3, 7>
-  /// E.g. For a Factor of 3 (LaneLen=4):
-  ///   <4, 0, 9, 5, 1, 10, 6, 2, 11, 7, 3, 12>
-  /// E.g. For a Factor of 4 (LaneLen=2):
-  ///   <0, 2, 6, 4, 1, 3, 7, 5>
-  ///
-  /// NumInputElts is the total number of elements in the input vectors.
-  ///
-  /// StartIndexes are the first indexes of each vector being interleaved,
-  /// substituting any indexes that were undef
-  /// E.g. <4, -1, 2, 5, 1, 3> (Factor=3): StartIndexes=<4, 0, 2>
-  ///
-  /// Note that this does not check if the input vectors are consecutive:
-  /// It will return true for masks such as
-  /// <0, 4, 6, 1, 5, 7> (Factor=3, LaneLen=2)
-  static bool isInterleaveMask(ArrayRef<int> Mask, unsigned Factor,
-                               unsigned NumInputElts,
-                               SmallVectorImpl<unsigned> &StartIndexes) {
-    return llvm::ShuffleVectorInst::isInterleaveMask(Mask, Factor, NumInputElts,
-                                                     StartIndexes);
-  }
-  static bool isInterleaveMask(ArrayRef<int> Mask, unsigned Factor,
-                               unsigned NumInputElts) {
-    return llvm::ShuffleVectorInst::isInterleaveMask(Mask, Factor,
-                                                     NumInputElts);
-  }
-
-  /// Check if the mask is a DE-interleave mask of the given factor
-  /// \p Factor like:
-  ///     <Index, Index+Factor, ..., Index+(NumElts-1)*Factor>
-  static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor,
-                                         unsigned &Index) {
-    return llvm::ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, Factor,
-                                                               Index);
-  }
-  static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor) {
-    return llvm::ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, Factor);
-  }
-
-  /// Checks if the shuffle is a bit rotation of the first operand across
-  /// multiple subelements, e.g:
-  ///
-  /// shuffle <8 x i8> %a, <8 x i8> poison, <8 x i32> <1, 0, 3, 2, 5, 4, 7, 6>
-  ///
-  /// could be expressed as
-  ///
-  /// rotl <4 x i16> %a, 8
-  ///
-  /// If it can be expressed as a rotation, returns the number of subelements to
-  /// group by in NumSubElts and the number of bits to rotate left in RotateAmt.
-  static bool isBitRotateMask(ArrayRef<int> Mask, unsigned EltSizeInBits,
-                              unsigned MinSubElts, unsigned MaxSubElts,
-                              unsigned &NumSubElts, unsigned &RotateAmt) {
-    return llvm::ShuffleVectorInst::isBitRotateMask(
-        Mask, EltSizeInBits, MinSubElts, MaxSubElts, NumSubElts, RotateAmt);
-  }
-};
-
-class InsertValueInst
-    : public SingleLLVMInstructionImpl<llvm::InsertValueInst> {
-  /// Use Context::createInsertValueInst(). Don't call the constructor directly.
-  InsertValueInst(llvm::InsertValueInst *IVI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::InsertValue, Opcode::InsertValue,
-                                  IVI, Ctx) {}
-  friend Context; // for InsertValueInst()
-
-public:
-  LLVM_ABI static Value *create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::InsertValue;
-  }
-
-  using idx_iterator = llvm::InsertValueInst::idx_iterator;
-  inline idx_iterator idx_begin() const {
-    return cast<llvm::InsertValueInst>(Val)->idx_begin();
-  }
-  inline idx_iterator idx_end() const {
-    return cast<llvm::InsertValueInst>(Val)->idx_end();
-  }
-  inline iterator_range<idx_iterator> indices() const {
-    return cast<llvm::InsertValueInst>(Val)->indices();
-  }
-
-  Value *getAggregateOperand() {
-    return getOperand(getAggregateOperandIndex());
-  }
-  const Value *getAggregateOperand() const {
-    return getOperand(getAggregateOperandIndex());
-  }
-  static unsigned getAggregateOperandIndex() {
-    return llvm::InsertValueInst::getAggregateOperandIndex();
-  }
-
-  Value *getInsertedValueOperand() {
-    return getOperand(getInsertedValueOperandIndex());
-  }
-  const Value *getInsertedValueOperand() const {
-    return getOperand(getInsertedValueOperandIndex());
-  }
-  static unsigned getInsertedValueOperandIndex() {
-    return llvm::InsertValueInst::getInsertedValueOperandIndex();
-  }
-
-  ArrayRef<unsigned> getIndices() const {
-    return cast<llvm::InsertValueInst>(Val)->getIndices();
-  }
-
-  unsigned getNumIndices() const {
-    return cast<llvm::InsertValueInst>(Val)->getNumIndices();
-  }
-
-  unsigned hasIndices() const {
-    return cast<llvm::InsertValueInst>(Val)->hasIndices();
-  }
-};
-
-class BranchInst : public SingleLLVMInstructionImpl<llvm::BranchInst> {
-  /// Use Context::createBranchInst(). Don't call the constructor directly.
-  BranchInst(llvm::BranchInst *BI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Br, Opcode::Br, BI, Ctx) {}
-  friend Context; // for BranchInst()
-
-public:
-  LLVM_ABI static BranchInst *create(BasicBlock *IfTrue, InsertPosition Pos,
-                                     Context &Ctx);
-  LLVM_ABI static BranchInst *create(BasicBlock *IfTrue, BasicBlock *IfFalse,
-                                     Value *Cond, InsertPosition Pos,
-                                     Context &Ctx);
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const Value *From);
-  bool isUnconditional() const {
-    return cast<llvm::BranchInst>(Val)->isUnconditional();
-  }
-  bool isConditional() const {
-    return cast<llvm::BranchInst>(Val)->isConditional();
-  }
-  LLVM_ABI Value *getCondition() const;
-  void setCondition(Value *V) { setOperand(0, V); }
-  unsigned getNumSuccessors() const { return 1 + isConditional(); }
-  LLVM_ABI BasicBlock *getSuccessor(unsigned SuccIdx) const;
-  LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *NewSucc);
-  void swapSuccessors() { swapOperandsInternal(1, 2); }
-
-private:
-  struct LLVMBBToSBBB {
-    Context &Ctx;
-    LLVMBBToSBBB(Context &Ctx) : Ctx(Ctx) {}
-    LLVM_ABI BasicBlock *operator()(llvm::BasicBlock *BB) const;
-  };
-
-  struct ConstLLVMBBToSBBB {
-    Context &Ctx;
-    ConstLLVMBBToSBBB(Context &Ctx) : Ctx(Ctx) {}
-    LLVM_ABI const BasicBlock *operator()(const llvm::BasicBlock *BB) const;
-  };
-
-public:
-  using sb_succ_op_iterator =
-      mapped_iterator<llvm::BranchInst::succ_op_iterator, LLVMBBToSBBB>;
-  iterator_range<sb_succ_op_iterator> successors() {
-    iterator_range<llvm::BranchInst::succ_op_iterator> LLVMRange =
-        cast<llvm::BranchInst>(Val)->successors();
-    LLVMBBToSBBB BBMap(Ctx);
-    sb_succ_op_iterator MappedBegin = map_iterator(LLVMRange.begin(), BBMap);
-    sb_succ_op_iterator MappedEnd = map_iterator(LLVMRange.end(), BBMap);
-    return make_range(MappedBegin, MappedEnd);
-  }
-
-  using const_sb_succ_op_iterator =
-      mapped_iterator<llvm::BranchInst::const_succ_op_iterator,
-                      ConstLLVMBBToSBBB>;
-  iterator_range<const_sb_succ_op_iterator> successors() const {
-    iterator_range<llvm::BranchInst::const_succ_op_iterator> ConstLLVMRange =
-        static_cast<const llvm::BranchInst *>(cast<llvm::BranchInst>(Val))
-            ->successors();
-    ConstLLVMBBToSBBB ConstBBMap(Ctx);
-    const_sb_succ_op_iterator ConstMappedBegin =
-        map_iterator(ConstLLVMRange.begin(), ConstBBMap);
-    const_sb_succ_op_iterator ConstMappedEnd =
-        map_iterator(ConstLLVMRange.end(), ConstBBMap);
-    return make_range(ConstMappedBegin, ConstMappedEnd);
-  }
-};
-
-/// An abstract class, parent of unary instructions.
-class UnaryInstruction
-    : public SingleLLVMInstructionImpl<llvm::UnaryInstruction> {
-protected:
-  UnaryInstruction(ClassID ID, Opcode Opc, llvm::Instruction *LLVMI,
-                   Context &Ctx)
-      : SingleLLVMInstructionImpl(ID, Opc, LLVMI, Ctx) {}
-
-public:
-  static bool classof(const Instruction *I) {
-    return isa<LoadInst>(I) || isa<CastInst>(I) || isa<FreezeInst>(I);
-  }
-  static bool classof(const Value *V) {
-    return isa<Instruction>(V) && classof(cast<Instruction>(V));
-  }
-};
-
-class ExtractValueInst : public UnaryInstruction {
-  /// Use Context::createExtractValueInst() instead.
-  ExtractValueInst(llvm::ExtractValueInst *EVI, Context &Ctx)
-      : UnaryInstruction(ClassID::ExtractValue, Opcode::ExtractValue, EVI,
-                         Ctx) {}
-  friend Context; // for ExtractValueInst()
-
-public:
-  LLVM_ABI static Value *create(Value *Agg, ArrayRef<unsigned> Idxs,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ExtractValue;
-  }
-
-  /// Returns the type of the element that would be extracted
-  /// with an extractvalue instruction with the specified parameters.
-  ///
-  /// Null is returned if the indices are invalid for the specified type.
-  LLVM_ABI static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
-
-  using idx_iterator = llvm::ExtractValueInst::idx_iterator;
-
-  inline idx_iterator idx_begin() const {
-    return cast<llvm::ExtractValueInst>(Val)->idx_begin();
-  }
-  inline idx_iterator idx_end() const {
-    return cast<llvm::ExtractValueInst>(Val)->idx_end();
-  }
-  inline iterator_range<idx_iterator> indices() const {
-    return cast<llvm::ExtractValueInst>(Val)->indices();
-  }
-
-  Value *getAggregateOperand() {
-    return getOperand(getAggregateOperandIndex());
-  }
-  const Value *getAggregateOperand() const {
-    return getOperand(getAggregateOperandIndex());
-  }
-  static unsigned getAggregateOperandIndex() {
-    return llvm::ExtractValueInst::getAggregateOperandIndex();
-  }
-
-  ArrayRef<unsigned> getIndices() const {
-    return cast<llvm::ExtractValueInst>(Val)->getIndices();
-  }
-
-  unsigned getNumIndices() const {
-    return cast<llvm::ExtractValueInst>(Val)->getNumIndices();
-  }
-
-  unsigned hasIndices() const {
-    return cast<llvm::ExtractValueInst>(Val)->hasIndices();
-  }
-};
-
-class VAArgInst : public UnaryInstruction {
-  VAArgInst(llvm::VAArgInst *FI, Context &Ctx)
-      : UnaryInstruction(ClassID::VAArg, Opcode::VAArg, FI, Ctx) {}
-  friend Context; // For constructor;
-
-public:
-  LLVM_ABI static VAArgInst *create(Value *List, Type *Ty, InsertPosition Pos,
-                                    Context &Ctx, const Twine &Name = "");
-  LLVM_ABI Value *getPointerOperand();
-  const Value *getPointerOperand() const {
-    return const_cast<VAArgInst *>(this)->getPointerOperand();
-  }
-  static unsigned getPointerOperandIndex() {
-    return llvm::VAArgInst::getPointerOperandIndex();
-  }
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::VAArg;
-  }
-};
-
-class FreezeInst : public UnaryInstruction {
-  FreezeInst(llvm::FreezeInst *FI, Context &Ctx)
-      : UnaryInstruction(ClassID::Freeze, Opcode::Freeze, FI, Ctx) {}
-  friend Context; // For constructor;
-
-public:
-  LLVM_ABI static FreezeInst *create(Value *V, InsertPosition Pos, Context &Ctx,
-                                     const Twine &Name = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Freeze;
-  }
-};
-
-class LoadInst final : public UnaryInstruction {
-  /// Use LoadInst::create() instead of calling the constructor.
-  LoadInst(llvm::LoadInst *LI, Context &Ctx)
-      : UnaryInstruction(ClassID::Load, Opcode::Load, LI, Ctx) {}
-  friend Context; // for LoadInst()
-
-public:
-  /// Return true if this is a load from a volatile memory location.
-  bool isVolatile() const { return cast<llvm::LoadInst>(Val)->isVolatile(); }
-  /// Specify whether this is a volatile load or not.
-  LLVM_ABI void setVolatile(bool V);
-
-  LLVM_ABI static LoadInst *create(Type *Ty, Value *Ptr, MaybeAlign Align,
-                                   InsertPosition Pos, bool IsVolatile,
-                                   Context &Ctx, const Twine &Name = "");
-  static LoadInst *create(Type *Ty, Value *Ptr, MaybeAlign Align,
-                          InsertPosition Pos, Context &Ctx,
-                          const Twine &Name = "") {
-    return create(Ty, Ptr, Align, Pos, /*IsVolatile=*/false, Ctx, Name);
-  }
-
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const Value *From);
-  LLVM_ABI Value *getPointerOperand() const;
-  Align getAlign() const { return cast<llvm::LoadInst>(Val)->getAlign(); }
-  bool isUnordered() const { return cast<llvm::LoadInst>(Val)->isUnordered(); }
-  bool isSimple() const { return cast<llvm::LoadInst>(Val)->isSimple(); }
-};
-
-class StoreInst final : public SingleLLVMInstructionImpl<llvm::StoreInst> {
-  /// Use StoreInst::create().
-  StoreInst(llvm::StoreInst *SI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Store, Opcode::Store, SI, Ctx) {}
-  friend Context; // for StoreInst()
-
-public:
-  /// Return true if this is a store from a volatile memory location.
-  bool isVolatile() const { return cast<llvm::StoreInst>(Val)->isVolatile(); }
-  /// Specify whether this is a volatile store or not.
-  LLVM_ABI void setVolatile(bool V);
-
-  LLVM_ABI static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
-                                    InsertPosition Pos, bool IsVolatile,
-                                    Context &Ctx);
-  static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
-                           InsertPosition Pos, Context &Ctx) {
-    return create(V, Ptr, Align, Pos, /*IsVolatile=*/false, Ctx);
-  }
-
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const Value *From);
-  LLVM_ABI Value *getValueOperand() const;
-  LLVM_ABI Value *getPointerOperand() const;
-  Align getAlign() const { return cast<llvm::StoreInst>(Val)->getAlign(); }
-  bool isSimple() const { return cast<llvm::StoreInst>(Val)->isSimple(); }
-  bool isUnordered() const { return cast<llvm::StoreInst>(Val)->isUnordered(); }
-};
-
-class UnreachableInst final : public Instruction {
-  /// Use UnreachableInst::create() instead of calling the constructor.
-  UnreachableInst(llvm::UnreachableInst *I, Context &Ctx)
-      : Instruction(ClassID::Unreachable, Opcode::Unreachable, I, Ctx) {}
-  friend Context;
-  Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
-    return getOperandUseDefault(OpIdx, Verify);
-  }
-  SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
-    return {cast<llvm::Instruction>(Val)};
-  }
-
-public:
-  LLVM_ABI static UnreachableInst *create(InsertPosition Pos, Context &Ctx);
-  LLVM_ABI static bool classof(const Value *From);
-  unsigned getNumSuccessors() const { return 0; }
-  unsigned getUseOperandNo(const Use &Use) const final {
-    llvm_unreachable("UnreachableInst has no operands!");
-  }
-  unsigned getNumOfIRInstrs() const final { return 1u; }
-};
-
-class ReturnInst final : public SingleLLVMInstructionImpl<llvm::ReturnInst> {
-  /// Use ReturnInst::create() instead of calling the constructor.
-  ReturnInst(llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Ret, Opcode::Ret, I, Ctx) {}
-  ReturnInst(ClassID SubclassID, llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(SubclassID, Opcode::Ret, I, Ctx) {}
-  friend class Context; // For accessing the constructor in create*()
-  static ReturnInst *createCommon(Value *RetVal, IRBuilder<> &Builder,
-                                  Context &Ctx);
-
-public:
-  LLVM_ABI static ReturnInst *create(Value *RetVal, InsertPosition Pos,
-                                     Context &Ctx);
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Ret;
-  }
-  /// \Returns null if there is no return value.
-  LLVM_ABI Value *getReturnValue() const;
-};
-
-class CallBase : public SingleLLVMInstructionImpl<llvm::CallBase> {
-  CallBase(ClassID ID, Opcode Opc, llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(ID, Opc, I, Ctx) {}
-  friend class CallInst;   // For constructor.
-  friend class InvokeInst; // For constructor.
-  friend class CallBrInst; // For constructor.
-
-public:
-  static bool classof(const Value *From) {
-    auto Opc = From->getSubclassID();
-    return Opc == Instruction::ClassID::Call ||
-           Opc == Instruction::ClassID::Invoke ||
-           Opc == Instruction::ClassID::CallBr;
-  }
-
-  LLVM_ABI FunctionType *getFunctionType() const;
-
-  op_iterator data_operands_begin() { return op_begin(); }
-  const_op_iterator data_operands_begin() const {
-    return const_cast<CallBase *>(this)->data_operands_begin();
-  }
-  op_iterator data_operands_end() {
-    auto *LLVMCB = cast<llvm::CallBase>(Val);
-    auto Dist = LLVMCB->data_operands_end() - LLVMCB->data_operands_begin();
-    return op_begin() + Dist;
-  }
-  const_op_iterator data_operands_end() const {
-    auto *LLVMCB = cast<llvm::CallBase>(Val);
-    auto Dist = LLVMCB->data_operands_end() - LLVMCB->data_operands_begin();
-    return op_begin() + Dist;
-  }
-  iterator_range<op_iterator> data_ops() {
-    return make_range(data_operands_begin(), data_operands_end());
-  }
-  iterator_range<const_op_iterator> data_ops() const {
-    return make_range(data_operands_begin(), data_operands_end());
-  }
-  bool data_operands_empty() const {
-    return data_operands_end() == data_operands_begin();
-  }
-  unsigned data_operands_size() const {
-    return std::distance(data_operands_begin(), data_operands_end());
-  }
-  bool isDataOperand(Use U) const {
-    assert(this == U.getUser() &&
-           "Only valid to query with a use of this instruction!");
-    return cast<llvm::CallBase>(Val)->isDataOperand(U.LLVMUse);
-  }
-  unsigned getDataOperandNo(Use U) const {
-    assert(isDataOperand(U) && "Data operand # out of range!");
-    return cast<llvm::CallBase>(Val)->getDataOperandNo(U.LLVMUse);
-  }
-
-  /// Return the total number operands (not operand bundles) used by
-  /// every operand bundle in this OperandBundleUser.
-  unsigned getNumTotalBundleOperands() const {
-    return cast<llvm::CallBase>(Val)->getNumTotalBundleOperands();
-  }
-
-  op_iterator arg_begin() { return op_begin(); }
-  const_op_iterator arg_begin() const { return op_begin(); }
-  op_iterator arg_end() {
-    return data_operands_end() - getNumTotalBundleOperands();
-  }
-  const_op_iterator arg_end() const {
-    return const_cast<CallBase *>(this)->arg_end();
-  }
-  iterator_range<op_iterator> args() {
-    return make_range(arg_begin(), arg_end());
-  }
-  iterator_range<const_op_iterator> args() const {
-    return make_range(arg_begin(), arg_end());
-  }
-  bool arg_empty() const { return arg_end() == arg_begin(); }
-  unsigned arg_size() const { return arg_end() - arg_begin(); }
-
-  Value *getArgOperand(unsigned OpIdx) const {
-    assert(OpIdx < arg_size() && "Out of bounds!");
-    return getOperand(OpIdx);
-  }
-  void setArgOperand(unsigned OpIdx, Value *NewOp) {
-    assert(OpIdx < arg_size() && "Out of bounds!");
-    setOperand(OpIdx, NewOp);
-  }
-
-  Use getArgOperandUse(unsigned Idx) const {
-    assert(Idx < arg_size() && "Out of bounds!");
-    return getOperandUse(Idx);
-  }
-  Use getArgOperandUse(unsigned Idx) {
-    assert(Idx < arg_size() && "Out of bounds!");
-    return getOperandUse(Idx);
-  }
-
-  bool isArgOperand(Use U) const {
-    return cast<llvm::CallBase>(Val)->isArgOperand(U.LLVMUse);
-  }
-  unsigned getArgOperandNo(Use U) const {
-    return cast<llvm::CallBase>(Val)->getArgOperandNo(U.LLVMUse);
-  }
-  bool hasArgument(const Value *V) const { return is_contained(args(), V); }
-
-  LLVM_ABI Value *getCalledOperand() const;
-  LLVM_ABI Use getCalledOperandUse() const;
-
-  LLVM_ABI Function *getCalledFunction() const;
-  bool isIndirectCall() const {
-    return cast<llvm::CallBase>(Val)->isIndirectCall();
-  }
-  bool isCallee(Use U) const {
-    return cast<llvm::CallBase>(Val)->isCallee(U.LLVMUse);
-  }
-  LLVM_ABI Function *getCaller();
-  const Function *getCaller() const {
-    return const_cast<CallBase *>(this)->getCaller();
-  }
-  bool isMustTailCall() const {
-    return cast<llvm::CallBase>(Val)->isMustTailCall();
-  }
-  bool isTailCall() const { return cast<llvm::CallBase>(Val)->isTailCall(); }
-  Intrinsic::ID getIntrinsicID() const {
-    return cast<llvm::CallBase>(Val)->getIntrinsicID();
-  }
-  void setCalledOperand(Value *V) { getCalledOperandUse().set(V); }
-  LLVM_ABI void setCalledFunction(Function *F);
-  CallingConv::ID getCallingConv() const {
-    return cast<llvm::CallBase>(Val)->getCallingConv();
-  }
-  bool isInlineAsm() const { return cast<llvm::CallBase>(Val)->isInlineAsm(); }
-};
-
-class CallInst : public CallBase {
-  /// Use Context::createCallInst(). Don't call the
-  /// constructor directly.
-  CallInst(llvm::Instruction *I, Context &Ctx)
-      : CallBase(ClassID::Call, Opcode::Call, I, Ctx) {}
-  friend class Context;       // For accessing the constructor in create*()
-  friend class IntrinsicInst; // For constructor
-
-public:
-  LLVM_ABI static CallInst *create(FunctionType *FTy, Value *Func,
-                                   ArrayRef<Value *> Args, InsertPosition Pos,
-                                   Context &Ctx, const Twine &NameStr = "");
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Call;
-  }
-};
-
-class InvokeInst final : public CallBase {
-  /// Use Context::createInvokeInst(). Don't call the
-  /// constructor directly.
-  InvokeInst(llvm::Instruction *I, Context &Ctx)
-      : CallBase(ClassID::Invoke, Opcode::Invoke, I, Ctx) {}
-  friend class Context; // For accessing the constructor in
-                        // create*()
-
-public:
-  LLVM_ABI static InvokeInst *create(FunctionType *FTy, Value *Func,
-                                     BasicBlock *IfNormal,
-                                     BasicBlock *IfException,
-                                     ArrayRef<Value *> Args, InsertPosition Pos,
-                                     Context &Ctx, const Twine &NameStr = "");
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Invoke;
-  }
-  LLVM_ABI BasicBlock *getNormalDest() const;
-  LLVM_ABI BasicBlock *getUnwindDest() const;
-  LLVM_ABI void setNormalDest(BasicBlock *BB);
-  LLVM_ABI void setUnwindDest(BasicBlock *BB);
-  LLVM_ABI LandingPadInst *getLandingPadInst() const;
-  LLVM_ABI BasicBlock *getSuccessor(unsigned SuccIdx) const;
-  void setSuccessor(unsigned SuccIdx, BasicBlock *NewSucc) {
-    assert(SuccIdx < 2 && "Successor # out of range for invoke!");
-    if (SuccIdx == 0)
-      setNormalDest(NewSucc);
-    else
-      setUnwindDest(NewSucc);
-  }
-  unsigned getNumSuccessors() const {
-    return cast<llvm::InvokeInst>(Val)->getNumSuccessors();
-  }
-};
-
-class CallBrInst final : public CallBase {
-  /// Use Context::createCallBrInst(). Don't call the
-  /// constructor directly.
-  CallBrInst(llvm::Instruction *I, Context &Ctx)
-      : CallBase(ClassID::CallBr, Opcode::CallBr, I, Ctx) {}
-  friend class Context; // For accessing the constructor in
-                        // create*()
-
-public:
-  LLVM_ABI static CallBrInst *create(FunctionType *FTy, Value *Func,
-                                     BasicBlock *DefaultDest,
-                                     ArrayRef<BasicBlock *> IndirectDests,
-                                     ArrayRef<Value *> Args, InsertPosition Pos,
-                                     Context &Ctx, const Twine &NameStr = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CallBr;
-  }
-  unsigned getNumIndirectDests() const {
-    return cast<llvm::CallBrInst>(Val)->getNumIndirectDests();
-  }
-  LLVM_ABI Value *getIndirectDestLabel(unsigned Idx) const;
-  LLVM_ABI Value *getIndirectDestLabelUse(unsigned Idx) const;
-  LLVM_ABI BasicBlock *getDefaultDest() const;
-  LLVM_ABI BasicBlock *getIndirectDest(unsigned Idx) const;
-  LLVM_ABI SmallVector<BasicBlock *, 16> getIndirectDests() const;
-  LLVM_ABI void setDefaultDest(BasicBlock *BB);
-  LLVM_ABI void setIndirectDest(unsigned Idx, BasicBlock *BB);
-  LLVM_ABI BasicBlock *getSuccessor(unsigned Idx) const;
-  unsigned getNumSuccessors() const {
-    return cast<llvm::CallBrInst>(Val)->getNumSuccessors();
-  }
-};
-
-class LandingPadInst : public SingleLLVMInstructionImpl<llvm::LandingPadInst> {
-  LandingPadInst(llvm::LandingPadInst *LP, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::LandingPad, Opcode::LandingPad, LP,
-                                  Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static LandingPadInst *create(Type *RetTy,
-                                         unsigned NumReservedClauses,
-                                         InsertPosition Pos, Context &Ctx,
-                                         const Twine &Name = "");
-  /// Return 'true' if this landingpad instruction is a
-  /// cleanup. I.e., it should be run when unwinding even if its landing pad
-  /// doesn't catch the exception.
-  bool isCleanup() const {
-    return cast<llvm::LandingPadInst>(Val)->isCleanup();
-  }
-  /// Indicate that this landingpad instruction is a cleanup.
-  LLVM_ABI void setCleanup(bool V);
-
-  // TODO: We are not implementing addClause() because we have no way to revert
-  // it for now.
-
-  /// Get the value of the clause at index Idx. Use isCatch/isFilter to
-  /// determine what type of clause this is.
-  LLVM_ABI Constant *getClause(unsigned Idx) const;
-
-  /// Return 'true' if the clause and index Idx is a catch clause.
-  bool isCatch(unsigned Idx) const {
-    return cast<llvm::LandingPadInst>(Val)->isCatch(Idx);
-  }
-  /// Return 'true' if the clause and index Idx is a filter clause.
-  bool isFilter(unsigned Idx) const {
-    return cast<llvm::LandingPadInst>(Val)->isFilter(Idx);
-  }
-  /// Get the number of clauses for this landing pad.
-  unsigned getNumClauses() const {
-    return cast<llvm::LandingPadInst>(Val)->getNumOperands();
-  }
-  // TODO: We are not implementing reserveClauses() because we can't revert it.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::LandingPad;
-  }
-};
-
-class FuncletPadInst : public SingleLLVMInstructionImpl<llvm::FuncletPadInst> {
-  FuncletPadInst(ClassID SubclassID, Opcode Opc, llvm::Instruction *I,
-                 Context &Ctx)
-      : SingleLLVMInstructionImpl(SubclassID, Opc, I, Ctx) {}
-  friend class CatchPadInst;   // For constructor.
-  friend class CleanupPadInst; // For constructor.
-
-public:
-  /// Return the number of funcletpad arguments.
-  unsigned arg_size() const {
-    return cast<llvm::FuncletPadInst>(Val)->arg_size();
-  }
-  /// Return the outer EH-pad this funclet is nested within.
-  ///
-  /// Note: This returns the associated CatchSwitchInst if this FuncletPadInst
-  /// is a CatchPadInst.
-  LLVM_ABI Value *getParentPad() const;
-  LLVM_ABI void setParentPad(Value *ParentPad);
-  /// Return the Idx-th funcletpad argument.
-  LLVM_ABI Value *getArgOperand(unsigned Idx) const;
-  /// Set the Idx-th funcletpad argument.
-  LLVM_ABI void setArgOperand(unsigned Idx, Value *V);
-
-  // TODO: Implement missing functions: arg_operands().
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CatchPad ||
-           From->getSubclassID() == ClassID::CleanupPad;
-  }
-};
-
-class CatchPadInst : public FuncletPadInst {
-  CatchPadInst(llvm::CatchPadInst *CPI, Context &Ctx)
-      : FuncletPadInst(ClassID::CatchPad, Opcode::CatchPad, CPI, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI CatchSwitchInst *getCatchSwitch() const;
-  // TODO: We have not implemented setCatchSwitch() because we can't revert it
-  // for now, as there is no CatchPadInst member function that can undo it.
-
-  LLVM_ABI static CatchPadInst *create(Value *ParentPad, ArrayRef<Value *> Args,
-                                       InsertPosition Pos, Context &Ctx,
-                                       const Twine &Name = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CatchPad;
-  }
-};
-
-class CleanupPadInst : public FuncletPadInst {
-  CleanupPadInst(llvm::CleanupPadInst *CPI, Context &Ctx)
-      : FuncletPadInst(ClassID::CleanupPad, Opcode::CleanupPad, CPI, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static CleanupPadInst *create(Value *ParentPad,
-                                         ArrayRef<Value *> Args,
-                                         InsertPosition Pos, Context &Ctx,
-                                         const Twine &Name = "");
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CleanupPad;
-  }
-};
-
-class CatchReturnInst
-    : public SingleLLVMInstructionImpl<llvm::CatchReturnInst> {
-  CatchReturnInst(llvm::CatchReturnInst *CRI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::CatchRet, Opcode::CatchRet, CRI,
-                                  Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static CatchReturnInst *create(CatchPadInst *CatchPad,
-                                          BasicBlock *BB, InsertPosition Pos,
-                                          Context &Ctx);
-  LLVM_ABI CatchPadInst *getCatchPad() const;
-  LLVM_ABI void setCatchPad(CatchPadInst *CatchPad);
-  LLVM_ABI BasicBlock *getSuccessor() const;
-  LLVM_ABI void setSuccessor(BasicBlock *NewSucc);
-  unsigned getNumSuccessors() {
-    return cast<llvm::CatchReturnInst>(Val)->getNumSuccessors();
-  }
-  LLVM_ABI Value *getCatchSwitchParentPad() const;
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CatchRet;
-  }
-};
-
-class CleanupReturnInst
-    : public SingleLLVMInstructionImpl<llvm::CleanupReturnInst> {
-  CleanupReturnInst(llvm::CleanupReturnInst *CRI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::CleanupRet, Opcode::CleanupRet, CRI,
-                                  Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static CleanupReturnInst *create(CleanupPadInst *CleanupPad,
-                                            BasicBlock *UnwindBB,
-                                            InsertPosition Pos, Context &Ctx);
-  bool hasUnwindDest() const {
-    return cast<llvm::CleanupReturnInst>(Val)->hasUnwindDest();
-  }
-  bool unwindsToCaller() const {
-    return cast<llvm::CleanupReturnInst>(Val)->unwindsToCaller();
-  }
-  LLVM_ABI CleanupPadInst *getCleanupPad() const;
-  LLVM_ABI void setCleanupPad(CleanupPadInst *CleanupPad);
-  unsigned getNumSuccessors() const {
-    return cast<llvm::CleanupReturnInst>(Val)->getNumSuccessors();
-  }
-  LLVM_ABI BasicBlock *getUnwindDest() const;
-  LLVM_ABI void setUnwindDest(BasicBlock *NewDest);
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CleanupRet;
-  }
-};
-
-class GetElementPtrInst final
-    : public SingleLLVMInstructionImpl<llvm::GetElementPtrInst> {
-  /// Use Context::createGetElementPtrInst(). Don't call
-  /// the constructor directly.
-  GetElementPtrInst(llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::GetElementPtr, Opcode::GetElementPtr,
-                                  I, Ctx) {}
-  GetElementPtrInst(ClassID SubclassID, llvm::Instruction *I, Context &Ctx)
-      : SingleLLVMInstructionImpl(SubclassID, Opcode::GetElementPtr, I, Ctx) {}
-  friend class Context; // For accessing the constructor in
-                        // create*()
-
-public:
-  LLVM_ABI static Value *create(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &NameStr = "");
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::GetElementPtr;
-  }
-
-  LLVM_ABI Type *getSourceElementType() const;
-  LLVM_ABI Type *getResultElementType() const;
-  unsigned getAddressSpace() const {
-    return cast<llvm::GetElementPtrInst>(Val)->getAddressSpace();
-  }
-
-  inline op_iterator idx_begin() { return op_begin() + 1; }
-  inline const_op_iterator idx_begin() const {
-    return const_cast<GetElementPtrInst *>(this)->idx_begin();
-  }
-  inline op_iterator idx_end() { return op_end(); }
-  inline const_op_iterator idx_end() const {
-    return const_cast<GetElementPtrInst *>(this)->idx_end();
-  }
-  inline iterator_range<op_iterator> indices() {
-    return make_range(idx_begin(), idx_end());
-  }
-  inline iterator_range<const_op_iterator> indices() const {
-    return const_cast<GetElementPtrInst *>(this)->indices();
-  }
-
-  LLVM_ABI Value *getPointerOperand() const;
-  static unsigned getPointerOperandIndex() {
-    return llvm::GetElementPtrInst::getPointerOperandIndex();
-  }
-  LLVM_ABI Type *getPointerOperandType() const;
-  unsigned getPointerAddressSpace() const {
-    return cast<llvm::GetElementPtrInst>(Val)->getPointerAddressSpace();
-  }
-  unsigned getNumIndices() const {
-    return cast<llvm::GetElementPtrInst>(Val)->getNumIndices();
-  }
-  bool hasIndices() const {
-    return cast<llvm::GetElementPtrInst>(Val)->hasIndices();
-  }
-  bool hasAllConstantIndices() const {
-    return cast<llvm::GetElementPtrInst>(Val)->hasAllConstantIndices();
-  }
-  GEPNoWrapFlags getNoWrapFlags() const {
-    return cast<llvm::GetElementPtrInst>(Val)->getNoWrapFlags();
-  }
-  bool isInBounds() const {
-    return cast<llvm::GetElementPtrInst>(Val)->isInBounds();
-  }
-  bool hasNoUnsignedSignedWrap() const {
-    return cast<llvm::GetElementPtrInst>(Val)->hasNoUnsignedSignedWrap();
-  }
-  bool hasNoUnsignedWrap() const {
-    return cast<llvm::GetElementPtrInst>(Val)->hasNoUnsignedWrap();
-  }
-  bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
-    return cast<llvm::GetElementPtrInst>(Val)->accumulateConstantOffset(DL,
-                                                                        Offset);
-  }
-  // TODO: Add missing member functions.
-};
-
-class CatchSwitchInst
-    : public SingleLLVMInstructionImpl<llvm::CatchSwitchInst> {
-  CatchSwitchInst(llvm::CatchSwitchInst *CSI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::CatchSwitch, Opcode::CatchSwitch,
-                                  CSI, Ctx) {}
-  friend class Context; // For accessing the constructor in create*()
-
-public:
-  LLVM_ABI static CatchSwitchInst *
-  create(Value *ParentPad, BasicBlock *UnwindBB, unsigned NumHandlers,
-         InsertPosition Pos, Context &Ctx, const Twine &Name = "");
-
-  LLVM_ABI Value *getParentPad() const;
-  LLVM_ABI void setParentPad(Value *ParentPad);
-
-  bool hasUnwindDest() const {
-    return cast<llvm::CatchSwitchInst>(Val)->hasUnwindDest();
-  }
-  bool unwindsToCaller() const {
-    return cast<llvm::CatchSwitchInst>(Val)->unwindsToCaller();
-  }
-  LLVM_ABI BasicBlock *getUnwindDest() const;
-  LLVM_ABI void setUnwindDest(BasicBlock *UnwindDest);
-
-  unsigned getNumHandlers() const {
-    return cast<llvm::CatchSwitchInst>(Val)->getNumHandlers();
-  }
-
-private:
-  static BasicBlock *handler_helper(Value *V) { return cast<BasicBlock>(V); }
-  static const BasicBlock *handler_helper(const Value *V) {
-    return cast<BasicBlock>(V);
-  }
-
-public:
-  using DerefFnTy = BasicBlock *(*)(Value *);
-  using handler_iterator = mapped_iterator<op_iterator, DerefFnTy>;
-  using handler_range = iterator_range<handler_iterator>;
-  using ConstDerefFnTy = const BasicBlock *(*)(const Value *);
-  using const_handler_iterator =
-      mapped_iterator<const_op_iterator, ConstDerefFnTy>;
-  using const_handler_range = iterator_range<const_handler_iterator>;
-
-  handler_iterator handler_begin() {
-    op_iterator It = op_begin() + 1;
-    if (hasUnwindDest())
-      ++It;
-    return handler_iterator(It, DerefFnTy(handler_helper));
-  }
-  const_handler_iterator handler_begin() const {
-    const_op_iterator It = op_begin() + 1;
-    if (hasUnwindDest())
-      ++It;
-    return const_handler_iterator(It, ConstDerefFnTy(handler_helper));
-  }
-  handler_iterator handler_end() {
-    return handler_iterator(op_end(), DerefFnTy(handler_helper));
-  }
-  const_handler_iterator handler_end() const {
-    return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper));
-  }
-  handler_range handlers() {
-    return make_range(handler_begin(), handler_end());
-  }
-  const_handler_range handlers() const {
-    return make_range(handler_begin(), handler_end());
-  }
-
-  LLVM_ABI void addHandler(BasicBlock *Dest);
-
-  // TODO: removeHandler() cannot be reverted because there is no equivalent
-  // addHandler() with a handler_iterator to specify the position. So we can't
-  // implement it for now.
-
-  unsigned getNumSuccessors() const { return getNumOperands() - 1; }
-  BasicBlock *getSuccessor(unsigned Idx) const {
-    assert(Idx < getNumSuccessors() &&
-           "Successor # out of range for catchswitch!");
-    return cast<BasicBlock>(getOperand(Idx + 1));
-  }
-  void setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
-    assert(Idx < getNumSuccessors() &&
-           "Successor # out of range for catchswitch!");
-    setOperand(Idx + 1, NewSucc);
-  }
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::CatchSwitch;
-  }
-};
-
-class ResumeInst : public SingleLLVMInstructionImpl<llvm::ResumeInst> {
-  ResumeInst(llvm::ResumeInst *CSI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Resume, Opcode::Resume, CSI, Ctx) {}
-  friend class Context; // For accessing the constructor in create*()
-
-public:
-  LLVM_ABI static ResumeInst *create(Value *Exn, InsertPosition Pos,
-                                     Context &Ctx);
-  LLVM_ABI Value *getValue() const;
-  unsigned getNumSuccessors() const {
-    return cast<llvm::ResumeInst>(Val)->getNumSuccessors();
-  }
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Resume;
-  }
-};
-
-class SwitchInst : public SingleLLVMInstructionImpl<llvm::SwitchInst> {
-  SwitchInst(llvm::SwitchInst *SI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Switch, Opcode::Switch, SI, Ctx) {}
-  friend class Context; // For accessing the constructor in create*()
-
-public:
-  static constexpr unsigned DefaultPseudoIndex =
-      llvm::SwitchInst::DefaultPseudoIndex;
-
-  LLVM_ABI static SwitchInst *create(Value *V, BasicBlock *Dest,
-                                     unsigned NumCases, InsertPosition Pos,
-                                     Context &Ctx, const Twine &Name = "");
-
-  LLVM_ABI Value *getCondition() const;
-  LLVM_ABI void setCondition(Value *V);
-  LLVM_ABI BasicBlock *getDefaultDest() const;
-  bool defaultDestUnreachable() const {
-    return cast<llvm::SwitchInst>(Val)->defaultDestUnreachable();
-  }
-  LLVM_ABI void setDefaultDest(BasicBlock *DefaultCase);
-  unsigned getNumCases() const {
-    return cast<llvm::SwitchInst>(Val)->getNumCases();
-  }
-
-  using CaseHandle =
-      llvm::SwitchInst::CaseHandleImpl<SwitchInst, ConstantInt, BasicBlock>;
-  using ConstCaseHandle =
-      llvm::SwitchInst::CaseHandleImpl<const SwitchInst, const ConstantInt,
-                                       const BasicBlock>;
-  using CaseIt = llvm::SwitchInst::CaseIteratorImpl<CaseHandle>;
-  using ConstCaseIt = llvm::SwitchInst::CaseIteratorImpl<ConstCaseHandle>;
-
-  /// Returns a read/write iterator that points to the first case in the
-  /// SwitchInst.
-  CaseIt case_begin() { return CaseIt(this, 0); }
-  ConstCaseIt case_begin() const { return ConstCaseIt(this, 0); }
-  /// Returns a read/write iterator that points one past the last in the
-  /// SwitchInst.
-  CaseIt case_end() { return CaseIt(this, getNumCases()); }
-  ConstCaseIt case_end() const { return ConstCaseIt(this, getNumCases()); }
-  /// Iteration adapter for range-for loops.
-  iterator_range<CaseIt> cases() {
-    return make_range(case_begin(), case_end());
-  }
-  iterator_range<ConstCaseIt> cases() const {
-    return make_range(case_begin(), case_end());
-  }
-  CaseIt case_default() { return CaseIt(this, DefaultPseudoIndex); }
-  ConstCaseIt case_default() const {
-    return ConstCaseIt(this, DefaultPseudoIndex);
-  }
-  CaseIt findCaseValue(const ConstantInt *C) {
-    return CaseIt(
-        this,
-        const_cast<const SwitchInst *>(this)->findCaseValue(C)->getCaseIndex());
-  }
-  ConstCaseIt findCaseValue(const ConstantInt *C) const {
-    ConstCaseIt I = llvm::find_if(cases(), [C](const ConstCaseHandle &Case) {
-      return Case.getCaseValue() == C;
-    });
-    if (I != case_end())
-      return I;
-    return case_default();
-  }
-  LLVM_ABI ConstantInt *findCaseDest(BasicBlock *BB);
-
-  LLVM_ABI void addCase(ConstantInt *OnVal, BasicBlock *Dest);
-  /// This method removes the specified case and its successor from the switch
-  /// instruction. Note that this operation may reorder the remaining cases at
-  /// index idx and above.
-  /// Note:
-  /// This action invalidates iterators for all cases following the one removed,
-  /// including the case_end() iterator. It returns an iterator for the next
-  /// case.
-  LLVM_ABI CaseIt removeCase(CaseIt It);
-
-  unsigned getNumSuccessors() const {
-    return cast<llvm::SwitchInst>(Val)->getNumSuccessors();
-  }
-  LLVM_ABI BasicBlock *getSuccessor(unsigned Idx) const;
-  LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *NewSucc);
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::Switch;
-  }
-};
-
-class UnaryOperator : public UnaryInstruction {
-  static Opcode getUnaryOpcode(llvm::Instruction::UnaryOps UnOp) {
-    switch (UnOp) {
-    case llvm::Instruction::FNeg:
-      return Opcode::FNeg;
-    case llvm::Instruction::UnaryOpsEnd:
-      llvm_unreachable("Bad UnOp!");
-    }
-    llvm_unreachable("Unhandled UnOp!");
-  }
-  UnaryOperator(llvm::UnaryOperator *UO, Context &Ctx)
-      : UnaryInstruction(ClassID::UnOp, getUnaryOpcode(UO->getOpcode()), UO,
-                         Ctx) {}
-  friend Context; // for constructor.
-public:
-  LLVM_ABI static Value *create(Instruction::Opcode Op, Value *OpV,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-  LLVM_ABI static Value *createWithCopiedFlags(Instruction::Opcode Op,
-                                               Value *OpV, Value *CopyFrom,
-                                               InsertPosition Pos, Context &Ctx,
-                                               const Twine &Name = "");
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::UnOp;
-  }
-};
-
-class BinaryOperator : public SingleLLVMInstructionImpl<llvm::BinaryOperator> {
-protected:
-  static Opcode getBinOpOpcode(llvm::Instruction::BinaryOps BinOp) {
-    switch (BinOp) {
-    case llvm::Instruction::Add:
-      return Opcode::Add;
-    case llvm::Instruction::FAdd:
-      return Opcode::FAdd;
-    case llvm::Instruction::Sub:
-      return Opcode::Sub;
-    case llvm::Instruction::FSub:
-      return Opcode::FSub;
-    case llvm::Instruction::Mul:
-      return Opcode::Mul;
-    case llvm::Instruction::FMul:
-      return Opcode::FMul;
-    case llvm::Instruction::UDiv:
-      return Opcode::UDiv;
-    case llvm::Instruction::SDiv:
-      return Opcode::SDiv;
-    case llvm::Instruction::FDiv:
-      return Opcode::FDiv;
-    case llvm::Instruction::URem:
-      return Opcode::URem;
-    case llvm::Instruction::SRem:
-      return Opcode::SRem;
-    case llvm::Instruction::FRem:
-      return Opcode::FRem;
-    case llvm::Instruction::Shl:
-      return Opcode::Shl;
-    case llvm::Instruction::LShr:
-      return Opcode::LShr;
-    case llvm::Instruction::AShr:
-      return Opcode::AShr;
-    case llvm::Instruction::And:
-      return Opcode::And;
-    case llvm::Instruction::Or:
-      return Opcode::Or;
-    case llvm::Instruction::Xor:
-      return Opcode::Xor;
-    case llvm::Instruction::BinaryOpsEnd:
-      llvm_unreachable("Bad BinOp!");
-    }
-    llvm_unreachable("Unhandled BinOp!");
-  }
-  BinaryOperator(llvm::BinaryOperator *BinOp, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::BinaryOperator,
-                                  getBinOpOpcode(BinOp->getOpcode()), BinOp,
-                                  Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static Value *create(Instruction::Opcode Op, Value *LHS, Value *RHS,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-
-  LLVM_ABI static Value *createWithCopiedFlags(Instruction::Opcode Op,
-                                               Value *LHS, Value *RHS,
-                                               Value *CopyFrom,
-                                               InsertPosition Pos, Context &Ctx,
-                                               const Twine &Name = "");
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::BinaryOperator;
-  }
-  void swapOperands() { swapOperandsInternal(0, 1); }
-};
-
-/// An or instruction, which can be marked as "disjoint", indicating that the
-/// inputs don't have a 1 in the same bit position. Meaning this instruction
-/// can also be treated as an add.
-class PossiblyDisjointInst : public BinaryOperator {
-public:
-  LLVM_ABI void setIsDisjoint(bool B);
-  bool isDisjoint() const {
-    return cast<llvm::PossiblyDisjointInst>(Val)->isDisjoint();
-  }
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    return isa<Instruction>(From) &&
-           cast<Instruction>(From)->getOpcode() == Opcode::Or;
-  }
-};
-
-class AtomicRMWInst : public SingleLLVMInstructionImpl<llvm::AtomicRMWInst> {
-  AtomicRMWInst(llvm::AtomicRMWInst *Atomic, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::AtomicRMW,
-                                  Instruction::Opcode::AtomicRMW, Atomic, Ctx) {
-  }
-  friend class Context; // For constructor.
-
-public:
-  using BinOp = llvm::AtomicRMWInst::BinOp;
-  BinOp getOperation() const {
-    return cast<llvm::AtomicRMWInst>(Val)->getOperation();
-  }
-  static StringRef getOperationName(BinOp Op) {
-    return llvm::AtomicRMWInst::getOperationName(Op);
-  }
-  static bool isFPOperation(BinOp Op) {
-    return llvm::AtomicRMWInst::isFPOperation(Op);
-  }
-  void setOperation(BinOp Op) {
-    cast<llvm::AtomicRMWInst>(Val)->setOperation(Op);
-  }
-  Align getAlign() const { return cast<llvm::AtomicRMWInst>(Val)->getAlign(); }
-  LLVM_ABI void setAlignment(Align Align);
-  bool isVolatile() const {
-    return cast<llvm::AtomicRMWInst>(Val)->isVolatile();
-  }
-  LLVM_ABI void setVolatile(bool V);
-  AtomicOrdering getOrdering() const {
-    return cast<llvm::AtomicRMWInst>(Val)->getOrdering();
-  }
-  LLVM_ABI void setOrdering(AtomicOrdering Ordering);
-  SyncScope::ID getSyncScopeID() const {
-    return cast<llvm::AtomicRMWInst>(Val)->getSyncScopeID();
-  }
-  LLVM_ABI void setSyncScopeID(SyncScope::ID SSID);
-  LLVM_ABI Value *getPointerOperand();
-  const Value *getPointerOperand() const {
-    return const_cast<AtomicRMWInst *>(this)->getPointerOperand();
-  }
-  LLVM_ABI Value *getValOperand();
-  const Value *getValOperand() const {
-    return const_cast<AtomicRMWInst *>(this)->getValOperand();
-  }
-  unsigned getPointerAddressSpace() const {
-    return cast<llvm::AtomicRMWInst>(Val)->getPointerAddressSpace();
-  }
-  bool isFloatingPointOperation() const {
-    return cast<llvm::AtomicRMWInst>(Val)->isFloatingPointOperation();
-  }
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::AtomicRMW;
-  }
-
-  LLVM_ABI static AtomicRMWInst *
-  create(BinOp Op, Value *Ptr, Value *Val, MaybeAlign Align,
-         AtomicOrdering Ordering, InsertPosition Pos, Context &Ctx,
-         SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
-};
-
-class AtomicCmpXchgInst
-    : public SingleLLVMInstructionImpl<llvm::AtomicCmpXchgInst> {
-  AtomicCmpXchgInst(llvm::AtomicCmpXchgInst *Atomic, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::AtomicCmpXchg,
-                                  Instruction::Opcode::AtomicCmpXchg, Atomic,
-                                  Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  /// Return the alignment of the memory that is being allocated by the
-  /// instruction.
-  Align getAlign() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->getAlign();
-  }
-
-  LLVM_ABI void setAlignment(Align Align);
-  /// Return true if this is a cmpxchg from a volatile memory
-  /// location.
-  bool isVolatile() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->isVolatile();
-  }
-  /// Specify whether this is a volatile cmpxchg.
-  LLVM_ABI void setVolatile(bool V);
-  /// Return true if this cmpxchg may spuriously fail.
-  bool isWeak() const { return cast<llvm::AtomicCmpXchgInst>(Val)->isWeak(); }
-  LLVM_ABI void setWeak(bool IsWeak);
-  static bool isValidSuccessOrdering(AtomicOrdering Ordering) {
-    return llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering);
-  }
-  static bool isValidFailureOrdering(AtomicOrdering Ordering) {
-    return llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering);
-  }
-  AtomicOrdering getSuccessOrdering() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->getSuccessOrdering();
-  }
-  LLVM_ABI void setSuccessOrdering(AtomicOrdering Ordering);
-
-  AtomicOrdering getFailureOrdering() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->getFailureOrdering();
-  }
-  LLVM_ABI void setFailureOrdering(AtomicOrdering Ordering);
-  AtomicOrdering getMergedOrdering() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->getMergedOrdering();
-  }
-  SyncScope::ID getSyncScopeID() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->getSyncScopeID();
-  }
-  LLVM_ABI void setSyncScopeID(SyncScope::ID SSID);
-  LLVM_ABI Value *getPointerOperand();
-  const Value *getPointerOperand() const {
-    return const_cast<AtomicCmpXchgInst *>(this)->getPointerOperand();
-  }
-
-  LLVM_ABI Value *getCompareOperand();
-  const Value *getCompareOperand() const {
-    return const_cast<AtomicCmpXchgInst *>(this)->getCompareOperand();
-  }
-
-  LLVM_ABI Value *getNewValOperand();
-  const Value *getNewValOperand() const {
-    return const_cast<AtomicCmpXchgInst *>(this)->getNewValOperand();
-  }
-
-  /// Returns the address space of the pointer operand.
-  unsigned getPointerAddressSpace() const {
-    return cast<llvm::AtomicCmpXchgInst>(Val)->getPointerAddressSpace();
-  }
-
-  LLVM_ABI static AtomicCmpXchgInst *
-  create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
-         AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
-         InsertPosition Pos, Context &Ctx,
-         SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::AtomicCmpXchg;
-  }
-};
-
-class AllocaInst final : public UnaryInstruction {
-  AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
-      : UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
-                         Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  LLVM_ABI static AllocaInst *create(Type *Ty, unsigned AddrSpace,
-                                     InsertPosition Pos, Context &Ctx,
-                                     Value *ArraySize = nullptr,
-                                     const Twine &Name = "");
-
-  /// Return true if there is an allocation size parameter to the allocation
-  /// instruction that is not 1.
-  bool isArrayAllocation() const {
-    return cast<llvm::AllocaInst>(Val)->isArrayAllocation();
-  }
-  /// Get the number of elements allocated. For a simple allocation of a single
-  /// element, this will return a constant 1 value.
-  LLVM_ABI Value *getArraySize();
-  const Value *getArraySize() const {
-    return const_cast<AllocaInst *>(this)->getArraySize();
-  }
-  /// Overload to return most specific pointer type.
-  LLVM_ABI PointerType *getType() const;
-  /// Return the address space for the allocation.
-  unsigned getAddressSpace() const {
-    return cast<llvm::AllocaInst>(Val)->getAddressSpace();
-  }
-  /// Get allocation size in bytes. Returns std::nullopt if size can't be
-  /// determined, e.g. in case of a VLA.
-  std::optional<TypeSize> getAllocationSize(const DataLayout &DL) const {
-    return cast<llvm::AllocaInst>(Val)->getAllocationSize(DL);
-  }
-  /// Get allocation size in bits. Returns std::nullopt if size can't be
-  /// determined, e.g. in case of a VLA.
-  std::optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const {
-    return cast<llvm::AllocaInst>(Val)->getAllocationSizeInBits(DL);
-  }
-  /// Return the type that is being allocated by the instruction.
-  LLVM_ABI Type *getAllocatedType() const;
-  /// for use only in special circumstances that need to generically
-  /// transform a whole instruction (eg: IR linking and vectorization).
-  LLVM_ABI void setAllocatedType(Type *Ty);
-  /// Return the alignment of the memory that is being allocated by the
-  /// instruction.
-  Align getAlign() const { return cast<llvm::AllocaInst>(Val)->getAlign(); }
-  LLVM_ABI void setAlignment(Align Align);
-  /// Return true if this alloca is in the entry block of the function and is a
-  /// constant size. If so, the code generator will fold it into the
-  /// prolog/epilog code, so it is basically free.
-  bool isStaticAlloca() const {
-    return cast<llvm::AllocaInst>(Val)->isStaticAlloca();
-  }
-  /// Return true if this alloca is used as an inalloca argument to a call. Such
-  /// allocas are never considered static even if they are in the entry block.
-  bool isUsedWithInAlloca() const {
-    return cast<llvm::AllocaInst>(Val)->isUsedWithInAlloca();
-  }
-  /// Specify whether this alloca is used to represent the arguments to a call.
-  LLVM_ABI void setUsedWithInAlloca(bool V);
-
-  static bool classof(const Value *From) {
-    if (auto *I = dyn_cast<Instruction>(From))
-      return I->getSubclassID() == Instruction::ClassID::Alloca;
-    return false;
-  }
-};
-
-class CastInst : public UnaryInstruction {
-  static Opcode getCastOpcode(llvm::Instruction::CastOps CastOp) {
-    switch (CastOp) {
-    case llvm::Instruction::ZExt:
-      return Opcode::ZExt;
-    case llvm::Instruction::SExt:
-      return Opcode::SExt;
-    case llvm::Instruction::FPToUI:
-      return Opcode::FPToUI;
-    case llvm::Instruction::FPToSI:
-      return Opcode::FPToSI;
-    case llvm::Instruction::FPExt:
-      return Opcode::FPExt;
-    case llvm::Instruction::PtrToAddr:
-      return Opcode::PtrToAddr;
-    case llvm::Instruction::PtrToInt:
-      return Opcode::PtrToInt;
-    case llvm::Instruction::IntToPtr:
-      return Opcode::IntToPtr;
-    case llvm::Instruction::SIToFP:
-      return Opcode::SIToFP;
-    case llvm::Instruction::UIToFP:
-      return Opcode::UIToFP;
-    case llvm::Instruction::Trunc:
-      return Opcode::Trunc;
-    case llvm::Instruction::FPTrunc:
-      return Opcode::FPTrunc;
-    case llvm::Instruction::BitCast:
-      return Opcode::BitCast;
-    case llvm::Instruction::AddrSpaceCast:
-      return Opcode::AddrSpaceCast;
-    case llvm::Instruction::CastOpsEnd:
-      llvm_unreachable("Bad CastOp!");
-    }
-    llvm_unreachable("Unhandled CastOp!");
-  }
-  /// Use Context::createCastInst(). Don't call the
-  /// constructor directly.
-  CastInst(llvm::CastInst *CI, Context &Ctx)
-      : UnaryInstruction(ClassID::Cast, getCastOpcode(CI->getOpcode()), CI,
-                         Ctx) {}
-  friend Context; // for SBCastInstruction()
-
-public:
-  LLVM_ABI static Value *create(Type *DestTy, Opcode Op, Value *Operand,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const Value *From);
-  LLVM_ABI Type *getSrcTy() const;
-  LLVM_ABI Type *getDestTy() const;
-};
-
-/// Instruction that can have a nneg flag (zext/uitofp).
-class PossiblyNonNegInst : public CastInst {
-public:
-  bool hasNonNeg() const {
-    return cast<llvm::PossiblyNonNegInst>(Val)->hasNonNeg();
-  }
-  LLVM_ABI void setNonNeg(bool B);
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From) {
-    if (auto *I = dyn_cast<Instruction>(From)) {
-      switch (I->getOpcode()) {
-      case Opcode::ZExt:
-      case Opcode::UIToFP:
-        return true;
-      default:
-        return false;
-      }
-    }
-    return false;
-  }
-};
-
-// Helper class to simplify stamping out CastInst subclasses.
-template <Instruction::Opcode Op> class CastInstImpl : public CastInst {
-public:
-  static Value *create(Value *Src, Type *DestTy, InsertPosition Pos,
-                       Context &Ctx, const Twine &Name = "") {
-    return CastInst::create(DestTy, Op, Src, Pos, Ctx, Name);
-  }
-
-  static bool classof(const Value *From) {
-    if (auto *I = dyn_cast<Instruction>(From))
-      return I->getOpcode() == Op;
-    return false;
-  }
-};
-
-class TruncInst final : public CastInstImpl<Instruction::Opcode::Trunc> {};
-class ZExtInst final : public CastInstImpl<Instruction::Opcode::ZExt> {};
-class SExtInst final : public CastInstImpl<Instruction::Opcode::SExt> {};
-class FPTruncInst final : public CastInstImpl<Instruction::Opcode::FPTrunc> {};
-class FPExtInst final : public CastInstImpl<Instruction::Opcode::FPExt> {};
-class UIToFPInst final : public CastInstImpl<Instruction::Opcode::UIToFP> {};
-class SIToFPInst final : public CastInstImpl<Instruction::Opcode::SIToFP> {};
-class FPToUIInst final : public CastInstImpl<Instruction::Opcode::FPToUI> {};
-class FPToSIInst final : public CastInstImpl<Instruction::Opcode::FPToSI> {};
-class IntToPtrInst final : public CastInstImpl<Instruction::Opcode::IntToPtr> {
-};
-class PtrToAddrInst final
-    : public CastInstImpl<Instruction::Opcode::PtrToAddr> {};
-class PtrToIntInst final : public CastInstImpl<Instruction::Opcode::PtrToInt> {
-};
-class BitCastInst final : public CastInstImpl<Instruction::Opcode::BitCast> {};
-class AddrSpaceCastInst final
-    : public CastInstImpl<Instruction::Opcode::AddrSpaceCast> {
-public:
-  /// \Returns the pointer operand.
-  Value *getPointerOperand() { return getOperand(0); }
-  /// \Returns the pointer operand.
-  const Value *getPointerOperand() const {
-    return const_cast<AddrSpaceCastInst *>(this)->getPointerOperand();
-  }
-  /// \Returns the operand index of the pointer operand.
-  static unsigned getPointerOperandIndex() { return 0u; }
-  /// \Returns the address space of the pointer operand.
-  unsigned getSrcAddressSpace() const {
-    return getPointerOperand()->getType()->getPointerAddressSpace();
-  }
-  /// \Returns the address space of the result.
-  unsigned getDestAddressSpace() const {
-    return getType()->getPointerAddressSpace();
-  }
-};
-
-class PHINode final : public SingleLLVMInstructionImpl<llvm::PHINode> {
-  /// Use Context::createPHINode(). Don't call the constructor directly.
-  PHINode(llvm::PHINode *PHI, Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::PHI, Opcode::PHI, PHI, Ctx) {}
-  friend Context; // for PHINode()
-  /// Helper for mapped_iterator.
-  struct LLVMBBToBB {
-    Context &Ctx;
-    LLVMBBToBB(Context &Ctx) : Ctx(Ctx) {}
-    LLVM_ABI BasicBlock *operator()(llvm::BasicBlock *LLVMBB) const;
-  };
-
-public:
-  LLVM_ABI static PHINode *create(Type *Ty, unsigned NumReservedValues,
-                                  InsertPosition Pos, Context &Ctx,
-                                  const Twine &Name = "");
-  /// For isa/dyn_cast.
-  LLVM_ABI static bool classof(const Value *From);
-
-  using const_block_iterator =
-      mapped_iterator<llvm::PHINode::const_block_iterator, LLVMBBToBB>;
-
-  const_block_iterator block_begin() const {
-    LLVMBBToBB BBGetter(Ctx);
-    return const_block_iterator(cast<llvm::PHINode>(Val)->block_begin(),
-                                BBGetter);
-  }
-  const_block_iterator block_end() const {
-    LLVMBBToBB BBGetter(Ctx);
-    return const_block_iterator(cast<llvm::PHINode>(Val)->block_end(),
-                                BBGetter);
-  }
-  iterator_range<const_block_iterator> blocks() const {
-    return make_range(block_begin(), block_end());
-  }
-
-  op_range incoming_values() { return operands(); }
-
-  const_op_range incoming_values() const { return operands(); }
-
-  unsigned getNumIncomingValues() const {
-    return cast<llvm::PHINode>(Val)->getNumIncomingValues();
-  }
-  LLVM_ABI Value *getIncomingValue(unsigned Idx) const;
-  LLVM_ABI void setIncomingValue(unsigned Idx, Value *V);
-  static unsigned getOperandNumForIncomingValue(unsigned Idx) {
-    return llvm::PHINode::getOperandNumForIncomingValue(Idx);
-  }
-  static unsigned getIncomingValueNumForOperand(unsigned Idx) {
-    return llvm::PHINode::getIncomingValueNumForOperand(Idx);
-  }
-  LLVM_ABI BasicBlock *getIncomingBlock(unsigned Idx) const;
-  LLVM_ABI BasicBlock *getIncomingBlock(const Use &U) const;
-
-  LLVM_ABI void setIncomingBlock(unsigned Idx, BasicBlock *BB);
-
-  LLVM_ABI void addIncoming(Value *V, BasicBlock *BB);
-
-  LLVM_ABI Value *removeIncomingValue(unsigned Idx);
-  LLVM_ABI Value *removeIncomingValue(BasicBlock *BB);
-
-  LLVM_ABI int getBasicBlockIndex(const BasicBlock *BB) const;
-  LLVM_ABI Value *getIncomingValueForBlock(const BasicBlock *BB) const;
-
-  LLVM_ABI Value *hasConstantValue() const;
-
-  bool hasConstantOrUndefValue() const {
-    return cast<llvm::PHINode>(Val)->hasConstantOrUndefValue();
-  }
-  bool isComplete() const { return cast<llvm::PHINode>(Val)->isComplete(); }
-  LLVM_ABI void replaceIncomingBlockWith(const BasicBlock *Old,
-                                         BasicBlock *New);
-  LLVM_ABI void removeIncomingValueIf(function_ref<bool(unsigned)> Predicate);
-  // TODO: Implement
-  // void copyIncomingBlocks(iterator_range<const_block_iterator> BBRange,
-  //                         uint32_t ToIdx = 0)
-};
-
-// Wraps a static function that takes a single Predicate parameter
-// LLVMValType should be the type of the wrapped class
-#define WRAP_STATIC_PREDICATE(FunctionName)                                    \
-  static auto FunctionName(Predicate P) { return LLVMValType::FunctionName(P); }
-// Wraps a member function that takes no parameters
-// LLVMValType should be the type of the wrapped class
-#define WRAP_MEMBER(FunctionName)                                              \
-  auto FunctionName() const { return cast<LLVMValType>(Val)->FunctionName(); }
-// Wraps both--a common idiom in the CmpInst classes
-#define WRAP_BOTH(FunctionName)                                                \
-  WRAP_STATIC_PREDICATE(FunctionName)                                          \
-  WRAP_MEMBER(FunctionName)
-
-class CmpInst : public SingleLLVMInstructionImpl<llvm::CmpInst> {
-protected:
-  using LLVMValType = llvm::CmpInst;
-  /// Use Context::createCmpInst(). Don't call the constructor directly.
-  CmpInst(llvm::CmpInst *CI, Context &Ctx, ClassID Id, Opcode Opc)
-      : SingleLLVMInstructionImpl(Id, Opc, CI, Ctx) {}
-  friend Context; // for CmpInst()
-  LLVM_ABI static Value *createCommon(Value *Cond, Value *True, Value *False,
-                                      const Twine &Name, IRBuilder<> &Builder,
-                                      Context &Ctx);
-
-public:
-  using Predicate = llvm::CmpInst::Predicate;
-
-  LLVM_ABI static Value *create(Predicate Pred, Value *S1, Value *S2,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name = "");
-  LLVM_ABI static Value *createWithCopiedFlags(Predicate Pred, Value *S1,
-                                               Value *S2,
-                                               const Instruction *FlagsSource,
-                                               InsertPosition Pos, Context &Ctx,
-                                               const Twine &Name = "");
-  LLVM_ABI void setPredicate(Predicate P);
-  LLVM_ABI void swapOperands();
-
-  WRAP_MEMBER(getPredicate);
-  WRAP_BOTH(isFPPredicate);
-  WRAP_BOTH(isIntPredicate);
-  WRAP_STATIC_PREDICATE(getPredicateName);
-  WRAP_BOTH(getInversePredicate);
-  WRAP_BOTH(getOrderedPredicate);
-  WRAP_BOTH(getUnorderedPredicate);
-  WRAP_BOTH(getSwappedPredicate);
-  WRAP_BOTH(isStrictPredicate);
-  WRAP_BOTH(isNonStrictPredicate);
-  WRAP_BOTH(getStrictPredicate);
-  WRAP_BOTH(getNonStrictPredicate);
-  WRAP_BOTH(getFlippedStrictnessPredicate);
-  WRAP_MEMBER(isCommutative);
-  WRAP_BOTH(isEquality);
-  WRAP_BOTH(isRelational);
-  WRAP_BOTH(isSigned);
-  WRAP_BOTH(isTrueWhenEqual);
-  WRAP_BOTH(isFalseWhenEqual);
-  WRAP_BOTH(isUnsigned);
-  WRAP_STATIC_PREDICATE(isOrdered);
-  WRAP_STATIC_PREDICATE(isUnordered);
-
-  /// Method for support type inquiry through isa, cast, and dyn_cast:
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ICmp ||
-           From->getSubclassID() == ClassID::FCmp;
-  }
-
-  /// Create a result type for fcmp/icmp
-  LLVM_ABI static Type *makeCmpResultType(Type *OpndType);
-
-#ifndef NDEBUG
-  void dumpOS(raw_ostream &OS) const override;
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-class ICmpInst : public CmpInst {
-  /// Use Context::createICmpInst(). Don't call the constructor directly.
-  ICmpInst(llvm::ICmpInst *CI, Context &Ctx)
-      : CmpInst(CI, Ctx, ClassID::ICmp, Opcode::ICmp) {}
-  friend class Context; // For constructor.
-  using LLVMValType = llvm::ICmpInst;
-
-public:
-  LLVM_ABI void swapOperands();
-
-  WRAP_BOTH(getSignedPredicate);
-  WRAP_BOTH(getUnsignedPredicate);
-  WRAP_BOTH(getFlippedSignednessPredicate);
-  WRAP_BOTH(isEquality);
-  WRAP_MEMBER(isCommutative);
-  WRAP_MEMBER(isRelational);
-  WRAP_STATIC_PREDICATE(isGT);
-  WRAP_STATIC_PREDICATE(isLT);
-  WRAP_STATIC_PREDICATE(isGE);
-  WRAP_STATIC_PREDICATE(isLE);
-
-  static std::optional<bool> isImpliedByMatchingCmp(CmpPredicate Pred1,
-                                                    CmpPredicate Pred2) {
-    return llvm::ICmpInst::isImpliedByMatchingCmp(Pred1, Pred2);
-  }
-
-  static auto predicates() { return llvm::ICmpInst::predicates(); }
-  static bool compare(const APInt &LHS, const APInt &RHS,
-                      ICmpInst::Predicate Pred) {
-    return llvm::ICmpInst::compare(LHS, RHS, Pred);
-  }
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::ICmp;
-  }
-};
-
-class FCmpInst : public CmpInst {
-  /// Use Context::createFCmpInst(). Don't call the constructor directly.
-  FCmpInst(llvm::FCmpInst *CI, Context &Ctx)
-      : CmpInst(CI, Ctx, ClassID::FCmp, Opcode::FCmp) {}
-  friend class Context; // For constructor.
-  using LLVMValType = llvm::FCmpInst;
-
-public:
-  LLVM_ABI void swapOperands();
-
-  WRAP_BOTH(isEquality);
-  WRAP_MEMBER(isCommutative);
-  WRAP_MEMBER(isRelational);
-
-  static auto predicates() { return llvm::FCmpInst::predicates(); }
-  static bool compare(const APFloat &LHS, const APFloat &RHS,
-                      FCmpInst::Predicate Pred) {
-    return llvm::FCmpInst::compare(LHS, RHS, Pred);
-  }
-
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::FCmp;
-  }
-};
-
-#undef WRAP_STATIC_PREDICATE
-#undef WRAP_MEMBER
-#undef WRAP_BOTH
-
-/// An LLLVM Instruction that has no SandboxIR equivalent class gets mapped to
-/// an OpaqueInstr.
-class OpaqueInst : public SingleLLVMInstructionImpl<llvm::Instruction> {
-  OpaqueInst(llvm::Instruction *I, sandboxir::Context &Ctx)
-      : SingleLLVMInstructionImpl(ClassID::Opaque, Opcode::Opaque, I, Ctx) {}
-  OpaqueInst(ClassID SubclassID, llvm::Instruction *I, sandboxir::Context &Ctx)
-      : SingleLLVMInstructionImpl(SubclassID, Opcode::Opaque, I, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  static bool classof(const sandboxir::Value *From) {
-    return From->getSubclassID() == ClassID::Opaque;
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_INSTRUCTION_H
diff --git a/llvm/include/llvm/SandboxIR/IntrinsicInst.h b/llvm/include/llvm/SandboxIR/IntrinsicInst.h
deleted file mode 100644
index 33d3746f15119..0000000000000
--- a/llvm/include/llvm/SandboxIR/IntrinsicInst.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===- IntrinsicInst.h ------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_INTRINSICINST_H
-#define LLVM_SANDBOXIR_INTRINSICINST_H
-
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/SandboxIR/Instruction.h"
-
-namespace llvm::sandboxir {
-
-class IntrinsicInst : public CallInst {
-  IntrinsicInst(llvm::IntrinsicInst *I, Context &Ctx) : CallInst(I, Ctx) {}
-
-public:
-  Intrinsic::ID getIntrinsicID() const {
-    return cast<llvm::IntrinsicInst>(Val)->getIntrinsicID();
-  }
-  bool isAssociative() const {
-    return cast<llvm::IntrinsicInst>(Val)->isAssociative();
-  }
-  bool isCommutative() const {
-    return cast<llvm::IntrinsicInst>(Val)->isCommutative();
-  }
-  bool isAssumeLikeIntrinsic() const {
-    return cast<llvm::IntrinsicInst>(Val)->isAssumeLikeIntrinsic();
-  }
-  static bool mayLowerToFunctionCall(Intrinsic::ID IID) {
-    return llvm::IntrinsicInst::mayLowerToFunctionCall(IID);
-  }
-  static bool classof(const Value *V) {
-    auto *LLVMV = V->Val;
-    return isa<llvm::IntrinsicInst>(LLVMV);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_INTRINSICINST_H
diff --git a/llvm/include/llvm/SandboxIR/Module.h b/llvm/include/llvm/SandboxIR/Module.h
deleted file mode 100644
index 275960392211d..0000000000000
--- a/llvm/include/llvm/SandboxIR/Module.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//===- Module.h -------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_MODULE_H
-#define LLVM_SANDBOXIR_MODULE_H
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/Module.h"
-#include "llvm/Support/Compiler.h"
-#include <string>
-
-namespace llvm {
-
-class DataLayout;
-
-namespace sandboxir {
-
-class Context;
-class Function;
-class GlobalVariable;
-class Type;
-class Constant;
-class GlobalAlias;
-class GlobalIFunc;
-
-/// In SandboxIR the Module is mainly used to access the list of global objects.
-class Module {
-  llvm::Module &LLVMM;
-  Context &Ctx;
-
-  Module(llvm::Module &LLVMM, Context &Ctx) : LLVMM(LLVMM), Ctx(Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  Context &getContext() const { return Ctx; }
-
-  LLVM_ABI Function *getFunction(StringRef Name) const;
-
-  const DataLayout &getDataLayout() const { return LLVMM.getDataLayout(); }
-
-  const std::string &getSourceFileName() const {
-    return LLVMM.getSourceFileName();
-  }
-
-  /// Look up the specified global variable in the module symbol table. If it
-  /// does not exist, return null. If AllowInternal is set to true, this
-  /// function will return types that have InternalLinkage. By default, these
-  /// types are not returned.
-  LLVM_ABI GlobalVariable *getGlobalVariable(StringRef Name,
-                                             bool AllowInternal) const;
-  GlobalVariable *getGlobalVariable(StringRef Name) const {
-    return getGlobalVariable(Name, /*AllowInternal=*/false);
-  }
-  /// Return the global variable in the module with the specified name, of
-  /// arbitrary type. This method returns null if a global with the specified
-  /// name is not found.
-  GlobalVariable *getNamedGlobal(StringRef Name) const {
-    return getGlobalVariable(Name, true);
-  }
-
-  // TODO: missing getOrInsertGlobal().
-
-  /// Return the global alias in the module with the specified name, of
-  /// arbitrary type. This method returns null if a global with the specified
-  /// name is not found.
-  LLVM_ABI GlobalAlias *getNamedAlias(StringRef Name) const;
-
-  /// Return the global ifunc in the module with the specified name, of
-  /// arbitrary type. This method returns null if a global with the specified
-  /// name is not found.
-  LLVM_ABI GlobalIFunc *getNamedIFunc(StringRef Name) const;
-
-  // TODO: Missing removeGlobalVariable() eraseGlobalVariable(),
-  // insertGlobalVariable()
-
-  // TODO: Missing global_begin(), global_end(), globals().
-
-  // TODO: Missing many other functions.
-
-#ifndef NDEBUG
-  void dumpOS(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif // NDEBUG
-};
-
-} // namespace sandboxir
-} // namespace llvm
-
-#endif // LLVM_SANDBOXIR_MODULE_H
diff --git a/llvm/include/llvm/SandboxIR/Operator.h b/llvm/include/llvm/SandboxIR/Operator.h
deleted file mode 100644
index f19c54c75e424..0000000000000
--- a/llvm/include/llvm/SandboxIR/Operator.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===- Operator.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_OPERATOR_H
-#define LLVM_SANDBOXIR_OPERATOR_H
-
-#include "llvm/IR/Operator.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/User.h"
-
-namespace llvm::sandboxir {
-
-class Operator : public User {
-public:
-  // The Operator class is intended to be used as a utility, and is never itself
-  // instantiated.
-  Operator() = delete;
-  void *operator new(size_t s) = delete;
-
-  static bool classof(const Instruction *) { return true; }
-  static bool classof(const ConstantExpr *) { return true; }
-  static bool classof(const Value *From) {
-    return llvm::Operator::classof(From->Val);
-  }
-  bool hasPoisonGeneratingFlags() const {
-    return cast<llvm::Operator>(Val)->hasPoisonGeneratingFlags();
-  }
-};
-
-class OverflowingBinaryOperator : public Operator {
-public:
-  bool hasNoUnsignedWrap() const {
-    return cast<llvm::OverflowingBinaryOperator>(Val)->hasNoUnsignedWrap();
-  }
-  bool hasNoSignedWrap() const {
-    return cast<llvm::OverflowingBinaryOperator>(Val)->hasNoSignedWrap();
-  }
-  unsigned getNoWrapKind() const {
-    return cast<llvm::OverflowingBinaryOperator>(Val)->getNoWrapKind();
-  }
-  static bool classof(const Instruction *From) {
-    return llvm::OverflowingBinaryOperator::classof(
-        cast<llvm::Instruction>(From->Val));
-  }
-  static bool classof(const ConstantExpr *From) {
-    return llvm::OverflowingBinaryOperator::classof(
-        cast<llvm::ConstantExpr>(From->Val));
-  }
-  static bool classof(const Value *From) {
-    return llvm::OverflowingBinaryOperator::classof(From->Val);
-  }
-};
-
-class FPMathOperator : public Operator {
-public:
-  bool isFast() const { return cast<llvm::FPMathOperator>(Val)->isFast(); }
-  bool hasAllowReassoc() const {
-    return cast<llvm::FPMathOperator>(Val)->hasAllowReassoc();
-  }
-  bool hasNoNaNs() const {
-    return cast<llvm::FPMathOperator>(Val)->hasNoNaNs();
-  }
-  bool hasNoInfs() const {
-    return cast<llvm::FPMathOperator>(Val)->hasNoInfs();
-  }
-  bool hasNoSignedZeros() const {
-    return cast<llvm::FPMathOperator>(Val)->hasNoSignedZeros();
-  }
-  bool hasAllowReciprocal() const {
-    return cast<llvm::FPMathOperator>(Val)->hasAllowReciprocal();
-  }
-  bool hasAllowContract() const {
-    return cast<llvm::FPMathOperator>(Val)->hasAllowContract();
-  }
-  bool hasApproxFunc() const {
-    return cast<llvm::FPMathOperator>(Val)->hasApproxFunc();
-  }
-  FastMathFlags getFastMathFlags() const {
-    return cast<llvm::FPMathOperator>(Val)->getFastMathFlags();
-  }
-  float getFPAccuracy() const {
-    return cast<llvm::FPMathOperator>(Val)->getFPAccuracy();
-  }
-  static bool isSupportedFloatingPointType(Type *Ty) {
-    return llvm::FPMathOperator::isSupportedFloatingPointType(Ty->LLVMTy);
-  }
-  static bool classof(const Value *V) {
-    return llvm::FPMathOperator::classof(V->Val);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_OPERATOR_H
diff --git a/llvm/include/llvm/SandboxIR/Pass.h b/llvm/include/llvm/SandboxIR/Pass.h
deleted file mode 100644
index eb84f21483f8e..0000000000000
--- a/llvm/include/llvm/SandboxIR/Pass.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//===- Pass.h ---------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_PASS_H
-#define LLVM_SANDBOXIR_PASS_H
-
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm {
-
-class AAResults;
-class ScalarEvolution;
-class TargetTransformInfo;
-
-namespace sandboxir {
-
-class Function;
-class Region;
-
-class Analyses {
-  AAResults *AA = nullptr;
-  ScalarEvolution *SE = nullptr;
-  TargetTransformInfo *TTI = nullptr;
-
-  Analyses() = default;
-
-public:
-  Analyses(AAResults &AA, ScalarEvolution &SE, TargetTransformInfo &TTI)
-      : AA(&AA), SE(&SE), TTI(&TTI) {}
-
-public:
-  AAResults &getAA() const { return *AA; }
-  ScalarEvolution &getScalarEvolution() const { return *SE; }
-  TargetTransformInfo &getTTI() const { return *TTI; }
-  /// For use by unit tests.
-  static Analyses emptyForTesting() { return Analyses(); }
-};
-
-/// The base class of a Sandbox IR Pass.
-class Pass {
-protected:
-  /// The pass name. This is also used as a command-line flag and should not
-  /// contain whitespaces.
-  const std::string Name;
-
-public:
-  /// \p Name can't contain any spaces or start with '-'.
-  Pass(StringRef Name) : Name(Name) {
-    assert(!Name.contains(' ') &&
-           "A pass name should not contain whitespaces!");
-    assert(!Name.starts_with('-') && "A pass name should not start with '-'!");
-  }
-  virtual ~Pass() = default;
-  /// \Returns the name of the pass.
-  StringRef getName() const { return Name; }
-#ifndef NDEBUG
-  friend raw_ostream &operator<<(raw_ostream &OS, const Pass &Pass) {
-    Pass.print(OS);
-    return OS;
-  }
-  virtual void print(raw_ostream &OS) const { OS << Name; }
-  LLVM_DUMP_METHOD virtual void dump() const;
-#endif
-  /// Similar to print() but adds a newline. Used for testing.
-  virtual void printPipeline(raw_ostream &OS) const { OS << Name << "\n"; }
-};
-
-/// A pass that runs on a sandbox::Function.
-class FunctionPass : public Pass {
-public:
-  /// \p Name can't contain any spaces or start with '-'.
-  FunctionPass(StringRef Name) : Pass(Name) {}
-  /// \Returns true if it modifies \p F.
-  virtual bool runOnFunction(Function &F, const Analyses &A) = 0;
-};
-
-/// A pass that runs on a sandbox::Region.
-class RegionPass : public Pass {
-public:
-  /// \p Name can't contain any spaces or start with '-'.
-  RegionPass(StringRef Name) : Pass(Name) {}
-  /// \Returns true if it modifies \p R.
-  virtual bool runOnRegion(Region &R, const Analyses &A) = 0;
-};
-
-} // namespace sandboxir
-} // namespace llvm
-
-#endif // LLVM_SANDBOXIR_PASS_H
diff --git a/llvm/include/llvm/SandboxIR/PassManager.h b/llvm/include/llvm/SandboxIR/PassManager.h
deleted file mode 100644
index a8117aa3b9fa8..0000000000000
--- a/llvm/include/llvm/SandboxIR/PassManager.h
+++ /dev/null
@@ -1,227 +0,0 @@
-//===- PassManager.h --------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Registers and executes the Sandbox IR passes.
-//
-// The pass manager contains an ordered sequence of passes that it runs in
-// order. The passes are owned by the PassRegistry, not by the PassManager.
-//
-// Note that in this design a pass manager is also a pass. So a pass manager
-// runs when it is it's turn to run in its parent pass-manager pass pipeline.
-//
-
-#ifndef LLVM_SANDBOXIR_PASSMANAGER_H
-#define LLVM_SANDBOXIR_PASSMANAGER_H
-
-#include "llvm/Support/Compiler.h"
-#include <memory>
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/Support/Debug.h"
-
-namespace llvm::sandboxir {
-
-class Value;
-
-/// Base class.
-template <typename ParentPass, typename ContainedPass>
-class PassManager : public ParentPass {
-public:
-  // CreatePassFunc(StringRef PassName, StringRef PassArgs).
-  using CreatePassFunc =
-      std::function<std::unique_ptr<ContainedPass>(StringRef, StringRef)>;
-
-protected:
-  /// The list of passes that this pass manager will run.
-  SmallVector<std::unique_ptr<ContainedPass>> Passes;
-
-  PassManager(StringRef Name) : ParentPass(Name) {}
-  PassManager(StringRef Name, StringRef Pipeline, CreatePassFunc CreatePass)
-      : ParentPass(Name) {
-    setPassPipeline(Pipeline, CreatePass);
-  }
-  PassManager(const PassManager &) = delete;
-  PassManager(PassManager &&) = default;
-  ~PassManager() override = default;
-  PassManager &operator=(const PassManager &) = delete;
-
-public:
-  /// Adds \p Pass to the pass pipeline.
-  void addPass(std::unique_ptr<ContainedPass> Pass) {
-    // TODO: Check that Pass's class type works with this PassManager type.
-    Passes.push_back(std::move(Pass));
-  }
-
-  static constexpr char EndToken = '\0';
-  static constexpr char BeginArgsToken = '<';
-  static constexpr char EndArgsToken = '>';
-  static constexpr char PassDelimToken = ',';
-
-  /// Parses \p Pipeline as a comma-separated sequence of pass names and sets
-  /// the pass pipeline, using \p CreatePass to instantiate passes by name.
-  ///
-  /// Passes can have arguments, for example:
-  ///   "pass1<arg1,arg2>,pass2,pass3<arg3,arg4>"
-  ///
-  /// The arguments between angle brackets are treated as a mostly opaque string
-  /// and each pass is responsible for parsing its arguments. The exception to
-  /// this are nested angle brackets, which must match pair-wise to allow
-  /// arguments to contain nested pipelines, like:
-  ///
-  ///   "pass1<subpass1,subpass2<arg1,arg2>,subpass3>"
-  ///
-  /// An empty args string is treated the same as no args, so "pass" and
-  /// "pass<>" are equivalent.
-  void setPassPipeline(StringRef Pipeline, CreatePassFunc CreatePass) {
-    assert(Passes.empty() &&
-           "setPassPipeline called on a non-empty sandboxir::PassManager");
-
-    // Accept an empty pipeline as a special case. This can be useful, for
-    // example, to test conversion to SandboxIR without running any passes on
-    // it.
-    if (Pipeline.empty())
-      return;
-
-    // Add EndToken to the end to ease parsing.
-    std::string PipelineStr = std::string(Pipeline) + EndToken;
-    Pipeline = StringRef(PipelineStr);
-
-    auto AddPass = [this, CreatePass](StringRef PassName, StringRef PassArgs) {
-      if (PassName.empty()) {
-        errs() << "Found empty pass name.\n";
-        exit(1);
-      }
-      // Get the pass that corresponds to PassName and add it to the pass
-      // manager.
-      auto Pass = CreatePass(PassName, PassArgs);
-      if (Pass == nullptr) {
-        errs() << "Pass '" << PassName << "' not registered!\n";
-        exit(1);
-      }
-      addPass(std::move(Pass));
-    };
-
-    enum class State {
-      ScanName,  // reading a pass name
-      ScanArgs,  // reading a list of args
-      ArgsEnded, // read the last '>' in an args list, must read delimiter next
-    } CurrentState = State::ScanName;
-    int PassBeginIdx = 0;
-    int ArgsBeginIdx;
-    StringRef PassName;
-    int NestedArgs = 0;
-    for (auto [Idx, C] : enumerate(Pipeline)) {
-      switch (CurrentState) {
-      case State::ScanName:
-        if (C == BeginArgsToken) {
-          // Save pass name for later and begin scanning args.
-          PassName = Pipeline.slice(PassBeginIdx, Idx);
-          ArgsBeginIdx = Idx + 1;
-          ++NestedArgs;
-          CurrentState = State::ScanArgs;
-          break;
-        }
-        if (C == EndArgsToken) {
-          errs() << "Unexpected '>' in pass pipeline.\n";
-          exit(1);
-        }
-        if (C == EndToken || C == PassDelimToken) {
-          // Delimiter found, add the pass (with empty args), stay in the
-          // ScanName state.
-          AddPass(Pipeline.slice(PassBeginIdx, Idx), StringRef());
-          PassBeginIdx = Idx + 1;
-        }
-        break;
-      case State::ScanArgs:
-        // While scanning args, we only care about making sure nesting of angle
-        // brackets is correct.
-        if (C == BeginArgsToken) {
-          ++NestedArgs;
-          break;
-        }
-        if (C == EndArgsToken) {
-          --NestedArgs;
-          if (NestedArgs == 0) {
-            // Done scanning args.
-            AddPass(PassName, Pipeline.slice(ArgsBeginIdx, Idx));
-            CurrentState = State::ArgsEnded;
-          } else if (NestedArgs < 0) {
-            errs() << "Unexpected '>' in pass pipeline.\n";
-            exit(1);
-          }
-          break;
-        }
-        if (C == EndToken) {
-          errs() << "Missing '>' in pass pipeline. End-of-string reached while "
-                    "reading arguments for pass '"
-                 << PassName << "'.\n";
-          exit(1);
-        }
-        break;
-      case State::ArgsEnded:
-        // Once we're done scanning args, only a delimiter is valid. This avoids
-        // accepting strings like "foo<args><more-args>" or "foo<args>bar".
-        if (C == EndToken || C == PassDelimToken) {
-          PassBeginIdx = Idx + 1;
-          CurrentState = State::ScanName;
-        } else {
-          errs() << "Expected delimiter or end-of-string after pass "
-                    "arguments.\n";
-          exit(1);
-        }
-        break;
-      }
-    }
-  }
-
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const override {
-    OS << this->getName();
-    OS << BeginArgsToken;
-    std::string Delim(1, PassDelimToken);
-    interleave(Passes, OS, [&OS](auto &Pass) { Pass->print(OS); }, Delim);
-    OS << EndArgsToken;
-  }
-  LLVM_DUMP_METHOD void dump() const override {
-    print(dbgs());
-    dbgs() << "\n";
-  }
-#endif
-  /// Similar to print() but prints one pass per line. Used for testing.
-  void printPipeline(raw_ostream &OS) const override {
-    OS << this->getName() << "\n";
-    for (const auto &PassPtr : Passes)
-      PassPtr->printPipeline(OS);
-  }
-};
-
-class LLVM_ABI FunctionPassManager final
-    : public PassManager<FunctionPass, FunctionPass> {
-public:
-  FunctionPassManager(StringRef Name) : PassManager(Name) {}
-  FunctionPassManager(StringRef Name, StringRef Pipeline,
-                      CreatePassFunc CreatePass)
-      : PassManager(Name, Pipeline, CreatePass) {}
-  bool runOnFunction(Function &F, const Analyses &A) final;
-};
-
-class LLVM_ABI RegionPassManager final
-    : public PassManager<RegionPass, RegionPass> {
-public:
-  RegionPassManager(StringRef Name) : PassManager(Name) {}
-  RegionPassManager(StringRef Name, StringRef Pipeline,
-                    CreatePassFunc CreatePass)
-      : PassManager(Name, Pipeline, CreatePass) {}
-  bool runOnRegion(Region &R, const Analyses &A) final;
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_PASSMANAGER_H
diff --git a/llvm/include/llvm/SandboxIR/Region.h b/llvm/include/llvm/SandboxIR/Region.h
deleted file mode 100644
index d70f21277fb1b..0000000000000
--- a/llvm/include/llvm/SandboxIR/Region.h
+++ /dev/null
@@ -1,193 +0,0 @@
-//===- Region.h -------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_REGION_H
-#define LLVM_SANDBOXIR_REGION_H
-
-#include "llvm/Support/Compiler.h"
-#include <memory>
-
-#include "llvm/ADT/SetVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm::sandboxir {
-
-class Region;
-
-class ScoreBoard {
-  const Region &Rgn;
-  TargetTransformInfo &TTI;
-  constexpr static TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
-  /// The cost of all instructions added to the region.
-  InstructionCost AfterCost = 0;
-  /// The cost of all instructions that got removed and replaced by new ones.
-  InstructionCost BeforeCost = 0;
-  /// Helper for both add() and remove(). \Returns the TTI cost of \p I.
-  LLVM_ABI InstructionCost getCost(Instruction *I) const;
-  /// No need to allow copies.
-  ScoreBoard(const ScoreBoard &) = delete;
-  const ScoreBoard &operator=(const ScoreBoard &) = delete;
-
-public:
-  ScoreBoard(Region &Rgn, TargetTransformInfo &TTI) : Rgn(Rgn), TTI(TTI) {}
-  /// Mark \p I as a newly added instruction to the region.
-  void add(Instruction *I) { AfterCost += getCost(I); }
-  /// Mark \p I as a deleted instruction from the region.
-  LLVM_ABI void remove(Instruction *I);
-  /// \Returns the cost of the newly added instructions.
-  InstructionCost getAfterCost() const { return AfterCost; }
-  /// \Returns the cost of the Removed instructions.
-  InstructionCost getBeforeCost() const { return BeforeCost; }
-
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const {
-    OS << "BeforeCost: " << BeforeCost << "\n";
-    OS << "AfterCost:  " << AfterCost << "\n";
-  }
-  LLVM_DUMP_METHOD void dump() const;
-#endif // NDEBUG
-};
-
-/// The main job of the Region is to point to new instructions generated by
-/// vectorization passes. It is the unit that RegionPasses operate on with their
-/// runOnRegion() function.
-///
-/// The region allows us to stack transformations horizontally, meaning that
-/// each transformation operates on a single region and the resulting region is
-/// the input to the next transformation, as opposed to vertically, which is the
-/// common way of applying a transformation across the whole function. This
-/// enables us to check for profitability and decide whether we accept or
-/// rollback at a region granularity, which is much better than doing this at
-/// the function level.
-///
-//  Traditional approach: transformations applied vertically for the whole
-//  function
-//    F
-//  +----+
-//  |    |
-//  |    |
-//  |    | -> Transform1 ->  ... -> TransformN -> Check Cost
-//  |    |
-//  |    |
-//  +----+
-//
-//  Region-based approach: transformations applied horizontally, for each Region
-//    F
-//  +----+
-//  |Rgn1| -> Transform1 ->  ... -> TransformN -> Check Cost
-//  |    |
-//  |Rgn2| -> Transform1 ->  ... -> TransformN -> Check Cost
-//  |    |
-//  |Rgn3| -> Transform1 ->  ... -> TransformN -> Check Cost
-//  +----+
-//
-// The region can also hold an ordered sequence of "auxiliary" instructions.
-// This can be used to pass auxiliary information across region passes, like for
-// example the initial seed slice used by the bottom-up vectorizer.
-
-class Region {
-  /// All the instructions in the Region. Only new instructions generated during
-  /// vectorization are part of the Region.
-  SetVector<Instruction *> Insts;
-  /// An auxiliary sequence of Instruction-Index pairs.
-  SmallVector<Instruction *> Aux;
-
-  /// MDNode that we'll use to mark instructions as being part of the region.
-  MDNode *RegionMDN;
-  static constexpr const char *MDKind = "sandboxvec";
-  static constexpr const char *RegionStr = "sandboxregion";
-  static constexpr const char *AuxMDKind = "sandboxaux";
-
-  Context &Ctx;
-  /// Keeps track of cost of instructions added and removed.
-  ScoreBoard Scoreboard;
-
-  /// ID (for later deregistration) of the "create instruction" callback.
-  Context::CallbackID CreateInstCB;
-  /// ID (for later deregistration) of the "erase instruction" callback.
-  Context::CallbackID EraseInstCB;
-
-  /// Adds \p I to the set but also don't track the instruction's score if \p
-  /// IgnoreCost is true. Only to be used when adding an instruction to the
-  /// auxiliary vector.
-  /// NOTE: When an instruction is added to the region we track it cost in the
-  /// scoreboard, which currently resides in the region class. However, when we
-  /// add an instruction to the auxiliary vector it does get tagged as being a
-  /// member of the region (for ownership reasons), but its cost does not get
-  /// counted because the instruction hasn't been added in the "normal" way.
-  LLVM_ABI void addImpl(Instruction *I, bool IgnoreCost);
-  /// Adds I to the set. This is the main API for adding an instruction to the
-  /// region.
-  void add(Instruction *I) { addImpl(I, /*IgnoreCost=*/false); }
-  /// Removes I from the set.
-  LLVM_ABI void remove(Instruction *I);
-  friend class Context; // The callbacks need to call add() and remove().
-  friend class RegionInternalsAttorney; // For unit tests.
-  friend class RegionsFromBBs;          // For add().
-
-  /// Set \p I as the \p Idx'th element in the auxiliary vector.
-  /// NOTE: This is for internal use, it does not set the metadata.
-  void setAux(unsigned Idx, Instruction *I);
-  /// Helper for dropping Aux metadata for \p I.
-  void dropAuxMetadata(Instruction *I);
-  /// Remove instruction \p I from Aux and drop metadata.
-  void removeFromAux(Instruction *I);
-
-public:
-  LLVM_ABI Region(Context &Ctx, TargetTransformInfo &TTI);
-  LLVM_ABI ~Region();
-
-  Context &getContext() const { return Ctx; }
-  /// Returns true if I is in the Region.
-  bool contains(Instruction *I) const { return Insts.contains(I); }
-  /// Returns true if the Region has no instructions.
-  bool empty() const { return Insts.empty(); }
-  /// Set the auxiliary vector.
-  LLVM_ABI void setAux(ArrayRef<Instruction *> Aux);
-  /// \Returns the auxiliary vector.
-  const SmallVector<Instruction *> &getAux() const { return Aux; }
-  /// Clears all auxiliary data.
-  LLVM_ABI void clearAux();
-
-  using iterator = decltype(Insts.begin());
-  iterator begin() { return Insts.begin(); }
-  iterator end() { return Insts.end(); }
-  iterator_range<iterator> insts() { return make_range(begin(), end()); }
-
-  LLVM_ABI static SmallVector<std::unique_ptr<Region>>
-  createRegionsFromMD(Function &F, TargetTransformInfo &TTI);
-  /// \Returns the ScoreBoard data structure that keeps track of instr costs.
-  const ScoreBoard &getScoreboard() const { return Scoreboard; }
-
-#ifndef NDEBUG
-  /// This is an expensive check, meant for testing.
-  bool operator==(const Region &Other) const;
-  bool operator!=(const Region &other) const { return !(*this == other); }
-
-  void dump(raw_ostream &OS) const;
-  void dump() const;
-  friend raw_ostream &operator<<(raw_ostream &OS, const Region &Rgn) {
-    Rgn.dump(OS);
-    return OS;
-  }
-#endif
-};
-
-/// A helper client-attorney class for unit tests.
-class RegionInternalsAttorney {
-public:
-  static void add(Region &Rgn, Instruction *I) { Rgn.add(I); }
-  static void remove(Region &Rgn, Instruction *I) { Rgn.remove(I); }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_REGION_H
diff --git a/llvm/include/llvm/SandboxIR/Tracker.h b/llvm/include/llvm/SandboxIR/Tracker.h
deleted file mode 100644
index 9a2c9dd516489..0000000000000
--- a/llvm/include/llvm/SandboxIR/Tracker.h
+++ /dev/null
@@ -1,529 +0,0 @@
-//===- Tracker.h ------------------------------------------------*- 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 file is the component of SandboxIR that tracks all changes made to its
-// state, such that we can revert the state when needed.
-//
-// Tracking changes
-// ----------------
-// The user needs to call `Tracker::save()` to enable tracking changes
-// made to SandboxIR. From that point on, any change made to SandboxIR, will
-// automatically create a change tracking object and register it with the
-// tracker. IR-change objects are subclasses of `IRChangeBase` and get
-// registered with the `Tracker::track()` function. The change objects
-// are saved in the order they are registered with the tracker and are stored in
-// the `Tracker::Changes` vector. All of this is done transparently to
-// the user.
-//
-// Reverting changes
-// -----------------
-// Calling `Tracker::revert()` will restore the state saved when
-// `Tracker::save()` was called. Internally this goes through the
-// change objects in `Tracker::Changes` in reverse order, calling their
-// `IRChangeBase::revert()` function one by one.
-//
-// Accepting changes
-// -----------------
-// The user needs to either revert or accept changes before the tracker object
-// is destroyed. This is enforced in the tracker's destructor.
-// This is the job of `Tracker::accept()`. Internally this will go
-// through the change objects in `Tracker::Changes` in order, calling
-// `IRChangeBase::accept()`.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_TRACKER_H
-#define LLVM_SANDBOXIR_TRACKER_H
-
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StableHashing.h"
-#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/SandboxIR/Use.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include <memory>
-
-namespace llvm::sandboxir {
-
-class BasicBlock;
-class CallBrInst;
-class LoadInst;
-class StoreInst;
-class Instruction;
-class Tracker;
-class AllocaInst;
-class CatchSwitchInst;
-class SwitchInst;
-class ConstantInt;
-class ShuffleVectorInst;
-class CmpInst;
-class GlobalVariable;
-
-#ifndef NDEBUG
-
-/// A class that saves hashes and textual IR snapshots of functions in a
-/// SandboxIR Context, and does hash comparison when `expectNoDiff` is called.
-/// If hashes differ, it prints textual IR for both old and new versions to
-/// aid debugging.
-///
-/// This is used as an additional debug check when reverting changes to
-/// SandboxIR, to verify the reverted state matches the initial state.
-class IRSnapshotChecker {
-  Context &Ctx;
-
-  // A snapshot of textual IR for a function, with a hash for quick comparison.
-  struct FunctionSnapshot {
-    llvm::stable_hash Hash;
-    std::string TextualIR;
-  };
-
-  // A snapshot for each llvm::Function found in every module in the SandboxIR
-  // Context. In practice there will always be one module, but sandbox IR
-  // save/restore ops work at the Context level, so we must take the full state
-  // into account.
-  using ContextSnapshot = DenseMap<const llvm::Function *, FunctionSnapshot>;
-
-  ContextSnapshot OrigContextSnapshot;
-
-  // Dumps to a string the textual IR for a single Function.
-  std::string dumpIR(const llvm::Function &F) const;
-
-  // Returns a snapshot of all the modules in the sandbox IR context.
-  ContextSnapshot takeSnapshot() const;
-
-  // Compares two snapshots and returns true if they differ.
-  bool diff(const ContextSnapshot &Orig, const ContextSnapshot &Curr) const;
-
-public:
-  IRSnapshotChecker(Context &Ctx) : Ctx(Ctx) {}
-
-  /// Saves a snapshot of the current state. If there was any previous snapshot,
-  /// it will be replaced with the new one.
-  void save();
-
-  /// Checks current state against saved state, crashes if different.
-  void expectNoDiff();
-};
-
-#endif // NDEBUG
-
-/// The base class for IR Change classes.
-class IRChangeBase {
-protected:
-  friend class Tracker; // For Parent.
-
-public:
-  /// This runs when changes get reverted.
-  virtual void revert(Tracker &Tracker) = 0;
-  /// This runs when changes get accepted.
-  virtual void accept() = 0;
-  virtual ~IRChangeBase() = default;
-#ifndef NDEBUG
-  virtual void dump(raw_ostream &OS) const = 0;
-  LLVM_DUMP_METHOD virtual void dump() const = 0;
-  friend raw_ostream &operator<<(raw_ostream &OS, const IRChangeBase &C) {
-    C.dump(OS);
-    return OS;
-  }
-#endif
-};
-
-/// Tracks the change of the source Value of a sandboxir::Use.
-class UseSet : public IRChangeBase {
-  Use U;
-  Value *OrigV = nullptr;
-
-public:
-  UseSet(const Use &U) : U(U), OrigV(U.get()) {}
-  void revert(Tracker &Tracker) final { U.set(OrigV); }
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "UseSet"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-class LLVM_ABI PHIRemoveIncoming : public IRChangeBase {
-  PHINode *PHI;
-  unsigned RemovedIdx;
-  Value *RemovedV;
-  BasicBlock *RemovedBB;
-
-public:
-  PHIRemoveIncoming(PHINode *PHI, unsigned RemovedIdx);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "PHISetIncoming"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-class LLVM_ABI PHIAddIncoming : public IRChangeBase {
-  PHINode *PHI;
-  unsigned Idx;
-
-public:
-  PHIAddIncoming(PHINode *PHI);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "PHISetIncoming"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-class LLVM_ABI CmpSwapOperands : public IRChangeBase {
-  CmpInst *Cmp;
-
-public:
-  CmpSwapOperands(CmpInst *Cmp);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "CmpSwapOperands"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-/// Tracks swapping a Use with another Use.
-class UseSwap : public IRChangeBase {
-  Use ThisUse;
-  Use OtherUse;
-
-public:
-  UseSwap(const Use &ThisUse, const Use &OtherUse)
-      : ThisUse(ThisUse), OtherUse(OtherUse) {
-    assert(ThisUse.getUser() == OtherUse.getUser() && "Expected same user!");
-  }
-  void revert(Tracker &Tracker) final { ThisUse.swap(OtherUse); }
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "UseSwap"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-class LLVM_ABI EraseFromParent : public IRChangeBase {
-  /// Contains all the data we need to restore an "erased" (i.e., detached)
-  /// instruction: the instruction itself and its operands in order.
-  struct InstrAndOperands {
-    /// The operands that got dropped.
-    SmallVector<llvm::Value *> Operands;
-    /// The instruction that got "erased".
-    llvm::Instruction *LLVMI;
-  };
-  /// The instruction data is in reverse program order, which helps create the
-  /// original program order during revert().
-  SmallVector<InstrAndOperands> InstrData;
-  /// This is either the next Instruction in the stream, or the parent
-  /// BasicBlock if at the end of the BB.
-  PointerUnion<llvm::Instruction *, llvm::BasicBlock *> NextLLVMIOrBB;
-  /// We take ownership of the "erased" instruction.
-  std::unique_ptr<sandboxir::Value> ErasedIPtr;
-
-public:
-  EraseFromParent(std::unique_ptr<sandboxir::Value> &&IPtr);
-  void revert(Tracker &Tracker) final;
-  void accept() final;
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "EraseFromParent"; }
-  LLVM_DUMP_METHOD void dump() const final;
-  friend raw_ostream &operator<<(raw_ostream &OS, const EraseFromParent &C) {
-    C.dump(OS);
-    return OS;
-  }
-#endif
-};
-
-class LLVM_ABI RemoveFromParent : public IRChangeBase {
-  /// The instruction that is about to get removed.
-  Instruction *RemovedI = nullptr;
-  /// This is either the next instr, or the parent BB if at the end of the BB.
-  PointerUnion<Instruction *, BasicBlock *> NextInstrOrBB;
-
-public:
-  RemoveFromParent(Instruction *RemovedI);
-  void revert(Tracker &Tracker) final;
-  void accept() final {};
-  Instruction *getInstruction() const { return RemovedI; }
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "RemoveFromParent"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif // NDEBUG
-};
-
-/// This class can be used for tracking most instruction setters.
-/// The two template arguments are:
-/// - GetterFn: The getter member function pointer (e.g., `&Foo::get`)
-/// - SetterFn: The setter member function pointer (e.g., `&Foo::set`)
-/// Upon construction, it saves a copy of the original value by calling the
-/// getter function. Revert sets the value back to the one saved, using the
-/// setter function provided.
-///
-/// Example:
-///  Tracker.track(std::make_unique<
-///                GenericSetter<&FooInst::get, &FooInst::set>>(I, Tracker));
-///
-template <auto GetterFn, auto SetterFn>
-class GenericSetter final : public IRChangeBase {
-  /// Traits for getting the class type from GetterFn type.
-  template <typename> struct GetClassTypeFromGetter;
-  template <typename RetT, typename ClassT>
-  struct GetClassTypeFromGetter<RetT (ClassT::*)() const> {
-    using ClassType = ClassT;
-  };
-  using InstrT = typename GetClassTypeFromGetter<decltype(GetterFn)>::ClassType;
-  using SavedValT = std::invoke_result_t<decltype(GetterFn), InstrT>;
-  InstrT *I;
-  SavedValT OrigVal;
-
-public:
-  GenericSetter(InstrT *I) : I(I), OrigVal((I->*GetterFn)()) {}
-  void revert(Tracker &Tracker) final { (I->*SetterFn)(OrigVal); }
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "GenericSetter"; }
-  LLVM_DUMP_METHOD void dump() const final {
-    dump(dbgs());
-    dbgs() << "\n";
-  }
-#endif
-};
-
-/// Similar to GenericSetter but the setters/getters have an index as their
-/// first argument. This is commont in cases like: getOperand(unsigned Idx)
-template <auto GetterFn, auto SetterFn>
-class GenericSetterWithIdx final : public IRChangeBase {
-  /// Helper for getting the class type from the getter
-  template <typename ClassT, typename RetT>
-  static ClassT getClassTypeFromGetter(RetT (ClassT::*Fn)(unsigned) const);
-  template <typename ClassT, typename RetT>
-  static ClassT getClassTypeFromGetter(RetT (ClassT::*Fn)(unsigned));
-
-  using InstrT = decltype(getClassTypeFromGetter(GetterFn));
-  using SavedValT = std::invoke_result_t<decltype(GetterFn), InstrT, unsigned>;
-  InstrT *I;
-  SavedValT OrigVal;
-  unsigned Idx;
-
-public:
-  GenericSetterWithIdx(InstrT *I, unsigned Idx)
-      : I(I), OrigVal((I->*GetterFn)(Idx)), Idx(Idx) {}
-  void revert(Tracker &Tracker) final { (I->*SetterFn)(Idx, OrigVal); }
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "GenericSetterWithIdx"; }
-  LLVM_DUMP_METHOD void dump() const final {
-    dump(dbgs());
-    dbgs() << "\n";
-  }
-#endif
-};
-
-class LLVM_ABI CatchSwitchAddHandler : public IRChangeBase {
-  CatchSwitchInst *CSI;
-  unsigned HandlerIdx;
-
-public:
-  CatchSwitchAddHandler(CatchSwitchInst *CSI);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "CatchSwitchAddHandler"; }
-  LLVM_DUMP_METHOD void dump() const final {
-    dump(dbgs());
-    dbgs() << "\n";
-  }
-#endif // NDEBUG
-};
-
-class LLVM_ABI SwitchAddCase : public IRChangeBase {
-  SwitchInst *Switch;
-  ConstantInt *Val;
-
-public:
-  SwitchAddCase(SwitchInst *Switch, ConstantInt *Val)
-      : Switch(Switch), Val(Val) {}
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "SwitchAddCase"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif // NDEBUG
-};
-
-class LLVM_ABI SwitchRemoveCase : public IRChangeBase {
-  SwitchInst *Switch;
-  struct Case {
-    ConstantInt *Val;
-    BasicBlock *Dest;
-  };
-  SmallVector<Case> Cases;
-
-public:
-  SwitchRemoveCase(SwitchInst *Switch);
-
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "SwitchRemoveCase"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif // NDEBUG
-};
-
-class LLVM_ABI MoveInstr : public IRChangeBase {
-  /// The instruction that moved.
-  Instruction *MovedI;
-  /// This is either the next instruction in the block, or the parent BB if at
-  /// the end of the BB.
-  PointerUnion<Instruction *, BasicBlock *> NextInstrOrBB;
-
-public:
-  MoveInstr(sandboxir::Instruction *I);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "MoveInstr"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif // NDEBUG
-};
-
-class LLVM_ABI InsertIntoBB final : public IRChangeBase {
-  Instruction *InsertedI = nullptr;
-
-public:
-  InsertIntoBB(Instruction *InsertedI);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "InsertIntoBB"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif // NDEBUG
-};
-
-class LLVM_ABI CreateAndInsertInst final : public IRChangeBase {
-  Instruction *NewI = nullptr;
-
-public:
-  CreateAndInsertInst(Instruction *NewI) : NewI(NewI) {}
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "CreateAndInsertInst"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-class LLVM_ABI ShuffleVectorSetMask final : public IRChangeBase {
-  ShuffleVectorInst *SVI;
-  SmallVector<int, 8> PrevMask;
-
-public:
-  ShuffleVectorSetMask(ShuffleVectorInst *SVI);
-  void revert(Tracker &Tracker) final;
-  void accept() final {}
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const final { OS << "ShuffleVectorSetMask"; }
-  LLVM_DUMP_METHOD void dump() const final;
-#endif
-};
-
-/// The tracker collects all the change objects and implements the main API for
-/// saving / reverting / accepting.
-class Tracker {
-public:
-  enum class TrackerState {
-    Disabled,  ///> Tracking is disabled
-    Record,    ///> Tracking changes
-    Reverting, ///> Reverting changes
-  };
-
-private:
-  /// The list of changes that are being tracked.
-  SmallVector<std::unique_ptr<IRChangeBase>> Changes;
-  /// The current state of the tracker.
-  TrackerState State = TrackerState::Disabled;
-  Context &Ctx;
-
-#ifndef NDEBUG
-  IRSnapshotChecker SnapshotChecker;
-#endif
-
-public:
-#ifndef NDEBUG
-  /// Helps catch bugs where we are creating new change objects while in the
-  /// middle of creating other change objects.
-  bool InMiddleOfCreatingChange = false;
-#endif // NDEBUG
-
-  explicit Tracker(Context &Ctx)
-      : Ctx(Ctx)
-#ifndef NDEBUG
-        ,
-        SnapshotChecker(Ctx)
-#endif
-  {
-  }
-
-  LLVM_ABI ~Tracker();
-  Context &getContext() const { return Ctx; }
-  /// \Returns true if there are no changes tracked.
-  bool empty() const { return Changes.empty(); }
-  /// Record \p Change and take ownership. This is the main function used to
-  /// track Sandbox IR changes.
-  void track(std::unique_ptr<IRChangeBase> &&Change) {
-    assert(State == TrackerState::Record && "The tracker should be tracking!");
-#ifndef NDEBUG
-    assert(!InMiddleOfCreatingChange &&
-           "We are in the middle of creating another change!");
-    if (isTracking())
-      InMiddleOfCreatingChange = true;
-#endif // NDEBUG
-    Changes.push_back(std::move(Change));
-
-#ifndef NDEBUG
-    InMiddleOfCreatingChange = false;
-#endif
-  }
-  /// A convenience wrapper for `track()` that constructs and tracks the Change
-  /// object if tracking is enabled. \Returns true if tracking is enabled.
-  template <typename ChangeT, typename... ArgsT>
-  bool emplaceIfTracking(ArgsT... Args) {
-    if (!isTracking())
-      return false;
-    track(std::make_unique<ChangeT>(Args...));
-    return true;
-  }
-  /// \Returns true if the tracker is recording changes.
-  bool isTracking() const { return State == TrackerState::Record; }
-  /// \Returns the current state of the tracker.
-  TrackerState getState() const { return State; }
-  /// Turns on IR tracking.
-  LLVM_ABI void save();
-  /// Stops tracking and accept changes.
-  LLVM_ABI void accept();
-  /// Stops tracking and reverts to saved state.
-  LLVM_ABI void revert();
-
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-  friend raw_ostream &operator<<(raw_ostream &OS, const Tracker &Tracker) {
-    Tracker.dump(OS);
-    return OS;
-  }
-#endif // NDEBUG
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_TRACKER_H
diff --git a/llvm/include/llvm/SandboxIR/Type.h b/llvm/include/llvm/SandboxIR/Type.h
deleted file mode 100644
index d9c5e6c098dad..0000000000000
--- a/llvm/include/llvm/SandboxIR/Type.h
+++ /dev/null
@@ -1,480 +0,0 @@
-//===- llvm/SandboxIR/Type.h - Classes for handling data types --*- 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 is a thin wrapper over llvm::Type.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_TYPE_H
-#define LLVM_SANDBOXIR_TYPE_H
-
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Type.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm::sandboxir {
-
-class Context;
-// Forward declare friend classes for MSVC.
-class ArrayType;
-class CallBase;
-class CmpInst;
-class ConstantDataSequential;
-class FixedVectorType;
-class FPMathOperator;
-class FunctionType;
-class IntegerType;
-class Module;
-class PointerType;
-class ScalableVectorType;
-class StructType;
-class TargetExtType;
-class VectorType;
-#define DEF_INSTR(ID, OPCODE, CLASS) class CLASS;
-#define DEF_CONST(ID, CLASS) class CLASS;
-#include "llvm/SandboxIR/Values.def"
-
-/// Just like llvm::Type these are immutable, unique, never get freed and
-/// can only be created via static factory methods.
-class Type {
-protected:
-  llvm::Type *LLVMTy;
-  friend class ArrayType;          // For LLVMTy.
-  friend class StructType;         // For LLVMTy.
-  friend class VectorType;         // For LLVMTy.
-  friend class FixedVectorType;    // For LLVMTy.
-  friend class ScalableVectorType; // For LLVMTy.
-  friend class PointerType;        // For LLVMTy.
-  friend class FunctionType;       // For LLVMTy.
-  friend class IntegerType;        // For LLVMTy.
-  friend class Function;           // For LLVMTy.
-  friend class CallBase;           // For LLVMTy.
-  friend class ConstantInt;        // For LLVMTy.
-  friend class ConstantArray;      // For LLVMTy.
-  friend class ConstantStruct;     // For LLVMTy.
-  friend class ConstantVector;     // For LLVMTy.
-  friend class CmpInst;            // For LLVMTy. TODO: Cleanup after
-                                   // sandboxir::VectorType is more complete.
-  friend class Utils;              // for LLVMTy
-  friend class TargetExtType;      // For LLVMTy.
-  friend class Module;             // For LLVMTy.
-  friend class FPMathOperator;     // For LLVMTy.
-  friend class ConstantDataSequential; // For LLVMTy.
-
-  // Friend all instruction classes because `create()` functions use LLVMTy.
-#define DEF_INSTR(ID, OPCODE, CLASS) friend class CLASS;
-#define DEF_CONST(ID, CLASS) friend class CLASS;
-#include "llvm/SandboxIR/Values.def"
-  Context &Ctx;
-
-  Type(llvm::Type *LLVMTy, Context &Ctx) : LLVMTy(LLVMTy), Ctx(Ctx) {}
-  friend class Context; // For constructor and ~Type().
-  ~Type() = default;
-
-public:
-  /// Print the current type.
-  /// Omit the type details if \p NoDetails == true.
-  /// E.g., let %st = type { i32, i16 }
-  /// When \p NoDetails is true, we only print %st.
-  /// Put differently, \p NoDetails prints the type as if
-  /// inlined with the operands when printing an instruction.
-  void print(raw_ostream &OS, bool IsForDebug = false,
-             bool NoDetails = false) const {
-    LLVMTy->print(OS, IsForDebug, NoDetails);
-  }
-
-  Context &getContext() const { return Ctx; }
-
-  /// Return true if this is 'void'.
-  bool isVoidTy() const { return LLVMTy->isVoidTy(); }
-
-  /// Return true if this is 'half', a 16-bit IEEE fp type.
-  bool isHalfTy() const { return LLVMTy->isHalfTy(); }
-
-  /// Return true if this is 'bfloat', a 16-bit bfloat type.
-  bool isBFloatTy() const { return LLVMTy->isBFloatTy(); }
-
-  /// Return true if this is a 16-bit float type.
-  bool is16bitFPTy() const { return LLVMTy->is16bitFPTy(); }
-
-  /// Return true if this is 'float', a 32-bit IEEE fp type.
-  bool isFloatTy() const { return LLVMTy->isFloatTy(); }
-
-  /// Return true if this is 'double', a 64-bit IEEE fp type.
-  bool isDoubleTy() const { return LLVMTy->isDoubleTy(); }
-
-  /// Return true if this is x86 long double.
-  bool isX86_FP80Ty() const { return LLVMTy->isX86_FP80Ty(); }
-
-  /// Return true if this is 'fp128'.
-  bool isFP128Ty() const { return LLVMTy->isFP128Ty(); }
-
-  /// Return true if this is powerpc long double.
-  bool isPPC_FP128Ty() const { return LLVMTy->isPPC_FP128Ty(); }
-
-  /// Return true if this is a well-behaved IEEE-like type, which has a IEEE
-  /// compatible layout, and does not have non-IEEE values, such as x86_fp80's
-  /// unnormal values.
-  bool isIEEELikeFPTy() const { return LLVMTy->isIEEELikeFPTy(); }
-
-  /// Return true if this is one of the floating-point types
-  bool isFloatingPointTy() const { return LLVMTy->isFloatingPointTy(); }
-
-  /// Returns true if this is a floating-point type that is an unevaluated sum
-  /// of multiple floating-point units.
-  /// An example of such a type is ppc_fp128, also known as double-double, which
-  /// consists of two IEEE 754 doubles.
-  bool isMultiUnitFPType() const { return LLVMTy->isMultiUnitFPType(); }
-
-  const fltSemantics &getFltSemantics() const {
-    return LLVMTy->getFltSemantics();
-  }
-
-  /// Return true if this is X86 AMX.
-  bool isX86_AMXTy() const { return LLVMTy->isX86_AMXTy(); }
-
-  /// Return true if this is a target extension type.
-  bool isTargetExtTy() const { return LLVMTy->isTargetExtTy(); }
-
-  /// Return true if this is a target extension type with a scalable layout.
-  bool isScalableTargetExtTy() const { return LLVMTy->isScalableTargetExtTy(); }
-
-  /// Return true if this is a type whose size is a known multiple of vscale.
-  bool isScalableTy() const { return LLVMTy->isScalableTy(); }
-
-  /// Return true if this is a FP type or a vector of FP.
-  bool isFPOrFPVectorTy() const { return LLVMTy->isFPOrFPVectorTy(); }
-
-  /// Return true if this is 'label'.
-  bool isLabelTy() const { return LLVMTy->isLabelTy(); }
-
-  /// Return true if this is 'metadata'.
-  bool isMetadataTy() const { return LLVMTy->isMetadataTy(); }
-
-  /// Return true if this is 'token'.
-  bool isTokenTy() const { return LLVMTy->isTokenTy(); }
-
-  /// True if this is an instance of IntegerType.
-  bool isIntegerTy() const { return LLVMTy->isIntegerTy(); }
-
-  /// Return true if this is an IntegerType of the given width.
-  bool isIntegerTy(unsigned Bitwidth) const {
-    return LLVMTy->isIntegerTy(Bitwidth);
-  }
-
-  /// Return true if this is an integer type or a vector of integer types.
-  bool isIntOrIntVectorTy() const { return LLVMTy->isIntOrIntVectorTy(); }
-
-  /// Return true if this is an integer type or a vector of integer types of
-  /// the given width.
-  bool isIntOrIntVectorTy(unsigned BitWidth) const {
-    return LLVMTy->isIntOrIntVectorTy(BitWidth);
-  }
-
-  /// Return true if this is an integer type or a pointer type.
-  bool isIntOrPtrTy() const { return LLVMTy->isIntOrPtrTy(); }
-
-  /// True if this is an instance of FunctionType.
-  bool isFunctionTy() const { return LLVMTy->isFunctionTy(); }
-
-  /// True if this is an instance of StructType.
-  bool isStructTy() const { return LLVMTy->isStructTy(); }
-
-  /// True if this is an instance of ArrayType.
-  bool isArrayTy() const { return LLVMTy->isArrayTy(); }
-
-  /// True if this is an instance of PointerType.
-  bool isPointerTy() const { return LLVMTy->isPointerTy(); }
-
-  /// Return true if this is a pointer type or a vector of pointer types.
-  bool isPtrOrPtrVectorTy() const { return LLVMTy->isPtrOrPtrVectorTy(); }
-
-  /// True if this is an instance of VectorType.
-  inline bool isVectorTy() const { return LLVMTy->isVectorTy(); }
-
-  /// Return true if this type could be converted with a lossless BitCast to
-  /// type 'Ty'. For example, i8* to i32*. BitCasts are valid for types of the
-  /// same size only where no re-interpretation of the bits is done.
-  /// Determine if this type could be losslessly bitcast to Ty
-  bool canLosslesslyBitCastTo(Type *Ty) const {
-    return LLVMTy->canLosslesslyBitCastTo(Ty->LLVMTy);
-  }
-
-  /// Return true if this type is empty, that is, it has no elements or all of
-  /// its elements are empty.
-  bool isEmptyTy() const { return LLVMTy->isEmptyTy(); }
-
-  /// Return true if the type is "first class", meaning it is a valid type for a
-  /// Value.
-  bool isFirstClassType() const { return LLVMTy->isFirstClassType(); }
-
-  /// Return true if the type is a valid type for a register in codegen. This
-  /// includes all first-class types except struct and array types.
-  bool isSingleValueType() const { return LLVMTy->isSingleValueType(); }
-
-  /// Return true if the type is an aggregate type. This means it is valid as
-  /// the first operand of an insertvalue or extractvalue instruction. This
-  /// includes struct and array types, but does not include vector types.
-  bool isAggregateType() const { return LLVMTy->isAggregateType(); }
-
-  /// Return true if it makes sense to take the size of this type. To get the
-  /// actual size for a particular target, it is reasonable to use the
-  /// DataLayout subsystem to do this.
-  bool isSized(SmallPtrSetImpl<Type *> *Visited = nullptr) const {
-    SmallPtrSet<llvm::Type *, 8> LLVMVisited;
-    LLVMVisited.reserve(Visited->size());
-    for (Type *Ty : *Visited)
-      LLVMVisited.insert(Ty->LLVMTy);
-    return LLVMTy->isSized(&LLVMVisited);
-  }
-
-  /// Return the basic size of this type if it is a primitive type. These are
-  /// fixed by LLVM and are not target-dependent.
-  /// This will return zero if the type does not have a size or is not a
-  /// primitive type.
-  ///
-  /// If this is a scalable vector type, the scalable property will be set and
-  /// the runtime size will be a positive integer multiple of the base size.
-  ///
-  /// Note that this may not reflect the size of memory allocated for an
-  /// instance of the type or the number of bytes that are written when an
-  /// instance of the type is stored to memory. The DataLayout class provides
-  /// additional query functions to provide this information.
-  ///
-  TypeSize getPrimitiveSizeInBits() const {
-    return LLVMTy->getPrimitiveSizeInBits();
-  }
-
-  /// If this is a vector type, return the getPrimitiveSizeInBits value for the
-  /// element type. Otherwise return the getPrimitiveSizeInBits value for this
-  /// type.
-  unsigned getScalarSizeInBits() const { return LLVMTy->getScalarSizeInBits(); }
-
-  /// Return the width of the mantissa of this type. This is only valid on
-  /// floating-point types. If the FP type does not have a stable mantissa (e.g.
-  /// ppc long double), this method returns -1.
-  int getFPMantissaWidth() const { return LLVMTy->getFPMantissaWidth(); }
-
-  /// If this is a vector type, return the element type, otherwise return
-  /// 'this'.
-  LLVM_ABI Type *getScalarType() const;
-
-  // TODO: ADD MISSING
-
-  LLVM_ABI static Type *getInt64Ty(Context &Ctx);
-  LLVM_ABI static Type *getInt32Ty(Context &Ctx);
-  LLVM_ABI static Type *getInt16Ty(Context &Ctx);
-  LLVM_ABI static Type *getInt8Ty(Context &Ctx);
-  LLVM_ABI static Type *getInt1Ty(Context &Ctx);
-  LLVM_ABI static Type *getDoubleTy(Context &Ctx);
-  LLVM_ABI static Type *getFloatTy(Context &Ctx);
-  LLVM_ABI static Type *getHalfTy(Context &Ctx);
-  // TODO: missing get*
-
-  /// Get the address space of this pointer or pointer vector type.
-  inline unsigned getPointerAddressSpace() const {
-    return LLVMTy->getPointerAddressSpace();
-  }
-
-#ifndef NDEBUG
-  void dumpOS(raw_ostream &OS);
-  LLVM_DUMP_METHOD void dump();
-#endif // NDEBUG
-};
-
-class PointerType : public Type {
-public:
-  // TODO: add missing functions
-
-  LLVM_ABI static PointerType *get(Context &Ctx, unsigned AddressSpace);
-
-  static bool classof(const Type *From) {
-    return isa<llvm::PointerType>(From->LLVMTy);
-  }
-};
-
-class ArrayType : public Type {
-public:
-  LLVM_ABI static ArrayType *get(Type *ElementType, uint64_t NumElements);
-  // TODO: add missing functions
-  static bool classof(const Type *From) {
-    return isa<llvm::ArrayType>(From->LLVMTy);
-  }
-};
-
-class StructType : public Type {
-public:
-  /// This static method is the primary way to create a literal StructType.
-  LLVM_ABI static StructType *get(Context &Ctx, ArrayRef<Type *> Elements,
-                                  bool IsPacked = false);
-
-  bool isPacked() const { return cast<llvm::StructType>(LLVMTy)->isPacked(); }
-
-  // TODO: add missing functions
-  static bool classof(const Type *From) {
-    return isa<llvm::StructType>(From->LLVMTy);
-  }
-};
-
-class VectorType : public Type {
-public:
-  LLVM_ABI static VectorType *get(Type *ElementType, ElementCount EC);
-  static VectorType *get(Type *ElementType, unsigned NumElements,
-                         bool Scalable) {
-    return VectorType::get(ElementType,
-                           ElementCount::get(NumElements, Scalable));
-  }
-  LLVM_ABI Type *getElementType() const;
-
-  static VectorType *get(Type *ElementType, const VectorType *Other) {
-    return VectorType::get(ElementType, Other->getElementCount());
-  }
-
-  inline ElementCount getElementCount() const {
-    return cast<llvm::VectorType>(LLVMTy)->getElementCount();
-  }
-  LLVM_ABI static VectorType *getInteger(VectorType *VTy);
-  LLVM_ABI static VectorType *getExtendedElementVectorType(VectorType *VTy);
-  LLVM_ABI static VectorType *getTruncatedElementVectorType(VectorType *VTy);
-  LLVM_ABI static VectorType *getSubdividedVectorType(VectorType *VTy,
-                                                      int NumSubdivs);
-  LLVM_ABI static VectorType *getHalfElementsVectorType(VectorType *VTy);
-  LLVM_ABI static VectorType *getDoubleElementsVectorType(VectorType *VTy);
-  LLVM_ABI static bool isValidElementType(Type *ElemTy);
-
-  static bool classof(const Type *From) {
-    return isa<llvm::VectorType>(From->LLVMTy);
-  }
-};
-
-class FixedVectorType : public VectorType {
-public:
-  LLVM_ABI static FixedVectorType *get(Type *ElementType, unsigned NumElts);
-
-  static FixedVectorType *get(Type *ElementType, const FixedVectorType *FVTy) {
-    return get(ElementType, FVTy->getNumElements());
-  }
-
-  static FixedVectorType *getInteger(FixedVectorType *VTy) {
-    return cast<FixedVectorType>(VectorType::getInteger(VTy));
-  }
-
-  static FixedVectorType *getExtendedElementVectorType(FixedVectorType *VTy) {
-    return cast<FixedVectorType>(VectorType::getExtendedElementVectorType(VTy));
-  }
-
-  static FixedVectorType *getTruncatedElementVectorType(FixedVectorType *VTy) {
-    return cast<FixedVectorType>(
-        VectorType::getTruncatedElementVectorType(VTy));
-  }
-
-  static FixedVectorType *getSubdividedVectorType(FixedVectorType *VTy,
-                                                  int NumSubdivs) {
-    return cast<FixedVectorType>(
-        VectorType::getSubdividedVectorType(VTy, NumSubdivs));
-  }
-
-  static FixedVectorType *getHalfElementsVectorType(FixedVectorType *VTy) {
-    return cast<FixedVectorType>(VectorType::getHalfElementsVectorType(VTy));
-  }
-
-  static FixedVectorType *getDoubleElementsVectorType(FixedVectorType *VTy) {
-    return cast<FixedVectorType>(VectorType::getDoubleElementsVectorType(VTy));
-  }
-
-  static bool classof(const Type *T) {
-    return isa<llvm::FixedVectorType>(T->LLVMTy);
-  }
-
-  unsigned getNumElements() const {
-    return cast<llvm::FixedVectorType>(LLVMTy)->getNumElements();
-  }
-};
-
-class ScalableVectorType : public VectorType {
-public:
-  LLVM_ABI static ScalableVectorType *get(Type *ElementType,
-                                          unsigned MinNumElts);
-
-  static ScalableVectorType *get(Type *ElementType,
-                                 const ScalableVectorType *SVTy) {
-    return get(ElementType, SVTy->getMinNumElements());
-  }
-
-  static ScalableVectorType *getInteger(ScalableVectorType *VTy) {
-    return cast<ScalableVectorType>(VectorType::getInteger(VTy));
-  }
-
-  static ScalableVectorType *
-  getExtendedElementVectorType(ScalableVectorType *VTy) {
-    return cast<ScalableVectorType>(
-        VectorType::getExtendedElementVectorType(VTy));
-  }
-
-  static ScalableVectorType *
-  getTruncatedElementVectorType(ScalableVectorType *VTy) {
-    return cast<ScalableVectorType>(
-        VectorType::getTruncatedElementVectorType(VTy));
-  }
-
-  static ScalableVectorType *getSubdividedVectorType(ScalableVectorType *VTy,
-                                                     int NumSubdivs) {
-    return cast<ScalableVectorType>(
-        VectorType::getSubdividedVectorType(VTy, NumSubdivs));
-  }
-
-  static ScalableVectorType *
-  getHalfElementsVectorType(ScalableVectorType *VTy) {
-    return cast<ScalableVectorType>(VectorType::getHalfElementsVectorType(VTy));
-  }
-
-  static ScalableVectorType *
-  getDoubleElementsVectorType(ScalableVectorType *VTy) {
-    return cast<ScalableVectorType>(
-        VectorType::getDoubleElementsVectorType(VTy));
-  }
-
-  unsigned getMinNumElements() const {
-    return cast<llvm::ScalableVectorType>(LLVMTy)->getMinNumElements();
-  }
-
-  static bool classof(const Type *T) {
-    return isa<llvm::ScalableVectorType>(T->LLVMTy);
-  }
-};
-
-class FunctionType : public Type {
-public:
-  // TODO: add missing functions
-  static bool classof(const Type *From) {
-    return isa<llvm::FunctionType>(From->LLVMTy);
-  }
-};
-
-/// Class to represent integer types. Note that this class is also used to
-/// represent the built-in integer types: Int1Ty, Int8Ty, Int16Ty, Int32Ty and
-/// Int64Ty.
-/// Integer representation type
-class IntegerType : public Type {
-public:
-  LLVM_ABI static IntegerType *get(Context &C, unsigned NumBits);
-  // TODO: add missing functions
-  static bool classof(const Type *From) {
-    return isa<llvm::IntegerType>(From->LLVMTy);
-  }
-  operator llvm::IntegerType &() const {
-    return *cast<llvm::IntegerType>(LLVMTy);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_TYPE_H
diff --git a/llvm/include/llvm/SandboxIR/Use.h b/llvm/include/llvm/SandboxIR/Use.h
deleted file mode 100644
index 5c02c4f2b3495..0000000000000
--- a/llvm/include/llvm/SandboxIR/Use.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===- Use.h ----------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Sandbox IR Use.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_USE_H
-#define LLVM_SANDBOXIR_USE_H
-
-#include "llvm/IR/Use.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvm::sandboxir {
-
-class Context;
-class Value;
-class User;
-class CallBase;
-class CallBrInst;
-class PHINode;
-
-/// Represents a Def-use/Use-def edge in SandboxIR.
-/// NOTE: Unlike llvm::Use, this is not an integral part of the use-def chains.
-/// It is also not uniqued and is currently passed by value, so you can have
-/// more than one sandboxir::Use objects for the same use-def edge.
-class Use {
-  llvm::Use *LLVMUse;
-  User *Usr;
-  Context *Ctx;
-
-  /// Don't allow the user to create a sandboxir::Use directly.
-  Use(llvm::Use *LLVMUse, User *Usr, Context &Ctx)
-      : LLVMUse(LLVMUse), Usr(Usr), Ctx(&Ctx) {}
-  Use() : LLVMUse(nullptr), Ctx(nullptr) {}
-
-  friend class Value;              // For constructor
-  friend class User;               // For constructor
-  friend class OperandUseIterator; // For constructor
-  friend class UserUseIterator;    // For accessing members
-  friend class CallBase;           // For LLVMUse
-  friend class CallBrInst;         // For constructor
-  friend class PHINode;            // For LLVMUse
-
-public:
-  operator Value *() const { return get(); }
-  LLVM_ABI Value *get() const;
-  LLVM_ABI void set(Value *V);
-  class User *getUser() const { return Usr; }
-  LLVM_ABI unsigned getOperandNo() const;
-  LLVM_ABI void swap(Use &OtherUse);
-  Context *getContext() const { return Ctx; }
-  bool operator==(const Use &Other) const {
-    assert(Ctx == Other.Ctx && "Contexts differ!");
-    return LLVMUse == Other.LLVMUse && Usr == Other.Usr;
-  }
-  bool operator!=(const Use &Other) const { return !(*this == Other); }
-#ifndef NDEBUG
-  void dumpOS(raw_ostream &OS) const;
-  void dump() const;
-#endif // NDEBUG
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_USE_H
diff --git a/llvm/include/llvm/SandboxIR/User.h b/llvm/include/llvm/SandboxIR/User.h
deleted file mode 100644
index c552e2e3378be..0000000000000
--- a/llvm/include/llvm/SandboxIR/User.h
+++ /dev/null
@@ -1,151 +0,0 @@
-//===- User.h ---------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_USER_H
-#define LLVM_SANDBOXIR_USER_H
-
-#include "llvm/IR/User.h"
-#include "llvm/IR/Value.h"
-#include "llvm/SandboxIR/Use.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-class Context;
-
-/// Iterator for the `Use` edges of a User's operands.
-/// \Returns the operand `Use` when dereferenced.
-class OperandUseIterator {
-  sandboxir::Use Use;
-  /// Don't let the user create a non-empty OperandUseIterator.
-  OperandUseIterator(const class Use &Use) : Use(Use) {}
-  friend class User;                                  // For constructor
-#define DEF_INSTR(ID, OPC, CLASS) friend class CLASS; // For constructor
-#include "llvm/SandboxIR/Values.def"
-
-public:
-  using difference_type = std::ptrdiff_t;
-  using value_type = sandboxir::Use;
-  using pointer = value_type *;
-  using reference = value_type &;
-  using iterator_category = std::input_iterator_tag;
-
-  OperandUseIterator() = default;
-  LLVM_ABI value_type operator*() const;
-  LLVM_ABI OperandUseIterator &operator++();
-  OperandUseIterator operator++(int) {
-    auto Copy = *this;
-    this->operator++();
-    return Copy;
-  }
-  bool operator==(const OperandUseIterator &Other) const {
-    return Use == Other.Use;
-  }
-  bool operator!=(const OperandUseIterator &Other) const {
-    return !(*this == Other);
-  }
-  LLVM_ABI OperandUseIterator operator+(unsigned Num) const;
-  LLVM_ABI OperandUseIterator operator-(unsigned Num) const;
-  LLVM_ABI int operator-(const OperandUseIterator &Other) const;
-};
-
-/// A sandboxir::User has operands.
-class LLVM_ABI User : public Value {
-protected:
-  User(ClassID ID, llvm::Value *V, Context &Ctx) : Value(ID, V, Ctx) {}
-
-  /// \Returns the Use edge that corresponds to \p OpIdx.
-  /// Note: This is the default implementation that works for instructions that
-  /// match the underlying LLVM instruction. All others should use a different
-  /// implementation.
-  Use getOperandUseDefault(unsigned OpIdx, bool Verify) const;
-  /// \Returns the Use for the \p OpIdx'th operand. This is virtual to allow
-  /// instructions to deviate from the LLVM IR operands, which is a requirement
-  /// for sandboxir Instructions that consist of more than one LLVM Instruction.
-  virtual Use getOperandUseInternal(unsigned OpIdx, bool Verify) const = 0;
-  friend class OperandUseIterator; // for getOperandUseInternal()
-
-  /// The default implementation works only for single-LLVMIR-instruction
-  /// Users and only if they match exactly the LLVM instruction.
-  unsigned getUseOperandNoDefault(const Use &Use) const {
-    return Use.LLVMUse->getOperandNo();
-  }
-  /// \Returns the operand index of \p Use.
-  virtual unsigned getUseOperandNo(const Use &Use) const = 0;
-  friend unsigned Use::getOperandNo() const; // For getUseOperandNo()
-
-  void swapOperandsInternal(unsigned OpIdxA, unsigned OpIdxB) {
-    assert(OpIdxA < getNumOperands() && "OpIdxA out of bounds!");
-    assert(OpIdxB < getNumOperands() && "OpIdxB out of bounds!");
-    auto UseA = getOperandUse(OpIdxA);
-    auto UseB = getOperandUse(OpIdxB);
-    UseA.swap(UseB);
-  }
-
-#ifndef NDEBUG
-  void verifyUserOfLLVMUse(const llvm::Use &Use) const;
-#endif // NDEBUG
-
-public:
-  /// For isa/dyn_cast.
-  static bool classof(const Value *From);
-  using op_iterator = OperandUseIterator;
-  using const_op_iterator = OperandUseIterator;
-  using op_range = iterator_range<op_iterator>;
-  using const_op_range = iterator_range<const_op_iterator>;
-
-  virtual op_iterator op_begin() {
-    assert(isa<llvm::User>(Val) && "Expect User value!");
-    return op_iterator(getOperandUseInternal(0, /*Verify=*/false));
-  }
-  virtual op_iterator op_end() {
-    assert(isa<llvm::User>(Val) && "Expect User value!");
-    return op_iterator(
-        getOperandUseInternal(getNumOperands(), /*Verify=*/false));
-  }
-  virtual const_op_iterator op_begin() const {
-    return const_cast<User *>(this)->op_begin();
-  }
-  virtual const_op_iterator op_end() const {
-    return const_cast<User *>(this)->op_end();
-  }
-
-  op_range operands() { return make_range<op_iterator>(op_begin(), op_end()); }
-  const_op_range operands() const {
-    return make_range<const_op_iterator>(op_begin(), op_end());
-  }
-  Value *getOperand(unsigned OpIdx) const { return getOperandUse(OpIdx).get(); }
-  /// \Returns the operand edge for \p OpIdx. NOTE: This should also work for
-  /// OpIdx == getNumOperands(), which is used for op_end().
-  Use getOperandUse(unsigned OpIdx) const {
-    return getOperandUseInternal(OpIdx, /*Verify=*/true);
-  }
-  virtual unsigned getNumOperands() const {
-    return isa<llvm::User>(Val) ? cast<llvm::User>(Val)->getNumOperands() : 0;
-  }
-
-  virtual void setOperand(unsigned OperandIdx, Value *Operand);
-  /// Replaces any operands that match \p FromV with \p ToV. Returns whether any
-  /// operands were replaced.
-  bool replaceUsesOfWith(Value *FromV, Value *ToV);
-
-#ifndef NDEBUG
-  void verify() const override {
-    assert(isa<llvm::User>(Val) && "Expected User!");
-  }
-  void dumpCommonHeader(raw_ostream &OS) const final;
-  void dumpOS(raw_ostream &OS) const override {
-    // TODO: Remove this tmp implementation once we get the Instruction classes.
-  }
-#endif
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_USER_H
diff --git a/llvm/include/llvm/SandboxIR/Utils.h b/llvm/include/llvm/SandboxIR/Utils.h
deleted file mode 100644
index 5c6f0d9edd618..0000000000000
--- a/llvm/include/llvm/SandboxIR/Utils.h
+++ /dev/null
@@ -1,138 +0,0 @@
-//===- Utils.h --------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Collector for SandboxIR related convenience functions that don't belong in
-// other classes.
-
-#ifndef LLVM_SANDBOXIR_UTILS_H
-#define LLVM_SANDBOXIR_UTILS_H
-
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/LoopAccessAnalysis.h"
-#include "llvm/Analysis/MemoryLocation.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/Verifier.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include <optional>
-
-namespace llvm::sandboxir {
-
-class Utils {
-public:
-  /// \Returns the expected type of \p Value V. For most Values this is
-  /// equivalent to getType, but for stores returns the stored type, rather
-  /// than void, and for ReturnInsts returns the returned type.
-  static Type *getExpectedType(const Value *V) {
-    if (auto *I = dyn_cast<Instruction>(V)) {
-      // A Return's value operand can be null if it returns void.
-      if (auto *RI = dyn_cast<ReturnInst>(I)) {
-        if (RI->getReturnValue() == nullptr)
-          return RI->getType();
-      }
-      return getExpectedValue(I)->getType();
-    }
-    return V->getType();
-  }
-
-  /// \Returns the expected Value for this instruction. For most instructions,
-  /// this is the instruction itself, but for stores returns the stored
-  /// operand, and for ReturnInstructions returns the returned value.
-  static Value *getExpectedValue(const Instruction *I) {
-    if (auto *SI = dyn_cast<StoreInst>(I))
-      return SI->getValueOperand();
-    if (auto *RI = dyn_cast<ReturnInst>(I))
-      return RI->getReturnValue();
-    return const_cast<Instruction *>(I);
-  }
-
-  /// \Returns the base Value for load or store instruction \p LSI.
-  template <typename LoadOrStoreT>
-  static Value *getMemInstructionBase(const LoadOrStoreT *LSI) {
-    static_assert(std::is_same_v<LoadOrStoreT, LoadInst> ||
-                      std::is_same_v<LoadOrStoreT, StoreInst>,
-                  "Expected sandboxir::Load or sandboxir::Store!");
-    return LSI->Ctx.getOrCreateValue(
-        getUnderlyingObject(LSI->getPointerOperand()->Val));
-  }
-
-  /// \Returns the number of bits of \p Ty.
-  static unsigned getNumBits(Type *Ty, const DataLayout &DL) {
-    return DL.getTypeSizeInBits(Ty->LLVMTy);
-  }
-
-  /// \Returns the number of bits required to represent the operands or return
-  /// value of \p V in \p DL.
-  static unsigned getNumBits(Value *V, const DataLayout &DL) {
-    Type *Ty = getExpectedType(V);
-    return getNumBits(Ty, DL);
-  }
-
-  /// \Returns the number of bits required to represent the operands or
-  /// return value of \p I.
-  static unsigned getNumBits(Instruction *I) {
-    return I->getDataLayout().getTypeSizeInBits(getExpectedType(I)->LLVMTy);
-  }
-
-  /// Equivalent to MemoryLocation::getOrNone(I).
-  static std::optional<llvm::MemoryLocation>
-  memoryLocationGetOrNone(const Instruction *I) {
-    return llvm::MemoryLocation::getOrNone(cast<llvm::Instruction>(I->Val));
-  }
-
-  /// \Returns the gap between the memory locations accessed by \p I0 and
-  /// \p I1 in bytes.
-  template <typename LoadOrStoreT>
-  static std::optional<int> getPointerDiffInBytes(LoadOrStoreT *I0,
-                                                  LoadOrStoreT *I1,
-                                                  ScalarEvolution &SE) {
-    static_assert(std::is_same_v<LoadOrStoreT, LoadInst> ||
-                      std::is_same_v<LoadOrStoreT, StoreInst>,
-                  "Expected sandboxir::Load or sandboxir::Store!");
-    llvm::Value *Opnd0 = I0->getPointerOperand()->Val;
-    llvm::Value *Opnd1 = I1->getPointerOperand()->Val;
-    llvm::Value *Ptr0 = getUnderlyingObject(Opnd0);
-    llvm::Value *Ptr1 = getUnderlyingObject(Opnd1);
-    if (Ptr0 != Ptr1)
-      return false;
-    llvm::Type *ElemTy = llvm::Type::getInt8Ty(SE.getContext());
-    return getPointersDiff(ElemTy, Opnd0, ElemTy, Opnd1, I0->getDataLayout(),
-                           SE, /*StrictCheck=*/false, /*CheckType=*/false);
-  }
-
-  /// \Returns true if \p I0 accesses a memory location lower than \p I1.
-  /// Returns false if the difference cannot be determined, if the memory
-  /// locations are equal, or if I1 accesses a memory location greater than I0.
-  template <typename LoadOrStoreT>
-  static bool atLowerAddress(LoadOrStoreT *I0, LoadOrStoreT *I1,
-                             ScalarEvolution &SE) {
-    auto Diff = getPointerDiffInBytes(I0, I1, SE);
-    if (!Diff)
-      return false;
-    return *Diff > 0;
-  }
-
-  /// Equivalent to BatchAA::getModRefInfo().
-  static ModRefInfo
-  aliasAnalysisGetModRefInfo(BatchAAResults &BatchAA, const Instruction *I,
-                             const std::optional<MemoryLocation> &OptLoc) {
-    return BatchAA.getModRefInfo(cast<llvm::Instruction>(I->Val), OptLoc);
-  }
-
-  /// Equivalent to llvm::verifyFunction().
-  /// \Returns true if the IR is broken.
-  static bool verifyFunction(const Function *F, raw_ostream &OS) {
-    const auto &LLVMF = *cast<llvm::Function>(F->Val);
-    return llvm::verifyFunction(LLVMF, &OS);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_UTILS_H
diff --git a/llvm/include/llvm/SandboxIR/Value.h b/llvm/include/llvm/SandboxIR/Value.h
deleted file mode 100644
index 8e50614d6a6d0..0000000000000
--- a/llvm/include/llvm/SandboxIR/Value.h
+++ /dev/null
@@ -1,316 +0,0 @@
-//===- Value.h --------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_SANDBOXIR_VALUE_H
-#define LLVM_SANDBOXIR_VALUE_H
-
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Value.h"
-#include "llvm/SandboxIR/Use.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-// Forward declare all classes to avoid some MSVC build errors.
-#define DEF_INSTR(ID, OPC, CLASS) class CLASS;
-#define DEF_CONST(ID, CLASS) class CLASS;
-#define DEF_USER(ID, CLASS) class CLASS;
-#include "llvm/SandboxIR/Values.def"
-class Context;
-class FuncletPadInst;
-class Type;
-class GlobalValue;
-class GlobalObject;
-class Module;
-class UnaryInstruction;
-class CmpInst;
-class IntrinsicInst;
-class Operator;
-class OverflowingBinaryOperator;
-class FPMathOperator;
-class Region;
-
-/// Iterator for the `Use` edges of a Value's users.
-/// \Returns a `Use` when dereferenced.
-class UserUseIterator {
-  sandboxir::Use Use;
-  /// Don't let the user create a non-empty UserUseIterator.
-  UserUseIterator(const class Use &Use) : Use(Use) {}
-  friend class Value; // For constructor
-
-public:
-  using difference_type = std::ptrdiff_t;
-  using value_type = sandboxir::Use;
-  using pointer = value_type *;
-  using reference = value_type &;
-  using iterator_category = std::input_iterator_tag;
-
-  UserUseIterator() = default;
-  value_type operator*() const { return Use; }
-  LLVM_ABI UserUseIterator &operator++();
-  bool operator==(const UserUseIterator &Other) const {
-    return Use == Other.Use;
-  }
-  bool operator!=(const UserUseIterator &Other) const {
-    return !(*this == Other);
-  }
-  const sandboxir::Use &getUse() const { return Use; }
-};
-
-/// A SandboxIR Value has users. This is the base class.
-class Value {
-public:
-  enum class ClassID : unsigned {
-#define DEF_VALUE(ID, CLASS) ID,
-#define DEF_USER(ID, CLASS) ID,
-#define DEF_CONST(ID, CLASS) ID,
-#define DEF_INSTR(ID, OPC, CLASS) ID,
-#include "llvm/SandboxIR/Values.def"
-  };
-
-protected:
-  static const char *getSubclassIDStr(ClassID ID) {
-    switch (ID) {
-#define DEF_VALUE(ID, CLASS)                                                   \
-  case ClassID::ID:                                                            \
-    return #ID;
-#define DEF_USER(ID, CLASS)                                                    \
-  case ClassID::ID:                                                            \
-    return #ID;
-#define DEF_CONST(ID, CLASS)                                                   \
-  case ClassID::ID:                                                            \
-    return #ID;
-#define DEF_INSTR(ID, OPC, CLASS)                                              \
-  case ClassID::ID:                                                            \
-    return #ID;
-#include "llvm/SandboxIR/Values.def"
-    }
-    llvm_unreachable("Unimplemented ID");
-  }
-
-  /// For isa/dyn_cast.
-  ClassID SubclassID;
-#ifndef NDEBUG
-  /// A unique ID used for forming the name (used for debugging).
-  unsigned UID;
-#endif
-  /// The LLVM Value that corresponds to this SandboxIR Value.
-  /// NOTE: Some sandboxir Instructions, like Packs, may include more than one
-  /// value and in these cases `Val` points to the last instruction in program
-  /// order.
-  llvm::Value *Val = nullptr;
-
-  friend class Context;               // For getting `Val`.
-  friend class User;                  // For getting `Val`.
-  friend class Use;                   // For getting `Val`.
-  friend class VAArgInst;             // For getting `Val`.
-  friend class FreezeInst;            // For getting `Val`.
-  friend class FenceInst;             // For getting `Val`.
-  friend class SelectInst;            // For getting `Val`.
-  friend class ExtractElementInst;    // For getting `Val`.
-  friend class InsertElementInst;     // For getting `Val`.
-  friend class ShuffleVectorInst;     // For getting `Val`.
-  friend class ExtractValueInst;      // For getting `Val`.
-  friend class InsertValueInst;       // For getting `Val`.
-  friend class BranchInst;            // For getting `Val`.
-  friend class LoadInst;              // For getting `Val`.
-  friend class StoreInst;             // For getting `Val`.
-  friend class ReturnInst;            // For getting `Val`.
-  friend class CallBase;              // For getting `Val`.
-  friend class CallInst;              // For getting `Val`.
-  friend class InvokeInst;            // For getting `Val`.
-  friend class CallBrInst;            // For getting `Val`.
-  friend class LandingPadInst;        // For getting `Val`.
-  friend class FuncletPadInst;        // For getting `Val`.
-  friend class CatchPadInst;          // For getting `Val`.
-  friend class CleanupPadInst;        // For getting `Val`.
-  friend class CatchReturnInst;       // For getting `Val`.
-  friend class GetElementPtrInst;     // For getting `Val`.
-  friend class ResumeInst;            // For getting `Val`.
-  friend class CatchSwitchInst;       // For getting `Val`.
-  friend class CleanupReturnInst;     // For getting `Val`.
-  friend class SwitchInst;            // For getting `Val`.
-  friend class UnaryOperator;         // For getting `Val`.
-  friend class BinaryOperator;        // For getting `Val`.
-  friend class AtomicRMWInst;         // For getting `Val`.
-  friend class AtomicCmpXchgInst;     // For getting `Val`.
-  friend class AllocaInst;            // For getting `Val`.
-  friend class CastInst;              // For getting `Val`.
-  friend class PHINode;               // For getting `Val`.
-  friend class UnreachableInst;       // For getting `Val`.
-  friend class CatchSwitchAddHandler; // For `Val`.
-  friend class CmpInst;               // For getting `Val`.
-  friend class ConstantArray;         // For `Val`.
-  friend class ConstantStruct;        // For `Val`.
-  friend class ConstantVector;        // For `Val`.
-  friend class ConstantAggregateZero; // For `Val`.
-  friend class ConstantPointerNull;   // For `Val`.
-  friend class UndefValue;            // For `Val`.
-  friend class PoisonValue;           // For `Val`.
-  friend class BlockAddress;          // For `Val`.
-  friend class GlobalValue;           // For `Val`.
-  friend class DSOLocalEquivalent;    // For `Val`.
-  friend class GlobalObject;          // For `Val`.
-  friend class GlobalIFunc;           // For `Val`.
-  friend class GlobalVariable;        // For `Val`.
-  friend class GlobalAlias;           // For `Val`.
-  friend class NoCFIValue;            // For `Val`.
-  friend class ConstantPtrAuth;       // For `Val`.
-  friend class ConstantExpr;          // For `Val`.
-  friend class Utils;                 // For `Val`.
-  friend class Module;                // For `Val`.
-  friend class IntrinsicInst;         // For `Val`.
-  friend class Operator;              // For `Val`.
-  friend class OverflowingBinaryOperator; // For `Val`.
-  friend class FPMathOperator;            // For `Val`.
-  // Region needs to manipulate metadata in the underlying LLVM Value, we don't
-  // expose metadata in sandboxir.
-  friend class Region;
-  friend class ScoreBoard; // Needs access to `Val` for the instruction cost.
-  friend class ConstantDataArray; // For `Val`
-  friend class ConstantDataVector; // For `Val`
-
-  /// All values point to the context.
-  Context &Ctx;
-  // This is used by eraseFromParent().
-  void clearValue() { Val = nullptr; }
-  template <typename ItTy, typename SBTy> friend class LLVMOpUserItToSBTy;
-
-  LLVM_ABI Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx);
-  /// Disable copies.
-  Value(const Value &) = delete;
-  Value &operator=(const Value &) = delete;
-
-public:
-  virtual ~Value() = default;
-  ClassID getSubclassID() const { return SubclassID; }
-
-  using use_iterator = UserUseIterator;
-  using const_use_iterator = UserUseIterator;
-
-  LLVM_ABI use_iterator use_begin();
-  const_use_iterator use_begin() const {
-    return const_cast<Value *>(this)->use_begin();
-  }
-  use_iterator use_end() { return use_iterator(Use(nullptr, nullptr, Ctx)); }
-  const_use_iterator use_end() const {
-    return const_cast<Value *>(this)->use_end();
-  }
-
-  iterator_range<use_iterator> uses() {
-    return make_range<use_iterator>(use_begin(), use_end());
-  }
-  iterator_range<const_use_iterator> uses() const {
-    return make_range<const_use_iterator>(use_begin(), use_end());
-  }
-
-  /// Helper for mapped_iterator.
-  struct UseToUser {
-    User *operator()(const Use &Use) const { return &*Use.getUser(); }
-  };
-
-  using user_iterator = mapped_iterator<sandboxir::UserUseIterator, UseToUser>;
-  using const_user_iterator = user_iterator;
-
-  LLVM_ABI user_iterator user_begin();
-  user_iterator user_end() {
-    return user_iterator(Use(nullptr, nullptr, Ctx), UseToUser());
-  }
-  const_user_iterator user_begin() const {
-    return const_cast<Value *>(this)->user_begin();
-  }
-  const_user_iterator user_end() const {
-    return const_cast<Value *>(this)->user_end();
-  }
-
-  iterator_range<user_iterator> users() {
-    return make_range<user_iterator>(user_begin(), user_end());
-  }
-  iterator_range<const_user_iterator> users() const {
-    return make_range<const_user_iterator>(user_begin(), user_end());
-  }
-  /// \Returns the number of user edges (not necessarily to unique users).
-  /// WARNING: This is a linear-time operation.
-  LLVM_ABI unsigned getNumUses() const;
-  /// Return true if this value has N uses or more.
-  /// This is logically equivalent to getNumUses() >= N.
-  /// WARNING: This can be expensive, as it is linear to the number of users.
-  bool hasNUsesOrMore(unsigned Num) const {
-    unsigned Cnt = 0;
-    for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
-      if (++Cnt >= Num)
-        return true;
-    }
-    return false;
-  }
-  /// Return true if this Value has exactly N uses.
-  bool hasNUses(unsigned Num) const {
-    unsigned Cnt = 0;
-    for (auto It = use_begin(), ItE = use_end(); It != ItE; ++It) {
-      if (++Cnt > Num)
-        return false;
-    }
-    return Cnt == Num;
-  }
-
-  LLVM_ABI Type *getType() const;
-
-  Context &getContext() const { return Ctx; }
-
-  LLVM_ABI void
-  replaceUsesWithIf(Value *OtherV,
-                    llvm::function_ref<bool(const Use &)> ShouldReplace);
-  LLVM_ABI void replaceAllUsesWith(Value *Other);
-
-  /// \Returns the LLVM IR name of the bottom-most LLVM value.
-  StringRef getName() const { return Val->getName(); }
-
-#ifndef NDEBUG
-  /// Should crash if there is something wrong with the instruction.
-  virtual void verify() const = 0;
-  /// Returns the unique id in the form 'SB<number>.' like 'SB1.'
-  std::string getUid() const;
-  virtual void dumpCommonHeader(raw_ostream &OS) const;
-  void dumpCommonFooter(raw_ostream &OS) const;
-  void dumpCommonPrefix(raw_ostream &OS) const;
-  void dumpCommonSuffix(raw_ostream &OS) const;
-  void printAsOperandCommon(raw_ostream &OS) const;
-  friend raw_ostream &operator<<(raw_ostream &OS, const sandboxir::Value &V) {
-    V.dumpOS(OS);
-    return OS;
-  }
-  virtual void dumpOS(raw_ostream &OS) const = 0;
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-class OpaqueValue : public Value {
-protected:
-  OpaqueValue(llvm::Value *V, Context &Ctx)
-      : Value(ClassID::OpaqueValue, V, Ctx) {}
-  friend class Context; // For constructor.
-
-public:
-  static bool classof(const Value *From) {
-    return From->getSubclassID() == ClassID::OpaqueValue;
-  }
-#ifndef NDEBUG
-  void verify() const override {
-    assert((isa<llvm::MetadataAsValue>(Val) || isa<llvm::InlineAsm>(Val)) &&
-           "Expected Metadata or InlineAssembly!");
-  }
-  void dumpOS(raw_ostream &OS) const override {
-    dumpCommonPrefix(OS);
-    dumpCommonSuffix(OS);
-  }
-#endif // NDEBUG
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_SANDBOXIR_VALUE_H
diff --git a/llvm/include/llvm/SandboxIR/Values.def b/llvm/include/llvm/SandboxIR/Values.def
deleted file mode 100644
index 72683e4c4d3f8..0000000000000
--- a/llvm/include/llvm/SandboxIR/Values.def
+++ /dev/null
@@ -1,154 +0,0 @@
-//===- Values.def -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-//    ClassID, Class
-#ifndef DEF_VALUE
-#define DEF_VALUE(ID, CLASS)
-#endif
-
-#ifndef DEF_USER
-#define DEF_USER(ID, CLASS)
-#endif
-
-#ifndef DEF_CONST
-#define DEF_CONST(ID, CLASS)
-#endif
-
-DEF_CONST(Function, Function)
-DEF_VALUE(Argument, Argument)
-DEF_VALUE(OpaqueValue, OpaqueValue)
-
-DEF_USER(User, User)
-DEF_VALUE(Block, BasicBlock)
-DEF_CONST(Constant, Constant)
-DEF_CONST(ConstantInt, ConstantInt)
-DEF_CONST(ConstantFP, ConstantFP)
-DEF_CONST(ConstantDataArray, ConstantDataArray)
-DEF_CONST(ConstantDataVector, ConstantDataVector)
-DEF_CONST(ConstantArray, ConstantArray)
-DEF_CONST(ConstantStruct, ConstantStruct)
-DEF_CONST(ConstantVector, ConstantVector)
-DEF_CONST(ConstantAggregateZero, ConstantAggregateZero)
-DEF_CONST(ConstantPointerNull, ConstantPointerNull)
-DEF_CONST(UndefValue, UndefValue)
-DEF_CONST(PoisonValue, PoisonValue)
-DEF_CONST(GlobalVariable, GlobalVariable)
-DEF_CONST(GlobalIFunc, GlobalIFunc)
-DEF_CONST(GlobalAlias, GlobalAlias)
-DEF_CONST(BlockAddress, BlockAddress)
-DEF_CONST(NoCFIValue, NoCFIValue)
-DEF_CONST(ConstantPtrAuth, ConstantPtrAuth)
-DEF_CONST(ConstantExpr, ConstantExpr)
-DEF_CONST(DSOLocalEquivalent, DSOLocalEquivalent)
-DEF_CONST(ConstantTokenNone, ConstantTokenNone)
-
-#ifndef DEF_INSTR
-#define DEF_INSTR(ID, OPCODE, CLASS)
-#endif
-
-#ifndef OP
-#define OP(OPCODE)
-#endif
-
-#ifndef OPCODES
-#define OPCODES(...)
-#endif
-// clang-format off
-//        ClassID,        Opcode(s),          Class
-DEF_INSTR(Opaque,         OP(Opaque),         OpaqueInst)
-DEF_INSTR(ExtractElement, OP(ExtractElement), ExtractElementInst)
-DEF_INSTR(InsertElement,  OP(InsertElement),  InsertElementInst)
-DEF_INSTR(VAArg,          OP(VAArg),          VAArgInst)
-DEF_INSTR(Freeze,         OP(Freeze),         FreezeInst)
-DEF_INSTR(Fence,          OP(Fence),          FenceInst)
-DEF_INSTR(ShuffleVector,  OP(ShuffleVector),  ShuffleVectorInst)
-DEF_INSTR(ExtractValue,   OP(ExtractValue),   ExtractValueInst)
-DEF_INSTR(InsertValue,    OP(InsertValue),    InsertValueInst)
-DEF_INSTR(Select,         OP(Select),         SelectInst)
-DEF_INSTR(Br,             OP(Br),             BranchInst)
-DEF_INSTR(Load,           OP(Load),           LoadInst)
-DEF_INSTR(Store,          OP(Store),          StoreInst)
-DEF_INSTR(Ret,            OP(Ret),            ReturnInst)
-DEF_INSTR(Call,           OP(Call),           CallInst)
-DEF_INSTR(Invoke,         OP(Invoke),         InvokeInst)
-DEF_INSTR(CallBr,         OP(CallBr),         CallBrInst)
-DEF_INSTR(LandingPad,     OP(LandingPad),     LandingPadInst)
-DEF_INSTR(CatchPad,       OP(CatchPad),       CatchPadInst)
-DEF_INSTR(CleanupPad,     OP(CleanupPad),     CleanupPadInst)
-DEF_INSTR(CatchRet,       OP(CatchRet),       CatchReturnInst)
-DEF_INSTR(CleanupRet,     OP(CleanupRet),     CleanupReturnInst)
-DEF_INSTR(GetElementPtr,  OP(GetElementPtr),  GetElementPtrInst)
-DEF_INSTR(Resume,         OP(Resume),         ResumeInst)
-DEF_INSTR(CatchSwitch,    OP(CatchSwitch),    CatchSwitchInst)
-DEF_INSTR(Switch,         OP(Switch),         SwitchInst)
-DEF_INSTR(UnOp,           OPCODES( \
-                          OP(FNeg) \
-                          ),                  UnaryOperator)
-DEF_INSTR(BinaryOperator, OPCODES(\
-                          OP(Add)  \
-                          OP(FAdd) \
-                          OP(Sub)  \
-                          OP(FSub) \
-                          OP(Mul)  \
-                          OP(FMul) \
-                          OP(UDiv) \
-                          OP(SDiv) \
-                          OP(FDiv) \
-                          OP(URem) \
-                          OP(SRem) \
-                          OP(FRem) \
-                          OP(Shl)  \
-                          OP(LShr) \
-                          OP(AShr) \
-                          OP(And)  \
-                          OP(Or)   \
-                          OP(Xor)  \
-                          ),                  BinaryOperator)
-DEF_INSTR(AtomicRMW,      OP(AtomicRMW),      AtomicRMWInst)
-DEF_INSTR(AtomicCmpXchg,  OP(AtomicCmpXchg),  AtomicCmpXchgInst)
-DEF_INSTR(Alloca,         OP(Alloca),         AllocaInst)
-DEF_INSTR(Cast,   OPCODES(\
-                          OP(ZExt)          \
-                          OP(SExt)          \
-                          OP(FPToUI)        \
-                          OP(FPToSI)        \
-                          OP(FPExt)         \
-                          OP(PtrToAddr)     \
-                          OP(PtrToInt)      \
-                          OP(IntToPtr)      \
-                          OP(SIToFP)        \
-                          OP(UIToFP)        \
-                          OP(Trunc)         \
-                          OP(FPTrunc)       \
-                          OP(BitCast)       \
-                          OP(AddrSpaceCast) \
-                          ),                  CastInst)
-DEF_INSTR(PHI,            OP(PHI),            PHINode)
-DEF_INSTR(Unreachable,    OP(Unreachable),    UnreachableInst)
-DEF_INSTR(ICmp,           OP(ICmp),          FCmpInst)
-DEF_INSTR(FCmp,           OP(FCmp),          ICmpInst)
-
-// clang-format on
-#ifdef DEF_VALUE
-#undef DEF_VALUE
-#endif
-#ifdef DEF_USER
-#undef DEF_USER
-#endif
-#ifdef DEF_CONST
-#undef DEF_CONST
-#endif
-#ifdef DEF_INSTR
-#undef DEF_INSTR
-#endif
-#ifdef OP
-#undef OP
-#endif
-#ifdef OPCODES
-#undef OPCODES
-#endif
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h
deleted file mode 100644
index 85b25c0249e7d..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h
+++ /dev/null
@@ -1,21 +0,0 @@
-//===- Debug.h --------------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Defines the DEBUG_TYPE macro for LLVM_DEBUG which is shared across the
-// vectorizer components.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEBUG_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEBUG_H
-
-#include "llvm/Support/Debug.h"
-
-#define DEBUG_TYPE "sandbox-vectorizer"
-#define DEBUG_PREFIX "SBVec: "
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEBUG_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h
deleted file mode 100644
index 588a6eb298470..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h
+++ /dev/null
@@ -1,469 +0,0 @@
-//===- DependencyGraph.h ----------------------------------------*- 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 file declares the dependency graph used by the vectorizer's instruction
-// scheduler.
-//
-// The nodes of the graph are objects of the `DGNode` class. Each `DGNode`
-// object points to an instruction.
-// The edges between `DGNode`s are implicitly defined by an ordered set of
-// predecessor nodes, to save memory.
-// Finally the whole dependency graph is an object of the `DependencyGraph`
-// class, which also provides the API for creating/extending the graph from
-// input Sandbox IR.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
-
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/IntrinsicInst.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
-
-namespace llvm::sandboxir {
-
-class DependencyGraph;
-class MemDGNode;
-class SchedBundle;
-
-/// SubclassIDs for isa/dyn_cast etc.
-enum class DGNodeID {
-  DGNode,
-  MemDGNode,
-};
-
-class DGNode;
-class MemDGNode;
-class DependencyGraph;
-
-// Defined in Transforms/Vectorize/SandboxVectorizer/Interval.cpp
-extern template class LLVM_TEMPLATE_ABI Interval<MemDGNode>;
-
-/// Iterate over both def-use and mem dependencies.
-class PredIterator {
-  User::op_iterator OpIt;
-  User::op_iterator OpItE;
-  DenseSet<MemDGNode *>::iterator MemIt;
-  DGNode *N = nullptr;
-  DependencyGraph *DAG = nullptr;
-
-  PredIterator(const User::op_iterator &OpIt, const User::op_iterator &OpItE,
-               const DenseSet<MemDGNode *>::iterator &MemIt, DGNode *N,
-               DependencyGraph &DAG)
-      : OpIt(OpIt), OpItE(OpItE), MemIt(MemIt), N(N), DAG(&DAG) {}
-  PredIterator(const User::op_iterator &OpIt, const User::op_iterator &OpItE,
-               DGNode *N, DependencyGraph &DAG)
-      : OpIt(OpIt), OpItE(OpItE), N(N), DAG(&DAG) {}
-  friend class DGNode;    // For constructor
-  friend class MemDGNode; // For constructor
-
-  /// Skip iterators that don't point instructions or are outside \p DAG,
-  /// starting from \p OpIt and ending before \p OpItE.n
-  LLVM_ABI static User::op_iterator skipBadIt(User::op_iterator OpIt,
-                                              User::op_iterator OpItE,
-                                              const DependencyGraph &DAG);
-
-public:
-  using difference_type = std::ptrdiff_t;
-  using value_type = DGNode *;
-  using pointer = value_type *;
-  using reference = value_type &;
-  using iterator_category = std::input_iterator_tag;
-  LLVM_ABI value_type operator*();
-  LLVM_ABI PredIterator &operator++();
-  PredIterator operator++(int) {
-    auto Copy = *this;
-    ++(*this);
-    return Copy;
-  }
-  LLVM_ABI bool operator==(const PredIterator &Other) const;
-  bool operator!=(const PredIterator &Other) const { return !(*this == Other); }
-};
-
-/// A DependencyGraph Node that points to an Instruction and contains memory
-/// dependency edges.
-class LLVM_ABI DGNode {
-protected:
-  Instruction *I;
-  // TODO: Use a PointerIntPair for SubclassID and I.
-  /// For isa/dyn_cast etc.
-  DGNodeID SubclassID;
-  /// The number of unscheduled successors.
-  unsigned UnscheduledSuccs = 0;
-  /// This is true if this node has been scheduled.
-  bool Scheduled = false;
-  /// The scheduler bundle that this node belongs to.
-  SchedBundle *SB = nullptr;
-
-  void setSchedBundle(SchedBundle &SB);
-  void clearSchedBundle() { this->SB = nullptr; }
-  friend class SchedBundle; // For setSchedBundle(), clearSchedBundle().
-
-  DGNode(Instruction *I, DGNodeID ID) : I(I), SubclassID(ID) {}
-  friend class MemDGNode;       // For constructor.
-  friend class DependencyGraph; // For UnscheduledSuccs
-
-public:
-  DGNode(Instruction *I) : I(I), SubclassID(DGNodeID::DGNode) {
-    assert(!isMemDepNodeCandidate(I) && "Expected Non-Mem instruction, ");
-  }
-  DGNode(const DGNode &Other) = delete;
-  virtual ~DGNode();
-  /// \Returns the number of unscheduled successors.
-  unsigned getNumUnscheduledSuccs() const { return UnscheduledSuccs; }
-  // TODO: Make this private?
-  void decrUnscheduledSuccs() {
-    assert(UnscheduledSuccs > 0 && "Counting error!");
-    --UnscheduledSuccs;
-  }
-  void incrUnscheduledSuccs() { ++UnscheduledSuccs; }
-  void resetScheduleState() {
-    UnscheduledSuccs = 0;
-    Scheduled = false;
-  }
-  /// \Returns true if all dependent successors have been scheduled.
-  bool ready() const { return UnscheduledSuccs == 0; }
-  /// \Returns true if this node has been scheduled.
-  bool scheduled() const { return Scheduled; }
-  void setScheduled(bool NewVal) { Scheduled = NewVal; }
-  /// \Returns the scheduling bundle that this node belongs to, or nullptr.
-  SchedBundle *getSchedBundle() const { return SB; }
-  /// \Returns true if this is before \p Other in program order.
-  bool comesBefore(const DGNode *Other) { return I->comesBefore(Other->I); }
-  using iterator = PredIterator;
-  virtual iterator preds_begin(DependencyGraph &DAG) {
-    return PredIterator(
-        PredIterator::skipBadIt(I->op_begin(), I->op_end(), DAG), I->op_end(),
-        this, DAG);
-  }
-  virtual iterator preds_end(DependencyGraph &DAG) {
-    return PredIterator(I->op_end(), I->op_end(), this, DAG);
-  }
-  iterator preds_begin(DependencyGraph &DAG) const {
-    return const_cast<DGNode *>(this)->preds_begin(DAG);
-  }
-  iterator preds_end(DependencyGraph &DAG) const {
-    return const_cast<DGNode *>(this)->preds_end(DAG);
-  }
-  /// \Returns a range of DAG predecessors nodes. If this is a MemDGNode then
-  /// this will also include the memory dependency predecessors.
-  /// Please note that this can include the same node more than once, if for
-  /// example it's both a use-def predecessor and a mem dep predecessor.
-  iterator_range<iterator> preds(DependencyGraph &DAG) const {
-    return make_range(preds_begin(DAG), preds_end(DAG));
-  }
-
-  static bool isStackSaveOrRestoreIntrinsic(Instruction *I) {
-    if (auto *II = dyn_cast<IntrinsicInst>(I)) {
-      auto IID = II->getIntrinsicID();
-      return IID == Intrinsic::stackrestore || IID == Intrinsic::stacksave;
-    }
-    return false;
-  }
-
-  /// \Returns true if intrinsic \p I touches memory. This is used by the
-  /// dependency graph.
-  static bool isMemIntrinsic(IntrinsicInst *I) {
-    auto IID = I->getIntrinsicID();
-    return IID != Intrinsic::sideeffect && IID != Intrinsic::pseudoprobe;
-  }
-
-  /// We consider \p I as a Memory Dependency Candidate instruction if it
-  /// reads/write memory or if it has side-effects. This is used by the
-  /// dependency graph.
-  static bool isMemDepCandidate(Instruction *I) {
-    IntrinsicInst *II;
-    return I->mayReadOrWriteMemory() &&
-           (!(II = dyn_cast<IntrinsicInst>(I)) || isMemIntrinsic(II));
-  }
-
-  /// \Returns true if \p I is fence like. It excludes non-mem intrinsics.
-  static bool isFenceLike(Instruction *I) {
-    IntrinsicInst *II;
-    return I->isFenceLike() &&
-           (!(II = dyn_cast<IntrinsicInst>(I)) || isMemIntrinsic(II));
-  }
-
-  /// \Returns true if \p I is a memory dependency candidate instruction.
-  static bool isMemDepNodeCandidate(Instruction *I) {
-    AllocaInst *Alloca;
-    return isMemDepCandidate(I) ||
-           ((Alloca = dyn_cast<AllocaInst>(I)) &&
-            Alloca->isUsedWithInAlloca()) ||
-           isStackSaveOrRestoreIntrinsic(I) || isFenceLike(I);
-  }
-
-  Instruction *getInstruction() const { return I; }
-
-#ifndef NDEBUG
-  virtual void print(raw_ostream &OS, bool PrintDeps = true) const;
-  friend raw_ostream &operator<<(raw_ostream &OS, DGNode &N) {
-    N.print(OS);
-    return OS;
-  }
-  LLVM_DUMP_METHOD void dump() const;
-#endif // NDEBUG
-};
-
-/// A DependencyGraph Node for instructions that may read/write memory, or have
-/// some ordering constraints, like with stacksave/stackrestore and
-/// alloca/inalloca.
-class MemDGNode final : public DGNode {
-  MemDGNode *PrevMemN = nullptr;
-  MemDGNode *NextMemN = nullptr;
-  /// Memory predecessors.
-  DenseSet<MemDGNode *> MemPreds;
-  /// Memory successors.
-  DenseSet<MemDGNode *> MemSuccs;
-  friend class PredIterator; // For MemPreds.
-  /// Creates both edges: this<->N.
-  void setNextNode(MemDGNode *N) {
-    assert(N != this && "About to point to self!");
-    NextMemN = N;
-    if (NextMemN != nullptr)
-      NextMemN->PrevMemN = this;
-  }
-  /// Creates both edges: N<->this.
-  void setPrevNode(MemDGNode *N) {
-    assert(N != this && "About to point to self!");
-    PrevMemN = N;
-    if (PrevMemN != nullptr)
-      PrevMemN->NextMemN = this;
-  }
-  friend class DependencyGraph; // For setNextNode(), setPrevNode().
-  void detachFromChain() {
-    if (PrevMemN != nullptr)
-      PrevMemN->NextMemN = NextMemN;
-    if (NextMemN != nullptr)
-      NextMemN->PrevMemN = PrevMemN;
-    PrevMemN = nullptr;
-    NextMemN = nullptr;
-  }
-
-public:
-  MemDGNode(Instruction *I) : DGNode(I, DGNodeID::MemDGNode) {
-    assert(isMemDepNodeCandidate(I) && "Expected Mem instruction!");
-  }
-  static bool classof(const DGNode *Other) {
-    return Other->SubclassID == DGNodeID::MemDGNode;
-  }
-  iterator preds_begin(DependencyGraph &DAG) override {
-    auto OpEndIt = I->op_end();
-    return PredIterator(PredIterator::skipBadIt(I->op_begin(), OpEndIt, DAG),
-                        OpEndIt, MemPreds.begin(), this, DAG);
-  }
-  iterator preds_end(DependencyGraph &DAG) override {
-    return PredIterator(I->op_end(), I->op_end(), MemPreds.end(), this, DAG);
-  }
-  /// \Returns the previous Mem DGNode in instruction order.
-  MemDGNode *getPrevNode() const { return PrevMemN; }
-  /// \Returns the next Mem DGNode in instruction order.
-  MemDGNode *getNextNode() const { return NextMemN; }
-  /// Adds the mem dependency edge PredN->this. This also increments the
-  /// UnscheduledSuccs counter of the predecessor if this node has not been
-  /// scheduled.
-  void addMemPred(MemDGNode *PredN) {
-    [[maybe_unused]] auto Inserted = MemPreds.insert(PredN).second;
-    assert(Inserted && "PredN already exists!");
-    assert(PredN != this && "Trying to add a dependency to self!");
-    PredN->MemSuccs.insert(this);
-    if (!Scheduled) {
-      ++PredN->UnscheduledSuccs;
-    }
-  }
-  /// Removes the memory dependency PredN->this. This also updates the
-  /// UnscheduledSuccs counter of PredN if this node has not been scheduled.
-  void removeMemPred(MemDGNode *PredN) {
-    MemPreds.erase(PredN);
-    PredN->MemSuccs.erase(this);
-    if (!Scheduled) {
-      PredN->decrUnscheduledSuccs();
-    }
-  }
-  /// \Returns true if there is a memory dependency N->this.
-  bool hasMemPred(DGNode *N) const {
-    if (auto *MN = dyn_cast<MemDGNode>(N))
-      return MemPreds.count(MN);
-    return false;
-  }
-  /// \Returns all memory dependency predecessors. Used by tests.
-  iterator_range<DenseSet<MemDGNode *>::const_iterator> memPreds() const {
-    return make_range(MemPreds.begin(), MemPreds.end());
-  }
-  /// \Returns all memory dependency successors.
-  iterator_range<DenseSet<MemDGNode *>::const_iterator> memSuccs() const {
-    return make_range(MemSuccs.begin(), MemSuccs.end());
-  }
-#ifndef NDEBUG
-  void print(raw_ostream &OS, bool PrintDeps = true) const override;
-#endif // NDEBUG
-};
-
-/// Convenience builders for a MemDGNode interval.
-class MemDGNodeIntervalBuilder {
-public:
-  /// Scans the instruction chain in \p Intvl top-down, returning the top-most
-  /// MemDGNode, or nullptr.
-  LLVM_ABI static MemDGNode *getTopMemDGNode(const Interval<Instruction> &Intvl,
-                                             const DependencyGraph &DAG);
-  /// Scans the instruction chain in \p Intvl bottom-up, returning the
-  /// bottom-most MemDGNode, or nullptr.
-  LLVM_ABI static MemDGNode *getBotMemDGNode(const Interval<Instruction> &Intvl,
-                                             const DependencyGraph &DAG);
-  /// Given \p Instrs it finds their closest mem nodes in the interval and
-  /// returns the corresponding mem range. Note: BotN (or its neighboring mem
-  /// node) is included in the range.
-  LLVM_ABI static Interval<MemDGNode> make(const Interval<Instruction> &Instrs,
-                                           DependencyGraph &DAG);
-  static Interval<MemDGNode> makeEmpty() { return {}; }
-};
-
-class DependencyGraph {
-private:
-  DenseMap<Instruction *, std::unique_ptr<DGNode>> InstrToNodeMap;
-  /// The DAG spans across all instructions in this interval.
-  Interval<Instruction> DAGInterval;
-
-  Context *Ctx = nullptr;
-  std::optional<Context::CallbackID> CreateInstrCB;
-  std::optional<Context::CallbackID> EraseInstrCB;
-  std::optional<Context::CallbackID> MoveInstrCB;
-  std::optional<Context::CallbackID> SetUseCB;
-
-  std::unique_ptr<BatchAAResults> BatchAA;
-
-  enum class DependencyType {
-    ReadAfterWrite,  ///> Memory dependency write -> read
-    WriteAfterWrite, ///> Memory dependency write -> write
-    WriteAfterRead,  ///> Memory dependency read -> write
-    Control,         ///> Control-related dependency, like with PHI/Terminator
-    Other,           ///> Currently used for stack related instrs
-    None,            ///> No memory/other dependency
-  };
-  /// \Returns the dependency type depending on whether instructions may
-  /// read/write memory or whether they are some specific opcode-related
-  /// restrictions.
-  /// Note: It does not check whether a memory dependency is actually correct,
-  /// as it won't call AA. Therefore it returns the worst-case dep type.
-  static DependencyType getRoughDepType(Instruction *FromI, Instruction *ToI);
-
-  // TODO: Implement AABudget.
-  /// \Returns true if there is a memory/other dependency \p SrcI->DstI.
-  bool alias(Instruction *SrcI, Instruction *DstI, DependencyType DepType);
-
-  bool hasDep(sandboxir::Instruction *SrcI, sandboxir::Instruction *DstI);
-
-  /// Go through all mem nodes in \p SrcScanRange and try to add dependencies to
-  /// \p DstN.
-  void scanAndAddDeps(MemDGNode &DstN, const Interval<MemDGNode> &SrcScanRange);
-
-  /// Sets the UnscheduledSuccs of all DGNodes in \p NewInterval based on
-  /// def-use edges.
-  void setDefUseUnscheduledSuccs(const Interval<Instruction> &NewInterval);
-
-  /// Create DAG nodes for instrs in \p NewInterval and update the MemNode
-  /// chain.
-  void createNewNodes(const Interval<Instruction> &NewInterval);
-
-  /// Helper for `notify*Instr()`. \Returns the first MemDGNode that comes
-  /// before \p N, skipping \p SkipN, including or excluding \p N based on
-  /// \p IncludingN, or nullptr if not found.
-  MemDGNode *getMemDGNodeBefore(DGNode *N, bool IncludingN,
-                                MemDGNode *SkipN = nullptr) const;
-  /// Helper for `notifyMoveInstr()`. \Returns the first MemDGNode that comes
-  /// after \p N, skipping \p SkipN, including or excluding \p N based on \p
-  /// IncludingN, or nullptr if not found.
-  MemDGNode *getMemDGNodeAfter(DGNode *N, bool IncludingN,
-                               MemDGNode *SkipN = nullptr) const;
-
-  /// Called by the callbacks when a new instruction \p I has been created.
-  LLVM_ABI void notifyCreateInstr(Instruction *I);
-  /// Called by the callbacks when instruction \p I is about to get
-  /// deleted.
-  LLVM_ABI void notifyEraseInstr(Instruction *I);
-  /// Called by the callbacks when instruction \p I is about to be moved to
-  /// \p To.
-  LLVM_ABI void notifyMoveInstr(Instruction *I, const BBIterator &To);
-  /// Called by the callbacks when \p U's source is about to be set to \p NewSrc
-  LLVM_ABI void notifySetUse(const Use &U, Value *NewSrc);
-
-public:
-  /// This constructor also registers callbacks.
-  DependencyGraph(AAResults &AA, Context &Ctx)
-      : Ctx(&Ctx), BatchAA(std::make_unique<BatchAAResults>(AA)) {
-    CreateInstrCB = Ctx.registerCreateInstrCallback(
-        [this](Instruction *I) { notifyCreateInstr(I); });
-    EraseInstrCB = Ctx.registerEraseInstrCallback(
-        [this](Instruction *I) { notifyEraseInstr(I); });
-    MoveInstrCB = Ctx.registerMoveInstrCallback(
-        [this](Instruction *I, const BBIterator &To) {
-          notifyMoveInstr(I, To);
-        });
-    SetUseCB = Ctx.registerSetUseCallback(
-        [this](const Use &U, Value *NewSrc) { notifySetUse(U, NewSrc); });
-  }
-  ~DependencyGraph() {
-    if (CreateInstrCB)
-      Ctx->unregisterCreateInstrCallback(*CreateInstrCB);
-    if (EraseInstrCB)
-      Ctx->unregisterEraseInstrCallback(*EraseInstrCB);
-    if (MoveInstrCB)
-      Ctx->unregisterMoveInstrCallback(*MoveInstrCB);
-    if (SetUseCB)
-      Ctx->unregisterSetUseCallback(*SetUseCB);
-  }
-
-  DGNode *getNode(Instruction *I) const {
-    auto It = InstrToNodeMap.find(I);
-    return It != InstrToNodeMap.end() ? It->second.get() : nullptr;
-  }
-  /// Like getNode() but returns nullptr if \p I is nullptr.
-  DGNode *getNodeOrNull(Instruction *I) const {
-    if (I == nullptr)
-      return nullptr;
-    return getNode(I);
-  }
-  DGNode *getOrCreateNode(Instruction *I) {
-    auto [It, NotInMap] = InstrToNodeMap.try_emplace(I);
-    if (NotInMap) {
-      if (DGNode::isMemDepNodeCandidate(I))
-        It->second = std::make_unique<MemDGNode>(I);
-      else
-        It->second = std::make_unique<DGNode>(I);
-    }
-    return It->second.get();
-  }
-  /// Build/extend the dependency graph such that it includes \p Instrs. Returns
-  /// the range of instructions added to the DAG.
-  LLVM_ABI Interval<Instruction> extend(ArrayRef<Instruction *> Instrs);
-  /// \Returns the range of instructions included in the DAG.
-  Interval<Instruction> getInterval() const { return DAGInterval; }
-  void clear() {
-    InstrToNodeMap.clear();
-    DAGInterval = {};
-  }
-#ifndef NDEBUG
-  /// \Returns true if the DAG's state is clear. Used in assertions.
-  bool empty() const {
-    bool IsEmpty = InstrToNodeMap.empty();
-    assert(IsEmpty == DAGInterval.empty() &&
-           "Interval and InstrToNodeMap out of sync!");
-    return IsEmpty;
-  }
-  void print(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif // NDEBUG
-};
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_DEPENDENCYGRAPH_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
deleted file mode 100644
index 4385df518a111..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h
+++ /dev/null
@@ -1,110 +0,0 @@
-//===- InstrMaps.h ----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVEC_PASSES_INSTRMAPS_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVEC_PASSES_INSTRMAPS_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-#include <algorithm>
-
-namespace llvm::sandboxir {
-
-class LegalityResult;
-
-struct Action {
-  unsigned Idx = 0;
-  const LegalityResult *LegalityRes = nullptr;
-  SmallVector<Value *, 4> Bndl;
-  SmallVector<Value *> UserBndl;
-  unsigned Depth;
-  SmallVector<Action *> Operands;
-  Value *Vec = nullptr;
-  Action(const LegalityResult *LR, ArrayRef<Value *> B, ArrayRef<Value *> UB,
-         unsigned Depth)
-      : LegalityRes(LR), Bndl(B), UserBndl(UB), Depth(Depth) {}
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const;
-  void dump() const;
-  friend raw_ostream &operator<<(raw_ostream &OS, const Action &A) {
-    A.print(OS);
-    return OS;
-  }
-#endif // NDEBUG
-};
-
-/// Maps the original instructions to the vectorized instrs and the reverse.
-/// For now an original instr can only map to a single vector.
-class InstrMaps {
-  /// A map from the original values that got combined into vectors, to the
-  /// vectorization Action.
-  DenseMap<Value *, Action *> OrigToVectorMap;
-  /// A map from the vec Action to a map of the original value to its lane.
-  /// Please note that for constant vectors, there may multiple original values
-  /// with the same lane, as they may be coming from vectorizing different
-  /// original values.
-  DenseMap<Action *, DenseMap<Value *, unsigned>> VectorToOrigLaneMap;
-  std::optional<Context::CallbackID> EraseInstrCB;
-
-public:
-  InstrMaps() = default;
-  ~InstrMaps() = default;
-  /// \Returns the vector value that we got from vectorizing \p Orig, or
-  /// nullptr if not found.
-  Action *getVectorForOrig(Value *Orig) const {
-    auto It = OrigToVectorMap.find(Orig);
-    return It != OrigToVectorMap.end() ? It->second : nullptr;
-  }
-  /// \Returns the lane of \p Orig before it got vectorized into \p Vec, or
-  /// nullopt if not found.
-  std::optional<unsigned> getOrigLane(Action *Vec, Value *Orig) const {
-    auto It1 = VectorToOrigLaneMap.find(Vec);
-    if (It1 == VectorToOrigLaneMap.end())
-      return std::nullopt;
-    const auto &OrigToLaneMap = It1->second;
-    auto It2 = OrigToLaneMap.find(Orig);
-    if (It2 == OrigToLaneMap.end())
-      return std::nullopt;
-    return It2->second;
-  }
-  /// Update the map to reflect that \p Origs got vectorized into \p Vec.
-  void registerVector(ArrayRef<Value *> Origs, Action *Vec) {
-    auto &OrigToLaneMap = VectorToOrigLaneMap[Vec];
-    unsigned Lane = 0;
-    for (Value *Orig : Origs) {
-      auto Pair = OrigToVectorMap.try_emplace(Orig, Vec);
-      assert(Pair.second && "Orig already exists in the map!");
-      (void)Pair;
-      OrigToLaneMap[Orig] = Lane;
-      Lane += VecUtils::getNumLanes(Orig);
-    }
-  }
-  void clear() {
-    OrigToVectorMap.clear();
-    VectorToOrigLaneMap.clear();
-  }
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const {
-    OS << "OrigToVectorMap:\n";
-    for (auto [Orig, Vec] : OrigToVectorMap)
-      OS << *Orig << " : " << *Vec << "\n";
-  }
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVEC_PASSES_INSTRMAPS_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h
deleted file mode 100644
index 2524ed6d98e74..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h
+++ /dev/null
@@ -1,244 +0,0 @@
-//===- Interval.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// The Interval class is a generic interval of ordered objects that implement:
-// - T * T::getPrevNode()
-// - T * T::getNextNode()
-// - bool T::comesBefore(const T *) const
-//
-// This is currently used for Instruction intervals.
-// It provides an API for some basic operations on the interval, including some
-// simple set operations, like union, intersection and others.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-#include <iterator>
-#include <type_traits>
-
-namespace llvm::sandboxir {
-
-/// A simple iterator for iterating the interval.
-template <typename T, typename IntervalType> class IntervalIterator {
-  T *I;
-  IntervalType &R;
-
-public:
-  using difference_type = std::ptrdiff_t;
-  using value_type = T;
-  using pointer = value_type *;
-  using reference = T &;
-  using iterator_category = std::bidirectional_iterator_tag;
-
-  IntervalIterator(T *I, IntervalType &R) : I(I), R(R) {}
-  bool operator==(const IntervalIterator &Other) const {
-    assert(&R == &Other.R && "Iterators belong to different regions!");
-    return Other.I == I;
-  }
-  bool operator!=(const IntervalIterator &Other) const {
-    return !(*this == Other);
-  }
-  IntervalIterator &operator++() {
-    assert(I != nullptr && "already at end()!");
-    I = I->getNextNode();
-    return *this;
-  }
-  IntervalIterator operator++(int) {
-    auto ItCopy = *this;
-    ++*this;
-    return ItCopy;
-  }
-  IntervalIterator &operator--() {
-    // `I` is nullptr for end() when To is the BB terminator.
-    I = I != nullptr ? I->getPrevNode() : R.bottom();
-    return *this;
-  }
-  IntervalIterator operator--(int) {
-    auto ItCopy = *this;
-    --*this;
-    return ItCopy;
-  }
-  template <typename HT = std::enable_if<std::is_same<T, T *&>::value>>
-  T &operator*() {
-    return *I;
-  }
-  T &operator*() const { return *I; }
-};
-
-template <typename T> class Interval {
-  T *Top;
-  T *Bottom;
-
-public:
-  Interval() : Top(nullptr), Bottom(nullptr) {}
-  Interval(T *Top, T *Bottom) : Top(Top), Bottom(Bottom) {
-    assert((Top == Bottom || Top->comesBefore(Bottom)) &&
-           "Top should come before Bottom!");
-  }
-  Interval(ArrayRef<T *> Elems) {
-    assert(!Elems.empty() && "Expected non-empty Elems!");
-    Top = Elems[0];
-    Bottom = Elems[0];
-    for (auto *I : drop_begin(Elems)) {
-      if (I->comesBefore(Top))
-        Top = I;
-      else if (Bottom->comesBefore(I))
-        Bottom = I;
-    }
-  }
-  bool empty() const {
-    assert(((Top == nullptr && Bottom == nullptr) ||
-            (Top != nullptr && Bottom != nullptr)) &&
-           "Either none or both should be null");
-    return Top == nullptr;
-  }
-  bool contains(T *I) const {
-    if (empty())
-      return false;
-    return (Top == I || Top->comesBefore(I)) &&
-           (I == Bottom || I->comesBefore(Bottom));
-  }
-  /// \Returns true if \p Elm is right before the top or right after the bottom.
-  bool touches(T *Elm) const {
-    return Top == Elm->getNextNode() || Bottom == Elm->getPrevNode();
-  }
-  T *top() const { return Top; }
-  T *bottom() const { return Bottom; }
-
-  using iterator = IntervalIterator<T, Interval>;
-  iterator begin() { return iterator(Top, *this); }
-  iterator end() {
-    return iterator(Bottom != nullptr ? Bottom->getNextNode() : nullptr, *this);
-  }
-  iterator begin() const {
-    return iterator(Top, const_cast<Interval &>(*this));
-  }
-  iterator end() const {
-    return iterator(Bottom != nullptr ? Bottom->getNextNode() : nullptr,
-                    const_cast<Interval &>(*this));
-  }
-  /// Equality.
-  bool operator==(const Interval &Other) const {
-    return Top == Other.Top && Bottom == Other.Bottom;
-  }
-  /// Inequality.
-  bool operator!=(const Interval &Other) const { return !(*this == Other); }
-  /// \Returns true if this interval comes before \p Other in program order.
-  /// This expects disjoint intervals.
-  bool comesBefore(const Interval &Other) const {
-    assert(disjoint(Other) && "Expect disjoint intervals!");
-    return bottom()->comesBefore(Other.top());
-  }
-  /// \Returns true if this and \p Other have nothing in common.
-  bool disjoint(const Interval &Other) const;
-  /// \Returns the intersection between this and \p Other.
-  // Example:
-  // |----|   this
-  //    |---| Other
-  //    |-|   this->getIntersection(Other)
-  Interval intersection(const Interval &Other) const {
-    if (empty())
-      return *this;
-    if (Other.empty())
-      return Interval();
-    // 1. No overlap
-    // A---B      this
-    //       C--D Other
-    if (Bottom->comesBefore(Other.Top) || Other.Bottom->comesBefore(Top))
-      return Interval();
-    // 2. Overlap.
-    // A---B   this
-    //   C--D  Other
-    auto NewTopI = Top->comesBefore(Other.Top) ? Other.Top : Top;
-    auto NewBottomI = Bottom->comesBefore(Other.Bottom) ? Bottom : Other.Bottom;
-    return Interval(NewTopI, NewBottomI);
-  }
-  /// Difference operation. This returns up to two intervals.
-  // Example:
-  // |--------| this
-  //    |-|     Other
-  // |-|   |--| this - Other
-  SmallVector<Interval, 2> operator-(const Interval &Other) {
-    if (disjoint(Other))
-      return {*this};
-    if (Other.empty())
-      return {*this};
-    if (*this == Other)
-      return {Interval()};
-    Interval Intersection = intersection(Other);
-    SmallVector<Interval, 2> Result;
-    // Part 1, skip if empty.
-    if (Top != Intersection.Top)
-      Result.emplace_back(Top, Intersection.Top->getPrevNode());
-    // Part 2, skip if empty.
-    if (Intersection.Bottom != Bottom)
-      Result.emplace_back(Intersection.Bottom->getNextNode(), Bottom);
-    return Result;
-  }
-  /// \Returns the interval difference `this - Other`. This will crash in Debug
-  /// if the result is not a single interval.
-  Interval getSingleDiff(const Interval &Other) {
-    auto Diff = *this - Other;
-    assert(Diff.size() == 1 && "Expected a single interval!");
-    return Diff[0];
-  }
-  /// \Returns a single interval that spans across both this and \p Other.
-  // For example:
-  // |---|        this
-  //        |---| Other
-  // |----------| this->getUnionInterval(Other)
-  Interval getUnionInterval(const Interval &Other) {
-    if (empty())
-      return Other;
-    if (Other.empty())
-      return *this;
-    auto *NewTop = Top->comesBefore(Other.Top) ? Top : Other.Top;
-    auto *NewBottom = Bottom->comesBefore(Other.Bottom) ? Other.Bottom : Bottom;
-    return {NewTop, NewBottom};
-  }
-
-  /// Update the interval when \p I is about to be moved before \p Before.
-  // SFINAE disables this for non-Instructions.
-  template <typename HelperT = T>
-  std::enable_if_t<std::is_same<HelperT, Instruction>::value, void>
-  notifyMoveInstr(HelperT *I, decltype(I->getIterator()) BeforeIt) {
-    assert(contains(I) && "Expect `I` in interval!");
-    assert(I->getIterator() != BeforeIt && "Can't move `I` before itself!");
-
-    // Nothing to do if the instruction won't move.
-    if (std::next(I->getIterator()) == BeforeIt)
-      return;
-
-    T *NewTop = Top->getIterator() == BeforeIt ? I
-                : I == Top                     ? Top->getNextNode()
-                                               : Top;
-    T *NewBottom = std::next(Bottom->getIterator()) == BeforeIt ? I
-                   : I == Bottom ? Bottom->getPrevNode()
-                                 : Bottom;
-    Top = NewTop;
-    Bottom = NewBottom;
-  }
-
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-// Defined in Transforms/Vectorize/SandboxVectorizer/Interval.cpp
-extern template class LLVM_TEMPLATE_ABI Interval<Instruction>;
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_INSTRINTERVAL_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h
deleted file mode 100644
index 3d76cdaad6240..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//===- Legality.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Legality checks for the Sandbox Vectorizer.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_LEGALITY_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_LEGALITY_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h"
-
-namespace llvm::sandboxir {
-
-class LegalityAnalysis;
-class Value;
-class InstrMaps;
-
-class ShuffleMask {
-public:
-  using IndicesVecT = SmallVector<int, 8>;
-
-private:
-  IndicesVecT Indices;
-
-public:
-  ShuffleMask(SmallVectorImpl<int> &&Indices) : Indices(std::move(Indices)) {}
-  ShuffleMask(std::initializer_list<int> Indices) : Indices(Indices) {}
-  explicit ShuffleMask(ArrayRef<int> Indices) : Indices(Indices) {}
-  operator ArrayRef<int>() const { return Indices; }
-  /// Creates and returns an identity shuffle mask of size \p Sz.
-  /// For example if Sz == 4 the returned mask is {0, 1, 2, 3}.
-  static ShuffleMask getIdentity(unsigned Sz) {
-    IndicesVecT Indices;
-    Indices.reserve(Sz);
-    llvm::append_range(Indices, seq<int>(0, (int)Sz));
-    return ShuffleMask(std::move(Indices));
-  }
-  /// \Returns true if the mask is a perfect identity mask with consecutive
-  /// indices, i.e., performs no lane shuffling, like 0,1,2,3...
-  bool isIdentity() const {
-    for (auto [Idx, Elm] : enumerate(Indices)) {
-      if ((int)Idx != Elm)
-        return false;
-    }
-    return true;
-  }
-  bool operator==(const ShuffleMask &Other) const {
-    return Indices == Other.Indices;
-  }
-  bool operator!=(const ShuffleMask &Other) const { return !(*this == Other); }
-  size_t size() const { return Indices.size(); }
-  int operator[](int Idx) const { return Indices[Idx]; }
-  using const_iterator = IndicesVecT::const_iterator;
-  const_iterator begin() const { return Indices.begin(); }
-  const_iterator end() const { return Indices.end(); }
-#ifndef NDEBUG
-  friend raw_ostream &operator<<(raw_ostream &OS, const ShuffleMask &Mask) {
-    Mask.print(OS);
-    return OS;
-  }
-  void print(raw_ostream &OS) const {
-    interleave(Indices, OS, [&OS](auto Elm) { OS << Elm; }, ",");
-  }
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-enum class LegalityResultID {
-  Pack,                    ///> Collect scalar values.
-  Widen,                   ///> Vectorize by combining scalars to a vector.
-  DiamondReuse,            ///> Don't generate new code, reuse existing vector.
-  DiamondReuseWithShuffle, ///> Reuse the existing vector but add a shuffle.
-  DiamondReuseMultiInput,  ///> Reuse more than one vector and/or scalars.
-};
-
-/// The reason for vectorizing or not vectorizing.
-enum class ResultReason {
-  NotInstructions,
-  DiffOpcodes,
-  DiffTypes,
-  DiffMathFlags,
-  DiffWrapFlags,
-  DiffBBs,
-  RepeatedInstrs,
-  NotConsecutive,
-  CantSchedule,
-  Unimplemented,
-  Infeasible,
-  ForcePackForDebugging,
-};
-
-#ifndef NDEBUG
-struct ToStr {
-  static const char *getLegalityResultID(LegalityResultID ID) {
-    switch (ID) {
-    case LegalityResultID::Pack:
-      return "Pack";
-    case LegalityResultID::Widen:
-      return "Widen";
-    case LegalityResultID::DiamondReuse:
-      return "DiamondReuse";
-    case LegalityResultID::DiamondReuseWithShuffle:
-      return "DiamondReuseWithShuffle";
-    case LegalityResultID::DiamondReuseMultiInput:
-      return "DiamondReuseMultiInput";
-    }
-    llvm_unreachable("Unknown LegalityResultID enum");
-  }
-
-  static const char *getVecReason(ResultReason Reason) {
-    switch (Reason) {
-    case ResultReason::NotInstructions:
-      return "NotInstructions";
-    case ResultReason::DiffOpcodes:
-      return "DiffOpcodes";
-    case ResultReason::DiffTypes:
-      return "DiffTypes";
-    case ResultReason::DiffMathFlags:
-      return "DiffMathFlags";
-    case ResultReason::DiffWrapFlags:
-      return "DiffWrapFlags";
-    case ResultReason::DiffBBs:
-      return "DiffBBs";
-    case ResultReason::RepeatedInstrs:
-      return "RepeatedInstrs";
-    case ResultReason::NotConsecutive:
-      return "NotConsecutive";
-    case ResultReason::CantSchedule:
-      return "CantSchedule";
-    case ResultReason::Unimplemented:
-      return "Unimplemented";
-    case ResultReason::Infeasible:
-      return "Infeasible";
-    case ResultReason::ForcePackForDebugging:
-      return "ForcePackForDebugging";
-    }
-    llvm_unreachable("Unknown ResultReason enum");
-  }
-};
-#endif // NDEBUG
-
-/// The legality outcome is represented by a class rather than an enum class
-/// because in some cases the legality checks are expensive and look for a
-/// particular instruction that can be passed along to the vectorizer to avoid
-/// repeating the same expensive computation.
-class LegalityResult {
-protected:
-  LegalityResultID ID;
-  /// Only Legality can create LegalityResults.
-  LegalityResult(LegalityResultID ID) : ID(ID) {}
-  friend class LegalityAnalysis;
-
-  /// We shouldn't need copies.
-  LegalityResult(const LegalityResult &) = delete;
-  LegalityResult &operator=(const LegalityResult &) = delete;
-
-public:
-  virtual ~LegalityResult() = default;
-  LegalityResultID getSubclassID() const { return ID; }
-#ifndef NDEBUG
-  virtual void print(raw_ostream &OS) const {
-    OS << ToStr::getLegalityResultID(ID);
-  }
-  LLVM_DUMP_METHOD void dump() const;
-  friend raw_ostream &operator<<(raw_ostream &OS, const LegalityResult &LR) {
-    LR.print(OS);
-    return OS;
-  }
-#endif // NDEBUG
-};
-
-/// Base class for results with reason.
-class LegalityResultWithReason : public LegalityResult {
-  [[maybe_unused]] ResultReason Reason;
-  LegalityResultWithReason(LegalityResultID ID, ResultReason Reason)
-      : LegalityResult(ID), Reason(Reason) {}
-  friend class Pack; // For constructor.
-
-public:
-  ResultReason getReason() const { return Reason; }
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const override {
-    LegalityResult::print(OS);
-    OS << " Reason: " << ToStr::getVecReason(Reason);
-  }
-#endif
-};
-
-class Widen final : public LegalityResult {
-  friend class LegalityAnalysis;
-  Widen() : LegalityResult(LegalityResultID::Widen) {}
-
-public:
-  static bool classof(const LegalityResult *From) {
-    return From->getSubclassID() == LegalityResultID::Widen;
-  }
-};
-
-class DiamondReuse final : public LegalityResult {
-  friend class LegalityAnalysis;
-  Action *Vec;
-  DiamondReuse(Action *Vec)
-      : LegalityResult(LegalityResultID::DiamondReuse), Vec(Vec) {}
-
-public:
-  static bool classof(const LegalityResult *From) {
-    return From->getSubclassID() == LegalityResultID::DiamondReuse;
-  }
-  Action *getVector() const { return Vec; }
-};
-
-class DiamondReuseWithShuffle final : public LegalityResult {
-  friend class LegalityAnalysis;
-  Action *Vec;
-  ShuffleMask Mask;
-  DiamondReuseWithShuffle(Action *Vec, const ShuffleMask &Mask)
-      : LegalityResult(LegalityResultID::DiamondReuseWithShuffle), Vec(Vec),
-        Mask(Mask) {}
-
-public:
-  static bool classof(const LegalityResult *From) {
-    return From->getSubclassID() == LegalityResultID::DiamondReuseWithShuffle;
-  }
-  Action *getVector() const { return Vec; }
-  const ShuffleMask &getMask() const { return Mask; }
-};
-
-class Pack final : public LegalityResultWithReason {
-  Pack(ResultReason Reason)
-      : LegalityResultWithReason(LegalityResultID::Pack, Reason) {}
-  friend class LegalityAnalysis; // For constructor.
-
-public:
-  static bool classof(const LegalityResult *From) {
-    return From->getSubclassID() == LegalityResultID::Pack;
-  }
-};
-
-/// Describes how to collect the values needed by each lane.
-class CollectDescr {
-public:
-  /// Describes how to get a value element. If the value is a vector then it
-  /// also provides the index to extract it from.
-  class ExtractElementDescr {
-    PointerUnion<Action *, Value *> V = nullptr;
-    /// The index in `V` that the value can be extracted from.
-    int ExtractIdx = 0;
-
-  public:
-    ExtractElementDescr(Action *V, int ExtractIdx)
-        : V(V), ExtractIdx(ExtractIdx) {}
-    ExtractElementDescr(Value *V) : V(V) {}
-    Action *getValue() const { return cast<Action *>(V); }
-    Value *getScalar() const { return cast<Value *>(V); }
-    bool needsExtract() const { return isa<Action *>(V); }
-    int getExtractIdx() const { return ExtractIdx; }
-  };
-
-  using DescrVecT = SmallVector<ExtractElementDescr, 4>;
-  DescrVecT Descrs;
-
-public:
-  CollectDescr(SmallVectorImpl<ExtractElementDescr> &&Descrs)
-      : Descrs(std::move(Descrs)) {}
-  /// If all elements come from a single vector input, then return that vector
-  /// and also the shuffle mask required to get them in order.
-  std::optional<std::pair<Action *, ShuffleMask>> getSingleInput() const {
-    const auto &Descr0 = *Descrs.begin();
-    if (!Descr0.needsExtract())
-      return std::nullopt;
-    auto *V0 = Descr0.getValue();
-    ShuffleMask::IndicesVecT MaskIndices;
-    MaskIndices.push_back(Descr0.getExtractIdx());
-    for (const auto &Descr : drop_begin(Descrs)) {
-      if (!Descr.needsExtract())
-        return std::nullopt;
-      if (Descr.getValue() != V0)
-        return std::nullopt;
-      MaskIndices.push_back(Descr.getExtractIdx());
-    }
-    return std::make_pair(V0, ShuffleMask(std::move(MaskIndices)));
-  }
-  bool hasVectorInputs() const {
-    return any_of(Descrs, [](const auto &D) { return D.needsExtract(); });
-  }
-  const SmallVector<ExtractElementDescr, 4> &getDescrs() const {
-    return Descrs;
-  }
-};
-
-class DiamondReuseMultiInput final : public LegalityResult {
-  friend class LegalityAnalysis;
-  CollectDescr Descr;
-  DiamondReuseMultiInput(CollectDescr &&Descr)
-      : LegalityResult(LegalityResultID::DiamondReuseMultiInput),
-        Descr(std::move(Descr)) {}
-
-public:
-  static bool classof(const LegalityResult *From) {
-    return From->getSubclassID() == LegalityResultID::DiamondReuseMultiInput;
-  }
-  const CollectDescr &getCollectDescr() const { return Descr; }
-};
-
-/// Performs the legality analysis and returns a LegalityResult object.
-class LegalityAnalysis {
-  Scheduler Sched;
-  /// Owns the legality result objects created by createLegalityResult().
-  SmallVector<std::unique_ptr<LegalityResult>> ResultPool;
-  /// Checks opcodes, types and other IR-specifics and returns a ResultReason
-  /// object if not vectorizable, or nullptr otherwise.
-  std::optional<ResultReason>
-  notVectorizableBasedOnOpcodesAndTypes(ArrayRef<Value *> Bndl);
-
-  ScalarEvolution &SE;
-  const DataLayout &DL;
-  InstrMaps &IMaps;
-
-  /// Finds how we can collect the values in \p Bndl from the vectorized or
-  /// non-vectorized code. It returns a map of the value we should extract from
-  /// and the corresponding shuffle mask we need to use.
-  CollectDescr getHowToCollectValues(ArrayRef<Value *> Bndl) const;
-
-public:
-  LegalityAnalysis(AAResults &AA, ScalarEvolution &SE, const DataLayout &DL,
-                   Context &Ctx, InstrMaps &IMaps)
-      : Sched(AA, Ctx), SE(SE), DL(DL), IMaps(IMaps) {}
-  /// A LegalityResult factory.
-  template <typename ResultT, typename... ArgsT>
-  ResultT &createLegalityResult(ArgsT &&...Args) {
-    ResultPool.push_back(
-        std::unique_ptr<ResultT>(new ResultT(std::move(Args)...)));
-    return cast<ResultT>(*ResultPool.back());
-  }
-  /// Checks if it's legal to vectorize the instructions in \p Bndl.
-  /// \Returns a LegalityResult object owned by LegalityAnalysis.
-  /// \p SkipScheduling skips the scheduler check and is only meant for testing.
-  // TODO: Try to remove the SkipScheduling argument by refactoring the tests.
-  LLVM_ABI const LegalityResult &canVectorize(ArrayRef<Value *> Bndl,
-                                              bool SkipScheduling = false);
-  /// \Returns a Pack with reason 'ForcePackForDebugging'.
-  const LegalityResult &getForcedPackForDebugging() {
-    return createLegalityResult<Pack>(ResultReason::ForcePackForDebugging);
-  }
-  LLVM_ABI void clear();
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_LEGALITY_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
deleted file mode 100644
index c65e2cd45ab48..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h
+++ /dev/null
@@ -1,104 +0,0 @@
-//===- BottomUpVec.h --------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// A Bottom-Up Vectorizer pass.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_BOTTOMUPVEC_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_BOTTOMUPVEC_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h"
-
-namespace llvm::sandboxir {
-
-/// This is a simple bottom-up vectorizer Region pass.
-/// It expects a "seed slice" as an input in the Region's Aux vector.
-/// The "seed slice" is a vector of instructions that can be used as a starting
-/// point for vectorization, like stores to consecutive memory addresses.
-/// Starting from the seed instructions, it walks up the def-use chain looking
-/// for more instructions that can be vectorized. This pass will generate vector
-/// code if it can legally vectorize the code, regardless of whether it is
-/// profitable or not. For now profitability is checked at the end of the region
-/// pass pipeline by a dedicated pass that accepts or rejects the IR
-/// transaction, depending on the cost.
-class BottomUpVec final : public RegionPass {
-  bool Change = false;
-  /// The original instructions that are potentially dead after vectorization.
-  DenseSet<Instruction *> DeadInstrCandidates;
-  /// Maps scalars to vectors.
-  std::unique_ptr<InstrMaps> IMaps;
-  /// Counter used for force-stopping the vectorizer after this many
-  /// invocations. Used for debugging miscompiles.
-  unsigned long BottomUpInvocationCnt = 0;
-
-  /// Creates and returns a vector instruction that replaces the instructions in
-  /// \p Bndl. \p Operands are the already vectorized operands.
-  Value *createVectorInstr(ArrayRef<Value *> Bndl, ArrayRef<Value *> Operands);
-  /// Erases all dead instructions from the dead instruction candidates
-  /// collected during vectorization.
-  void tryEraseDeadInstrs();
-  /// Creates a shuffle instruction that shuffles \p VecOp according to \p Mask.
-  /// \p UserBB is the block of the user bundle.
-  Value *createShuffle(Value *VecOp, const ShuffleMask &Mask,
-                       BasicBlock *UserBB);
-  /// Packs all elements of \p ToPack into a vector and returns that vector. \p
-  /// UserBB is the block of the user bundle.
-  Value *createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB);
-  /// After we create vectors for groups of instructions, the original
-  /// instructions are potentially dead and may need to be removed. This
-  /// function helps collect these instructions (along with the pointer operands
-  /// for loads/stores) so that they can be cleaned up later.
-  void collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl);
-
-  /// Helper class describing how(if) to vectorize the code.
-  class ActionsVector {
-  private:
-    SmallVector<std::unique_ptr<Action>, 16> Actions;
-
-  public:
-    auto begin() const { return Actions.begin(); }
-    auto end() const { return Actions.end(); }
-    void push_back(std::unique_ptr<Action> &&ActPtr) {
-      ActPtr->Idx = Actions.size();
-      Actions.push_back(std::move(ActPtr));
-    }
-    void clear() { Actions.clear(); }
-#ifndef NDEBUG
-    void print(raw_ostream &OS) const;
-    void dump() const;
-#endif // NDEBUG
-  };
-  ActionsVector Actions;
-  /// Helper counter for debugging. It counts the bundles that we attempt to
-  /// vectorize in vectorizeRec().
-  unsigned DebugBndlCnt = 0;
-
-  /// Recursively try to vectorize \p Bndl and its operands. This populates the
-  /// `Actions` vector.
-  Action *vectorizeRec(ArrayRef<Value *> Bndl, ArrayRef<Value *> UserBndl,
-                       unsigned Depth, LegalityAnalysis &Legality);
-  /// Generate vector instructions based on `Actions` and return the last vector
-  /// created.
-  Value *emitVectors();
-  /// Entry point for vectorization starting from \p Seeds.
-  bool tryVectorize(ArrayRef<Value *> Seeds, LegalityAnalysis &Legality);
-
-public:
-  BottomUpVec() : RegionPass("bottom-up-vec") {}
-  bool runOnRegion(Region &Rgn, const Analyses &A) final;
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_BOTTOMUPVEC_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h
deleted file mode 100644
index 2c5defb4e02e1..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===- NullPass.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// A null region pass that does nothing. Used for testing.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_NULLPASS_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_NULLPASS_H
-
-#include "llvm/SandboxIR/Pass.h"
-
-namespace llvm::sandboxir {
-
-class Region;
-
-/// A Region pass that does nothing, for use as a placeholder in tests.
-class NullPass final : public RegionPass {
-public:
-  NullPass() : RegionPass("null") {}
-  bool runOnRegion(Region &R, const Analyses &A) final { return false; }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_NULLPASS_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h
deleted file mode 100644
index bd0bf244f6b1d..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h
+++ /dev/null
@@ -1,36 +0,0 @@
-//===- PackReuse.h --------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// A pack de-duplication pass.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PACKREUSE_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PACKREUSE_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-/// This pass aims at de-duplicating packs, i.e., try to reuse already existing
-/// pack patterns instead of keeping both.
-/// This is useful because even though the duplicates will most probably be
-/// optimized away by future passes, their added cost can make vectorization
-/// more conservative than it should be.
-class PackReuse final : public RegionPass {
-  bool Change = false;
-
-public:
-  PackReuse() : RegionPass("pack-reuse") {}
-  bool runOnRegion(Region &Rgn, const Analyses &A) final;
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PACKREUSE_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCount.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCount.h
deleted file mode 100644
index cd11d4c148926..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCount.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTINSTRUCTIONCOUNT_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTINSTRUCTIONCOUNT_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-/// A Region pass that prints the instruction count for the region to stdout.
-/// Used to test -sbvec-passes while we don't have any actual optimization
-/// passes.
-class PrintInstructionCount final : public RegionPass {
-public:
-  PrintInstructionCount() : RegionPass("null") {}
-  bool runOnRegion(Region &R, const Analyses &A) final {
-    outs() << "InstructionCount: " << std::distance(R.begin(), R.end()) << "\n";
-    return false;
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTINSTRUCTIONCOUNTPASS_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintRegion.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintRegion.h
deleted file mode 100644
index 34ed8c5e6d6bc..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintRegion.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTREGION_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTREGION_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-/// A Region pass that does nothing, for use as a placeholder in tests.
-class PrintRegion final : public RegionPass {
-public:
-  PrintRegion() : RegionPass("print-region") {}
-  bool runOnRegion(Region &R, const Analyses &A) final {
-    raw_ostream &OS = outs();
-#ifndef NDEBUG
-    OS << "-- Region --\n";
-    OS << R << "\n";
-#else
-    // TODO: Make this available in all builds, depends on enabling SandboxIR
-    // dumps in non-debug builds.
-    OS << "Region dump only available in DEBUG build!";
-#endif
-    return false;
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_PRINTREGION_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.h
deleted file mode 100644
index 66c9cd42fb878..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- RegionsFromBBs.h -----------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// A SandboxIR function pass that builds one region per BB and then runs a
-// pipeline of region passes on them. This is useful to test region passes in
-// isolation without relying on the output of other vectorizer components.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_REGIONSFROMBBS_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_REGIONSFROMBBS_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/PassManager.h"
-
-namespace llvm::sandboxir {
-
-class RegionsFromBBs final : public FunctionPass {
-  // The PM containing the pipeline of region passes.
-  RegionPassManager RPM;
-
-public:
-  RegionsFromBBs(StringRef Pipeline);
-  bool runOnFunction(Function &F, const Analyses &A) final;
-  void printPipeline(raw_ostream &OS) const final {
-    OS << getName() << "\n";
-    RPM.printPipeline(OS);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_REGIONSFROMBBS_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h
deleted file mode 100644
index 3d738ac8917ef..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h
+++ /dev/null
@@ -1,38 +0,0 @@
-//===- RegionsFromMetadata.h ------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// A SandboxIR function pass that builds regions from IR metadata and then runs
-// a pipeline of region passes on them. This is useful to test region passes in
-// isolation without relying on the output of the bottom-up vectorizer.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_REGIONSFROMMETADATA_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_REGIONSFROMMETADATA_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/PassManager.h"
-
-namespace llvm::sandboxir {
-
-class RegionsFromMetadata final : public FunctionPass {
-  // The PM containing the pipeline of region passes.
-  RegionPassManager RPM;
-
-public:
-  RegionsFromMetadata(StringRef Pipeline);
-  bool runOnFunction(Function &F, const Analyses &A) final;
-  void printPipeline(raw_ostream &OS) const final {
-    OS << getName() << "\n";
-    RPM.printPipeline(OS);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_REGIONSFROMMETADATA_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.h
deleted file mode 100644
index 286d971ff4851..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- SeedCollection.h -----------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// The seed-collection pass of the bottom-up vectorizer.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_SEEDCOLLECTION_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_SEEDCOLLECTION_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/PassManager.h"
-
-namespace llvm::sandboxir {
-
-/// This pass collects the instructions that can become vectorization "seeds",
-/// like stores to consecutive memory addresses. It then goes over the collected
-/// seeds, slicing them into appropriately sized chunks, creating a Region with
-/// the seed slice as the Auxiliary vector and runs the region pass pipeline.
-class SeedCollection final : public FunctionPass {
-
-  /// The PM containing the pipeline of region passes.
-  RegionPassManager RPM;
-
-public:
-  SeedCollection(StringRef Pipeline);
-  bool runOnFunction(Function &F, const Analyses &A) final;
-  void printPipeline(raw_ostream &OS) const final {
-    OS << getName() << "\n";
-    RPM.printPipeline(OS);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_SEEDCOLLECTION_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h
deleted file mode 100644
index fce9cc0c1bde7..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===- TransactionAcceptOrRevert.h ------------------------------*- 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 is a region pass that checks the region cost before/after vectorization
-// and accepts the state of Sandbox IR if the cost is better, or otherwise
-// reverts it.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONACCEPTORREVERT_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONACCEPTORREVERT_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-class TransactionAcceptOrRevert : public RegionPass {
-public:
-  TransactionAcceptOrRevert() : RegionPass("tr-accept-or-revert") {}
-  bool runOnRegion(Region &Rgn, const Analyses &A) final;
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONACCEPTORREVERT_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h
deleted file mode 100644
index ed6cf1bf7cf51..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- TransactionAlwaysAccept.h --------------------------------*- 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 is a region pass that always accepts the transaction without checking
-// its cost. This is mainly used as a final pass in lit tests.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSACCEPT_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSACCEPT_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-class TransactionAlwaysAccept : public RegionPass {
-public:
-  TransactionAlwaysAccept() : RegionPass("tr-accept") {}
-  bool runOnRegion(Region &Rgn, const Analyses &A) final {
-    auto &Tracker = Rgn.getContext().getTracker();
-    bool HasChanges = !Tracker.empty();
-    Tracker.accept();
-    return HasChanges;
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSACCEPT_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysRevert.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysRevert.h
deleted file mode 100644
index 308ba208d777e..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysRevert.h
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- TransactionAlwaysRevert.h --------------------------------*- 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 is a region pass that always reverts the transaction without checking
-// its cost. This is mainly used as a final pass in lit tests.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSREVERT_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSREVERT_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-class TransactionAlwaysRevert : public RegionPass {
-public:
-  TransactionAlwaysRevert() : RegionPass("tr-revert") {}
-  bool runOnRegion(Region &Rgn, const Analyses &A) final {
-    auto &Tracker = Rgn.getContext().getTracker();
-    bool HasChanges = !Tracker.empty();
-    Tracker.revert();
-    return HasChanges;
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONALWAYSREVERT_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.h
deleted file mode 100644
index 73aafabfd0b0c..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.h
+++ /dev/null
@@ -1,28 +0,0 @@
-//===- TransactionSave.h ----------------------------------------*- 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 is a region pass that simply calls Context::save() to save the IR state.
-//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONSAVE_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONSAVE_H
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/SandboxIR/Region.h"
-
-namespace llvm::sandboxir {
-
-class TransactionSave : public RegionPass {
-public:
-  TransactionSave() : RegionPass("tr-save") {}
-  bool runOnRegion(Region &Rgn, const Analyses &A) final;
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_PASSES_TRANSACTIONSAVE_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h
deleted file mode 100644
index fc8765217c0c2..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h
+++ /dev/null
@@ -1,62 +0,0 @@
-//===- SandboxVectorizer.h --------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
-
-#include "llvm/Support/Compiler.h"
-#include <memory>
-
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/PassManager.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/PassManager.h"
-
-namespace llvm {
-
-class TargetTransformInfo;
-
-class SandboxVectorizerPass : public PassInfoMixin<SandboxVectorizerPass> {
-  TargetTransformInfo *TTI = nullptr;
-  AAResults *AA = nullptr;
-  ScalarEvolution *SE = nullptr;
-  // NOTE: We define the Context as a pass-scope object instead of local object
-  // in runOnFunction() because the passes defined in the pass-manager need
-  // access to it for registering/deregistering callbacks during construction
-  // and destruction.
-  std::unique_ptr<sandboxir::Context> Ctx;
-
-  // A pipeline of SandboxIR function passes run by the vectorizer.
-  // NOTE: We define this as a pass-scope object to avoid recreating the
-  // pass-pipeline every time in runOnFunction(). The downside is that the
-  // Context also needs to be defined as a pass-scope object because the passes
-  // within FPM may register/unregister callbacks, so they need access to
-  // Context.
-  sandboxir::FunctionPassManager FPM;
-  /// \Returns true if we should attempt to vectorize \p SrcFilePath based on
-  /// `AllowFiles` option.
-  bool allowFile(const std::string &SrcFilePath);
-
-  bool runImpl(Function &F);
-
-public:
-  // Make sure the constructors/destructors are out-of-line. This works around a
-  // problem with -DBUILD_SHARED_LIBS=on where components that depend on the
-  // Vectorizer component can't find the vtable for classes like
-  // sandboxir::Pass. This way we don't have to make LLVMPasses add a direct
-  // dependency on SandboxIR.
-  LLVM_ABI SandboxVectorizerPass();
-  LLVM_ABI SandboxVectorizerPass(SandboxVectorizerPass &&);
-  LLVM_ABI ~SandboxVectorizerPass();
-
-  LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
-};
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZER_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h
deleted file mode 100644
index e3d6ecae836fc..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//===- SandboxVectorizerPassBuilder.h ---------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Utility functions so passes with sub-pipelines can create SandboxVectorizer
-// passes without replicating the same logic in each pass.
-//
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZERPASSBUILDER_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZERPASSBUILDER_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/SandboxIR/Pass.h"
-
-#include <memory>
-
-namespace llvm::sandboxir {
-
-class SandboxVectorizerPassBuilder {
-public:
-  static std::unique_ptr<FunctionPass> createFunctionPass(StringRef Name,
-                                                          StringRef Args);
-  static std::unique_ptr<RegionPass> createRegionPass(StringRef Name,
-                                                      StringRef Args);
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SANDBOXVECTORIZERPASSBUILDER_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h
deleted file mode 100644
index 66ba91c58430d..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h
+++ /dev/null
@@ -1,268 +0,0 @@
-//===- Scheduler.h ----------------------------------------------*- 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 is the bottom-up list scheduler used by the vectorizer. It is used for
-// checking the legality of vectorization and for scheduling instructions in
-// such a way that makes vectorization possible, if legal.
-//
-// The legality check is performed by `trySchedule(Instrs)`, which will try to
-// schedule the IR until all instructions in `Instrs` can be scheduled together
-// back-to-back. If this fails then it is illegal to vectorize `Instrs`.
-//
-// Internally the scheduler uses the vectorizer-specific DependencyGraph class.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
-
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h"
-#include <queue>
-
-namespace llvm::sandboxir {
-
-class PriorityCmp {
-public:
-  bool operator()(const DGNode *N1, const DGNode *N2) {
-    // Given that the DAG does not model dependencies such that PHIs are always
-    // at the top, or terminators always at the bottom, we need to force the
-    // priority here in the comparator of the ready list container.
-    auto *I1 = N1->getInstruction();
-    auto *I2 = N2->getInstruction();
-    bool IsTerm1 = I1->isTerminator();
-    bool IsTerm2 = I2->isTerminator();
-    if (IsTerm1 != IsTerm2)
-      // Terminators have the lowest priority.
-      return IsTerm1 > IsTerm2;
-    bool IsPHI1 = isa<PHINode>(I1);
-    bool IsPHI2 = isa<PHINode>(I2);
-    if (IsPHI1 != IsPHI2)
-      // PHIs have the highest priority.
-      return IsPHI1 < IsPHI2;
-    // Otherwise rely on the instruction order.
-    return I2->comesBefore(I1);
-  }
-};
-
-/// The list holding nodes that are ready to schedule. Used by the scheduler.
-class ReadyListContainer {
-  PriorityCmp Cmp;
-  /// Control/Other dependencies are not modeled by the DAG to save memory.
-  /// These have to be modeled in the ready list for correctness.
-  /// This means that the list will hold back nodes that need to meet such
-  /// unmodeled dependencies.
-  std::priority_queue<DGNode *, std::vector<DGNode *>, PriorityCmp> List;
-
-public:
-  ReadyListContainer() : List(Cmp) {}
-  void insert(DGNode *N) {
-#ifndef NDEBUG
-    assert(!N->scheduled() && "Don't insert a scheduled node!");
-    auto ListCopy = List;
-    while (!ListCopy.empty()) {
-      DGNode *Top = ListCopy.top();
-      ListCopy.pop();
-      assert(Top != N && "Node already exists in ready list!");
-    }
-#endif
-    List.push(N);
-  }
-  DGNode *pop() {
-    auto *Back = List.top();
-    List.pop();
-    return Back;
-  }
-  bool empty() const { return List.empty(); }
-  void clear() { List = {}; }
-  /// \Removes \p N if found in the ready list.
-  void remove(DGNode *N) {
-    // TODO: Use a more efficient data-structure for the ready list because the
-    // priority queue does not support fast removals.
-    SmallVector<DGNode *, 8> Keep;
-    Keep.reserve(List.size());
-    while (!List.empty()) {
-      auto *Top = List.top();
-      List.pop();
-      if (Top == N)
-        break;
-      Keep.push_back(Top);
-    }
-    for (auto *KeepN : Keep)
-      List.push(KeepN);
-  }
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif // NDEBUG
-};
-
-/// The nodes that need to be scheduled back-to-back in a single scheduling
-/// cycle form a SchedBundle.
-class SchedBundle {
-public:
-  using ContainerTy = SmallVector<DGNode *, 4>;
-
-private:
-  ContainerTy Nodes;
-
-  /// Called by the DGNode destructor to avoid accessing freed memory.
-  void eraseFromBundle(DGNode *N) { llvm::erase(Nodes, N); }
-  friend void DGNode::setSchedBundle(SchedBundle &); // For eraseFromBunde().
-  friend DGNode::~DGNode();                          // For eraseFromBundle().
-
-public:
-  SchedBundle() = default;
-  SchedBundle(ContainerTy &&Nodes) : Nodes(std::move(Nodes)) {
-    for (auto *N : this->Nodes)
-      N->setSchedBundle(*this);
-  }
-  /// Copy CTOR (unimplemented).
-  SchedBundle(const SchedBundle &Other) = delete;
-  /// Copy Assignment (unimplemented).
-  SchedBundle &operator=(const SchedBundle &Other) = delete;
-  ~SchedBundle() {
-    for (auto *N : this->Nodes)
-      N->clearSchedBundle();
-  }
-  bool empty() const { return Nodes.empty(); }
-  /// Singleton bundles are created when scheduling instructions temporarily to
-  /// fill in the schedule until we schedule the vector bundle. These are
-  /// non-vector bundles containing just a single instruction.
-  bool isSingleton() const { return Nodes.size() == 1u; }
-  DGNode *back() const { return Nodes.back(); }
-  using iterator = ContainerTy::iterator;
-  using const_iterator = ContainerTy::const_iterator;
-  iterator begin() { return Nodes.begin(); }
-  iterator end() { return Nodes.end(); }
-  const_iterator begin() const { return Nodes.begin(); }
-  const_iterator end() const { return Nodes.end(); }
-  /// \Returns the bundle node that comes before the others in program order.
-  LLVM_ABI DGNode *getTop() const;
-  /// \Returns the bundle node that comes after the others in program order.
-  LLVM_ABI DGNode *getBot() const;
-  /// Move all bundle instructions to \p Where back-to-back.
-  LLVM_ABI void cluster(BasicBlock::iterator Where);
-  /// \Returns true if all nodes in the bundle are ready.
-  bool ready() const {
-    return all_of(Nodes, [](const auto *N) { return N->ready(); });
-  }
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-/// The list scheduler.
-class Scheduler {
-  /// This is a list-scheduler and this is the list containing the instructions
-  /// that are ready, meaning that all their dependency successors have already
-  /// been scheduled.
-  ReadyListContainer ReadyList;
-  /// The dependency graph is used by the scheduler to determine the legal
-  /// ordering of instructions.
-  DependencyGraph DAG;
-  friend class SchedulerInternalsAttorney; // For DAG.
-  Context &Ctx;
-  /// This is the top of the schedule, i.e. the location where the scheduler
-  /// is about to place the scheduled instructions. It gets updated as we
-  /// schedule.
-  std::optional<BasicBlock::iterator> ScheduleTopItOpt;
-  // TODO: This is wasting memory in exchange for fast removal using a raw ptr.
-  DenseMap<SchedBundle *, std::unique_ptr<SchedBundle>> Bndls;
-  /// The BB that we are currently scheduling.
-  BasicBlock *ScheduledBB = nullptr;
-  /// The ID of the callback we register with Sandbox IR.
-  std::optional<Context::CallbackID> CreateInstrCB;
-  /// Called by Sandbox IR's callback system, after \p I has been created.
-  /// NOTE: This should run after DAG's callback has run.
-  // TODO: Perhaps call DAG's notify function from within this one?
-  LLVM_ABI void notifyCreateInstr(Instruction *I);
-
-  /// \Returns a scheduling bundle containing \p Instrs.
-  SchedBundle *createBundle(ArrayRef<Instruction *> Instrs);
-  void eraseBundle(SchedBundle *SB);
-  /// Schedule nodes until we can schedule \p Instrs back-to-back.
-  bool tryScheduleUntil(ArrayRef<Instruction *> Instrs);
-  /// Schedules all nodes in \p Bndl, marks them as scheduled, updates the
-  /// UnscheduledSuccs counter of all dependency predecessors, and adds any of
-  /// them that become ready to the ready list.
-  void scheduleAndUpdateReadyList(SchedBundle &Bndl);
-  /// The scheduling state of the instructions in the bundle.
-  enum class BndlSchedState {
-    NoneScheduled, ///> No instruction in the bundle was previously scheduled.
-    AlreadyScheduled, ///> At least one instruction in the bundle belongs to a
-                      /// different non-singleton scheduling bundle.
-    TemporarilyScheduled, ///> Instructions were temporarily scheduled as
-                          /// singleton bundles or some of them were not
-                          /// scheduled at all. None of them were in a vector
-                          ///(non-singleton) bundle.
-    FullyScheduled, ///> All instrs in the bundle were previously scheduled and
-                    /// were in the same SchedBundle.
-  };
-  /// \Returns whether none/some/all of \p Instrs have been scheduled.
-  LLVM_ABI BndlSchedState
-  getBndlSchedState(ArrayRef<Instruction *> Instrs) const;
-  /// Destroy the top-most part of the schedule that includes \p Instrs.
-  void trimSchedule(ArrayRef<Instruction *> Instrs);
-  /// Disable copies.
-  Scheduler(const Scheduler &) = delete;
-  Scheduler &operator=(const Scheduler &) = delete;
-
-public:
-  Scheduler(AAResults &AA, Context &Ctx) : DAG(AA, Ctx), Ctx(Ctx) {
-    // NOTE: The scheduler's callback depends on the DAG's callback running
-    // before it and updating the DAG accordingly.
-    CreateInstrCB = Ctx.registerCreateInstrCallback(
-        [this](Instruction *I) { notifyCreateInstr(I); });
-  }
-  ~Scheduler() {
-    if (CreateInstrCB)
-      Ctx.unregisterCreateInstrCallback(*CreateInstrCB);
-  }
-  /// Tries to build a schedule that includes all of \p Instrs scheduled at the
-  /// same scheduling cycle. This essentially checks that there are no
-  /// dependencies among \p Instrs. This function may involve scheduling
-  /// intermediate instructions or canceling and re-scheduling if needed.
-  /// \Returns true on success, false otherwise.
-  LLVM_ABI bool trySchedule(ArrayRef<Instruction *> Instrs);
-  /// Clear the scheduler's state, including the DAG.
-  void clear() {
-    Bndls.clear();
-    // TODO: clear view once it lands.
-    DAG.clear();
-    ReadyList.clear();
-    ScheduleTopItOpt = std::nullopt;
-    ScheduledBB = nullptr;
-    assert(Bndls.empty() && DAG.empty() && ReadyList.empty() &&
-           !ScheduleTopItOpt && ScheduledBB == nullptr &&
-           "Expected empty state!");
-  }
-
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-/// A client-attorney class for accessing the Scheduler's internals (used for
-/// unit tests).
-class SchedulerInternalsAttorney {
-public:
-  static DependencyGraph &getDAG(Scheduler &Sched) { return Sched.DAG; }
-  using BndlSchedState = Scheduler::BndlSchedState;
-  static BndlSchedState getBndlSchedState(const Scheduler &Sched,
-                                          ArrayRef<Instruction *> Instrs) {
-    return Sched.getBndlSchedState(Instrs);
-  }
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SCHEDULER_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h
deleted file mode 100644
index 821382b0b12d0..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h
+++ /dev/null
@@ -1,331 +0,0 @@
-//===- SeedCollector.h ------------------------------------------*- 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 file contains the mechanism for collecting the seed instructions that
-// are used as starting points for forming the vectorization graph.
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SEEDCOLLECTOR_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SEEDCOLLECTOR_H
-
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/Compiler.h"
-#include <iterator>
-#include <memory>
-
-namespace llvm::sandboxir {
-
-/// A set of candidate Instructions for vectorizing together.
-class SeedBundle {
-public:
-  /// Initialize a bundle with \p I.
-  explicit SeedBundle(Instruction *I) { insertAt(begin(), I); }
-  explicit SeedBundle(SmallVector<Instruction *> &&L) : Seeds(std::move(L)) {
-    for (auto &S : Seeds)
-      NumUnusedBits += Utils::getNumBits(S);
-  }
-  /// No need to allow copies.
-  SeedBundle(const SeedBundle &) = delete;
-  SeedBundle &operator=(const SeedBundle &) = delete;
-  virtual ~SeedBundle() = default;
-
-  using iterator = SmallVector<Instruction *>::iterator;
-  using const_iterator = SmallVector<Instruction *>::const_iterator;
-  iterator begin() { return Seeds.begin(); }
-  iterator end() { return Seeds.end(); }
-  const_iterator begin() const { return Seeds.begin(); }
-  const_iterator end() const { return Seeds.end(); }
-
-  Instruction *operator[](unsigned Idx) const { return Seeds[Idx]; }
-
-  /// Insert \p I into position \p P. Clients should choose Pos
-  /// by symbol, symbol-offset, and program order (which depends if scheduling
-  /// bottom-up or top-down).
-  void insertAt(iterator Pos, Instruction *I) {
-    Seeds.insert(Pos, I);
-    NumUnusedBits += Utils::getNumBits(I);
-  }
-
-  virtual void insert(Instruction *I, ScalarEvolution &SE) = 0;
-
-  unsigned getFirstUnusedElementIdx() const {
-    for (unsigned ElmIdx : seq<unsigned>(0, Seeds.size()))
-      if (!isUsed(ElmIdx))
-        return ElmIdx;
-    return Seeds.size();
-  }
-  /// Marks instruction \p I "used" within the bundle. Clients
-  /// use this property when assembling a vectorized instruction from
-  /// the seeds in a bundle. This allows constant time evaluation
-  /// and "removal" from the list.
-  void setUsed(Instruction *I) {
-    auto It = llvm::find(*this, I);
-    assert(It != end() && "Instruction not in the bundle!");
-    auto Idx = It - begin();
-    setUsed(Idx, 1, /*VerifyUnused=*/false);
-  }
-
-  void setUsed(unsigned ElementIdx, unsigned Sz = 1, bool VerifyUnused = true) {
-    if (ElementIdx + Sz >= UsedLanes.size())
-      UsedLanes.resize(ElementIdx + Sz);
-    for (unsigned Idx : seq<unsigned>(ElementIdx, ElementIdx + Sz)) {
-      assert((!VerifyUnused || !UsedLanes.test(Idx)) &&
-             "Already marked as used!");
-      UsedLanes.set(Idx);
-      UsedLaneCount++;
-    }
-    NumUnusedBits -= Utils::getNumBits(Seeds[ElementIdx]);
-  }
-  /// \Returns whether or not \p Element has been used.
-  bool isUsed(unsigned Element) const {
-    return Element < UsedLanes.size() && UsedLanes.test(Element);
-  }
-  bool allUsed() const { return UsedLaneCount == Seeds.size(); }
-  unsigned getNumUnusedBits() const { return NumUnusedBits; }
-
-  /// \Returns a slice of seed elements, starting at the element \p StartIdx,
-  /// with a total size <= \p MaxVecRegBits, or an empty slice if the
-  /// requirements cannot be met . If \p ForcePowOf2 is true, then the returned
-  /// slice will have a total number of bits that is a power of 2.
-  LLVM_ABI ArrayRef<Instruction *>
-  getSlice(unsigned StartIdx, unsigned MaxVecRegBits, bool ForcePowOf2);
-
-  /// \Returns the number of seed elements in the bundle.
-  std::size_t size() const { return Seeds.size(); }
-
-protected:
-  SmallVector<Instruction *> Seeds;
-  /// The lanes that we have already vectorized.
-  BitVector UsedLanes;
-  /// Tracks used lanes for constant-time accessor.
-  unsigned UsedLaneCount = 0;
-  /// Tracks the remaining bits available to vectorize
-  unsigned NumUnusedBits = 0;
-
-public:
-#ifndef NDEBUG
-  void dump(raw_ostream &OS) const {
-    for (auto [ElmIdx, I] : enumerate(*this)) {
-      OS.indent(2) << ElmIdx << ". ";
-      if (isUsed(ElmIdx))
-        OS << "[USED]";
-      else
-        OS << *I;
-      OS << "\n";
-    }
-  }
-  LLVM_DUMP_METHOD void dump() const {
-    dump(dbgs());
-    dbgs() << "\n";
-  }
-#endif // NDEBUG
-};
-
-/// Specialization of SeedBundle for memory access instructions. Keeps
-/// seeds sorted in ascending memory order, which is convenient for slicing
-/// these bundles into vectorizable groups.
-template <typename LoadOrStoreT> class MemSeedBundle : public SeedBundle {
-public:
-  explicit MemSeedBundle(SmallVector<Instruction *> &&SV, ScalarEvolution &SE)
-      : SeedBundle(std::move(SV)) {
-    static_assert(std::is_same<LoadOrStoreT, LoadInst>::value ||
-                      std::is_same<LoadOrStoreT, StoreInst>::value,
-                  "Expected LoadInst or StoreInst!");
-    assert(all_of(Seeds, [](auto *S) { return isa<LoadOrStoreT>(S); }) &&
-           "Expected Load or Store instructions!");
-    auto Cmp = [&SE](Instruction *I0, Instruction *I1) {
-      return Utils::atLowerAddress(cast<LoadOrStoreT>(I0),
-                                   cast<LoadOrStoreT>(I1), SE);
-    };
-    std::sort(Seeds.begin(), Seeds.end(), Cmp);
-  }
-  explicit MemSeedBundle(LoadOrStoreT *MemI) : SeedBundle(MemI) {
-    static_assert(std::is_same<LoadOrStoreT, LoadInst>::value ||
-                      std::is_same<LoadOrStoreT, StoreInst>::value,
-                  "Expected LoadInst or StoreInst!");
-    assert(isa<LoadOrStoreT>(MemI) && "Expected Load or Store!");
-  }
-  void insert(sandboxir::Instruction *I, ScalarEvolution &SE) override {
-    assert(isa<LoadOrStoreT>(I) && "Expected a Store or a Load!");
-    auto Cmp = [&SE](Instruction *I0, Instruction *I1) {
-      return Utils::atLowerAddress(cast<LoadOrStoreT>(I0),
-                                   cast<LoadOrStoreT>(I1), SE);
-    };
-    // Find the first element after I in mem. Then insert I before it.
-    insertAt(llvm::upper_bound(*this, I, Cmp), I);
-  }
-};
-
-using StoreSeedBundle = MemSeedBundle<sandboxir::StoreInst>;
-using LoadSeedBundle = MemSeedBundle<sandboxir::LoadInst>;
-
-/// Class to conveniently track Seeds within SeedBundles. Saves newly collected
-/// seeds in the proper bundle. Supports constant-time removal, as seeds and
-/// entire bundles are vectorized and marked used to signify removal. Iterators
-/// skip bundles that are completely used.
-class SeedContainer {
-  // Use the same key for different seeds if they are the same type and
-  // reference the same pointer, even if at different offsets. This directs
-  // potentially vectorizable seeds into the same bundle.
-  using KeyT = std::tuple<Value *, Type *, Instruction::Opcode>;
-  // Trying to vectorize too many seeds at once is expensive in
-  // compilation-time. Use a vector of bundles (all with the same key) to
-  // partition the candidate set into more manageable units. Each bundle is
-  // size-limited by sbvec-seed-bundle-size-limit.  TODO: There might be a
-  // better way to divide these than by simple insertion order.
-  using ValT = SmallVector<std::unique_ptr<SeedBundle>>;
-  using BundleMapT = MapVector<KeyT, ValT>;
-  // Map from {pointer, Type, Opcode} to a vector of bundles.
-  BundleMapT Bundles;
-  // Allows finding a particular Instruction's bundle.
-  DenseMap<Instruction *, SeedBundle *> SeedLookupMap;
-
-  ScalarEvolution &SE;
-
-  template <typename LoadOrStoreT>
-  KeyT getKey(LoadOrStoreT *LSI, bool AllowDiffTypes) const;
-
-public:
-  SeedContainer(ScalarEvolution &SE) : SE(SE) {}
-
-  class iterator {
-    BundleMapT *Map = nullptr;
-    BundleMapT::iterator MapIt;
-    ValT *Vec = nullptr;
-    size_t VecIdx;
-
-  public:
-    using difference_type = std::ptrdiff_t;
-    using value_type = SeedBundle;
-    using pointer = value_type *;
-    using reference = value_type &;
-    using iterator_category = std::input_iterator_tag;
-
-    /// Iterates over the \p Map of SeedBundle Vectors, starting at \p MapIt,
-    /// and \p Vec at \p VecIdx, skipping vectors that are completely
-    /// used. Iteration order over the keys {Pointer, Type, Opcode} follows
-    /// DenseMap iteration order. For a given key, the vectors of
-    /// SeedBundles will be returned in insertion order. As in the
-    /// pseudo code below:
-    ///
-    /// for Key,Value in Bundles
-    ///   for SeedBundleVector in Value
-    ///     for SeedBundle in SeedBundleVector
-    ///        if !SeedBundle.allUsed() ...
-    ///
-    /// Note that the bundles themselves may have additional ordering, created
-    /// by the subclasses by insertAt. The bundles themselves may also have used
-    /// instructions.
-
-    // TODO: Range_size counts fully used-bundles. Further, iterating over
-    // anything other than the Bundles in a SeedContainer includes used
-    // seeds. Rework the iterator logic to clean this up.
-    iterator(BundleMapT &Map, BundleMapT::iterator MapIt, ValT *Vec, int VecIdx)
-        : Map(&Map), MapIt(MapIt), Vec(Vec), VecIdx(VecIdx) {}
-    value_type &operator*() {
-      assert(Vec != nullptr && "Already at end!");
-      return *(*Vec)[VecIdx];
-    }
-    // Skip completely used bundles by repeatedly calling operator++().
-    void skipUsed() {
-      while (Vec && VecIdx < Vec->size() && this->operator*().allUsed())
-        ++(*this);
-    }
-    // Iterators iterate over the bundles
-    iterator &operator++() {
-      ++VecIdx;
-      if (VecIdx >= Vec->size()) {
-        assert(MapIt != Map->end() && "Already at end!");
-        VecIdx = 0;
-        ++MapIt;
-        if (MapIt != Map->end())
-          Vec = &MapIt->second;
-        else {
-          Vec = nullptr;
-        }
-      }
-      skipUsed();
-      return *this;
-    }
-    iterator operator++(int) {
-      auto Copy = *this;
-      ++(*this);
-      return Copy;
-    }
-    bool operator==(const iterator &Other) const {
-      assert(Map == Other.Map && "Iterator of different objects!");
-      return MapIt == Other.MapIt && VecIdx == Other.VecIdx;
-    }
-    bool operator!=(const iterator &Other) const { return !(*this == Other); }
-  };
-  using const_iterator = BundleMapT::const_iterator;
-  template <typename LoadOrStoreT>
-  void insert(LoadOrStoreT *LSI, bool AllowDiffTypes);
-  // To support constant-time erase, these just mark the element used, rather
-  // than actually removing them from the bundle.
-  LLVM_ABI bool erase(Instruction *I);
-  bool erase(const KeyT &Key) { return Bundles.erase(Key); }
-  iterator begin() {
-    if (Bundles.empty())
-      return end();
-    auto BeginIt =
-        iterator(Bundles, Bundles.begin(), &Bundles.begin()->second, 0);
-    BeginIt.skipUsed();
-    return BeginIt;
-  }
-  iterator end() { return iterator(Bundles, Bundles.end(), nullptr, 0); }
-  unsigned size() const { return Bundles.size(); }
-
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif // NDEBUG
-};
-
-// Explicit instantiations
-extern template LLVM_TEMPLATE_ABI void
-SeedContainer::insert<LoadInst>(LoadInst *, bool);
-extern template LLVM_TEMPLATE_ABI void
-SeedContainer::insert<StoreInst>(StoreInst *, bool);
-
-class SeedCollector {
-  SeedContainer StoreSeeds;
-  SeedContainer LoadSeeds;
-  Context &Ctx;
-  Context::CallbackID EraseCallbackID;
-  /// \Returns the number of SeedBundle groups for all seed types.
-  /// This is to be used for limiting compilation time.
-  unsigned totalNumSeedGroups() const {
-    return StoreSeeds.size() + LoadSeeds.size();
-  }
-
-public:
-  LLVM_ABI SeedCollector(BasicBlock *BB, ScalarEvolution &SE,
-                         bool CollectStores, bool CollectLoads,
-                         bool AllowDiffTypes = false);
-  LLVM_ABI ~SeedCollector();
-
-  iterator_range<SeedContainer::iterator> getStoreSeeds() {
-    return {StoreSeeds.begin(), StoreSeeds.end()};
-  }
-  iterator_range<SeedContainer::iterator> getLoadSeeds() {
-    return {LoadSeeds.begin(), LoadSeeds.end()};
-  }
-#ifndef NDEBUG
-  void print(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
-#endif
-};
-
-} // namespace llvm::sandboxir
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_SEEDCOLLECTOR_H
diff --git a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h b/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
deleted file mode 100644
index d32bfbaf7a4c8..0000000000000
--- a/llvm/include/llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h
+++ /dev/null
@@ -1,276 +0,0 @@
-//===- VecUtils.h -----------------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-//
-// Collector for SandboxVectorizer related convenience functions that don't
-// belong in other classes.
-
-#ifndef LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_VECUTILS_H
-#define LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_VECUTILS_H
-
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/SandboxIR/Type.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm {
-/// Traits for DenseMap.
-template <> struct DenseMapInfo<SmallVector<sandboxir::Value *>> {
-  static inline SmallVector<sandboxir::Value *> getEmptyKey() {
-    return SmallVector<sandboxir::Value *>({(sandboxir::Value *)-1});
-  }
-  static inline SmallVector<sandboxir::Value *> getTombstoneKey() {
-    return SmallVector<sandboxir::Value *>({(sandboxir::Value *)-2});
-  }
-  static unsigned getHashValue(const SmallVector<sandboxir::Value *> &Vec) {
-    return hash_combine_range(Vec);
-  }
-  static bool isEqual(const SmallVector<sandboxir::Value *> &Vec1,
-                      const SmallVector<sandboxir::Value *> &Vec2) {
-    return Vec1 == Vec2;
-  }
-};
-
-namespace sandboxir {
-
-class VecUtils {
-public:
-  /// \Returns the number of elements in \p Ty. That is the number of lanes if a
-  /// fixed vector or 1 if scalar. ScalableVectors have unknown size and
-  /// therefore are unsupported.
-  static int getNumElements(Type *Ty) {
-    assert(!isa<ScalableVectorType>(Ty));
-    return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() : 1;
-  }
-  /// Returns \p Ty if scalar or its element type if vector.
-  static Type *getElementType(Type *Ty) {
-    return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getElementType() : Ty;
-  }
-
-  /// \Returns true if \p I1 and \p I2 are load/stores accessing consecutive
-  /// memory addresses.
-  template <typename LoadOrStoreT>
-  static bool areConsecutive(LoadOrStoreT *I1, LoadOrStoreT *I2,
-                             ScalarEvolution &SE, const DataLayout &DL) {
-    static_assert(std::is_same<LoadOrStoreT, LoadInst>::value ||
-                      std::is_same<LoadOrStoreT, StoreInst>::value,
-                  "Expected Load or Store!");
-    auto Diff = Utils::getPointerDiffInBytes(I1, I2, SE);
-    if (!Diff)
-      return false;
-    int ElmBytes = Utils::getNumBits(I1) / 8;
-    return *Diff == ElmBytes;
-  }
-
-  template <typename LoadOrStoreT>
-  static bool areConsecutive(ArrayRef<Value *> &Bndl, ScalarEvolution &SE,
-                             const DataLayout &DL) {
-    static_assert(std::is_same<LoadOrStoreT, LoadInst>::value ||
-                      std::is_same<LoadOrStoreT, StoreInst>::value,
-                  "Expected Load or Store!");
-    assert(isa<LoadOrStoreT>(Bndl[0]) && "Expected Load or Store!");
-    auto *LastLS = cast<LoadOrStoreT>(Bndl[0]);
-    for (Value *V : drop_begin(Bndl)) {
-      assert(isa<LoadOrStoreT>(V) &&
-             "Unimplemented: we only support StoreInst!");
-      auto *LS = cast<LoadOrStoreT>(V);
-      if (!VecUtils::areConsecutive(LastLS, LS, SE, DL))
-        return false;
-      LastLS = LS;
-    }
-    return true;
-  }
-
-  /// \Returns the number of vector lanes of \p Ty or 1 if not a vector.
-  /// NOTE: It asserts that \p Ty is a fixed vector type.
-  static unsigned getNumLanes(Type *Ty) {
-    assert(!isa<ScalableVectorType>(Ty) && "Expect scalar or fixed vector");
-    if (auto *FixedVecTy = dyn_cast<FixedVectorType>(Ty))
-      return FixedVecTy->getNumElements();
-    return 1u;
-  }
-
-  /// \Returns the expected vector lanes of \p V or 1 if not a vector.
-  /// NOTE: It asserts that \p V is a fixed vector.
-  static unsigned getNumLanes(Value *V) {
-    return VecUtils::getNumLanes(Utils::getExpectedType(V));
-  }
-
-  /// \Returns the total number of lanes across all values in \p Bndl.
-  static unsigned getNumLanes(ArrayRef<Value *> Bndl) {
-    unsigned Lanes = 0;
-    for (Value *V : Bndl)
-      Lanes += getNumLanes(V);
-    return Lanes;
-  }
-
-  /// \Returns <NumElts x ElemTy>.
-  /// It works for both scalar and vector \p ElemTy.
-  static Type *getWideType(Type *ElemTy, unsigned NumElts) {
-    if (ElemTy->isVectorTy()) {
-      auto *VecTy = cast<FixedVectorType>(ElemTy);
-      ElemTy = VecTy->getElementType();
-      NumElts = VecTy->getNumElements() * NumElts;
-    }
-    return FixedVectorType::get(ElemTy, NumElts);
-  }
-  /// \Returns the instruction in \p Instrs that is lowest in the BB. Expects
-  /// that all instructions are in the same BB.
-  static Instruction *getLowest(ArrayRef<Instruction *> Instrs) {
-    Instruction *LowestI = Instrs.front();
-    for (auto *I : drop_begin(Instrs)) {
-      if (LowestI->comesBefore(I))
-        LowestI = I;
-    }
-    return LowestI;
-  }
-  /// \Returns the lowest instruction in \p Vals, or nullptr if no instructions
-  /// are found. Skips instructions not in \p BB.
-  static Instruction *getLowest(ArrayRef<Value *> Vals, BasicBlock *BB) {
-    // Find the first Instruction in Vals that is also in `BB`.
-    auto It = find_if(Vals, [BB](Value *V) {
-      return isa<Instruction>(V) && cast<Instruction>(V)->getParent() == BB;
-    });
-    // If we couldn't find an instruction return nullptr.
-    if (It == Vals.end())
-      return nullptr;
-    Instruction *FirstI = cast<Instruction>(*It);
-    // Now look for the lowest instruction in Vals starting from one position
-    // after FirstI.
-    Instruction *LowestI = FirstI;
-    for (auto *V : make_range(std::next(It), Vals.end())) {
-      auto *I = dyn_cast<Instruction>(V);
-      // Skip non-instructions.
-      if (I == nullptr)
-        continue;
-      // Skips instructions not in \p BB.
-      if (I->getParent() != BB)
-        continue;
-      // If `LowestI` comes before `I` then `I` is the new lowest.
-      if (LowestI->comesBefore(I))
-        LowestI = I;
-    }
-    return LowestI;
-  }
-
-  /// If \p I is not a PHI it returns it. Else it walks down the instruction
-  /// chain looking for the last PHI and returns it. \Returns nullptr if \p I is
-  /// nullptr.
-  static Instruction *getLastPHIOrSelf(Instruction *I) {
-    Instruction *LastI = I;
-    while (I != nullptr && isa<PHINode>(I)) {
-      LastI = I;
-      I = I->getNextNode();
-    }
-    return LastI;
-  }
-
-  /// If all values in \p Bndl are of the same scalar type then return it,
-  /// otherwise return nullptr.
-  static Type *tryGetCommonScalarType(ArrayRef<Value *> Bndl) {
-    Value *V0 = Bndl[0];
-    Type *Ty0 = Utils::getExpectedType(V0);
-    Type *ScalarTy = VecUtils::getElementType(Ty0);
-    for (auto *V : drop_begin(Bndl)) {
-      Type *NTy = Utils::getExpectedType(V);
-      Type *NScalarTy = VecUtils::getElementType(NTy);
-      if (NScalarTy != ScalarTy)
-        return nullptr;
-    }
-    return ScalarTy;
-  }
-
-  /// Similar to tryGetCommonScalarType() but will assert that there is a common
-  /// type. So this is faster in release builds as it won't iterate through the
-  /// values.
-  static Type *getCommonScalarType(ArrayRef<Value *> Bndl) {
-    Value *V0 = Bndl[0];
-    Type *Ty0 = Utils::getExpectedType(V0);
-    Type *ScalarTy = VecUtils::getElementType(Ty0);
-    assert(tryGetCommonScalarType(Bndl) && "Expected common scalar type!");
-    return ScalarTy;
-  }
-  /// \Returns the first integer power of 2 that is <= Num.
-  LLVM_ABI static unsigned getFloorPowerOf2(unsigned Num);
-
-  /// Helper struct for `matchPack()`. Describes the instructions and operands
-  /// of a pack pattern.
-  struct PackPattern {
-    /// The insertelement instructions that form the pack pattern in bottom-up
-    /// order, i.e., the first instruction in `Instrs` is the bottom-most
-    /// InsertElement instruction of the pack pattern.
-    /// For example in this simple pack pattern:
-    ///  %Pack0 = insertelement <2 x i8> poison, i8 %v0, i64 0
-    ///  %Pack1 = insertelement <2 x i8> %Pack0, i8 %v1, i64 1
-    /// this is [ %Pack1, %Pack0 ].
-    SmallVector<Instruction *> Instrs;
-    /// The "external" operands of the pack pattern, i.e., the values that get
-    /// packed into a vector, skipping the ones in `Instrs`. The operands are in
-    /// bottom-up order, starting from the operands of the bottom-most insert.
-    /// So in our example this would be [ %v1, %v0 ].
-    SmallVector<Value *> Operands;
-  };
-
-  /// If \p I is the last instruction of a pack pattern (i.e., an InsertElement
-  /// into a vector), then this function returns the instructions in the pack
-  /// and the operands in the pack, else returns nullopt.
-  /// Here is an example of a matched pattern:
-  ///  %PackA0 = insertelement <2 x i8> poison, i8 %v0, i64 0
-  ///  %PackA1 = insertelement <2 x i8> %PackA0, i8 %v1, i64 1
-  /// TODO: this currently detects only simple canonicalized patterns.
-  static std::optional<PackPattern> matchPack(Instruction *I) {
-    // TODO: Support vector pack patterns.
-    // TODO: Support out-of-order inserts.
-
-    // Early return if `I` is not an Insert.
-    if (!isa<InsertElementInst>(I))
-      return std::nullopt;
-    auto *BB0 = I->getParent();
-    // The pack contains as many instrs as the lanes of the bottom-most Insert
-    unsigned ExpectedNumInserts = VecUtils::getNumLanes(I);
-    assert(ExpectedNumInserts >= 2 && "Expected at least 2 inserts!");
-    PackPattern Pack;
-    Pack.Operands.resize(ExpectedNumInserts);
-    // Collect the inserts by walking up the use-def chain.
-    Instruction *InsertI = I;
-    for (auto ExpectedLane : reverse(seq<unsigned>(ExpectedNumInserts))) {
-      if (InsertI == nullptr)
-        return std::nullopt;
-      if (InsertI->getParent() != BB0)
-        return std::nullopt;
-      // Check the lane.
-      auto *LaneC = dyn_cast<ConstantInt>(InsertI->getOperand(2));
-      if (LaneC == nullptr || LaneC->getSExtValue() != ExpectedLane)
-        return std::nullopt;
-      Pack.Instrs.push_back(InsertI);
-      Pack.Operands[ExpectedLane] = InsertI->getOperand(1);
-
-      Value *Op = InsertI->getOperand(0);
-      if (ExpectedLane == 0) {
-        // Check the topmost insert. The operand should be a Poison.
-        if (!isa<PoisonValue>(Op))
-          return std::nullopt;
-      } else {
-        InsertI = dyn_cast<InsertElementInst>(Op);
-      }
-    }
-    return Pack;
-  }
-
-#ifndef NDEBUG
-  /// Helper dump function for debugging.
-  LLVM_DUMP_METHOD static void dump(ArrayRef<Value *> Bndl);
-  LLVM_DUMP_METHOD static void dump(ArrayRef<Instruction *> Bndl);
-#endif // NDEBUG
-};
-
-} // namespace sandboxir
-
-} // namespace llvm
-
-#endif // LLVM_TRANSFORMS_VECTORIZE_SANDBOXVECTORIZER_VECUTILS_H
diff --git a/llvm/include/module.modulemap b/llvm/include/module.modulemap
index 6269acb71d132..11544b7a9e27e 100644
--- a/llvm/include/module.modulemap
+++ b/llvm/include/module.modulemap
@@ -444,12 +444,3 @@ module LLVM_WindowsManifest {
   umbrella "llvm/WindowsManifest"
   module * { export * }
 }
-
-module LLVM_SandboxIR {
-  requires cplusplus
-
-  umbrella "llvm/SandboxIR"
-  module * { export * }
-
-  textual header "llvm/SandboxIR/Values.def"
-}
diff --git a/llvm/lib/CMakeLists.txt b/llvm/lib/CMakeLists.txt
index a9432977718c6..964f906e63b98 100644
--- a/llvm/lib/CMakeLists.txt
+++ b/llvm/lib/CMakeLists.txt
@@ -36,7 +36,6 @@ add_subdirectory(DWARFCFIChecker)
 add_subdirectory(DWP)
 add_subdirectory(ExecutionEngine)
 add_subdirectory(Target)
-add_subdirectory(SandboxIR)
 add_subdirectory(AsmParser)
 add_subdirectory(LineEditor)
 add_subdirectory(ProfileData)
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 3c9a27ac24015..62241f29c2102 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -380,7 +380,6 @@
 #include "llvm/Transforms/Vectorize/LoopIdiomVectorize.h"
 #include "llvm/Transforms/Vectorize/LoopVectorize.h"
 #include "llvm/Transforms/Vectorize/SLPVectorizer.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
 #include "llvm/Transforms/Vectorize/VectorCombine.h"
 #include <optional>
 
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 1853cdd45d0ee..b45f38c7ad9d1 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -534,7 +534,6 @@ FUNCTION_PASS("redundant-dbg-inst-elim", RedundantDbgInstEliminationPass())
 FUNCTION_PASS("replace-with-veclib", ReplaceWithVeclib())
 FUNCTION_PASS("reg2mem", RegToMemPass())
 FUNCTION_PASS("safe-stack", SafeStackPass(*TM))
-FUNCTION_PASS("sandbox-vectorizer", SandboxVectorizerPass())
 FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass())
 FUNCTION_PASS("sccp", SCCPPass())
 FUNCTION_PASS("select-optimize", SelectOptimizePass(*TM))
diff --git a/llvm/lib/SandboxIR/Argument.cpp b/llvm/lib/SandboxIR/Argument.cpp
deleted file mode 100644
index e35da2d1dbcb7..0000000000000
--- a/llvm/lib/SandboxIR/Argument.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//===- Argument.cpp - The function Argument class of Sandbox IR -----------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Argument.h"
-
-namespace llvm::sandboxir {
-
-#ifndef NDEBUG
-void Argument::printAsOperand(raw_ostream &OS) const {
-  printAsOperandCommon(OS);
-}
-void Argument::dumpOS(raw_ostream &OS) const {
-  dumpCommonPrefix(OS);
-  dumpCommonSuffix(OS);
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/BasicBlock.cpp b/llvm/lib/SandboxIR/BasicBlock.cpp
deleted file mode 100644
index b45c046402487..0000000000000
--- a/llvm/lib/SandboxIR/BasicBlock.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-//===- BasicBlock.cpp - The BasicBlock class of Sandbox IR ----------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/BasicBlock.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-
-namespace llvm::sandboxir {
-
-BBIterator &BBIterator::operator++() {
-  auto ItE = BB->end();
-  assert(It != ItE && "Already at end!");
-  ++It;
-  if (It == ItE)
-    return *this;
-  Instruction &NextI = *cast<sandboxir::Instruction>(Ctx->getValue(&*It));
-  unsigned Num = NextI.getNumOfIRInstrs();
-  assert(Num > 0 && "Bad getNumOfIRInstrs()");
-  It = std::next(It, Num - 1);
-  return *this;
-}
-
-BBIterator &BBIterator::operator--() {
-  assert(It != BB->begin() && "Already at begin!");
-  if (It == BB->end()) {
-    --It;
-    return *this;
-  }
-  Instruction &CurrI = **this;
-  unsigned Num = CurrI.getNumOfIRInstrs();
-  assert(Num > 0 && "Bad getNumOfIRInstrs()");
-  assert(std::prev(It, Num - 1) != BB->begin() && "Already at begin!");
-  It = std::prev(It, Num);
-  return *this;
-}
-
-BasicBlock *BBIterator::getNodeParent() const {
-  llvm::BasicBlock *Parent = const_cast<BBIterator *>(this)->It.getNodeParent();
-  return cast<BasicBlock>(Ctx->getValue(Parent));
-}
-
-BasicBlock::iterator::pointer
-BasicBlock::iterator::getInstr(llvm::BasicBlock::iterator It) const {
-  return cast_or_null<Instruction>(Ctx->getValue(&*It));
-}
-
-Function *BasicBlock::getParent() const {
-  auto *BB = cast<llvm::BasicBlock>(Val);
-  auto *F = BB->getParent();
-  if (F == nullptr)
-    // Detached
-    return nullptr;
-  return cast_or_null<Function>(Ctx.getValue(F));
-}
-
-void BasicBlock::buildBasicBlockFromLLVMIR(llvm::BasicBlock *LLVMBB) {
-  for (llvm::Instruction &IRef : reverse(*LLVMBB)) {
-    llvm::Instruction *I = &IRef;
-    Ctx.getOrCreateValue(I);
-    for (auto [OpIdx, Op] : enumerate(I->operands())) {
-      // Skip instruction's label operands
-      if (isa<llvm::BasicBlock>(Op))
-        continue;
-      Ctx.getOrCreateValue(Op);
-    }
-  }
-#if !defined(NDEBUG)
-  verify();
-#endif
-}
-
-BasicBlock::iterator BasicBlock::begin() const {
-  llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
-  llvm::BasicBlock::iterator It = BB->begin();
-  if (!BB->empty()) {
-    auto *V = Ctx.getValue(&*BB->begin());
-    assert(V != nullptr && "No SandboxIR for BB->begin()!");
-    auto *I = cast<Instruction>(V);
-    unsigned Num = I->getNumOfIRInstrs();
-    assert(Num >= 1u && "Bad getNumOfIRInstrs()");
-    It = std::next(It, Num - 1);
-  }
-  return iterator(BB, It, &Ctx);
-}
-
-Instruction *BasicBlock::getTerminator() const {
-  auto *TerminatorV =
-      Ctx.getValue(cast<llvm::BasicBlock>(Val)->getTerminator());
-  return cast_or_null<Instruction>(TerminatorV);
-}
-
-Instruction &BasicBlock::front() const {
-  auto *BB = cast<llvm::BasicBlock>(Val);
-  assert(!BB->empty() && "Empty block!");
-  auto *SBI = cast<Instruction>(getContext().getValue(&*BB->begin()));
-  assert(SBI != nullptr && "Expected Instr!");
-  return *SBI;
-}
-
-Instruction &BasicBlock::back() const {
-  auto *BB = cast<llvm::BasicBlock>(Val);
-  assert(!BB->empty() && "Empty block!");
-  auto *SBI = cast<Instruction>(getContext().getValue(&*BB->rbegin()));
-  assert(SBI != nullptr && "Expected Instr!");
-  return *SBI;
-}
-
-#ifndef NDEBUG
-void BasicBlock::dumpOS(raw_ostream &OS) const {
-  llvm::BasicBlock *BB = cast<llvm::BasicBlock>(Val);
-  const auto &Name = BB->getName();
-  OS << Name;
-  if (!Name.empty())
-    OS << ":\n";
-  // If there are Instructions in the BB that are not mapped to SandboxIR, then
-  // use a crash-proof dump.
-  if (any_of(*BB, [this](llvm::Instruction &I) {
-        return Ctx.getValue(&I) == nullptr;
-      })) {
-    OS << "<Crash-proof mode!>\n";
-    DenseSet<Instruction *> Visited;
-    for (llvm::Instruction &IRef : *BB) {
-      Value *SBV = Ctx.getValue(&IRef);
-      if (SBV == nullptr)
-        OS << IRef << " *** No SandboxIR ***\n";
-      else {
-        auto *SBI = dyn_cast<Instruction>(SBV);
-        if (SBI == nullptr) {
-          OS << IRef << " *** Not a SBInstruction!!! ***\n";
-        } else {
-          if (Visited.insert(SBI).second)
-            OS << *SBI << "\n";
-        }
-      }
-    }
-  } else {
-    for (auto &SBI : *this) {
-      SBI.dumpOS(OS);
-      OS << "\n";
-    }
-  }
-}
-
-void BasicBlock::verify() const {
-  assert(isa<llvm::BasicBlock>(Val) && "Expected BasicBlock!");
-  for (const auto &I : *this) {
-    I.verify();
-  }
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/CMakeLists.txt b/llvm/lib/SandboxIR/CMakeLists.txt
deleted file mode 100644
index 3ec53b04b046f..0000000000000
--- a/llvm/lib/SandboxIR/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-add_llvm_component_library(LLVMSandboxIR
-  Argument.cpp
-  BasicBlock.cpp
-  Constant.cpp
-  Context.cpp
-  Function.cpp
-  Instruction.cpp
-  Module.cpp
-  Pass.cpp
-  PassManager.cpp
-  Region.cpp
-  Tracker.cpp
-  Type.cpp
-  User.cpp
-  Use.cpp
-  Value.cpp
-
-  ADDITIONAL_HEADER_DIRS
-  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/SandboxIR
-
-  LINK_COMPONENTS
-  Core
-  Support
-  Analysis
-  )
-
diff --git a/llvm/lib/SandboxIR/Constant.cpp b/llvm/lib/SandboxIR/Constant.cpp
deleted file mode 100644
index 9de88ef2cf0a0..0000000000000
--- a/llvm/lib/SandboxIR/Constant.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-//===- Constant.cpp - The Constant classes of Sandbox IR ------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/BasicBlock.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/Support/Compiler.h"
-
-namespace llvm::sandboxir {
-
-#ifndef NDEBUG
-void Constant::dumpOS(raw_ostream &OS) const {
-  dumpCommonPrefix(OS);
-  dumpCommonSuffix(OS);
-}
-#endif // NDEBUG
-
-ConstantInt *ConstantInt::getTrue(Context &Ctx) {
-  auto *LLVMC = llvm::ConstantInt::getTrue(Ctx.LLVMCtx);
-  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::getFalse(Context &Ctx) {
-  auto *LLVMC = llvm::ConstantInt::getFalse(Ctx.LLVMCtx);
-  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::getBool(Context &Ctx, bool V) {
-  auto *LLVMC = llvm::ConstantInt::getBool(Ctx.LLVMCtx, V);
-  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-Constant *ConstantInt::getTrue(Type *Ty) {
-  auto *LLVMC = llvm::ConstantInt::getTrue(Ty->LLVMTy);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-Constant *ConstantInt::getFalse(Type *Ty) {
-  auto *LLVMC = llvm::ConstantInt::getFalse(Ty->LLVMTy);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-Constant *ConstantInt::getBool(Type *Ty, bool V) {
-  auto *LLVMC = llvm::ConstantInt::getBool(Ty->LLVMTy, V);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-ConstantInt *ConstantInt::get(Type *Ty, uint64_t V, bool IsSigned) {
-  auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
-  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::get(IntegerType *Ty, uint64_t V, bool IsSigned) {
-  auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V, IsSigned);
-  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::getSigned(IntegerType *Ty, int64_t V) {
-  auto *LLVMC =
-      llvm::ConstantInt::getSigned(cast<llvm::IntegerType>(Ty->LLVMTy), V);
-  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantInt::getSigned(Type *Ty, int64_t V) {
-  auto *LLVMC = llvm::ConstantInt::getSigned(Ty->LLVMTy, V);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-ConstantInt *ConstantInt::get(Context &Ctx, const APInt &V) {
-  auto *LLVMC = llvm::ConstantInt::get(Ctx.LLVMCtx, V);
-  return cast<ConstantInt>(Ctx.getOrCreateConstant(LLVMC));
-}
-ConstantInt *ConstantInt::get(IntegerType *Ty, StringRef Str, uint8_t Radix) {
-  auto *LLVMC =
-      llvm::ConstantInt::get(cast<llvm::IntegerType>(Ty->LLVMTy), Str, Radix);
-  return cast<ConstantInt>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantInt::get(Type *Ty, const APInt &V) {
-  auto *LLVMC = llvm::ConstantInt::get(Ty->LLVMTy, V);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-IntegerType *ConstantInt::getIntegerType() const {
-  auto *LLVMTy = cast<llvm::ConstantInt>(Val)->getIntegerType();
-  return cast<IntegerType>(Ctx.getType(LLVMTy));
-}
-
-bool ConstantInt::isValueValidForType(Type *Ty, uint64_t V) {
-  return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
-}
-bool ConstantInt::isValueValidForType(Type *Ty, int64_t V) {
-  return llvm::ConstantInt::isValueValidForType(Ty->LLVMTy, V);
-}
-
-Constant *ConstantFP::get(Type *Ty, double V) {
-  auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-
-Constant *ConstantFP::get(Type *Ty, const APFloat &V) {
-  auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, V);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-
-Constant *ConstantFP::get(Type *Ty, StringRef Str) {
-  auto *LLVMC = llvm::ConstantFP::get(Ty->LLVMTy, Str);
-  return Ty->getContext().getOrCreateConstant(LLVMC);
-}
-
-ConstantFP *ConstantFP::get(const APFloat &V, Context &Ctx) {
-  auto *LLVMC = llvm::ConstantFP::get(Ctx.LLVMCtx, V);
-  return cast<ConstantFP>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-Constant *ConstantFP::getNaN(Type *Ty, bool Negative, uint64_t Payload) {
-  auto *LLVMC = llvm::ConstantFP::getNaN(Ty->LLVMTy, Negative, Payload);
-  return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getQNaN(Type *Ty, bool Negative, APInt *Payload) {
-  auto *LLVMC = llvm::ConstantFP::getQNaN(Ty->LLVMTy, Negative, Payload);
-  return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getSNaN(Type *Ty, bool Negative, APInt *Payload) {
-  auto *LLVMC = llvm::ConstantFP::getSNaN(Ty->LLVMTy, Negative, Payload);
-  return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getZero(Type *Ty, bool Negative) {
-  auto *LLVMC = llvm::ConstantFP::getZero(Ty->LLVMTy, Negative);
-  return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getNegativeZero(Type *Ty) {
-  auto *LLVMC = llvm::ConstantFP::getNegativeZero(Ty->LLVMTy);
-  return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
-  auto *LLVMC = llvm::ConstantFP::getInfinity(Ty->LLVMTy, Negative);
-  return cast<Constant>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-bool ConstantFP::isValueValidForType(Type *Ty, const APFloat &V) {
-  return llvm::ConstantFP::isValueValidForType(Ty->LLVMTy, V);
-}
-
-Constant *ConstantArray::get(ArrayType *T, ArrayRef<Constant *> V) {
-  auto &Ctx = T->getContext();
-  SmallVector<llvm::Constant *> LLVMValues;
-  LLVMValues.reserve(V.size());
-  for (auto *Elm : V)
-    LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));
-  auto *LLVMC =
-      llvm::ConstantArray::get(cast<llvm::ArrayType>(T->LLVMTy), LLVMValues);
-  return cast<ConstantArray>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-ArrayType *ConstantArray::getType() const {
-  return cast<ArrayType>(
-      Ctx.getType(cast<llvm::ConstantArray>(Val)->getType()));
-}
-
-Constant *ConstantStruct::get(StructType *T, ArrayRef<Constant *> V) {
-  auto &Ctx = T->getContext();
-  SmallVector<llvm::Constant *> LLVMValues;
-  LLVMValues.reserve(V.size());
-  for (auto *Elm : V)
-    LLVMValues.push_back(cast<llvm::Constant>(Elm->Val));
-  auto *LLVMC =
-      llvm::ConstantStruct::get(cast<llvm::StructType>(T->LLVMTy), LLVMValues);
-  return cast<ConstantStruct>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-StructType *ConstantStruct::getTypeForElements(Context &Ctx,
-                                               ArrayRef<Constant *> V,
-                                               bool Packed) {
-  unsigned VecSize = V.size();
-  SmallVector<Type *, 16> EltTypes;
-  EltTypes.reserve(VecSize);
-  for (Constant *Elm : V)
-    EltTypes.push_back(Elm->getType());
-  return StructType::get(Ctx, EltTypes, Packed);
-}
-
-Constant *ConstantVector::get(ArrayRef<Constant *> V) {
-  assert(!V.empty() && "Expected non-empty V!");
-  auto &Ctx = V[0]->getContext();
-  SmallVector<llvm::Constant *, 8> LLVMV;
-  LLVMV.reserve(V.size());
-  for (auto *Elm : V)
-    LLVMV.push_back(cast<llvm::Constant>(Elm->Val));
-  return Ctx.getOrCreateConstant(llvm::ConstantVector::get(LLVMV));
-}
-
-Constant *ConstantVector::getSplat(ElementCount EC, Constant *Elt) {
-  auto *LLVMElt = cast<llvm::Constant>(Elt->Val);
-  auto &Ctx = Elt->getContext();
-  return Ctx.getOrCreateConstant(llvm::ConstantVector::getSplat(EC, LLVMElt));
-}
-
-Constant *ConstantVector::getSplatValue(bool AllowPoison) const {
-  auto *LLVMSplatValue = cast_or_null<llvm::Constant>(
-      cast<llvm::ConstantVector>(Val)->getSplatValue(AllowPoison));
-  return LLVMSplatValue ? Ctx.getOrCreateConstant(LLVMSplatValue) : nullptr;
-}
-
-ConstantAggregateZero *ConstantAggregateZero::get(Type *Ty) {
-  auto *LLVMC = llvm::ConstantAggregateZero::get(Ty->LLVMTy);
-  return cast<ConstantAggregateZero>(
-      Ty->getContext().getOrCreateConstant(LLVMC));
-}
-
-Constant *ConstantAggregateZero::getSequentialElement() const {
-  return cast<Constant>(Ctx.getValue(
-      cast<llvm::ConstantAggregateZero>(Val)->getSequentialElement()));
-}
-Constant *ConstantAggregateZero::getStructElement(unsigned Elt) const {
-  return cast<Constant>(Ctx.getValue(
-      cast<llvm::ConstantAggregateZero>(Val)->getStructElement(Elt)));
-}
-Constant *ConstantAggregateZero::getElementValue(Constant *C) const {
-  return cast<Constant>(
-      Ctx.getValue(cast<llvm::ConstantAggregateZero>(Val)->getElementValue(
-          cast<llvm::Constant>(C->Val))));
-}
-Constant *ConstantAggregateZero::getElementValue(unsigned Idx) const {
-  return cast<Constant>(Ctx.getValue(
-      cast<llvm::ConstantAggregateZero>(Val)->getElementValue(Idx)));
-}
-
-ConstantPointerNull *ConstantPointerNull::get(PointerType *Ty) {
-  auto *LLVMC =
-      llvm::ConstantPointerNull::get(cast<llvm::PointerType>(Ty->LLVMTy));
-  return cast<ConstantPointerNull>(Ty->getContext().getOrCreateConstant(LLVMC));
-}
-
-PointerType *ConstantPointerNull::getType() const {
-  return cast<PointerType>(
-      Ctx.getType(cast<llvm::ConstantPointerNull>(Val)->getType()));
-}
-
-UndefValue *UndefValue::get(Type *T) {
-  auto *LLVMC = llvm::UndefValue::get(T->LLVMTy);
-  return cast<UndefValue>(T->getContext().getOrCreateConstant(LLVMC));
-}
-
-UndefValue *UndefValue::getSequentialElement() const {
-  return cast<UndefValue>(Ctx.getOrCreateConstant(
-      cast<llvm::UndefValue>(Val)->getSequentialElement()));
-}
-
-UndefValue *UndefValue::getStructElement(unsigned Elt) const {
-  return cast<UndefValue>(Ctx.getOrCreateConstant(
-      cast<llvm::UndefValue>(Val)->getStructElement(Elt)));
-}
-
-UndefValue *UndefValue::getElementValue(Constant *C) const {
-  return cast<UndefValue>(
-      Ctx.getOrCreateConstant(cast<llvm::UndefValue>(Val)->getElementValue(
-          cast<llvm::Constant>(C->Val))));
-}
-
-UndefValue *UndefValue::getElementValue(unsigned Idx) const {
-  return cast<UndefValue>(Ctx.getOrCreateConstant(
-      cast<llvm::UndefValue>(Val)->getElementValue(Idx)));
-}
-
-PoisonValue *PoisonValue::get(Type *T) {
-  auto *LLVMC = llvm::PoisonValue::get(T->LLVMTy);
-  return cast<PoisonValue>(T->getContext().getOrCreateConstant(LLVMC));
-}
-
-PoisonValue *PoisonValue::getSequentialElement() const {
-  return cast<PoisonValue>(Ctx.getOrCreateConstant(
-      cast<llvm::PoisonValue>(Val)->getSequentialElement()));
-}
-
-PoisonValue *PoisonValue::getStructElement(unsigned Elt) const {
-  return cast<PoisonValue>(Ctx.getOrCreateConstant(
-      cast<llvm::PoisonValue>(Val)->getStructElement(Elt)));
-}
-
-PoisonValue *PoisonValue::getElementValue(Constant *C) const {
-  return cast<PoisonValue>(
-      Ctx.getOrCreateConstant(cast<llvm::PoisonValue>(Val)->getElementValue(
-          cast<llvm::Constant>(C->Val))));
-}
-
-PoisonValue *PoisonValue::getElementValue(unsigned Idx) const {
-  return cast<PoisonValue>(Ctx.getOrCreateConstant(
-      cast<llvm::PoisonValue>(Val)->getElementValue(Idx)));
-}
-
-void GlobalVariable::setAlignment(MaybeAlign Align) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&GlobalVariable::getAlign,
-                                       &GlobalVariable::setAlignment>>(this);
-  cast<llvm::GlobalVariable>(Val)->setAlignment(Align);
-}
-
-void GlobalObject::setSection(StringRef S) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&GlobalObject::getSection, &GlobalObject::setSection>>(
-          this);
-  cast<llvm::GlobalObject>(Val)->setSection(S);
-}
-
-template <typename GlobalT, typename LLVMGlobalT, typename ParentT,
-          typename LLVMParentT>
-GlobalT &GlobalWithNodeAPI<GlobalT, LLVMGlobalT, ParentT, LLVMParentT>::
-    LLVMGVToGV::operator()(LLVMGlobalT &LLVMGV) const {
-  return cast<GlobalT>(*Ctx.getValue(&LLVMGV));
-}
-
-// Explicit instantiations.
-template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<
-    GlobalIFunc, llvm::GlobalIFunc, GlobalObject, llvm::GlobalObject>;
-template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<
-    Function, llvm::Function, GlobalObject, llvm::GlobalObject>;
-template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<
-    GlobalVariable, llvm::GlobalVariable, GlobalObject, llvm::GlobalObject>;
-template class LLVM_EXPORT_TEMPLATE GlobalWithNodeAPI<
-    GlobalAlias, llvm::GlobalAlias, GlobalValue, llvm::GlobalValue>;
-
-void GlobalIFunc::setResolver(Constant *Resolver) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&GlobalIFunc::getResolver, &GlobalIFunc::setResolver>>(
-          this);
-  cast<llvm::GlobalIFunc>(Val)->setResolver(
-      cast<llvm::Constant>(Resolver->Val));
-}
-
-Constant *GlobalIFunc::getResolver() const {
-  return Ctx.getOrCreateConstant(cast<llvm::GlobalIFunc>(Val)->getResolver());
-}
-
-Function *GlobalIFunc::getResolverFunction() {
-  return cast<Function>(Ctx.getOrCreateConstant(
-      cast<llvm::GlobalIFunc>(Val)->getResolverFunction()));
-}
-
-GlobalVariable &
-GlobalVariable::LLVMGVToGV::operator()(llvm::GlobalVariable &LLVMGV) const {
-  return cast<GlobalVariable>(*Ctx.getValue(&LLVMGV));
-}
-
-Constant *GlobalVariable::getInitializer() const {
-  return Ctx.getOrCreateConstant(
-      cast<llvm::GlobalVariable>(Val)->getInitializer());
-}
-
-void GlobalVariable::setInitializer(Constant *InitVal) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&GlobalVariable::getInitializer,
-                                       &GlobalVariable::setInitializer>>(this);
-  cast<llvm::GlobalVariable>(Val)->setInitializer(
-      cast<llvm::Constant>(InitVal->Val));
-}
-
-void GlobalVariable::setConstant(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&GlobalVariable::isConstant,
-                                       &GlobalVariable::setConstant>>(this);
-  cast<llvm::GlobalVariable>(Val)->setConstant(V);
-}
-
-void GlobalVariable::setExternallyInitialized(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&GlobalVariable::isExternallyInitialized,
-                        &GlobalVariable::setExternallyInitialized>>(this);
-  cast<llvm::GlobalVariable>(Val)->setExternallyInitialized(V);
-}
-
-void GlobalAlias::setAliasee(Constant *Aliasee) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&GlobalAlias::getAliasee, &GlobalAlias::setAliasee>>(
-          this);
-  cast<llvm::GlobalAlias>(Val)->setAliasee(cast<llvm::Constant>(Aliasee->Val));
-}
-
-Constant *GlobalAlias::getAliasee() const {
-  return cast<Constant>(
-      Ctx.getOrCreateConstant(cast<llvm::GlobalAlias>(Val)->getAliasee()));
-}
-
-const GlobalObject *GlobalAlias::getAliaseeObject() const {
-  return cast<GlobalObject>(Ctx.getOrCreateConstant(
-      cast<llvm::GlobalAlias>(Val)->getAliaseeObject()));
-}
-
-void GlobalValue::setUnnamedAddr(UnnamedAddr V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&GlobalValue::getUnnamedAddr,
-                                       &GlobalValue::setUnnamedAddr>>(this);
-  cast<llvm::GlobalValue>(Val)->setUnnamedAddr(V);
-}
-
-void GlobalValue::setVisibility(VisibilityTypes V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&GlobalValue::getVisibility,
-                                       &GlobalValue::setVisibility>>(this);
-  cast<llvm::GlobalValue>(Val)->setVisibility(V);
-}
-
-NoCFIValue *NoCFIValue::get(GlobalValue *GV) {
-  auto *LLVMC = llvm::NoCFIValue::get(cast<llvm::GlobalValue>(GV->Val));
-  return cast<NoCFIValue>(GV->getContext().getOrCreateConstant(LLVMC));
-}
-
-GlobalValue *NoCFIValue::getGlobalValue() const {
-  auto *LLVMC = cast<llvm::NoCFIValue>(Val)->getGlobalValue();
-  return cast<GlobalValue>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-PointerType *NoCFIValue::getType() const {
-  return cast<PointerType>(Ctx.getType(cast<llvm::NoCFIValue>(Val)->getType()));
-}
-
-ConstantPtrAuth *ConstantPtrAuth::get(Constant *Ptr, ConstantInt *Key,
-                                      ConstantInt *Disc, Constant *AddrDisc) {
-  auto *LLVMC = llvm::ConstantPtrAuth::get(
-      cast<llvm::Constant>(Ptr->Val), cast<llvm::ConstantInt>(Key->Val),
-      cast<llvm::ConstantInt>(Disc->Val), cast<llvm::Constant>(AddrDisc->Val));
-  return cast<ConstantPtrAuth>(Ptr->getContext().getOrCreateConstant(LLVMC));
-}
-
-Constant *ConstantPtrAuth::getPointer() const {
-  return Ctx.getOrCreateConstant(
-      cast<llvm::ConstantPtrAuth>(Val)->getPointer());
-}
-
-ConstantInt *ConstantPtrAuth::getKey() const {
-  return cast<ConstantInt>(
-      Ctx.getOrCreateConstant(cast<llvm::ConstantPtrAuth>(Val)->getKey()));
-}
-
-ConstantInt *ConstantPtrAuth::getDiscriminator() const {
-  return cast<ConstantInt>(Ctx.getOrCreateConstant(
-      cast<llvm::ConstantPtrAuth>(Val)->getDiscriminator()));
-}
-
-Constant *ConstantPtrAuth::getAddrDiscriminator() const {
-  return Ctx.getOrCreateConstant(
-      cast<llvm::ConstantPtrAuth>(Val)->getAddrDiscriminator());
-}
-
-ConstantPtrAuth *ConstantPtrAuth::getWithSameSchema(Constant *Pointer) const {
-  auto *LLVMC = cast<llvm::ConstantPtrAuth>(Val)->getWithSameSchema(
-      cast<llvm::Constant>(Pointer->Val));
-  return cast<ConstantPtrAuth>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
-  auto *LLVMC = llvm::BlockAddress::get(cast<llvm::Function>(F->Val),
-                                        cast<llvm::BasicBlock>(BB->Val));
-  return cast<BlockAddress>(F->getContext().getOrCreateConstant(LLVMC));
-}
-
-BlockAddress *BlockAddress::get(BasicBlock *BB) {
-  auto *LLVMC = llvm::BlockAddress::get(cast<llvm::BasicBlock>(BB->Val));
-  return cast<BlockAddress>(BB->getContext().getOrCreateConstant(LLVMC));
-}
-
-BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
-  auto *LLVMC = llvm::BlockAddress::lookup(cast<llvm::BasicBlock>(BB->Val));
-  return cast_or_null<BlockAddress>(BB->getContext().getValue(LLVMC));
-}
-
-Function *BlockAddress::getFunction() const {
-  return cast<Function>(
-      Ctx.getValue(cast<llvm::BlockAddress>(Val)->getFunction()));
-}
-
-BasicBlock *BlockAddress::getBasicBlock() const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::BlockAddress>(Val)->getBasicBlock()));
-}
-
-DSOLocalEquivalent *DSOLocalEquivalent::get(GlobalValue *GV) {
-  auto *LLVMC = llvm::DSOLocalEquivalent::get(cast<llvm::GlobalValue>(GV->Val));
-  return cast<DSOLocalEquivalent>(GV->getContext().getValue(LLVMC));
-}
-
-GlobalValue *DSOLocalEquivalent::getGlobalValue() const {
-  return cast<GlobalValue>(
-      Ctx.getValue(cast<llvm::DSOLocalEquivalent>(Val)->getGlobalValue()));
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Context.cpp b/llvm/lib/SandboxIR/Context.cpp
deleted file mode 100644
index 6f5d072fb6913..0000000000000
--- a/llvm/lib/SandboxIR/Context.cpp
+++ /dev/null
@@ -1,781 +0,0 @@
-//===- Context.cpp - The Context class of Sandbox IR ----------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/IR/InlineAsm.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Module.h"
-
-namespace llvm::sandboxir {
-
-std::unique_ptr<Value> Context::detachLLVMValue(llvm::Value *V) {
-  std::unique_ptr<Value> Erased;
-  auto It = LLVMValueToValueMap.find(V);
-  if (It != LLVMValueToValueMap.end()) {
-    auto *Val = It->second.release();
-    Erased = std::unique_ptr<Value>(Val);
-    LLVMValueToValueMap.erase(It);
-  }
-  return Erased;
-}
-
-std::unique_ptr<Value> Context::detach(Value *V) {
-  assert(V->getSubclassID() != Value::ClassID::Constant &&
-         "Can't detach a constant!");
-  assert(V->getSubclassID() != Value::ClassID::User && "Can't detach a user!");
-  return detachLLVMValue(V->Val);
-}
-
-Value *Context::registerValue(std::unique_ptr<Value> &&VPtr) {
-  assert(VPtr->getSubclassID() != Value::ClassID::User &&
-         "Can't register a user!");
-
-  Value *V = VPtr.get();
-  [[maybe_unused]] auto Pair =
-      LLVMValueToValueMap.insert({VPtr->Val, std::move(VPtr)});
-  assert(Pair.second && "Already exists!");
-
-  // Track creation of instructions.
-  // Please note that we don't allow the creation of detached instructions,
-  // meaning that the instructions need to be inserted into a block upon
-  // creation. This is why the tracker class combines creation and insertion.
-  if (auto *I = dyn_cast<Instruction>(V)) {
-    getTracker().emplaceIfTracking<CreateAndInsertInst>(I);
-    runCreateInstrCallbacks(I);
-  }
-
-  return V;
-}
-
-Value *Context::getOrCreateValueInternal(llvm::Value *LLVMV, llvm::User *U) {
-  auto Pair = LLVMValueToValueMap.try_emplace(LLVMV);
-  auto It = Pair.first;
-  if (!Pair.second)
-    return It->second.get();
-
-  // Instruction
-  if (auto *LLVMI = dyn_cast<llvm::Instruction>(LLVMV)) {
-    switch (LLVMI->getOpcode()) {
-    case llvm::Instruction::VAArg: {
-      auto *LLVMVAArg = cast<llvm::VAArgInst>(LLVMV);
-      It->second = std::unique_ptr<VAArgInst>(new VAArgInst(LLVMVAArg, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Freeze: {
-      auto *LLVMFreeze = cast<llvm::FreezeInst>(LLVMV);
-      It->second =
-          std::unique_ptr<FreezeInst>(new FreezeInst(LLVMFreeze, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Fence: {
-      auto *LLVMFence = cast<llvm::FenceInst>(LLVMV);
-      It->second = std::unique_ptr<FenceInst>(new FenceInst(LLVMFence, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Select: {
-      auto *LLVMSel = cast<llvm::SelectInst>(LLVMV);
-      It->second = std::unique_ptr<SelectInst>(new SelectInst(LLVMSel, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::ExtractElement: {
-      auto *LLVMIns = cast<llvm::ExtractElementInst>(LLVMV);
-      It->second = std::unique_ptr<ExtractElementInst>(
-          new ExtractElementInst(LLVMIns, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::InsertElement: {
-      auto *LLVMIns = cast<llvm::InsertElementInst>(LLVMV);
-      It->second = std::unique_ptr<InsertElementInst>(
-          new InsertElementInst(LLVMIns, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::ShuffleVector: {
-      auto *LLVMIns = cast<llvm::ShuffleVectorInst>(LLVMV);
-      It->second = std::unique_ptr<ShuffleVectorInst>(
-          new ShuffleVectorInst(LLVMIns, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::ExtractValue: {
-      auto *LLVMIns = cast<llvm::ExtractValueInst>(LLVMV);
-      It->second = std::unique_ptr<ExtractValueInst>(
-          new ExtractValueInst(LLVMIns, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::InsertValue: {
-      auto *LLVMIns = cast<llvm::InsertValueInst>(LLVMV);
-      It->second =
-          std::unique_ptr<InsertValueInst>(new InsertValueInst(LLVMIns, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Br: {
-      auto *LLVMBr = cast<llvm::BranchInst>(LLVMV);
-      It->second = std::unique_ptr<BranchInst>(new BranchInst(LLVMBr, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Load: {
-      auto *LLVMLd = cast<llvm::LoadInst>(LLVMV);
-      It->second = std::unique_ptr<LoadInst>(new LoadInst(LLVMLd, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Store: {
-      auto *LLVMSt = cast<llvm::StoreInst>(LLVMV);
-      It->second = std::unique_ptr<StoreInst>(new StoreInst(LLVMSt, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Ret: {
-      auto *LLVMRet = cast<llvm::ReturnInst>(LLVMV);
-      It->second = std::unique_ptr<ReturnInst>(new ReturnInst(LLVMRet, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Call: {
-      auto *LLVMCall = cast<llvm::CallInst>(LLVMV);
-      It->second = std::unique_ptr<CallInst>(new CallInst(LLVMCall, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Invoke: {
-      auto *LLVMInvoke = cast<llvm::InvokeInst>(LLVMV);
-      It->second =
-          std::unique_ptr<InvokeInst>(new InvokeInst(LLVMInvoke, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::CallBr: {
-      auto *LLVMCallBr = cast<llvm::CallBrInst>(LLVMV);
-      It->second =
-          std::unique_ptr<CallBrInst>(new CallBrInst(LLVMCallBr, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::LandingPad: {
-      auto *LLVMLPad = cast<llvm::LandingPadInst>(LLVMV);
-      It->second =
-          std::unique_ptr<LandingPadInst>(new LandingPadInst(LLVMLPad, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::CatchPad: {
-      auto *LLVMCPI = cast<llvm::CatchPadInst>(LLVMV);
-      It->second =
-          std::unique_ptr<CatchPadInst>(new CatchPadInst(LLVMCPI, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::CleanupPad: {
-      auto *LLVMCPI = cast<llvm::CleanupPadInst>(LLVMV);
-      It->second =
-          std::unique_ptr<CleanupPadInst>(new CleanupPadInst(LLVMCPI, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::CatchRet: {
-      auto *LLVMCRI = cast<llvm::CatchReturnInst>(LLVMV);
-      It->second =
-          std::unique_ptr<CatchReturnInst>(new CatchReturnInst(LLVMCRI, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::CleanupRet: {
-      auto *LLVMCRI = cast<llvm::CleanupReturnInst>(LLVMV);
-      It->second = std::unique_ptr<CleanupReturnInst>(
-          new CleanupReturnInst(LLVMCRI, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::GetElementPtr: {
-      auto *LLVMGEP = cast<llvm::GetElementPtrInst>(LLVMV);
-      It->second = std::unique_ptr<GetElementPtrInst>(
-          new GetElementPtrInst(LLVMGEP, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::CatchSwitch: {
-      auto *LLVMCatchSwitchInst = cast<llvm::CatchSwitchInst>(LLVMV);
-      It->second = std::unique_ptr<CatchSwitchInst>(
-          new CatchSwitchInst(LLVMCatchSwitchInst, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Resume: {
-      auto *LLVMResumeInst = cast<llvm::ResumeInst>(LLVMV);
-      It->second =
-          std::unique_ptr<ResumeInst>(new ResumeInst(LLVMResumeInst, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Switch: {
-      auto *LLVMSwitchInst = cast<llvm::SwitchInst>(LLVMV);
-      It->second =
-          std::unique_ptr<SwitchInst>(new SwitchInst(LLVMSwitchInst, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::FNeg: {
-      auto *LLVMUnaryOperator = cast<llvm::UnaryOperator>(LLVMV);
-      It->second = std::unique_ptr<UnaryOperator>(
-          new UnaryOperator(LLVMUnaryOperator, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Add:
-    case llvm::Instruction::FAdd:
-    case llvm::Instruction::Sub:
-    case llvm::Instruction::FSub:
-    case llvm::Instruction::Mul:
-    case llvm::Instruction::FMul:
-    case llvm::Instruction::UDiv:
-    case llvm::Instruction::SDiv:
-    case llvm::Instruction::FDiv:
-    case llvm::Instruction::URem:
-    case llvm::Instruction::SRem:
-    case llvm::Instruction::FRem:
-    case llvm::Instruction::Shl:
-    case llvm::Instruction::LShr:
-    case llvm::Instruction::AShr:
-    case llvm::Instruction::And:
-    case llvm::Instruction::Or:
-    case llvm::Instruction::Xor: {
-      auto *LLVMBinaryOperator = cast<llvm::BinaryOperator>(LLVMV);
-      It->second = std::unique_ptr<BinaryOperator>(
-          new BinaryOperator(LLVMBinaryOperator, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::AtomicRMW: {
-      auto *LLVMAtomicRMW = cast<llvm::AtomicRMWInst>(LLVMV);
-      It->second = std::unique_ptr<AtomicRMWInst>(
-          new AtomicRMWInst(LLVMAtomicRMW, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::AtomicCmpXchg: {
-      auto *LLVMAtomicCmpXchg = cast<llvm::AtomicCmpXchgInst>(LLVMV);
-      It->second = std::unique_ptr<AtomicCmpXchgInst>(
-          new AtomicCmpXchgInst(LLVMAtomicCmpXchg, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Alloca: {
-      auto *LLVMAlloca = cast<llvm::AllocaInst>(LLVMV);
-      It->second =
-          std::unique_ptr<AllocaInst>(new AllocaInst(LLVMAlloca, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::ZExt:
-    case llvm::Instruction::SExt:
-    case llvm::Instruction::FPToUI:
-    case llvm::Instruction::FPToSI:
-    case llvm::Instruction::FPExt:
-    case llvm::Instruction::PtrToAddr:
-    case llvm::Instruction::PtrToInt:
-    case llvm::Instruction::IntToPtr:
-    case llvm::Instruction::SIToFP:
-    case llvm::Instruction::UIToFP:
-    case llvm::Instruction::Trunc:
-    case llvm::Instruction::FPTrunc:
-    case llvm::Instruction::BitCast:
-    case llvm::Instruction::AddrSpaceCast: {
-      auto *LLVMCast = cast<llvm::CastInst>(LLVMV);
-      It->second = std::unique_ptr<CastInst>(new CastInst(LLVMCast, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::PHI: {
-      auto *LLVMPhi = cast<llvm::PHINode>(LLVMV);
-      It->second = std::unique_ptr<PHINode>(new PHINode(LLVMPhi, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::ICmp: {
-      auto *LLVMICmp = cast<llvm::ICmpInst>(LLVMV);
-      It->second = std::unique_ptr<ICmpInst>(new ICmpInst(LLVMICmp, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::FCmp: {
-      auto *LLVMFCmp = cast<llvm::FCmpInst>(LLVMV);
-      It->second = std::unique_ptr<FCmpInst>(new FCmpInst(LLVMFCmp, *this));
-      return It->second.get();
-    }
-    case llvm::Instruction::Unreachable: {
-      auto *LLVMUnreachable = cast<llvm::UnreachableInst>(LLVMV);
-      It->second = std::unique_ptr<UnreachableInst>(
-          new UnreachableInst(LLVMUnreachable, *this));
-      return It->second.get();
-    }
-    default:
-      break;
-    }
-    It->second = std::unique_ptr<OpaqueInst>(
-        new OpaqueInst(cast<llvm::Instruction>(LLVMV), *this));
-    return It->second.get();
-  }
-  // Constant
-  if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV)) {
-    switch (LLVMC->getValueID()) {
-    case llvm::Value::ConstantIntVal:
-      It->second = std::unique_ptr<ConstantInt>(
-          new ConstantInt(cast<llvm::ConstantInt>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::ConstantFPVal:
-      It->second = std::unique_ptr<ConstantFP>(
-          new ConstantFP(cast<llvm::ConstantFP>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::BlockAddressVal:
-      It->second = std::unique_ptr<BlockAddress>(
-          new BlockAddress(cast<llvm::BlockAddress>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::ConstantTokenNoneVal:
-      It->second = std::unique_ptr<ConstantTokenNone>(
-          new ConstantTokenNone(cast<llvm::ConstantTokenNone>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::ConstantAggregateZeroVal: {
-      auto *CAZ = cast<llvm::ConstantAggregateZero>(LLVMC);
-      It->second = std::unique_ptr<ConstantAggregateZero>(
-          new ConstantAggregateZero(CAZ, *this));
-      auto *Ret = It->second.get();
-      // Must create sandboxir for elements.
-      auto EC = CAZ->getElementCount();
-      if (EC.isFixed()) {
-        for (auto ElmIdx : seq<unsigned>(0, EC.getFixedValue()))
-          getOrCreateValueInternal(CAZ->getElementValue(ElmIdx), CAZ);
-      }
-      return Ret;
-    }
-    case llvm::Value::ConstantPointerNullVal:
-      It->second = std::unique_ptr<ConstantPointerNull>(new ConstantPointerNull(
-          cast<llvm::ConstantPointerNull>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::PoisonValueVal:
-      It->second = std::unique_ptr<PoisonValue>(
-          new PoisonValue(cast<llvm::PoisonValue>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::UndefValueVal:
-      It->second = std::unique_ptr<UndefValue>(
-          new UndefValue(cast<llvm::UndefValue>(LLVMC), *this));
-      return It->second.get();
-    case llvm::Value::DSOLocalEquivalentVal: {
-      auto *DSOLE = cast<llvm::DSOLocalEquivalent>(LLVMC);
-      It->second = std::unique_ptr<DSOLocalEquivalent>(
-          new DSOLocalEquivalent(DSOLE, *this));
-      auto *Ret = It->second.get();
-      getOrCreateValueInternal(DSOLE->getGlobalValue(), DSOLE);
-      return Ret;
-    }
-    case llvm::Value::ConstantArrayVal:
-      It->second = std::unique_ptr<ConstantArray>(
-          new ConstantArray(cast<llvm::ConstantArray>(LLVMC), *this));
-      break;
-    case llvm::Value::ConstantStructVal:
-      It->second = std::unique_ptr<ConstantStruct>(
-          new ConstantStruct(cast<llvm::ConstantStruct>(LLVMC), *this));
-      break;
-    case llvm::Value::ConstantVectorVal:
-      It->second = std::unique_ptr<ConstantVector>(
-          new ConstantVector(cast<llvm::ConstantVector>(LLVMC), *this));
-      break;
-    case llvm::Value::ConstantDataArrayVal:
-      It->second = std::unique_ptr<ConstantDataArray>(
-          new ConstantDataArray(cast<llvm::ConstantDataArray>(LLVMC), *this));
-      break;
-    case llvm::Value::ConstantDataVectorVal:
-      It->second = std::unique_ptr<ConstantDataVector>(
-          new ConstantDataVector(cast<llvm::ConstantDataVector>(LLVMC), *this));
-      break;
-    case llvm::Value::FunctionVal:
-      It->second = std::unique_ptr<Function>(
-          new Function(cast<llvm::Function>(LLVMC), *this));
-      break;
-    case llvm::Value::GlobalIFuncVal:
-      It->second = std::unique_ptr<GlobalIFunc>(
-          new GlobalIFunc(cast<llvm::GlobalIFunc>(LLVMC), *this));
-      break;
-    case llvm::Value::GlobalVariableVal:
-      It->second = std::unique_ptr<GlobalVariable>(
-          new GlobalVariable(cast<llvm::GlobalVariable>(LLVMC), *this));
-      break;
-    case llvm::Value::GlobalAliasVal:
-      It->second = std::unique_ptr<GlobalAlias>(
-          new GlobalAlias(cast<llvm::GlobalAlias>(LLVMC), *this));
-      break;
-    case llvm::Value::NoCFIValueVal:
-      It->second = std::unique_ptr<NoCFIValue>(
-          new NoCFIValue(cast<llvm::NoCFIValue>(LLVMC), *this));
-      break;
-    case llvm::Value::ConstantPtrAuthVal:
-      It->second = std::unique_ptr<ConstantPtrAuth>(
-          new ConstantPtrAuth(cast<llvm::ConstantPtrAuth>(LLVMC), *this));
-      break;
-    case llvm::Value::ConstantExprVal:
-      It->second = std::unique_ptr<ConstantExpr>(
-          new ConstantExpr(cast<llvm::ConstantExpr>(LLVMC), *this));
-      break;
-    default:
-      It->second = std::unique_ptr<Constant>(new Constant(LLVMC, *this));
-      break;
-    }
-    auto *NewC = It->second.get();
-    for (llvm::Value *COp : LLVMC->operands())
-      getOrCreateValueInternal(COp, LLVMC);
-    return NewC;
-  }
-  // Argument
-  if (auto *LLVMArg = dyn_cast<llvm::Argument>(LLVMV)) {
-    It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
-    return It->second.get();
-  }
-  // BasicBlock
-  if (auto *LLVMBB = dyn_cast<llvm::BasicBlock>(LLVMV)) {
-    assert(isa<llvm::BlockAddress>(U) &&
-           "This won't create a SBBB, don't call this function directly!");
-    if (auto *SBBB = getValue(LLVMBB))
-      return SBBB;
-    return nullptr;
-  }
-  // Metadata
-  if (auto *LLVMMD = dyn_cast<llvm::MetadataAsValue>(LLVMV)) {
-    It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(LLVMMD, *this));
-    return It->second.get();
-  }
-  // InlineAsm
-  if (auto *LLVMAsm = dyn_cast<llvm::InlineAsm>(LLVMV)) {
-    It->second = std::unique_ptr<OpaqueValue>(new OpaqueValue(LLVMAsm, *this));
-    return It->second.get();
-  }
-  llvm_unreachable("Unhandled LLVMV type!");
-}
-
-Argument *Context::getOrCreateArgument(llvm::Argument *LLVMArg) {
-  auto Pair = LLVMValueToValueMap.try_emplace(LLVMArg);
-  auto It = Pair.first;
-  if (Pair.second) {
-    It->second = std::unique_ptr<Argument>(new Argument(LLVMArg, *this));
-    return cast<Argument>(It->second.get());
-  }
-  return cast<Argument>(It->second.get());
-}
-
-Constant *Context::getOrCreateConstant(llvm::Constant *LLVMC) {
-  return cast<Constant>(getOrCreateValueInternal(LLVMC, nullptr));
-}
-
-BasicBlock *Context::createBasicBlock(llvm::BasicBlock *LLVMBB) {
-  assert(getValue(LLVMBB) == nullptr && "Already exists!");
-  auto NewBBPtr = std::unique_ptr<BasicBlock>(new BasicBlock(LLVMBB, *this));
-  auto *BB = cast<BasicBlock>(registerValue(std::move(NewBBPtr)));
-  // Create SandboxIR for BB's body.
-  BB->buildBasicBlockFromLLVMIR(LLVMBB);
-  return BB;
-}
-
-VAArgInst *Context::createVAArgInst(llvm::VAArgInst *SI) {
-  auto NewPtr = std::unique_ptr<VAArgInst>(new VAArgInst(SI, *this));
-  return cast<VAArgInst>(registerValue(std::move(NewPtr)));
-}
-
-FreezeInst *Context::createFreezeInst(llvm::FreezeInst *SI) {
-  auto NewPtr = std::unique_ptr<FreezeInst>(new FreezeInst(SI, *this));
-  return cast<FreezeInst>(registerValue(std::move(NewPtr)));
-}
-
-FenceInst *Context::createFenceInst(llvm::FenceInst *SI) {
-  auto NewPtr = std::unique_ptr<FenceInst>(new FenceInst(SI, *this));
-  return cast<FenceInst>(registerValue(std::move(NewPtr)));
-}
-
-SelectInst *Context::createSelectInst(llvm::SelectInst *SI) {
-  auto NewPtr = std::unique_ptr<SelectInst>(new SelectInst(SI, *this));
-  return cast<SelectInst>(registerValue(std::move(NewPtr)));
-}
-
-ExtractElementInst *
-Context::createExtractElementInst(llvm::ExtractElementInst *EEI) {
-  auto NewPtr =
-      std::unique_ptr<ExtractElementInst>(new ExtractElementInst(EEI, *this));
-  return cast<ExtractElementInst>(registerValue(std::move(NewPtr)));
-}
-
-InsertElementInst *
-Context::createInsertElementInst(llvm::InsertElementInst *IEI) {
-  auto NewPtr =
-      std::unique_ptr<InsertElementInst>(new InsertElementInst(IEI, *this));
-  return cast<InsertElementInst>(registerValue(std::move(NewPtr)));
-}
-
-ShuffleVectorInst *
-Context::createShuffleVectorInst(llvm::ShuffleVectorInst *SVI) {
-  auto NewPtr =
-      std::unique_ptr<ShuffleVectorInst>(new ShuffleVectorInst(SVI, *this));
-  return cast<ShuffleVectorInst>(registerValue(std::move(NewPtr)));
-}
-
-ExtractValueInst *Context::createExtractValueInst(llvm::ExtractValueInst *EVI) {
-  auto NewPtr =
-      std::unique_ptr<ExtractValueInst>(new ExtractValueInst(EVI, *this));
-  return cast<ExtractValueInst>(registerValue(std::move(NewPtr)));
-}
-
-InsertValueInst *Context::createInsertValueInst(llvm::InsertValueInst *IVI) {
-  auto NewPtr =
-      std::unique_ptr<InsertValueInst>(new InsertValueInst(IVI, *this));
-  return cast<InsertValueInst>(registerValue(std::move(NewPtr)));
-}
-
-BranchInst *Context::createBranchInst(llvm::BranchInst *BI) {
-  auto NewPtr = std::unique_ptr<BranchInst>(new BranchInst(BI, *this));
-  return cast<BranchInst>(registerValue(std::move(NewPtr)));
-}
-
-LoadInst *Context::createLoadInst(llvm::LoadInst *LI) {
-  auto NewPtr = std::unique_ptr<LoadInst>(new LoadInst(LI, *this));
-  return cast<LoadInst>(registerValue(std::move(NewPtr)));
-}
-
-StoreInst *Context::createStoreInst(llvm::StoreInst *SI) {
-  auto NewPtr = std::unique_ptr<StoreInst>(new StoreInst(SI, *this));
-  return cast<StoreInst>(registerValue(std::move(NewPtr)));
-}
-
-ReturnInst *Context::createReturnInst(llvm::ReturnInst *I) {
-  auto NewPtr = std::unique_ptr<ReturnInst>(new ReturnInst(I, *this));
-  return cast<ReturnInst>(registerValue(std::move(NewPtr)));
-}
-
-CallInst *Context::createCallInst(llvm::CallInst *I) {
-  auto NewPtr = std::unique_ptr<CallInst>(new CallInst(I, *this));
-  return cast<CallInst>(registerValue(std::move(NewPtr)));
-}
-
-InvokeInst *Context::createInvokeInst(llvm::InvokeInst *I) {
-  auto NewPtr = std::unique_ptr<InvokeInst>(new InvokeInst(I, *this));
-  return cast<InvokeInst>(registerValue(std::move(NewPtr)));
-}
-
-CallBrInst *Context::createCallBrInst(llvm::CallBrInst *I) {
-  auto NewPtr = std::unique_ptr<CallBrInst>(new CallBrInst(I, *this));
-  return cast<CallBrInst>(registerValue(std::move(NewPtr)));
-}
-
-UnreachableInst *Context::createUnreachableInst(llvm::UnreachableInst *UI) {
-  auto NewPtr =
-      std::unique_ptr<UnreachableInst>(new UnreachableInst(UI, *this));
-  return cast<UnreachableInst>(registerValue(std::move(NewPtr)));
-}
-LandingPadInst *Context::createLandingPadInst(llvm::LandingPadInst *I) {
-  auto NewPtr = std::unique_ptr<LandingPadInst>(new LandingPadInst(I, *this));
-  return cast<LandingPadInst>(registerValue(std::move(NewPtr)));
-}
-CatchPadInst *Context::createCatchPadInst(llvm::CatchPadInst *I) {
-  auto NewPtr = std::unique_ptr<CatchPadInst>(new CatchPadInst(I, *this));
-  return cast<CatchPadInst>(registerValue(std::move(NewPtr)));
-}
-CleanupPadInst *Context::createCleanupPadInst(llvm::CleanupPadInst *I) {
-  auto NewPtr = std::unique_ptr<CleanupPadInst>(new CleanupPadInst(I, *this));
-  return cast<CleanupPadInst>(registerValue(std::move(NewPtr)));
-}
-CatchReturnInst *Context::createCatchReturnInst(llvm::CatchReturnInst *I) {
-  auto NewPtr = std::unique_ptr<CatchReturnInst>(new CatchReturnInst(I, *this));
-  return cast<CatchReturnInst>(registerValue(std::move(NewPtr)));
-}
-CleanupReturnInst *
-Context::createCleanupReturnInst(llvm::CleanupReturnInst *I) {
-  auto NewPtr =
-      std::unique_ptr<CleanupReturnInst>(new CleanupReturnInst(I, *this));
-  return cast<CleanupReturnInst>(registerValue(std::move(NewPtr)));
-}
-GetElementPtrInst *
-Context::createGetElementPtrInst(llvm::GetElementPtrInst *I) {
-  auto NewPtr =
-      std::unique_ptr<GetElementPtrInst>(new GetElementPtrInst(I, *this));
-  return cast<GetElementPtrInst>(registerValue(std::move(NewPtr)));
-}
-CatchSwitchInst *Context::createCatchSwitchInst(llvm::CatchSwitchInst *I) {
-  auto NewPtr = std::unique_ptr<CatchSwitchInst>(new CatchSwitchInst(I, *this));
-  return cast<CatchSwitchInst>(registerValue(std::move(NewPtr)));
-}
-ResumeInst *Context::createResumeInst(llvm::ResumeInst *I) {
-  auto NewPtr = std::unique_ptr<ResumeInst>(new ResumeInst(I, *this));
-  return cast<ResumeInst>(registerValue(std::move(NewPtr)));
-}
-SwitchInst *Context::createSwitchInst(llvm::SwitchInst *I) {
-  auto NewPtr = std::unique_ptr<SwitchInst>(new SwitchInst(I, *this));
-  return cast<SwitchInst>(registerValue(std::move(NewPtr)));
-}
-UnaryOperator *Context::createUnaryOperator(llvm::UnaryOperator *I) {
-  auto NewPtr = std::unique_ptr<UnaryOperator>(new UnaryOperator(I, *this));
-  return cast<UnaryOperator>(registerValue(std::move(NewPtr)));
-}
-BinaryOperator *Context::createBinaryOperator(llvm::BinaryOperator *I) {
-  auto NewPtr = std::unique_ptr<BinaryOperator>(new BinaryOperator(I, *this));
-  return cast<BinaryOperator>(registerValue(std::move(NewPtr)));
-}
-AtomicRMWInst *Context::createAtomicRMWInst(llvm::AtomicRMWInst *I) {
-  auto NewPtr = std::unique_ptr<AtomicRMWInst>(new AtomicRMWInst(I, *this));
-  return cast<AtomicRMWInst>(registerValue(std::move(NewPtr)));
-}
-AtomicCmpXchgInst *
-Context::createAtomicCmpXchgInst(llvm::AtomicCmpXchgInst *I) {
-  auto NewPtr =
-      std::unique_ptr<AtomicCmpXchgInst>(new AtomicCmpXchgInst(I, *this));
-  return cast<AtomicCmpXchgInst>(registerValue(std::move(NewPtr)));
-}
-AllocaInst *Context::createAllocaInst(llvm::AllocaInst *I) {
-  auto NewPtr = std::unique_ptr<AllocaInst>(new AllocaInst(I, *this));
-  return cast<AllocaInst>(registerValue(std::move(NewPtr)));
-}
-CastInst *Context::createCastInst(llvm::CastInst *I) {
-  auto NewPtr = std::unique_ptr<CastInst>(new CastInst(I, *this));
-  return cast<CastInst>(registerValue(std::move(NewPtr)));
-}
-PHINode *Context::createPHINode(llvm::PHINode *I) {
-  auto NewPtr = std::unique_ptr<PHINode>(new PHINode(I, *this));
-  return cast<PHINode>(registerValue(std::move(NewPtr)));
-}
-ICmpInst *Context::createICmpInst(llvm::ICmpInst *I) {
-  auto NewPtr = std::unique_ptr<ICmpInst>(new ICmpInst(I, *this));
-  return cast<ICmpInst>(registerValue(std::move(NewPtr)));
-}
-FCmpInst *Context::createFCmpInst(llvm::FCmpInst *I) {
-  auto NewPtr = std::unique_ptr<FCmpInst>(new FCmpInst(I, *this));
-  return cast<FCmpInst>(registerValue(std::move(NewPtr)));
-}
-Value *Context::getValue(llvm::Value *V) const {
-  auto It = LLVMValueToValueMap.find(V);
-  if (It != LLVMValueToValueMap.end())
-    return It->second.get();
-  return nullptr;
-}
-
-Context::Context(LLVMContext &LLVMCtx)
-    : LLVMCtx(LLVMCtx), IRTracker(*this),
-      LLVMIRBuilder(LLVMCtx, ConstantFolder()) {}
-
-Context::~Context() = default;
-
-void Context::clear() {
-  // TODO: Ideally we should clear only function-scope objects, and keep global
-  // objects, like Constants to avoid recreating them.
-  LLVMValueToValueMap.clear();
-}
-
-Module *Context::getModule(llvm::Module *LLVMM) const {
-  auto It = LLVMModuleToModuleMap.find(LLVMM);
-  if (It != LLVMModuleToModuleMap.end())
-    return It->second.get();
-  return nullptr;
-}
-
-Module *Context::getOrCreateModule(llvm::Module *LLVMM) {
-  auto Pair = LLVMModuleToModuleMap.try_emplace(LLVMM);
-  auto It = Pair.first;
-  if (!Pair.second)
-    return It->second.get();
-  It->second = std::unique_ptr<Module>(new Module(*LLVMM, *this));
-  return It->second.get();
-}
-
-Function *Context::createFunction(llvm::Function *F) {
-  // Create the module if needed before we create the new sandboxir::Function.
-  // Note: this won't fully populate the module. The only globals that will be
-  // available will be the ones being used within the function.
-  getOrCreateModule(F->getParent());
-
-  // There may be a function declaration already defined. Regardless destroy it.
-  if (Function *ExistingF = cast_or_null<Function>(getValue(F)))
-    detach(ExistingF);
-
-  auto NewFPtr = std::unique_ptr<Function>(new Function(F, *this));
-  auto *SBF = cast<Function>(registerValue(std::move(NewFPtr)));
-  // Create arguments.
-  for (auto &Arg : F->args())
-    getOrCreateArgument(&Arg);
-  // Create BBs.
-  for (auto &BB : *F)
-    createBasicBlock(&BB);
-  return SBF;
-}
-
-Module *Context::createModule(llvm::Module *LLVMM) {
-  auto *M = getOrCreateModule(LLVMM);
-  // Create the functions.
-  for (auto &LLVMF : *LLVMM)
-    createFunction(&LLVMF);
-  // Create globals.
-  for (auto &Global : LLVMM->globals())
-    getOrCreateValue(&Global);
-  // Create aliases.
-  for (auto &Alias : LLVMM->aliases())
-    getOrCreateValue(&Alias);
-  // Create ifuncs.
-  for (auto &IFunc : LLVMM->ifuncs())
-    getOrCreateValue(&IFunc);
-
-  return M;
-}
-
-void Context::runEraseInstrCallbacks(Instruction *I) {
-  for (const auto &CBEntry : EraseInstrCallbacks)
-    CBEntry.second(I);
-}
-
-void Context::runCreateInstrCallbacks(Instruction *I) {
-  for (auto &CBEntry : CreateInstrCallbacks)
-    CBEntry.second(I);
-}
-
-void Context::runMoveInstrCallbacks(Instruction *I, const BBIterator &WhereIt) {
-  for (auto &CBEntry : MoveInstrCallbacks)
-    CBEntry.second(I, WhereIt);
-}
-
-void Context::runSetUseCallbacks(const Use &U, Value *NewSrc) {
-  for (auto &CBEntry : SetUseCallbacks)
-    CBEntry.second(U, NewSrc);
-}
-
-// An arbitrary limit, to check for accidental misuse. We expect a small number
-// of callbacks to be registered at a time, but we can increase this number if
-// we discover we needed more.
-[[maybe_unused]] static constexpr int MaxRegisteredCallbacks = 16;
-
-Context::CallbackID Context::registerEraseInstrCallback(EraseInstrCallback CB) {
-  assert(EraseInstrCallbacks.size() <= MaxRegisteredCallbacks &&
-         "EraseInstrCallbacks size limit exceeded");
-  CallbackID ID{NextCallbackID++};
-  EraseInstrCallbacks[ID] = CB;
-  return ID;
-}
-void Context::unregisterEraseInstrCallback(CallbackID ID) {
-  [[maybe_unused]] bool Erased = EraseInstrCallbacks.erase(ID);
-  assert(Erased &&
-         "Callback ID not found in EraseInstrCallbacks during deregistration");
-}
-
-Context::CallbackID
-Context::registerCreateInstrCallback(CreateInstrCallback CB) {
-  assert(CreateInstrCallbacks.size() <= MaxRegisteredCallbacks &&
-         "CreateInstrCallbacks size limit exceeded");
-  CallbackID ID{NextCallbackID++};
-  CreateInstrCallbacks[ID] = CB;
-  return ID;
-}
-void Context::unregisterCreateInstrCallback(CallbackID ID) {
-  [[maybe_unused]] bool Erased = CreateInstrCallbacks.erase(ID);
-  assert(Erased &&
-         "Callback ID not found in CreateInstrCallbacks during deregistration");
-}
-
-Context::CallbackID Context::registerMoveInstrCallback(MoveInstrCallback CB) {
-  assert(MoveInstrCallbacks.size() <= MaxRegisteredCallbacks &&
-         "MoveInstrCallbacks size limit exceeded");
-  CallbackID ID{NextCallbackID++};
-  MoveInstrCallbacks[ID] = CB;
-  return ID;
-}
-void Context::unregisterMoveInstrCallback(CallbackID ID) {
-  [[maybe_unused]] bool Erased = MoveInstrCallbacks.erase(ID);
-  assert(Erased &&
-         "Callback ID not found in MoveInstrCallbacks during deregistration");
-}
-
-Context::CallbackID Context::registerSetUseCallback(SetUseCallback CB) {
-  assert(SetUseCallbacks.size() <= MaxRegisteredCallbacks &&
-         "SetUseCallbacks size limit exceeded");
-  CallbackID ID{NextCallbackID++};
-  SetUseCallbacks[ID] = CB;
-  return ID;
-}
-void Context::unregisterSetUseCallback(CallbackID ID) {
-  [[maybe_unused]] bool Erased = SetUseCallbacks.erase(ID);
-  assert(Erased &&
-         "Callback ID not found in SetUseCallbacks during deregistration");
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Function.cpp b/llvm/lib/SandboxIR/Function.cpp
deleted file mode 100644
index f400389ed7605..0000000000000
--- a/llvm/lib/SandboxIR/Function.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//===- Function.cpp - The Function class of Sandbox IR --------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/IR/Value.h"
-#include "llvm/SandboxIR/Context.h"
-
-namespace llvm::sandboxir {
-
-FunctionType *Function::getFunctionType() const {
-  return cast<FunctionType>(
-      Ctx.getType(cast<llvm::Function>(Val)->getFunctionType()));
-}
-
-void Function::setAlignment(MaybeAlign Align) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&Function::getAlign, &Function::setAlignment>>(this);
-  cast<llvm::Function>(Val)->setAlignment(Align);
-}
-
-#ifndef NDEBUG
-void Function::dumpNameAndArgs(raw_ostream &OS) const {
-  auto *F = cast<llvm::Function>(Val);
-  OS << *F->getReturnType() << " @" << F->getName() << "(";
-  interleave(
-      F->args(),
-      [this, &OS](const llvm::Argument &LLVMArg) {
-        auto *SBArg = cast_or_null<Argument>(Ctx.getValue(&LLVMArg));
-        if (SBArg == nullptr)
-          OS << "NULL";
-        else
-          SBArg->printAsOperand(OS);
-      },
-      [&] { OS << ", "; });
-  OS << ")";
-}
-
-void Function::dumpOS(raw_ostream &OS) const {
-  dumpNameAndArgs(OS);
-  OS << " {\n";
-  auto *LLVMF = cast<llvm::Function>(Val);
-  interleave(
-      *LLVMF,
-      [this, &OS](const llvm::BasicBlock &LLVMBB) {
-        auto *BB = cast_or_null<BasicBlock>(Ctx.getValue(&LLVMBB));
-        if (BB == nullptr)
-          OS << "NULL";
-        else
-          OS << *BB;
-      },
-      [&OS] { OS << "\n"; });
-  OS << "}\n";
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Instruction.cpp b/llvm/lib/SandboxIR/Instruction.cpp
deleted file mode 100644
index 1a81d185acf76..0000000000000
--- a/llvm/lib/SandboxIR/Instruction.cpp
+++ /dev/null
@@ -1,1562 +0,0 @@
-//===- Instruction.cpp - The Instructions of Sandbox IR -------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Function.h"
-
-namespace llvm::sandboxir {
-
-const char *Instruction::getOpcodeName(Opcode Opc) {
-  switch (Opc) {
-#define OP(OPC)                                                                \
-  case Opcode::OPC:                                                            \
-    return #OPC;
-#define OPCODES(...) __VA_ARGS__
-#define DEF_INSTR(ID, OPC, CLASS) OPC
-#include "llvm/SandboxIR/Values.def"
-  }
-  llvm_unreachable("Unknown Opcode");
-}
-
-llvm::Instruction *Instruction::getTopmostLLVMInstruction() const {
-  Instruction *Prev = getPrevNode();
-  if (Prev == nullptr) {
-    // If at top of the BB, return the first BB instruction.
-    return &*cast<llvm::BasicBlock>(getParent()->Val)->begin();
-  }
-  // Else get the Previous sandbox IR instruction's bottom IR instruction and
-  // return its successor.
-  llvm::Instruction *PrevBotI = cast<llvm::Instruction>(Prev->Val);
-  return PrevBotI->getNextNode();
-}
-
-BBIterator Instruction::getIterator() const {
-  auto *I = cast<llvm::Instruction>(Val);
-  return BasicBlock::iterator(I->getParent(), I->getIterator(), &Ctx);
-}
-
-Instruction *Instruction::getNextNode() const {
-  assert(getParent() != nullptr && "Detached!");
-  assert(getIterator() != getParent()->end() && "Already at end!");
-  // `Val` is the bottom-most LLVM IR instruction. Get the next in the chain,
-  // and get the corresponding sandboxir Instruction that maps to it. This works
-  // even for SandboxIR Instructions that map to more than one LLVM Instruction.
-  auto *LLVMI = cast<llvm::Instruction>(Val);
-  assert(LLVMI->getParent() != nullptr && "LLVM IR instr is detached!");
-  auto *NextLLVMI = LLVMI->getNextNode();
-  auto *NextI = cast_or_null<Instruction>(Ctx.getValue(NextLLVMI));
-  if (NextI == nullptr)
-    return nullptr;
-  return NextI;
-}
-
-Instruction *Instruction::getPrevNode() const {
-  assert(getParent() != nullptr && "Detached!");
-  auto It = getIterator();
-  if (It != getParent()->begin())
-    return std::prev(getIterator()).get();
-  return nullptr;
-}
-
-void Instruction::removeFromParent() {
-  Ctx.getTracker().emplaceIfTracking<RemoveFromParent>(this);
-
-  // Detach all the LLVM IR instructions from their parent BB.
-  for (llvm::Instruction *I : getLLVMInstrs())
-    I->removeFromParent();
-}
-
-void Instruction::eraseFromParent() {
-  assert(users().empty() && "Still connected to users, can't erase!");
-
-  Ctx.runEraseInstrCallbacks(this);
-  std::unique_ptr<Value> Detached = Ctx.detach(this);
-  auto LLVMInstrs = getLLVMInstrs();
-
-  auto &Tracker = Ctx.getTracker();
-  if (Tracker.isTracking()) {
-    Tracker.track(std::make_unique<EraseFromParent>(std::move(Detached)));
-    // We don't actually delete the IR instruction, because then it would be
-    // impossible to bring it back from the dead at the same memory location.
-    // Instead we remove it from its BB and track its current location.
-    for (llvm::Instruction *I : LLVMInstrs)
-      I->removeFromParent();
-    // TODO: Multi-instructions need special treatment because some of the
-    // references are internal to the instruction.
-    for (llvm::Instruction *I : LLVMInstrs)
-      I->dropAllReferences();
-  } else {
-    // Erase in reverse to avoid erasing nstructions with attached uses.
-    for (llvm::Instruction *I : reverse(LLVMInstrs))
-      I->eraseFromParent();
-  }
-}
-
-void Instruction::moveBefore(BasicBlock &BB, const BBIterator &WhereIt) {
-  if (std::next(getIterator()) == WhereIt)
-    // Destination is same as origin, nothing to do.
-    return;
-
-  Ctx.runMoveInstrCallbacks(this, WhereIt);
-  Ctx.getTracker().emplaceIfTracking<MoveInstr>(this);
-
-  auto *LLVMBB = cast<llvm::BasicBlock>(BB.Val);
-  llvm::BasicBlock::iterator It;
-  if (WhereIt == BB.end()) {
-    It = LLVMBB->end();
-  } else {
-    Instruction *WhereI = &*WhereIt;
-    It = WhereI->getTopmostLLVMInstruction()->getIterator();
-  }
-  // TODO: Move this to the verifier of sandboxir::Instruction.
-  assert(is_sorted(getLLVMInstrs(),
-                   [](auto *I1, auto *I2) { return I1->comesBefore(I2); }) &&
-         "Expected program order!");
-  // Do the actual move in LLVM IR.
-  for (auto *I : getLLVMInstrs())
-    I->moveBefore(*LLVMBB, It);
-}
-
-void Instruction::insertBefore(Instruction *BeforeI) {
-  llvm::Instruction *BeforeTopI = BeforeI->getTopmostLLVMInstruction();
-
-  Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
-
-  // Insert the LLVM IR Instructions in program order.
-  for (llvm::Instruction *I : getLLVMInstrs())
-    I->insertBefore(BeforeTopI->getIterator());
-}
-
-void Instruction::insertAfter(Instruction *AfterI) {
-  insertInto(AfterI->getParent(), std::next(AfterI->getIterator()));
-}
-
-void Instruction::insertInto(BasicBlock *BB, const BBIterator &WhereIt) {
-  llvm::BasicBlock *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
-  llvm::Instruction *LLVMBeforeI;
-  llvm::BasicBlock::iterator LLVMBeforeIt;
-  Instruction *BeforeI;
-  if (WhereIt != BB->end()) {
-    BeforeI = &*WhereIt;
-    LLVMBeforeI = BeforeI->getTopmostLLVMInstruction();
-    LLVMBeforeIt = LLVMBeforeI->getIterator();
-  } else {
-    BeforeI = nullptr;
-    LLVMBeforeI = nullptr;
-    LLVMBeforeIt = LLVMBB->end();
-  }
-
-  Ctx.getTracker().emplaceIfTracking<InsertIntoBB>(this);
-
-  // Insert the LLVM IR Instructions in program order.
-  for (llvm::Instruction *I : getLLVMInstrs())
-    I->insertInto(LLVMBB, LLVMBeforeIt);
-}
-
-BasicBlock *Instruction::getParent() const {
-  // Get the LLVM IR Instruction that this maps to, get its parent, and get the
-  // corresponding sandboxir::BasicBlock by looking it up in sandboxir::Context.
-  auto *BB = cast<llvm::Instruction>(Val)->getParent();
-  if (BB == nullptr)
-    return nullptr;
-  return cast<BasicBlock>(Ctx.getValue(BB));
-}
-
-bool Instruction::classof(const sandboxir::Value *From) {
-  switch (From->getSubclassID()) {
-#define DEF_INSTR(ID, OPC, CLASS)                                              \
-  case ClassID::ID:                                                            \
-    return true;
-#include "llvm/SandboxIR/Values.def"
-  default:
-    return false;
-  }
-}
-
-void Instruction::setHasNoUnsignedWrap(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasNoUnsignedWrap,
-                                       &Instruction::setHasNoUnsignedWrap>>(
-          this);
-  cast<llvm::Instruction>(Val)->setHasNoUnsignedWrap(B);
-}
-
-void Instruction::setHasNoSignedWrap(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedWrap,
-                                       &Instruction::setHasNoSignedWrap>>(this);
-  cast<llvm::Instruction>(Val)->setHasNoSignedWrap(B);
-}
-
-void Instruction::setFast(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&Instruction::isFast, &Instruction::setFast>>(this);
-  cast<llvm::Instruction>(Val)->setFast(B);
-}
-
-void Instruction::setIsExact(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&Instruction::isExact, &Instruction::setIsExact>>(this);
-  cast<llvm::Instruction>(Val)->setIsExact(B);
-}
-
-void Instruction::setHasAllowReassoc(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReassoc,
-                                       &Instruction::setHasAllowReassoc>>(this);
-  cast<llvm::Instruction>(Val)->setHasAllowReassoc(B);
-}
-
-void Instruction::setHasNoNaNs(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&Instruction::hasNoNaNs, &Instruction::setHasNoNaNs>>(
-          this);
-  cast<llvm::Instruction>(Val)->setHasNoNaNs(B);
-}
-
-void Instruction::setHasNoInfs(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&Instruction::hasNoInfs, &Instruction::setHasNoInfs>>(
-          this);
-  cast<llvm::Instruction>(Val)->setHasNoInfs(B);
-}
-
-void Instruction::setHasNoSignedZeros(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasNoSignedZeros,
-                                       &Instruction::setHasNoSignedZeros>>(
-          this);
-  cast<llvm::Instruction>(Val)->setHasNoSignedZeros(B);
-}
-
-void Instruction::setHasAllowReciprocal(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasAllowReciprocal,
-                                       &Instruction::setHasAllowReciprocal>>(
-          this);
-  cast<llvm::Instruction>(Val)->setHasAllowReciprocal(B);
-}
-
-void Instruction::setHasAllowContract(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasAllowContract,
-                                       &Instruction::setHasAllowContract>>(
-          this);
-  cast<llvm::Instruction>(Val)->setHasAllowContract(B);
-}
-
-void Instruction::setFastMathFlags(FastMathFlags FMF) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
-                                       &Instruction::copyFastMathFlags>>(this);
-  cast<llvm::Instruction>(Val)->setFastMathFlags(FMF);
-}
-
-void Instruction::copyFastMathFlags(FastMathFlags FMF) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::getFastMathFlags,
-                                       &Instruction::copyFastMathFlags>>(this);
-  cast<llvm::Instruction>(Val)->copyFastMathFlags(FMF);
-}
-
-Type *Instruction::getAccessType() const {
-  return Ctx.getType(cast<llvm::Instruction>(Val)->getAccessType());
-}
-
-void Instruction::setHasApproxFunc(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&Instruction::hasApproxFunc,
-                                       &Instruction::setHasApproxFunc>>(this);
-  cast<llvm::Instruction>(Val)->setHasApproxFunc(B);
-}
-
-#ifndef NDEBUG
-void Instruction::dumpOS(raw_ostream &OS) const {
-  OS << "Unimplemented! Please override dump().";
-}
-#endif // NDEBUG
-
-VAArgInst *VAArgInst::create(Value *List, Type *Ty, InsertPosition Pos,
-                             Context &Ctx, const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMI =
-      cast<llvm::VAArgInst>(Builder.CreateVAArg(List->Val, Ty->LLVMTy, Name));
-  return Ctx.createVAArgInst(LLVMI);
-}
-
-Value *VAArgInst::getPointerOperand() {
-  return Ctx.getValue(cast<llvm::VAArgInst>(Val)->getPointerOperand());
-}
-
-FreezeInst *FreezeInst::create(Value *V, InsertPosition Pos, Context &Ctx,
-                               const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMI = cast<llvm::FreezeInst>(Builder.CreateFreeze(V->Val, Name));
-  return Ctx.createFreezeInst(LLVMI);
-}
-
-FenceInst *FenceInst::create(AtomicOrdering Ordering, InsertPosition Pos,
-                             Context &Ctx, SyncScope::ID SSID) {
-  auto &Builder = Instruction::setInsertPos(Pos);
-  llvm::FenceInst *LLVMI = Builder.CreateFence(Ordering, SSID);
-  return Ctx.createFenceInst(LLVMI);
-}
-
-void FenceInst::setOrdering(AtomicOrdering Ordering) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&FenceInst::getOrdering, &FenceInst::setOrdering>>(
-          this);
-  cast<llvm::FenceInst>(Val)->setOrdering(Ordering);
-}
-
-void FenceInst::setSyncScopeID(SyncScope::ID SSID) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&FenceInst::getSyncScopeID,
-                                       &FenceInst::setSyncScopeID>>(this);
-  cast<llvm::FenceInst>(Val)->setSyncScopeID(SSID);
-}
-
-Value *SelectInst::create(Value *Cond, Value *True, Value *False,
-                          InsertPosition Pos, Context &Ctx, const Twine &Name) {
-  auto &Builder = Instruction::setInsertPos(Pos);
-  llvm::Value *NewV =
-      Builder.CreateSelect(Cond->Val, True->Val, False->Val, Name);
-  if (auto *NewSI = dyn_cast<llvm::SelectInst>(NewV))
-    return Ctx.createSelectInst(NewSI);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-void SelectInst::swapValues() {
-  Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(1),
-                                              getOperandUse(2));
-  cast<llvm::SelectInst>(Val)->swapValues();
-}
-
-bool SelectInst::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::Select;
-}
-
-BranchInst *BranchInst::create(BasicBlock *IfTrue, InsertPosition Pos,
-                               Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::BranchInst *NewBr =
-      Builder.CreateBr(cast<llvm::BasicBlock>(IfTrue->Val));
-  return Ctx.createBranchInst(NewBr);
-}
-
-BranchInst *BranchInst::create(BasicBlock *IfTrue, BasicBlock *IfFalse,
-                               Value *Cond, InsertPosition Pos, Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::BranchInst *NewBr =
-      Builder.CreateCondBr(Cond->Val, cast<llvm::BasicBlock>(IfTrue->Val),
-                           cast<llvm::BasicBlock>(IfFalse->Val));
-  return Ctx.createBranchInst(NewBr);
-}
-
-bool BranchInst::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::Br;
-}
-
-Value *BranchInst::getCondition() const {
-  assert(isConditional() && "Cannot get condition of an uncond branch!");
-  return Ctx.getValue(cast<llvm::BranchInst>(Val)->getCondition());
-}
-
-BasicBlock *BranchInst::getSuccessor(unsigned SuccIdx) const {
-  assert(SuccIdx < getNumSuccessors() &&
-         "Successor # out of range for Branch!");
-  return cast_or_null<BasicBlock>(
-      Ctx.getValue(cast<llvm::BranchInst>(Val)->getSuccessor(SuccIdx)));
-}
-
-void BranchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
-  assert((Idx == 0 || Idx == 1) && "Out of bounds!");
-  setOperand(2u - Idx, NewSucc);
-}
-
-BasicBlock *BranchInst::LLVMBBToSBBB::operator()(llvm::BasicBlock *BB) const {
-  return cast<BasicBlock>(Ctx.getValue(BB));
-}
-const BasicBlock *
-BranchInst::ConstLLVMBBToSBBB::operator()(const llvm::BasicBlock *BB) const {
-  return cast<BasicBlock>(Ctx.getValue(BB));
-}
-
-void LoadInst::setVolatile(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&LoadInst::isVolatile, &LoadInst::setVolatile>>(this);
-  cast<llvm::LoadInst>(Val)->setVolatile(V);
-}
-
-LoadInst *LoadInst::create(Type *Ty, Value *Ptr, MaybeAlign Align,
-                           InsertPosition Pos, bool IsVolatile, Context &Ctx,
-                           const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *NewLI =
-      Builder.CreateAlignedLoad(Ty->LLVMTy, Ptr->Val, Align, IsVolatile, Name);
-  auto *NewSBI = Ctx.createLoadInst(NewLI);
-  return NewSBI;
-}
-
-bool LoadInst::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::Load;
-}
-
-Value *LoadInst::getPointerOperand() const {
-  return Ctx.getValue(cast<llvm::LoadInst>(Val)->getPointerOperand());
-}
-
-void StoreInst::setVolatile(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&StoreInst::isVolatile, &StoreInst::setVolatile>>(this);
-  cast<llvm::StoreInst>(Val)->setVolatile(V);
-}
-
-StoreInst *StoreInst::create(Value *V, Value *Ptr, MaybeAlign Align,
-                             InsertPosition Pos, bool IsVolatile,
-                             Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  auto *NewSI = Builder.CreateAlignedStore(V->Val, Ptr->Val, Align, IsVolatile);
-  auto *NewSBI = Ctx.createStoreInst(NewSI);
-  return NewSBI;
-}
-
-bool StoreInst::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::Store;
-}
-
-Value *StoreInst::getValueOperand() const {
-  return Ctx.getValue(cast<llvm::StoreInst>(Val)->getValueOperand());
-}
-
-Value *StoreInst::getPointerOperand() const {
-  return Ctx.getValue(cast<llvm::StoreInst>(Val)->getPointerOperand());
-}
-
-UnreachableInst *UnreachableInst::create(InsertPosition Pos, Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::UnreachableInst *NewUI = Builder.CreateUnreachable();
-  return Ctx.createUnreachableInst(NewUI);
-}
-
-bool UnreachableInst::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::Unreachable;
-}
-
-ReturnInst *ReturnInst::createCommon(Value *RetVal, IRBuilder<> &Builder,
-                                     Context &Ctx) {
-  llvm::ReturnInst *NewRI;
-  if (RetVal != nullptr)
-    NewRI = Builder.CreateRet(RetVal->Val);
-  else
-    NewRI = Builder.CreateRetVoid();
-  return Ctx.createReturnInst(NewRI);
-}
-
-ReturnInst *ReturnInst::create(Value *RetVal, InsertPosition Pos,
-                               Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  return createCommon(RetVal, Builder, Ctx);
-}
-
-Value *ReturnInst::getReturnValue() const {
-  auto *LLVMRetVal = cast<llvm::ReturnInst>(Val)->getReturnValue();
-  return LLVMRetVal != nullptr ? Ctx.getValue(LLVMRetVal) : nullptr;
-}
-
-FunctionType *CallBase::getFunctionType() const {
-  return cast<FunctionType>(
-      Ctx.getType(cast<llvm::CallBase>(Val)->getFunctionType()));
-}
-
-Value *CallBase::getCalledOperand() const {
-  return Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledOperand());
-}
-
-Use CallBase::getCalledOperandUse() const {
-  llvm::Use *LLVMUse = &cast<llvm::CallBase>(Val)->getCalledOperandUse();
-  return Use(LLVMUse, cast<User>(Ctx.getValue(LLVMUse->getUser())), Ctx);
-}
-
-Function *CallBase::getCalledFunction() const {
-  return cast_or_null<Function>(
-      Ctx.getValue(cast<llvm::CallBase>(Val)->getCalledFunction()));
-}
-Function *CallBase::getCaller() {
-  return cast<Function>(Ctx.getValue(cast<llvm::CallBase>(Val)->getCaller()));
-}
-
-void CallBase::setCalledFunction(Function *F) {
-  // F's function type is private, so we rely on `setCalledFunction()` to update
-  // it. But even though we are calling `setCalledFunction()` we also need to
-  // track this change at the SandboxIR level, which is why we call
-  // `setCalledOperand()` here.
-  // Note: This may break if `setCalledFunction()` early returns if `F`
-  // is already set, but we do have a unit test for it.
-  setCalledOperand(F);
-  cast<llvm::CallBase>(Val)->setCalledFunction(
-      cast<llvm::FunctionType>(F->getFunctionType()->LLVMTy),
-      cast<llvm::Function>(F->Val));
-}
-
-CallInst *CallInst::create(FunctionType *FTy, Value *Func,
-                           ArrayRef<Value *> Args, InsertPosition Pos,
-                           Context &Ctx, const Twine &NameStr) {
-  auto &Builder = setInsertPos(Pos);
-  SmallVector<llvm::Value *> LLVMArgs;
-  LLVMArgs.reserve(Args.size());
-  for (Value *Arg : Args)
-    LLVMArgs.push_back(Arg->Val);
-  llvm::CallInst *NewCI = Builder.CreateCall(
-      cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val, LLVMArgs, NameStr);
-  return Ctx.createCallInst(NewCI);
-}
-
-InvokeInst *InvokeInst::create(FunctionType *FTy, Value *Func,
-                               BasicBlock *IfNormal, BasicBlock *IfException,
-                               ArrayRef<Value *> Args, InsertPosition Pos,
-                               Context &Ctx, const Twine &NameStr) {
-  auto &Builder = setInsertPos(Pos);
-  SmallVector<llvm::Value *> LLVMArgs;
-  LLVMArgs.reserve(Args.size());
-  for (Value *Arg : Args)
-    LLVMArgs.push_back(Arg->Val);
-  llvm::InvokeInst *Invoke = Builder.CreateInvoke(
-      cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
-      cast<llvm::BasicBlock>(IfNormal->Val),
-      cast<llvm::BasicBlock>(IfException->Val), LLVMArgs, NameStr);
-  return Ctx.createInvokeInst(Invoke);
-}
-
-BasicBlock *InvokeInst::getNormalDest() const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::InvokeInst>(Val)->getNormalDest()));
-}
-BasicBlock *InvokeInst::getUnwindDest() const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::InvokeInst>(Val)->getUnwindDest()));
-}
-void InvokeInst::setNormalDest(BasicBlock *BB) {
-  setOperand(1, BB);
-  assert(getNormalDest() == BB && "LLVM IR uses a different operan index!");
-}
-void InvokeInst::setUnwindDest(BasicBlock *BB) {
-  setOperand(2, BB);
-  assert(getUnwindDest() == BB && "LLVM IR uses a different operan index!");
-}
-LandingPadInst *InvokeInst::getLandingPadInst() const {
-  return cast<LandingPadInst>(
-      Ctx.getValue(cast<llvm::InvokeInst>(Val)->getLandingPadInst()));
-  ;
-}
-BasicBlock *InvokeInst::getSuccessor(unsigned SuccIdx) const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::InvokeInst>(Val)->getSuccessor(SuccIdx)));
-}
-
-CallBrInst *CallBrInst::create(FunctionType *FTy, Value *Func,
-                               BasicBlock *DefaultDest,
-                               ArrayRef<BasicBlock *> IndirectDests,
-                               ArrayRef<Value *> Args, InsertPosition Pos,
-                               Context &Ctx, const Twine &NameStr) {
-  auto &Builder = setInsertPos(Pos);
-  SmallVector<llvm::BasicBlock *> LLVMIndirectDests;
-  LLVMIndirectDests.reserve(IndirectDests.size());
-  for (BasicBlock *IndDest : IndirectDests)
-    LLVMIndirectDests.push_back(cast<llvm::BasicBlock>(IndDest->Val));
-
-  SmallVector<llvm::Value *> LLVMArgs;
-  LLVMArgs.reserve(Args.size());
-  for (Value *Arg : Args)
-    LLVMArgs.push_back(Arg->Val);
-
-  llvm::CallBrInst *CallBr =
-      Builder.CreateCallBr(cast<llvm::FunctionType>(FTy->LLVMTy), Func->Val,
-                           cast<llvm::BasicBlock>(DefaultDest->Val),
-                           LLVMIndirectDests, LLVMArgs, NameStr);
-  return Ctx.createCallBrInst(CallBr);
-}
-
-Value *CallBrInst::getIndirectDestLabel(unsigned Idx) const {
-  return Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDestLabel(Idx));
-}
-Value *CallBrInst::getIndirectDestLabelUse(unsigned Idx) const {
-  return Ctx.getValue(
-      cast<llvm::CallBrInst>(Val)->getIndirectDestLabelUse(Idx));
-}
-BasicBlock *CallBrInst::getDefaultDest() const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::CallBrInst>(Val)->getDefaultDest()));
-}
-BasicBlock *CallBrInst::getIndirectDest(unsigned Idx) const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::CallBrInst>(Val)->getIndirectDest(Idx)));
-}
-llvm::SmallVector<BasicBlock *, 16> CallBrInst::getIndirectDests() const {
-  SmallVector<BasicBlock *, 16> BBs;
-  for (llvm::BasicBlock *LLVMBB :
-       cast<llvm::CallBrInst>(Val)->getIndirectDests())
-    BBs.push_back(cast<BasicBlock>(Ctx.getValue(LLVMBB)));
-  return BBs;
-}
-void CallBrInst::setDefaultDest(BasicBlock *BB) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CallBrInst::getDefaultDest,
-                                       &CallBrInst::setDefaultDest>>(this);
-  cast<llvm::CallBrInst>(Val)->setDefaultDest(cast<llvm::BasicBlock>(BB->Val));
-}
-void CallBrInst::setIndirectDest(unsigned Idx, BasicBlock *BB) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetterWithIdx<&CallBrInst::getIndirectDest,
-                                              &CallBrInst::setIndirectDest>>(
-          this, Idx);
-  cast<llvm::CallBrInst>(Val)->setIndirectDest(Idx,
-                                               cast<llvm::BasicBlock>(BB->Val));
-}
-BasicBlock *CallBrInst::getSuccessor(unsigned Idx) const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::CallBrInst>(Val)->getSuccessor(Idx)));
-}
-
-LandingPadInst *LandingPadInst::create(Type *RetTy, unsigned NumReservedClauses,
-                                       InsertPosition Pos, Context &Ctx,
-                                       const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::LandingPadInst *LLVMI =
-      Builder.CreateLandingPad(RetTy->LLVMTy, NumReservedClauses, Name);
-  return Ctx.createLandingPadInst(LLVMI);
-}
-
-void LandingPadInst::setCleanup(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&LandingPadInst::isCleanup,
-                                       &LandingPadInst::setCleanup>>(this);
-  cast<llvm::LandingPadInst>(Val)->setCleanup(V);
-}
-
-Constant *LandingPadInst::getClause(unsigned Idx) const {
-  return cast<Constant>(
-      Ctx.getValue(cast<llvm::LandingPadInst>(Val)->getClause(Idx)));
-}
-
-Value *FuncletPadInst::getParentPad() const {
-  return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getParentPad());
-}
-
-void FuncletPadInst::setParentPad(Value *ParentPad) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&FuncletPadInst::getParentPad,
-                                       &FuncletPadInst::setParentPad>>(this);
-  cast<llvm::FuncletPadInst>(Val)->setParentPad(ParentPad->Val);
-}
-
-Value *FuncletPadInst::getArgOperand(unsigned Idx) const {
-  return Ctx.getValue(cast<llvm::FuncletPadInst>(Val)->getArgOperand(Idx));
-}
-
-void FuncletPadInst::setArgOperand(unsigned Idx, Value *V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetterWithIdx<&FuncletPadInst::getArgOperand,
-                                              &FuncletPadInst::setArgOperand>>(
-          this, Idx);
-  cast<llvm::FuncletPadInst>(Val)->setArgOperand(Idx, V->Val);
-}
-
-CatchSwitchInst *CatchPadInst::getCatchSwitch() const {
-  return cast<CatchSwitchInst>(
-      Ctx.getValue(cast<llvm::CatchPadInst>(Val)->getCatchSwitch()));
-}
-
-CatchPadInst *CatchPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
-                                   InsertPosition Pos, Context &Ctx,
-                                   const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  SmallVector<llvm::Value *> LLVMArgs;
-  LLVMArgs.reserve(Args.size());
-  for (auto *Arg : Args)
-    LLVMArgs.push_back(Arg->Val);
-  llvm::CatchPadInst *LLVMI =
-      Builder.CreateCatchPad(ParentPad->Val, LLVMArgs, Name);
-  return Ctx.createCatchPadInst(LLVMI);
-}
-
-CleanupPadInst *CleanupPadInst::create(Value *ParentPad, ArrayRef<Value *> Args,
-                                       InsertPosition Pos, Context &Ctx,
-                                       const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  SmallVector<llvm::Value *> LLVMArgs;
-  LLVMArgs.reserve(Args.size());
-  for (auto *Arg : Args)
-    LLVMArgs.push_back(Arg->Val);
-  llvm::CleanupPadInst *LLVMI =
-      Builder.CreateCleanupPad(ParentPad->Val, LLVMArgs, Name);
-  return Ctx.createCleanupPadInst(LLVMI);
-}
-
-CatchReturnInst *CatchReturnInst::create(CatchPadInst *CatchPad, BasicBlock *BB,
-                                         InsertPosition Pos, Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::CatchReturnInst *LLVMI = Builder.CreateCatchRet(
-      cast<llvm::CatchPadInst>(CatchPad->Val), cast<llvm::BasicBlock>(BB->Val));
-  return Ctx.createCatchReturnInst(LLVMI);
-}
-
-CatchPadInst *CatchReturnInst::getCatchPad() const {
-  return cast<CatchPadInst>(
-      Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getCatchPad()));
-}
-
-void CatchReturnInst::setCatchPad(CatchPadInst *CatchPad) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CatchReturnInst::getCatchPad,
-                                       &CatchReturnInst::setCatchPad>>(this);
-  cast<llvm::CatchReturnInst>(Val)->setCatchPad(
-      cast<llvm::CatchPadInst>(CatchPad->Val));
-}
-
-BasicBlock *CatchReturnInst::getSuccessor() const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::CatchReturnInst>(Val)->getSuccessor()));
-}
-
-void CatchReturnInst::setSuccessor(BasicBlock *NewSucc) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CatchReturnInst::getSuccessor,
-                                       &CatchReturnInst::setSuccessor>>(this);
-  cast<llvm::CatchReturnInst>(Val)->setSuccessor(
-      cast<llvm::BasicBlock>(NewSucc->Val));
-}
-
-Value *CatchReturnInst::getCatchSwitchParentPad() const {
-  return Ctx.getValue(
-      cast<llvm::CatchReturnInst>(Val)->getCatchSwitchParentPad());
-}
-
-CleanupReturnInst *CleanupReturnInst::create(CleanupPadInst *CleanupPad,
-                                             BasicBlock *UnwindBB,
-                                             InsertPosition Pos, Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMUnwindBB =
-      UnwindBB != nullptr ? cast<llvm::BasicBlock>(UnwindBB->Val) : nullptr;
-  llvm::CleanupReturnInst *LLVMI = Builder.CreateCleanupRet(
-      cast<llvm::CleanupPadInst>(CleanupPad->Val), LLVMUnwindBB);
-  return Ctx.createCleanupReturnInst(LLVMI);
-}
-
-CleanupPadInst *CleanupReturnInst::getCleanupPad() const {
-  return cast<CleanupPadInst>(
-      Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getCleanupPad()));
-}
-
-void CleanupReturnInst::setCleanupPad(CleanupPadInst *CleanupPad) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getCleanupPad,
-                                       &CleanupReturnInst::setCleanupPad>>(
-          this);
-  cast<llvm::CleanupReturnInst>(Val)->setCleanupPad(
-      cast<llvm::CleanupPadInst>(CleanupPad->Val));
-}
-
-BasicBlock *CleanupReturnInst::getUnwindDest() const {
-  return cast_or_null<BasicBlock>(
-      Ctx.getValue(cast<llvm::CleanupReturnInst>(Val)->getUnwindDest()));
-}
-
-void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CleanupReturnInst::getUnwindDest,
-                                       &CleanupReturnInst::setUnwindDest>>(
-          this);
-  cast<llvm::CleanupReturnInst>(Val)->setUnwindDest(
-      cast<llvm::BasicBlock>(NewDest->Val));
-}
-
-Value *GetElementPtrInst::create(Type *Ty, Value *Ptr,
-                                 ArrayRef<Value *> IdxList, InsertPosition Pos,
-                                 Context &Ctx, const Twine &NameStr) {
-  auto &Builder = setInsertPos(Pos);
-  SmallVector<llvm::Value *> LLVMIdxList;
-  LLVMIdxList.reserve(IdxList.size());
-  for (Value *Idx : IdxList)
-    LLVMIdxList.push_back(Idx->Val);
-  llvm::Value *NewV =
-      Builder.CreateGEP(Ty->LLVMTy, Ptr->Val, LLVMIdxList, NameStr);
-  if (auto *NewGEP = dyn_cast<llvm::GetElementPtrInst>(NewV))
-    return Ctx.createGetElementPtrInst(NewGEP);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-Type *GetElementPtrInst::getSourceElementType() const {
-  return Ctx.getType(
-      cast<llvm::GetElementPtrInst>(Val)->getSourceElementType());
-}
-
-Type *GetElementPtrInst::getResultElementType() const {
-  return Ctx.getType(
-      cast<llvm::GetElementPtrInst>(Val)->getResultElementType());
-}
-
-Value *GetElementPtrInst::getPointerOperand() const {
-  return Ctx.getValue(cast<llvm::GetElementPtrInst>(Val)->getPointerOperand());
-}
-
-Type *GetElementPtrInst::getPointerOperandType() const {
-  return Ctx.getType(
-      cast<llvm::GetElementPtrInst>(Val)->getPointerOperandType());
-}
-
-BasicBlock *PHINode::LLVMBBToBB::operator()(llvm::BasicBlock *LLVMBB) const {
-  return cast<BasicBlock>(Ctx.getValue(LLVMBB));
-}
-
-PHINode *PHINode::create(Type *Ty, unsigned NumReservedValues,
-                         InsertPosition Pos, Context &Ctx, const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::PHINode *NewPHI =
-      Builder.CreatePHI(Ty->LLVMTy, NumReservedValues, Name);
-  return Ctx.createPHINode(NewPHI);
-}
-
-bool PHINode::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::PHI;
-}
-
-Value *PHINode::getIncomingValue(unsigned Idx) const {
-  return Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingValue(Idx));
-}
-void PHINode::setIncomingValue(unsigned Idx, Value *V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetterWithIdx<&PHINode::getIncomingValue,
-                                              &PHINode::setIncomingValue>>(this,
-                                                                           Idx);
-  cast<llvm::PHINode>(Val)->setIncomingValue(Idx, V->Val);
-}
-BasicBlock *PHINode::getIncomingBlock(unsigned Idx) const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::PHINode>(Val)->getIncomingBlock(Idx)));
-}
-BasicBlock *PHINode::getIncomingBlock(const Use &U) const {
-  llvm::Use *LLVMUse = U.LLVMUse;
-  llvm::BasicBlock *BB = cast<llvm::PHINode>(Val)->getIncomingBlock(*LLVMUse);
-  return cast<BasicBlock>(Ctx.getValue(BB));
-}
-void PHINode::setIncomingBlock(unsigned Idx, BasicBlock *BB) {
-  // Helper to disambiguate PHINode::getIncomingBlock(unsigned).
-  constexpr BasicBlock *(PHINode::*GetIncomingBlockFn)(unsigned) const =
-      &PHINode::getIncomingBlock;
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetterWithIdx<GetIncomingBlockFn, &PHINode::setIncomingBlock>>(
-          this, Idx);
-  cast<llvm::PHINode>(Val)->setIncomingBlock(Idx,
-                                             cast<llvm::BasicBlock>(BB->Val));
-}
-void PHINode::addIncoming(Value *V, BasicBlock *BB) {
-  auto &Tracker = Ctx.getTracker();
-  Tracker.emplaceIfTracking<PHIAddIncoming>(this);
-
-  cast<llvm::PHINode>(Val)->addIncoming(V->Val,
-                                        cast<llvm::BasicBlock>(BB->Val));
-}
-Value *PHINode::removeIncomingValue(unsigned Idx) {
-  auto &Tracker = Ctx.getTracker();
-  Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, Idx);
-  llvm::Value *LLVMV =
-      cast<llvm::PHINode>(Val)->removeIncomingValue(Idx,
-                                                    /*DeletePHIIfEmpty=*/false);
-  return Ctx.getValue(LLVMV);
-}
-Value *PHINode::removeIncomingValue(BasicBlock *BB) {
-  auto &Tracker = Ctx.getTracker();
-  Tracker.emplaceIfTracking<PHIRemoveIncoming>(this, getBasicBlockIndex(BB));
-
-  auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
-  llvm::Value *LLVMV =
-      cast<llvm::PHINode>(Val)->removeIncomingValue(LLVMBB,
-                                                    /*DeletePHIIfEmpty=*/false);
-  return Ctx.getValue(LLVMV);
-}
-int PHINode::getBasicBlockIndex(const BasicBlock *BB) const {
-  auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
-  return cast<llvm::PHINode>(Val)->getBasicBlockIndex(LLVMBB);
-}
-Value *PHINode::getIncomingValueForBlock(const BasicBlock *BB) const {
-  auto *LLVMBB = cast<llvm::BasicBlock>(BB->Val);
-  llvm::Value *LLVMV =
-      cast<llvm::PHINode>(Val)->getIncomingValueForBlock(LLVMBB);
-  return Ctx.getValue(LLVMV);
-}
-Value *PHINode::hasConstantValue() const {
-  llvm::Value *LLVMV = cast<llvm::PHINode>(Val)->hasConstantValue();
-  return LLVMV != nullptr ? Ctx.getValue(LLVMV) : nullptr;
-}
-void PHINode::replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) {
-  assert(New && Old && "Sandbox IR PHI node got a null basic block!");
-  for (unsigned Idx = 0, NumOps = cast<llvm::PHINode>(Val)->getNumOperands();
-       Idx != NumOps; ++Idx)
-    if (getIncomingBlock(Idx) == Old)
-      setIncomingBlock(Idx, New);
-}
-void PHINode::removeIncomingValueIf(function_ref<bool(unsigned)> Predicate) {
-  // Avoid duplicate tracking by going through this->removeIncomingValue here at
-  // the expense of some performance. Copy PHI::removeIncomingValueIf more
-  // directly if performance becomes an issue.
-
-  // Removing the element at index X, moves the element previously at X + 1
-  // to X. Working from the end avoids complications from that.
-  unsigned Idx = getNumIncomingValues();
-  while (Idx > 0) {
-    if (Predicate(Idx - 1))
-      removeIncomingValue(Idx - 1);
-    --Idx;
-  }
-}
-
-Value *CmpInst::create(Predicate P, Value *S1, Value *S2, InsertPosition Pos,
-                       Context &Ctx, const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMV = Builder.CreateCmp(P, S1->Val, S2->Val, Name);
-  // It may have been folded into a constant.
-  if (auto *LLVMC = dyn_cast<llvm::Constant>(LLVMV))
-    return Ctx.getOrCreateConstant(LLVMC);
-  if (isa<llvm::ICmpInst>(LLVMV))
-    return Ctx.createICmpInst(cast<llvm::ICmpInst>(LLVMV));
-  return Ctx.createFCmpInst(cast<llvm::FCmpInst>(LLVMV));
-}
-
-Value *CmpInst::createWithCopiedFlags(Predicate P, Value *S1, Value *S2,
-                                      const Instruction *F, InsertPosition Pos,
-                                      Context &Ctx, const Twine &Name) {
-  Value *V = create(P, S1, S2, Pos, Ctx, Name);
-  if (auto *C = dyn_cast<Constant>(V))
-    return C;
-  cast<llvm::CmpInst>(V->Val)->copyIRFlags(F->Val);
-  return V;
-}
-
-Type *CmpInst::makeCmpResultType(Type *OpndType) {
-  if (auto *VT = dyn_cast<VectorType>(OpndType)) {
-    // TODO: Cleanup when we have more complete support for
-    // sandboxir::VectorType
-    return OpndType->getContext().getType(llvm::VectorType::get(
-        llvm::Type::getInt1Ty(OpndType->getContext().LLVMCtx),
-        cast<llvm::VectorType>(VT->LLVMTy)->getElementCount()));
-  }
-  return Type::getInt1Ty(OpndType->getContext());
-}
-
-void CmpInst::setPredicate(Predicate P) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&CmpInst::getPredicate, &CmpInst::setPredicate>>(this);
-  cast<llvm::CmpInst>(Val)->setPredicate(P);
-}
-
-void CmpInst::swapOperands() {
-  if (ICmpInst *IC = dyn_cast<ICmpInst>(this))
-    IC->swapOperands();
-  else
-    cast<FCmpInst>(this)->swapOperands();
-}
-
-void ICmpInst::swapOperands() {
-  Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
-  cast<llvm::ICmpInst>(Val)->swapOperands();
-}
-
-void FCmpInst::swapOperands() {
-  Ctx.getTracker().emplaceIfTracking<CmpSwapOperands>(this);
-  cast<llvm::FCmpInst>(Val)->swapOperands();
-}
-
-#ifndef NDEBUG
-void CmpInst::dumpOS(raw_ostream &OS) const {
-  dumpCommonPrefix(OS);
-  dumpCommonSuffix(OS);
-}
-
-void CmpInst::dump() const {
-  dumpOS(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-static llvm::Instruction::CastOps getLLVMCastOp(Instruction::Opcode Opc) {
-  switch (Opc) {
-  case Instruction::Opcode::ZExt:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::ZExt);
-  case Instruction::Opcode::SExt:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SExt);
-  case Instruction::Opcode::FPToUI:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToUI);
-  case Instruction::Opcode::FPToSI:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPToSI);
-  case Instruction::Opcode::FPExt:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPExt);
-  case Instruction::Opcode::PtrToAddr:
-    return static_cast<llvm::Instruction::CastOps>(
-        llvm::Instruction::PtrToAddr);
-  case Instruction::Opcode::PtrToInt:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::PtrToInt);
-  case Instruction::Opcode::IntToPtr:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::IntToPtr);
-  case Instruction::Opcode::SIToFP:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::SIToFP);
-  case Instruction::Opcode::UIToFP:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::UIToFP);
-  case Instruction::Opcode::Trunc:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::Trunc);
-  case Instruction::Opcode::FPTrunc:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::FPTrunc);
-  case Instruction::Opcode::BitCast:
-    return static_cast<llvm::Instruction::CastOps>(llvm::Instruction::BitCast);
-  case Instruction::Opcode::AddrSpaceCast:
-    return static_cast<llvm::Instruction::CastOps>(
-        llvm::Instruction::AddrSpaceCast);
-  default:
-    llvm_unreachable("Opcode not suitable for CastInst!");
-  }
-}
-
-/// \Returns the LLVM opcode that corresponds to \p Opc.
-static llvm::Instruction::UnaryOps getLLVMUnaryOp(Instruction::Opcode Opc) {
-  switch (Opc) {
-  case Instruction::Opcode::FNeg:
-    return static_cast<llvm::Instruction::UnaryOps>(llvm::Instruction::FNeg);
-  default:
-    llvm_unreachable("Not a unary op!");
-  }
-}
-
-CatchSwitchInst *CatchSwitchInst::create(Value *ParentPad, BasicBlock *UnwindBB,
-                                         unsigned NumHandlers,
-                                         InsertPosition Pos, Context &Ctx,
-                                         const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::CatchSwitchInst *LLVMCSI = Builder.CreateCatchSwitch(
-      ParentPad->Val, cast<llvm::BasicBlock>(UnwindBB->Val), NumHandlers, Name);
-  return Ctx.createCatchSwitchInst(LLVMCSI);
-}
-
-Value *CatchSwitchInst::getParentPad() const {
-  return Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getParentPad());
-}
-
-void CatchSwitchInst::setParentPad(Value *ParentPad) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getParentPad,
-                                       &CatchSwitchInst::setParentPad>>(this);
-  cast<llvm::CatchSwitchInst>(Val)->setParentPad(ParentPad->Val);
-}
-
-BasicBlock *CatchSwitchInst::getUnwindDest() const {
-  return cast_or_null<BasicBlock>(
-      Ctx.getValue(cast<llvm::CatchSwitchInst>(Val)->getUnwindDest()));
-}
-
-void CatchSwitchInst::setUnwindDest(BasicBlock *UnwindDest) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&CatchSwitchInst::getUnwindDest,
-                                       &CatchSwitchInst::setUnwindDest>>(this);
-  cast<llvm::CatchSwitchInst>(Val)->setUnwindDest(
-      cast<llvm::BasicBlock>(UnwindDest->Val));
-}
-
-void CatchSwitchInst::addHandler(BasicBlock *Dest) {
-  Ctx.getTracker().emplaceIfTracking<CatchSwitchAddHandler>(this);
-  cast<llvm::CatchSwitchInst>(Val)->addHandler(
-      cast<llvm::BasicBlock>(Dest->Val));
-}
-
-ResumeInst *ResumeInst::create(Value *Exn, InsertPosition Pos, Context &Ctx) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMI = cast<llvm::ResumeInst>(Builder.CreateResume(Exn->Val));
-  return Ctx.createResumeInst(LLVMI);
-}
-
-Value *ResumeInst::getValue() const {
-  return Ctx.getValue(cast<llvm::ResumeInst>(Val)->getValue());
-}
-
-SwitchInst *SwitchInst::create(Value *V, BasicBlock *Dest, unsigned NumCases,
-                               InsertPosition Pos, Context &Ctx,
-                               const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::SwitchInst *LLVMSwitch =
-      Builder.CreateSwitch(V->Val, cast<llvm::BasicBlock>(Dest->Val), NumCases);
-  return Ctx.createSwitchInst(LLVMSwitch);
-}
-
-Value *SwitchInst::getCondition() const {
-  return Ctx.getValue(cast<llvm::SwitchInst>(Val)->getCondition());
-}
-
-void SwitchInst::setCondition(Value *V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&SwitchInst::getCondition, &SwitchInst::setCondition>>(
-          this);
-  cast<llvm::SwitchInst>(Val)->setCondition(V->Val);
-}
-
-BasicBlock *SwitchInst::getDefaultDest() const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::SwitchInst>(Val)->getDefaultDest()));
-}
-
-void SwitchInst::setDefaultDest(BasicBlock *DefaultCase) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&SwitchInst::getDefaultDest,
-                                       &SwitchInst::setDefaultDest>>(this);
-  cast<llvm::SwitchInst>(Val)->setDefaultDest(
-      cast<llvm::BasicBlock>(DefaultCase->Val));
-}
-ConstantInt *SwitchInst::findCaseDest(BasicBlock *BB) {
-  auto *LLVMC = cast<llvm::SwitchInst>(Val)->findCaseDest(
-      cast<llvm::BasicBlock>(BB->Val));
-  return LLVMC != nullptr ? cast<ConstantInt>(Ctx.getValue(LLVMC)) : nullptr;
-}
-
-void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
-  Ctx.getTracker().emplaceIfTracking<SwitchAddCase>(this, OnVal);
-  // TODO: Track this!
-  cast<llvm::SwitchInst>(Val)->addCase(cast<llvm::ConstantInt>(OnVal->Val),
-                                       cast<llvm::BasicBlock>(Dest->Val));
-}
-
-SwitchInst::CaseIt SwitchInst::removeCase(CaseIt It) {
-  Ctx.getTracker().emplaceIfTracking<SwitchRemoveCase>(this);
-
-  auto *LLVMSwitch = cast<llvm::SwitchInst>(Val);
-  unsigned CaseNum = It - case_begin();
-  llvm::SwitchInst::CaseIt LLVMIt(LLVMSwitch, CaseNum);
-  auto LLVMCaseIt = LLVMSwitch->removeCase(LLVMIt);
-  unsigned Num = LLVMCaseIt - LLVMSwitch->case_begin();
-  return CaseIt(this, Num);
-}
-
-BasicBlock *SwitchInst::getSuccessor(unsigned Idx) const {
-  return cast<BasicBlock>(
-      Ctx.getValue(cast<llvm::SwitchInst>(Val)->getSuccessor(Idx)));
-}
-
-void SwitchInst::setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetterWithIdx<&SwitchInst::getSuccessor,
-                                              &SwitchInst::setSuccessor>>(this,
-                                                                          Idx);
-  cast<llvm::SwitchInst>(Val)->setSuccessor(
-      Idx, cast<llvm::BasicBlock>(NewSucc->Val));
-}
-
-Value *UnaryOperator::create(Instruction::Opcode Op, Value *OpV,
-                             InsertPosition Pos, Context &Ctx,
-                             const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *NewLLVMV = Builder.CreateUnOp(getLLVMUnaryOp(Op), OpV->Val, Name);
-  if (auto *NewUnOpV = dyn_cast<llvm::UnaryOperator>(NewLLVMV)) {
-    return Ctx.createUnaryOperator(NewUnOpV);
-  }
-  assert(isa<llvm::Constant>(NewLLVMV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewLLVMV));
-}
-
-Value *UnaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *OpV,
-                                            Value *CopyFrom, InsertPosition Pos,
-                                            Context &Ctx, const Twine &Name) {
-  auto *NewV = create(Op, OpV, Pos, Ctx, Name);
-  if (auto *UnI = dyn_cast<llvm::UnaryOperator>(NewV->Val))
-    UnI->copyIRFlags(CopyFrom->Val);
-  return NewV;
-}
-
-/// \Returns the LLVM opcode that corresponds to \p Opc.
-static llvm::Instruction::BinaryOps getLLVMBinaryOp(Instruction::Opcode Opc) {
-  switch (Opc) {
-  case Instruction::Opcode::Add:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Add);
-  case Instruction::Opcode::FAdd:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FAdd);
-  case Instruction::Opcode::Sub:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Sub);
-  case Instruction::Opcode::FSub:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FSub);
-  case Instruction::Opcode::Mul:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Mul);
-  case Instruction::Opcode::FMul:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FMul);
-  case Instruction::Opcode::UDiv:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::UDiv);
-  case Instruction::Opcode::SDiv:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SDiv);
-  case Instruction::Opcode::FDiv:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FDiv);
-  case Instruction::Opcode::URem:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::URem);
-  case Instruction::Opcode::SRem:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::SRem);
-  case Instruction::Opcode::FRem:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::FRem);
-  case Instruction::Opcode::Shl:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Shl);
-  case Instruction::Opcode::LShr:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::LShr);
-  case Instruction::Opcode::AShr:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::AShr);
-  case Instruction::Opcode::And:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::And);
-  case Instruction::Opcode::Or:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Or);
-  case Instruction::Opcode::Xor:
-    return static_cast<llvm::Instruction::BinaryOps>(llvm::Instruction::Xor);
-  default:
-    llvm_unreachable("Not a binary op!");
-  }
-}
-Value *BinaryOperator::create(Instruction::Opcode Op, Value *LHS, Value *RHS,
-                              InsertPosition Pos, Context &Ctx,
-                              const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::Value *NewV =
-      Builder.CreateBinOp(getLLVMBinaryOp(Op), LHS->Val, RHS->Val, Name);
-  if (auto *NewBinOp = dyn_cast<llvm::BinaryOperator>(NewV))
-    return Ctx.createBinaryOperator(NewBinOp);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-Value *BinaryOperator::createWithCopiedFlags(Instruction::Opcode Op, Value *LHS,
-                                             Value *RHS, Value *CopyFrom,
-                                             InsertPosition Pos, Context &Ctx,
-                                             const Twine &Name) {
-
-  Value *NewV = create(Op, LHS, RHS, Pos, Ctx, Name);
-  if (auto *NewBO = dyn_cast<BinaryOperator>(NewV))
-    cast<llvm::BinaryOperator>(NewBO->Val)->copyIRFlags(CopyFrom->Val);
-  return NewV;
-}
-
-void PossiblyDisjointInst::setIsDisjoint(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&PossiblyDisjointInst::isDisjoint,
-                                       &PossiblyDisjointInst::setIsDisjoint>>(
-          this);
-  cast<llvm::PossiblyDisjointInst>(Val)->setIsDisjoint(B);
-}
-
-void AtomicRMWInst::setAlignment(Align Align) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getAlign,
-                                       &AtomicRMWInst::setAlignment>>(this);
-  cast<llvm::AtomicRMWInst>(Val)->setAlignment(Align);
-}
-
-void AtomicRMWInst::setVolatile(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicRMWInst::isVolatile,
-                                       &AtomicRMWInst::setVolatile>>(this);
-  cast<llvm::AtomicRMWInst>(Val)->setVolatile(V);
-}
-
-void AtomicRMWInst::setOrdering(AtomicOrdering Ordering) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getOrdering,
-                                       &AtomicRMWInst::setOrdering>>(this);
-  cast<llvm::AtomicRMWInst>(Val)->setOrdering(Ordering);
-}
-
-void AtomicRMWInst::setSyncScopeID(SyncScope::ID SSID) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicRMWInst::getSyncScopeID,
-                                       &AtomicRMWInst::setSyncScopeID>>(this);
-  cast<llvm::AtomicRMWInst>(Val)->setSyncScopeID(SSID);
-}
-
-Value *AtomicRMWInst::getPointerOperand() {
-  return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getPointerOperand());
-}
-
-Value *AtomicRMWInst::getValOperand() {
-  return Ctx.getValue(cast<llvm::AtomicRMWInst>(Val)->getValOperand());
-}
-
-AtomicRMWInst *AtomicRMWInst::create(BinOp Op, Value *Ptr, Value *Val,
-                                     MaybeAlign Align, AtomicOrdering Ordering,
-                                     InsertPosition Pos, Context &Ctx,
-                                     SyncScope::ID SSID, const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMAtomicRMW =
-      Builder.CreateAtomicRMW(Op, Ptr->Val, Val->Val, Align, Ordering, SSID);
-  LLVMAtomicRMW->setName(Name);
-  return Ctx.createAtomicRMWInst(LLVMAtomicRMW);
-}
-
-void AtomicCmpXchgInst::setSyncScopeID(SyncScope::ID SSID) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSyncScopeID,
-                                       &AtomicCmpXchgInst::setSyncScopeID>>(
-          this);
-  cast<llvm::AtomicCmpXchgInst>(Val)->setSyncScopeID(SSID);
-}
-
-Value *AtomicCmpXchgInst::getPointerOperand() {
-  return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getPointerOperand());
-}
-
-Value *AtomicCmpXchgInst::getCompareOperand() {
-  return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getCompareOperand());
-}
-
-Value *AtomicCmpXchgInst::getNewValOperand() {
-  return Ctx.getValue(cast<llvm::AtomicCmpXchgInst>(Val)->getNewValOperand());
-}
-
-AtomicCmpXchgInst *
-AtomicCmpXchgInst::create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
-                          AtomicOrdering SuccessOrdering,
-                          AtomicOrdering FailureOrdering, InsertPosition Pos,
-                          Context &Ctx, SyncScope::ID SSID, const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *LLVMAtomicCmpXchg =
-      Builder.CreateAtomicCmpXchg(Ptr->Val, Cmp->Val, New->Val, Align,
-                                  SuccessOrdering, FailureOrdering, SSID);
-  LLVMAtomicCmpXchg->setName(Name);
-  return Ctx.createAtomicCmpXchgInst(LLVMAtomicCmpXchg);
-}
-
-void AtomicCmpXchgInst::setAlignment(Align Align) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getAlign,
-                                       &AtomicCmpXchgInst::setAlignment>>(this);
-  cast<llvm::AtomicCmpXchgInst>(Val)->setAlignment(Align);
-}
-
-void AtomicCmpXchgInst::setVolatile(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isVolatile,
-                                       &AtomicCmpXchgInst::setVolatile>>(this);
-  cast<llvm::AtomicCmpXchgInst>(Val)->setVolatile(V);
-}
-
-void AtomicCmpXchgInst::setWeak(bool IsWeak) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::isWeak,
-                                       &AtomicCmpXchgInst::setWeak>>(this);
-  cast<llvm::AtomicCmpXchgInst>(Val)->setWeak(IsWeak);
-}
-
-void AtomicCmpXchgInst::setSuccessOrdering(AtomicOrdering Ordering) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getSuccessOrdering,
-                                       &AtomicCmpXchgInst::setSuccessOrdering>>(
-          this);
-  cast<llvm::AtomicCmpXchgInst>(Val)->setSuccessOrdering(Ordering);
-}
-
-void AtomicCmpXchgInst::setFailureOrdering(AtomicOrdering Ordering) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AtomicCmpXchgInst::getFailureOrdering,
-                                       &AtomicCmpXchgInst::setFailureOrdering>>(
-          this);
-  cast<llvm::AtomicCmpXchgInst>(Val)->setFailureOrdering(Ordering);
-}
-
-AllocaInst *AllocaInst::create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
-                               Context &Ctx, Value *ArraySize,
-                               const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  auto *NewAlloca =
-      Builder.CreateAlloca(Ty->LLVMTy, AddrSpace, ArraySize->Val, Name);
-  return Ctx.createAllocaInst(NewAlloca);
-}
-
-Type *AllocaInst::getAllocatedType() const {
-  return Ctx.getType(cast<llvm::AllocaInst>(Val)->getAllocatedType());
-}
-
-void AllocaInst::setAllocatedType(Type *Ty) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AllocaInst::getAllocatedType,
-                                       &AllocaInst::setAllocatedType>>(this);
-  cast<llvm::AllocaInst>(Val)->setAllocatedType(Ty->LLVMTy);
-}
-
-void AllocaInst::setAlignment(Align Align) {
-  Ctx.getTracker()
-      .emplaceIfTracking<
-          GenericSetter<&AllocaInst::getAlign, &AllocaInst::setAlignment>>(
-          this);
-  cast<llvm::AllocaInst>(Val)->setAlignment(Align);
-}
-
-void AllocaInst::setUsedWithInAlloca(bool V) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&AllocaInst::isUsedWithInAlloca,
-                                       &AllocaInst::setUsedWithInAlloca>>(this);
-  cast<llvm::AllocaInst>(Val)->setUsedWithInAlloca(V);
-}
-
-Value *AllocaInst::getArraySize() {
-  return Ctx.getValue(cast<llvm::AllocaInst>(Val)->getArraySize());
-}
-
-PointerType *AllocaInst::getType() const {
-  return cast<PointerType>(Ctx.getType(cast<llvm::AllocaInst>(Val)->getType()));
-}
-
-Value *CastInst::create(Type *DestTy, Opcode Op, Value *Operand,
-                        InsertPosition Pos, Context &Ctx, const Twine &Name) {
-  assert(getLLVMCastOp(Op) && "Opcode not suitable for CastInst!");
-  auto &Builder = setInsertPos(Pos);
-  auto *NewV =
-      Builder.CreateCast(getLLVMCastOp(Op), Operand->Val, DestTy->LLVMTy, Name);
-  if (auto *NewCI = dyn_cast<llvm::CastInst>(NewV))
-    return Ctx.createCastInst(NewCI);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-bool CastInst::classof(const Value *From) {
-  return From->getSubclassID() == ClassID::Cast;
-}
-
-Type *CastInst::getSrcTy() const {
-  return Ctx.getType(cast<llvm::CastInst>(Val)->getSrcTy());
-}
-
-Type *CastInst::getDestTy() const {
-  return Ctx.getType(cast<llvm::CastInst>(Val)->getDestTy());
-}
-
-void PossiblyNonNegInst::setNonNeg(bool B) {
-  Ctx.getTracker()
-      .emplaceIfTracking<GenericSetter<&PossiblyNonNegInst::hasNonNeg,
-                                       &PossiblyNonNegInst::setNonNeg>>(this);
-  cast<llvm::PossiblyNonNegInst>(Val)->setNonNeg(B);
-}
-
-Value *InsertElementInst::create(Value *Vec, Value *NewElt, Value *Idx,
-                                 InsertPosition Pos, Context &Ctx,
-                                 const Twine &Name) {
-  auto &Builder = Instruction::setInsertPos(Pos);
-  llvm::Value *NewV =
-      Builder.CreateInsertElement(Vec->Val, NewElt->Val, Idx->Val, Name);
-  if (auto *NewInsert = dyn_cast<llvm::InsertElementInst>(NewV))
-    return Ctx.createInsertElementInst(NewInsert);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-Value *ExtractElementInst::create(Value *Vec, Value *Idx, InsertPosition Pos,
-                                  Context &Ctx, const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::Value *NewV = Builder.CreateExtractElement(Vec->Val, Idx->Val, Name);
-  if (auto *NewExtract = dyn_cast<llvm::ExtractElementInst>(NewV))
-    return Ctx.createExtractElementInst(NewExtract);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-Value *ShuffleVectorInst::create(Value *V1, Value *V2, Value *Mask,
-                                 InsertPosition Pos, Context &Ctx,
-                                 const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::Value *NewV =
-      Builder.CreateShuffleVector(V1->Val, V2->Val, Mask->Val, Name);
-  if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
-    return Ctx.createShuffleVectorInst(NewShuffle);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-Value *ShuffleVectorInst::create(Value *V1, Value *V2, ArrayRef<int> Mask,
-                                 InsertPosition Pos, Context &Ctx,
-                                 const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::Value *NewV = Builder.CreateShuffleVector(V1->Val, V2->Val, Mask, Name);
-  if (auto *NewShuffle = dyn_cast<llvm::ShuffleVectorInst>(NewV))
-    return Ctx.createShuffleVectorInst(NewShuffle);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-void ShuffleVectorInst::setShuffleMask(ArrayRef<int> Mask) {
-  Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
-  cast<llvm::ShuffleVectorInst>(Val)->setShuffleMask(Mask);
-}
-
-VectorType *ShuffleVectorInst::getType() const {
-  return cast<VectorType>(
-      Ctx.getType(cast<llvm::ShuffleVectorInst>(Val)->getType()));
-}
-
-void ShuffleVectorInst::commute() {
-  Ctx.getTracker().emplaceIfTracking<ShuffleVectorSetMask>(this);
-  Ctx.getTracker().emplaceIfTracking<UseSwap>(getOperandUse(0),
-                                              getOperandUse(1));
-  cast<llvm::ShuffleVectorInst>(Val)->commute();
-}
-
-Constant *ShuffleVectorInst::getShuffleMaskForBitcode() const {
-  return Ctx.getOrCreateConstant(
-      cast<llvm::ShuffleVectorInst>(Val)->getShuffleMaskForBitcode());
-}
-
-Constant *ShuffleVectorInst::convertShuffleMaskForBitcode(ArrayRef<int> Mask,
-                                                          Type *ResultTy) {
-  return ResultTy->getContext().getOrCreateConstant(
-      llvm::ShuffleVectorInst::convertShuffleMaskForBitcode(Mask,
-                                                            ResultTy->LLVMTy));
-}
-
-VectorType *ExtractElementInst::getVectorOperandType() const {
-  return cast<VectorType>(Ctx.getType(getVectorOperand()->getType()->LLVMTy));
-}
-
-Value *ExtractValueInst::create(Value *Agg, ArrayRef<unsigned> Idxs,
-                                InsertPosition Pos, Context &Ctx,
-                                const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::Value *NewV = Builder.CreateExtractValue(Agg->Val, Idxs, Name);
-  if (auto *NewExtractValueInst = dyn_cast<llvm::ExtractValueInst>(NewV))
-    return Ctx.createExtractValueInst(NewExtractValueInst);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-Type *ExtractValueInst::getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs) {
-  auto *LLVMTy = llvm::ExtractValueInst::getIndexedType(Agg->LLVMTy, Idxs);
-  return Agg->getContext().getType(LLVMTy);
-}
-
-Value *InsertValueInst::create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
-                               InsertPosition Pos, Context &Ctx,
-                               const Twine &Name) {
-  auto &Builder = setInsertPos(Pos);
-  llvm::Value *NewV = Builder.CreateInsertValue(Agg->Val, Val->Val, Idxs, Name);
-  if (auto *NewInsertValueInst = dyn_cast<llvm::InsertValueInst>(NewV))
-    return Ctx.createInsertValueInst(NewInsertValueInst);
-  assert(isa<llvm::Constant>(NewV) && "Expected constant");
-  return Ctx.getOrCreateConstant(cast<llvm::Constant>(NewV));
-}
-
-ConstantTokenNone *ConstantTokenNone::get(Context &Ctx) {
-  auto *LLVMC = llvm::ConstantTokenNone::get(Ctx.LLVMCtx);
-  return cast<ConstantTokenNone>(Ctx.getOrCreateConstant(LLVMC));
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Module.cpp b/llvm/lib/SandboxIR/Module.cpp
deleted file mode 100644
index 61cc2414c45ae..0000000000000
--- a/llvm/lib/SandboxIR/Module.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//===- Module.cpp ---------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Module.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Value.h"
-
-using namespace llvm::sandboxir;
-
-Function *Module::getFunction(StringRef Name) const {
-  llvm::Function *LLVMF = LLVMM.getFunction(Name);
-  return cast_or_null<Function>(Ctx.getValue(LLVMF));
-}
-
-GlobalVariable *Module::getGlobalVariable(StringRef Name,
-                                          bool AllowInternal) const {
-  return cast_or_null<GlobalVariable>(
-      Ctx.getValue(LLVMM.getGlobalVariable(Name, AllowInternal)));
-}
-
-GlobalAlias *Module::getNamedAlias(StringRef Name) const {
-  return cast_or_null<GlobalAlias>(Ctx.getValue(LLVMM.getNamedAlias(Name)));
-}
-
-GlobalIFunc *Module::getNamedIFunc(StringRef Name) const {
-  return cast_or_null<GlobalIFunc>(Ctx.getValue(LLVMM.getNamedIFunc(Name)));
-}
-
-#ifndef NDEBUG
-void Module::dumpOS(raw_ostream &OS) const { OS << LLVMM; }
-
-void Module::dump() const {
-  dumpOS(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
diff --git a/llvm/lib/SandboxIR/Pass.cpp b/llvm/lib/SandboxIR/Pass.cpp
deleted file mode 100644
index 64e1b609a9f49..0000000000000
--- a/llvm/lib/SandboxIR/Pass.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-//===- Pass.cpp - Passes that operate on Sandbox IR -----------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/Support/Debug.h"
-
-using namespace llvm::sandboxir;
-
-#ifndef NDEBUG
-void Pass::dump() const {
-  print(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
diff --git a/llvm/lib/SandboxIR/PassManager.cpp b/llvm/lib/SandboxIR/PassManager.cpp
deleted file mode 100644
index aaa49e0f6912b..0000000000000
--- a/llvm/lib/SandboxIR/PassManager.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-//===- PassManager.cpp - Runs a pipeline of Sandbox IR passes -------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/PassManager.h"
-
-namespace llvm::sandboxir {
-
-bool FunctionPassManager::runOnFunction(Function &F, const Analyses &A) {
-  bool Change = false;
-  for (auto &Pass : Passes) {
-    Change |= Pass->runOnFunction(F, A);
-    // TODO: run the verifier.
-  }
-  // TODO: Check ChangeAll against hashes before/after.
-  return Change;
-}
-
-bool RegionPassManager::runOnRegion(Region &R, const Analyses &A) {
-  bool Change = false;
-  for (auto &Pass : Passes) {
-    Change |= Pass->runOnRegion(R, A);
-    // TODO: run the verifier.
-  }
-  // TODO: Check ChangeAll against hashes before/after.
-  return Change;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Region.cpp b/llvm/lib/SandboxIR/Region.cpp
deleted file mode 100644
index bd79a97cdd0a9..0000000000000
--- a/llvm/lib/SandboxIR/Region.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-//===- Region.cpp ---------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/SandboxIR/Function.h"
-
-namespace llvm::sandboxir {
-
-InstructionCost ScoreBoard::getCost(Instruction *I) const {
-  auto *LLVMI = cast<llvm::Instruction>(I->Val);
-  SmallVector<const llvm::Value *> Operands(LLVMI->operands());
-  return TTI.getInstructionCost(LLVMI, Operands, CostKind);
-}
-
-void ScoreBoard::remove(Instruction *I) {
-  auto Cost = getCost(I);
-  if (Rgn.contains(I))
-    // If `I` is one the newly added ones, then we should adjust `AfterCost`
-    AfterCost -= Cost;
-  else
-    // If `I` is one of the original instructions (outside the region) then it
-    // is part of the original code, so adjust `BeforeCost`.
-    BeforeCost += Cost;
-}
-
-#ifndef NDEBUG
-void ScoreBoard::dump() const { dump(dbgs()); }
-#endif
-
-Region::Region(Context &Ctx, TargetTransformInfo &TTI)
-    : Ctx(Ctx), Scoreboard(*this, TTI) {
-  LLVMContext &LLVMCtx = Ctx.LLVMCtx;
-  auto *RegionStrMD = MDString::get(LLVMCtx, RegionStr);
-  RegionMDN = MDNode::getDistinct(LLVMCtx, {RegionStrMD});
-
-  CreateInstCB = Ctx.registerCreateInstrCallback(
-      [this](Instruction *NewInst) { add(NewInst); });
-  EraseInstCB = Ctx.registerEraseInstrCallback([this](Instruction *ErasedInst) {
-    remove(ErasedInst);
-    removeFromAux(ErasedInst);
-  });
-}
-
-Region::~Region() {
-  Ctx.unregisterCreateInstrCallback(CreateInstCB);
-  Ctx.unregisterEraseInstrCallback(EraseInstCB);
-}
-
-void Region::addImpl(Instruction *I, bool IgnoreCost) {
-  Insts.insert(I);
-  // TODO: Consider tagging instructions lazily.
-  cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, RegionMDN);
-  if (!IgnoreCost)
-    // Keep track of the instruction cost.
-    Scoreboard.add(I);
-}
-
-void Region::setAux(ArrayRef<Instruction *> Aux) {
-  this->Aux = SmallVector<Instruction *>(Aux);
-  auto &LLVMCtx = Ctx.LLVMCtx;
-  for (auto [Idx, I] : enumerate(Aux)) {
-    llvm::ConstantInt *IdxC =
-        llvm::ConstantInt::get(llvm::Type::getInt32Ty(LLVMCtx), Idx, false);
-    assert(cast<llvm::Instruction>(I->Val)->getMetadata(AuxMDKind) == nullptr &&
-           "Instruction already in Aux!");
-    cast<llvm::Instruction>(I->Val)->setMetadata(
-        AuxMDKind, MDNode::get(LLVMCtx, ConstantAsMetadata::get(IdxC)));
-    // Aux instrs should always be in a region.
-    addImpl(I, /*DontTrackCost=*/true);
-  }
-}
-
-void Region::setAux(unsigned Idx, Instruction *I) {
-  assert((Idx >= Aux.size() || Aux[Idx] == nullptr) &&
-         "There is already an Instruction at Idx in Aux!");
-  unsigned ExpectedSz = Idx + 1;
-  if (Aux.size() < ExpectedSz) {
-    auto SzBefore = Aux.size();
-    Aux.resize(ExpectedSz);
-    // Initialize the gap with nullptr.
-    for (unsigned Idx = SzBefore; Idx + 1 < ExpectedSz; ++Idx)
-      Aux[Idx] = nullptr;
-  }
-  Aux[Idx] = I;
-  // Aux instrs should always be in a region.
-  addImpl(I, /*DontTrackCost=*/true);
-}
-
-void Region::dropAuxMetadata(Instruction *I) {
-  auto *LLVMI = cast<llvm::Instruction>(I->Val);
-  LLVMI->setMetadata(AuxMDKind, nullptr);
-}
-
-void Region::removeFromAux(Instruction *I) {
-  auto It = find(Aux, I);
-  if (It == Aux.end())
-    return;
-  dropAuxMetadata(I);
-  Aux.erase(It);
-}
-
-void Region::clearAux() {
-  for (unsigned Idx : seq<unsigned>(0, Aux.size()))
-    dropAuxMetadata(Aux[Idx]);
-  Aux.clear();
-}
-
-void Region::remove(Instruction *I) {
-  // Keep track of the instruction cost. This need to be done *before* we remove
-  // `I` from the region.
-  Scoreboard.remove(I);
-
-  Insts.remove(I);
-  cast<llvm::Instruction>(I->Val)->setMetadata(MDKind, nullptr);
-}
-
-#ifndef NDEBUG
-bool Region::operator==(const Region &Other) const {
-  if (Insts.size() != Other.Insts.size())
-    return false;
-  if (!std::is_permutation(Insts.begin(), Insts.end(), Other.Insts.begin()))
-    return false;
-  return true;
-}
-
-void Region::dump(raw_ostream &OS) const {
-  for (auto *I : Insts)
-    OS << *I << "\n";
-  if (!Aux.empty()) {
-    OS << "\nAux:\n";
-    for (auto *I : Aux) {
-      if (I == nullptr)
-        OS << "NULL\n";
-      else
-        OS << *I << "\n";
-    }
-  }
-}
-
-void Region::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-SmallVector<std::unique_ptr<Region>>
-Region::createRegionsFromMD(Function &F, TargetTransformInfo &TTI) {
-  SmallVector<std::unique_ptr<Region>> Regions;
-  DenseMap<MDNode *, Region *> MDNToRegion;
-  auto &Ctx = F.getContext();
-  for (BasicBlock &BB : F) {
-    for (Instruction &Inst : BB) {
-      auto *LLVMI = cast<llvm::Instruction>(Inst.Val);
-      Region *R = nullptr;
-      if (auto *MDN = LLVMI->getMetadata(MDKind)) {
-        auto [It, Inserted] = MDNToRegion.try_emplace(MDN);
-        if (Inserted) {
-          Regions.push_back(std::make_unique<Region>(Ctx, TTI));
-          R = Regions.back().get();
-          It->second = R;
-        } else {
-          R = It->second;
-        }
-        R->addImpl(&Inst, /*IgnoreCost=*/true);
-      }
-      if (auto *AuxMDN = LLVMI->getMetadata(AuxMDKind)) {
-        llvm::Constant *IdxC =
-            dyn_cast<ConstantAsMetadata>(AuxMDN->getOperand(0))->getValue();
-        auto Idx = cast<llvm::ConstantInt>(IdxC)->getSExtValue();
-        if (R == nullptr) {
-          errs() << "No region specified for Aux: '" << *LLVMI << "'\n";
-          exit(1);
-        }
-        R->setAux(Idx, &Inst);
-      }
-    }
-  }
-#ifndef NDEBUG
-  // Check that there are no gaps in the Aux vector.
-  for (auto &RPtr : Regions)
-    for (auto *I : RPtr->getAux())
-      assert(I != nullptr && "Gap in Aux!");
-#endif
-  return Regions;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Tracker.cpp b/llvm/lib/SandboxIR/Tracker.cpp
deleted file mode 100644
index 08dbfaf8398bd..0000000000000
--- a/llvm/lib/SandboxIR/Tracker.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-//===- Tracker.cpp --------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Tracker.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/StructuralHash.h"
-#include "llvm/SandboxIR/Instruction.h"
-
-using namespace llvm::sandboxir;
-
-#ifndef NDEBUG
-
-std::string IRSnapshotChecker::dumpIR(const llvm::Function &F) const {
-  std::string Result;
-  raw_string_ostream SS(Result);
-  F.print(SS, /*AssemblyAnnotationWriter=*/nullptr);
-  return Result;
-}
-
-IRSnapshotChecker::ContextSnapshot IRSnapshotChecker::takeSnapshot() const {
-  ContextSnapshot Result;
-  for (const auto &Entry : Ctx.LLVMModuleToModuleMap)
-    for (const auto &F : *Entry.first) {
-      FunctionSnapshot Snapshot;
-      Snapshot.Hash = StructuralHash(F, /*DetailedHash=*/true);
-      Snapshot.TextualIR = dumpIR(F);
-      Result[&F] = Snapshot;
-    }
-  return Result;
-}
-
-bool IRSnapshotChecker::diff(const ContextSnapshot &Orig,
-                             const ContextSnapshot &Curr) const {
-  bool DifferenceFound = false;
-  for (const auto &[F, OrigFS] : Orig) {
-    auto CurrFSIt = Curr.find(F);
-    if (CurrFSIt == Curr.end()) {
-      DifferenceFound = true;
-      dbgs() << "Function " << F->getName() << " not found in current IR.\n";
-      dbgs() << OrigFS.TextualIR << "\n";
-      continue;
-    }
-    const FunctionSnapshot &CurrFS = CurrFSIt->second;
-    if (OrigFS.Hash != CurrFS.Hash) {
-      DifferenceFound = true;
-      dbgs() << "Found IR difference in Function " << F->getName() << "\n";
-      dbgs() << "Original:\n" << OrigFS.TextualIR << "\n";
-      dbgs() << "Current:\n" << CurrFS.TextualIR << "\n";
-    }
-  }
-  // Check that Curr doesn't contain any new functions.
-  for (const auto &[F, CurrFS] : Curr) {
-    if (!Orig.contains(F)) {
-      DifferenceFound = true;
-      dbgs() << "Function " << F->getName()
-             << " found in current IR but not in original snapshot.\n";
-      dbgs() << CurrFS.TextualIR << "\n";
-    }
-  }
-  return DifferenceFound;
-}
-
-void IRSnapshotChecker::save() { OrigContextSnapshot = takeSnapshot(); }
-
-void IRSnapshotChecker::expectNoDiff() {
-  ContextSnapshot CurrContextSnapshot = takeSnapshot();
-  if (diff(OrigContextSnapshot, CurrContextSnapshot)) {
-    llvm_unreachable(
-        "Original and current IR differ! Probably a checkpointing bug.");
-  }
-}
-
-void UseSet::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-
-void UseSwap::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-PHIRemoveIncoming::PHIRemoveIncoming(PHINode *PHI, unsigned RemovedIdx)
-    : PHI(PHI), RemovedIdx(RemovedIdx) {
-  RemovedV = PHI->getIncomingValue(RemovedIdx);
-  RemovedBB = PHI->getIncomingBlock(RemovedIdx);
-}
-
-void PHIRemoveIncoming::revert(Tracker &Tracker) {
-  // Special case: if the PHI is now empty, as we don't need to care about the
-  // order of the incoming values.
-  unsigned NumIncoming = PHI->getNumIncomingValues();
-  if (NumIncoming == 0) {
-    PHI->addIncoming(RemovedV, RemovedBB);
-    return;
-  }
-  // Shift all incoming values by one starting from the end until `Idx`.
-  // Start by adding a copy of the last incoming values.
-  unsigned LastIdx = NumIncoming - 1;
-  PHI->addIncoming(PHI->getIncomingValue(LastIdx),
-                   PHI->getIncomingBlock(LastIdx));
-  for (unsigned Idx = LastIdx; Idx > RemovedIdx; --Idx) {
-    auto *PrevV = PHI->getIncomingValue(Idx - 1);
-    auto *PrevBB = PHI->getIncomingBlock(Idx - 1);
-    PHI->setIncomingValue(Idx, PrevV);
-    PHI->setIncomingBlock(Idx, PrevBB);
-  }
-  PHI->setIncomingValue(RemovedIdx, RemovedV);
-  PHI->setIncomingBlock(RemovedIdx, RemovedBB);
-}
-
-#ifndef NDEBUG
-void PHIRemoveIncoming::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-PHIAddIncoming::PHIAddIncoming(PHINode *PHI)
-    : PHI(PHI), Idx(PHI->getNumIncomingValues()) {}
-
-void PHIAddIncoming::revert(Tracker &Tracker) { PHI->removeIncomingValue(Idx); }
-
-#ifndef NDEBUG
-void PHIAddIncoming::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-Tracker::~Tracker() {
-  assert(Changes.empty() && "You must accept or revert changes!");
-}
-
-EraseFromParent::EraseFromParent(std::unique_ptr<sandboxir::Value> &&ErasedIPtr)
-    : ErasedIPtr(std::move(ErasedIPtr)) {
-  auto *I = cast<Instruction>(this->ErasedIPtr.get());
-  auto LLVMInstrs = I->getLLVMInstrs();
-  // Iterate in reverse program order.
-  for (auto *LLVMI : reverse(LLVMInstrs)) {
-    SmallVector<llvm::Value *> Operands;
-    Operands.reserve(LLVMI->getNumOperands());
-    for (auto [OpNum, Use] : enumerate(LLVMI->operands()))
-      Operands.push_back(Use.get());
-    InstrData.push_back({Operands, LLVMI});
-  }
-  assert(is_sorted(InstrData,
-                   [](const auto &D0, const auto &D1) {
-                     return D0.LLVMI->comesBefore(D1.LLVMI);
-                   }) &&
-         "Expected reverse program order!");
-  auto *BotLLVMI = cast<llvm::Instruction>(I->Val);
-  if (BotLLVMI->getNextNode() != nullptr)
-    NextLLVMIOrBB = BotLLVMI->getNextNode();
-  else
-    NextLLVMIOrBB = BotLLVMI->getParent();
-}
-
-void EraseFromParent::accept() {
-  for (const auto &IData : InstrData)
-    IData.LLVMI->deleteValue();
-}
-
-void EraseFromParent::revert(Tracker &Tracker) {
-  // Place the bottom-most instruction first.
-  auto [Operands, BotLLVMI] = InstrData[0];
-  if (auto *NextLLVMI = dyn_cast<llvm::Instruction *>(NextLLVMIOrBB)) {
-    BotLLVMI->insertBefore(NextLLVMI->getIterator());
-  } else {
-    auto *LLVMBB = cast<llvm::BasicBlock *>(NextLLVMIOrBB);
-    BotLLVMI->insertInto(LLVMBB, LLVMBB->end());
-  }
-  for (auto [OpNum, Op] : enumerate(Operands))
-    BotLLVMI->setOperand(OpNum, Op);
-
-  // Go over the rest of the instructions and stack them on top.
-  for (auto [Operands, LLVMI] : drop_begin(InstrData)) {
-    LLVMI->insertBefore(BotLLVMI->getIterator());
-    for (auto [OpNum, Op] : enumerate(Operands))
-      LLVMI->setOperand(OpNum, Op);
-    BotLLVMI = LLVMI;
-  }
-  Tracker.getContext().registerValue(std::move(ErasedIPtr));
-}
-
-#ifndef NDEBUG
-void EraseFromParent::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-RemoveFromParent::RemoveFromParent(Instruction *RemovedI) : RemovedI(RemovedI) {
-  if (auto *NextI = RemovedI->getNextNode())
-    NextInstrOrBB = NextI;
-  else
-    NextInstrOrBB = RemovedI->getParent();
-}
-
-void RemoveFromParent::revert(Tracker &Tracker) {
-  if (auto *NextI = dyn_cast<Instruction *>(NextInstrOrBB)) {
-    RemovedI->insertBefore(NextI);
-  } else {
-    auto *BB = cast<BasicBlock *>(NextInstrOrBB);
-    RemovedI->insertInto(BB, BB->end());
-  }
-}
-
-#ifndef NDEBUG
-void RemoveFromParent::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-CatchSwitchAddHandler::CatchSwitchAddHandler(CatchSwitchInst *CSI)
-    : CSI(CSI), HandlerIdx(CSI->getNumHandlers()) {}
-
-void CatchSwitchAddHandler::revert(Tracker &Tracker) {
-  // TODO: This should ideally use sandboxir::CatchSwitchInst::removeHandler()
-  // once it gets implemented.
-  auto *LLVMCSI = cast<llvm::CatchSwitchInst>(CSI->Val);
-  LLVMCSI->removeHandler(LLVMCSI->handler_begin() + HandlerIdx);
-}
-
-SwitchRemoveCase::SwitchRemoveCase(SwitchInst *Switch) : Switch(Switch) {
-  for (const auto &C : Switch->cases())
-    Cases.push_back({C.getCaseValue(), C.getCaseSuccessor()});
-}
-
-void SwitchRemoveCase::revert(Tracker &Tracker) {
-  // SwitchInst::removeCase doesn't provide any guarantees about the order of
-  // cases after removal. In order to preserve the original ordering, we save
-  // all of them and, when reverting, clear them all then insert them in the
-  // desired order. This still relies on the fact that `addCase` will insert
-  // them at the end, but it is documented to invalidate `case_end()` so it's
-  // probably okay.
-  unsigned NumCases = Switch->getNumCases();
-  for (unsigned I = 0; I < NumCases; ++I)
-    Switch->removeCase(Switch->case_begin());
-  for (auto &Case : Cases)
-    Switch->addCase(Case.Val, Case.Dest);
-}
-
-#ifndef NDEBUG
-void SwitchRemoveCase::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-void SwitchAddCase::revert(Tracker &Tracker) {
-  auto It = Switch->findCaseValue(Val);
-  Switch->removeCase(It);
-}
-
-#ifndef NDEBUG
-void SwitchAddCase::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-MoveInstr::MoveInstr(Instruction *MovedI) : MovedI(MovedI) {
-  if (auto *NextI = MovedI->getNextNode())
-    NextInstrOrBB = NextI;
-  else
-    NextInstrOrBB = MovedI->getParent();
-}
-
-void MoveInstr::revert(Tracker &Tracker) {
-  if (auto *NextI = dyn_cast<Instruction *>(NextInstrOrBB)) {
-    MovedI->moveBefore(NextI);
-  } else {
-    auto *BB = cast<BasicBlock *>(NextInstrOrBB);
-    MovedI->moveBefore(*BB, BB->end());
-  }
-}
-
-#ifndef NDEBUG
-void MoveInstr::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-void InsertIntoBB::revert(Tracker &Tracker) { InsertedI->removeFromParent(); }
-
-InsertIntoBB::InsertIntoBB(Instruction *InsertedI) : InsertedI(InsertedI) {}
-
-#ifndef NDEBUG
-void InsertIntoBB::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-void CreateAndInsertInst::revert(Tracker &Tracker) { NewI->eraseFromParent(); }
-
-#ifndef NDEBUG
-void CreateAndInsertInst::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-ShuffleVectorSetMask::ShuffleVectorSetMask(ShuffleVectorInst *SVI)
-    : SVI(SVI), PrevMask(SVI->getShuffleMask()) {}
-
-void ShuffleVectorSetMask::revert(Tracker &Tracker) {
-  SVI->setShuffleMask(PrevMask);
-}
-
-#ifndef NDEBUG
-void ShuffleVectorSetMask::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-CmpSwapOperands::CmpSwapOperands(CmpInst *Cmp) : Cmp(Cmp) {}
-
-void CmpSwapOperands::revert(Tracker &Tracker) { Cmp->swapOperands(); }
-#ifndef NDEBUG
-void CmpSwapOperands::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-void Tracker::save() {
-  State = TrackerState::Record;
-#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
-  SnapshotChecker.save();
-#endif
-}
-
-void Tracker::revert() {
-  assert(State == TrackerState::Record && "Forgot to save()!");
-  State = TrackerState::Reverting;
-  for (auto &Change : reverse(Changes))
-    Change->revert(*this);
-  Changes.clear();
-#if !defined(NDEBUG) && defined(EXPENSIVE_CHECKS)
-  SnapshotChecker.expectNoDiff();
-#endif
-  State = TrackerState::Disabled;
-}
-
-void Tracker::accept() {
-  assert(State == TrackerState::Record && "Forgot to save()!");
-  State = TrackerState::Disabled;
-  for (auto &Change : Changes)
-    Change->accept();
-  Changes.clear();
-}
-
-#ifndef NDEBUG
-void Tracker::dump(raw_ostream &OS) const {
-  for (auto [Idx, ChangePtr] : enumerate(Changes)) {
-    OS << Idx << ". ";
-    ChangePtr->dump(OS);
-    OS << "\n";
-  }
-}
-void Tracker::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
diff --git a/llvm/lib/SandboxIR/Type.cpp b/llvm/lib/SandboxIR/Type.cpp
deleted file mode 100644
index dfb54df0c9ce8..0000000000000
--- a/llvm/lib/SandboxIR/Type.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-//===- Type.cpp - Sandbox IR Type -----------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Type.h"
-#include "llvm/SandboxIR/Context.h"
-
-using namespace llvm::sandboxir;
-
-Type *Type::getScalarType() const {
-  return Ctx.getType(LLVMTy->getScalarType());
-}
-
-Type *Type::getInt64Ty(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getInt64Ty(Ctx.LLVMCtx));
-}
-Type *Type::getInt32Ty(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getInt32Ty(Ctx.LLVMCtx));
-}
-Type *Type::getInt16Ty(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getInt16Ty(Ctx.LLVMCtx));
-}
-Type *Type::getInt8Ty(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getInt8Ty(Ctx.LLVMCtx));
-}
-Type *Type::getInt1Ty(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getInt1Ty(Ctx.LLVMCtx));
-}
-Type *Type::getDoubleTy(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getDoubleTy(Ctx.LLVMCtx));
-}
-Type *Type::getFloatTy(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getFloatTy(Ctx.LLVMCtx));
-}
-Type *Type::getHalfTy(Context &Ctx) {
-  return Ctx.getType(llvm::Type::getHalfTy(Ctx.LLVMCtx));
-}
-
-#ifndef NDEBUG
-void Type::dumpOS(raw_ostream &OS) { LLVMTy->print(OS); }
-void Type::dump() {
-  dumpOS(dbgs());
-  dbgs() << "\n";
-}
-#endif
-
-PointerType *PointerType::get(Context &Ctx, unsigned AddressSpace) {
-  return cast<PointerType>(
-      Ctx.getType(llvm::PointerType::get(Ctx.LLVMCtx, AddressSpace)));
-}
-
-ArrayType *ArrayType::get(Type *ElementType, uint64_t NumElements) {
-  return cast<ArrayType>(ElementType->getContext().getType(
-      llvm::ArrayType::get(ElementType->LLVMTy, NumElements)));
-}
-
-StructType *StructType::get(Context &Ctx, ArrayRef<Type *> Elements,
-                            bool IsPacked) {
-  SmallVector<llvm::Type *> LLVMElements;
-  LLVMElements.reserve(Elements.size());
-  for (Type *Elm : Elements)
-    LLVMElements.push_back(Elm->LLVMTy);
-  return cast<StructType>(
-      Ctx.getType(llvm::StructType::get(Ctx.LLVMCtx, LLVMElements, IsPacked)));
-}
-
-VectorType *VectorType::get(Type *ElementType, ElementCount EC) {
-  return cast<VectorType>(ElementType->getContext().getType(
-      llvm::VectorType::get(ElementType->LLVMTy, EC)));
-}
-
-Type *VectorType::getElementType() const {
-  return Ctx.getType(cast<llvm::VectorType>(LLVMTy)->getElementType());
-}
-VectorType *VectorType::getInteger(VectorType *VTy) {
-  return cast<VectorType>(VTy->getContext().getType(
-      llvm::VectorType::getInteger(cast<llvm::VectorType>(VTy->LLVMTy))));
-}
-VectorType *VectorType::getExtendedElementVectorType(VectorType *VTy) {
-  return cast<VectorType>(
-      VTy->getContext().getType(llvm::VectorType::getExtendedElementVectorType(
-          cast<llvm::VectorType>(VTy->LLVMTy))));
-}
-VectorType *VectorType::getTruncatedElementVectorType(VectorType *VTy) {
-  return cast<VectorType>(
-      VTy->getContext().getType(llvm::VectorType::getTruncatedElementVectorType(
-          cast<llvm::VectorType>(VTy->LLVMTy))));
-}
-VectorType *VectorType::getSubdividedVectorType(VectorType *VTy,
-                                                int NumSubdivs) {
-  return cast<VectorType>(
-      VTy->getContext().getType(llvm::VectorType::getSubdividedVectorType(
-          cast<llvm::VectorType>(VTy->LLVMTy), NumSubdivs)));
-}
-VectorType *VectorType::getHalfElementsVectorType(VectorType *VTy) {
-  return cast<VectorType>(
-      VTy->getContext().getType(llvm::VectorType::getHalfElementsVectorType(
-          cast<llvm::VectorType>(VTy->LLVMTy))));
-}
-VectorType *VectorType::getDoubleElementsVectorType(VectorType *VTy) {
-  return cast<VectorType>(
-      VTy->getContext().getType(llvm::VectorType::getDoubleElementsVectorType(
-          cast<llvm::VectorType>(VTy->LLVMTy))));
-}
-bool VectorType::isValidElementType(Type *ElemTy) {
-  return llvm::VectorType::isValidElementType(ElemTy->LLVMTy);
-}
-
-FixedVectorType *FixedVectorType::get(Type *ElementType, unsigned NumElts) {
-  return cast<FixedVectorType>(ElementType->getContext().getType(
-      llvm::FixedVectorType::get(ElementType->LLVMTy, NumElts)));
-}
-
-ScalableVectorType *ScalableVectorType::get(Type *ElementType,
-                                            unsigned NumElts) {
-  return cast<ScalableVectorType>(ElementType->getContext().getType(
-      llvm::ScalableVectorType::get(ElementType->LLVMTy, NumElts)));
-}
-
-IntegerType *IntegerType::get(Context &Ctx, unsigned NumBits) {
-  return cast<IntegerType>(
-      Ctx.getType(llvm::IntegerType::get(Ctx.LLVMCtx, NumBits)));
-}
diff --git a/llvm/lib/SandboxIR/Use.cpp b/llvm/lib/SandboxIR/Use.cpp
deleted file mode 100644
index ffbd41da51849..0000000000000
--- a/llvm/lib/SandboxIR/Use.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-//===- Use.cpp ------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Use.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/User.h"
-
-namespace llvm::sandboxir {
-
-Value *Use::get() const { return Ctx->getValue(LLVMUse->get()); }
-
-void Use::set(Value *V) {
-  Ctx->getTracker().emplaceIfTracking<UseSet>(*this);
-  LLVMUse->set(V->Val);
-}
-
-unsigned Use::getOperandNo() const { return Usr->getUseOperandNo(*this); }
-
-void Use::swap(Use &OtherUse) {
-  Ctx->getTracker().emplaceIfTracking<UseSwap>(*this, OtherUse);
-  LLVMUse->swap(*OtherUse.LLVMUse);
-}
-
-#ifndef NDEBUG
-void Use::dumpOS(raw_ostream &OS) const {
-  Value *Def = nullptr;
-  if (LLVMUse == nullptr)
-    OS << "<null> LLVM Use! ";
-  else
-    Def = Ctx->getValue(LLVMUse->get());
-  OS << "Def:  ";
-  if (Def == nullptr)
-    OS << "NULL";
-  else
-    OS << *Def;
-  OS << "\n";
-
-  OS << "User: ";
-  if (Usr == nullptr)
-    OS << "NULL";
-  else
-    OS << *Usr;
-  OS << "\n";
-
-  OS << "OperandNo: ";
-  if (Usr == nullptr)
-    OS << "N/A";
-  else
-    OS << getOperandNo();
-  OS << "\n";
-}
-
-void Use::dump() const { dumpOS(dbgs()); }
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/User.cpp b/llvm/lib/SandboxIR/User.cpp
deleted file mode 100644
index 43fd565e23836..0000000000000
--- a/llvm/lib/SandboxIR/User.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-//===- User.cpp - The User class of Sandbox IR ----------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/User.h"
-#include "llvm/SandboxIR/Context.h"
-
-namespace llvm::sandboxir {
-
-Use OperandUseIterator::operator*() const { return Use; }
-
-OperandUseIterator &OperandUseIterator::operator++() {
-  assert(Use.LLVMUse != nullptr && "Already at end!");
-  User *User = Use.getUser();
-  Use = User->getOperandUseInternal(Use.getOperandNo() + 1, /*Verify=*/false);
-  return *this;
-}
-
-UserUseIterator &UserUseIterator::operator++() {
-  // Get the corresponding llvm::Use, get the next in the list, and update the
-  // sandboxir::Use.
-  llvm::Use *&LLVMUse = Use.LLVMUse;
-  assert(LLVMUse != nullptr && "Already at end!");
-  LLVMUse = LLVMUse->getNext();
-  if (LLVMUse == nullptr) {
-    Use.Usr = nullptr;
-    return *this;
-  }
-  auto *Ctx = Use.Ctx;
-  auto *LLVMUser = LLVMUse->getUser();
-  Use.Usr = cast_or_null<sandboxir::User>(Ctx->getValue(LLVMUser));
-  return *this;
-}
-
-OperandUseIterator OperandUseIterator::operator+(unsigned Num) const {
-  sandboxir::Use U = Use.getUser()->getOperandUseInternal(
-      Use.getOperandNo() + Num, /*Verify=*/true);
-  return OperandUseIterator(U);
-}
-
-OperandUseIterator OperandUseIterator::operator-(unsigned Num) const {
-  assert(Use.getOperandNo() >= Num && "Out of bounds!");
-  sandboxir::Use U = Use.getUser()->getOperandUseInternal(
-      Use.getOperandNo() - Num, /*Verify=*/true);
-  return OperandUseIterator(U);
-}
-
-int OperandUseIterator::operator-(const OperandUseIterator &Other) const {
-  int ThisOpNo = Use.getOperandNo();
-  int OtherOpNo = Other.Use.getOperandNo();
-  return ThisOpNo - OtherOpNo;
-}
-
-Use User::getOperandUseDefault(unsigned OpIdx, bool Verify) const {
-  assert((!Verify || OpIdx < getNumOperands()) && "Out of bounds!");
-  assert(isa<llvm::User>(Val) && "Non-users have no operands!");
-  llvm::Use *LLVMUse;
-  if (OpIdx != getNumOperands())
-    LLVMUse = &cast<llvm::User>(Val)->getOperandUse(OpIdx);
-  else
-    LLVMUse = cast<llvm::User>(Val)->op_end();
-  return Use(LLVMUse, const_cast<User *>(this), Ctx);
-}
-
-#ifndef NDEBUG
-void User::verifyUserOfLLVMUse(const llvm::Use &Use) const {
-  assert(Ctx.getValue(Use.getUser()) == this &&
-         "Use not found in this SBUser's operands!");
-}
-#endif
-
-bool User::classof(const Value *From) {
-  switch (From->getSubclassID()) {
-#define DEF_VALUE(ID, CLASS)
-#define DEF_USER(ID, CLASS)                                                    \
-  case ClassID::ID:                                                            \
-    return true;
-#define DEF_INSTR(ID, OPC, CLASS)                                              \
-  case ClassID::ID:                                                            \
-    return true;
-#include "llvm/SandboxIR/Values.def"
-  default:
-    return false;
-  }
-}
-
-void User::setOperand(unsigned OperandIdx, Value *Operand) {
-  assert(isa<llvm::User>(Val) && "No operands!");
-  const auto &U = getOperandUse(OperandIdx);
-  Ctx.getTracker().emplaceIfTracking<UseSet>(U);
-  Ctx.runSetUseCallbacks(U, Operand);
-  // We are delegating to llvm::User::setOperand().
-  cast<llvm::User>(Val)->setOperand(OperandIdx, Operand->Val);
-}
-
-bool User::replaceUsesOfWith(Value *FromV, Value *ToV) {
-  auto &Tracker = Ctx.getTracker();
-  for (auto OpIdx : seq<unsigned>(0, getNumOperands())) {
-    auto Use = getOperandUse(OpIdx);
-    if (Use.get() == FromV) {
-      Ctx.runSetUseCallbacks(Use, ToV);
-      if (Tracker.isTracking())
-        Tracker.emplaceIfTracking<UseSet>(Use);
-    }
-  }
-  // We are delegating RUOW to LLVM IR's RUOW.
-  return cast<llvm::User>(Val)->replaceUsesOfWith(FromV->Val, ToV->Val);
-}
-
-#ifndef NDEBUG
-void User::dumpCommonHeader(raw_ostream &OS) const {
-  Value::dumpCommonHeader(OS);
-  // TODO: This is incomplete
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/SandboxIR/Value.cpp b/llvm/lib/SandboxIR/Value.cpp
deleted file mode 100644
index 94b4a4c9a406f..0000000000000
--- a/llvm/lib/SandboxIR/Value.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-//===- Value.cpp - The Value class of Sandbox IR --------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/User.h"
-#include <sstream>
-
-namespace llvm::sandboxir {
-
-Value::Value(ClassID SubclassID, llvm::Value *Val, Context &Ctx)
-    : SubclassID(SubclassID), Val(Val), Ctx(Ctx) {
-#ifndef NDEBUG
-  UID = Ctx.getNumValues();
-#endif
-}
-
-Value::use_iterator Value::use_begin() {
-  llvm::Use *LLVMUse = nullptr;
-  if (!Val->uses().empty())
-    LLVMUse = &*Val->use_begin();
-  User *User = LLVMUse != nullptr ? cast_or_null<sandboxir::User>(Ctx.getValue(
-                                        Val->use_begin()->getUser()))
-                                  : nullptr;
-  return use_iterator(Use(LLVMUse, User, Ctx));
-}
-
-Value::user_iterator Value::user_begin() {
-  auto UseBegin = Val->use_begin();
-  auto UseEnd = Val->use_end();
-  bool AtEnd = UseBegin == UseEnd;
-  llvm::Use *LLVMUse = AtEnd ? nullptr : &*UseBegin;
-  User *User =
-      AtEnd ? nullptr
-            : cast_or_null<sandboxir::User>(Ctx.getValue(&*LLVMUse->getUser()));
-  return user_iterator(Use(LLVMUse, User, Ctx), UseToUser());
-}
-
-unsigned Value::getNumUses() const { return range_size(Val->users()); }
-
-Type *Value::getType() const { return Ctx.getType(Val->getType()); }
-
-void Value::replaceUsesWithIf(
-    Value *OtherV, llvm::function_ref<bool(const Use &)> ShouldReplace) {
-  assert(getType() == OtherV->getType() && "Can't replace with different type");
-  llvm::Value *OtherVal = OtherV->Val;
-  // We are delegating RUWIf to LLVM IR's RUWIf.
-  Val->replaceUsesWithIf(
-      OtherVal, [&ShouldReplace, this, OtherV](llvm::Use &LLVMUse) -> bool {
-        User *DstU = cast_or_null<User>(Ctx.getValue(LLVMUse.getUser()));
-        if (DstU == nullptr)
-          return false;
-        Use UseToReplace(&LLVMUse, DstU, Ctx);
-        if (!ShouldReplace(UseToReplace))
-          return false;
-        Ctx.getTracker().emplaceIfTracking<UseSet>(UseToReplace);
-        Ctx.runSetUseCallbacks(UseToReplace, OtherV);
-        return true;
-      });
-}
-
-void Value::replaceAllUsesWith(Value *Other) {
-  assert(getType() == Other->getType() &&
-         "Replacing with Value of different type!");
-  auto &Tracker = Ctx.getTracker();
-  for (auto Use : uses()) {
-    Ctx.runSetUseCallbacks(Use, Other);
-    if (Tracker.isTracking())
-      Tracker.track(std::make_unique<UseSet>(Use));
-  }
-  // We are delegating RAUW to LLVM IR's RAUW.
-  Val->replaceAllUsesWith(Other->Val);
-}
-
-#ifndef NDEBUG
-std::string Value::getUid() const {
-  std::stringstream SS;
-  SS << "SB" << UID << ".";
-  return SS.str();
-}
-
-void Value::dumpCommonHeader(raw_ostream &OS) const {
-  OS << getUid() << " " << getSubclassIDStr(SubclassID) << " ";
-}
-
-void Value::dumpCommonFooter(raw_ostream &OS) const {
-  OS.indent(2) << "Val: ";
-  if (Val)
-    OS << *Val;
-  else
-    OS << "NULL";
-  OS << "\n";
-}
-
-void Value::dumpCommonPrefix(raw_ostream &OS) const {
-  if (Val)
-    OS << *Val;
-  else
-    OS << "NULL ";
-}
-
-void Value::dumpCommonSuffix(raw_ostream &OS) const {
-  OS << " ; " << getUid() << " (" << getSubclassIDStr(SubclassID) << ")";
-}
-
-void Value::printAsOperandCommon(raw_ostream &OS) const {
-  if (Val)
-    Val->printAsOperand(OS);
-  else
-    OS << "NULL ";
-}
-
-void Value::dump() const {
-  dumpOS(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/CMakeLists.txt b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
index 9f4a242214471..f4c88f1098058 100644
--- a/llvm/lib/Transforms/Vectorize/CMakeLists.txt
+++ b/llvm/lib/Transforms/Vectorize/CMakeLists.txt
@@ -3,22 +3,6 @@ add_llvm_component_library(LLVMVectorize
   LoopIdiomVectorize.cpp
   LoopVectorizationLegality.cpp
   LoopVectorize.cpp
-  SandboxVectorizer/DependencyGraph.cpp
-  SandboxVectorizer/InstrMaps.cpp
-  SandboxVectorizer/Interval.cpp
-  SandboxVectorizer/Legality.cpp
-  SandboxVectorizer/Passes/BottomUpVec.cpp
-  SandboxVectorizer/Passes/PackReuse.cpp
-  SandboxVectorizer/Passes/RegionsFromBBs.cpp
-  SandboxVectorizer/Passes/RegionsFromMetadata.cpp
-  SandboxVectorizer/Passes/SeedCollection.cpp
-  SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
-  SandboxVectorizer/Passes/TransactionSave.cpp
-  SandboxVectorizer/SandboxVectorizer.cpp
-  SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
-  SandboxVectorizer/Scheduler.cpp
-  SandboxVectorizer/SeedCollector.cpp
-  SandboxVectorizer/VecUtils.cpp
   SLPVectorizer.cpp
   Vectorize.cpp
   VectorCombine.cpp
@@ -36,7 +20,6 @@ add_llvm_component_library(LLVMVectorize
   ADDITIONAL_HEADER_DIRS
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms
   ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/Vectorize
-  ${LLVM_MAIN_INCLUDE_DIR}/llvm/Transforms/Vectorize/SandboxVectorizer
 
   DEPENDS
   intrinsics_gen
@@ -46,5 +29,4 @@ add_llvm_component_library(LLVMVectorize
   Core
   Support
   TransformUtils
-  SandboxIR
   )
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
deleted file mode 100644
index d354933f9d4ec..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.cpp
+++ /dev/null
@@ -1,665 +0,0 @@
-//===- DependencyGraph.cpp ------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h"
-
-namespace llvm::sandboxir {
-
-User::op_iterator PredIterator::skipBadIt(User::op_iterator OpIt,
-                                          User::op_iterator OpItE,
-                                          const DependencyGraph &DAG) {
-  auto Skip = [&DAG](auto OpIt) {
-    auto *I = dyn_cast<Instruction>((*OpIt).get());
-    return I == nullptr || DAG.getNode(I) == nullptr;
-  };
-  while (OpIt != OpItE && Skip(OpIt))
-    ++OpIt;
-  return OpIt;
-}
-
-PredIterator::value_type PredIterator::operator*() {
-  // If it's a DGNode then we dereference the operand iterator.
-  if (!isa<MemDGNode>(N)) {
-    assert(OpIt != OpItE && "Can't dereference end iterator!");
-    return DAG->getNode(cast<Instruction>((Value *)*OpIt));
-  }
-  // It's a MemDGNode, so we check if we return either the use-def operand,
-  // or a mem predecessor.
-  if (OpIt != OpItE)
-    return DAG->getNode(cast<Instruction>((Value *)*OpIt));
-  // It's a MemDGNode with OpIt == end, so we need to use MemIt.
-  assert(MemIt != cast<MemDGNode>(N)->MemPreds.end() &&
-         "Cant' dereference end iterator!");
-  return *MemIt;
-}
-
-PredIterator &PredIterator::operator++() {
-  // If it's a DGNode then we increment the use-def iterator.
-  if (!isa<MemDGNode>(N)) {
-    assert(OpIt != OpItE && "Already at end!");
-    ++OpIt;
-    // Skip operands that are not instructions or are outside the DAG.
-    OpIt = PredIterator::skipBadIt(OpIt, OpItE, *DAG);
-    return *this;
-  }
-  // It's a MemDGNode, so if we are not at the end of the use-def iterator we
-  // need to first increment that.
-  if (OpIt != OpItE) {
-    ++OpIt;
-    // Skip operands that are not instructions or are outside the DAG.
-    OpIt = PredIterator::skipBadIt(OpIt, OpItE, *DAG);
-    return *this;
-  }
-  // It's a MemDGNode with OpIt == end, so we need to increment MemIt.
-  assert(MemIt != cast<MemDGNode>(N)->MemPreds.end() && "Already at end!");
-  ++MemIt;
-  return *this;
-}
-
-bool PredIterator::operator==(const PredIterator &Other) const {
-  assert(DAG == Other.DAG && "Iterators of different DAGs!");
-  assert(N == Other.N && "Iterators of different nodes!");
-  return OpIt == Other.OpIt && MemIt == Other.MemIt;
-}
-
-void DGNode::setSchedBundle(SchedBundle &SB) {
-  if (this->SB != nullptr)
-    this->SB->eraseFromBundle(this);
-  this->SB = &SB;
-}
-
-DGNode::~DGNode() {
-  if (SB == nullptr)
-    return;
-  SB->eraseFromBundle(this);
-}
-
-#ifndef NDEBUG
-void DGNode::print(raw_ostream &OS, bool PrintDeps) const {
-  OS << *I << " USuccs:" << UnscheduledSuccs << " Sched:" << Scheduled << "\n";
-}
-void DGNode::dump() const { print(dbgs()); }
-void MemDGNode::print(raw_ostream &OS, bool PrintDeps) const {
-  DGNode::print(OS, false);
-  if (PrintDeps) {
-    // Print memory preds.
-    static constexpr unsigned Indent = 4;
-    for (auto *Pred : MemPreds)
-      OS.indent(Indent) << "<-" << *Pred->getInstruction() << "\n";
-  }
-}
-#endif // NDEBUG
-
-MemDGNode *
-MemDGNodeIntervalBuilder::getTopMemDGNode(const Interval<Instruction> &Intvl,
-                                          const DependencyGraph &DAG) {
-  Instruction *I = Intvl.top();
-  Instruction *BeforeI = Intvl.bottom();
-  // Walk down the chain looking for a mem-dep candidate instruction.
-  while (!DGNode::isMemDepNodeCandidate(I) && I != BeforeI)
-    I = I->getNextNode();
-  if (!DGNode::isMemDepNodeCandidate(I))
-    return nullptr;
-  return cast<MemDGNode>(DAG.getNode(I));
-}
-
-MemDGNode *
-MemDGNodeIntervalBuilder::getBotMemDGNode(const Interval<Instruction> &Intvl,
-                                          const DependencyGraph &DAG) {
-  Instruction *I = Intvl.bottom();
-  Instruction *AfterI = Intvl.top();
-  // Walk up the chain looking for a mem-dep candidate instruction.
-  while (!DGNode::isMemDepNodeCandidate(I) && I != AfterI)
-    I = I->getPrevNode();
-  if (!DGNode::isMemDepNodeCandidate(I))
-    return nullptr;
-  return cast<MemDGNode>(DAG.getNode(I));
-}
-
-Interval<MemDGNode>
-MemDGNodeIntervalBuilder::make(const Interval<Instruction> &Instrs,
-                               DependencyGraph &DAG) {
-  if (Instrs.empty())
-    return {};
-  auto *TopMemN = getTopMemDGNode(Instrs, DAG);
-  // If we couldn't find a mem node in range TopN - BotN then it's empty.
-  if (TopMemN == nullptr)
-    return {};
-  auto *BotMemN = getBotMemDGNode(Instrs, DAG);
-  assert(BotMemN != nullptr && "TopMemN should be null too!");
-  // Now that we have the mem-dep nodes, create and return the range.
-  return Interval<MemDGNode>(TopMemN, BotMemN);
-}
-
-DependencyGraph::DependencyType
-DependencyGraph::getRoughDepType(Instruction *FromI, Instruction *ToI) {
-  // TODO: Perhaps compile-time improvement by skipping if neither is mem?
-  if (FromI->mayWriteToMemory()) {
-    if (ToI->mayReadFromMemory())
-      return DependencyType::ReadAfterWrite;
-    if (ToI->mayWriteToMemory())
-      return DependencyType::WriteAfterWrite;
-  } else if (FromI->mayReadFromMemory()) {
-    if (ToI->mayWriteToMemory())
-      return DependencyType::WriteAfterRead;
-  }
-  if (isa<sandboxir::PHINode>(FromI) || isa<sandboxir::PHINode>(ToI))
-    return DependencyType::Control;
-  if (ToI->isTerminator())
-    return DependencyType::Control;
-  if (DGNode::isStackSaveOrRestoreIntrinsic(FromI) ||
-      DGNode::isStackSaveOrRestoreIntrinsic(ToI))
-    return DependencyType::Other;
-  return DependencyType::None;
-}
-
-static bool isOrdered(Instruction *I) {
-  auto IsOrdered = [](Instruction *I) {
-    if (auto *LI = dyn_cast<LoadInst>(I))
-      return !LI->isUnordered();
-    if (auto *SI = dyn_cast<StoreInst>(I))
-      return !SI->isUnordered();
-    if (DGNode::isFenceLike(I))
-      return true;
-    return false;
-  };
-  bool Is = IsOrdered(I);
-  assert((!Is || DGNode::isMemDepCandidate(I)) &&
-         "An ordered instruction must be a MemDepCandidate!");
-  return Is;
-}
-
-bool DependencyGraph::alias(Instruction *SrcI, Instruction *DstI,
-                            DependencyType DepType) {
-  std::optional<MemoryLocation> DstLocOpt =
-      Utils::memoryLocationGetOrNone(DstI);
-  if (!DstLocOpt)
-    return true;
-  // Check aliasing.
-  assert((SrcI->mayReadFromMemory() || SrcI->mayWriteToMemory()) &&
-         "Expected a mem instr");
-  // TODO: Check AABudget
-  ModRefInfo SrcModRef =
-      isOrdered(SrcI)
-          ? ModRefInfo::ModRef
-          : Utils::aliasAnalysisGetModRefInfo(*BatchAA, SrcI, *DstLocOpt);
-  switch (DepType) {
-  case DependencyType::ReadAfterWrite:
-  case DependencyType::WriteAfterWrite:
-    return isModSet(SrcModRef);
-  case DependencyType::WriteAfterRead:
-    return isRefSet(SrcModRef);
-  default:
-    llvm_unreachable("Expected only RAW, WAW and WAR!");
-  }
-}
-
-bool DependencyGraph::hasDep(Instruction *SrcI, Instruction *DstI) {
-  DependencyType RoughDepType = getRoughDepType(SrcI, DstI);
-  switch (RoughDepType) {
-  case DependencyType::ReadAfterWrite:
-  case DependencyType::WriteAfterWrite:
-  case DependencyType::WriteAfterRead:
-    return alias(SrcI, DstI, RoughDepType);
-  case DependencyType::Control:
-    // Adding actual dep edges from PHIs/to terminator would just create too
-    // many edges, which would be bad for compile-time.
-    // So we ignore them in the DAG formation but handle them in the
-    // scheduler, while sorting the ready list.
-    return false;
-  case DependencyType::Other:
-    return true;
-  case DependencyType::None:
-    return false;
-  }
-  llvm_unreachable("Unknown DependencyType enum");
-}
-
-void DependencyGraph::scanAndAddDeps(MemDGNode &DstN,
-                                     const Interval<MemDGNode> &SrcScanRange) {
-  assert(isa<MemDGNode>(DstN) &&
-         "DstN is the mem dep destination, so it must be mem");
-  Instruction *DstI = DstN.getInstruction();
-  // Walk up the instruction chain from ScanRange bottom to top, looking for
-  // memory instrs that may alias.
-  for (MemDGNode &SrcN : reverse(SrcScanRange)) {
-    Instruction *SrcI = SrcN.getInstruction();
-    if (hasDep(SrcI, DstI))
-      DstN.addMemPred(&SrcN);
-  }
-}
-
-void DependencyGraph::setDefUseUnscheduledSuccs(
-    const Interval<Instruction> &NewInterval) {
-  // +---+
-  // |   |  Def
-  // |   |   |
-  // |   |   v
-  // |   |  Use
-  // +---+
-  // Set the intra-interval counters in NewInterval.
-  for (Instruction &I : NewInterval) {
-    for (Value *Op : I.operands()) {
-      auto *OpI = dyn_cast<Instruction>(Op);
-      if (OpI == nullptr)
-        continue;
-      // TODO: For now don't cross BBs.
-      if (OpI->getParent() != I.getParent())
-        continue;
-      if (!NewInterval.contains(OpI))
-        continue;
-      auto *OpN = getNode(OpI);
-      if (OpN == nullptr)
-        continue;
-      ++OpN->UnscheduledSuccs;
-    }
-  }
-
-  // Now handle the cross-interval edges.
-  bool NewIsAbove = DAGInterval.empty() || NewInterval.comesBefore(DAGInterval);
-  const auto &TopInterval = NewIsAbove ? NewInterval : DAGInterval;
-  const auto &BotInterval = NewIsAbove ? DAGInterval : NewInterval;
-  // +---+
-  // |Top|
-  // |   |  Def
-  // +---+   |
-  // |   |   v
-  // |Bot|  Use
-  // |   |
-  // +---+
-  // Walk over all instructions in "BotInterval" and update the counter
-  // of operands that are in "TopInterval".
-  for (Instruction &BotI : BotInterval) {
-    auto *BotN = getNode(&BotI);
-    // Skip scheduled nodes.
-    if (BotN->scheduled())
-      continue;
-    for (Value *Op : BotI.operands()) {
-      auto *OpI = dyn_cast<Instruction>(Op);
-      if (OpI == nullptr)
-        continue;
-      auto *OpN = getNode(OpI);
-      if (OpN == nullptr)
-        continue;
-      if (!TopInterval.contains(OpI))
-        continue;
-      ++OpN->UnscheduledSuccs;
-    }
-  }
-}
-
-void DependencyGraph::createNewNodes(const Interval<Instruction> &NewInterval) {
-  // Create Nodes only for the new sections of the DAG.
-  DGNode *LastN = getOrCreateNode(NewInterval.top());
-  MemDGNode *LastMemN = dyn_cast<MemDGNode>(LastN);
-  for (Instruction &I : drop_begin(NewInterval)) {
-    auto *N = getOrCreateNode(&I);
-    // Build the Mem node chain.
-    if (auto *MemN = dyn_cast<MemDGNode>(N)) {
-      MemN->setPrevNode(LastMemN);
-      LastMemN = MemN;
-    }
-  }
-  // Link new MemDGNode chain with the old one, if any.
-  if (!DAGInterval.empty()) {
-    bool NewIsAbove = NewInterval.comesBefore(DAGInterval);
-    const auto &TopInterval = NewIsAbove ? NewInterval : DAGInterval;
-    const auto &BotInterval = NewIsAbove ? DAGInterval : NewInterval;
-    MemDGNode *LinkTopN =
-        MemDGNodeIntervalBuilder::getBotMemDGNode(TopInterval, *this);
-    MemDGNode *LinkBotN =
-        MemDGNodeIntervalBuilder::getTopMemDGNode(BotInterval, *this);
-    assert((LinkTopN == nullptr || LinkBotN == nullptr ||
-            LinkTopN->comesBefore(LinkBotN)) &&
-           "Wrong order!");
-    if (LinkTopN != nullptr && LinkBotN != nullptr) {
-      LinkTopN->setNextNode(LinkBotN);
-    }
-#ifndef NDEBUG
-    // TODO: Remove this once we've done enough testing.
-    // Check that the chain is well formed.
-    auto UnionIntvl = DAGInterval.getUnionInterval(NewInterval);
-    MemDGNode *ChainTopN =
-        MemDGNodeIntervalBuilder::getTopMemDGNode(UnionIntvl, *this);
-    MemDGNode *ChainBotN =
-        MemDGNodeIntervalBuilder::getBotMemDGNode(UnionIntvl, *this);
-    if (ChainTopN != nullptr && ChainBotN != nullptr) {
-      for (auto *N = ChainTopN->getNextNode(), *LastN = ChainTopN; N != nullptr;
-           LastN = N, N = N->getNextNode()) {
-        assert(N == LastN->getNextNode() && "Bad chain!");
-        assert(N->getPrevNode() == LastN && "Bad chain!");
-      }
-    }
-#endif // NDEBUG
-  }
-
-  setDefUseUnscheduledSuccs(NewInterval);
-}
-
-MemDGNode *DependencyGraph::getMemDGNodeBefore(DGNode *N, bool IncludingN,
-                                               MemDGNode *SkipN) const {
-  auto *I = N->getInstruction();
-  for (auto *PrevI = IncludingN ? I : I->getPrevNode(); PrevI != nullptr;
-       PrevI = PrevI->getPrevNode()) {
-    auto *PrevN = getNodeOrNull(PrevI);
-    if (PrevN == nullptr)
-      return nullptr;
-    auto *PrevMemN = dyn_cast<MemDGNode>(PrevN);
-    if (PrevMemN != nullptr && PrevMemN != SkipN)
-      return PrevMemN;
-  }
-  return nullptr;
-}
-
-MemDGNode *DependencyGraph::getMemDGNodeAfter(DGNode *N, bool IncludingN,
-                                              MemDGNode *SkipN) const {
-  auto *I = N->getInstruction();
-  for (auto *NextI = IncludingN ? I : I->getNextNode(); NextI != nullptr;
-       NextI = NextI->getNextNode()) {
-    auto *NextN = getNodeOrNull(NextI);
-    if (NextN == nullptr)
-      return nullptr;
-    auto *NextMemN = dyn_cast<MemDGNode>(NextN);
-    if (NextMemN != nullptr && NextMemN != SkipN)
-      return NextMemN;
-  }
-  return nullptr;
-}
-
-void DependencyGraph::notifyCreateInstr(Instruction *I) {
-  if (Ctx->getTracker().getState() == Tracker::TrackerState::Reverting)
-    // We don't maintain the DAG while reverting.
-    return;
-  // Nothing to do if the node is not in the focus range of the DAG.
-  if (!(DAGInterval.contains(I) || DAGInterval.touches(I)))
-    return;
-  // Include `I` into the interval.
-  DAGInterval = DAGInterval.getUnionInterval({I, I});
-  auto *N = getOrCreateNode(I);
-  auto *MemN = dyn_cast<MemDGNode>(N);
-
-  // Update the MemDGNode chain if this is a memory node.
-  if (MemN != nullptr) {
-    if (auto *PrevMemN = getMemDGNodeBefore(MemN, /*IncludingN=*/false)) {
-      PrevMemN->NextMemN = MemN;
-      MemN->PrevMemN = PrevMemN;
-    }
-    if (auto *NextMemN = getMemDGNodeAfter(MemN, /*IncludingN=*/false)) {
-      NextMemN->PrevMemN = MemN;
-      MemN->NextMemN = NextMemN;
-    }
-
-    // Add Mem dependencies.
-    // 1. Scan for deps above `I` for deps to `I`: AboveN->MemN.
-    if (DAGInterval.top()->comesBefore(I)) {
-      Interval<Instruction> AboveIntvl(DAGInterval.top(), I->getPrevNode());
-      auto SrcInterval = MemDGNodeIntervalBuilder::make(AboveIntvl, *this);
-      scanAndAddDeps(*MemN, SrcInterval);
-    }
-    // 2. Scan for deps below `I` for deps from `I`: MemN->BelowN.
-    if (I->comesBefore(DAGInterval.bottom())) {
-      Interval<Instruction> BelowIntvl(I->getNextNode(), DAGInterval.bottom());
-      for (MemDGNode &BelowN :
-           MemDGNodeIntervalBuilder::make(BelowIntvl, *this))
-        scanAndAddDeps(BelowN, Interval<MemDGNode>(MemN, MemN));
-    }
-  }
-}
-
-void DependencyGraph::notifyMoveInstr(Instruction *I, const BBIterator &To) {
-  if (Ctx->getTracker().getState() == Tracker::TrackerState::Reverting)
-    // We don't maintain the DAG while reverting.
-    return;
-  // NOTE: This function runs before `I` moves to its new destination.
-  BasicBlock *BB = To.getNodeParent();
-  assert(!(To != BB->end() && &*To == I->getNextNode()) &&
-         !(To == BB->end() && std::next(I->getIterator()) == BB->end()) &&
-         "Should not have been called if destination is same as origin.");
-
-  // TODO: We can only handle fully internal movements within DAGInterval or at
-  // the borders, i.e., right before the top or right after the bottom.
-  assert(To.getNodeParent() == I->getParent() &&
-         "TODO: We don't support movement across BBs!");
-  assert(
-      (To == std::next(DAGInterval.bottom()->getIterator()) ||
-       (To != BB->end() && std::next(To) == DAGInterval.top()->getIterator()) ||
-       (To != BB->end() && DAGInterval.contains(&*To))) &&
-      "TODO: To should be either within the DAGInterval or right "
-      "before/after it.");
-
-  // Make a copy of the DAGInterval before we update it.
-  auto OrigDAGInterval = DAGInterval;
-
-  // Maintain the DAGInterval.
-  DAGInterval.notifyMoveInstr(I, To);
-
-  // TODO: Perhaps check if this is legal by checking the dependencies?
-
-  // Update the MemDGNode chain to reflect the instr movement if necessary.
-  DGNode *N = getNodeOrNull(I);
-  if (N == nullptr)
-    return;
-  MemDGNode *MemN = dyn_cast<MemDGNode>(N);
-  if (MemN == nullptr)
-    return;
-
-  // First safely detach it from the existing chain.
-  MemN->detachFromChain();
-
-  // Now insert it back into the chain at the new location.
-  //
-  // We won't always have a DGNode to insert before it. If `To` is BB->end() or
-  // if it points to an instr after DAGInterval.bottom() then we will have to
-  // find a node to insert *after*.
-  //
-  // BB:                              BB:
-  //  I1                               I1 ^
-  //  I2                               I2 | DAGInteval [I1 to I3]
-  //  I3                               I3 V
-  //  I4                               I4   <- `To` == right after DAGInterval
-  //    <- `To` == BB->end()
-  //
-  if (To == BB->end() ||
-      To == std::next(OrigDAGInterval.bottom()->getIterator())) {
-    // If we don't have a node to insert before, find a node to insert after and
-    // update the chain.
-    DGNode *InsertAfterN = getNode(&*std::prev(To));
-    MemN->setPrevNode(
-        getMemDGNodeBefore(InsertAfterN, /*IncludingN=*/true, /*SkipN=*/MemN));
-  } else {
-    // We have a node to insert before, so update the chain.
-    DGNode *BeforeToN = getNode(&*To);
-    MemN->setPrevNode(
-        getMemDGNodeBefore(BeforeToN, /*IncludingN=*/false, /*SkipN=*/MemN));
-    MemN->setNextNode(
-        getMemDGNodeAfter(BeforeToN, /*IncludingN=*/true, /*SkipN=*/MemN));
-  }
-}
-
-void DependencyGraph::notifyEraseInstr(Instruction *I) {
-  if (Ctx->getTracker().getState() == Tracker::TrackerState::Reverting)
-    // We don't maintain the DAG while reverting.
-    return;
-  auto *N = getNode(I);
-  if (N == nullptr)
-    // Early return if there is no DAG node for `I`.
-    return;
-  if (auto *MemN = dyn_cast<MemDGNode>(getNode(I))) {
-    // Update the MemDGNode chain if this is a memory node.
-    auto *PrevMemN = getMemDGNodeBefore(MemN, /*IncludingN=*/false);
-    auto *NextMemN = getMemDGNodeAfter(MemN, /*IncludingN=*/false);
-    if (PrevMemN != nullptr)
-      PrevMemN->NextMemN = NextMemN;
-    if (NextMemN != nullptr)
-      NextMemN->PrevMemN = PrevMemN;
-
-    // Drop the memory dependencies from both predecessors and successors.
-    while (!MemN->memPreds().empty()) {
-      auto *PredN = *MemN->memPreds().begin();
-      MemN->removeMemPred(PredN);
-    }
-    while (!MemN->memSuccs().empty()) {
-      auto *SuccN = *MemN->memSuccs().begin();
-      SuccN->removeMemPred(MemN);
-    }
-    // NOTE: The unscheduled succs for MemNodes get updated be setMemPred().
-  } else {
-    // If this is a non-mem node we only need to update UnscheduledSuccs.
-    if (!N->scheduled())
-      for (auto *PredN : N->preds(*this))
-        PredN->decrUnscheduledSuccs();
-  }
-  // Finally erase the Node.
-  InstrToNodeMap.erase(I);
-}
-
-void DependencyGraph::notifySetUse(const Use &U, Value *NewSrc) {
-  // Update the UnscheduledSuccs counter for both the current source and NewSrc
-  // if needed.
-  if (auto *CurrSrcI = dyn_cast<Instruction>(U.get())) {
-    if (auto *CurrSrcN = getNode(CurrSrcI)) {
-      CurrSrcN->decrUnscheduledSuccs();
-    }
-  }
-  if (auto *NewSrcI = dyn_cast<Instruction>(NewSrc)) {
-    if (auto *NewSrcN = getNode(NewSrcI)) {
-      ++NewSrcN->UnscheduledSuccs;
-    }
-  }
-}
-
-Interval<Instruction> DependencyGraph::extend(ArrayRef<Instruction *> Instrs) {
-  if (Instrs.empty())
-    return {};
-
-  Interval<Instruction> InstrsInterval(Instrs);
-  Interval<Instruction> Union = DAGInterval.getUnionInterval(InstrsInterval);
-  auto NewInterval = Union.getSingleDiff(DAGInterval);
-  if (NewInterval.empty())
-    return {};
-
-  createNewNodes(NewInterval);
-
-  // Create the dependencies.
-  //
-  // 1. This is a new DAG, DAGInterval is empty. Fully scan the whole interval.
-  // +---+       -             -
-  // |   | SrcN  |             |
-  // |   |  |    | SrcRange    |
-  // |New|  v    |             | DstRange
-  // |   | DstN  -             |
-  // |   |                     |
-  // +---+                     -
-  // We are scanning for deps with destination in NewInterval and sources in
-  // NewInterval until DstN, for each DstN.
-  auto FullScan = [this](const Interval<Instruction> Intvl) {
-    auto DstRange = MemDGNodeIntervalBuilder::make(Intvl, *this);
-    if (!DstRange.empty()) {
-      for (MemDGNode &DstN : drop_begin(DstRange)) {
-        auto SrcRange = Interval<MemDGNode>(DstRange.top(), DstN.getPrevNode());
-        scanAndAddDeps(DstN, SrcRange);
-      }
-    }
-  };
-  auto MemDAGInterval = MemDGNodeIntervalBuilder::make(DAGInterval, *this);
-  if (MemDAGInterval.empty()) {
-    FullScan(NewInterval);
-  }
-  // 2. The new section is below the old section.
-  // +---+       -
-  // |   |       |
-  // |Old| SrcN  |
-  // |   |  |    |
-  // +---+  |    | SrcRange
-  // +---+  |    |             -
-  // |   |  |    |             |
-  // |New|  v    |             | DstRange
-  // |   | DstN  -             |
-  // |   |                     |
-  // +---+                     -
-  // We are scanning for deps with destination in NewInterval because the deps
-  // in DAGInterval have already been computed. We consider sources in the whole
-  // range including both NewInterval and DAGInterval until DstN, for each DstN.
-  else if (DAGInterval.bottom()->comesBefore(NewInterval.top())) {
-    auto DstRange = MemDGNodeIntervalBuilder::make(NewInterval, *this);
-    auto SrcRangeFull = MemDAGInterval.getUnionInterval(DstRange);
-    for (MemDGNode &DstN : DstRange) {
-      auto SrcRange =
-          Interval<MemDGNode>(SrcRangeFull.top(), DstN.getPrevNode());
-      scanAndAddDeps(DstN, SrcRange);
-    }
-  }
-  // 3. The new section is above the old section.
-  else if (NewInterval.bottom()->comesBefore(DAGInterval.top())) {
-    // +---+       -             -
-    // |   | SrcN  |             |
-    // |New|  |    | SrcRange    | DstRange
-    // |   |  v    |             |
-    // |   | DstN  -             |
-    // |   |                     |
-    // +---+                     -
-    // +---+
-    // |Old|
-    // |   |
-    // +---+
-    // When scanning for deps with destination in NewInterval we need to fully
-    // scan the interval. This is the same as the scanning for a new DAG.
-    FullScan(NewInterval);
-
-    // +---+       -
-    // |   |       |
-    // |New| SrcN  | SrcRange
-    // |   |  |    |
-    // |   |  |    |
-    // |   |  |    |
-    // +---+  |    -
-    // +---+  |                  -
-    // |Old|  v                  | DstRange
-    // |   | DstN                |
-    // +---+                     -
-    // When scanning for deps with destination in DAGInterval we need to
-    // consider sources from the NewInterval only, because all intra-DAGInterval
-    // dependencies have already been created.
-    auto DstRangeOld = MemDAGInterval;
-    auto SrcRange = MemDGNodeIntervalBuilder::make(NewInterval, *this);
-    for (MemDGNode &DstN : DstRangeOld)
-      scanAndAddDeps(DstN, SrcRange);
-  } else {
-    llvm_unreachable("We don't expect extending in both directions!");
-  }
-
-  DAGInterval = Union;
-  return NewInterval;
-}
-
-#ifndef NDEBUG
-void DependencyGraph::print(raw_ostream &OS) const {
-  // InstrToNodeMap is unordered so we need to create an ordered vector.
-  SmallVector<DGNode *> Nodes;
-  Nodes.reserve(InstrToNodeMap.size());
-  for (const auto &Pair : InstrToNodeMap)
-    Nodes.push_back(Pair.second.get());
-  // Sort them based on which one comes first in the BB.
-  sort(Nodes, [](DGNode *N1, DGNode *N2) {
-    return N1->getInstruction()->comesBefore(N2->getInstruction());
-  });
-  for (auto *N : Nodes)
-    N->print(OS, /*PrintDeps=*/true);
-}
-
-void DependencyGraph::dump() const {
-  print(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/InstrMaps.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/InstrMaps.cpp
deleted file mode 100644
index 37f1ec450f2eb..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/InstrMaps.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-//===- InstructionMaps.cpp - Maps scalars to vectors and reverse ----------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h"
-
-namespace llvm::sandboxir {
-
-#ifndef NDEBUG
-void Action::print(raw_ostream &OS) const {
-  OS << Idx << ". " << *LegalityRes << " Depth:" << Depth << "\n";
-  OS.indent(2) << "Bndl:\n";
-  for (Value *V : Bndl)
-    OS.indent(4) << *V << "\n";
-  OS.indent(2) << "UserBndl:\n";
-  for (Value *V : UserBndl)
-    OS.indent(4) << *V << "\n";
-}
-
-void Action::dump() const { print(dbgs()); }
-
-void InstrMaps::dump() const {
-  print(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Interval.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Interval.cpp
deleted file mode 100644
index e651e92f8b272..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Interval.cpp
+++ /dev/null
@@ -1,49 +0,0 @@
-//===- Interval.cpp -------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h"
-
-namespace llvm::sandboxir {
-
-template <typename T> bool Interval<T>::disjoint(const Interval &Other) const {
-  if (Other.empty())
-    return true;
-  if (empty())
-    return true;
-  return Other.Bottom->comesBefore(Top) || Bottom->comesBefore(Other.Top);
-}
-
-#ifndef NDEBUG
-template <typename T> void Interval<T>::print(raw_ostream &OS) const {
-  auto *Top = top();
-  auto *Bot = bottom();
-  OS << "Top: ";
-  if (Top != nullptr)
-    OS << *Top;
-  else
-    OS << "nullptr";
-  OS << "\n";
-
-  OS << "Bot: ";
-  if (Bot != nullptr)
-    OS << *Bot;
-  else
-    OS << "nullptr";
-  OS << "\n";
-}
-template <typename T> void Interval<T>::dump() const { print(dbgs()); }
-#endif
-
-template class LLVM_EXPORT_TEMPLATE Interval<Instruction>;
-template class LLVM_EXPORT_TEMPLATE Interval<MemDGNode>;
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp
deleted file mode 100644
index e414c120b2a8b..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Legality.cpp
+++ /dev/null
@@ -1,259 +0,0 @@
-//===- Legality.cpp -------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Operator.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-
-namespace llvm::sandboxir {
-
-#ifndef NDEBUG
-void ShuffleMask::dump() const {
-  print(dbgs());
-  dbgs() << "\n";
-}
-
-void LegalityResult::dump() const {
-  print(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-std::optional<ResultReason>
-LegalityAnalysis::notVectorizableBasedOnOpcodesAndTypes(
-    ArrayRef<Value *> Bndl) {
-  auto *I0 = cast<Instruction>(Bndl[0]);
-  auto Opcode = I0->getOpcode();
-  // If they have different opcodes, then we cannot form a vector (for now).
-  if (any_of(drop_begin(Bndl), [Opcode](Value *V) {
-        return cast<Instruction>(V)->getOpcode() != Opcode;
-      }))
-    return ResultReason::DiffOpcodes;
-
-  // If not the same scalar type, Pack. This will accept scalars and vectors as
-  // long as the element type is the same.
-  Type *ElmTy0 = VecUtils::getElementType(Utils::getExpectedType(I0));
-  if (any_of(drop_begin(Bndl), [ElmTy0](Value *V) {
-        return VecUtils::getElementType(Utils::getExpectedType(V)) != ElmTy0;
-      }))
-    return ResultReason::DiffTypes;
-
-  // TODO: Allow vectorization of instrs with different flags as long as we
-  // change them to the least common one.
-  // For now pack if differnt FastMathFlags.
-  if (isa<FPMathOperator>(I0)) {
-    FastMathFlags FMF0 = cast<Instruction>(Bndl[0])->getFastMathFlags();
-    if (any_of(drop_begin(Bndl), [FMF0](auto *V) {
-          return cast<Instruction>(V)->getFastMathFlags() != FMF0;
-        }))
-      return ResultReason::DiffMathFlags;
-  }
-
-  // TODO: Allow vectorization by using common flags.
-  // For now Pack if they don't have the same wrap flags.
-  bool CanHaveWrapFlags =
-      isa<OverflowingBinaryOperator>(I0) || isa<TruncInst>(I0);
-  if (CanHaveWrapFlags) {
-    bool NUW0 = I0->hasNoUnsignedWrap();
-    bool NSW0 = I0->hasNoSignedWrap();
-    if (any_of(drop_begin(Bndl), [NUW0, NSW0](auto *V) {
-          return cast<Instruction>(V)->hasNoUnsignedWrap() != NUW0 ||
-                 cast<Instruction>(V)->hasNoSignedWrap() != NSW0;
-        })) {
-      return ResultReason::DiffWrapFlags;
-    }
-  }
-
-  // Now we need to do further checks for specific opcodes.
-  switch (Opcode) {
-  case Instruction::Opcode::ZExt:
-  case Instruction::Opcode::SExt:
-  case Instruction::Opcode::FPToUI:
-  case Instruction::Opcode::FPToSI:
-  case Instruction::Opcode::FPExt:
-  case Instruction::Opcode::PtrToAddr:
-  case Instruction::Opcode::PtrToInt:
-  case Instruction::Opcode::IntToPtr:
-  case Instruction::Opcode::SIToFP:
-  case Instruction::Opcode::UIToFP:
-  case Instruction::Opcode::Trunc:
-  case Instruction::Opcode::FPTrunc:
-  case Instruction::Opcode::BitCast: {
-    // We have already checked that they are of the same opcode.
-    assert(all_of(Bndl,
-                  [Opcode](Value *V) {
-                    return cast<Instruction>(V)->getOpcode() == Opcode;
-                  }) &&
-           "Different opcodes, should have early returned!");
-    // But for these opcodes we should also check the operand type.
-    Type *FromTy0 = Utils::getExpectedType(I0->getOperand(0));
-    if (any_of(drop_begin(Bndl), [FromTy0](Value *V) {
-          return Utils::getExpectedType(cast<User>(V)->getOperand(0)) !=
-                 FromTy0;
-        }))
-      return ResultReason::DiffTypes;
-    return std::nullopt;
-  }
-  case Instruction::Opcode::FCmp:
-  case Instruction::Opcode::ICmp: {
-    // We need the same predicate..
-    auto Pred0 = cast<CmpInst>(I0)->getPredicate();
-    bool Same = all_of(Bndl, [Pred0](Value *V) {
-      return cast<CmpInst>(V)->getPredicate() == Pred0;
-    });
-    if (Same)
-      return std::nullopt;
-    return ResultReason::DiffOpcodes;
-  }
-  case Instruction::Opcode::Select: {
-    auto *Sel0 = cast<SelectInst>(Bndl[0]);
-    auto *Cond0 = Sel0->getCondition();
-    if (VecUtils::getNumLanes(Cond0) != VecUtils::getNumLanes(Sel0))
-      // TODO: For now we don't vectorize if the lanes in the condition don't
-      // match those of the select instruction.
-      return ResultReason::Unimplemented;
-    return std::nullopt;
-  }
-  case Instruction::Opcode::FNeg:
-  case Instruction::Opcode::Add:
-  case Instruction::Opcode::FAdd:
-  case Instruction::Opcode::Sub:
-  case Instruction::Opcode::FSub:
-  case Instruction::Opcode::Mul:
-  case Instruction::Opcode::FMul:
-  case Instruction::Opcode::FRem:
-  case Instruction::Opcode::UDiv:
-  case Instruction::Opcode::SDiv:
-  case Instruction::Opcode::FDiv:
-  case Instruction::Opcode::URem:
-  case Instruction::Opcode::SRem:
-  case Instruction::Opcode::Shl:
-  case Instruction::Opcode::LShr:
-  case Instruction::Opcode::AShr:
-  case Instruction::Opcode::And:
-  case Instruction::Opcode::Or:
-  case Instruction::Opcode::Xor:
-    return std::nullopt;
-  case Instruction::Opcode::Load:
-    if (VecUtils::areConsecutive<LoadInst>(Bndl, SE, DL))
-      return std::nullopt;
-    return ResultReason::NotConsecutive;
-  case Instruction::Opcode::Store:
-    if (VecUtils::areConsecutive<StoreInst>(Bndl, SE, DL))
-      return std::nullopt;
-    return ResultReason::NotConsecutive;
-  case Instruction::Opcode::PHI:
-    return ResultReason::Unimplemented;
-  case Instruction::Opcode::Opaque:
-    return ResultReason::Unimplemented;
-  case Instruction::Opcode::Br:
-  case Instruction::Opcode::Ret:
-  case Instruction::Opcode::AddrSpaceCast:
-  case Instruction::Opcode::InsertElement:
-  case Instruction::Opcode::InsertValue:
-  case Instruction::Opcode::ExtractElement:
-  case Instruction::Opcode::ExtractValue:
-  case Instruction::Opcode::ShuffleVector:
-  case Instruction::Opcode::Call:
-  case Instruction::Opcode::GetElementPtr:
-  case Instruction::Opcode::Switch:
-    return ResultReason::Unimplemented;
-  case Instruction::Opcode::VAArg:
-  case Instruction::Opcode::Freeze:
-  case Instruction::Opcode::Fence:
-  case Instruction::Opcode::Invoke:
-  case Instruction::Opcode::CallBr:
-  case Instruction::Opcode::LandingPad:
-  case Instruction::Opcode::CatchPad:
-  case Instruction::Opcode::CleanupPad:
-  case Instruction::Opcode::CatchRet:
-  case Instruction::Opcode::CleanupRet:
-  case Instruction::Opcode::Resume:
-  case Instruction::Opcode::CatchSwitch:
-  case Instruction::Opcode::AtomicRMW:
-  case Instruction::Opcode::AtomicCmpXchg:
-  case Instruction::Opcode::Alloca:
-  case Instruction::Opcode::Unreachable:
-    return ResultReason::Infeasible;
-  }
-
-  return std::nullopt;
-}
-
-CollectDescr
-LegalityAnalysis::getHowToCollectValues(ArrayRef<Value *> Bndl) const {
-  SmallVector<CollectDescr::ExtractElementDescr, 4> Vec;
-  Vec.reserve(Bndl.size());
-  for (auto [Elm, V] : enumerate(Bndl)) {
-    if (auto *VecOp = IMaps.getVectorForOrig(V)) {
-      // If there is a vector containing `V`, then get the lane it came from.
-      std::optional<int> ExtractIdxOpt = IMaps.getOrigLane(VecOp, V);
-      // This could be a vector, like <2 x float> in which case the mask needs
-      // to enumerate all lanes.
-      for (unsigned Ln = 0, Lanes = VecUtils::getNumLanes(V); Ln != Lanes; ++Ln)
-        Vec.emplace_back(VecOp, ExtractIdxOpt ? *ExtractIdxOpt + Ln : -1);
-    } else {
-      Vec.emplace_back(V);
-    }
-  }
-  return CollectDescr(std::move(Vec));
-}
-
-const LegalityResult &LegalityAnalysis::canVectorize(ArrayRef<Value *> Bndl,
-                                                     bool SkipScheduling) {
-  // If Bndl contains values other than instructions, we need to Pack.
-  if (any_of(Bndl, [](auto *V) { return !isa<Instruction>(V); }))
-    return createLegalityResult<Pack>(ResultReason::NotInstructions);
-  // Pack if not in the same BB.
-  auto *BB = cast<Instruction>(Bndl[0])->getParent();
-  if (any_of(drop_begin(Bndl),
-             [BB](auto *V) { return cast<Instruction>(V)->getParent() != BB; }))
-    return createLegalityResult<Pack>(ResultReason::DiffBBs);
-  // Pack if instructions repeat, i.e., require some sort of broadcast.
-  SmallPtrSet<Value *, 8> Unique(llvm::from_range, Bndl);
-  if (Unique.size() != Bndl.size())
-    return createLegalityResult<Pack>(ResultReason::RepeatedInstrs);
-
-  auto CollectDescrs = getHowToCollectValues(Bndl);
-  if (CollectDescrs.hasVectorInputs()) {
-    if (auto ValueShuffleOpt = CollectDescrs.getSingleInput()) {
-      auto [Vec, Mask] = *ValueShuffleOpt;
-      if (Mask.isIdentity())
-        return createLegalityResult<DiamondReuse>(Vec);
-      return createLegalityResult<DiamondReuseWithShuffle>(Vec, Mask);
-    }
-    return createLegalityResult<DiamondReuseMultiInput>(
-        std::move(CollectDescrs));
-  }
-
-  if (auto ReasonOpt = notVectorizableBasedOnOpcodesAndTypes(Bndl))
-    return createLegalityResult<Pack>(*ReasonOpt);
-
-  if (!SkipScheduling) {
-    // TODO: Try to remove the IBndl vector.
-    SmallVector<Instruction *, 8> IBndl;
-    IBndl.reserve(Bndl.size());
-    for (auto *V : Bndl)
-      IBndl.push_back(cast<Instruction>(V));
-    if (!Sched.trySchedule(IBndl))
-      return createLegalityResult<Pack>(ResultReason::CantSchedule);
-  }
-
-  return createLegalityResult<Widen>();
-}
-
-void LegalityAnalysis::clear() {
-  Sched.clear();
-  IMaps.clear();
-}
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
deleted file mode 100644
index 5534da902b968..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.cpp
+++ /dev/null
@@ -1,518 +0,0 @@
-//===- BottomUpVec.cpp - A bottom-up vectorizer pass ----------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Module.h"
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-
-namespace llvm {
-
-#ifndef NDEBUG
-static cl::opt<bool>
-    AlwaysVerify("sbvec-always-verify", cl::init(false), cl::Hidden,
-                 cl::desc("Helps find bugs by verifying the IR whenever we "
-                          "emit new instructions (*very* expensive)."));
-#endif // NDEBUG
-
-static constexpr unsigned long StopAtDisabled =
-    std::numeric_limits<unsigned long>::max();
-static cl::opt<unsigned long>
-    StopAt("sbvec-stop-at", cl::init(StopAtDisabled), cl::Hidden,
-           cl::desc("Vectorize if the invocation count is < than this. 0 "
-                    "disables vectorization."));
-
-static constexpr unsigned long StopBundleDisabled =
-    std::numeric_limits<unsigned long>::max();
-static cl::opt<unsigned long>
-    StopBundle("sbvec-stop-bndl", cl::init(StopBundleDisabled), cl::Hidden,
-               cl::desc("Vectorize up to this many bundles."));
-
-namespace sandboxir {
-
-static SmallVector<Value *, 4> getOperand(ArrayRef<Value *> Bndl,
-                                          unsigned OpIdx) {
-  SmallVector<Value *, 4> Operands;
-  for (Value *BndlV : Bndl) {
-    auto *BndlI = cast<Instruction>(BndlV);
-    Operands.push_back(BndlI->getOperand(OpIdx));
-  }
-  return Operands;
-}
-
-/// \Returns the BB iterator after the lowest instruction in \p Vals, or the top
-/// of BB if no instruction found in \p Vals.
-static BasicBlock::iterator getInsertPointAfterInstrs(ArrayRef<Value *> Vals,
-                                                      BasicBlock *BB) {
-  auto *BotI = VecUtils::getLastPHIOrSelf(VecUtils::getLowest(Vals, BB));
-  if (BotI == nullptr)
-    // We are using BB->begin() (or after PHIs) as the fallback insert point.
-    return BB->empty()
-               ? BB->begin()
-               : std::next(
-                     VecUtils::getLastPHIOrSelf(&*BB->begin())->getIterator());
-  return std::next(BotI->getIterator());
-}
-
-Value *BottomUpVec::createVectorInstr(ArrayRef<Value *> Bndl,
-                                      ArrayRef<Value *> Operands) {
-  auto CreateVectorInstr = [](ArrayRef<Value *> Bndl,
-                              ArrayRef<Value *> Operands) -> Value * {
-    assert(all_of(Bndl, [](auto *V) { return isa<Instruction>(V); }) &&
-           "Expect Instructions!");
-    auto &Ctx = Bndl[0]->getContext();
-
-    Type *ScalarTy = VecUtils::getElementType(Utils::getExpectedType(Bndl[0]));
-    auto *VecTy = VecUtils::getWideType(ScalarTy, VecUtils::getNumLanes(Bndl));
-
-    BasicBlock::iterator WhereIt = getInsertPointAfterInstrs(
-        Bndl, cast<Instruction>(Bndl[0])->getParent());
-
-    auto Opcode = cast<Instruction>(Bndl[0])->getOpcode();
-    switch (Opcode) {
-    case Instruction::Opcode::ZExt:
-    case Instruction::Opcode::SExt:
-    case Instruction::Opcode::FPToUI:
-    case Instruction::Opcode::FPToSI:
-    case Instruction::Opcode::FPExt:
-    case Instruction::Opcode::PtrToInt:
-    case Instruction::Opcode::IntToPtr:
-    case Instruction::Opcode::SIToFP:
-    case Instruction::Opcode::UIToFP:
-    case Instruction::Opcode::Trunc:
-    case Instruction::Opcode::FPTrunc:
-    case Instruction::Opcode::BitCast: {
-      assert(Operands.size() == 1u && "Casts are unary!");
-      return CastInst::create(VecTy, Opcode, Operands[0], WhereIt, Ctx,
-                              "VCast");
-    }
-    case Instruction::Opcode::FCmp:
-    case Instruction::Opcode::ICmp: {
-      auto Pred = cast<CmpInst>(Bndl[0])->getPredicate();
-      assert(all_of(drop_begin(Bndl),
-                    [Pred](auto *SBV) {
-                      return cast<CmpInst>(SBV)->getPredicate() == Pred;
-                    }) &&
-             "Expected same predicate across bundle.");
-      return CmpInst::create(Pred, Operands[0], Operands[1], WhereIt, Ctx,
-                             "VCmp");
-    }
-    case Instruction::Opcode::Select: {
-      return SelectInst::create(Operands[0], Operands[1], Operands[2], WhereIt,
-                                Ctx, "Vec");
-    }
-    case Instruction::Opcode::FNeg: {
-      auto *UOp0 = cast<UnaryOperator>(Bndl[0]);
-      auto OpC = UOp0->getOpcode();
-      return UnaryOperator::createWithCopiedFlags(OpC, Operands[0], UOp0,
-                                                  WhereIt, Ctx, "Vec");
-    }
-    case Instruction::Opcode::Add:
-    case Instruction::Opcode::FAdd:
-    case Instruction::Opcode::Sub:
-    case Instruction::Opcode::FSub:
-    case Instruction::Opcode::Mul:
-    case Instruction::Opcode::FMul:
-    case Instruction::Opcode::UDiv:
-    case Instruction::Opcode::SDiv:
-    case Instruction::Opcode::FDiv:
-    case Instruction::Opcode::URem:
-    case Instruction::Opcode::SRem:
-    case Instruction::Opcode::FRem:
-    case Instruction::Opcode::Shl:
-    case Instruction::Opcode::LShr:
-    case Instruction::Opcode::AShr:
-    case Instruction::Opcode::And:
-    case Instruction::Opcode::Or:
-    case Instruction::Opcode::Xor: {
-      auto *BinOp0 = cast<BinaryOperator>(Bndl[0]);
-      auto *LHS = Operands[0];
-      auto *RHS = Operands[1];
-      return BinaryOperator::createWithCopiedFlags(
-          BinOp0->getOpcode(), LHS, RHS, BinOp0, WhereIt, Ctx, "Vec");
-    }
-    case Instruction::Opcode::Load: {
-      auto *Ld0 = cast<LoadInst>(Bndl[0]);
-      Value *Ptr = Ld0->getPointerOperand();
-      return LoadInst::create(VecTy, Ptr, Ld0->getAlign(), WhereIt, Ctx,
-                              "VecL");
-    }
-    case Instruction::Opcode::Store: {
-      auto Align = cast<StoreInst>(Bndl[0])->getAlign();
-      Value *Val = Operands[0];
-      Value *Ptr = Operands[1];
-      return StoreInst::create(Val, Ptr, Align, WhereIt, Ctx);
-    }
-    case Instruction::Opcode::Br:
-    case Instruction::Opcode::Ret:
-    case Instruction::Opcode::PHI:
-    case Instruction::Opcode::AddrSpaceCast:
-    case Instruction::Opcode::Call:
-    case Instruction::Opcode::GetElementPtr:
-      llvm_unreachable("Unimplemented");
-      break;
-    default:
-      llvm_unreachable("Unimplemented");
-      break;
-    }
-    llvm_unreachable("Missing switch case!");
-    // TODO: Propagate debug info.
-  };
-
-  auto *NewI = CreateVectorInstr(Bndl, Operands);
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "New instr: " << *NewI << "\n");
-  return NewI;
-}
-
-void BottomUpVec::tryEraseDeadInstrs() {
-  DenseMap<BasicBlock *, SmallVector<Instruction *>> SortedDeadInstrCandidates;
-  // The dead instrs could span BBs, so we need to collect and sort them per BB.
-  for (auto *DeadI : DeadInstrCandidates)
-    SortedDeadInstrCandidates[DeadI->getParent()].push_back(DeadI);
-  for (auto &Pair : SortedDeadInstrCandidates)
-    sort(Pair.second,
-         [](Instruction *I1, Instruction *I2) { return I1->comesBefore(I2); });
-  for (const auto &Pair : SortedDeadInstrCandidates) {
-    for (Instruction *I : reverse(Pair.second)) {
-      if (I->hasNUses(0)) {
-        // Erase the dead instructions bottom-to-top.
-        LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Erase dead: " << *I << "\n");
-        I->eraseFromParent();
-      }
-    }
-  }
-  DeadInstrCandidates.clear();
-}
-
-Value *BottomUpVec::createShuffle(Value *VecOp, const ShuffleMask &Mask,
-                                  BasicBlock *UserBB) {
-  BasicBlock::iterator WhereIt = getInsertPointAfterInstrs({VecOp}, UserBB);
-  return ShuffleVectorInst::create(VecOp, VecOp, Mask, WhereIt,
-                                   VecOp->getContext(), "VShuf");
-}
-
-Value *BottomUpVec::createPack(ArrayRef<Value *> ToPack, BasicBlock *UserBB) {
-  BasicBlock::iterator WhereIt = getInsertPointAfterInstrs(ToPack, UserBB);
-
-  Type *ScalarTy = VecUtils::getCommonScalarType(ToPack);
-  unsigned Lanes = VecUtils::getNumLanes(ToPack);
-  Type *VecTy = VecUtils::getWideType(ScalarTy, Lanes);
-
-  // Create a series of pack instructions.
-  Value *LastInsert = PoisonValue::get(VecTy);
-
-  Context &Ctx = ToPack[0]->getContext();
-
-  unsigned InsertIdx = 0;
-  for (Value *Elm : ToPack) {
-    // An element can be either scalar or vector. We need to generate different
-    // IR for each case.
-    if (Elm->getType()->isVectorTy()) {
-      unsigned NumElms =
-          cast<FixedVectorType>(Elm->getType())->getNumElements();
-      for (auto ExtrLane : seq<int>(0, NumElms)) {
-        // We generate extract-insert pairs, for each lane in `Elm`.
-        Constant *ExtrLaneC =
-            ConstantInt::getSigned(Type::getInt32Ty(Ctx), ExtrLane);
-        // This may return a Constant if Elm is a Constant.
-        auto *ExtrI =
-            ExtractElementInst::create(Elm, ExtrLaneC, WhereIt, Ctx, "VPack");
-        if (!isa<Constant>(ExtrI))
-          WhereIt = std::next(cast<Instruction>(ExtrI)->getIterator());
-        Constant *InsertLaneC =
-            ConstantInt::getSigned(Type::getInt32Ty(Ctx), InsertIdx++);
-        // This may also return a Constant if ExtrI is a Constant.
-        auto *InsertI = InsertElementInst::create(
-            LastInsert, ExtrI, InsertLaneC, WhereIt, Ctx, "VPack");
-        LastInsert = InsertI;
-        if (!isa<Constant>(InsertI))
-          WhereIt = std::next(cast<Instruction>(LastInsert)->getIterator());
-      }
-    } else {
-      Constant *InsertLaneC =
-          ConstantInt::getSigned(Type::getInt32Ty(Ctx), InsertIdx++);
-      // This may be folded into a Constant if LastInsert is a Constant. In
-      // that case we only collect the last constant.
-      LastInsert = InsertElementInst::create(LastInsert, Elm, InsertLaneC,
-                                             WhereIt, Ctx, "Pack");
-      if (auto *NewI = dyn_cast<Instruction>(LastInsert))
-        WhereIt = std::next(NewI->getIterator());
-    }
-  }
-  return LastInsert;
-}
-
-void BottomUpVec::collectPotentiallyDeadInstrs(ArrayRef<Value *> Bndl) {
-  for (Value *V : Bndl)
-    DeadInstrCandidates.insert(cast<Instruction>(V));
-  // Also collect the GEPs of vectorized loads and stores.
-  auto Opcode = cast<Instruction>(Bndl[0])->getOpcode();
-  switch (Opcode) {
-  case Instruction::Opcode::Load: {
-    for (Value *V : drop_begin(Bndl))
-      if (auto *Ptr =
-              dyn_cast<Instruction>(cast<LoadInst>(V)->getPointerOperand()))
-        DeadInstrCandidates.insert(Ptr);
-    break;
-  }
-  case Instruction::Opcode::Store: {
-    for (Value *V : drop_begin(Bndl))
-      if (auto *Ptr =
-              dyn_cast<Instruction>(cast<StoreInst>(V)->getPointerOperand()))
-        DeadInstrCandidates.insert(Ptr);
-    break;
-  }
-  default:
-    break;
-  }
-}
-
-Action *BottomUpVec::vectorizeRec(ArrayRef<Value *> Bndl,
-                                  ArrayRef<Value *> UserBndl, unsigned Depth,
-                                  LegalityAnalysis &Legality) {
-  bool StopForDebug =
-      DebugBndlCnt++ >= StopBundle && StopBundle != StopBundleDisabled;
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "canVectorize() Bundle:\n";
-             VecUtils::dump(Bndl));
-  const auto &LegalityRes = StopForDebug ? Legality.getForcedPackForDebugging()
-                                         : Legality.canVectorize(Bndl);
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Legality: " << LegalityRes << "\n");
-  auto ActionPtr =
-      std::make_unique<Action>(&LegalityRes, Bndl, UserBndl, Depth);
-  SmallVector<Action *> Operands;
-  switch (LegalityRes.getSubclassID()) {
-  case LegalityResultID::Widen: {
-    auto *I = cast<Instruction>(Bndl[0]);
-    switch (I->getOpcode()) {
-    case Instruction::Opcode::Load:
-      break;
-    case Instruction::Opcode::Store: {
-      // Don't recurse towards the pointer operand.
-      Action *OpA =
-          vectorizeRec(getOperand(Bndl, 0), Bndl, Depth + 1, Legality);
-      Operands.push_back(OpA);
-      break;
-    }
-    default:
-      // Visit all operands.
-      for (auto OpIdx : seq<unsigned>(I->getNumOperands())) {
-        Action *OpA =
-            vectorizeRec(getOperand(Bndl, OpIdx), Bndl, Depth + 1, Legality);
-        Operands.push_back(OpA);
-      }
-      break;
-    }
-    // Update the maps to mark Bndl as "vectorized".
-    IMaps->registerVector(Bndl, ActionPtr.get());
-    break;
-  }
-  case LegalityResultID::DiamondReuse:
-  case LegalityResultID::DiamondReuseWithShuffle:
-  case LegalityResultID::DiamondReuseMultiInput:
-  case LegalityResultID::Pack:
-    break;
-  }
-  // Create actions in post-order.
-  ActionPtr->Operands = std::move(Operands);
-  auto *Action = ActionPtr.get();
-  Actions.push_back(std::move(ActionPtr));
-  return Action;
-}
-
-#ifndef NDEBUG
-void BottomUpVec::ActionsVector::print(raw_ostream &OS) const {
-  for (auto [Idx, Action] : enumerate(Actions)) {
-    Action->print(OS);
-    OS << "\n";
-  }
-}
-void BottomUpVec::ActionsVector::dump() const { print(dbgs()); }
-#endif // NDEBUG
-
-Value *BottomUpVec::emitVectors() {
-  Value *NewVec = nullptr;
-  for (const auto &ActionPtr : Actions) {
-    ArrayRef<Value *> Bndl = ActionPtr->Bndl;
-    ArrayRef<Value *> UserBndl = ActionPtr->UserBndl;
-    const LegalityResult &LegalityRes = *ActionPtr->LegalityRes;
-    unsigned Depth = ActionPtr->Depth;
-    auto *UserBB = !UserBndl.empty()
-                       ? cast<Instruction>(UserBndl.front())->getParent()
-                       : cast<Instruction>(Bndl[0])->getParent();
-
-    switch (LegalityRes.getSubclassID()) {
-    case LegalityResultID::Widen: {
-      auto *I = cast<Instruction>(Bndl[0]);
-      SmallVector<Value *, 2> VecOperands;
-      switch (I->getOpcode()) {
-      case Instruction::Opcode::Load:
-        VecOperands.push_back(cast<LoadInst>(I)->getPointerOperand());
-        break;
-      case Instruction::Opcode::Store: {
-        VecOperands.push_back(ActionPtr->Operands[0]->Vec);
-        VecOperands.push_back(cast<StoreInst>(I)->getPointerOperand());
-        break;
-      }
-      default:
-        // Visit all operands.
-        for (Action *OpA : ActionPtr->Operands) {
-          auto *VecOp = OpA->Vec;
-          VecOperands.push_back(VecOp);
-        }
-        break;
-      }
-      NewVec = createVectorInstr(ActionPtr->Bndl, VecOperands);
-      // Collect any potentially dead scalar instructions, including the
-      // original scalars and pointer operands of loads/stores.
-      if (NewVec != nullptr)
-        collectPotentiallyDeadInstrs(Bndl);
-      break;
-    }
-    case LegalityResultID::DiamondReuse: {
-      NewVec = cast<DiamondReuse>(LegalityRes).getVector()->Vec;
-      break;
-    }
-    case LegalityResultID::DiamondReuseWithShuffle: {
-      auto *VecOp = cast<DiamondReuseWithShuffle>(LegalityRes).getVector()->Vec;
-      const ShuffleMask &Mask =
-          cast<DiamondReuseWithShuffle>(LegalityRes).getMask();
-      NewVec = createShuffle(VecOp, Mask, UserBB);
-      assert(NewVec->getType() == VecOp->getType() &&
-             "Expected same type! Bad mask ?");
-      break;
-    }
-    case LegalityResultID::DiamondReuseMultiInput: {
-      const auto &Descr =
-          cast<DiamondReuseMultiInput>(LegalityRes).getCollectDescr();
-      Type *ResTy = VecUtils::getWideType(Bndl[0]->getType(), Bndl.size());
-
-      // TODO: Try to get WhereIt without creating a vector.
-      SmallVector<Value *, 4> DescrInstrs;
-      for (const auto &ElmDescr : Descr.getDescrs()) {
-        auto *V = ElmDescr.needsExtract() ? ElmDescr.getValue()->Vec
-                                          : ElmDescr.getScalar();
-        if (auto *I = dyn_cast<Instruction>(V))
-          DescrInstrs.push_back(I);
-      }
-      BasicBlock::iterator WhereIt =
-          getInsertPointAfterInstrs(DescrInstrs, UserBB);
-
-      Value *LastV = PoisonValue::get(ResTy);
-      Context &Ctx = LastV->getContext();
-      unsigned Lane = 0;
-      for (const auto &ElmDescr : Descr.getDescrs()) {
-        Value *VecOp = nullptr;
-        Value *ValueToInsert;
-        if (ElmDescr.needsExtract()) {
-          VecOp = ElmDescr.getValue()->Vec;
-          ConstantInt *IdxC =
-              ConstantInt::get(Type::getInt32Ty(Ctx), ElmDescr.getExtractIdx());
-          ValueToInsert = ExtractElementInst::create(
-              VecOp, IdxC, WhereIt, VecOp->getContext(), "VExt");
-        } else {
-          ValueToInsert = ElmDescr.getScalar();
-        }
-        auto NumLanesToInsert = VecUtils::getNumLanes(ValueToInsert);
-        if (NumLanesToInsert == 1) {
-          // If we are inserting a scalar element then we need a single insert.
-          //   %VIns = insert %DstVec,  %SrcScalar, Lane
-          ConstantInt *LaneC = ConstantInt::get(Type::getInt32Ty(Ctx), Lane);
-          LastV = InsertElementInst::create(LastV, ValueToInsert, LaneC,
-                                            WhereIt, Ctx, "VIns");
-        } else {
-          // If we are inserting a vector element then we need to extract and
-          // insert each vector element one by one with a chain of extracts and
-          // inserts, for example:
-          //   %VExt0 = extract %SrcVec, 0
-          //   %VIns0 = insert  %DstVec, %Vect0, Lane + 0
-          //   %VExt1 = extract %SrcVec, 1
-          //   %VIns1 = insert  %VIns0,  %Vect0, Lane + 1
-          for (unsigned LnCnt = 0; LnCnt != NumLanesToInsert; ++LnCnt) {
-            auto *ExtrIdxC = ConstantInt::get(Type::getInt32Ty(Ctx), LnCnt);
-            auto *ExtrI = ExtractElementInst::create(ValueToInsert, ExtrIdxC,
-                                                     WhereIt, Ctx, "VExt");
-            unsigned InsLane = Lane + LnCnt;
-            auto *InsLaneC = ConstantInt::get(Type::getInt32Ty(Ctx), InsLane);
-            LastV = InsertElementInst::create(LastV, ExtrI, InsLaneC, WhereIt,
-                                              Ctx, "VIns");
-          }
-        }
-        Lane += NumLanesToInsert;
-      }
-      NewVec = LastV;
-      break;
-    }
-    case LegalityResultID::Pack: {
-      // If we can't vectorize the seeds then just return.
-      if (Depth == 0)
-        return nullptr;
-      NewVec = createPack(Bndl, UserBB);
-      break;
-    }
-    }
-    if (NewVec != nullptr) {
-      Change = true;
-      ActionPtr->Vec = NewVec;
-    }
-#ifndef NDEBUG
-    if (AlwaysVerify) {
-      // This helps find broken IR by constantly verifying the function. Note
-      // that this is very expensive and should only be used for debugging.
-      Instruction *I0 = isa<Instruction>(Bndl[0])
-                            ? cast<Instruction>(Bndl[0])
-                            : cast<Instruction>(UserBndl[0]);
-      assert(!Utils::verifyFunction(I0->getParent()->getParent(), dbgs()) &&
-             "Broken function!");
-    }
-#endif // NDEBUG
-  }
-  return NewVec;
-}
-
-bool BottomUpVec::tryVectorize(ArrayRef<Value *> Bndl,
-                               LegalityAnalysis &Legality) {
-  Change = false;
-  if (LLVM_UNLIKELY(BottomUpInvocationCnt++ >= StopAt &&
-                    StopAt != StopAtDisabled))
-    return false;
-  DeadInstrCandidates.clear();
-  Legality.clear();
-  Actions.clear();
-  DebugBndlCnt = 0;
-  vectorizeRec(Bndl, {}, /*Depth=*/0, Legality);
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "BottomUpVec: Vectorization Actions:\n";
-             Actions.dump());
-  emitVectors();
-  tryEraseDeadInstrs();
-  return Change;
-}
-
-bool BottomUpVec::runOnRegion(Region &Rgn, const Analyses &A) {
-  const auto &SeedSlice = Rgn.getAux();
-  assert(SeedSlice.size() >= 2 && "Bad slice!");
-  Function &F = *SeedSlice[0]->getParent()->getParent();
-  IMaps = std::make_unique<InstrMaps>();
-  LegalityAnalysis Legality(A.getAA(), A.getScalarEvolution(),
-                            F.getParent()->getDataLayout(), F.getContext(),
-                            *IMaps);
-
-  // TODO: Refactor to remove the unnecessary copy to SeedSliceVals.
-  SmallVector<Value *> SeedSliceVals(SeedSlice.begin(), SeedSlice.end());
-  // Try to vectorize starting from the seed slice. The returned value
-  // is true if we found vectorizable code and generated some vector
-  // code for it. It does not mean that the code is profitable.
-  return tryVectorize(SeedSliceVals, Legality);
-}
-
-} // namespace sandboxir
-} // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.cpp
deleted file mode 100644
index 14a6de30bf398..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//===- PackReuse.cpp - A pack de-duplication pass -------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-
-namespace llvm::sandboxir {
-
-bool PackReuse::runOnRegion(Region &Rgn, const Analyses &A) {
-  if (Rgn.empty())
-    return Change;
-  // The key to the map is the ordered operands of the pack.
-  // The value is a vector of all Pack Instrs with the same operands.
-  DenseMap<std::pair<BasicBlock *, SmallVector<Value *>>,
-           SmallVector<SmallVector<Instruction *>>>
-      PacksMap;
-  // Go over the region and look for pack patterns.
-  for (auto *I : Rgn) {
-    auto PackOpt = VecUtils::matchPack(I);
-    if (PackOpt) {
-      // TODO: For now limit pack reuse within a BB.
-      BasicBlock *BB = (*PackOpt->Instrs.front()).getParent();
-      PacksMap[{BB, PackOpt->Operands}].push_back(PackOpt->Instrs);
-    }
-  }
-  for (auto &Pair : PacksMap) {
-    auto &Packs = Pair.second;
-    if (Packs.size() <= 1)
-      continue;
-    // Sort packs by program order.
-    sort(Packs, [](const auto &PackInstrs1, const auto &PackInstrs2) {
-      return PackInstrs1.front()->comesBefore(PackInstrs2.front());
-    });
-    Instruction *TopMostPack = Packs[0].front();
-    // Replace duplicate packs with the first one.
-    for (const auto &PackInstrs :
-         make_range(std::next(Packs.begin()), Packs.end())) {
-      PackInstrs.front()->replaceAllUsesWith(TopMostPack);
-      // Delete the pack instrs bottom-up since they are now dead.
-      for (auto *PackI : PackInstrs)
-        PackI->eraseFromParent();
-    }
-    Change = true;
-  }
-  return Change;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
deleted file mode 100644
index 02b973926854d..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/PassRegistry.def
+++ /dev/null
@@ -1,40 +0,0 @@
-//===- PassRegistry.def - Registry of passes --------------------*- 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 file is used as the registry of sub-passes that are part of the
-// SandboxVectorizer pass.
-//
-//===----------------------------------------------------------------------===//
-
-// NOTE: NO INCLUDE GUARD DESIRED!
-
-#ifndef REGION_PASS
-#define REGION_PASS(NAME, CLASS_NAME)
-#endif
-
-REGION_PASS("null", ::llvm::sandboxir::NullPass)
-REGION_PASS("pack-reuse", ::llvm::sandboxir::PackReuse)
-REGION_PASS("print-instruction-count", ::llvm::sandboxir::PrintInstructionCount)
-REGION_PASS("print-region", ::llvm::sandboxir::PrintRegion)
-REGION_PASS("tr-save", ::llvm::sandboxir::TransactionSave)
-REGION_PASS("tr-accept", ::llvm::sandboxir::TransactionAlwaysAccept)
-REGION_PASS("tr-revert", ::llvm::sandboxir::TransactionAlwaysRevert)
-REGION_PASS("tr-accept-or-revert", ::llvm::sandboxir::TransactionAcceptOrRevert)
-REGION_PASS("bottom-up-vec", ::llvm::sandboxir::BottomUpVec)
-
-#undef REGION_PASS
-
-#ifndef FUNCTION_PASS_WITH_PARAMS
-#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS_NAME)
-#endif
-
-FUNCTION_PASS_WITH_PARAMS("seed-collection", ::llvm::sandboxir::SeedCollection)
-FUNCTION_PASS_WITH_PARAMS("regions-from-bbs", ::llvm::sandboxir::RegionsFromBBs)
-FUNCTION_PASS_WITH_PARAMS("regions-from-metadata", ::llvm::sandboxir::RegionsFromMetadata)
-
-#undef FUNCTION_PASS_WITH_PARAMS
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.cpp
deleted file mode 100644
index 6801524732ce6..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- RegionsFromBBs.cpp - A helper to test RegionPasses -----------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
-
-namespace llvm::sandboxir {
-
-RegionsFromBBs::RegionsFromBBs(StringRef Pipeline)
-    : FunctionPass("regions-from-bbs"),
-      RPM("rpm", Pipeline, SandboxVectorizerPassBuilder::createRegionPass) {}
-
-bool RegionsFromBBs::runOnFunction(Function &F, const Analyses &A) {
-  SmallVector<std::unique_ptr<Region>, 16> Regions;
-  // Create a region for each BB.
-  for (BasicBlock &BB : F) {
-    Regions.push_back(std::make_unique<Region>(F.getContext(), A.getTTI()));
-    auto &RgnPtr = Regions.back();
-    for (Instruction &I : BB)
-      RgnPtr->add(&I);
-  }
-  // For each region run the region pass pipeline.
-  for (auto &RgnPtr : Regions)
-    RPM.runOnRegion(*RgnPtr, A);
-  return false;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.cpp
deleted file mode 100644
index 73d5b938261d5..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-//===- RegionsFromMetadata.cpp - A helper to test RegionPasses -----------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h"
-
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
-
-namespace llvm::sandboxir {
-
-RegionsFromMetadata::RegionsFromMetadata(StringRef Pipeline)
-    : FunctionPass("regions-from-metadata"),
-      RPM("rpm", Pipeline, SandboxVectorizerPassBuilder::createRegionPass) {}
-
-bool RegionsFromMetadata::runOnFunction(Function &F, const Analyses &A) {
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(F, A.getTTI());
-  bool Change = false;
-  for (auto &R : Regions) {
-    Change |= RPM.runOnRegion(*R, A);
-  }
-  return Change;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp
deleted file mode 100644
index ddb4a1e154a18..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-//===- SeedCollection.cpp - Seed collection pass --------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/SandboxIR/Module.h"
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-
-namespace llvm {
-
-static cl::opt<unsigned>
-    OverrideVecRegBits("sbvec-vec-reg-bits", cl::init(0), cl::Hidden,
-                       cl::desc("Override the vector register size in bits, "
-                                "which is otherwise found by querying TTI."));
-static cl::opt<bool>
-    AllowNonPow2("sbvec-allow-non-pow2", cl::init(false), cl::Hidden,
-                 cl::desc("Allow non-power-of-2 vectorization."));
-
-#define LoadSeedsDef "loads"
-#define StoreSeedsDef "stores"
-cl::opt<std::string> CollectSeeds(
-    "sbvec-collect-seeds", cl::init(StoreSeedsDef), cl::Hidden,
-    cl::desc("Collect these seeds. Use empty for none or a comma-separated "
-             "list of '" StoreSeedsDef "' and '" LoadSeedsDef "'."));
-
-namespace sandboxir {
-SeedCollection::SeedCollection(StringRef Pipeline)
-    : FunctionPass("seed-collection"),
-      RPM("rpm", Pipeline, SandboxVectorizerPassBuilder::createRegionPass) {}
-
-bool SeedCollection::runOnFunction(Function &F, const Analyses &A) {
-  bool Change = false;
-  const auto &DL = F.getParent()->getDataLayout();
-  unsigned VecRegBits =
-      OverrideVecRegBits != 0
-          ? OverrideVecRegBits
-          : A.getTTI()
-                .getRegisterBitWidth(TargetTransformInfo::RGK_FixedWidthVector)
-                .getFixedValue();
-  bool CollectStores = CollectSeeds.find(StoreSeedsDef) != std::string::npos;
-  bool CollectLoads = CollectSeeds.find(LoadSeedsDef) != std::string::npos;
-
-  // TODO: Start from innermost BBs first
-  for (auto &BB : F) {
-    SeedCollector SC(&BB, A.getScalarEvolution(), CollectStores, CollectLoads);
-    for (SeedBundle &Seeds : SC.getStoreSeeds()) {
-      unsigned ElmBits =
-          Utils::getNumBits(VecUtils::getElementType(Utils::getExpectedType(
-                                Seeds[Seeds.getFirstUnusedElementIdx()])),
-                            DL);
-
-      auto DivideBy2 = [](unsigned Num) {
-        auto Floor = VecUtils::getFloorPowerOf2(Num);
-        if (Floor == Num)
-          return Floor / 2;
-        return Floor;
-      };
-      // Try to create the largest vector supported by the target. If it fails
-      // reduce the vector size by half.
-      for (unsigned SliceElms = std::min(VecRegBits / ElmBits,
-                                         Seeds.getNumUnusedBits() / ElmBits);
-           SliceElms >= 2u; SliceElms = DivideBy2(SliceElms)) {
-        if (Seeds.allUsed())
-          break;
-        // Keep trying offsets after FirstUnusedElementIdx, until we vectorize
-        // the slice. This could be quite expensive, so we enforce a limit.
-        for (unsigned Offset = Seeds.getFirstUnusedElementIdx(),
-                      OE = Seeds.size();
-             Offset + 1 < OE; Offset += 1) {
-          // Seeds are getting used as we vectorize, so skip them.
-          if (Seeds.isUsed(Offset))
-            continue;
-          if (Seeds.allUsed())
-            break;
-
-          auto SeedSlice =
-              Seeds.getSlice(Offset, SliceElms * ElmBits, !AllowNonPow2);
-          if (SeedSlice.empty())
-            continue;
-
-          assert(SeedSlice.size() >= 2 && "Should have been rejected!");
-
-          // Create a region containing the seed slice.
-          auto &Ctx = F.getContext();
-          Region Rgn(Ctx, A.getTTI());
-          Rgn.setAux(SeedSlice);
-          // Run the region pass pipeline.
-          Change |= RPM.runOnRegion(Rgn, A);
-          Rgn.clearAux();
-        }
-      }
-    }
-  }
-  return Change;
-}
-} // namespace sandboxir
-} // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
deleted file mode 100644
index 7194529b87404..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-//===- TransactionAcceptOrRevert.cpp - Check cost and accept/revert region ===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/InstructionCost.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h"
-
-namespace llvm {
-
-static cl::opt<int> CostThreshold("sbvec-cost-threshold", cl::init(0),
-                                  cl::Hidden,
-                                  cl::desc("Vectorization cost threshold."));
-
-namespace sandboxir {
-
-bool TransactionAcceptOrRevert::runOnRegion(Region &Rgn, const Analyses &A) {
-  const auto &SB = Rgn.getScoreboard();
-  [[maybe_unused]] auto CostBefore = SB.getBeforeCost();
-  [[maybe_unused]] auto CostAfter = SB.getAfterCost();
-  InstructionCost CostAfterMinusBefore = SB.getAfterCost() - SB.getBeforeCost();
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Cost gain: " << CostAfterMinusBefore
-                    << " (before/after/threshold: " << CostBefore << "/"
-                    << CostAfter << "/" << CostThreshold << ")\n");
-  // TODO: Print costs / write to remarks.
-  auto &Tracker = Rgn.getContext().getTracker();
-  if (CostAfterMinusBefore < -CostThreshold) {
-    bool HasChanges = !Tracker.empty();
-    Tracker.accept();
-    LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "*** Transaction Accept ***\n");
-    return HasChanges;
-  }
-  // Revert the IR.
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "*** Transaction Revert ***\n");
-  Rgn.getContext().getTracker().revert();
-  return false;
-}
-
-} // namespace sandboxir
-} // namespace llvm
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.cpp
deleted file mode 100644
index 8603caf7d02ea..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-//===- TransactionSave.cpp - Save the IR state ----------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.h"
-#include "llvm/Support/InstructionCost.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h"
-
-namespace llvm::sandboxir {
-
-bool TransactionSave::runOnRegion(Region &Rgn, const Analyses &A) {
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "*** Save Transaction ***\n");
-  Rgn.getContext().save();
-  return false;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
deleted file mode 100644
index 2de692143c1b6..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-//===- SandboxVectorizer.cpp - Vectorizer based on Sandbox IR -------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Regex.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Debug.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
-
-using namespace llvm;
-
-static cl::opt<bool>
-    PrintPassPipeline("sbvec-print-pass-pipeline", cl::init(false), cl::Hidden,
-                      cl::desc("Prints the pass pipeline and returns."));
-
-/// A magic string for the default pass pipeline.
-static const char *DefaultPipelineMagicStr = "*";
-
-static cl::opt<std::string> UserDefinedPassPipeline(
-    "sbvec-passes", cl::init(DefaultPipelineMagicStr), cl::Hidden,
-    cl::desc("Comma-separated list of vectorizer passes. If not set "
-             "we run the predefined pipeline."));
-
-// This option is useful for bisection debugging.
-// For example you may use it to figure out which filename is the one causing a
-// miscompile. You can specify a regex for the filename like: "/[a-m][^/]*"
-// which will enable any file name starting with 'a' to 'm' and disable the
-// rest. If the miscompile goes away, then we try "/[n-z][^/]*" for the other
-// half of the range, from 'n' to 'z'. If we can reproduce the miscompile then
-// we can keep looking in [n-r] and [s-z] and so on, in a binary-search fashion.
-//
-// Please note that we are using [^/]* and not .* to make sure that we are
-// matching the actual filename and not some other directory in the path.
-cl::opt<std::string> AllowFiles(
-    "sbvec-allow-files", cl::init(".*"), cl::Hidden,
-    cl::desc("Run the vectorizer only on file paths that match any in the "
-             "list of comma-separated regex's."));
-static constexpr char AllowFilesDelim = ',';
-
-SandboxVectorizerPass::SandboxVectorizerPass() : FPM("fpm") {
-  if (UserDefinedPassPipeline == DefaultPipelineMagicStr) {
-    // TODO: Add passes to the default pipeline. It currently contains:
-    //       - Seed collection, which creates seed regions and runs the pipeline
-    //         - Bottom-up Vectorizer pass that starts from a seed
-    //         - Accept or revert IR state pass
-    FPM.setPassPipeline(
-        "seed-collection<tr-save,bottom-up-vec,tr-accept-or-revert>",
-        sandboxir::SandboxVectorizerPassBuilder::createFunctionPass);
-  } else {
-    // Create the user-defined pipeline.
-    FPM.setPassPipeline(
-        UserDefinedPassPipeline,
-        sandboxir::SandboxVectorizerPassBuilder::createFunctionPass);
-  }
-}
-
-SandboxVectorizerPass::SandboxVectorizerPass(SandboxVectorizerPass &&) =
-    default;
-
-SandboxVectorizerPass::~SandboxVectorizerPass() = default;
-
-PreservedAnalyses SandboxVectorizerPass::run(Function &F,
-                                             FunctionAnalysisManager &AM) {
-  TTI = &AM.getResult<TargetIRAnalysis>(F);
-  AA = &AM.getResult<AAManager>(F);
-  SE = &AM.getResult<ScalarEvolutionAnalysis>(F);
-
-  bool Changed = runImpl(F);
-  if (!Changed)
-    return PreservedAnalyses::all();
-
-  PreservedAnalyses PA;
-  PA.preserveSet<CFGAnalyses>();
-  return PA;
-}
-
-bool SandboxVectorizerPass::allowFile(const std::string &SrcFilePath) {
-  // Iterate over all files in AllowFiles separated by `AllowFilesDelim`.
-  size_t DelimPos = 0;
-  do {
-    size_t LastPos = DelimPos != 0 ? DelimPos + 1 : DelimPos;
-    DelimPos = AllowFiles.find(AllowFilesDelim, LastPos);
-    auto FileNameToMatch = AllowFiles.substr(LastPos, DelimPos - LastPos);
-    if (FileNameToMatch.empty())
-      return false;
-    // Note: This only runs when debugging so its OK not to reuse the regex.
-    Regex FileNameRegex(".*" + FileNameToMatch + "$");
-    assert(FileNameRegex.isValid() && "Bad regex!");
-    if (FileNameRegex.match(SrcFilePath))
-      return true;
-  } while (DelimPos != std::string::npos);
-  return false;
-}
-
-bool SandboxVectorizerPass::runImpl(Function &LLVMF) {
-  if (Ctx == nullptr)
-    Ctx = std::make_unique<sandboxir::Context>(LLVMF.getContext());
-
-  if (PrintPassPipeline) {
-    FPM.printPipeline(outs());
-    return false;
-  }
-
-  // This is used for debugging.
-  if (LLVM_UNLIKELY(AllowFiles != ".*")) {
-    const auto &SrcFilePath = LLVMF.getParent()->getSourceFileName();
-    if (!allowFile(SrcFilePath))
-      return false;
-  }
-
-  // If the target claims to have no vector registers early return.
-  if (!TTI->getNumberOfRegisters(TTI->getRegisterClassForType(true))) {
-    LLVM_DEBUG(dbgs() << DEBUG_PREFIX
-                      << "Target has no vector registers, return.\n");
-    return false;
-  }
-  LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Analyzing " << LLVMF.getName()
-                    << ".\n");
-  // Early return if the attribute NoImplicitFloat is used.
-  if (LLVMF.hasFnAttribute(Attribute::NoImplicitFloat)) {
-    LLVM_DEBUG(dbgs() << DEBUG_PREFIX
-                      << "NoImplicitFloat attribute, return.\n");
-    return false;
-  }
-
-  // Create SandboxIR for LLVMF and run BottomUpVec on it.
-  sandboxir::Function &F = *Ctx->createFunction(&LLVMF);
-  sandboxir::Analyses A(*AA, *SE, *TTI);
-  bool Change = FPM.runOnFunction(F, A);
-  // Given that sandboxir::Context `Ctx` is defined at a pass-level scope, the
-  // maps from LLVM IR to Sandbox IR may go stale as later passes remove LLVM IR
-  // objects. To avoid issues caused by this clear the context's state.
-  // NOTE: The alternative would be to define Ctx and FPM within runOnFunction()
-  Ctx->clear();
-  return Change;
-}
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
deleted file mode 100644
index 8432b066f966c..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.cpp
+++ /dev/null
@@ -1,40 +0,0 @@
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerPassBuilder.h"
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/BottomUpVec.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/NullPass.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PackReuse.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintInstructionCount.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/PrintRegion.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromBBs.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/RegionsFromMetadata.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/SeedCollection.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAcceptOrRevert.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysAccept.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionAlwaysRevert.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Passes/TransactionSave.h"
-
-namespace llvm::sandboxir {
-
-std::unique_ptr<sandboxir::RegionPass>
-SandboxVectorizerPassBuilder::createRegionPass(StringRef Name, StringRef Args) {
-#define REGION_PASS(NAME, CLASS_NAME)                                          \
-  if (Name == NAME) {                                                          \
-    assert(Args.empty() && "Unexpected arguments for pass '" NAME "'.");       \
-    return std::make_unique<CLASS_NAME>();                                     \
-  }
-// TODO: Support region passes with params.
-#include "Passes/PassRegistry.def"
-  return nullptr;
-}
-
-std::unique_ptr<sandboxir::FunctionPass>
-SandboxVectorizerPassBuilder::createFunctionPass(StringRef Name,
-                                                 StringRef Args) {
-#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS_NAME)                            \
-  if (Name == NAME)                                                            \
-    return std::make_unique<CLASS_NAME>(Args);
-#include "Passes/PassRegistry.def"
-  return nullptr;
-}
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Scheduler.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Scheduler.cpp
deleted file mode 100644
index 4893d9177eead..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/Scheduler.cpp
+++ /dev/null
@@ -1,360 +0,0 @@
-//===- Scheduler.cpp ------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-
-namespace llvm::sandboxir {
-
-// TODO: Check if we can cache top/bottom to reduce compile-time.
-DGNode *SchedBundle::getTop() const {
-  DGNode *TopN = Nodes.front();
-  for (auto *N : drop_begin(Nodes)) {
-    if (N->getInstruction()->comesBefore(TopN->getInstruction()))
-      TopN = N;
-  }
-  return TopN;
-}
-
-DGNode *SchedBundle::getBot() const {
-  DGNode *BotN = Nodes.front();
-  for (auto *N : drop_begin(Nodes)) {
-    if (BotN->getInstruction()->comesBefore(N->getInstruction()))
-      BotN = N;
-  }
-  return BotN;
-}
-
-void SchedBundle::cluster(BasicBlock::iterator Where) {
-  for (auto *N : Nodes) {
-    auto *I = N->getInstruction();
-    if (I->getIterator() == Where)
-      ++Where; // Try to maintain bundle order.
-    I->moveBefore(*Where.getNodeParent(), Where);
-  }
-}
-
-#ifndef NDEBUG
-void SchedBundle::dump(raw_ostream &OS) const {
-  for (auto *N : Nodes)
-    OS << *N;
-}
-
-void SchedBundle::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-#ifndef NDEBUG
-void ReadyListContainer::dump(raw_ostream &OS) const {
-  auto ListCopy = List;
-  while (!ListCopy.empty()) {
-    OS << *ListCopy.top() << "\n";
-    ListCopy.pop();
-  }
-}
-
-void ReadyListContainer::dump() const {
-  dump(dbgs());
-  dbgs() << "\n";
-}
-#endif // NDEBUG
-
-void Scheduler::scheduleAndUpdateReadyList(SchedBundle &Bndl) {
-  // Find where we should schedule the instructions.
-  assert(ScheduleTopItOpt && "Should have been set by now!");
-  auto Where = *ScheduleTopItOpt;
-  // Move all instructions in `Bndl` to `Where`.
-  Bndl.cluster(Where);
-  // Update the last scheduled bundle.
-  ScheduleTopItOpt = Bndl.getTop()->getInstruction()->getIterator();
-  // Set nodes as "scheduled" and decrement the UnsceduledSuccs counter of all
-  // dependency predecessors.
-  for (DGNode *N : Bndl) {
-    for (auto *DepN : N->preds(DAG)) {
-      DepN->decrUnscheduledSuccs();
-      if (DepN->ready() && !DepN->scheduled())
-        ReadyList.insert(DepN);
-    }
-    N->setScheduled(true);
-  }
-}
-
-void Scheduler::notifyCreateInstr(Instruction *I) {
-  // The DAG notifier should have run by now.
-  auto *N = DAG.getNode(I);
-  // If there is no DAG node for `I` it means that this is out of scope for the
-  // DAG and as such out of scope for the scheduler too, so nothing to do.
-  if (N == nullptr)
-    return;
-  // If the instruction is inserted below the top-of-schedule then we mark it as
-  // "scheduled".
-  bool IsScheduled = ScheduleTopItOpt &&
-                     *ScheduleTopItOpt != I->getParent()->end() &&
-                     (*ScheduleTopItOpt.value()).comesBefore(I);
-  if (IsScheduled)
-    N->setScheduled(true);
-  // If the new instruction is above the top of schedule we need to remove its
-  // dependency predecessors from the ready list and increment their
-  // `UnscheduledSuccs` counters.
-  if (!IsScheduled) {
-    for (auto *PredN : N->preds(DAG)) {
-      ReadyList.remove(PredN);
-      PredN->incrUnscheduledSuccs();
-    }
-  }
-}
-
-SchedBundle *Scheduler::createBundle(ArrayRef<Instruction *> Instrs) {
-  SchedBundle::ContainerTy Nodes;
-  Nodes.reserve(Instrs.size());
-  for (auto *I : Instrs)
-    Nodes.push_back(DAG.getNode(I));
-  auto BndlPtr = std::make_unique<SchedBundle>(std::move(Nodes));
-  auto *Bndl = BndlPtr.get();
-  Bndls[Bndl] = std::move(BndlPtr);
-  return Bndl;
-}
-
-void Scheduler::eraseBundle(SchedBundle *SB) { Bndls.erase(SB); }
-
-bool Scheduler::tryScheduleUntil(ArrayRef<Instruction *> Instrs) {
-  // Create a bundle for Instrs. If it turns out the schedule is infeasible we
-  // will dismantle it.
-  auto *InstrsSB = createBundle(Instrs);
-  // Keep scheduling ready nodes until we either run out of ready nodes (i.e.,
-  // ReadyList is empty), or all nodes that correspond to `Instrs` (the nodes of
-  // which are collected in DeferredNodes) are all ready to schedule.
-  SmallVector<DGNode *> Retry;
-  bool KeepScheduling = true;
-  while (KeepScheduling) {
-    enum class TryScheduleRes {
-      Success,  ///> We successfully scheduled the bundle.
-      Failure,  ///> We failed to schedule the bundle.
-      Finished, ///> We successfully scheduled the bundle and it is the last
-                /// bundle to be scheduled.
-    };
-    /// TryScheduleNode() attempts to schedule all DAG nodes in the bundle that
-    /// ReadyN is in. If it's not in a bundle it will create a singleton bundle
-    /// and will try to schedule it.
-    auto TryScheduleBndl = [this, InstrsSB](DGNode *ReadyN) -> TryScheduleRes {
-      auto *SB = ReadyN->getSchedBundle();
-      if (SB == nullptr) {
-        // If ReadyN does not belong to a bundle, create a singleton bundle
-        // and schedule it.
-        auto *SingletonSB = createBundle({ReadyN->getInstruction()});
-        scheduleAndUpdateReadyList(*SingletonSB);
-        return TryScheduleRes::Success;
-      }
-      if (SB->ready()) {
-        // Remove the rest of the bundle from the ready list.
-        // TODO: Perhaps change the Scheduler + ReadyList to operate on
-        // SchedBundles instead of DGNodes.
-        for (auto *N : *SB) {
-          if (N != ReadyN)
-            ReadyList.remove(N);
-        }
-        // If all nodes in the bundle are ready.
-        scheduleAndUpdateReadyList(*SB);
-        if (SB == InstrsSB)
-          // We just scheduled InstrsSB bundle, so we are done scheduling.
-          return TryScheduleRes::Finished;
-        return TryScheduleRes::Success;
-      }
-      return TryScheduleRes::Failure;
-    };
-    while (!ReadyList.empty()) {
-      auto *ReadyN = ReadyList.pop();
-      auto Res = TryScheduleBndl(ReadyN);
-      switch (Res) {
-      case TryScheduleRes::Success:
-        // We successfully scheduled ReadyN, keep scheduling.
-        continue;
-      case TryScheduleRes::Failure:
-        // We failed to schedule ReadyN, defer it to later and keep scheduling
-        // other ready instructions.
-        Retry.push_back(ReadyN);
-        continue;
-      case TryScheduleRes::Finished:
-        // We successfully scheduled the instruction bundle, so we are done.
-        return true;
-      }
-      llvm_unreachable("Unhandled TrySchedule() result");
-    }
-    // Try to schedule nodes from the Retry list.
-    KeepScheduling = false;
-    for (auto *N : make_early_inc_range(Retry)) {
-      auto Res = TryScheduleBndl(N);
-      if (Res == TryScheduleRes::Success) {
-        Retry.erase(find(Retry, N));
-        KeepScheduling = true;
-      }
-    }
-  }
-
-  eraseBundle(InstrsSB);
-  return false;
-}
-
-Scheduler::BndlSchedState
-Scheduler::getBndlSchedState(ArrayRef<Instruction *> Instrs) const {
-  assert(!Instrs.empty() && "Expected non-empty bundle");
-  auto *N0 = DAG.getNode(Instrs[0]);
-  auto *SB0 = N0 != nullptr ? N0->getSchedBundle() : nullptr;
-  bool AllUnscheduled = SB0 == nullptr;
-  bool FullyScheduled = SB0 != nullptr && !SB0->isSingleton();
-  for (auto *I : drop_begin(Instrs)) {
-    auto *N = DAG.getNode(I);
-    auto *SB = N != nullptr ? N->getSchedBundle() : nullptr;
-    if (SB != nullptr) {
-      // We found a scheduled instr, so there is now way all are unscheduled.
-      AllUnscheduled = false;
-      if (SB->isSingleton()) {
-        // We found an instruction in a temporarily scheduled singleton. There
-        // is no way that all instructions are scheduled in the same bundle.
-        FullyScheduled = false;
-      }
-    }
-
-    if (SB != SB0) {
-      // Either one of SB, SB0 is null, or they are in different bundles, so
-      // Instrs are definitely not in the same vector bundle.
-      FullyScheduled = false;
-      // One of SB, SB0 are in a vector bundle and they differ.
-      if ((SB != nullptr && !SB->isSingleton()) ||
-          (SB0 != nullptr && !SB0->isSingleton()))
-        return BndlSchedState::AlreadyScheduled;
-    }
-  }
-  return AllUnscheduled   ? BndlSchedState::NoneScheduled
-         : FullyScheduled ? BndlSchedState::FullyScheduled
-                          : BndlSchedState::TemporarilyScheduled;
-}
-
-void Scheduler::trimSchedule(ArrayRef<Instruction *> Instrs) {
-  //                                |  Legend: N: DGNode
-  //  N <- DAGInterval.top()        |          B: SchedBundle
-  //  N                             |          *: Contains instruction in Instrs
-  //  B <- TopI (Top of schedule)   +-------------------------------------------
-  //  B
-  //  B *
-  //  B
-  //  B * <- LowestI (Lowest in Instrs)
-  //  B
-  //  N
-  //  N
-  //  N <- DAGInterval.bottom()
-  //
-  Instruction *TopI = &*ScheduleTopItOpt.value();
-  Instruction *LowestI = VecUtils::getLowest(Instrs);
-  // Destroy the singleton schedule bundles from LowestI all the way to the top.
-  for (auto *I = LowestI, *E = TopI->getPrevNode(); I != E;
-       I = I->getPrevNode()) {
-    auto *N = DAG.getNode(I);
-    if (N == nullptr)
-      continue;
-    auto *SB = N->getSchedBundle();
-    if (SB->isSingleton())
-      eraseBundle(SB);
-  }
-  // The DAG Nodes contain state like the number of UnscheduledSuccs and the
-  // Scheduled flag. We need to reset their state. We need to do this for all
-  // nodes from LowestI to the top of the schedule. DAG Nodes that are above the
-  // top of schedule that depend on nodes that got reset need to have their
-  // UnscheduledSuccs adjusted.
-  Interval<Instruction> ResetIntvl(TopI, LowestI);
-  for (Instruction &I : ResetIntvl) {
-    auto *N = DAG.getNode(&I);
-    N->resetScheduleState();
-    // Recompute UnscheduledSuccs for nodes not only in ResetIntvl but even for
-    // nodes above the top of schedule.
-    for (auto *PredN : N->preds(DAG))
-      PredN->incrUnscheduledSuccs();
-  }
-  // Refill the ready list by visiting all nodes from the top of DAG to LowestI.
-  ReadyList.clear();
-  Interval<Instruction> RefillIntvl(DAG.getInterval().top(), LowestI);
-  for (Instruction &I : RefillIntvl) {
-    auto *N = DAG.getNode(&I);
-    if (N->ready())
-      ReadyList.insert(N);
-  }
-}
-
-bool Scheduler::trySchedule(ArrayRef<Instruction *> Instrs) {
-  assert(all_of(drop_begin(Instrs),
-                [Instrs](Instruction *I) {
-                  return I->getParent() == (*Instrs.begin())->getParent();
-                }) &&
-         "Instrs not in the same BB, should have been rejected by Legality!");
-  // TODO: For now don't cross BBs.
-  if (!DAG.getInterval().empty()) {
-    auto *BB = DAG.getInterval().top()->getParent();
-    if (any_of(Instrs, [BB](auto *I) { return I->getParent() != BB; }))
-      return false;
-  }
-  if (ScheduledBB == nullptr)
-    ScheduledBB = Instrs[0]->getParent();
-  // We don't support crossing BBs for now.
-  if (any_of(Instrs,
-             [this](Instruction *I) { return I->getParent() != ScheduledBB; }))
-    return false;
-  auto SchedState = getBndlSchedState(Instrs);
-  switch (SchedState) {
-  case BndlSchedState::FullyScheduled:
-    // Nothing to do.
-    return true;
-  case BndlSchedState::AlreadyScheduled:
-    // Instructions are part of a different vector schedule, so we can't
-    // schedule \p Instrs in the same bundle (without destroying the existing
-    // schedule).
-    return false;
-  case BndlSchedState::TemporarilyScheduled:
-    // If one or more instrs are already scheduled we need to destroy the
-    // top-most part of the schedule that includes the instrs in the bundle and
-    // re-schedule.
-    DAG.extend(Instrs);
-    trimSchedule(Instrs);
-    ScheduleTopItOpt = std::next(VecUtils::getLowest(Instrs)->getIterator());
-    return tryScheduleUntil(Instrs);
-  case BndlSchedState::NoneScheduled: {
-    // TODO: Set the window of the DAG that we are interested in.
-    if (!ScheduleTopItOpt)
-      // We start scheduling at the bottom instr of Instrs.
-      ScheduleTopItOpt = std::next(VecUtils::getLowest(Instrs)->getIterator());
-    // Extend the DAG to include Instrs.
-    Interval<Instruction> Extension = DAG.extend(Instrs);
-    // Add nodes to ready list.
-    for (auto &I : Extension) {
-      auto *N = DAG.getNode(&I);
-      if (N->ready())
-        ReadyList.insert(N);
-    }
-    // Try schedule all nodes until we can schedule Instrs back-to-back.
-    return tryScheduleUntil(Instrs);
-  }
-  }
-  llvm_unreachable("Unhandled BndlSchedState enum");
-}
-
-#ifndef NDEBUG
-void Scheduler::dump(raw_ostream &OS) const {
-  OS << "ReadyList:\n";
-  ReadyList.dump(OS);
-  OS << "Top of schedule: ";
-  if (ScheduleTopItOpt)
-    OS << **ScheduleTopItOpt;
-  else
-    OS << "Empty";
-  OS << "\n";
-}
-void Scheduler::dump() const { dump(dbgs()); }
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SeedCollector.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SeedCollector.cpp
deleted file mode 100644
index e80dc04e15326..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/SeedCollector.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-//===- SeedCollector.cpp  -------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h"
-#include "llvm/Analysis/LoopAccessAnalysis.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/Type.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Debug.h"
-
-using namespace llvm;
-namespace llvm::sandboxir {
-
-static cl::opt<unsigned> SeedBundleSizeLimit(
-    "sbvec-seed-bundle-size-limit", cl::init(32), cl::Hidden,
-    cl::desc("Limit the size of the seed bundle to cap compilation time."));
-
-static cl::opt<unsigned> SeedGroupsLimit(
-    "sbvec-seed-groups-limit", cl::init(256), cl::Hidden,
-    cl::desc("Limit the number of collected seeds groups in a BB to "
-             "cap compilation time."));
-
-ArrayRef<Instruction *> SeedBundle::getSlice(unsigned StartIdx,
-                                             unsigned MaxVecRegBits,
-                                             bool ForcePowerOf2) {
-  // Use uint32_t here for compatibility with IsPowerOf2_32
-
-  // BitCount tracks the size of the working slice. From that we can tell
-  // when the working slice's size is a power-of-two and when it exceeds
-  // the legal size in MaxVecBits.
-  uint32_t BitCount = 0;
-  uint32_t NumElements = 0;
-  // Tracks the most recent slice where NumElements gave a power-of-2 BitCount
-  uint32_t NumElementsPowerOfTwo = 0;
-  uint32_t BitCountPowerOfTwo = 0;
-  // Can't start a slice with a used instruction.
-  assert(!isUsed(StartIdx) && "Expected unused at StartIdx");
-  for (Instruction *S : drop_begin(Seeds, StartIdx)) {
-    // Stop if this instruction is used. This needs to be done before
-    // getNumBits() because a "used" instruction may have been erased.
-    if (isUsed(StartIdx + NumElements))
-      break;
-    uint32_t InstBits = Utils::getNumBits(S);
-    // Stop if adding it puts the slice over the limit.
-    if (BitCount + InstBits > MaxVecRegBits)
-      break;
-    NumElements++;
-    BitCount += InstBits;
-    if (ForcePowerOf2 && isPowerOf2_32(BitCount)) {
-      NumElementsPowerOfTwo = NumElements;
-      BitCountPowerOfTwo = BitCount;
-    }
-  }
-  if (ForcePowerOf2) {
-    NumElements = NumElementsPowerOfTwo;
-    BitCount = BitCountPowerOfTwo;
-  }
-
-  // Return any non-empty slice
-  if (NumElements > 1) {
-    assert((!ForcePowerOf2 || isPowerOf2_32(BitCount)) &&
-           "Must be a power of two");
-    return ArrayRef<Instruction *>(&Seeds[StartIdx], NumElements);
-  }
-  return {};
-}
-
-template <typename LoadOrStoreT>
-SeedContainer::KeyT SeedContainer::getKey(LoadOrStoreT *LSI,
-                                          bool AllowDiffTypes) const {
-  assert((isa<LoadInst>(LSI) || isa<StoreInst>(LSI)) &&
-         "Expected Load or Store!");
-  Value *Ptr = Utils::getMemInstructionBase(LSI);
-  Instruction::Opcode Op = LSI->getOpcode();
-  Type *Ty;
-  if (AllowDiffTypes) {
-    Ty = nullptr;
-  } else {
-    Ty = Utils::getExpectedType(LSI);
-    if (auto *VTy = dyn_cast<VectorType>(Ty))
-      Ty = VTy->getElementType();
-  }
-  return {Ptr, Ty, Op};
-}
-
-// Explicit instantiations
-template SeedContainer::KeyT
-SeedContainer::getKey<LoadInst>(LoadInst *LSI, bool AllowDiffTypes) const;
-template SeedContainer::KeyT
-SeedContainer::getKey<StoreInst>(StoreInst *LSI, bool AllowDiffTypes) const;
-
-bool SeedContainer::erase(Instruction *I) {
-  assert((isa<LoadInst>(I) || isa<StoreInst>(I)) && "Expected Load or Store!");
-  auto It = SeedLookupMap.find(I);
-  if (It == SeedLookupMap.end())
-    return false;
-  SeedBundle *Bndl = It->second;
-  Bndl->setUsed(I);
-  return true;
-}
-
-template <typename LoadOrStoreT>
-void SeedContainer::insert(LoadOrStoreT *LSI, bool AllowDiffTypes) {
-  // Find the bundle containing seeds for this symbol and type-of-access.
-  auto &BundleVec = Bundles[getKey(LSI, AllowDiffTypes)];
-  // Fill this vector of bundles front to back so that only the last bundle in
-  // the vector may have available space. This avoids iteration to find one with
-  // space.
-  if (BundleVec.empty() || BundleVec.back()->size() == SeedBundleSizeLimit)
-    BundleVec.emplace_back(std::make_unique<MemSeedBundle<LoadOrStoreT>>(LSI));
-  else
-    BundleVec.back()->insert(LSI, SE);
-
-  SeedLookupMap[LSI] = BundleVec.back().get();
-}
-
-// Explicit instantiations
-template LLVM_EXPORT_TEMPLATE void SeedContainer::insert<LoadInst>(LoadInst *,
-                                                                   bool);
-template LLVM_EXPORT_TEMPLATE void SeedContainer::insert<StoreInst>(StoreInst *,
-                                                                    bool);
-
-#ifndef NDEBUG
-void SeedContainer::print(raw_ostream &OS) const {
-  for (const auto &Pair : Bundles) {
-    auto [I, Ty, Opc] = Pair.first;
-    const auto &SeedsVec = Pair.second;
-    std::string RefType = dyn_cast<LoadInst>(I)    ? "Load"
-                          : dyn_cast<StoreInst>(I) ? "Store"
-                                                   : "Other";
-    OS << "[Inst=" << *I << " Ty=" << Ty << " " << RefType << "]\n";
-    for (const auto &SeedPtr : SeedsVec) {
-      SeedPtr->dump(OS);
-      OS << "\n";
-    }
-  }
-  OS << "\n";
-}
-
-LLVM_DUMP_METHOD void SeedContainer::dump() const { print(dbgs()); }
-#endif // NDEBUG
-
-template <typename LoadOrStoreT> static bool isValidMemSeed(LoadOrStoreT *LSI) {
-  if (!LSI->isSimple())
-    return false;
-  auto *Ty = Utils::getExpectedType(LSI);
-  // Omit types that are architecturally unvectorizable
-  if (Ty->isX86_FP80Ty() || Ty->isPPC_FP128Ty())
-    return false;
-  // Omit vector types without compile-time-known lane counts
-  if (isa<ScalableVectorType>(Ty))
-    return false;
-  if (auto *VTy = dyn_cast<FixedVectorType>(Ty))
-    return VectorType::isValidElementType(VTy->getElementType());
-  return VectorType::isValidElementType(Ty);
-}
-
-template bool isValidMemSeed<LoadInst>(LoadInst *LSI);
-template bool isValidMemSeed<StoreInst>(StoreInst *LSI);
-
-SeedCollector::SeedCollector(BasicBlock *BB, ScalarEvolution &SE,
-                             bool CollectStores, bool CollectLoads,
-                             bool AllowDiffTypes)
-    : StoreSeeds(SE), LoadSeeds(SE), Ctx(BB->getContext()) {
-
-  if (!CollectStores && !CollectLoads)
-    return;
-
-  EraseCallbackID = Ctx.registerEraseInstrCallback([this](Instruction *I) {
-    if (auto SI = dyn_cast<StoreInst>(I))
-      StoreSeeds.erase(SI);
-    else if (auto LI = dyn_cast<LoadInst>(I))
-      LoadSeeds.erase(LI);
-  });
-
-  // Actually collect the seeds.
-  for (auto &I : *BB) {
-    if (StoreInst *SI = dyn_cast<StoreInst>(&I))
-      if (CollectStores && isValidMemSeed(SI))
-        StoreSeeds.insert(SI, AllowDiffTypes);
-    if (LoadInst *LI = dyn_cast<LoadInst>(&I))
-      if (CollectLoads && isValidMemSeed(LI))
-        LoadSeeds.insert(LI, AllowDiffTypes);
-    // Cap compilation time.
-    if (totalNumSeedGroups() > SeedGroupsLimit)
-      break;
-  }
-}
-
-SeedCollector::~SeedCollector() {
-  Ctx.unregisterEraseInstrCallback(EraseCallbackID);
-}
-
-#ifndef NDEBUG
-void SeedCollector::print(raw_ostream &OS) const {
-  OS << "=== StoreSeeds ===\n";
-  StoreSeeds.print(OS);
-  OS << "=== LoadSeeds ===\n";
-  LoadSeeds.print(OS);
-}
-
-void SeedCollector::dump() const { print(dbgs()); }
-#endif
-
-} // namespace llvm::sandboxir
diff --git a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp b/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
deleted file mode 100644
index 6f9ef07e467d2..0000000000000
--- a/llvm/lib/Transforms/Vectorize/SandboxVectorizer/VecUtils.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//===- VecUtils.cpp -------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-
-namespace llvm::sandboxir {
-
-unsigned VecUtils::getFloorPowerOf2(unsigned Num) {
-  if (Num == 0)
-    return Num;
-  unsigned Mask = Num;
-  Mask >>= 1;
-  for (unsigned ShiftBy = 1; ShiftBy < sizeof(Num) * 8; ShiftBy <<= 1)
-    Mask |= Mask >> ShiftBy;
-  return Num & ~Mask;
-}
-
-#ifndef NDEBUG
-template <typename T> static void dumpImpl(ArrayRef<T *> Bndl) {
-  for (auto [Idx, V] : enumerate(Bndl))
-    dbgs() << Idx << "." << *V << "\n";
-}
-void VecUtils::dump(ArrayRef<Value *> Bndl) { dumpImpl(Bndl); }
-void VecUtils::dump(ArrayRef<Instruction *> Bndl) { dumpImpl(Bndl); }
-#endif // NDEBUG
-
-} // namespace llvm::sandboxir
diff --git a/llvm/test/Transforms/SandboxVectorizer/X86/lit.local.cfg b/llvm/test/Transforms/SandboxVectorizer/X86/lit.local.cfg
deleted file mode 100644
index 42bf50dcc13c3..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/X86/lit.local.cfg
+++ /dev/null
@@ -1,2 +0,0 @@
-if not "X86" in config.root.targets:
-    config.unsupported = True
diff --git a/llvm/test/Transforms/SandboxVectorizer/X86/no_implicit_float.ll b/llvm/test/Transforms/SandboxVectorizer/X86/no_implicit_float.ll
deleted file mode 100644
index 37fc03cb31166..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/X86/no_implicit_float.ll
+++ /dev/null
@@ -1,23 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -mtriple=x86_64-- -mattr=+avx %s -S | FileCheck %s
-
-; Check that we don't vectorize a NoImplicitFloat function.
-define void @no_implicit_float(ptr %ptr) noimplicitfloat {
-; CHECK-LABEL: define void @no_implicit_float(
-; CHECK-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr double, ptr [[PTR]], i32 1
-; CHECK-NEXT:    [[LD0:%.*]] = load double, ptr [[PTR0]], align 8
-; CHECK-NEXT:    [[LD1:%.*]] = load double, ptr [[PTR1]], align 8
-; CHECK-NEXT:    store double [[LD0]], ptr [[PTR0]], align 8
-; CHECK-NEXT:    store double [[LD1]], ptr [[PTR1]], align 8
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr double, ptr %ptr, i32 0
-  %ptr1 = getelementptr double, ptr %ptr, i32 1
-  %ld0 = load double, ptr %ptr0
-  %ld1 = load double, ptr %ptr1
-  store double %ld0, ptr %ptr0
-  store double %ld1, ptr %ptr1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll b/llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll
deleted file mode 100644
index f1df52bd88ad7..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/X86/simple_cost_test.ll
+++ /dev/null
@@ -1,91 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -mtriple=x86_64-- -mattr=+sse4.1 %s -S -sbvec-cost-threshold=0 | FileCheck %s --check-prefix=THRESHOLD_0
-; RUN: opt -passes=sandbox-vectorizer -mtriple=x86_64-- -mattr=+sse4.1 %s -S -sbvec-cost-threshold=99 | FileCheck %s --check-prefix=THRESHOLD_99
-
-define void @simple_cost_test(ptr %ptr) {
-; THRESHOLD_0-LABEL: define void @simple_cost_test(
-; THRESHOLD_0-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
-; THRESHOLD_0-NEXT:    [[PTR0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
-; THRESHOLD_0-NEXT:    [[VECL:%.*]] = load <2 x double>, ptr [[PTR0]], align 8, !sandboxvec [[META0:![0-9]+]]
-; THRESHOLD_0-NEXT:    store <2 x double> [[VECL]], ptr [[PTR0]], align 8, !sandboxvec [[META0]]
-; THRESHOLD_0-NEXT:    ret void
-;
-; THRESHOLD_99-LABEL: define void @simple_cost_test(
-; THRESHOLD_99-SAME: ptr [[PTR:%.*]]) #[[ATTR0:[0-9]+]] {
-; THRESHOLD_99-NEXT:    [[PTR0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
-; THRESHOLD_99-NEXT:    [[PTR1:%.*]] = getelementptr double, ptr [[PTR]], i32 1, !sandboxvec [[META0:![0-9]+]]
-; THRESHOLD_99-NEXT:    [[LD0:%.*]] = load double, ptr [[PTR0]], align 8, !sandboxvec [[META0]]
-; THRESHOLD_99-NEXT:    [[LD1:%.*]] = load double, ptr [[PTR1]], align 8, !sandboxvec [[META0]]
-; THRESHOLD_99-NEXT:    store double [[LD0]], ptr [[PTR0]], align 8, !sandboxvec [[META0]]
-; THRESHOLD_99-NEXT:    store double [[LD1]], ptr [[PTR1]], align 8, !sandboxvec [[META0]]
-; THRESHOLD_99-NEXT:    ret void
-;
-  %ptr0 = getelementptr double, ptr %ptr, i32 0
-  %ptr1 = getelementptr double, ptr %ptr, i32 1
-  %ld0 = load double, ptr %ptr0
-  %ld1 = load double, ptr %ptr1
-  store double %ld0, ptr %ptr0
-  store double %ld1, ptr %ptr1
-  ret void
-}
-
-define void @pack_cost_test_(ptr %ptr) {
-; THRESHOLD_0-LABEL: define void @pack_cost_test_(
-; THRESHOLD_0-SAME: ptr [[PTR:%.*]]) #[[ATTR0]] {
-; THRESHOLD_0-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; THRESHOLD_0-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; THRESHOLD_0-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; THRESHOLD_0-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; THRESHOLD_0-NEXT:    [[PACK4:%.*]] = insertelement <4 x float> poison, float [[LD0]], i32 0, !sandboxvec [[META1:![0-9]+]]
-; THRESHOLD_0-NEXT:    [[PACK5:%.*]] = insertelement <4 x float> [[PACK4]], float [[LD1]], i32 1, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[PACK6:%.*]] = insertelement <4 x float> [[PACK5]], float [[LD0]], i32 2, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[PACK7:%.*]] = insertelement <4 x float> [[PACK6]], float [[LD1]], i32 3, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[PACK:%.*]] = insertelement <4 x float> poison, float [[LD0]], i32 0, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[PACK1:%.*]] = insertelement <4 x float> [[PACK]], float [[LD1]], i32 1, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[PACK2:%.*]] = insertelement <4 x float> [[PACK1]], float [[LD0]], i32 2, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[PACK3:%.*]] = insertelement <4 x float> [[PACK2]], float [[LD1]], i32 3, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    [[VEC:%.*]] = fmul <4 x float> [[PACK3]], [[PACK7]], !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    store <4 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META1]]
-; THRESHOLD_0-NEXT:    ret void
-;
-; THRESHOLD_99-LABEL: define void @pack_cost_test_(
-; THRESHOLD_99-SAME: ptr [[PTR:%.*]]) #[[ATTR0]] {
-; THRESHOLD_99-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; THRESHOLD_99-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; THRESHOLD_99-NEXT:    [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2, !sandboxvec [[META1:![0-9]+]]
-; THRESHOLD_99-NEXT:    [[PTR3:%.*]] = getelementptr float, ptr [[PTR]], i32 3, !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; THRESHOLD_99-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; THRESHOLD_99-NEXT:    [[MUL0:%.*]] = fmul float [[LD0]], [[LD0]], !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    [[MUL1:%.*]] = fmul float [[LD1]], [[LD1]], !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    [[MUL2:%.*]] = fmul float [[LD0]], [[LD0]], !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    [[MUL3:%.*]] = fmul float [[LD1]], [[LD1]], !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    store float [[MUL0]], ptr [[PTR0]], align 4, !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    store float [[MUL1]], ptr [[PTR1]], align 4, !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    store float [[MUL2]], ptr [[PTR2]], align 4, !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    store float [[MUL3]], ptr [[PTR3]], align 4, !sandboxvec [[META1]]
-; THRESHOLD_99-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptr2 = getelementptr float, ptr %ptr, i32 2
-  %ptr3 = getelementptr float, ptr %ptr, i32 3
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %mul0 = fmul float %ld0, %ld0
-  %mul1 = fmul float %ld1, %ld1
-  %mul2 = fmul float %ld0, %ld0
-  %mul3 = fmul float %ld1, %ld1
-  store float %mul0, ptr %ptr0
-  store float %mul1, ptr %ptr1
-  store float %mul2, ptr %ptr2
-  store float %mul3, ptr %ptr3
-  ret void
-}
-;.
-; THRESHOLD_0: [[META0]] = distinct !{!"sandboxregion"}
-; THRESHOLD_0: [[META1]] = distinct !{!"sandboxregion"}
-;.
-; THRESHOLD_99: [[META0]] = distinct !{!"sandboxregion"}
-; THRESHOLD_99: [[META1]] = distinct !{!"sandboxregion"}
-;.
diff --git a/llvm/test/Transforms/SandboxVectorizer/allow_files.ll b/llvm/test/Transforms/SandboxVectorizer/allow_files.ll
deleted file mode 100644
index 0929eca6a1047..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/allow_files.ll
+++ /dev/null
@@ -1,39 +0,0 @@
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="some_other_file" %s -S | FileCheck %s --check-prefix=ALLOW_OTHER
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="allow_files.ll" %s -S | FileCheck %s --check-prefix=ALLOW_THIS
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="al.*_files.ll" %s -S | FileCheck %s --check-prefix=ALLOW_REGEX
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="some_file,.*_files.ll,some_other_file" %s -S | FileCheck %s --check-prefix=ALLOW_REGEX_CSV
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="allow" %s -S | FileCheck %s --check-prefix=ALLOW_BAD_REGEX
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="some_file,some_other_file1,some_other_file2" %s -S | FileCheck %s --check-prefix=ALLOW_OTHER_CSV
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-allow-files="" %s -S | FileCheck %s --check-prefix=ALLOW_EMPTY
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s --check-prefix=DEFAULT
-
-; Checks the command-line option `-sbvec-allow-files`.
-define void @widen(ptr %ptr) {
-; ALLOW_OTHER:     store float {{%.*}}, ptr {{%.*}}, align 4
-; ALLOW_OTHER:     store float {{%.*}}, ptr {{%.*}}, align 4
-;
-; ALLOW_THIS:      store <2 x float> {{%.*}}, ptr {{%.*}}, align 4
-;
-; ALLOW_REGEX:     store <2 x float> {{%.*}}, ptr {{%.*}}, align 4
-;
-; ALLOW_REGEX_CSV: store <2 x float> {{%.*}}, ptr {{%.*}}, align 4
-;
-; ALLOW_BAD_REGEX: store float {{%.*}}, ptr {{%.*}}, align 4
-; ALLOW_BAD_REGEX: store float {{%.*}}, ptr {{%.*}}, align 4
-;
-; ALLOW_OTHER_CSV: store float {{%.*}}, ptr {{%.*}}, align 4
-; ALLOW_OTHER_CSV: store float {{%.*}}, ptr {{%.*}}, align 4
-;
-; ALLOW_EMPTY:     store float {{%.*}}, ptr {{%.*}}, align 4
-; ALLOW_EMPTY:     store float {{%.*}}, ptr {{%.*}}, align 4
-;
-; DEFAULT:         store <2 x float> {{%.*}}, ptr {{%.*}}, align 4
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  store float %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/boilerplate.ll b/llvm/test/Transforms/SandboxVectorizer/boilerplate.ll
deleted file mode 100644
index 353659d41485f..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/boilerplate.ll
+++ /dev/null
@@ -1,11 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer %s -S | FileCheck %s
-
-; This test checks that the pass was registered with the pass manager.
-; TODO: Remove this test once actual tests land.
-define void @boilerplate() {
-; CHECK-LABEL: define void @boilerplate() {
-; CHECK-NEXT:    ret void
-;
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
deleted file mode 100644
index 76dd3694b71b5..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_basic.ll
+++ /dev/null
@@ -1,743 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-revert>" %s -S | FileCheck %s --check-prefix REVERT
-
-define void @store_load(ptr %ptr) {
-; CHECK-LABEL: define void @store_load(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META0:![0-9]+]]
-; CHECK-NEXT:    store <2 x float> [[VECL]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @store_load(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META0:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META0]]
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META0]]
-; REVERT-NEXT:    store float [[LD0]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
-; REVERT-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META0]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  store float %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  ret void
-}
-
-
-define void @store_fpext_load(ptr %ptr) {
-; CHECK-LABEL: define void @store_fpext_load(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META1:![0-9]+]]
-; CHECK-NEXT:    [[VCAST:%.*]] = fpext <2 x float> [[VECL]] to <2 x double>, !sandboxvec [[META1]]
-; CHECK-NEXT:    store <2 x double> [[VCAST]], ptr [[PTRD0]], align 8, !sandboxvec [[META1]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @store_fpext_load(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META1:![0-9]+]]
-; REVERT-NEXT:    [[PTRD0:%.*]] = getelementptr double, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTRD1:%.*]] = getelementptr double, ptr [[PTR]], i32 1, !sandboxvec [[META1]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META1]]
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META1]]
-; REVERT-NEXT:    [[FPEXT0:%.*]] = fpext float [[LD0]] to double, !sandboxvec [[META1]]
-; REVERT-NEXT:    [[FPEXT1:%.*]] = fpext float [[LD1]] to double, !sandboxvec [[META1]]
-; REVERT-NEXT:    store double [[FPEXT0]], ptr [[PTRD0]], align 8, !sandboxvec [[META1]]
-; REVERT-NEXT:    store double [[FPEXT1]], ptr [[PTRD1]], align 8, !sandboxvec [[META1]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptrd0 = getelementptr double, ptr %ptr, i32 0
-  %ptrd1 = getelementptr double, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %fpext0 = fpext float %ld0 to double
-  %fpext1 = fpext float %ld1 to double
-  store double %fpext0, ptr %ptrd0
-  store double %fpext1, ptr %ptrd1
-  ret void
-}
-
-define void @store_fcmp_zext_load(ptr %ptr) {
-; CHECK-LABEL: define void @store_fcmp_zext_load(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META2:![0-9]+]]
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META2]]
-; CHECK-NEXT:    [[VCMP:%.*]] = fcmp ogt <2 x float> [[VECL]], [[VECL1]], !sandboxvec [[META2]]
-; CHECK-NEXT:    [[VCAST:%.*]] = zext <2 x i1> [[VCMP]] to <2 x i32>, !sandboxvec [[META2]]
-; CHECK-NEXT:    store <2 x i32> [[VCAST]], ptr [[PTRB0]], align 4, !sandboxvec [[META2]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @store_fcmp_zext_load(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META2:![0-9]+]]
-; REVERT-NEXT:    [[PTRB0:%.*]] = getelementptr i32, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTRB1:%.*]] = getelementptr i32, ptr [[PTR]], i32 1, !sandboxvec [[META2]]
-; REVERT-NEXT:    [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META2]]
-; REVERT-NEXT:    [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META2]]
-; REVERT-NEXT:    [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META2]]
-; REVERT-NEXT:    [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META2]]
-; REVERT-NEXT:    [[FCMP0:%.*]] = fcmp ogt float [[LDA0]], [[LDB0]], !sandboxvec [[META2]]
-; REVERT-NEXT:    [[FCMP1:%.*]] = fcmp ogt float [[LDA1]], [[LDB1]], !sandboxvec [[META2]]
-; REVERT-NEXT:    [[ZEXT0:%.*]] = zext i1 [[FCMP0]] to i32, !sandboxvec [[META2]]
-; REVERT-NEXT:    [[ZEXT1:%.*]] = zext i1 [[FCMP1]] to i32, !sandboxvec [[META2]]
-; REVERT-NEXT:    store i32 [[ZEXT0]], ptr [[PTRB0]], align 4, !sandboxvec [[META2]]
-; REVERT-NEXT:    store i32 [[ZEXT1]], ptr [[PTRB1]], align 4, !sandboxvec [[META2]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptrb0 = getelementptr i32, ptr %ptr, i32 0
-  %ptrb1 = getelementptr i32, ptr %ptr, i32 1
-  %ldB0 = load float, ptr %ptr0
-  %ldB1 = load float, ptr %ptr1
-  %ldA0 = load float, ptr %ptr0
-  %ldA1 = load float, ptr %ptr1
-  %fcmp0 = fcmp ogt float %ldA0, %ldB0
-  %fcmp1 = fcmp ogt float %ldA1, %ldB1
-  %zext0 = zext i1 %fcmp0 to i32
-  %zext1 = zext i1 %fcmp1 to i32
-  store i32 %zext0, ptr %ptrb0
-  store i32 %zext1, ptr %ptrb1
-  ret void
-}
-
-define void @store_fadd_load(ptr %ptr) {
-; CHECK-LABEL: define void @store_fadd_load(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL1:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META3:![0-9]+]]
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META3]]
-; CHECK-NEXT:    [[VEC:%.*]] = fadd <2 x float> [[VECL]], [[VECL1]], !sandboxvec [[META3]]
-; CHECK-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META3]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @store_fadd_load(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META3:![0-9]+]]
-; REVERT-NEXT:    [[LDA0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META3]]
-; REVERT-NEXT:    [[LDA1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META3]]
-; REVERT-NEXT:    [[LDB0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META3]]
-; REVERT-NEXT:    [[LDB1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META3]]
-; REVERT-NEXT:    [[FADD0:%.*]] = fadd float [[LDA0]], [[LDB0]], !sandboxvec [[META3]]
-; REVERT-NEXT:    [[FADD1:%.*]] = fadd float [[LDA1]], [[LDB1]], !sandboxvec [[META3]]
-; REVERT-NEXT:    store float [[FADD0]], ptr [[PTR0]], align 4, !sandboxvec [[META3]]
-; REVERT-NEXT:    store float [[FADD1]], ptr [[PTR1]], align 4, !sandboxvec [[META3]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ldA0 = load float, ptr %ptr0
-  %ldA1 = load float, ptr %ptr1
-  %ldB0 = load float, ptr %ptr0
-  %ldB1 = load float, ptr %ptr1
-  %fadd0 = fadd float %ldA0, %ldB0
-  %fadd1 = fadd float %ldA1, %ldB1
-  store float %fadd0, ptr %ptr0
-  store float %fadd1, ptr %ptr1
-  ret void
-}
-
-define void @store_fneg_load(ptr %ptr) {
-; CHECK-LABEL: define void @store_fneg_load(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META4:![0-9]+]]
-; CHECK-NEXT:    [[VEC:%.*]] = fneg <2 x float> [[VECL]], !sandboxvec [[META4]]
-; CHECK-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META4]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @store_fneg_load(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META4:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META4]]
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META4]]
-; REVERT-NEXT:    [[FNEG0:%.*]] = fneg float [[LD0]], !sandboxvec [[META4]]
-; REVERT-NEXT:    [[FNEG1:%.*]] = fneg float [[LD1]], !sandboxvec [[META4]]
-; REVERT-NEXT:    store float [[FNEG0]], ptr [[PTR0]], align 4, !sandboxvec [[META4]]
-; REVERT-NEXT:    store float [[FNEG1]], ptr [[PTR1]], align 4, !sandboxvec [[META4]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %fneg0 = fneg float %ld0
-  %fneg1 = fneg float %ld1
-  store float %fneg0, ptr %ptr0
-  store float %fneg1, ptr %ptr1
-  ret void
-}
-
-define float @scalars_with_external_uses_not_dead(ptr %ptr) {
-; CHECK-LABEL: define float @scalars_with_external_uses_not_dead(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; CHECK-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META5:![0-9]+]]
-; CHECK-NEXT:    store <2 x float> [[VECL]], ptr [[PTR0]], align 4, !sandboxvec [[META5]]
-; CHECK-NEXT:    [[USER:%.*]] = fneg float [[LD1]]
-; CHECK-NEXT:    ret float [[LD0]]
-;
-; REVERT-LABEL: define float @scalars_with_external_uses_not_dead(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; REVERT-NEXT:    store float [[LD0]], ptr [[PTR0]], align 4, !sandboxvec [[META5:![0-9]+]]
-; REVERT-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META5]]
-; REVERT-NEXT:    [[USER:%.*]] = fneg float [[LD1]]
-; REVERT-NEXT:    ret float [[LD0]]
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  store float %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  %user = fneg float %ld1
-  ret float %ld0
-}
-
-define void @pack_scalars(ptr %ptr, ptr %ptr2) {
-; CHECK-LABEL: define void @pack_scalars(
-; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <2 x float> poison, float [[LD0]], i32 0, !sandboxvec [[META6:![0-9]+]]
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <2 x float> [[PACK]], float [[LD1]], i32 1, !sandboxvec [[META6]]
-; CHECK-NEXT:    store <2 x float> [[PACK1]], ptr [[PTR0]], align 4, !sandboxvec [[META6]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @pack_scalars(
-; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META6:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
-; REVERT-NEXT:    store float [[LD0]], ptr [[PTR0]], align 4, !sandboxvec [[META6]]
-; REVERT-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META6]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr2
-  store float %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  ret void
-}
-
-declare void @foo()
-define void @cant_vectorize_seeds(ptr %ptr) {
-; CHECK-LABEL: define void @cant_vectorize_seeds(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; CHECK-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; CHECK-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; CHECK-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @cant_vectorize_seeds(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; REVERT-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4
-; REVERT-NEXT:    call void @foo()
-; REVERT-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  store float %ld1, ptr %ptr1
-  call void @foo() ; This call blocks scheduling of the store seeds.
-  store float %ld1, ptr %ptr1
-  ret void
-}
-
-define void @pack_vectors(ptr %ptr, ptr %ptr2) {
-; CHECK-LABEL: define void @pack_vectors(
-; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8
-; CHECK-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
-; CHECK-NEXT:    [[VPACK:%.*]] = extractelement <2 x float> [[LD0]], i32 0, !sandboxvec [[META7:![0-9]+]]
-; CHECK-NEXT:    [[VPACK1:%.*]] = insertelement <3 x float> poison, float [[VPACK]], i32 0, !sandboxvec [[META7]]
-; CHECK-NEXT:    [[VPACK2:%.*]] = extractelement <2 x float> [[LD0]], i32 1, !sandboxvec [[META7]]
-; CHECK-NEXT:    [[VPACK3:%.*]] = insertelement <3 x float> [[VPACK1]], float [[VPACK2]], i32 1, !sandboxvec [[META7]]
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <3 x float> [[VPACK3]], float [[LD1]], i32 2, !sandboxvec [[META7]]
-; CHECK-NEXT:    store <3 x float> [[PACK]], ptr [[PTR0]], align 8, !sandboxvec [[META7]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @pack_vectors(
-; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTR2:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 2, !sandboxvec [[META7:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR2]], align 4
-; REVERT-NEXT:    store <2 x float> [[LD0]], ptr [[PTR0]], align 8, !sandboxvec [[META7]]
-; REVERT-NEXT:    store float [[LD1]], ptr [[PTR1]], align 4, !sandboxvec [[META7]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 2
-  %ld0 = load <2 x float>, ptr %ptr0
-  %ld1 = load float, ptr %ptr2
-  store <2 x float> %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  ret void
-}
-
-define void @diamond(ptr %ptr) {
-; CHECK-LABEL: define void @diamond(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META8:![0-9]+]]
-; CHECK-NEXT:    [[VEC:%.*]] = fsub <2 x float> [[VECL]], [[VECL]], !sandboxvec [[META8]]
-; CHECK-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META8]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @diamond(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META8:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META8]]
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META8]]
-; REVERT-NEXT:    [[SUB0:%.*]] = fsub float [[LD0]], [[LD0]], !sandboxvec [[META8]]
-; REVERT-NEXT:    [[SUB1:%.*]] = fsub float [[LD1]], [[LD1]], !sandboxvec [[META8]]
-; REVERT-NEXT:    store float [[SUB0]], ptr [[PTR0]], align 4, !sandboxvec [[META8]]
-; REVERT-NEXT:    store float [[SUB1]], ptr [[PTR1]], align 4, !sandboxvec [[META8]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %sub0 = fsub float %ld0, %ld0
-  %sub1 = fsub float %ld1, %ld1
-  store float %sub0, ptr %ptr0
-  store float %sub1, ptr %ptr1
-  ret void
-}
-
-define void @diamondWithShuffle(ptr %ptr) {
-; CHECK-LABEL: define void @diamondWithShuffle(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META9:![0-9]+]]
-; CHECK-NEXT:    [[VSHUF:%.*]] = shufflevector <2 x float> [[VECL]], <2 x float> [[VECL]], <2 x i32> <i32 1, i32 0>, !sandboxvec [[META9]]
-; CHECK-NEXT:    [[VEC:%.*]] = fsub <2 x float> [[VECL]], [[VSHUF]], !sandboxvec [[META9]]
-; CHECK-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META9]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @diamondWithShuffle(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META9:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META9]]
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META9]]
-; REVERT-NEXT:    [[SUB0:%.*]] = fsub float [[LD0]], [[LD1]], !sandboxvec [[META9]]
-; REVERT-NEXT:    [[SUB1:%.*]] = fsub float [[LD1]], [[LD0]], !sandboxvec [[META9]]
-; REVERT-NEXT:    store float [[SUB0]], ptr [[PTR0]], align 4, !sandboxvec [[META9]]
-; REVERT-NEXT:    store float [[SUB1]], ptr [[PTR1]], align 4, !sandboxvec [[META9]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %sub0 = fsub float %ld0, %ld1
-  %sub1 = fsub float %ld1, %ld0
-  store float %sub0, ptr %ptr0
-  store float %sub1, ptr %ptr1
-  ret void
-}
-
-; Same but with <2 x float> elements instead of scalars.
-define void @diamondWithShuffleFromVec(ptr %ptr) {
-; CHECK-LABEL: define void @diamondWithShuffleFromVec(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <4 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META10:![0-9]+]]
-; CHECK-NEXT:    [[VSHUF:%.*]] = shufflevector <4 x float> [[VECL]], <4 x float> [[VECL]], <4 x i32> <i32 2, i32 3, i32 0, i32 1>, !sandboxvec [[META10]]
-; CHECK-NEXT:    [[VEC:%.*]] = fsub <4 x float> [[VECL]], [[VSHUF]], !sandboxvec [[META10]]
-; CHECK-NEXT:    store <4 x float> [[VEC]], ptr [[PTR0]], align 8, !sandboxvec [[META10]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @diamondWithShuffleFromVec(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 1, !sandboxvec [[META10:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META10]]
-; REVERT-NEXT:    [[LD1:%.*]] = load <2 x float>, ptr [[PTR1]], align 8, !sandboxvec [[META10]]
-; REVERT-NEXT:    [[SUB0:%.*]] = fsub <2 x float> [[LD0]], [[LD1]], !sandboxvec [[META10]]
-; REVERT-NEXT:    [[SUB1:%.*]] = fsub <2 x float> [[LD1]], [[LD0]], !sandboxvec [[META10]]
-; REVERT-NEXT:    store <2 x float> [[SUB0]], ptr [[PTR0]], align 8, !sandboxvec [[META10]]
-; REVERT-NEXT:    store <2 x float> [[SUB1]], ptr [[PTR1]], align 8, !sandboxvec [[META10]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
-  %ptr1 = getelementptr <2 x float>, ptr %ptr, i32 1
-  %ld0 = load <2 x float>, ptr %ptr0
-  %ld1 = load <2 x float>, ptr %ptr1
-  %sub0 = fsub <2 x float> %ld0, %ld1
-  %sub1 = fsub <2 x float> %ld1, %ld0
-  store <2 x float> %sub0, ptr %ptr0
-  store <2 x float> %sub1, ptr %ptr1
-  ret void
-}
-
-define void @diamondMultiInput(ptr %ptr, ptr %ptrX) {
-; CHECK-LABEL: define void @diamondMultiInput(
-; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[LDX:%.*]] = load float, ptr [[PTRX]], align 4
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4, !sandboxvec [[META11:![0-9]+]]
-; CHECK-NEXT:    [[VINS:%.*]] = insertelement <2 x float> poison, float [[LDX]], i32 0, !sandboxvec [[META11]]
-; CHECK-NEXT:    [[VEXT:%.*]] = extractelement <2 x float> [[VECL]], i32 0, !sandboxvec [[META11]]
-; CHECK-NEXT:    [[VINS1:%.*]] = insertelement <2 x float> [[VINS]], float [[VEXT]], i32 1, !sandboxvec [[META11]]
-; CHECK-NEXT:    [[VEC:%.*]] = fsub <2 x float> [[VECL]], [[VINS1]], !sandboxvec [[META11]]
-; CHECK-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META11]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @diamondMultiInput(
-; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1, !sandboxvec [[META11:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4, !sandboxvec [[META11]]
-; REVERT-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4, !sandboxvec [[META11]]
-; REVERT-NEXT:    [[LDX:%.*]] = load float, ptr [[PTRX]], align 4
-; REVERT-NEXT:    [[SUB0:%.*]] = fsub float [[LD0]], [[LDX]], !sandboxvec [[META11]]
-; REVERT-NEXT:    [[SUB1:%.*]] = fsub float [[LD1]], [[LD0]], !sandboxvec [[META11]]
-; REVERT-NEXT:    store float [[SUB0]], ptr [[PTR0]], align 4, !sandboxvec [[META11]]
-; REVERT-NEXT:    store float [[SUB1]], ptr [[PTR1]], align 4, !sandboxvec [[META11]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-
-  %ldX = load float, ptr %ptrX
-
-  %sub0 = fsub float %ld0, %ldX
-  %sub1 = fsub float %ld1, %ld0
-  store float %sub0, ptr %ptr0
-  store float %sub1, ptr %ptr1
-  ret void
-}
-
-; Same but vectorizing <2 x float> vectors instead of scalars.
-define void @diamondMultiInputVector(ptr %ptr, ptr %ptrX) {
-; CHECK-LABEL: define void @diamondMultiInputVector(
-; CHECK-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[LDX:%.*]] = load <2 x float>, ptr [[PTRX]], align 8
-; CHECK-NEXT:    [[VECL:%.*]] = load <4 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META12:![0-9]+]]
-; CHECK-NEXT:    [[VEXT:%.*]] = extractelement <2 x float> [[LDX]], i32 0, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VINS:%.*]] = insertelement <4 x float> poison, float [[VEXT]], i32 0, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VEXT1:%.*]] = extractelement <2 x float> [[LDX]], i32 1, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VINS2:%.*]] = insertelement <4 x float> [[VINS]], float [[VEXT1]], i32 1, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VEXT3:%.*]] = extractelement <4 x float> [[VECL]], i32 0, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VINS4:%.*]] = insertelement <4 x float> [[VINS2]], float [[VEXT3]], i32 2, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VEXT5:%.*]] = extractelement <4 x float> [[VECL]], i32 1, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VINS6:%.*]] = insertelement <4 x float> [[VINS4]], float [[VEXT5]], i32 3, !sandboxvec [[META12]]
-; CHECK-NEXT:    [[VEC:%.*]] = fsub <4 x float> [[VECL]], [[VINS6]], !sandboxvec [[META12]]
-; CHECK-NEXT:    store <4 x float> [[VEC]], ptr [[PTR0]], align 8, !sandboxvec [[META12]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @diamondMultiInputVector(
-; REVERT-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr <2 x float>, ptr [[PTR]], i32 1, !sandboxvec [[META12:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load <2 x float>, ptr [[PTR0]], align 8, !sandboxvec [[META12]]
-; REVERT-NEXT:    [[LD1:%.*]] = load <2 x float>, ptr [[PTR1]], align 8, !sandboxvec [[META12]]
-; REVERT-NEXT:    [[LDX:%.*]] = load <2 x float>, ptr [[PTRX]], align 8
-; REVERT-NEXT:    [[SUB0:%.*]] = fsub <2 x float> [[LD0]], [[LDX]], !sandboxvec [[META12]]
-; REVERT-NEXT:    [[SUB1:%.*]] = fsub <2 x float> [[LD1]], [[LD0]], !sandboxvec [[META12]]
-; REVERT-NEXT:    store <2 x float> [[SUB0]], ptr [[PTR0]], align 8, !sandboxvec [[META12]]
-; REVERT-NEXT:    store <2 x float> [[SUB1]], ptr [[PTR1]], align 8, !sandboxvec [[META12]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x float>, ptr %ptr, i32 0
-  %ptr1 = getelementptr <2 x float>, ptr %ptr, i32 1
-  %ld0 = load <2 x float>, ptr %ptr0
-  %ld1 = load <2 x float>, ptr %ptr1
-
-  %ldX = load <2 x float>, ptr %ptrX
-
-  %sub0 = fsub <2 x float> %ld0, %ldX
-  %sub1 = fsub <2 x float> %ld1, %ld0
-  store <2 x float> %sub0, ptr %ptr0
-  store <2 x float> %sub1, ptr %ptr1
-  ret void
-}
-
-define void @diamondWithConstantVector(ptr %ptr) {
-; CHECK-LABEL: define void @diamondWithConstantVector(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[GEPA0:%.*]] = getelementptr i32, ptr [[PTR]], i64 0
-; CHECK-NEXT:    [[GEPB0:%.*]] = getelementptr i32, ptr [[PTR]], i64 10
-; CHECK-NEXT:    store <2 x i32> zeroinitializer, ptr [[GEPA0]], align 4, !sandboxvec [[META13:![0-9]+]]
-; CHECK-NEXT:    store <2 x i32> zeroinitializer, ptr [[GEPB0]], align 4, !sandboxvec [[META14:![0-9]+]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @diamondWithConstantVector(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[GEPA0:%.*]] = getelementptr i32, ptr [[PTR]], i64 0
-; REVERT-NEXT:    [[GEPA1:%.*]] = getelementptr i32, ptr [[PTR]], i64 1, !sandboxvec [[META13:![0-9]+]]
-; REVERT-NEXT:    [[GEPB0:%.*]] = getelementptr i32, ptr [[PTR]], i64 10
-; REVERT-NEXT:    [[GEPB1:%.*]] = getelementptr i32, ptr [[PTR]], i64 11, !sandboxvec [[META14:![0-9]+]]
-; REVERT-NEXT:    [[ZEXT0:%.*]] = zext i16 0 to i32
-; REVERT-NEXT:    [[ZEXT1:%.*]] = zext i16 0 to i32
-; REVERT-NEXT:    store i32 [[ZEXT0]], ptr [[GEPA0]], align 4, !sandboxvec [[META13]]
-; REVERT-NEXT:    store i32 [[ZEXT1]], ptr [[GEPA1]], align 4, !sandboxvec [[META13]]
-; REVERT-NEXT:    [[ORB0:%.*]] = or i32 0, [[ZEXT0]], !sandboxvec [[META14]]
-; REVERT-NEXT:    [[ORB1:%.*]] = or i32 0, [[ZEXT1]], !sandboxvec [[META14]]
-; REVERT-NEXT:    store i32 [[ORB0]], ptr [[GEPB0]], align 4, !sandboxvec [[META14]]
-; REVERT-NEXT:    store i32 [[ORB1]], ptr [[GEPB1]], align 4, !sandboxvec [[META14]]
-; REVERT-NEXT:    ret void
-;
-  %gepA0 = getelementptr i32, ptr %ptr, i64 0
-  %gepA1 = getelementptr i32, ptr %ptr, i64 1
-
-  %gepB0 = getelementptr i32, ptr %ptr, i64 10
-  %gepB1 = getelementptr i32, ptr %ptr, i64 11
-
-  %zext0 = zext i16 0 to i32
-  %zext1 = zext i16 0 to i32
-
-  store i32 %zext0, ptr %gepA0
-  store i32 %zext1, ptr %gepA1
-
-  %orB0 = or i32 0, %zext0
-  %orB1 = or i32 0, %zext1
-  store i32 %orB0, ptr %gepB0
-  store i32 %orB1, ptr %gepB1
-  ret void
-}
-
-; Check that we don't get def-after-use errors due to wrong placement
-; of new vector instructions.
-define void @vecInstrsPlacement(ptr %ptr0) {
-; CHECK-LABEL: define void @vecInstrsPlacement(
-; CHECK-SAME: ptr [[PTR0:%.*]]) {
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x double>, ptr [[PTR0]], align 8, !sandboxvec [[META15:![0-9]+]]
-; CHECK-NEXT:    [[VECL1:%.*]] = load <2 x double>, ptr [[PTR0]], align 8, !sandboxvec [[META15]]
-; CHECK-NEXT:    [[VEC2:%.*]] = fmul <2 x double> [[VECL]], [[VECL1]], !sandboxvec [[META15]]
-; CHECK-NEXT:    [[VEC:%.*]] = fmul <2 x double> [[VECL]], [[VECL1]], !sandboxvec [[META15]]
-; CHECK-NEXT:    [[VEC3:%.*]] = fadd <2 x double> [[VEC]], [[VEC2]], !sandboxvec [[META15]]
-; CHECK-NEXT:    store <2 x double> [[VEC3]], ptr [[PTR0]], align 8, !sandboxvec [[META15]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @vecInstrsPlacement(
-; REVERT-SAME: ptr [[PTR0:%.*]]) {
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr inbounds double, ptr [[PTR0]], i64 1, !sandboxvec [[META15:![0-9]+]]
-; REVERT-NEXT:    [[LDA_0:%.*]] = load double, ptr [[PTR0]], align 8, !sandboxvec [[META15]]
-; REVERT-NEXT:    [[LDA_1:%.*]] = load double, ptr [[PTR1]], align 8, !sandboxvec [[META15]]
-; REVERT-NEXT:    [[LDB_0:%.*]] = load double, ptr [[PTR0]], align 8, !sandboxvec [[META15]]
-; REVERT-NEXT:    [[LDB_1:%.*]] = load double, ptr [[PTR1]], align 8, !sandboxvec [[META15]]
-; REVERT-NEXT:    [[MUL0:%.*]] = fmul double [[LDA_0]], [[LDB_0]], !sandboxvec [[META15]]
-; REVERT-NEXT:    [[MUL1:%.*]] = fmul double [[LDA_1]], [[LDB_1]], !sandboxvec [[META15]]
-; REVERT-NEXT:    [[MUL2:%.*]] = fmul double [[LDA_0]], [[LDB_0]], !sandboxvec [[META15]]
-; REVERT-NEXT:    [[MUL3:%.*]] = fmul double [[LDA_1]], [[LDB_1]], !sandboxvec [[META15]]
-; REVERT-NEXT:    [[ADD0:%.*]] = fadd double [[MUL0]], [[MUL2]], !sandboxvec [[META15]]
-; REVERT-NEXT:    [[ADD1:%.*]] = fadd double [[MUL1]], [[MUL3]], !sandboxvec [[META15]]
-; REVERT-NEXT:    store double [[ADD0]], ptr [[PTR0]], align 8, !sandboxvec [[META15]]
-; REVERT-NEXT:    store double [[ADD1]], ptr [[PTR1]], align 8, !sandboxvec [[META15]]
-; REVERT-NEXT:    ret void
-;
-  %ptr1 = getelementptr inbounds double, ptr %ptr0, i64 1
-  %ldA_0 = load double, ptr %ptr0
-  %ldA_1 = load double, ptr %ptr1
-
-  %ldB_0 = load double, ptr %ptr0
-  %ldB_1 = load double, ptr %ptr1
-
-  %mul0 = fmul double %ldA_0, %ldB_0
-  %mul1 = fmul double %ldA_1, %ldB_1
-
-  %mul2 = fmul double %ldA_0, %ldB_0
-  %mul3 = fmul double %ldA_1, %ldB_1
-
-  %add0 = fadd double %mul0, %mul2
-  %add1 = fadd double %mul1, %mul3
-
-  store double %add0, ptr %ptr0
-  store double %add1, ptr %ptr1
-  ret void
-}
-
-; During the bottom-up traversal we form bundle {ldA0,ldA1} but later when we
-; visit the RHS operands of the additions we try to form {ldA1,ldA2}
-; which is not allowed.
-define void @instrsInMultipleBundles(ptr noalias %ptr) {
-; CHECK-LABEL: define void @instrsInMultipleBundles(
-; CHECK-SAME: ptr noalias [[PTR:%.*]]) {
-; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
-; CHECK-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 2
-; CHECK-NEXT:    [[LDA2:%.*]] = load i8, ptr [[GEP2]], align 1
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x i8>, ptr [[GEP0]], align 1, !sandboxvec [[META16:![0-9]+]]
-; CHECK-NEXT:    [[VEXT:%.*]] = extractelement <2 x i8> [[VECL]], i32 1, !sandboxvec [[META16]]
-; CHECK-NEXT:    [[VINS:%.*]] = insertelement <2 x i8> poison, i8 [[VEXT]], i32 0, !sandboxvec [[META16]]
-; CHECK-NEXT:    [[VINS1:%.*]] = insertelement <2 x i8> [[VINS]], i8 [[LDA2]], i32 1, !sandboxvec [[META16]]
-; CHECK-NEXT:    [[VEC:%.*]] = add <2 x i8> [[VECL]], [[VINS1]], !sandboxvec [[META16]]
-; CHECK-NEXT:    store <2 x i8> [[VEC]], ptr [[GEP0]], align 1, !sandboxvec [[META16]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @instrsInMultipleBundles(
-; REVERT-SAME: ptr noalias [[PTR:%.*]]) {
-; REVERT-NEXT:    [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
-; REVERT-NEXT:    [[GEP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 1, !sandboxvec [[META16:![0-9]+]]
-; REVERT-NEXT:    [[GEP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 2
-; REVERT-NEXT:    [[LDA0:%.*]] = load i8, ptr [[GEP0]], align 1, !sandboxvec [[META16]]
-; REVERT-NEXT:    [[LDA1:%.*]] = load i8, ptr [[GEP1]], align 1, !sandboxvec [[META16]]
-; REVERT-NEXT:    [[LDA2:%.*]] = load i8, ptr [[GEP2]], align 1
-; REVERT-NEXT:    [[ADD0:%.*]] = add i8 [[LDA0]], [[LDA1]], !sandboxvec [[META16]]
-; REVERT-NEXT:    [[ADD1:%.*]] = add i8 [[LDA1]], [[LDA2]], !sandboxvec [[META16]]
-; REVERT-NEXT:    store i8 [[ADD0]], ptr [[GEP0]], align 1, !sandboxvec [[META16]]
-; REVERT-NEXT:    store i8 [[ADD1]], ptr [[GEP1]], align 1, !sandboxvec [[META16]]
-; REVERT-NEXT:    ret void
-;
-  %gep0 = getelementptr i8, ptr %ptr, i64 0
-  %gep1 = getelementptr i8, ptr %ptr, i64 1
-  %gep2 = getelementptr i8, ptr %ptr, i64 2
-  %ldA0 = load i8, ptr %gep0
-  %ldA1 = load i8, ptr %gep1
-  %ldA2 = load i8, ptr %gep2
-  %add0 = add i8 %ldA0, %ldA1
-  %add1 = add i8 %ldA1, %ldA2
-  store i8 %add0, ptr %gep0
-  store i8 %add1, ptr %gep1
-  ret void
-}
-
-define void @vectorize_constants(ptr %ptr) {
-; CHECK-LABEL: define void @vectorize_constants(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x i8>, ptr [[PTR0]], align 1, !sandboxvec [[META17:![0-9]+]]
-; CHECK-NEXT:    [[VEC:%.*]] = add <2 x i8> [[VECL]], <i8 0, i8 1>, !sandboxvec [[META17]]
-; CHECK-NEXT:    store <2 x i8> [[VEC]], ptr [[PTR0]], align 1, !sandboxvec [[META17]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @vectorize_constants(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr i8, ptr [[PTR]], i32 1, !sandboxvec [[META17:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load i8, ptr [[PTR0]], align 1, !sandboxvec [[META17]]
-; REVERT-NEXT:    [[LD1:%.*]] = load i8, ptr [[PTR1]], align 1, !sandboxvec [[META17]]
-; REVERT-NEXT:    [[ADD0:%.*]] = add i8 [[LD0]], 0, !sandboxvec [[META17]]
-; REVERT-NEXT:    [[ADD1:%.*]] = add i8 [[LD1]], 1, !sandboxvec [[META17]]
-; REVERT-NEXT:    store i8 [[ADD0]], ptr [[PTR0]], align 1, !sandboxvec [[META17]]
-; REVERT-NEXT:    store i8 [[ADD1]], ptr [[PTR1]], align 1, !sandboxvec [[META17]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr i8, ptr %ptr, i32 0
-  %ptr1 = getelementptr i8, ptr %ptr, i32 1
-  %ld0 = load i8, ptr %ptr0
-  %ld1 = load i8, ptr %ptr1
-  %add0 = add i8 %ld0, 0
-  %add1 = add i8 %ld1, 1
-  store i8 %add0, ptr %ptr0
-  store i8 %add1, ptr %ptr1
-  ret void
-}
-
-define void @vectorize_constant_vectors(ptr %ptr) {
-; CHECK-LABEL: define void @vectorize_constant_vectors(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VECL:%.*]] = load <4 x i8>, ptr [[PTR0]], align 2, !sandboxvec [[META18:![0-9]+]]
-; CHECK-NEXT:    [[VEC:%.*]] = sub <4 x i8> [[VECL]], <i8 0, i8 0, i8 1, i8 1>, !sandboxvec [[META18]]
-; CHECK-NEXT:    store <4 x i8> [[VEC]], ptr [[PTR0]], align 2, !sandboxvec [[META18]]
-; CHECK-NEXT:    ret void
-;
-; REVERT-LABEL: define void @vectorize_constant_vectors(
-; REVERT-SAME: ptr [[PTR:%.*]]) {
-; REVERT-NEXT:    [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
-; REVERT-NEXT:    [[PTR1:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 1, !sandboxvec [[META18:![0-9]+]]
-; REVERT-NEXT:    [[LD0:%.*]] = load <2 x i8>, ptr [[PTR0]], align 2, !sandboxvec [[META18]]
-; REVERT-NEXT:    [[LD1:%.*]] = load <2 x i8>, ptr [[PTR1]], align 2, !sandboxvec [[META18]]
-; REVERT-NEXT:    [[SUB0:%.*]] = sub <2 x i8> [[LD0]], zeroinitializer, !sandboxvec [[META18]]
-; REVERT-NEXT:    [[SUB1:%.*]] = sub <2 x i8> [[LD1]], splat (i8 1), !sandboxvec [[META18]]
-; REVERT-NEXT:    store <2 x i8> [[SUB0]], ptr [[PTR0]], align 2, !sandboxvec [[META18]]
-; REVERT-NEXT:    store <2 x i8> [[SUB1]], ptr [[PTR1]], align 2, !sandboxvec [[META18]]
-; REVERT-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x i8>, ptr %ptr, i32 0
-  %ptr1 = getelementptr <2 x i8>, ptr %ptr, i32 1
-  %ld0 = load <2 x i8>, ptr %ptr0
-  %ld1 = load <2 x i8>, ptr %ptr1
-  %sub0 = sub <2 x i8> %ld0, splat(i8 0)
-  %sub1 = sub <2 x i8> %ld1, splat(i8 1)
-  store <2 x i8> %sub0, ptr %ptr0
-  store <2 x i8> %sub1, ptr %ptr1
-  ret void
-}
-;.
-; CHECK: [[META0]] = distinct !{!"sandboxregion"}
-; CHECK: [[META1]] = distinct !{!"sandboxregion"}
-; CHECK: [[META2]] = distinct !{!"sandboxregion"}
-; CHECK: [[META3]] = distinct !{!"sandboxregion"}
-; CHECK: [[META4]] = distinct !{!"sandboxregion"}
-; CHECK: [[META5]] = distinct !{!"sandboxregion"}
-; CHECK: [[META6]] = distinct !{!"sandboxregion"}
-; CHECK: [[META7]] = distinct !{!"sandboxregion"}
-; CHECK: [[META8]] = distinct !{!"sandboxregion"}
-; CHECK: [[META9]] = distinct !{!"sandboxregion"}
-; CHECK: [[META10]] = distinct !{!"sandboxregion"}
-; CHECK: [[META11]] = distinct !{!"sandboxregion"}
-; CHECK: [[META12]] = distinct !{!"sandboxregion"}
-; CHECK: [[META13]] = distinct !{!"sandboxregion"}
-; CHECK: [[META14]] = distinct !{!"sandboxregion"}
-; CHECK: [[META15]] = distinct !{!"sandboxregion"}
-; CHECK: [[META16]] = distinct !{!"sandboxregion"}
-; CHECK: [[META17]] = distinct !{!"sandboxregion"}
-; CHECK: [[META18]] = distinct !{!"sandboxregion"}
-;.
-; REVERT: [[META0]] = distinct !{!"sandboxregion"}
-; REVERT: [[META1]] = distinct !{!"sandboxregion"}
-; REVERT: [[META2]] = distinct !{!"sandboxregion"}
-; REVERT: [[META3]] = distinct !{!"sandboxregion"}
-; REVERT: [[META4]] = distinct !{!"sandboxregion"}
-; REVERT: [[META5]] = distinct !{!"sandboxregion"}
-; REVERT: [[META6]] = distinct !{!"sandboxregion"}
-; REVERT: [[META7]] = distinct !{!"sandboxregion"}
-; REVERT: [[META8]] = distinct !{!"sandboxregion"}
-; REVERT: [[META9]] = distinct !{!"sandboxregion"}
-; REVERT: [[META10]] = distinct !{!"sandboxregion"}
-; REVERT: [[META11]] = distinct !{!"sandboxregion"}
-; REVERT: [[META12]] = distinct !{!"sandboxregion"}
-; REVERT: [[META13]] = distinct !{!"sandboxregion"}
-; REVERT: [[META14]] = distinct !{!"sandboxregion"}
-; REVERT: [[META15]] = distinct !{!"sandboxregion"}
-; REVERT: [[META16]] = distinct !{!"sandboxregion"}
-; REVERT: [[META17]] = distinct !{!"sandboxregion"}
-; REVERT: [[META18]] = distinct !{!"sandboxregion"}
-;.
diff --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
deleted file mode 100644
index 38c0816504481..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice.ll
+++ /dev/null
@@ -1,32 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-
-
-declare void @foo()
-define void @slice_seeds(ptr %ptr, float %val) {
-; CHECK-LABEL: define void @slice_seeds(
-; CHECK-SAME: ptr [[PTR:%.*]], float [[VAL:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2
-; CHECK-NEXT:    [[LD2:%.*]] = load float, ptr [[PTR2]], align 4
-; CHECK-NEXT:    store float [[LD2]], ptr [[PTR2]], align 4
-; CHECK-NEXT:    call void @foo()
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; CHECK-NEXT:    store <2 x float> [[VECL]], ptr [[PTR0]], align 4
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptr2 = getelementptr float, ptr %ptr, i32 2
-
-  %ld2 = load float, ptr %ptr2
-  store float %ld2, ptr %ptr2
-  ; This call blocks scheduling of all 3 stores.
-  call void @foo()
-
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  store float %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll b/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
deleted file mode 100644
index f2eb124494b5e..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/bottomup_seed_slice_pow2.ll
+++ /dev/null
@@ -1,34 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2=false -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s --check-prefix=POW2
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2=true -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s --check-prefix=NON-POW2
-
-define void @pow2(ptr %ptr, float %val) {
-; POW2-LABEL: define void @pow2(
-; POW2-SAME: ptr [[PTR:%.*]], float [[VAL:%.*]]) {
-; POW2-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; POW2-NEXT:    [[PTR2:%.*]] = getelementptr float, ptr [[PTR]], i32 2
-; POW2-NEXT:    [[LD2:%.*]] = load float, ptr [[PTR2]], align 4
-; POW2-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; POW2-NEXT:    store <2 x float> [[VECL]], ptr [[PTR0]], align 4
-; POW2-NEXT:    store float [[LD2]], ptr [[PTR2]], align 4
-; POW2-NEXT:    ret void
-;
-; NON-POW2-LABEL: define void @pow2(
-; NON-POW2-SAME: ptr [[PTR:%.*]], float [[VAL:%.*]]) {
-; NON-POW2-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; NON-POW2-NEXT:    [[PACK2:%.*]] = load <3 x float>, ptr [[PTR0]], align 4
-; NON-POW2-NEXT:    store <3 x float> [[PACK2]], ptr [[PTR0]], align 4
-; NON-POW2-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptr2 = getelementptr float, ptr %ptr, i32 2
-
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %ld2 = load float, ptr %ptr2
-  store float %ld0, ptr %ptr0
-  store float %ld1, ptr %ptr1
-  store float %ld2, ptr %ptr2
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll b/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
deleted file mode 100644
index c559f294f9695..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/cross_bbs.ll
+++ /dev/null
@@ -1,28 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-
-define void @cross_bbs(ptr %ptr) {
-; CHECK-LABEL: define void @cross_bbs(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr i8, ptr [[PTR]], i32 1
-; CHECK-NEXT:    [[L0:%.*]] = load i8, ptr [[PTR0]], align 1
-; CHECK-NEXT:    [[L1:%.*]] = load i8, ptr [[PTR1]], align 1
-; CHECK-NEXT:    br label %[[BB:.*]]
-; CHECK:       [[BB]]:
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <2 x i8> poison, i8 [[L0]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <2 x i8> [[PACK]], i8 [[L1]], i32 1
-; CHECK-NEXT:    store <2 x i8> [[PACK1]], ptr [[PTR0]], align 1
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr i8, ptr %ptr, i32 0
-  %ptr1 = getelementptr i8, ptr %ptr, i32 1
-  %l0 = load i8, ptr %ptr0
-  %l1 = load i8, ptr %ptr1
-  br label %bb
-
-bb:
-  store i8 %l0, ptr %ptr0
-  store i8 %l1, ptr %ptr1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll b/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
deleted file mode 100644
index 86000da42c799..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/default_pass_pipeline.ll
+++ /dev/null
@@ -1,14 +0,0 @@
-; RUN: opt -passes=sandbox-vectorizer -sbvec-print-pass-pipeline %s -disable-output | FileCheck %s
-
-; !!!WARNING!!! This won't get updated by update_test_checks.py !
-
-; This checks the default pass pipeline for the sandbox vectorizer.
-define void @pipeline() {
-; CHECK: fpm
-; CHECK: seed-collection
-; CHECK: rpm
-; CHECK: bottom-up-vec
-; CHECK: tr-accept-or-revert
-; CHECK-EMPTY:
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/pack.ll b/llvm/test/Transforms/SandboxVectorizer/pack.ll
deleted file mode 100644
index c5abddb7fba01..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/pack.ll
+++ /dev/null
@@ -1,117 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-
-define void @pack_constants(ptr %ptr) {
-; CHECK-LABEL: define void @pack_constants(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr i8, ptr [[PTR]], i32 0
-; CHECK-NEXT:    store <2 x i8> <i8 0, i8 1>, ptr [[PTR0]], align 1
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr i8, ptr %ptr, i32 0
-  %ptr1 = getelementptr i8, ptr %ptr, i32 1
-  store i8 0, ptr %ptr0
-  store i8 1, ptr %ptr1
-  ret void
-}
-
-; Make sure we don't generate bad IR when packing PHIs.
-; NOTE: This test may become obsolete once we start vectorizing PHIs.
-define void @packPHIs(ptr %ptr) {
-; CHECK-LABEL: define void @packPHIs(
-; CHECK-SAME: ptr [[PTR:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*]]:
-; CHECK-NEXT:    br label %[[LOOP:.*]]
-; CHECK:       [[LOOP]]:
-; CHECK-NEXT:    [[PHI0:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]
-; CHECK-NEXT:    [[PHI1:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]
-; CHECK-NEXT:    [[PHI2:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]
-; CHECK-NEXT:    [[PHI3:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <2 x i8> poison, i8 [[PHI0]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <2 x i8> [[PACK]], i8 [[PHI1]], i32 1
-; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
-; CHECK-NEXT:    store <2 x i8> [[PACK1]], ptr [[GEP0]], align 1
-; CHECK-NEXT:    br label %[[LOOP]]
-; CHECK:       [[EXIT:.*:]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  br label %loop
-
-loop:
-  %phi0 = phi i8 [0, %entry], [1, %loop]
-  %phi1 = phi i8 [0, %entry], [1, %loop]
-  %phi2 = phi i8 [0, %entry], [1, %loop]
-  %phi3 = phi i8 [0, %entry], [1, %loop]
-  %gep0 = getelementptr i8, ptr %ptr, i64 0
-  %gep1 = getelementptr i8, ptr %ptr, i64 1
-  store i8 %phi0, ptr %gep0
-  store i8 %phi1, ptr %gep1
-  br label %loop
-
-exit:
-  ret void
-}
-
-define void @packFromOtherBB(ptr %ptr, i8 %val) {
-; CHECK-LABEL: define void @packFromOtherBB(
-; CHECK-SAME: ptr [[PTR:%.*]], i8 [[VAL:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*]]:
-; CHECK-NEXT:    [[ADD0:%.*]] = add i8 [[VAL]], 0
-; CHECK-NEXT:    [[MUL1:%.*]] = mul i8 [[VAL]], 1
-; CHECK-NEXT:    br label %[[LOOP:.*]]
-; CHECK:       [[LOOP]]:
-; CHECK-NEXT:    [[PHI0:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]
-; CHECK-NEXT:    [[PHI1:%.*]] = phi i8 [ 0, %[[ENTRY]] ], [ 1, %[[LOOP]] ]
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <2 x i8> poison, i8 [[ADD0]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <2 x i8> [[PACK]], i8 [[MUL1]], i32 1
-; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
-; CHECK-NEXT:    store <2 x i8> [[PACK1]], ptr [[GEP0]], align 1
-; CHECK-NEXT:    br label %[[LOOP]]
-; CHECK:       [[EXIT:.*:]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  %add0 = add i8 %val, 0
-  %mul1 = mul i8 %val, 1
-  br label %loop
-
-loop:
-  %phi0 = phi i8 [0, %entry], [1, %loop]
-  %phi1 = phi i8 [0, %entry], [1, %loop]
-  %gep0 = getelementptr i8, ptr %ptr, i64 0
-  %gep1 = getelementptr i8, ptr %ptr, i64 1
-  store i8 %add0, ptr %gep0
-  store i8 %mul1, ptr %gep1
-  br label %loop
-
-exit:
-  ret void
-}
-
-define void @packFromDiffBBs(ptr %ptr, i8 %v) {
-; CHECK-LABEL: define void @packFromDiffBBs(
-; CHECK-SAME: ptr [[PTR:%.*]], i8 [[V:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[ADD0:%.*]] = add i8 [[V]], 1
-; CHECK-NEXT:    br label %[[BB:.*]]
-; CHECK:       [[BB]]:
-; CHECK-NEXT:    [[ADD1:%.*]] = add i8 [[V]], 2
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <2 x i8> poison, i8 [[ADD0]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <2 x i8> [[PACK]], i8 [[ADD1]], i32 1
-; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr i8, ptr [[PTR]], i64 0
-; CHECK-NEXT:    store <2 x i8> [[PACK1]], ptr [[GEP0]], align 1
-; CHECK-NEXT:    ret void
-;
-entry:
-  %add0 = add i8 %v, 1
-  br label %bb
-
-bb:
-  %add1 = add i8 %v, 2
-  %gep0 = getelementptr i8, ptr %ptr, i64 0
-  %gep1 = getelementptr i8, ptr %ptr, i64 1
-  store i8 %add0, ptr %gep0
-  store i8 %add1, ptr %gep1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/pack_reuse_basic.ll b/llvm/test/Transforms/SandboxVectorizer/pack_reuse_basic.ll
deleted file mode 100644
index 33cdaf54252c2..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/pack_reuse_basic.ll
+++ /dev/null
@@ -1,71 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-passes="regions-from-metadata<pack-reuse>" %s -S | FileCheck %s
-
-define void @pack_reuse(i8 %v0, i8 %v1, ptr %ptr) {
-; CHECK-LABEL: define void @pack_reuse(
-; CHECK-SAME: i8 [[V0:%.*]], i8 [[V1:%.*]], ptr [[PTR:%.*]]) {
-; CHECK-NEXT:    [[PACKA0:%.*]] = insertelement <2 x i8> poison, i8 [[V0]], i64 0, !sandboxvec [[META0:![0-9]+]]
-; CHECK-NEXT:    [[PACKA1:%.*]] = insertelement <2 x i8> [[PACKA0]], i8 [[V1]], i64 1, !sandboxvec [[META0]]
-; CHECK-NEXT:    store <2 x i8> [[PACKA1]], ptr [[PTR]], align 2, !sandboxvec [[META0]]
-; CHECK-NEXT:    store <2 x i8> [[PACKA1]], ptr [[PTR]], align 2, !sandboxvec [[META0]]
-; CHECK-NEXT:    [[PACKC0:%.*]] = insertelement <2 x i8> poison, i8 [[V1]], i64 0, !sandboxvec [[META0]]
-; CHECK-NEXT:    [[PACKC1:%.*]] = insertelement <2 x i8> [[PACKC0]], i8 [[V0]], i64 1, !sandboxvec [[META0]]
-; CHECK-NEXT:    store <2 x i8> [[PACKC1]], ptr [[PTR]], align 2, !sandboxvec [[META0]]
-; CHECK-NEXT:    ret void
-;
-  %PackA0 = insertelement <2 x i8> poison, i8 %v0, i64 0, !sandboxvec !0
-  %PackA1 = insertelement <2 x i8> %PackA0, i8 %v1, i64 1, !sandboxvec !0
-  store <2 x i8> %PackA1, ptr %ptr, !sandboxvec !0
-
-  ; Should reuse PackA1.
-  %PackB0 = insertelement <2 x i8> poison, i8 %v0, i64 0, !sandboxvec !0
-  %PackB1 = insertelement <2 x i8> %PackB0, i8 %v1, i64 1, !sandboxvec !0
-  store <2 x i8> %PackB1, ptr %ptr, !sandboxvec !0
-
-  ; Should remain.
-  %PackC0 = insertelement <2 x i8> poison, i8 %v1, i64 0, !sandboxvec !0
-  %PackC1 = insertelement <2 x i8> %PackC0, i8 %v0, i64 1, !sandboxvec !0
-  store <2 x i8> %PackC1, ptr %ptr, !sandboxvec !0
-  ret void
-}
-
-; TODO: For now we don't support reusing packs from earlier BBs.
-define void @pack_cross_bb(i8 %v0, i8 %v1, ptr %ptr) {
-; CHECK-LABEL: define void @pack_cross_bb(
-; CHECK-SAME: i8 [[V0:%.*]], i8 [[V1:%.*]], ptr [[PTR:%.*]]) {
-; CHECK-NEXT:  [[ENTRY:.*:]]
-; CHECK-NEXT:    [[PACKA0:%.*]] = insertelement <2 x i8> poison, i8 [[V0]], i64 0, !sandboxvec [[META1:![0-9]+]]
-; CHECK-NEXT:    [[PACKA1:%.*]] = insertelement <2 x i8> [[PACKA0]], i8 [[V1]], i64 1, !sandboxvec [[META1]]
-; CHECK-NEXT:    store <2 x i8> [[PACKA1]], ptr [[PTR]], align 2, !sandboxvec [[META1]]
-; CHECK-NEXT:    br label %[[BB:.*]]
-; CHECK:       [[BB]]:
-; CHECK-NEXT:    [[PACKB0:%.*]] = insertelement <2 x i8> poison, i8 [[V0]], i64 0, !sandboxvec [[META1]]
-; CHECK-NEXT:    [[PACKB1:%.*]] = insertelement <2 x i8> [[PACKB0]], i8 [[V1]], i64 1, !sandboxvec [[META1]]
-; CHECK-NEXT:    store <2 x i8> [[PACKB1]], ptr [[PTR]], align 2, !sandboxvec [[META1]]
-; CHECK-NEXT:    [[PACKC0:%.*]] = insertelement <2 x i8> poison, i8 [[V1]], i64 0, !sandboxvec [[META1]]
-; CHECK-NEXT:    [[PACKC1:%.*]] = insertelement <2 x i8> [[PACKC0]], i8 [[V0]], i64 1, !sandboxvec [[META1]]
-; CHECK-NEXT:    store <2 x i8> [[PACKC1]], ptr [[PTR]], align 2, !sandboxvec [[META1]]
-; CHECK-NEXT:    ret void
-;
-entry:
-  %PackA0 = insertelement <2 x i8> poison, i8 %v0, i64 0, !sandboxvec !0
-  %PackA1 = insertelement <2 x i8> %PackA0, i8 %v1, i64 1, !sandboxvec !0
-  store <2 x i8> %PackA1, ptr %ptr, !sandboxvec !0
-  br label %bb
-
-bb:
-  %PackB0 = insertelement <2 x i8> poison, i8 %v0, i64 0, !sandboxvec !0
-  %PackB1 = insertelement <2 x i8> %PackB0, i8 %v1, i64 1, !sandboxvec !0
-  store <2 x i8> %PackB1, ptr %ptr, !sandboxvec !0
-
-  %PackC0 = insertelement <2 x i8> poison, i8 %v1, i64 0, !sandboxvec !0
-  %PackC1 = insertelement <2 x i8> %PackC0, i8 %v0, i64 1, !sandboxvec !0
-  store <2 x i8> %PackC1, ptr %ptr, !sandboxvec !0
-  ret void
-}
-
-!0 = distinct !{!"sandboxregion"}
-;.
-; CHECK: [[META0]] = distinct !{!"sandboxregion"}
-; CHECK: [[META1]] = distinct !{!"sandboxregion"}
-;.
diff --git a/llvm/test/Transforms/SandboxVectorizer/pack_reuse_end_to_end.ll b/llvm/test/Transforms/SandboxVectorizer/pack_reuse_end_to_end.ll
deleted file mode 100644
index 0861c7827c91c..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/pack_reuse_end_to_end.ll
+++ /dev/null
@@ -1,45 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s --check-prefix NOREUSE
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,pack-reuse,tr-accept>" %s -S | FileCheck %s --check-prefix PKREUSE
-
-define void @pack_reuse(ptr %ptr, ptr %ptrX, ptr %ptrY) {
-; NOREUSE-LABEL: define void @pack_reuse(
-; NOREUSE-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]], ptr [[PTRY:%.*]]) {
-; NOREUSE-NEXT:    [[LDX:%.*]] = load float, ptr [[PTRX]], align 4
-; NOREUSE-NEXT:    [[LDY:%.*]] = load float, ptr [[PTRY]], align 4
-; NOREUSE-NEXT:    [[PACK2:%.*]] = insertelement <2 x float> poison, float [[LDX]], i32 0, !sandboxvec [[META0:![0-9]+]]
-; NOREUSE-NEXT:    [[PACK3:%.*]] = insertelement <2 x float> [[PACK2]], float [[LDY]], i32 1, !sandboxvec [[META0]]
-; NOREUSE-NEXT:    [[PACK:%.*]] = insertelement <2 x float> poison, float [[LDX]], i32 0, !sandboxvec [[META0]]
-; NOREUSE-NEXT:    [[PACK1:%.*]] = insertelement <2 x float> [[PACK]], float [[LDY]], i32 1, !sandboxvec [[META0]]
-; NOREUSE-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; NOREUSE-NEXT:    [[VEC:%.*]] = fsub <2 x float> [[PACK1]], [[PACK3]], !sandboxvec [[META0]]
-; NOREUSE-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
-; NOREUSE-NEXT:    ret void
-;
-; PKREUSE-LABEL: define void @pack_reuse(
-; PKREUSE-SAME: ptr [[PTR:%.*]], ptr [[PTRX:%.*]], ptr [[PTRY:%.*]]) {
-; PKREUSE-NEXT:    [[LDX:%.*]] = load float, ptr [[PTRX]], align 4
-; PKREUSE-NEXT:    [[LDY:%.*]] = load float, ptr [[PTRY]], align 4
-; PKREUSE-NEXT:    [[PACK2:%.*]] = insertelement <2 x float> poison, float [[LDX]], i32 0, !sandboxvec [[META0:![0-9]+]]
-; PKREUSE-NEXT:    [[PACK3:%.*]] = insertelement <2 x float> [[PACK2]], float [[LDY]], i32 1, !sandboxvec [[META0]]
-; PKREUSE-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; PKREUSE-NEXT:    [[VEC:%.*]] = fsub <2 x float> [[PACK3]], [[PACK3]], !sandboxvec [[META0]]
-; PKREUSE-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4, !sandboxvec [[META0]]
-; PKREUSE-NEXT:    ret void
-;
-  %ldX = load float, ptr %ptrX
-  %ldY = load float, ptr %ptrY
-
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %sub0 = fsub float %ldX, %ldX
-  %sub1 = fsub float %ldY, %ldY
-  store float %sub0, ptr %ptr0
-  store float %sub1, ptr %ptr1
-  ret void
-}
-;.
-; NOREUSE: [[META0]] = distinct !{!"sandboxregion"}
-;.
-; PKREUSE: [[META0]] = distinct !{!"sandboxregion"}
-;.
diff --git a/llvm/test/Transforms/SandboxVectorizer/print_region_pass.ll b/llvm/test/Transforms/SandboxVectorizer/print_region_pass.ll
deleted file mode 100644
index 0b808d6025e46..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/print_region_pass.ll
+++ /dev/null
@@ -1,26 +0,0 @@
-; RUN: opt -disable-output -passes=sandbox-vectorizer -sbvec-passes="regions-from-metadata<print-region>" %s | FileCheck %s
-; REQUIRES: asserts
-
-define void @foo(i8 %v) {
-; CHECK: -- Region --
-; CHECK-NEXT:  %add0 = add i8 %v, 0, !sandboxvec !0 {{.*}}
-; CHECK: -- Region --
-; CHECK-NEXT:  %add1 = add i8 %v, 1, !sandboxvec !1 {{.*}}
-; CHECK-NEXT:  %add2 = add i8 %v, 2, !sandboxvec !1 {{.*}}
-; CHECK-NEXT:  %add3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2 {{.*}}
-; CHECK-NEXT:  %add4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !3 {{.*}}
-; CHECK: Aux:
-; CHECK-NEXT:  %add3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2 {{.*}}
-; CHECK-NEXT:  %add4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !3 {{.*}}
-  %add0 = add i8 %v, 0, !sandboxvec !0
-  %add1 = add i8 %v, 1, !sandboxvec !1
-  %add2 = add i8 %v, 2, !sandboxvec !1
-  %add3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2
-  %add4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !3
-  ret void
-}
-
-!0 = distinct !{!"sandboxregion"}
-!1 = distinct !{!"sandboxregion"}
-!2 = !{i32 0}
-!3 = !{i32 1}
diff --git a/llvm/test/Transforms/SandboxVectorizer/regions-from-bbs.ll b/llvm/test/Transforms/SandboxVectorizer/regions-from-bbs.ll
deleted file mode 100644
index 065baadb1478b..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/regions-from-bbs.ll
+++ /dev/null
@@ -1,31 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt --passes=sandbox-vectorizer -sbvec-passes='regions-from-bbs<null>' %s -S | FileCheck %s
-
-define void @foo(i8 %v) {
-; CHECK-LABEL: define void @foo(
-; CHECK-SAME: i8 [[V:%.*]]) {
-; CHECK-NEXT:  [[BBA:.*:]]
-; CHECK-NEXT:    [[ADD0:%.*]] = add i8 [[V]], 0, !sandboxvec [[META0:![0-9]+]]
-; CHECK-NEXT:    br label %[[BBB:.*]], !sandboxvec [[META0]]
-; CHECK:       [[BBB]]:
-; CHECK-NEXT:    [[ADD1:%.*]] = add i8 [[V]], 1, !sandboxvec [[META1:![0-9]+]]
-; CHECK-NEXT:    br label %[[BBC:.*]], !sandboxvec [[META1]]
-; CHECK:       [[BBC]]:
-; CHECK-NEXT:    ret void, !sandboxvec [[META2:![0-9]+]]
-;
-bbA:
-  %add0 = add i8 %v, 0
-  br label %bbB
-
-bbB:
-  %add1 = add i8 %v, 1
-  br label %bbC
-
-bbC:
-  ret void
-}
-;.
-; CHECK: [[META0]] = distinct !{!"sandboxregion"}
-; CHECK: [[META1]] = distinct !{!"sandboxregion"}
-; CHECK: [[META2]] = distinct !{!"sandboxregion"}
-;.
diff --git a/llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll b/llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll
deleted file mode 100644
index 3e57bde76e72d..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/regions-from-metadata.ll
+++ /dev/null
@@ -1,15 +0,0 @@
-; RUN: opt -disable-output --passes=sandbox-vectorizer \
-; RUN:    -sbvec-passes='regions-from-metadata<print-instruction-count>' %s | FileCheck %s
-
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1, !sandboxvec !0
-  %t1 = add i8 %t0, %v1, !sandboxvec !1
-  %t2 = add i8 %t1, %v1, !sandboxvec !1
-  ret i8 %t2
-}
-
-!0 = distinct !{!"sandboxregion"}
-!1 = distinct !{!"sandboxregion"}
-
-; CHECK: InstructionCount: 1
-; CHECK: InstructionCount: 2
diff --git a/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll b/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
deleted file mode 100644
index 081267da77e5f..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/repeated_instrs.ll
+++ /dev/null
@@ -1,65 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-
-define i32 @repeated_splat(ptr %ptr, i32 %v) #0 {
-; CHECK-LABEL: define i32 @repeated_splat(
-; CHECK-SAME: ptr [[PTR:%.*]], i32 [[V:%.*]]) {
-; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 0
-; CHECK-NEXT:    [[SPLAT:%.*]] = add i32 [[V]], 0
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <2 x i32> poison, i32 [[SPLAT]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <2 x i32> [[PACK]], i32 [[SPLAT]], i32 1
-; CHECK-NEXT:    [[VECL:%.*]] = load <2 x i32>, ptr [[GEP0]], align 4
-; CHECK-NEXT:    [[VEC:%.*]] = mul <2 x i32> [[VECL]], [[PACK1]]
-; CHECK-NEXT:    store <2 x i32> [[VEC]], ptr [[GEP0]], align 4
-; CHECK-NEXT:    ret i32 0
-;
-  %gep0 = getelementptr inbounds i32, ptr %ptr, i64 0
-  %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
-  %ld0 = load i32, ptr %gep0, align 4
-  %ld1 = load i32, ptr %gep1, align 4
-  %splat = add i32 %v, 0
-  %add0 = mul i32 %ld0, %splat
-  %add1 = mul i32 %ld1, %splat
-  store i32 %add0, ptr %gep0, align 4
-  store i32 %add1, ptr %gep1, align 4
-  ret i32 0
-}
-
-define i32 @repeated_partial(ptr %ptr, i32 %v) #0 {
-; CHECK-LABEL: define i32 @repeated_partial(
-; CHECK-SAME: ptr [[PTR:%.*]], i32 [[V:%.*]]) {
-; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 0
-; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 1
-; CHECK-NEXT:    [[GEP3:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 3
-; CHECK-NEXT:    [[SPLAT:%.*]] = add i32 [[V]], 0
-; CHECK-NEXT:    [[LD0:%.*]] = load i32, ptr [[GEP0]], align 4
-; CHECK-NEXT:    [[LD1:%.*]] = load i32, ptr [[GEP1]], align 4
-; CHECK-NEXT:    [[LD3:%.*]] = load i32, ptr [[GEP3]], align 4
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <4 x i32> poison, i32 [[LD0]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <4 x i32> [[PACK]], i32 [[LD1]], i32 1
-; CHECK-NEXT:    [[PACK2:%.*]] = insertelement <4 x i32> [[PACK1]], i32 [[LD1]], i32 2
-; CHECK-NEXT:    [[PACK3:%.*]] = insertelement <4 x i32> [[PACK2]], i32 [[LD3]], i32 3
-; CHECK-NEXT:    [[VECL:%.*]] = load <4 x i32>, ptr [[GEP0]], align 4
-; CHECK-NEXT:    [[VEC:%.*]] = mul <4 x i32> [[VECL]], [[PACK3]]
-; CHECK-NEXT:    store <4 x i32> [[VEC]], ptr [[GEP0]], align 4
-; CHECK-NEXT:    ret i32 0
-;
-  %gep0 = getelementptr inbounds i32, ptr %ptr, i64 0
-  %gep1 = getelementptr inbounds i32, ptr %ptr, i64 1
-  %gep2 = getelementptr inbounds i32, ptr %ptr, i64 2
-  %gep3 = getelementptr inbounds i32, ptr %ptr, i64 3
-  %ld0 = load i32, ptr %gep0, align 4
-  %ld1 = load i32, ptr %gep1, align 4
-  %ld2 = load i32, ptr %gep2, align 4
-  %ld3 = load i32, ptr %gep3, align 4
-  %splat = add i32 %v, 0
-  %add0 = mul i32 %ld0, %ld0
-  %add1 = mul i32 %ld1, %ld1
-  %add2 = mul i32 %ld2, %ld1
-  %add3 = mul i32 %ld3, %ld3
-  store i32 %add0, ptr %gep0, align 4
-  store i32 %add1, ptr %gep1, align 4
-  store i32 %add2, ptr %gep2, align 4
-  store i32 %add3, ptr %gep3, align 4
-  ret i32 0
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/scheduler.ll b/llvm/test/Transforms/SandboxVectorizer/scheduler.ll
deleted file mode 100644
index 5306661f13fa6..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/scheduler.ll
+++ /dev/null
@@ -1,76 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-
-; This used to crash because the newly added pack   instructions would not update
-; the DAG and scheduler, leading to def-after-use.
-define void @check_dag_scheduler_update(ptr noalias %p, ptr noalias %p1) {
-; CHECK-LABEL: define void @check_dag_scheduler_update(
-; CHECK-SAME: ptr noalias [[P:%.*]], ptr noalias [[P1:%.*]]) {
-; CHECK-NEXT:    [[I:%.*]] = load i32, ptr [[P]], align 4
-; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr i32, ptr [[P]], i64 32
-; CHECK-NEXT:    [[I2:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4
-; CHECK-NEXT:    [[ARRAYIDX11:%.*]] = getelementptr i32, ptr [[P]], i64 33
-; CHECK-NEXT:    [[I4:%.*]] = load i32, ptr [[ARRAYIDX11]], align 4
-; CHECK-NEXT:    [[ARRAYIDX18:%.*]] = getelementptr i32, ptr [[P]], i64 34
-; CHECK-NEXT:    [[I6:%.*]] = load i32, ptr [[ARRAYIDX18]], align 4
-; CHECK-NEXT:    [[PACK:%.*]] = insertelement <4 x i32> poison, i32 [[I]], i32 0
-; CHECK-NEXT:    [[PACK1:%.*]] = insertelement <4 x i32> [[PACK]], i32 [[I2]], i32 1
-; CHECK-NEXT:    [[PACK2:%.*]] = insertelement <4 x i32> [[PACK1]], i32 [[I4]], i32 2
-; CHECK-NEXT:    [[PACK3:%.*]] = insertelement <4 x i32> [[PACK2]], i32 [[I6]], i32 3
-; CHECK-NEXT:    [[VECL:%.*]] = load <4 x i32>, ptr [[P]], align 4
-; CHECK-NEXT:    [[VEC:%.*]] = add nsw <4 x i32> [[PACK3]], [[VECL]]
-; CHECK-NEXT:    store <4 x i32> [[VEC]], ptr [[P1]], align 4
-; CHECK-NEXT:    ret void
-;
-  %i = load i32, ptr %p
-  %i1 = load i32, ptr %p
-  %add = add nsw i32 %i, %i1
-  store i32 %add, ptr %p1
-  %arrayidx4 = getelementptr i32, ptr %p, i64 32
-  %i2 = load i32, ptr %arrayidx4
-  %arrayidx6 = getelementptr i32, ptr %p, i64 1
-  %i3 = load i32, ptr %arrayidx6
-  %add7 = add nsw i32 %i2, %i3
-  %arrayidx9 = getelementptr i32, ptr %p1, i64 1
-  store i32 %add7, ptr %arrayidx9
-  %arrayidx11 = getelementptr i32, ptr %p, i64 33
-  %i4 = load i32, ptr %arrayidx11
-  %arrayidx13 = getelementptr i32, ptr %p, i64 2
-  %i5 = load i32, ptr %arrayidx13
-  %add14 = add nsw i32 %i4, %i5
-  %arrayidx16 = getelementptr i32, ptr %p1, i64 2
-  store i32 %add14, ptr %arrayidx16
-  %arrayidx18 = getelementptr i32, ptr %p, i64 34
-  %i6 = load i32, ptr %arrayidx18
-  %arrayidx19 = getelementptr i32, ptr %p, i64 3
-  %i7 = load i32, ptr %arrayidx19
-  %add21 = add nsw i32 %i6, %i7
-  %arrayidx23 = getelementptr i32, ptr %p1, i64 3
-  store i32 %add21, ptr %arrayidx23
-  ret void
-}
-
-; This used to generate use-before-def because of a buggy update of the
-; top-of-schedule variable.
-define <4 x float> @check_top_of_schedule(ptr %0) {
-; CHECK-LABEL: define <4 x float> @check_top_of_schedule(
-; CHECK-SAME: ptr [[TMP0:%.*]]) {
-; CHECK-NEXT:    [[INS_1:%.*]] = insertelement <4 x float> zeroinitializer, float poison, i64 0
-; CHECK-NEXT:    [[GEP_1:%.*]] = getelementptr double, ptr [[TMP0]], i64 1
-; CHECK-NEXT:    [[TRUNC_1:%.*]] = fptrunc double 0.000000e+00 to float
-; CHECK-NEXT:    [[INS_2:%.*]] = insertelement <4 x float> [[INS_1]], float [[TRUNC_1]], i64 0
-; CHECK-NEXT:    store <2 x double> <double 0.000000e+00, double 1.000000e+00>, ptr [[GEP_1]], align 8
-; CHECK-NEXT:    ret <4 x float> [[INS_2]]
-;
-  %trunc.1 = fptrunc double 0.000000e+00 to float
-  %trunc.2 = fptrunc double 1.000000e+00 to float
-  %ins.1 = insertelement <4 x float> zeroinitializer, float poison, i64 0
-  %ins.2 = insertelement <4 x float> %ins.1, float %trunc.1, i64 0
-  %ext.1 = fpext float %trunc.1 to double
-  %gep.1  = getelementptr double, ptr %0, i64 1
-  store double %ext.1, ptr %gep.1, align 8
-  %ext.2 = fpext float %trunc.2 to double
-  %gep.2 = getelementptr double, ptr %0, i64 2
-  store double %ext.2, ptr %gep.2, align 8
-  ret <4 x float> %ins.2
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll b/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
deleted file mode 100644
index edb8d615e0055..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/special_opcodes.ll
+++ /dev/null
@@ -1,97 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" %s -S | FileCheck %s
-
-; This file includes tests for opcodes that need special checks.
-
-; TODO: Selects with conditions of diff number of lanes than the instruction itself need special treatment.
-define void @selects_with_diff_cond_lanes(ptr %ptr, i1 %cond0, i1 %cond1, <2 x i8> %op0, <2 x i8> %op1) {
-; CHECK-LABEL: define void @selects_with_diff_cond_lanes(
-; CHECK-SAME: ptr [[PTR:%.*]], i1 [[COND0:%.*]], i1 [[COND1:%.*]], <2 x i8> [[OP0:%.*]], <2 x i8> [[OP1:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 1
-; CHECK-NEXT:    [[LD0:%.*]] = load <2 x i8>, ptr [[PTR0]], align 2
-; CHECK-NEXT:    [[LD1:%.*]] = load <2 x i8>, ptr [[PTR1]], align 2
-; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[COND0]], <2 x i8> [[LD0]], <2 x i8> [[LD0]]
-; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[COND1]], <2 x i8> [[LD1]], <2 x i8> [[LD1]]
-; CHECK-NEXT:    [[VPACK:%.*]] = extractelement <2 x i8> [[SEL0]], i32 0
-; CHECK-NEXT:    [[VPACK1:%.*]] = insertelement <4 x i8> poison, i8 [[VPACK]], i32 0
-; CHECK-NEXT:    [[VPACK2:%.*]] = extractelement <2 x i8> [[SEL0]], i32 1
-; CHECK-NEXT:    [[VPACK3:%.*]] = insertelement <4 x i8> [[VPACK1]], i8 [[VPACK2]], i32 1
-; CHECK-NEXT:    [[VPACK4:%.*]] = extractelement <2 x i8> [[SEL1]], i32 0
-; CHECK-NEXT:    [[VPACK5:%.*]] = insertelement <4 x i8> [[VPACK3]], i8 [[VPACK4]], i32 2
-; CHECK-NEXT:    [[VPACK6:%.*]] = extractelement <2 x i8> [[SEL1]], i32 1
-; CHECK-NEXT:    [[VPACK7:%.*]] = insertelement <4 x i8> [[VPACK5]], i8 [[VPACK6]], i32 3
-; CHECK-NEXT:    store <4 x i8> [[VPACK7]], ptr [[PTR0]], align 2
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x i8>, ptr %ptr, i32 0
-  %ptr1 = getelementptr <2 x i8>, ptr %ptr, i32 1
-  %ld0 = load <2 x i8>, ptr %ptr0
-  %ld1 = load <2 x i8>, ptr %ptr1
-  %sel0 = select i1 %cond0, <2 x i8> %ld0, <2 x i8> %ld0
-  %sel1 = select i1 %cond1, <2 x i8> %ld1, <2 x i8> %ld1
-  store <2 x i8> %sel0, ptr %ptr0
-  store <2 x i8> %sel1, ptr %ptr1
-  ret void
-}
-
-; TODO: Selects that share the same condition need special treatment.
-define void @selects_with_common_condition_but_diff_lanes(ptr %ptr, i1 %cond, <2 x i8> %op0, <2 x i8> %op1) {
-; CHECK-LABEL: define void @selects_with_common_condition_but_diff_lanes(
-; CHECK-SAME: ptr [[PTR:%.*]], i1 [[COND:%.*]], <2 x i8> [[OP0:%.*]], <2 x i8> [[OP1:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[PTR1:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 1
-; CHECK-NEXT:    [[LD0:%.*]] = load <2 x i8>, ptr [[PTR0]], align 2
-; CHECK-NEXT:    [[LD1:%.*]] = load <2 x i8>, ptr [[PTR1]], align 2
-; CHECK-NEXT:    [[SEL0:%.*]] = select i1 [[COND]], <2 x i8> [[LD0]], <2 x i8> [[LD0]]
-; CHECK-NEXT:    [[SEL1:%.*]] = select i1 [[COND]], <2 x i8> [[LD1]], <2 x i8> [[LD1]]
-; CHECK-NEXT:    [[VPACK:%.*]] = extractelement <2 x i8> [[SEL0]], i32 0
-; CHECK-NEXT:    [[VPACK1:%.*]] = insertelement <4 x i8> poison, i8 [[VPACK]], i32 0
-; CHECK-NEXT:    [[VPACK2:%.*]] = extractelement <2 x i8> [[SEL0]], i32 1
-; CHECK-NEXT:    [[VPACK3:%.*]] = insertelement <4 x i8> [[VPACK1]], i8 [[VPACK2]], i32 1
-; CHECK-NEXT:    [[VPACK4:%.*]] = extractelement <2 x i8> [[SEL1]], i32 0
-; CHECK-NEXT:    [[VPACK5:%.*]] = insertelement <4 x i8> [[VPACK3]], i8 [[VPACK4]], i32 2
-; CHECK-NEXT:    [[VPACK6:%.*]] = extractelement <2 x i8> [[SEL1]], i32 1
-; CHECK-NEXT:    [[VPACK7:%.*]] = insertelement <4 x i8> [[VPACK5]], i8 [[VPACK6]], i32 3
-; CHECK-NEXT:    store <4 x i8> [[VPACK7]], ptr [[PTR0]], align 2
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x i8>, ptr %ptr, i32 0
-  %ptr1 = getelementptr <2 x i8>, ptr %ptr, i32 1
-  %ld0 = load <2 x i8>, ptr %ptr0
-  %ld1 = load <2 x i8>, ptr %ptr1
-  %sel0 = select i1 %cond, <2 x i8> %ld0, <2 x i8> %ld0
-  %sel1 = select i1 %cond, <2 x i8> %ld1, <2 x i8> %ld1
-  store <2 x i8> %sel0, ptr %ptr0
-  store <2 x i8> %sel1, ptr %ptr1
-  ret void
-}
-
-; Selects with conditions of the same number of lanes as the instruction itself be vectorized as usual.
-define void @selects_same_cond_lanes(ptr %ptr, <2 x i1> %cond0, <2 x i1> %cond1, <2 x i8> %op0, <2 x i8> %op1) {
-; CHECK-LABEL: define void @selects_same_cond_lanes(
-; CHECK-SAME: ptr [[PTR:%.*]], <2 x i1> [[COND0:%.*]], <2 x i1> [[COND1:%.*]], <2 x i8> [[OP0:%.*]], <2 x i8> [[OP1:%.*]]) {
-; CHECK-NEXT:    [[PTR0:%.*]] = getelementptr <2 x i8>, ptr [[PTR]], i32 0
-; CHECK-NEXT:    [[VPACK:%.*]] = extractelement <2 x i1> [[COND0]], i32 0
-; CHECK-NEXT:    [[VPACK1:%.*]] = insertelement <4 x i1> poison, i1 [[VPACK]], i32 0
-; CHECK-NEXT:    [[VPACK2:%.*]] = extractelement <2 x i1> [[COND0]], i32 1
-; CHECK-NEXT:    [[VPACK3:%.*]] = insertelement <4 x i1> [[VPACK1]], i1 [[VPACK2]], i32 1
-; CHECK-NEXT:    [[VPACK4:%.*]] = extractelement <2 x i1> [[COND1]], i32 0
-; CHECK-NEXT:    [[VPACK5:%.*]] = insertelement <4 x i1> [[VPACK3]], i1 [[VPACK4]], i32 2
-; CHECK-NEXT:    [[VPACK6:%.*]] = extractelement <2 x i1> [[COND1]], i32 1
-; CHECK-NEXT:    [[VPACK7:%.*]] = insertelement <4 x i1> [[VPACK5]], i1 [[VPACK6]], i32 3
-; CHECK-NEXT:    [[VECL:%.*]] = load <4 x i8>, ptr [[PTR0]], align 2
-; CHECK-NEXT:    [[VEC:%.*]] = select <4 x i1> [[VPACK7]], <4 x i8> [[VECL]], <4 x i8> [[VECL]]
-; CHECK-NEXT:    store <4 x i8> [[VEC]], ptr [[PTR0]], align 2
-; CHECK-NEXT:    ret void
-;
-  %ptr0 = getelementptr <2 x i8>, ptr %ptr, i32 0
-  %ptr1 = getelementptr <2 x i8>, ptr %ptr, i32 1
-  %ld0 = load <2 x i8>, ptr %ptr0
-  %ld1 = load <2 x i8>, ptr %ptr1
-  %sel0 = select <2 x i1> %cond0, <2 x i8> %ld0, <2 x i8> %ld0
-  %sel1 = select <2 x i1> %cond1, <2 x i8> %ld1, <2 x i8> %ld1
-  store <2 x i8> %sel0, ptr %ptr0
-  store <2 x i8> %sel1, ptr %ptr1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/stop_at.ll b/llvm/test/Transforms/SandboxVectorizer/stop_at.ll
deleted file mode 100644
index f37b9f1fd7587..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/stop_at.ll
+++ /dev/null
@@ -1,61 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" --sbvec-stop-at=0 %s -S | FileCheck %s --check-prefix=STOPAT0
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" --sbvec-stop-at=1 %s -S | FileCheck %s --check-prefix=STOPAT1
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" --sbvec-stop-at=2 %s -S | FileCheck %s --check-prefix=STOPAT2
-
-define void @widen(ptr %ptrA, ptr %ptrB) {
-; STOPAT0-LABEL: define void @widen(
-; STOPAT0-SAME: ptr [[PTRA:%.*]], ptr [[PTRB:%.*]]) {
-; STOPAT0-NEXT:    [[PTRA0:%.*]] = getelementptr float, ptr [[PTRA]], i32 0
-; STOPAT0-NEXT:    [[PTRA1:%.*]] = getelementptr float, ptr [[PTRA]], i32 1
-; STOPAT0-NEXT:    [[LDA0:%.*]] = load float, ptr [[PTRA0]], align 4
-; STOPAT0-NEXT:    [[LDA1:%.*]] = load float, ptr [[PTRA1]], align 4
-; STOPAT0-NEXT:    store float [[LDA0]], ptr [[PTRA0]], align 4
-; STOPAT0-NEXT:    store float [[LDA1]], ptr [[PTRA1]], align 4
-; STOPAT0-NEXT:    [[PTRB0:%.*]] = getelementptr float, ptr [[PTRB]], i32 0
-; STOPAT0-NEXT:    [[PTRB1:%.*]] = getelementptr float, ptr [[PTRB]], i32 1
-; STOPAT0-NEXT:    [[LDB0:%.*]] = load float, ptr [[PTRB0]], align 4
-; STOPAT0-NEXT:    [[LDB1:%.*]] = load float, ptr [[PTRB1]], align 4
-; STOPAT0-NEXT:    store float [[LDB0]], ptr [[PTRB0]], align 4
-; STOPAT0-NEXT:    store float [[LDB1]], ptr [[PTRB1]], align 4
-; STOPAT0-NEXT:    ret void
-;
-; STOPAT1-LABEL: define void @widen(
-; STOPAT1-SAME: ptr [[PTRA:%.*]], ptr [[PTRB:%.*]]) {
-; STOPAT1-NEXT:    [[PTRA0:%.*]] = getelementptr float, ptr [[PTRA]], i32 0
-; STOPAT1-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTRA0]], align 4
-; STOPAT1-NEXT:    store <2 x float> [[VECL]], ptr [[PTRA0]], align 4
-; STOPAT1-NEXT:    [[PTRB0:%.*]] = getelementptr float, ptr [[PTRB]], i32 0
-; STOPAT1-NEXT:    [[PTRB1:%.*]] = getelementptr float, ptr [[PTRB]], i32 1
-; STOPAT1-NEXT:    [[LDB0:%.*]] = load float, ptr [[PTRB0]], align 4
-; STOPAT1-NEXT:    [[LDB1:%.*]] = load float, ptr [[PTRB1]], align 4
-; STOPAT1-NEXT:    store float [[LDB0]], ptr [[PTRB0]], align 4
-; STOPAT1-NEXT:    store float [[LDB1]], ptr [[PTRB1]], align 4
-; STOPAT1-NEXT:    ret void
-;
-; STOPAT2-LABEL: define void @widen(
-; STOPAT2-SAME: ptr [[PTRA:%.*]], ptr [[PTRB:%.*]]) {
-; STOPAT2-NEXT:    [[PTRA0:%.*]] = getelementptr float, ptr [[PTRA]], i32 0
-; STOPAT2-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTRA0]], align 4
-; STOPAT2-NEXT:    store <2 x float> [[VECL]], ptr [[PTRA0]], align 4
-; STOPAT2-NEXT:    [[PTRB0:%.*]] = getelementptr float, ptr [[PTRB]], i32 0
-; STOPAT2-NEXT:    [[VECL1:%.*]] = load <2 x float>, ptr [[PTRB0]], align 4
-; STOPAT2-NEXT:    store <2 x float> [[VECL1]], ptr [[PTRB0]], align 4
-; STOPAT2-NEXT:    ret void
-;
-  %ptrA0 = getelementptr float, ptr %ptrA, i32 0
-  %ptrA1 = getelementptr float, ptr %ptrA, i32 1
-  %ldA0 = load float, ptr %ptrA0
-  %ldA1 = load float, ptr %ptrA1
-  store float %ldA0, ptr %ptrA0
-  store float %ldA1, ptr %ptrA1
-
-  %ptrB0 = getelementptr float, ptr %ptrB, i32 0
-  %ptrB1 = getelementptr float, ptr %ptrB, i32 1
-  %ldB0 = load float, ptr %ptrB0
-  %ldB1 = load float, ptr %ptrB1
-  store float %ldB0, ptr %ptrB0
-  store float %ldB1, ptr %ptrB1
-
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/stop_bndl.ll b/llvm/test/Transforms/SandboxVectorizer/stop_bndl.ll
deleted file mode 100644
index 61e2d82a3e5c1..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/stop_bndl.ll
+++ /dev/null
@@ -1,71 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-stop-bndl=0 %s -S | FileCheck %s --check-prefix=STOP0
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-stop-bndl=1 %s -S | FileCheck %s --check-prefix=STOP1
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-stop-bndl=2 %s -S | FileCheck %s --check-prefix=STOP2
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>" -sbvec-stop-bndl=3 %s -S | FileCheck %s --check-prefix=STOP3
-; RUN: opt -passes=sandbox-vectorizer -sbvec-vec-reg-bits=1024 -sbvec-allow-non-pow2 -sbvec-passes="seed-collection<tr-save,bottom-up-vec,tr-accept>"  %s -S | FileCheck %s --check-prefix=NOSTOP
-
-define void @stop_bndl(ptr %ptr) {
-; STOP0-LABEL: define void @stop_bndl(
-; STOP0-SAME: ptr [[PTR:%.*]]) {
-; STOP0-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; STOP0-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; STOP0-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; STOP0-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; STOP0-NEXT:    [[ADD0:%.*]] = fadd float [[LD0]], 0.000000e+00
-; STOP0-NEXT:    [[ADD1:%.*]] = fadd float [[LD1]], 0.000000e+00
-; STOP0-NEXT:    store float [[ADD0]], ptr [[PTR0]], align 4
-; STOP0-NEXT:    store float [[ADD1]], ptr [[PTR1]], align 4
-; STOP0-NEXT:    ret void
-;
-; STOP1-LABEL: define void @stop_bndl(
-; STOP1-SAME: ptr [[PTR:%.*]]) {
-; STOP1-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; STOP1-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; STOP1-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; STOP1-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; STOP1-NEXT:    [[ADD0:%.*]] = fadd float [[LD0]], 0.000000e+00
-; STOP1-NEXT:    [[ADD1:%.*]] = fadd float [[LD1]], 0.000000e+00
-; STOP1-NEXT:    [[PACK:%.*]] = insertelement <2 x float> poison, float [[ADD0]], i32 0
-; STOP1-NEXT:    [[PACK1:%.*]] = insertelement <2 x float> [[PACK]], float [[ADD1]], i32 1
-; STOP1-NEXT:    store <2 x float> [[PACK1]], ptr [[PTR0]], align 4
-; STOP1-NEXT:    ret void
-;
-; STOP2-LABEL: define void @stop_bndl(
-; STOP2-SAME: ptr [[PTR:%.*]]) {
-; STOP2-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; STOP2-NEXT:    [[PTR1:%.*]] = getelementptr float, ptr [[PTR]], i32 1
-; STOP2-NEXT:    [[LD0:%.*]] = load float, ptr [[PTR0]], align 4
-; STOP2-NEXT:    [[LD1:%.*]] = load float, ptr [[PTR1]], align 4
-; STOP2-NEXT:    [[PACK:%.*]] = insertelement <2 x float> poison, float [[LD0]], i32 0
-; STOP2-NEXT:    [[PACK1:%.*]] = insertelement <2 x float> [[PACK]], float [[LD1]], i32 1
-; STOP2-NEXT:    [[VEC:%.*]] = fadd <2 x float> [[PACK1]], zeroinitializer
-; STOP2-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4
-; STOP2-NEXT:    ret void
-;
-; STOP3-LABEL: define void @stop_bndl(
-; STOP3-SAME: ptr [[PTR:%.*]]) {
-; STOP3-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; STOP3-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; STOP3-NEXT:    [[VEC:%.*]] = fadd <2 x float> [[VECL]], zeroinitializer
-; STOP3-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4
-; STOP3-NEXT:    ret void
-;
-; NOSTOP-LABEL: define void @stop_bndl(
-; NOSTOP-SAME: ptr [[PTR:%.*]]) {
-; NOSTOP-NEXT:    [[PTR0:%.*]] = getelementptr float, ptr [[PTR]], i32 0
-; NOSTOP-NEXT:    [[VECL:%.*]] = load <2 x float>, ptr [[PTR0]], align 4
-; NOSTOP-NEXT:    [[VEC:%.*]] = fadd <2 x float> [[VECL]], zeroinitializer
-; NOSTOP-NEXT:    store <2 x float> [[VEC]], ptr [[PTR0]], align 4
-; NOSTOP-NEXT:    ret void
-;
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %ptr0
-  %ld1 = load float, ptr %ptr1
-  %add0 = fadd float %ld0, 0.0
-  %add1 = fadd float %ld1, 0.0
-  store float %add0, ptr %ptr0
-  store float %add1, ptr %ptr1
-  ret void
-}
diff --git a/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll b/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll
deleted file mode 100644
index 2c57a8e7347d2..0000000000000
--- a/llvm/test/Transforms/SandboxVectorizer/user_pass_pipeline.ll
+++ /dev/null
@@ -1,28 +0,0 @@
-; RUN: opt -passes=sandbox-vectorizer -sbvec-print-pass-pipeline \
-; RUN:     -disable-output -sbvec-passes="seed-collection<null,null>" %s \
-; RUN:     | FileCheck %s
-;
-; RUN: opt -passes=sandbox-vectorizer -sbvec-print-pass-pipeline \
-; RUN:     -disable-output -sbvec-passes="seed-collection<>,regions-from-metadata<>" %s \
-; RUN:     | FileCheck --check-prefix CHECK-MULTIPLE-FUNCTION-PASSES %s
-
-; !!!WARNING!!! This won't get updated by update_test_checks.py !
-
-; This checks the user defined pass pipeline.
-define void @pipeline() {
-  ret void
-}
-
-; CHECK: fpm
-; CHECK: seed-collection
-; CHECK: rpm
-; CHECK: null
-; CHECK: null
-; CHECK-EMPTY:
-
-; CHECK-MULTIPLE-FUNCTION-PASSES: fpm
-; CHECK-MULTIPLE-FUNCTION-PASSES: seed-collection
-; CHECK-MULTIPLE-FUNCTION-PASSES: rpm
-; CHECK-MULTIPLE-FUNCTION-PASSES: regions-from-metadata
-; CHECK-MULTIPLE-FUNCTION-PASSES: rpm
-; CHECK-MULTIPLE-FUNCTION-PASSES-EMPTY:
diff --git a/llvm/unittests/CMakeLists.txt b/llvm/unittests/CMakeLists.txt
index d22613d12d6dc..d025754ecb431 100644
--- a/llvm/unittests/CMakeLists.txt
+++ b/llvm/unittests/CMakeLists.txt
@@ -59,7 +59,6 @@ add_subdirectory(Option)
 add_subdirectory(Remarks)
 add_subdirectory(Passes)
 add_subdirectory(ProfileData)
-add_subdirectory(SandboxIR)
 add_subdirectory(Support)
 add_subdirectory(TableGen)
 add_subdirectory(Target)
diff --git a/llvm/unittests/SandboxIR/CMakeLists.txt b/llvm/unittests/SandboxIR/CMakeLists.txt
deleted file mode 100644
index b20ef829ed0c9..0000000000000
--- a/llvm/unittests/SandboxIR/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  AsmParser
-  SandboxIR
-  Core
-  Analysis
-  )
-
-add_llvm_unittest(SandboxIRTests
-  IntrinsicInstTest.cpp
-  PassTest.cpp
-  RegionTest.cpp
-  OperatorTest.cpp
-  SandboxIRTest.cpp
-  TrackerTest.cpp
-  TypesTest.cpp
-  UtilsTest.cpp
-  )
diff --git a/llvm/unittests/SandboxIR/IntrinsicInstTest.cpp b/llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
deleted file mode 100644
index 2272cfc114616..0000000000000
--- a/llvm/unittests/SandboxIR/IntrinsicInstTest.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-//===- IntrinsicInstTest.cpp ----------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/IntrinsicInst.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/IntrinsicInst.h"
-#include "llvm/IR/Value.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct IntrinsicInstTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("SandboxIRTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-TEST_F(IntrinsicInstTest, Basic) {
-  parseIR(C, R"IR(
-declare void @llvm.sideeffect()
-declare void @llvm.assume(i1)
-declare i8 @llvm.uadd.sat.i8(i8, i8)
-declare i8 @llvm.smax.i8(i8, i8)
-
-define void @foo(i8 %v1, i1 %cond) {
-  call void @llvm.sideeffect()
-  call void @llvm.assume(i1 %cond)
-  call i8 @llvm.uadd.sat.i8(i8 %v1, i8 %v1)
-  call i8 @llvm.smax.i8(i8 %v1, i8 %v1)
-  ret void
-}
-)IR");
-
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF->begin();
-  auto LLVMIt = LLVMBB->begin();
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto ItE = BB->getTerminator()->getIterator();
-  for (; It != ItE; ++It, ++LLVMIt) {
-    auto *I = &*It;
-    auto *LLVMI = &*LLVMIt;
-    // Check classof().
-    EXPECT_TRUE(isa<sandboxir::IntrinsicInst>(I));
-    // Check getIntrinsicID().
-    EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->getIntrinsicID(),
-              cast<llvm::IntrinsicInst>(LLVMI)->getIntrinsicID());
-    // Check isAssociative().
-    EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isAssociative(),
-              cast<llvm::IntrinsicInst>(LLVMI)->isAssociative());
-    // Check isCommutative().
-    EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isCommutative(),
-              cast<llvm::IntrinsicInst>(LLVMI)->isCommutative());
-    // Check isAssumeLikeIntrinsic().
-    EXPECT_EQ(cast<sandboxir::IntrinsicInst>(I)->isAssumeLikeIntrinsic(),
-              cast<llvm::IntrinsicInst>(LLVMI)->isAssumeLikeIntrinsic());
-    // Check mayLowerToFunctionCall().
-    auto ID = cast<sandboxir::IntrinsicInst>(I)->getIntrinsicID();
-    EXPECT_EQ(sandboxir::IntrinsicInst::mayLowerToFunctionCall(ID),
-              llvm::IntrinsicInst::mayLowerToFunctionCall(ID));
-  }
-}
diff --git a/llvm/unittests/SandboxIR/OperatorTest.cpp b/llvm/unittests/SandboxIR/OperatorTest.cpp
deleted file mode 100644
index b1e324417da41..0000000000000
--- a/llvm/unittests/SandboxIR/OperatorTest.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-//===- OperatorTest.cpp ---------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Operator.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Module.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct OperatorTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("OperatorTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-TEST_F(OperatorTest, Operator) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v1) {
-  %add0 = add i8 %v1, 42
-  %add1 = add nuw i8 %v1, 42
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *OperatorI0 = cast<sandboxir::Operator>(&*It++);
-  auto *OperatorI1 = cast<sandboxir::Operator>(&*It++);
-  EXPECT_FALSE(OperatorI0->hasPoisonGeneratingFlags());
-  EXPECT_TRUE(OperatorI1->hasPoisonGeneratingFlags());
-}
-
-TEST_F(OperatorTest, OverflowingBinaryOperator) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v1) {
-  %add = add i8 %v1, 42
-  %addNSW = add nsw i8 %v1, 42
-  %addNUW = add nuw i8 %v1, 42
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
-  auto *AddNSW = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
-  auto *AddNUW = cast<sandboxir::OverflowingBinaryOperator>(&*It++);
-  EXPECT_FALSE(Add->hasNoUnsignedWrap());
-  EXPECT_FALSE(Add->hasNoSignedWrap());
-  EXPECT_EQ(Add->getNoWrapKind(), llvm::OverflowingBinaryOperator::AnyWrap);
-
-  EXPECT_FALSE(AddNSW->hasNoUnsignedWrap());
-  EXPECT_TRUE(AddNSW->hasNoSignedWrap());
-  EXPECT_EQ(AddNSW->getNoWrapKind(),
-            llvm::OverflowingBinaryOperator::NoSignedWrap);
-
-  EXPECT_TRUE(AddNUW->hasNoUnsignedWrap());
-  EXPECT_FALSE(AddNUW->hasNoSignedWrap());
-  EXPECT_EQ(AddNUW->getNoWrapKind(),
-            llvm::OverflowingBinaryOperator::NoUnsignedWrap);
-}
-
-TEST_F(OperatorTest, FPMathOperator) {
-  parseIR(C, R"IR(
-define void @foo(float %v1, double %v2) {
-  %fadd = fadd float %v1, 42.0
-  %Fast = fadd fast float %v1, 42.0
-  %Reassoc = fmul reassoc float %v1, 42.0
-  %NNAN = fmul nnan float %v1, 42.0
-  %NINF = fmul ninf float %v1, 42.0
-  %NSZ = fmul nsz float %v1, 42.0
-  %ARCP = fmul arcp float %v1, 42.0
-  %CONTRACT = fmul contract float %v1, 42.0
-  %AFN = fmul afn double %v2, 42.0
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF->begin();
-  auto LLVMIt = LLVMBB->begin();
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto TermIt = BB->getTerminator()->getIterator();
-  while (It != TermIt) {
-    auto *FPM = cast<sandboxir::FPMathOperator>(&*It++);
-    auto *LLVMFPM = cast<llvm::FPMathOperator>(&*LLVMIt++);
-    EXPECT_EQ(FPM->isFast(), LLVMFPM->isFast());
-    EXPECT_EQ(FPM->hasAllowReassoc(), LLVMFPM->hasAllowReassoc());
-    EXPECT_EQ(FPM->hasNoNaNs(), LLVMFPM->hasNoNaNs());
-    EXPECT_EQ(FPM->hasNoInfs(), LLVMFPM->hasNoInfs());
-    EXPECT_EQ(FPM->hasNoSignedZeros(), LLVMFPM->hasNoSignedZeros());
-    EXPECT_EQ(FPM->hasAllowReciprocal(), LLVMFPM->hasAllowReciprocal());
-    EXPECT_EQ(FPM->hasAllowContract(), LLVMFPM->hasAllowContract());
-    EXPECT_EQ(FPM->hasApproxFunc(), LLVMFPM->hasApproxFunc());
-
-    // There doesn't seem to be an operator== for FastMathFlags so let's do a
-    // string comparison instead.
-    std::string Str1;
-    raw_string_ostream SS1(Str1);
-    std::string Str2;
-    raw_string_ostream SS2(Str2);
-    FPM->getFastMathFlags().print(SS1);
-    LLVMFPM->getFastMathFlags().print(SS2);
-    EXPECT_EQ(Str1, Str2);
-
-    EXPECT_EQ(FPM->getFPAccuracy(), LLVMFPM->getFPAccuracy());
-    EXPECT_EQ(
-        sandboxir::FPMathOperator::isSupportedFloatingPointType(FPM->getType()),
-        llvm::FPMathOperator::isSupportedFloatingPointType(LLVMFPM->getType()));
-  }
-}
diff --git a/llvm/unittests/SandboxIR/PassTest.cpp b/llvm/unittests/SandboxIR/PassTest.cpp
deleted file mode 100644
index 1a32702fa4ac2..0000000000000
--- a/llvm/unittests/SandboxIR/PassTest.cpp
+++ /dev/null
@@ -1,351 +0,0 @@
-//===- PassTest.cpp -------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Pass.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/PassManager.h"
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gtest/gtest.h"
-
-using namespace llvm::sandboxir;
-
-struct PassTest : public testing::Test {
-  llvm::LLVMContext LLVMCtx;
-  std::unique_ptr<llvm::Module> LLVMM;
-  std::unique_ptr<Context> Ctx;
-  std::unique_ptr<llvm::TargetTransformInfo> TTI;
-
-  Function *parseFunction(const char *IR, const char *FuncName) {
-    llvm::SMDiagnostic Err;
-    LLVMM = parseAssemblyString(IR, Err, LLVMCtx);
-    TTI = std::make_unique<llvm::TargetTransformInfo>(LLVMM->getDataLayout());
-
-    if (!LLVMM)
-      Err.print("PassTest", llvm::errs());
-    Ctx = std::make_unique<Context>(LLVMCtx);
-    return Ctx->createFunction(LLVMM->getFunction(FuncName));
-  }
-};
-
-TEST_F(PassTest, FunctionPass) {
-  auto *F = parseFunction(R"IR(
-define void @foo() {
-  ret void
-}
-)IR",
-                          "foo");
-  class TestPass final : public FunctionPass {
-    unsigned &BBCnt;
-
-  public:
-    TestPass(unsigned &BBCnt) : FunctionPass("test-pass"), BBCnt(BBCnt) {}
-    bool runOnFunction(Function &F, const Analyses &A) final {
-      for ([[maybe_unused]] auto &BB : F)
-        ++BBCnt;
-      return false;
-    }
-  };
-  unsigned BBCnt = 0;
-  TestPass TPass(BBCnt);
-  // Check getName(),
-  EXPECT_EQ(TPass.getName(), "test-pass");
-  // Check classof().
-  EXPECT_TRUE(llvm::isa<FunctionPass>(TPass));
-  // Check runOnFunction();
-  TPass.runOnFunction(*F, Analyses::emptyForTesting());
-  EXPECT_EQ(BBCnt, 1u);
-#ifndef NDEBUG
-  {
-    // Check print().
-    std::string Buff;
-    llvm::raw_string_ostream SS(Buff);
-    TPass.print(SS);
-    EXPECT_EQ(Buff, "test-pass");
-  }
-  {
-    // Check operator<<().
-    std::string Buff;
-    llvm::raw_string_ostream SS(Buff);
-    SS << TPass;
-    EXPECT_EQ(Buff, "test-pass");
-  }
-  // Check pass name assertions.
-  class TestNamePass final : public FunctionPass {
-  public:
-    TestNamePass(llvm::StringRef Name) : FunctionPass(Name) {}
-    bool runOnFunction(Function &F, const Analyses &A) override {
-      return false;
-    }
-  };
-  EXPECT_DEATH(TestNamePass("white space"), ".*whitespace.*");
-  EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
-#endif
-}
-
-TEST_F(PassTest, RegionPass) {
-  auto *F = parseFunction(R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1, !sandboxvec !0
-  %t2 = add i8 %t1, %v1, !sandboxvec !0
-  ret i8 %t1
-}
-
-!0 = distinct !{!"sandboxregion"}
-)IR",
-                          "foo");
-
-  class TestPass final : public RegionPass {
-    unsigned &InstCount;
-
-  public:
-    TestPass(unsigned &InstCount)
-        : RegionPass("test-pass"), InstCount(InstCount) {}
-    bool runOnRegion(Region &R, const Analyses &A) final {
-      for ([[maybe_unused]] auto &Inst : R) {
-        ++InstCount;
-      }
-      return false;
-    }
-  };
-  unsigned InstCount = 0;
-  TestPass TPass(InstCount);
-  // Check getName(),
-  EXPECT_EQ(TPass.getName(), "test-pass");
-  // Check runOnRegion();
-  llvm::SmallVector<std::unique_ptr<Region>> Regions =
-      Region::createRegionsFromMD(*F, *TTI);
-  ASSERT_EQ(Regions.size(), 1u);
-  TPass.runOnRegion(*Regions[0], Analyses::emptyForTesting());
-  EXPECT_EQ(InstCount, 2u);
-#ifndef NDEBUG
-  {
-    // Check print().
-    std::string Buff;
-    llvm::raw_string_ostream SS(Buff);
-    TPass.print(SS);
-    EXPECT_EQ(Buff, "test-pass");
-  }
-  {
-    // Check operator<<().
-    std::string Buff;
-    llvm::raw_string_ostream SS(Buff);
-    SS << TPass;
-    EXPECT_EQ(Buff, "test-pass");
-  }
-  // Check pass name assertions.
-  class TestNamePass final : public RegionPass {
-  public:
-    TestNamePass(llvm::StringRef Name) : RegionPass(Name) {}
-    bool runOnRegion(Region &F, const Analyses &A) override { return false; }
-  };
-  EXPECT_DEATH(TestNamePass("white space"), ".*whitespace.*");
-  EXPECT_DEATH(TestNamePass("-dash"), ".*start with.*");
-#endif
-}
-
-TEST_F(PassTest, FunctionPassManager) {
-  auto *F = parseFunction(R"IR(
-define void @foo() {
-  ret void
-}
-)IR",
-                          "foo");
-  class TestPass1 final : public FunctionPass {
-    unsigned &BBCnt;
-
-  public:
-    TestPass1(unsigned &BBCnt) : FunctionPass("test-pass1"), BBCnt(BBCnt) {}
-    bool runOnFunction(Function &F, const Analyses &A) final {
-      for ([[maybe_unused]] auto &BB : F)
-        ++BBCnt;
-      return false;
-    }
-  };
-  class TestPass2 final : public FunctionPass {
-    unsigned &BBCnt;
-
-  public:
-    TestPass2(unsigned &BBCnt) : FunctionPass("test-pass2"), BBCnt(BBCnt) {}
-    bool runOnFunction(Function &F, const Analyses &A) final {
-      for ([[maybe_unused]] auto &BB : F)
-        ++BBCnt;
-      return false;
-    }
-  };
-  unsigned BBCnt1 = 0;
-  unsigned BBCnt2 = 0;
-
-  FunctionPassManager FPM("test-fpm");
-  FPM.addPass(std::make_unique<TestPass1>(BBCnt1));
-  FPM.addPass(std::make_unique<TestPass2>(BBCnt2));
-  // Check runOnFunction().
-  FPM.runOnFunction(*F, Analyses::emptyForTesting());
-  EXPECT_EQ(BBCnt1, 1u);
-  EXPECT_EQ(BBCnt2, 1u);
-#ifndef NDEBUG
-  // Check dump().
-  std::string Buff;
-  llvm::raw_string_ostream SS(Buff);
-  FPM.print(SS);
-  EXPECT_EQ(Buff, "test-fpm<test-pass1,test-pass2>");
-#endif // NDEBUG
-}
-
-TEST_F(PassTest, RegionPassManager) {
-  auto *F = parseFunction(R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1, !sandboxvec !0
-  %t2 = add i8 %t1, %v1, !sandboxvec !0
-  ret i8 %t1
-}
-
-!0 = distinct !{!"sandboxregion"}
-)IR",
-                          "foo");
-
-  class TestPass1 final : public RegionPass {
-    unsigned &InstCount;
-
-  public:
-    TestPass1(unsigned &InstCount)
-        : RegionPass("test-pass1"), InstCount(InstCount) {}
-    bool runOnRegion(Region &R, const Analyses &A) final {
-      for ([[maybe_unused]] auto &Inst : R)
-        ++InstCount;
-      return false;
-    }
-  };
-  class TestPass2 final : public RegionPass {
-    unsigned &InstCount;
-
-  public:
-    TestPass2(unsigned &InstCount)
-        : RegionPass("test-pass2"), InstCount(InstCount) {}
-    bool runOnRegion(Region &R, const Analyses &A) final {
-      for ([[maybe_unused]] auto &Inst : R)
-        ++InstCount;
-      return false;
-    }
-  };
-  unsigned InstCount1 = 0;
-  unsigned InstCount2 = 0;
-
-  RegionPassManager RPM("test-rpm");
-  RPM.addPass(std::make_unique<TestPass1>(InstCount1));
-  RPM.addPass(std::make_unique<TestPass2>(InstCount2));
-  // Check runOnRegion().
-  llvm::SmallVector<std::unique_ptr<Region>> Regions =
-      Region::createRegionsFromMD(*F, *TTI);
-  ASSERT_EQ(Regions.size(), 1u);
-  RPM.runOnRegion(*Regions[0], Analyses::emptyForTesting());
-  EXPECT_EQ(InstCount1, 2u);
-  EXPECT_EQ(InstCount2, 2u);
-#ifndef NDEBUG
-  // Check dump().
-  std::string Buff;
-  llvm::raw_string_ostream SS(Buff);
-  RPM.print(SS);
-  EXPECT_EQ(Buff, "test-rpm<test-pass1,test-pass2>");
-#endif // NDEBUG
-}
-
-TEST_F(PassTest, SetPassPipeline) {
-  auto *F = parseFunction(R"IR(
-define void @f() {
-  ret void
-}
-)IR",
-                          "f");
-  class FooPass final : public FunctionPass {
-    std::string &Str;
-    std::string Args;
-
-  public:
-    FooPass(std::string &Str, llvm::StringRef Args)
-        : FunctionPass("foo-pass"), Str(Str), Args(Args.str()) {}
-    bool runOnFunction(Function &F, const Analyses &A) final {
-      Str += "foo<" + Args + ">";
-      return false;
-    }
-  };
-  class BarPass final : public FunctionPass {
-    std::string &Str;
-    std::string Args;
-
-  public:
-    BarPass(std::string &Str, llvm::StringRef Args)
-        : FunctionPass("bar-pass"), Str(Str), Args(Args.str()) {}
-    bool runOnFunction(Function &F, const Analyses &A) final {
-      Str += "bar<" + Args + ">";
-      return false;
-    }
-  };
-
-  std::string Str;
-  auto CreatePass =
-      [&Str](llvm::StringRef Name,
-             llvm::StringRef Args) -> std::unique_ptr<FunctionPass> {
-    if (Name == "foo")
-      return std::make_unique<FooPass>(Str, Args);
-    if (Name == "bar")
-      return std::make_unique<BarPass>(Str, Args);
-    return nullptr;
-  };
-
-  FunctionPassManager FPM("test-fpm");
-  FPM.setPassPipeline("foo<abc>,bar<nested1<nested2<nested3>>>,foo",
-                      CreatePass);
-  FPM.runOnFunction(*F, Analyses::emptyForTesting());
-  EXPECT_EQ(Str, "foo<abc>bar<nested1<nested2<nested3>>>foo<>");
-
-  // A second call to setPassPipeline will trigger an assertion in debug mode.
-#ifndef NDEBUG
-  EXPECT_DEATH(FPM.setPassPipeline("bar,bar,foo", CreatePass),
-               "setPassPipeline called on a non-empty sandboxir::PassManager");
-#endif
-
-  // Fresh PM for the death tests so they die from bad pipeline strings, rather
-  // than from multiple setPassPipeline calls.
-  FunctionPassManager FPM2("test-fpm");
-  // Bad/empty pass names.
-  EXPECT_DEATH(FPM2.setPassPipeline("bad-pass-name", CreatePass),
-               ".*not registered.*");
-  EXPECT_DEATH(FPM2.setPassPipeline(",", CreatePass), ".*empty pass name.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("<>", CreatePass), ".*empty pass name.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("<>foo", CreatePass),
-               ".*empty pass name.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("foo,<>", CreatePass),
-               ".*empty pass name.*");
-
-  // Mismatched argument brackets.
-  EXPECT_DEATH(FPM2.setPassPipeline("foo<", CreatePass), ".*Missing '>'.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("foo<bar", CreatePass), ".*Missing '>'.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("foo<bar<>", CreatePass),
-               ".*Missing '>'.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("foo>", CreatePass), ".*Unexpected '>'.*");
-  EXPECT_DEATH(FPM2.setPassPipeline(">foo", CreatePass), ".*Unexpected '>'.*");
-  // Extra garbage between args and next delimiter/end-of-string.
-  EXPECT_DEATH(FPM2.setPassPipeline("foo<bar<>>>", CreatePass),
-               ".*Expected delimiter.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("bar<>foo", CreatePass),
-               ".*Expected delimiter.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("bar<>foo,baz", CreatePass),
-               ".*Expected delimiter.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("foo<args><more-args>", CreatePass),
-               ".*Expected delimiter.*");
-  EXPECT_DEATH(FPM2.setPassPipeline("foo<args>bar", CreatePass),
-               ".*Expected delimiter.*");
-}
diff --git a/llvm/unittests/SandboxIR/RegionTest.cpp b/llvm/unittests/SandboxIR/RegionTest.cpp
deleted file mode 100644
index 5d7283fa1024f..0000000000000
--- a/llvm/unittests/SandboxIR/RegionTest.cpp
+++ /dev/null
@@ -1,512 +0,0 @@
-//===- RegionTest.cpp -----------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Region.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock-matchers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct RegionTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-  std::unique_ptr<TargetTransformInfo> TTI;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    TTI = std::make_unique<TargetTransformInfo>(M->getDataLayout());
-    if (!M)
-      Err.print("RegionTest", errs());
-  }
-};
-
-TEST_F(RegionTest, Basic) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1
-  ret i8 %t1
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  auto *T1 = cast<sandboxir::Instruction>(&*It++);
-  auto *Ret = cast<sandboxir::Instruction>(&*It++);
-  sandboxir::Region Rgn(Ctx, *TTI);
-
-  // Check getContext.
-  EXPECT_EQ(&Ctx, &Rgn.getContext());
-
-  // Check add / remove / empty.
-  EXPECT_TRUE(Rgn.empty());
-  sandboxir::RegionInternalsAttorney::add(Rgn, T0);
-  EXPECT_FALSE(Rgn.empty());
-  sandboxir::RegionInternalsAttorney::remove(Rgn, T0);
-  EXPECT_TRUE(Rgn.empty());
-
-  // Check iteration.
-  sandboxir::RegionInternalsAttorney::add(Rgn, T0);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T1);
-  sandboxir::RegionInternalsAttorney::add(Rgn, Ret);
-  // Use an ordered matcher because we're supposed to preserve the insertion
-  // order for determinism.
-  EXPECT_THAT(Rgn.insts(), testing::ElementsAre(T0, T1, Ret));
-
-  // Check contains
-  EXPECT_TRUE(Rgn.contains(T0));
-  sandboxir::RegionInternalsAttorney::remove(Rgn, T0);
-  EXPECT_FALSE(Rgn.contains(T0));
-
-#ifndef NDEBUG
-  // Check equality comparison. Insert in reverse order into `Other` to check
-  // that comparison is order-independent.
-  sandboxir::Region Other(Ctx, *TTI);
-  sandboxir::RegionInternalsAttorney::add(Other, Ret);
-  EXPECT_NE(Rgn, Other);
-  sandboxir::RegionInternalsAttorney::add(Other, T1);
-  EXPECT_EQ(Rgn, Other);
-#endif
-}
-
-TEST_F(RegionTest, CallbackUpdates) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1, ptr %ptr) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1
-  ret i8 %t0
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *Ptr = F->getArg(2);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  auto *T1 = cast<sandboxir::Instruction>(&*It++);
-  auto *Ret = cast<sandboxir::Instruction>(&*It++);
-  sandboxir::Region Rgn(Ctx, *TTI);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T0);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T1);
-
-  // Test creation.
-  auto *NewI = sandboxir::StoreInst::create(T0, Ptr, /*Align=*/std::nullopt,
-                                            Ret->getIterator(), Ctx);
-  EXPECT_THAT(Rgn.insts(), testing::ElementsAre(T0, T1, NewI));
-
-  // Test deletion.
-  T1->eraseFromParent();
-  EXPECT_THAT(Rgn.insts(), testing::ElementsAre(T0, NewI));
-}
-
-TEST_F(RegionTest, MetadataFromIR) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1, !sandboxvec !0
-  %t1 = add i8 %t0, %v1, !sandboxvec !1
-  %t2 = add i8 %t1, %v1, !sandboxvec !1
-  ret i8 %t2
-}
-
-!0 = distinct !{!"sandboxregion"}
-!1 = distinct !{!"sandboxregion"}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  auto *T1 = cast<sandboxir::Instruction>(&*It++);
-  auto *T2 = cast<sandboxir::Instruction>(&*It++);
-
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  EXPECT_THAT(Regions[0]->insts(), testing::UnorderedElementsAre(T0));
-  EXPECT_THAT(Regions[1]->insts(), testing::UnorderedElementsAre(T1, T2));
-}
-
-TEST_F(RegionTest, NonContiguousRegion) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1, !sandboxvec !0
-  %t1 = add i8 %t0, %v1
-  %t2 = add i8 %t1, %v1, !sandboxvec !0
-  ret i8 %t2
-}
-
-!0 = distinct !{!"sandboxregion"}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  [[maybe_unused]] auto *T1 = cast<sandboxir::Instruction>(&*It++);
-  auto *T2 = cast<sandboxir::Instruction>(&*It++);
-
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  EXPECT_THAT(Regions[0]->insts(), testing::UnorderedElementsAre(T0, T2));
-}
-
-TEST_F(RegionTest, DumpedMetadata) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1
-  %t2 = add i8 %t1, %v1
-  ret i8 %t1
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  [[maybe_unused]] auto *T1 = cast<sandboxir::Instruction>(&*It++);
-  auto *T2 = cast<sandboxir::Instruction>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::Instruction>(&*It++);
-  sandboxir::Region Rgn(Ctx, *TTI);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T0);
-  sandboxir::Region Rgn2(Ctx, *TTI);
-  sandboxir::RegionInternalsAttorney::add(Rgn2, T2);
-
-  std::string output;
-  llvm::raw_string_ostream RSO(output);
-  M->print(RSO, nullptr, /*ShouldPreserveUseListOrder=*/true,
-           /*IsForDebug=*/true);
-
-  // TODO: Replace this with a lit test, which is more suitable for this kind
-  // of IR comparison.
-  std::string expected = R"(; ModuleID = '<string>'
-source_filename = "<string>"
-
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1, !sandboxvec !0
-  %t1 = add i8 %t0, %v1
-  %t2 = add i8 %t1, %v1, !sandboxvec !1
-  ret i8 %t1
-}
-
-!0 = distinct !{!"sandboxregion"}
-!1 = distinct !{!"sandboxregion"}
-)";
-  EXPECT_EQ(expected, output);
-}
-
-TEST_F(RegionTest, MetadataRoundTrip) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1
-  ret i8 %t1
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  auto *T1 = cast<sandboxir::Instruction>(&*It++);
-
-  sandboxir::Region Rgn(Ctx, *TTI);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T0);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T1);
-
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  ASSERT_EQ(1U, Regions.size());
-#ifndef NDEBUG
-  EXPECT_EQ(Rgn, *Regions[0].get());
-#endif
-}
-
-TEST_F(RegionTest, RegionCost) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0, i8 %v1, i8 %v2) {
-  %add0 = add i8 %v0, 1
-  %add1 = add i8 %v1, 2
-  %add2 = add i8 %v2, 3
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF->begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMAdd0 = &*LLVMIt++;
-  auto *LLVMAdd1 = &*LLVMIt++;
-  auto *LLVMAdd2 = &*LLVMIt++;
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = cast<sandboxir::Instruction>(&*It++);
-  auto *Add1 = cast<sandboxir::Instruction>(&*It++);
-  auto *Add2 = cast<sandboxir::Instruction>(&*It++);
-
-  sandboxir::Region Rgn(Ctx, *TTI);
-  const auto &SB = Rgn.getScoreboard();
-  EXPECT_EQ(SB.getAfterCost(), 0);
-  EXPECT_EQ(SB.getBeforeCost(), 0);
-
-  auto GetCost = [this](llvm::Instruction *LLVMI) {
-    constexpr static TTI::TargetCostKind CostKind = TTI::TCK_RecipThroughput;
-    SmallVector<const llvm::Value *> Operands(LLVMI->operands());
-    return TTI->getInstructionCost(LLVMI, Operands, CostKind);
-  };
-  // Add `Add0` to the region, should be counted in "After".
-  sandboxir::RegionInternalsAttorney::add(Rgn, Add0);
-  EXPECT_EQ(SB.getBeforeCost(), 0);
-  EXPECT_EQ(SB.getAfterCost(), GetCost(LLVMAdd0));
-  // Same for `Add1`.
-  sandboxir::RegionInternalsAttorney::add(Rgn, Add1);
-  EXPECT_EQ(SB.getBeforeCost(), 0);
-  EXPECT_EQ(SB.getAfterCost(), GetCost(LLVMAdd0) + GetCost(LLVMAdd1));
-  // Remove `Add0`, should be subtracted from "After".
-  sandboxir::RegionInternalsAttorney::remove(Rgn, Add0);
-  EXPECT_EQ(SB.getBeforeCost(), 0);
-  EXPECT_EQ(SB.getAfterCost(), GetCost(LLVMAdd1));
-  // Remove `Add2` which was never in the region, should counted in "Before".
-  sandboxir::RegionInternalsAttorney::remove(Rgn, Add2);
-  EXPECT_EQ(SB.getBeforeCost(), GetCost(LLVMAdd2));
-  EXPECT_EQ(SB.getAfterCost(), GetCost(LLVMAdd1));
-}
-
-TEST_F(RegionTest, Aux) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %t0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !2
-  %t1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !3
-  %t2 = add i8 %v, 2, !sandboxvec !1
-  %t3 = add i8 %v, 3, !sandboxvec !1, !sandboxaux !2
-  %t4 = add i8 %v, 4, !sandboxvec !1, !sandboxaux !4
-  %t5 = add i8 %v, 5, !sandboxvec !1, !sandboxaux !3
-  ret void
-}
-
-!0 = distinct !{!"sandboxregion"}
-!1 = distinct !{!"sandboxregion"}
-
-!2 = !{i32 0}
-!3 = !{i32 1}
-!4 = !{i32 2}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF->begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMI0 = &*LLVMIt++;
-  auto *LLVMI1 = &*LLVMIt++;
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  auto *T1 = cast<sandboxir::Instruction>(&*It++);
-  auto *T2 = cast<sandboxir::Instruction>(&*It++);
-  auto *T3 = cast<sandboxir::Instruction>(&*It++);
-  auto *T4 = cast<sandboxir::Instruction>(&*It++);
-  auto *T5 = cast<sandboxir::Instruction>(&*It++);
-
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  // Check that the regions are correct.
-  EXPECT_THAT(Regions[0]->insts(), testing::UnorderedElementsAre(T0, T1));
-  EXPECT_THAT(Regions[1]->insts(),
-              testing::UnorderedElementsAre(T2, T3, T4, T5));
-  // Check aux.
-  EXPECT_THAT(Regions[0]->getAux(), testing::ElementsAre(T0, T1));
-  EXPECT_THAT(Regions[1]->getAux(), testing::ElementsAre(T3, T5, T4));
-  // Check clearAux().
-  EXPECT_TRUE(LLVMI0->getMetadata("sandboxaux"));
-  EXPECT_TRUE(LLVMI1->getMetadata("sandboxaux"));
-  Regions[0]->clearAux();
-  EXPECT_TRUE(Regions[0]->getAux().empty());
-  EXPECT_FALSE(LLVMI0->getMetadata("sandboxaux"));
-  EXPECT_FALSE(LLVMI1->getMetadata("sandboxaux"));
-}
-
-// Check that Aux is well-formed.
-TEST_F(RegionTest, AuxVerify) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %t0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !2
-  %t1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !3
-  ret void
-}
-
-!0 = distinct !{!"sandboxregion"}
-!2 = !{i32 0}
-!3 = !{i32 2}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  EXPECT_DEBUG_DEATH(sandboxir::Region::createRegionsFromMD(*F, *TTI),
-                     ".*Gap*");
-}
-
-// Check that we get an assertion failure if we try to set the same index more
-// than once.
-TEST_F(RegionTest, AuxSameIndex) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %t0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !2
-  %t1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !2
-  ret void
-}
-
-!0 = distinct !{!"sandboxregion"}
-!2 = !{i32 0}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  EXPECT_DEBUG_DEATH(sandboxir::Region::createRegionsFromMD(*F, *TTI),
-                     ".*already.*");
-}
-
-// Check that Aux automatically drops instructions that get deleted.
-TEST_F(RegionTest, AuxDeleteInstr) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %Add0 = add i8 %v, 0, !sandboxvec !0, !sandboxaux !1
-  %Add1 = add i8 %v, 1, !sandboxvec !0, !sandboxaux !2
-  %Add2 = add i8 %v, 2, !sandboxvec !0, !sandboxaux !3
-  %Add3 = add i8 %v, 2, !sandboxvec !0, !sandboxaux !4
-  ret void
-}
-
-!0 = distinct !{!"sandboxregion"}
-!1 = !{i32 0}
-!2 = !{i32 1}
-!3 = !{i32 2}
-!4 = !{i32 3}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = &*It++;
-  auto *Add1 = &*It++;
-  auto *Add2 = &*It++;
-  auto *Add3 = &*It++;
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  auto &R = *Regions[0];
-  EXPECT_THAT(R.getAux(), testing::ElementsAre(Add0, Add1, Add2, Add3));
-  // Now delete Add1 and check that Aux contains nullptr instead of Add1.
-  Add2->eraseFromParent();
-  EXPECT_THAT(R.getAux(), testing::ElementsAre(Add0, Add1, Add3));
-  {
-    // Check that metadata have also been updated.
-    // But first drop Add3 to create a legal Aux vector with no gaps.
-    Add3->eraseFromParent();
-    SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-        sandboxir::Region::createRegionsFromMD(*F, *TTI);
-    EXPECT_THAT(Regions[0]->getAux(), testing::ElementsAre(Add0, Add1));
-  }
-}
-
-TEST_F(RegionTest, AuxWithoutRegion) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %Add0 = add i8 %v, 0, !sandboxaux !0
-  ret void
-}
-!0 = !{i32 0}
-)IR");
-#ifndef NDEBUG
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  EXPECT_DEATH(sandboxir::Region::createRegionsFromMD(*F, *TTI), "No region.*");
-#endif
-}
-
-TEST_F(RegionTest, AuxRoundTrip) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %v0, i8 %v1) {
-  %t0 = add i8 %v0, 1
-  %t1 = add i8 %t0, %v1
-  ret i8 %t1
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *T0 = cast<sandboxir::Instruction>(&*It++);
-  auto *T1 = cast<sandboxir::Instruction>(&*It++);
-
-  sandboxir::Region Rgn(Ctx, *TTI);
-#ifndef NDEBUG
-  EXPECT_DEATH(Rgn.setAux({T0, T0}), ".*already.*");
-#endif
-  sandboxir::RegionInternalsAttorney::add(Rgn, T0);
-  sandboxir::RegionInternalsAttorney::add(Rgn, T1);
-  Rgn.setAux({T1, T0});
-
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  ASSERT_EQ(1U, Regions.size());
-#ifndef NDEBUG
-  EXPECT_EQ(Rgn, *Regions[0].get());
-#endif
-  EXPECT_THAT(Rgn.getAux(), testing::ElementsAre(T1, T0));
-}
-
-// Same as before but only add instructions to aux. They should get added too
-// the region too automatically.
-TEST_F(RegionTest, AuxOnlyRoundTrip) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %add0 = add i8 %v, 0
-  %add1 = add i8 %v, 1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = cast<sandboxir::Instruction>(&*It++);
-  auto *Add1 = cast<sandboxir::Instruction>(&*It++);
-
-  sandboxir::Region Rgn(Ctx, *TTI);
-#ifndef NDEBUG
-  EXPECT_DEATH(Rgn.setAux({Add0, Add0}), ".*already.*");
-#endif
-  Rgn.setAux({Add1, Add0});
-
-  SmallVector<std::unique_ptr<sandboxir::Region>> Regions =
-      sandboxir::Region::createRegionsFromMD(*F, *TTI);
-  ASSERT_EQ(1U, Regions.size());
-#ifndef NDEBUG
-  EXPECT_EQ(Rgn, *Regions[0].get());
-#endif
-  EXPECT_THAT(Rgn.getAux(), testing::ElementsAre(Add1, Add0));
-}
diff --git a/llvm/unittests/SandboxIR/SandboxIRTest.cpp b/llvm/unittests/SandboxIR/SandboxIRTest.cpp
deleted file mode 100644
index 33928ac118e0c..0000000000000
--- a/llvm/unittests/SandboxIR/SandboxIRTest.cpp
+++ /dev/null
@@ -1,6419 +0,0 @@
-//===- SandboxIRTest.cpp --------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/BasicBlock.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/SandboxIR/Module.h"
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/SandboxIR/Value.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct SandboxIRTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("SandboxIRTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-TEST_F(SandboxIRTest, ClassID) {
-  parseIR(C, R"IR(
-define void @foo(i32 %v1) {
-  %add = add i32 %v1, 42
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
-  llvm::Instruction *LLVMAdd = &*LLVMBB->begin();
-  auto *LLVMC = cast<llvm::Constant>(LLVMAdd->getOperand(1));
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  sandboxir::Argument *Arg0 = F->getArg(0);
-  sandboxir::BasicBlock *BB = &*F->begin();
-  sandboxir::Instruction *AddI = &*BB->begin();
-  sandboxir::Constant *Const0 = cast<sandboxir::Constant>(Ctx.getValue(LLVMC));
-
-  EXPECT_TRUE(isa<sandboxir::Function>(F));
-  EXPECT_FALSE(isa<sandboxir::Function>(Arg0));
-  EXPECT_FALSE(isa<sandboxir::Function>(BB));
-  EXPECT_FALSE(isa<sandboxir::Function>(AddI));
-  EXPECT_FALSE(isa<sandboxir::Function>(Const0));
-
-  EXPECT_FALSE(isa<sandboxir::Argument>(F));
-  EXPECT_TRUE(isa<sandboxir::Argument>(Arg0));
-  EXPECT_FALSE(isa<sandboxir::Argument>(BB));
-  EXPECT_FALSE(isa<sandboxir::Argument>(AddI));
-  EXPECT_FALSE(isa<sandboxir::Argument>(Const0));
-
-  EXPECT_TRUE(isa<sandboxir::Constant>(F));
-  EXPECT_FALSE(isa<sandboxir::Constant>(Arg0));
-  EXPECT_FALSE(isa<sandboxir::Constant>(BB));
-  EXPECT_FALSE(isa<sandboxir::Constant>(AddI));
-  EXPECT_TRUE(isa<sandboxir::Constant>(Const0));
-
-  EXPECT_FALSE(isa<sandboxir::OpaqueInst>(F));
-  EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Arg0));
-  EXPECT_FALSE(isa<sandboxir::OpaqueInst>(BB));
-  EXPECT_FALSE(isa<sandboxir::OpaqueInst>(AddI));
-  EXPECT_FALSE(isa<sandboxir::OpaqueInst>(Const0));
-
-  EXPECT_FALSE(isa<sandboxir::Instruction>(F));
-  EXPECT_FALSE(isa<sandboxir::Instruction>(Arg0));
-  EXPECT_FALSE(isa<sandboxir::Instruction>(BB));
-  EXPECT_TRUE(isa<sandboxir::Instruction>(AddI));
-  EXPECT_FALSE(isa<sandboxir::Instruction>(Const0));
-
-  EXPECT_TRUE(isa<sandboxir::User>(F));
-  EXPECT_FALSE(isa<sandboxir::User>(Arg0));
-  EXPECT_FALSE(isa<sandboxir::User>(BB));
-  EXPECT_TRUE(isa<sandboxir::User>(AddI));
-  EXPECT_TRUE(isa<sandboxir::User>(Const0));
-
-#ifndef NDEBUG
-  std::string Buff;
-  raw_string_ostream BS(Buff);
-  F->dumpOS(BS);
-  Arg0->dumpOS(BS);
-  BB->dumpOS(BS);
-  AddI->dumpOS(BS);
-  Const0->dumpOS(BS);
-#endif
-}
-
-TEST_F(SandboxIRTest, ConstantInt) {
-  parseIR(C, R"IR(
-define void @foo(i32 %v0) {
-  %add0 = add i32 %v0, 42
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto *LLVMAdd0 = &*LLVMBB->begin();
-  auto *LLVMFortyTwo = cast<llvm::ConstantInt>(LLVMAdd0->getOperand(1));
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *FortyTwo = cast<sandboxir::ConstantInt>(Add0->getOperand(1));
-
-  // Check that creating an identical constant gives us the same object.
-  auto *NewCI =
-      sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
-  EXPECT_EQ(NewCI, FortyTwo);
-  {
-    // Check getTrue(Ctx).
-    auto *True = sandboxir::ConstantInt::getTrue(Ctx);
-    EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(C)));
-    // Check getFalse(Ctx).
-    auto *False = sandboxir::ConstantInt::getFalse(Ctx);
-    EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(C)));
-    // Check getBool(Ctx).
-    auto *Bool = sandboxir::ConstantInt::getBool(Ctx, true);
-    EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(C, true)));
-  }
-  {
-    auto *Int1Ty = sandboxir::Type::getInt1Ty(Ctx);
-    auto *LLVMInt1Ty = llvm::Type::getInt1Ty(C);
-    // Check getTrue(Ty).
-    auto *True = sandboxir::ConstantInt::getTrue(Int1Ty);
-    EXPECT_EQ(True, Ctx.getValue(llvm::ConstantInt::getTrue(LLVMInt1Ty)));
-    // Check getFalse(Ty).
-    auto *False = sandboxir::ConstantInt::getFalse(Int1Ty);
-    EXPECT_EQ(False, Ctx.getValue(llvm::ConstantInt::getFalse(LLVMInt1Ty)));
-    // Check getBool(Ty).
-    auto *Bool = sandboxir::ConstantInt::getBool(Int1Ty, true);
-    EXPECT_EQ(Bool, Ctx.getValue(llvm::ConstantInt::getBool(LLVMInt1Ty, true)));
-  }
-
-  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
-  auto *LLVMInt32Ty = llvm::Type::getInt32Ty(C);
-  {
-    // Check get(Type, V).
-    auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, 43);
-    auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, 43);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  {
-    // Check get(Type, V, IsSigned).
-    auto *FortyThree =
-        sandboxir::ConstantInt::get(Int32Ty, 43, /*IsSigned=*/true);
-    auto *LLVMFortyThree =
-        llvm::ConstantInt::get(LLVMInt32Ty, 43, /*IsSigned=*/true);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-
-  {
-    // Check get(IntegerType, V).
-    auto *FortyThree =
-        sandboxir::ConstantInt::get(sandboxir::IntegerType::get(Ctx, 32), 43);
-    auto *LLVMFortyThree =
-        llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), 43);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  {
-    // Check get(IntegerType, V, IsSigned).
-    auto *FortyThree = sandboxir::ConstantInt::get(
-        sandboxir::IntegerType::get(Ctx, 32), 43, /*IsSigned=*/true);
-    auto *LLVMFortyThree = llvm::ConstantInt::get(llvm::IntegerType::get(C, 32),
-                                                  43, /*IsSigned=*/true);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-
-  {
-    // Check getSigned(IntegerType, V).
-    auto *FortyThree = sandboxir::ConstantInt::getSigned(
-        sandboxir::IntegerType::get(Ctx, 32), 43);
-    auto *LLVMFortyThree =
-        llvm::ConstantInt::getSigned(llvm::IntegerType::get(C, 32), 43);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  {
-    // Check getSigned(Type, V).
-    auto *FortyThree = sandboxir::ConstantInt::getSigned(Int32Ty, 43);
-    auto *LLVMFortyThree = llvm::ConstantInt::getSigned(LLVMInt32Ty, 43);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  {
-    // Check get(Ctx, APInt).
-    APInt APInt43(32, 43);
-    auto *FortyThree = sandboxir::ConstantInt::get(Ctx, APInt43);
-    auto *LLVMFortyThree = llvm::ConstantInt::get(C, APInt43);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  {
-    // Check get(Ty, Str, Radix).
-    StringRef Str("43");
-    uint8_t Radix(10);
-    auto *FortyThree = sandboxir::ConstantInt::get(
-        sandboxir::IntegerType::get(Ctx, 32), Str, Radix);
-    auto *LLVMFortyThree =
-        llvm::ConstantInt::get(llvm::IntegerType::get(C, 32), Str, Radix);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  {
-    // Check get(Ty, APInt).
-    APInt APInt43(32, 43);
-    auto *FortyThree = sandboxir::ConstantInt::get(Int32Ty, APInt43);
-    auto *LLVMFortyThree = llvm::ConstantInt::get(LLVMInt32Ty, APInt43);
-    EXPECT_NE(FortyThree, FortyTwo);
-    EXPECT_EQ(FortyThree, Ctx.getValue(LLVMFortyThree));
-  }
-  // Check getValue().
-  EXPECT_EQ(FortyTwo->getValue(), LLVMFortyTwo->getValue());
-  // Check getBitWidth().
-  EXPECT_EQ(FortyTwo->getBitWidth(), LLVMFortyTwo->getBitWidth());
-  // Check getZExtValue().
-  EXPECT_EQ(FortyTwo->getZExtValue(), LLVMFortyTwo->getZExtValue());
-  // Check getSExtValue().
-  EXPECT_EQ(FortyTwo->getSExtValue(), LLVMFortyTwo->getSExtValue());
-  // Check getMaybeAlignValue().
-  auto *SixtyFour =
-      cast<sandboxir::ConstantInt>(sandboxir::ConstantInt::get(Int32Ty, 64));
-  auto *LLVMSixtyFour =
-      cast<llvm::ConstantInt>(llvm::ConstantInt::get(LLVMInt32Ty, 64));
-  EXPECT_EQ(SixtyFour->getMaybeAlignValue(),
-            LLVMSixtyFour->getMaybeAlignValue());
-  // Check getAlignValue().
-  EXPECT_EQ(SixtyFour->getAlignValue(), LLVMSixtyFour->getAlignValue());
-  // Check equalsInt().
-  EXPECT_TRUE(FortyTwo->equalsInt(42));
-  EXPECT_FALSE(FortyTwo->equalsInt(43));
-  // Check getIntegerType().
-  EXPECT_EQ(FortyTwo->getIntegerType(), sandboxir::IntegerType::get(Ctx, 32));
-  // Check isValueValidForType().
-  EXPECT_TRUE(
-      sandboxir::ConstantInt::isValueValidForType(Int32Ty, (uint64_t)42));
-  EXPECT_TRUE(
-      sandboxir::ConstantInt::isValueValidForType(Int32Ty, (int64_t)42));
-  // Check isNegative().
-  EXPECT_FALSE(FortyTwo->isNegative());
-  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -42));
-  // Check isZero().
-  EXPECT_FALSE(FortyTwo->isZero());
-  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 0)->isZero());
-  // Check isOne().
-  EXPECT_FALSE(FortyTwo->isOne());
-  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, 1)->isOne());
-  // Check isMinusOne().
-  EXPECT_FALSE(FortyTwo->isMinusOne());
-  EXPECT_TRUE(sandboxir::ConstantInt::get(Int32Ty, -1)->isMinusOne());
-  // Check isMaxValue().
-  EXPECT_FALSE(FortyTwo->isMaxValue(/*Signed=*/true));
-  EXPECT_TRUE(
-      sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::max())
-          ->isMaxValue(/*Signed=*/true));
-  // Check isMinValue().
-  EXPECT_FALSE(FortyTwo->isMinValue(/*Signed=*/true));
-  EXPECT_TRUE(
-      sandboxir::ConstantInt::get(Int32Ty, std::numeric_limits<int32_t>::min())
-          ->isMinValue(/*Signed=*/true));
-  // Check uge().
-  EXPECT_TRUE(FortyTwo->uge(41));
-  EXPECT_FALSE(FortyTwo->uge(43));
-  // Check getLimitedValue().
-  EXPECT_EQ(FortyTwo->getLimitedValue(40u), 40u);
-  EXPECT_EQ(FortyTwo->getLimitedValue(50u), 42u);
-}
-
-TEST_F(SandboxIRTest, ConstantFP) {
-  parseIR(C, R"IR(
-define void @foo(float %v0, double %v1, half %v2) {
-  %fadd0 = fadd float %v0, 42.0
-  %fadd1 = fadd double %v1, 43.0
-  %fadd2 = fadd half %v2, 44.0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *FAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *FAdd1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *FAdd2 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *FortyTwo = cast<sandboxir::ConstantFP>(FAdd0->getOperand(1));
-  [[maybe_unused]] auto *FortyThree =
-      cast<sandboxir::ConstantFP>(FAdd1->getOperand(1));
-
-  auto *FloatTy = sandboxir::Type::getFloatTy(Ctx);
-  auto *DoubleTy = sandboxir::Type::getDoubleTy(Ctx);
-  auto *HalfTy = sandboxir::Type::getHalfTy(Ctx);
-  EXPECT_EQ(HalfTy, Ctx.getType(llvm::Type::getHalfTy(C)));
-  EXPECT_EQ(FAdd2->getType(), HalfTy);
-  auto *LLVMFloatTy = Type::getFloatTy(C);
-  auto *LLVMDoubleTy = Type::getDoubleTy(C);
-  // Check that creating an identical constant gives us the same object.
-  auto *NewFortyTwo = sandboxir::ConstantFP::get(FloatTy, 42.0);
-  EXPECT_EQ(NewFortyTwo, FortyTwo);
-  // Check get(Type, double).
-  auto *FortyFour =
-      cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::get(FloatTy, 44.0));
-  auto *LLVMFortyFour =
-      cast<llvm::ConstantFP>(llvm::ConstantFP::get(LLVMFloatTy, 44.0));
-  EXPECT_NE(FortyFour, FortyTwo);
-  EXPECT_EQ(FortyFour, Ctx.getValue(LLVMFortyFour));
-  // Check get(Type, APFloat).
-  auto *FortyFive = cast<sandboxir::ConstantFP>(
-      sandboxir::ConstantFP::get(DoubleTy, APFloat(45.0)));
-  auto *LLVMFortyFive = cast<llvm::ConstantFP>(
-      llvm::ConstantFP::get(LLVMDoubleTy, APFloat(45.0)));
-  EXPECT_EQ(FortyFive, Ctx.getValue(LLVMFortyFive));
-  // Check get(Type, StringRef).
-  auto *FortySix = sandboxir::ConstantFP::get(FloatTy, "46.0");
-  EXPECT_EQ(FortySix, Ctx.getValue(llvm::ConstantFP::get(LLVMFloatTy, "46.0")));
-  // Check get(APFloat).
-  auto *FortySeven = sandboxir::ConstantFP::get(APFloat(47.0), Ctx);
-  EXPECT_EQ(FortySeven, Ctx.getValue(llvm::ConstantFP::get(C, APFloat(47.0))));
-  // Check getNaN().
-  {
-    auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy);
-    EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(LLVMFloatTy)));
-  }
-  {
-    auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy, /*Negative=*/true);
-    EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(LLVMFloatTy,
-                                                         /*Negative=*/true)));
-  }
-  {
-    auto *NaN = sandboxir::ConstantFP::getNaN(FloatTy, /*Negative=*/true,
-                                              /*Payload=*/1);
-    EXPECT_EQ(NaN, Ctx.getValue(llvm::ConstantFP::getNaN(
-                       LLVMFloatTy, /*Negative=*/true, /*Payload=*/1)));
-  }
-  // Check getQNaN().
-  {
-    auto *QNaN = sandboxir::ConstantFP::getQNaN(FloatTy);
-    EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(LLVMFloatTy)));
-  }
-  {
-    auto *QNaN = sandboxir::ConstantFP::getQNaN(FloatTy, /*Negative=*/true);
-    EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(LLVMFloatTy,
-                                                           /*Negative=*/true)));
-  }
-  {
-    APInt Payload(1, 1);
-    auto *QNaN =
-        sandboxir::ConstantFP::getQNaN(FloatTy, /*Negative=*/true, &Payload);
-    EXPECT_EQ(QNaN, Ctx.getValue(llvm::ConstantFP::getQNaN(
-                        LLVMFloatTy, /*Negative=*/true, &Payload)));
-  }
-  // Check getSNaN().
-  {
-    auto *SNaN = sandboxir::ConstantFP::getSNaN(FloatTy);
-    EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(LLVMFloatTy)));
-  }
-  {
-    auto *SNaN = sandboxir::ConstantFP::getSNaN(FloatTy, /*Negative=*/true);
-    EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(LLVMFloatTy,
-                                                           /*Negative=*/true)));
-  }
-  {
-    APInt Payload(1, 1);
-    auto *SNaN =
-        sandboxir::ConstantFP::getSNaN(FloatTy, /*Negative=*/true, &Payload);
-    EXPECT_EQ(SNaN, Ctx.getValue(llvm::ConstantFP::getSNaN(
-                        LLVMFloatTy, /*Negative=*/true, &Payload)));
-  }
-
-  // Check getZero().
-  {
-    auto *Zero = sandboxir::ConstantFP::getZero(FloatTy);
-    EXPECT_EQ(Zero, Ctx.getValue(llvm::ConstantFP::getZero(LLVMFloatTy)));
-  }
-  {
-    auto *Zero = sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true);
-    EXPECT_EQ(Zero, Ctx.getValue(llvm::ConstantFP::getZero(LLVMFloatTy,
-                                                           /*Negative=*/true)));
-  }
-
-  // Check getNegativeZero().
-  auto *NegZero = cast<sandboxir::ConstantFP>(
-      sandboxir::ConstantFP::getNegativeZero(FloatTy));
-  EXPECT_EQ(NegZero,
-            Ctx.getValue(llvm::ConstantFP::getNegativeZero(LLVMFloatTy)));
-
-  // Check getInfinity().
-  {
-    auto *Inf = sandboxir::ConstantFP::getInfinity(FloatTy);
-    EXPECT_EQ(Inf, Ctx.getValue(llvm::ConstantFP::getInfinity(LLVMFloatTy)));
-  }
-  {
-    auto *Inf = sandboxir::ConstantFP::getInfinity(FloatTy, /*Negative=*/true);
-    EXPECT_EQ(Inf, Ctx.getValue(llvm::ConstantFP::getInfinity(
-                       LLVMFloatTy, /*Negative=*/true)));
-  }
-
-  // Check isValueValidForType().
-  APFloat V(1.1);
-  EXPECT_EQ(sandboxir::ConstantFP::isValueValidForType(FloatTy, V),
-            llvm::ConstantFP::isValueValidForType(LLVMFloatTy, V));
-  // Check getValueAPF().
-  EXPECT_EQ(FortyFour->getValueAPF(), LLVMFortyFour->getValueAPF());
-  // Check getValue().
-  EXPECT_EQ(FortyFour->getValue(), LLVMFortyFour->getValue());
-  // Check isZero().
-  EXPECT_EQ(FortyFour->isZero(), LLVMFortyFour->isZero());
-  EXPECT_TRUE(sandboxir::ConstantFP::getZero(FloatTy));
-  EXPECT_TRUE(sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true));
-  // Check isNegative().
-  EXPECT_TRUE(cast<sandboxir::ConstantFP>(
-                  sandboxir::ConstantFP::getZero(FloatTy, /*Negative=*/true))
-                  ->isNegative());
-  // Check isInfinity().
-  EXPECT_TRUE(
-      cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::getInfinity(FloatTy))
-          ->isInfinity());
-  // Check isNaN().
-  EXPECT_TRUE(
-      cast<sandboxir::ConstantFP>(sandboxir::ConstantFP::getNaN(FloatTy))
-          ->isNaN());
-  // Check isExactlyValue(APFloat).
-  EXPECT_TRUE(NegZero->isExactlyValue(NegZero->getValueAPF()));
-  // Check isExactlyValue(double).
-  EXPECT_TRUE(NegZero->isExactlyValue(-0.0));
-}
-
-// Tests ConstantArray, ConstantStruct and ConstantVector.
-TEST_F(SandboxIRTest, ConstantAggregate) {
-  // Note: we are using i42 to avoid the creation of ConstantDataVector or
-  // ConstantDataArray.
-  parseIR(C, R"IR(
-define void @foo() {
-  %array = extractvalue [2 x i42] [i42 0, i42 1], 0
-  %struct = extractvalue {i42, i42} {i42 0, i42 1}, 0
-  %vector = extractelement <2 x i42> <i42 0, i42 1>, i32 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  // Check classof() and creation.
-  auto *Array = cast<sandboxir::ConstantArray>(I0->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Array));
-  auto *Struct = cast<sandboxir::ConstantStruct>(I1->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Struct));
-  auto *Vector = cast<sandboxir::ConstantVector>(I2->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantAggregate>(Vector));
-
-  auto *ZeroI42 = cast<sandboxir::ConstantInt>(Array->getOperand(0));
-  auto *OneI42 = cast<sandboxir::ConstantInt>(Array->getOperand(1));
-  // Check ConstantArray::get(), getType().
-  auto *NewCA =
-      sandboxir::ConstantArray::get(Array->getType(), {ZeroI42, OneI42});
-  EXPECT_EQ(NewCA, Array);
-
-  // Check ConstantStruct::get(), getType().
-  auto *NewCS =
-      sandboxir::ConstantStruct::get(Struct->getType(), {ZeroI42, OneI42});
-  EXPECT_EQ(NewCS, Struct);
-  // Check ConstantStruct::get(...).
-  auto *NewCS2 =
-      sandboxir::ConstantStruct::get(Struct->getType(), ZeroI42, OneI42);
-  EXPECT_EQ(NewCS2, Struct);
-  // Check ConstantStruct::getAnon(ArayRef).
-  auto *AnonCS = sandboxir::ConstantStruct::getAnon({ZeroI42, OneI42});
-  EXPECT_FALSE(cast<sandboxir::StructType>(AnonCS->getType())->isPacked());
-  auto *AnonCSPacked =
-      sandboxir::ConstantStruct::getAnon({ZeroI42, OneI42}, /*Packed=*/true);
-  EXPECT_TRUE(cast<sandboxir::StructType>(AnonCSPacked->getType())->isPacked());
-  // Check ConstantStruct::getAnon(Ctx, ArrayRef).
-  auto *AnonCS2 = sandboxir::ConstantStruct::getAnon(Ctx, {ZeroI42, OneI42});
-  EXPECT_EQ(AnonCS2, AnonCS);
-  auto *AnonCS2Packed = sandboxir::ConstantStruct::getAnon(
-      Ctx, {ZeroI42, OneI42}, /*Packed=*/true);
-  EXPECT_EQ(AnonCS2Packed, AnonCSPacked);
-  // Check ConstantStruct::getTypeForElements(Ctx, ArrayRef).
-  auto *StructTy =
-      sandboxir::ConstantStruct::getTypeForElements(Ctx, {ZeroI42, OneI42});
-  EXPECT_EQ(StructTy, Struct->getType());
-  EXPECT_FALSE(StructTy->isPacked());
-  // Check ConstantStruct::getTypeForElements(Ctx, ArrayRef, Packed).
-  auto *StructTyPacked = sandboxir::ConstantStruct::getTypeForElements(
-      Ctx, {ZeroI42, OneI42}, /*Packed=*/true);
-  EXPECT_TRUE(StructTyPacked->isPacked());
-  // Check ConstantStruct::getTypeForElements(ArrayRef).
-  auto *StructTy2 =
-      sandboxir::ConstantStruct::getTypeForElements(Ctx, {ZeroI42, OneI42});
-  EXPECT_EQ(StructTy2, Struct->getType());
-  // Check ConstantStruct::getTypeForElements(ArrayRef, Packed).
-  auto *StructTy2Packed = sandboxir::ConstantStruct::getTypeForElements(
-      Ctx, {ZeroI42, OneI42}, /*Packed=*/true);
-  EXPECT_EQ(StructTy2Packed, StructTyPacked);
-
-  // Check ConstantVector::get().
-  auto *NewCV = sandboxir::ConstantVector::get({ZeroI42, OneI42});
-  EXPECT_EQ(NewCV, Vector);
-  // Check ConstantVector::getSplat(), getType().
-  auto *SplatRaw =
-      sandboxir::ConstantVector::getSplat(ElementCount::getFixed(2), OneI42);
-  auto *Splat = cast<sandboxir::ConstantVector>(SplatRaw);
-  EXPECT_EQ(Splat->getType()->getNumElements(), 2u);
-  EXPECT_THAT(Splat->operands(), testing::ElementsAre(OneI42, OneI42));
-  // Check ConstantVector::getSplatValue().
-  EXPECT_EQ(Splat->getSplatValue(), OneI42);
-}
-
-TEST_F(SandboxIRTest, ConstantAggregateZero) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, {i32, i8} %v1, <2 x i8> %v2) {
-  %extr0 = extractvalue [2 x i8] zeroinitializer, 0
-  %extr1 = extractvalue {i32, i8} zeroinitializer, 0
-  %extr2 = extractelement <2 x i8> zeroinitializer, i32 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *Extr0 = &*It++;
-  auto *Extr1 = &*It++;
-  auto *Extr2 = &*It++;
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  auto *Zero32 =
-      sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
-  auto *Zero8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
-  auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
-  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
-  auto *ArrayTy = sandboxir::ArrayType::get(Int8Ty, 2u);
-  auto *StructTy = sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty});
-  auto *VectorTy =
-      sandboxir::VectorType::get(Int8Ty, ElementCount::getFixed(2u));
-
-  // Check creation and classof().
-  auto *ArrayCAZ = cast<sandboxir::ConstantAggregateZero>(Extr0->getOperand(0));
-  EXPECT_EQ(ArrayCAZ->getType(), ArrayTy);
-  auto *StructCAZ =
-      cast<sandboxir::ConstantAggregateZero>(Extr1->getOperand(0));
-  EXPECT_EQ(StructCAZ->getType(), StructTy);
-  auto *VectorCAZ =
-      cast<sandboxir::ConstantAggregateZero>(Extr2->getOperand(0));
-  EXPECT_EQ(VectorCAZ->getType(), VectorTy);
-  // Check get().
-  auto *SameVectorCAZ =
-      sandboxir::ConstantAggregateZero::get(sandboxir::VectorType::get(
-          sandboxir::Type::getInt8Ty(Ctx), ElementCount::getFixed(2)));
-  EXPECT_EQ(SameVectorCAZ, VectorCAZ); // Should be uniqued.
-  auto *NewVectorCAZ =
-      sandboxir::ConstantAggregateZero::get(sandboxir::VectorType::get(
-          sandboxir::Type::getInt8Ty(Ctx), ElementCount::getFixed(4)));
-  EXPECT_NE(NewVectorCAZ, VectorCAZ);
-  // Check getSequentialElement().
-  auto *SeqElm = VectorCAZ->getSequentialElement();
-  EXPECT_EQ(SeqElm,
-            sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0));
-  // Check getStructElement().
-  auto *StructElm0 = StructCAZ->getStructElement(0);
-  auto *StructElm1 = StructCAZ->getStructElement(1);
-  EXPECT_EQ(StructElm0, Zero32);
-  EXPECT_EQ(StructElm1, Zero8);
-  // Check getElementValue(Constant).
-  EXPECT_EQ(ArrayCAZ->getElementValue(Zero32), Zero8);
-  EXPECT_EQ(StructCAZ->getElementValue(Zero32), Zero32);
-  EXPECT_EQ(VectorCAZ->getElementValue(Zero32), Zero8);
-  // Check getElementValue(unsigned).
-  EXPECT_EQ(ArrayCAZ->getElementValue(0u), Zero8);
-  EXPECT_EQ(StructCAZ->getElementValue(0u), Zero32);
-  EXPECT_EQ(VectorCAZ->getElementValue(0u), Zero8);
-  // Check getElementCount().
-  EXPECT_EQ(ArrayCAZ->getElementCount(), ElementCount::getFixed(2));
-  EXPECT_EQ(NewVectorCAZ->getElementCount(), ElementCount::getFixed(4));
-}
-
-// Tests ConstantDataSequential, ConstantDataArray and ConstantDataVector.
-TEST_F(SandboxIRTest, ConstantDataSequential) {
-  parseIR(C, R"IR(
-define void @foo() {
-  %array = extractvalue [2 x i8] [i8 0, i8 1], 0
-  %vector = extractelement <2 x i8> <i8 0, i8 1>, i32 0
-  %farray = extractvalue [2 x float] [float 0.0, float 1.0], 0
-  %fvector = extractelement <2 x double> <double 0.0, double 1.0>, i32 0
-  %string = extractvalue [6 x i8] [i8 72, i8 69, i8 76, i8 76, i8 79, i8 0], 0
-  %stringNoNull = extractvalue [5 x i8] [i8 72, i8 69, i8 76, i8 76, i8 79], 0
-  %splat = extractelement <4 x i8> <i8 1, i8 1, i8 1, i8 1>, i32 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *I3 = &*It++;
-  auto *I4 = &*It++;
-  auto *I5 = &*It++;
-  auto *I6 = &*It++;
-  auto *Array = cast<sandboxir::ConstantDataArray>(I0->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataSequential>(Array));
-  auto *Vector = cast<sandboxir::ConstantDataVector>(I1->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(Vector));
-  auto *FArray = cast<sandboxir::ConstantDataArray>(I2->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataSequential>(FArray));
-  auto *FVector = cast<sandboxir::ConstantDataVector>(I3->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(FVector));
-  auto *String = cast<sandboxir::ConstantDataArray>(I4->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataArray>(String));
-  auto *StringNoNull = cast<sandboxir::ConstantDataArray>(I5->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataArray>(StringNoNull));
-  auto *Splat = cast<sandboxir::ConstantDataVector>(I6->getOperand(0));
-  EXPECT_TRUE(isa<sandboxir::ConstantDataVector>(Splat));
-
-  auto *Zero8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
-  auto *One8 = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 1);
-
-  // Check isElementTypeCompatible().
-  for (llvm::Type *LLVMTy :
-       {llvm::Type::getIntNTy(C, 42), llvm::Type::getInt8Ty(C)})
-    EXPECT_EQ(llvm::ConstantDataSequential::isElementTypeCompatible(LLVMTy),
-              sandboxir::ConstantDataSequential::isElementTypeCompatible(
-                  Ctx.getType(LLVMTy)));
-  // Check getElementAsInteger().
-  EXPECT_EQ(Array->getElementAsInteger(0), 0u);
-  EXPECT_EQ(Array->getElementAsInteger(1), 1u);
-  EXPECT_EQ(Vector->getElementAsInteger(0), 0u);
-  EXPECT_EQ(Vector->getElementAsInteger(1), 1u);
-  // Check getElementAsAPInt().
-  EXPECT_EQ(Array->getElementAsAPInt(0), 0u);
-  EXPECT_EQ(Array->getElementAsAPInt(1), 1u);
-  EXPECT_EQ(Vector->getElementAsAPInt(0), 0u);
-  EXPECT_EQ(Vector->getElementAsAPInt(1), 1u);
-  // Check geteElementAsFloat().
-  EXPECT_EQ(FArray->getElementAsFloat(0), 0.0);
-  EXPECT_EQ(FArray->getElementAsFloat(1), 1.0);
-  // Check getElementAsDouble().
-  EXPECT_EQ(FVector->getElementAsDouble(0), 0.0);
-  EXPECT_EQ(FVector->getElementAsDouble(1), 1.0);
-  // Check getElementAsConstant().
-  EXPECT_EQ(Array->getElementAsConstant(0), Zero8);
-  EXPECT_EQ(Array->getElementAsConstant(1), One8);
-  EXPECT_EQ(Vector->getElementAsConstant(0), Zero8);
-  EXPECT_EQ(Vector->getElementAsConstant(1), One8);
-  // Check getElementType().
-  EXPECT_EQ(Array->getElementType(), sandboxir::Type::getInt8Ty(Ctx));
-  EXPECT_EQ(Vector->getElementType(), sandboxir::Type::getInt8Ty(Ctx));
-  EXPECT_EQ(FArray->getElementType(), sandboxir::Type::getFloatTy(Ctx));
-  EXPECT_EQ(FVector->getElementType(), sandboxir::Type::getDoubleTy(Ctx));
-  // Check getNumElements(),
-  EXPECT_EQ(Array->getNumElements(), 2u);
-  EXPECT_EQ(Vector->getNumElements(), 2u);
-  EXPECT_EQ(FArray->getNumElements(), 2u);
-  EXPECT_EQ(FVector->getNumElements(), 2u);
-  // Check getElementByteSize().
-  EXPECT_EQ(Array->getElementByteSize(), 1u);
-  EXPECT_EQ(Vector->getElementByteSize(), 1u);
-  EXPECT_EQ(FArray->getElementByteSize(), 4u);
-  EXPECT_EQ(FVector->getElementByteSize(), 8u);
-  // Check isString().
-  EXPECT_EQ(Array->isString(), true);
-  EXPECT_EQ(Vector->isString(), false);
-  EXPECT_EQ(FArray->isString(), false);
-  EXPECT_EQ(FVector->isString(), false);
-  EXPECT_EQ(String->isString(), true);
-  // Check isCString().
-  EXPECT_EQ(Array->isCString(), false);
-  EXPECT_EQ(Vector->isCString(), false);
-  EXPECT_EQ(FArray->isCString(), false);
-  EXPECT_EQ(FVector->isCString(), false);
-  EXPECT_EQ(String->isCString(), true);
-  // Check getAsString().
-  char Data[] = {'H', 'E', 'L', 'L', 'O', '\0'};
-  StringRef HelloWithNull(Data, 6);
-  EXPECT_EQ(String->getAsString(), HelloWithNull);
-  // Check getAsCString().
-  EXPECT_EQ(String->getAsCString(), "HELLO");
-  // Check getRawDataValues().
-  EXPECT_EQ(String->getRawDataValues(), HelloWithNull);
-
-  // Check ConstantDataArray member functions
-  // ----------------------------------------
-  // Check get<ElementTy>().
-  EXPECT_EQ(sandboxir::ConstantDataArray::get<char>(Ctx, {0, 1}), Array);
-  // Check get<ArrayTy>().
-  SmallVector<char> Elmts({0, 1});
-  EXPECT_EQ(sandboxir::ConstantDataArray::get<SmallVector<char>>(Ctx, Elmts),
-            Array);
-  // Check getRaw().
-  EXPECT_EQ(sandboxir::ConstantDataArray::getRaw(StringRef("HELLO"), 5,
-                                                 Zero8->getType()),
-            StringNoNull);
-  // Check getFP().
-  SmallVector<uint16_t> Elts16({42, 43});
-  SmallVector<uint32_t> Elts32({42, 43});
-  SmallVector<uint64_t> Elts64({42, 43});
-  auto *F16Ty = sandboxir::Type::getHalfTy(Ctx);
-  auto *F32Ty = sandboxir::Type::getFloatTy(Ctx);
-  auto *F64Ty = sandboxir::Type::getDoubleTy(Ctx);
-
-  auto *CDA16 = sandboxir::ConstantDataArray::getFP(F16Ty, Elts16);
-  EXPECT_EQ(CDA16, cast<sandboxir::ConstantDataArray>(
-                       Ctx.getValue(llvm::ConstantDataArray::getFP(
-                           llvm::Type::getHalfTy(C), Elts16))));
-  auto *CDA32 = sandboxir::ConstantDataArray::getFP(F32Ty, Elts32);
-  EXPECT_EQ(CDA32, cast<sandboxir::ConstantDataArray>(
-                       Ctx.getValue(llvm::ConstantDataArray::getFP(
-                           llvm::Type::getFloatTy(C), Elts32))));
-  auto *CDA64 = sandboxir::ConstantDataArray::getFP(F64Ty, Elts64);
-  EXPECT_EQ(CDA64, cast<sandboxir::ConstantDataArray>(
-                       Ctx.getValue(llvm::ConstantDataArray::getFP(
-                           llvm::Type::getDoubleTy(C), Elts64))));
-  // Check getString().
-  EXPECT_EQ(sandboxir::ConstantDataArray::getString(Ctx, "HELLO"), String);
-
-  EXPECT_EQ(sandboxir::ConstantDataArray::getString(Ctx, "HELLO",
-                                                    /*AddNull=*/false),
-            StringNoNull);
-  EXPECT_EQ(
-      sandboxir::ConstantDataArray::getString(Ctx, "HELLO", /*AddNull=*/false),
-      StringNoNull);
-
-  {
-    // Check ConstantDataArray member functions
-    // ----------------------------------------
-    // Check get().
-    SmallVector<uint8_t> Elts8({0u, 1u});
-    SmallVector<uint16_t> Elts16({0u, 1u});
-    SmallVector<uint32_t> Elts32({0u, 1u});
-    SmallVector<uint64_t> Elts64({0u, 1u});
-    SmallVector<float> EltsF32({0.0, 1.0});
-    SmallVector<double> EltsF64({0.0, 1.0});
-    auto *CDV8 = sandboxir::ConstantDataVector::get(Ctx, Elts8);
-    EXPECT_EQ(CDV8, cast<sandboxir::ConstantDataVector>(
-                        Ctx.getValue(llvm::ConstantDataVector::get(C, Elts8))));
-    auto *CDV16 = sandboxir::ConstantDataVector::get(Ctx, Elts16);
-    EXPECT_EQ(CDV16, cast<sandboxir::ConstantDataVector>(Ctx.getValue(
-                         llvm::ConstantDataVector::get(C, Elts16))));
-    auto *CDV32 = sandboxir::ConstantDataVector::get(Ctx, Elts32);
-    EXPECT_EQ(CDV32, cast<sandboxir::ConstantDataVector>(Ctx.getValue(
-                         llvm::ConstantDataVector::get(C, Elts32))));
-    auto *CDVF32 = sandboxir::ConstantDataVector::get(Ctx, EltsF32);
-    EXPECT_EQ(CDVF32, cast<sandboxir::ConstantDataVector>(Ctx.getValue(
-                          llvm::ConstantDataVector::get(C, EltsF32))));
-    auto *CDVF64 = sandboxir::ConstantDataVector::get(Ctx, EltsF64);
-    EXPECT_EQ(CDVF64, cast<sandboxir::ConstantDataVector>(Ctx.getValue(
-                          llvm::ConstantDataVector::get(C, EltsF64))));
-    // Check getRaw().
-    auto *CDVRaw = sandboxir::ConstantDataVector::getRaw(
-        StringRef("HELLO"), 5, sandboxir::Type::getInt8Ty(Ctx));
-    EXPECT_EQ(CDVRaw,
-              cast<sandboxir::ConstantDataVector>(
-                  Ctx.getValue(llvm::ConstantDataVector::getRaw(
-                      StringRef("HELLO"), 5, llvm::Type::getInt8Ty(C)))));
-    // Check getFP().
-    auto *CDVFP16 = sandboxir::ConstantDataVector::getFP(F16Ty, Elts16);
-    EXPECT_EQ(CDVFP16, cast<sandboxir::ConstantDataVector>(
-                           Ctx.getValue(llvm::ConstantDataVector::getFP(
-                               llvm::Type::getHalfTy(C), Elts16))));
-    auto *CDVFP32 = sandboxir::ConstantDataVector::getFP(F32Ty, Elts32);
-    EXPECT_EQ(CDVFP32, cast<sandboxir::ConstantDataVector>(
-                           Ctx.getValue(llvm::ConstantDataVector::getFP(
-                               llvm::Type::getFloatTy(C), Elts32))));
-    auto *CDVFP64 = sandboxir::ConstantDataVector::getFP(F64Ty, Elts64);
-    EXPECT_EQ(CDVFP64, cast<sandboxir::ConstantDataVector>(
-                           Ctx.getValue(llvm::ConstantDataVector::getFP(
-                               llvm::Type::getDoubleTy(C), Elts64))));
-    // Check getSplat().
-    auto *NewSplat = cast<sandboxir::ConstantDataVector>(
-        sandboxir::ConstantDataVector::getSplat(4, One8));
-    EXPECT_EQ(NewSplat, Splat);
-    // Check isSplat().
-    EXPECT_TRUE(NewSplat->isSplat());
-    EXPECT_FALSE(Vector->isSplat());
-    // Check getSplatValue().
-    EXPECT_EQ(NewSplat->getSplatValue(), One8);
-    // Check getType().
-    EXPECT_TRUE(isa<sandboxir::FixedVectorType>(NewSplat->getType()));
-    EXPECT_EQ(
-        cast<sandboxir::FixedVectorType>(NewSplat->getType())->getNumElements(),
-        4u);
-  }
-}
-
-TEST_F(SandboxIRTest, ConstantPointerNull) {
-  parseIR(C, R"IR(
-define ptr @foo() {
-  ret ptr null
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  // Check classof() and creation.
-  auto *CPNull = cast<sandboxir::ConstantPointerNull>(Ret->getReturnValue());
-  // Check get().
-  auto *NewCPNull =
-      sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx, 0u));
-  EXPECT_EQ(NewCPNull, CPNull);
-  auto *NewCPNull2 =
-      sandboxir::ConstantPointerNull::get(sandboxir::PointerType::get(Ctx, 1u));
-  EXPECT_NE(NewCPNull2, CPNull);
-  // Check getType().
-  EXPECT_EQ(CPNull->getType(), sandboxir::PointerType::get(Ctx, 0u));
-  EXPECT_EQ(NewCPNull2->getType(), sandboxir::PointerType::get(Ctx, 1u));
-}
-
-TEST_F(SandboxIRTest, PoisonValue) {
-  parseIR(C, R"IR(
-define void @foo() {
-  %i0 = add i32 poison, poison
-  %i1 = add <2 x i32> poison, poison
-  %i2 = extractvalue {i32, i8} poison, 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
-  auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
-  auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u);
-  auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u);
-
-  // Check classof() and creation.
-  auto *Poison = cast<sandboxir::PoisonValue>(I0->getOperand(0));
-  EXPECT_EQ(Poison->getType(), Int32Ty);
-  EXPECT_TRUE(isa<sandboxir::UndefValue>(Poison)); // Poison is Undef
-  // Check get().
-  auto *NewPoison = sandboxir::PoisonValue::get(Int32Ty);
-  EXPECT_EQ(NewPoison, Poison);
-  auto *NewPoison2 =
-      sandboxir::PoisonValue::get(sandboxir::PointerType::get(Ctx, 0u));
-  EXPECT_NE(NewPoison2, Poison);
-  // Check getSequentialElement().
-  auto *PoisonVector = cast<sandboxir::PoisonValue>(I1->getOperand(0));
-  auto *SeqElm = PoisonVector->getSequentialElement();
-  EXPECT_EQ(SeqElm->getType(), Int32Ty);
-  // Check getStructElement().
-  auto *PoisonStruct = cast<sandboxir::PoisonValue>(I2->getOperand(0));
-  auto *StrElm0 = PoisonStruct->getStructElement(0);
-  auto *StrElm1 = PoisonStruct->getStructElement(1);
-  EXPECT_EQ(StrElm0->getType(), Int32Ty);
-  EXPECT_EQ(StrElm1->getType(), Int8Ty);
-  // Check getElementValue(Constant)
-  EXPECT_EQ(PoisonStruct->getElementValue(Zero32),
-            sandboxir::PoisonValue::get(Int32Ty));
-  EXPECT_EQ(PoisonStruct->getElementValue(One32),
-            sandboxir::PoisonValue::get(Int8Ty));
-  // Check getElementValue(unsigned)
-  EXPECT_EQ(PoisonStruct->getElementValue(0u),
-            sandboxir::PoisonValue::get(Int32Ty));
-  EXPECT_EQ(PoisonStruct->getElementValue(1u),
-            sandboxir::PoisonValue::get(Int8Ty));
-}
-
-TEST_F(SandboxIRTest, UndefValue) {
-  parseIR(C, R"IR(
-define void @foo() {
-  %i0 = add i32 undef, undef
-  %i1 = add <2 x i32> undef, undef
-  %i2 = extractvalue {i32, i8} undef, 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
-  auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
-  auto *Zero32 = sandboxir::ConstantInt::get(Int32Ty, 0u);
-  auto *One32 = sandboxir::ConstantInt::get(Int32Ty, 1u);
-
-  // Check classof() and creation.
-  auto *Undef = cast<sandboxir::UndefValue>(I0->getOperand(0));
-  EXPECT_EQ(Undef->getType(), Int32Ty);
-  EXPECT_FALSE(isa<sandboxir::PoisonValue>(Undef)); // Undef is not Poison
-  // Check get().
-  auto *NewUndef = sandboxir::UndefValue::get(Int32Ty);
-  EXPECT_EQ(NewUndef, Undef);
-  auto *NewUndef2 =
-      sandboxir::UndefValue::get(sandboxir::PointerType::get(Ctx, 0u));
-  EXPECT_NE(NewUndef2, Undef);
-  // Check getSequentialElement().
-  auto *UndefVector = cast<sandboxir::UndefValue>(I1->getOperand(0));
-  auto *SeqElm = UndefVector->getSequentialElement();
-  EXPECT_EQ(SeqElm->getType(), Int32Ty);
-  // Check getStructElement().
-  auto *UndefStruct = cast<sandboxir::UndefValue>(I2->getOperand(0));
-  auto *StrElm0 = UndefStruct->getStructElement(0);
-  auto *StrElm1 = UndefStruct->getStructElement(1);
-  EXPECT_EQ(StrElm0->getType(), Int32Ty);
-  EXPECT_EQ(StrElm1->getType(), Int8Ty);
-  // Check getElementValue(Constant)
-  EXPECT_EQ(UndefStruct->getElementValue(Zero32),
-            sandboxir::UndefValue::get(Int32Ty));
-  EXPECT_EQ(UndefStruct->getElementValue(One32),
-            sandboxir::UndefValue::get(Int8Ty));
-  // Check getElementValue(unsigned)
-  EXPECT_EQ(UndefStruct->getElementValue(0u),
-            sandboxir::UndefValue::get(Int32Ty));
-  EXPECT_EQ(UndefStruct->getElementValue(1u),
-            sandboxir::UndefValue::get(Int8Ty));
-  // Check getNumElements().
-  EXPECT_EQ(UndefVector->getNumElements(), 2u);
-  EXPECT_EQ(UndefStruct->getNumElements(), 2u);
-}
-
-TEST_F(SandboxIRTest, GlobalValue) {
-  parseIR(C, R"IR(
-declare external void @bar()
-define void @foo() {
-  call void @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
-  auto *LLVMGV = cast<llvm::GlobalValue>(LLVMCall->getCalledOperand());
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call = cast<sandboxir::CallInst>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check classof(), creation, getFunction(), getBasicBlock().
-  auto *GV = cast<sandboxir::GlobalValue>(Call->getCalledOperand());
-  // Check getAddressSpace().
-  EXPECT_EQ(GV->getAddressSpace(), LLVMGV->getAddressSpace());
-  // Check hasGlobalUnnamedAddr().
-  EXPECT_EQ(GV->hasGlobalUnnamedAddr(), LLVMGV->hasGlobalUnnamedAddr());
-  // Check hasAtLeastLocalUnnamedAddr().
-  EXPECT_EQ(GV->hasAtLeastLocalUnnamedAddr(),
-            LLVMGV->hasAtLeastLocalUnnamedAddr());
-  // Check getUnnamedAddr().
-  EXPECT_EQ(GV->getUnnamedAddr(), LLVMGV->getUnnamedAddr());
-  // Check setUnnamedAddr().
-  auto OrigUnnamedAddr = GV->getUnnamedAddr();
-  auto NewUnnamedAddr = sandboxir::GlobalValue::UnnamedAddr::Global;
-  EXPECT_NE(NewUnnamedAddr, OrigUnnamedAddr);
-  GV->setUnnamedAddr(NewUnnamedAddr);
-  EXPECT_EQ(GV->getUnnamedAddr(), NewUnnamedAddr);
-  GV->setUnnamedAddr(OrigUnnamedAddr);
-  EXPECT_EQ(GV->getUnnamedAddr(), OrigUnnamedAddr);
-  // Check getMinUnnamedAddr().
-  EXPECT_EQ(
-      sandboxir::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr,
-                                                NewUnnamedAddr),
-      llvm::GlobalValue::getMinUnnamedAddr(OrigUnnamedAddr, NewUnnamedAddr));
-  // Check hasComdat().
-  EXPECT_EQ(GV->hasComdat(), LLVMGV->hasComdat());
-  // Check getVisibility().
-  EXPECT_EQ(GV->getVisibility(), LLVMGV->getVisibility());
-  // Check hasDefaultVisibility().
-  EXPECT_EQ(GV->hasDefaultVisibility(), LLVMGV->hasDefaultVisibility());
-  // Check hasHiddenVisibility().
-  EXPECT_EQ(GV->hasHiddenVisibility(), LLVMGV->hasHiddenVisibility());
-  // Check hasProtectedVisibility().
-  EXPECT_EQ(GV->hasProtectedVisibility(), LLVMGV->hasProtectedVisibility());
-  // Check setVisibility().
-  auto OrigVisibility = GV->getVisibility();
-  auto NewVisibility =
-      sandboxir::GlobalValue::VisibilityTypes::ProtectedVisibility;
-  EXPECT_NE(NewVisibility, OrigVisibility);
-  GV->setVisibility(NewVisibility);
-  EXPECT_EQ(GV->getVisibility(), NewVisibility);
-  GV->setVisibility(OrigVisibility);
-  EXPECT_EQ(GV->getVisibility(), OrigVisibility);
-}
-
-TEST_F(SandboxIRTest, GlobalObject) {
-  parseIR(C, R"IR(
-declare external void @bar()
-define void @foo() {
-  call void @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMCall = cast<llvm::CallInst>(&*LLVMIt++);
-  auto *LLVMGO = cast<llvm::GlobalObject>(LLVMCall->getCalledOperand());
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call = cast<sandboxir::CallInst>(&*It++);
-  // Check classof(), creation.
-  auto *GO = cast<sandboxir::GlobalObject>(Call->getCalledOperand());
-  // Check hasSection().
-  EXPECT_EQ(GO->hasSection(), LLVMGO->hasSection());
-  // Check getSection().
-  EXPECT_EQ(GO->getSection(), LLVMGO->getSection());
-  // Check setSection().
-  auto OrigSection = GO->getSection();
-  auto NewSection = ".some_section";
-  EXPECT_NE(NewSection, OrigSection);
-  GO->setSection(NewSection);
-  EXPECT_EQ(GO->getSection(), NewSection);
-  GO->setSection(OrigSection);
-  EXPECT_EQ(GO->getSection(), OrigSection);
-  // Check hasComdat().
-  EXPECT_EQ(GO->hasComdat(), LLVMGO->hasComdat());
-  // Check getVCallVisibility().
-  EXPECT_EQ(GO->getVCallVisibility(), LLVMGO->getVCallVisibility());
-  // Check canIncreaseAlignment().
-  EXPECT_EQ(GO->canIncreaseAlignment(), LLVMGO->canIncreaseAlignment());
-}
-
-TEST_F(SandboxIRTest, GlobalIFunc) {
-  parseIR(C, R"IR(
-declare external void @bar()
- at ifunc0 = ifunc void(), ptr @foo
- at ifunc1 = ifunc void(), ptr @foo
-define void @foo() {
-  call void @ifunc0()
-  call void @ifunc1()
-  call void @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMCall0 = cast<llvm::CallInst>(&*LLVMIt++);
-  auto *LLVMIFunc0 = cast<llvm::GlobalIFunc>(LLVMCall0->getCalledOperand());
-
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call0 = cast<sandboxir::CallInst>(&*It++);
-  auto *Call1 = cast<sandboxir::CallInst>(&*It++);
-  auto *CallBar = cast<sandboxir::CallInst>(&*It++);
-  // Check classof(), creation.
-  auto *IFunc0 = cast<sandboxir::GlobalIFunc>(Call0->getCalledOperand());
-  auto *IFunc1 = cast<sandboxir::GlobalIFunc>(Call1->getCalledOperand());
-  auto *Bar = cast<sandboxir::Function>(CallBar->getCalledOperand());
-
-  // Check getIterator().
-  {
-    auto It0 = IFunc0->getIterator();
-    auto It1 = IFunc1->getIterator();
-    EXPECT_EQ(&*It0, IFunc0);
-    EXPECT_EQ(&*It1, IFunc1);
-    EXPECT_EQ(std::next(It0), It1);
-    EXPECT_EQ(std::prev(It1), It0);
-    EXPECT_EQ(&*std::next(It0), IFunc1);
-    EXPECT_EQ(&*std::prev(It1), IFunc0);
-  }
-  // Check getReverseIterator().
-  {
-    auto RevIt0 = IFunc0->getReverseIterator();
-    auto RevIt1 = IFunc1->getReverseIterator();
-    EXPECT_EQ(&*RevIt0, IFunc0);
-    EXPECT_EQ(&*RevIt1, IFunc1);
-    EXPECT_EQ(std::prev(RevIt0), RevIt1);
-    EXPECT_EQ(std::next(RevIt1), RevIt0);
-    EXPECT_EQ(&*std::prev(RevIt0), IFunc1);
-    EXPECT_EQ(&*std::next(RevIt1), IFunc0);
-  }
-
-  // Check setResolver(), getResolver().
-  EXPECT_EQ(IFunc0->getResolver(), Ctx.getValue(LLVMIFunc0->getResolver()));
-  auto *OrigResolver = IFunc0->getResolver();
-  auto *NewResolver = Bar;
-  EXPECT_NE(NewResolver, OrigResolver);
-  IFunc0->setResolver(NewResolver);
-  EXPECT_EQ(IFunc0->getResolver(), NewResolver);
-  IFunc0->setResolver(OrigResolver);
-  EXPECT_EQ(IFunc0->getResolver(), OrigResolver);
-  // Check getResolverFunction().
-  EXPECT_EQ(IFunc0->getResolverFunction(),
-            Ctx.getValue(LLVMIFunc0->getResolverFunction()));
-  // Check isValidLinkage().
-  for (auto L :
-       {GlobalValue::ExternalLinkage, GlobalValue::AvailableExternallyLinkage,
-        GlobalValue::LinkOnceAnyLinkage, GlobalValue::LinkOnceODRLinkage,
-        GlobalValue::WeakAnyLinkage, GlobalValue::WeakODRLinkage,
-        GlobalValue::AppendingLinkage, GlobalValue::InternalLinkage,
-        GlobalValue::PrivateLinkage, GlobalValue::ExternalWeakLinkage,
-        GlobalValue::CommonLinkage}) {
-    EXPECT_EQ(IFunc0->isValidLinkage(L), LLVMIFunc0->isValidLinkage(L));
-  }
-}
-
-TEST_F(SandboxIRTest, GlobalVariable) {
-  parseIR(C, R"IR(
- at glob0 = global i32 42
- at glob1 = global i32 43
-define void @foo() {
-  %ld0 = load i32, ptr @glob0
-  %ld1 = load i32, ptr @glob1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMLd0 = cast<llvm::LoadInst>(&*LLVMIt++);
-  auto *LLVMGV0 = cast<llvm::GlobalVariable>(LLVMLd0->getPointerOperand());
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
-  // Check classof(), creation.
-  auto *GV0 = cast<sandboxir::GlobalVariable>(Ld0->getPointerOperand());
-  auto *GV1 = cast<sandboxir::GlobalVariable>(Ld1->getPointerOperand());
-  // Check getIterator().
-  {
-    auto It0 = GV0->getIterator();
-    auto It1 = GV1->getIterator();
-    EXPECT_EQ(&*It0, GV0);
-    EXPECT_EQ(&*It1, GV1);
-    EXPECT_EQ(std::next(It0), It1);
-    EXPECT_EQ(std::prev(It1), It0);
-    EXPECT_EQ(&*std::next(It0), GV1);
-    EXPECT_EQ(&*std::prev(It1), GV0);
-  }
-  // Check getReverseIterator().
-  {
-    auto RevIt0 = GV0->getReverseIterator();
-    auto RevIt1 = GV1->getReverseIterator();
-    EXPECT_EQ(&*RevIt0, GV0);
-    EXPECT_EQ(&*RevIt1, GV1);
-    EXPECT_EQ(std::prev(RevIt0), RevIt1);
-    EXPECT_EQ(std::next(RevIt1), RevIt0);
-    EXPECT_EQ(&*std::prev(RevIt0), GV1);
-    EXPECT_EQ(&*std::next(RevIt1), GV0);
-  }
-  // Check hasInitializer().
-  EXPECT_EQ(GV0->hasInitializer(), LLVMGV0->hasInitializer());
-  // Check hasDefinitiveInitializer().
-  EXPECT_EQ(GV0->hasDefinitiveInitializer(),
-            LLVMGV0->hasDefinitiveInitializer());
-  // Check hasUniqueInitializer().
-  EXPECT_EQ(GV0->hasUniqueInitializer(), LLVMGV0->hasUniqueInitializer());
-  // Check getInitializer().
-  EXPECT_EQ(GV0->getInitializer(), Ctx.getValue(LLVMGV0->getInitializer()));
-  // Check setInitializer().
-  auto *OrigInitializer = GV0->getInitializer();
-  auto *NewInitializer = GV1->getInitializer();
-  EXPECT_NE(NewInitializer, OrigInitializer);
-  GV0->setInitializer(NewInitializer);
-  EXPECT_EQ(GV0->getInitializer(), NewInitializer);
-  GV0->setInitializer(OrigInitializer);
-  EXPECT_EQ(GV0->getInitializer(), OrigInitializer);
-  // Check isConstant().
-  EXPECT_EQ(GV0->isConstant(), LLVMGV0->isConstant());
-  // Check setConstant().
-  bool OrigIsConstant = GV0->isConstant();
-  bool NewIsConstant = !OrigIsConstant;
-  GV0->setConstant(NewIsConstant);
-  EXPECT_EQ(GV0->isConstant(), NewIsConstant);
-  GV0->setConstant(OrigIsConstant);
-  EXPECT_EQ(GV0->isConstant(), OrigIsConstant);
-  // Check isExternallyInitialized().
-  EXPECT_EQ(GV0->isExternallyInitialized(), LLVMGV0->isExternallyInitialized());
-  // Check setExternallyInitialized().
-  bool OrigIsExtInit = GV0->isExternallyInitialized();
-  bool NewIsExtInit = !OrigIsExtInit;
-  GV0->setExternallyInitialized(NewIsExtInit);
-  EXPECT_EQ(GV0->isExternallyInitialized(), NewIsExtInit);
-  GV0->setExternallyInitialized(OrigIsExtInit);
-  EXPECT_EQ(GV0->isExternallyInitialized(), OrigIsExtInit);
-  for (auto KindIdx : seq<int>(0, Attribute::AttrKind::EndAttrKinds)) {
-    // Check hasAttribute(AttrKind).
-    auto Kind = static_cast<Attribute::AttrKind>(KindIdx);
-    EXPECT_EQ(GV0->hasAttribute(Kind), LLVMGV0->hasAttribute(Kind));
-    // Check hasAttribute(StringRef).
-    StringRef KindStr = Attribute::getNameFromAttrKind(Kind);
-    EXPECT_EQ(GV0->hasAttribute(KindStr), LLVMGV0->hasAttribute(KindStr));
-  }
-  // Check hasAttributes().
-  EXPECT_EQ(GV0->hasAttributes(), LLVMGV0->hasAttributes());
-
-  for (auto KindIdx : seq<int>(0, Attribute::AttrKind::EndAttrKinds)) {
-    // Check getAttribute(AttrKind).
-    auto Kind = static_cast<Attribute::AttrKind>(KindIdx);
-    EXPECT_EQ(GV0->getAttribute(Kind), LLVMGV0->getAttribute(Kind));
-    // Check getAttribute(StringRef).
-    StringRef KindStr = Attribute::getNameFromAttrKind(Kind);
-    EXPECT_EQ(GV0->getAttribute(KindStr), LLVMGV0->getAttribute(KindStr));
-  }
-  // Check getAttributes().
-  EXPECT_EQ(GV0->getAttributes(), LLVMGV0->getAttributes());
-  // Check getAttributesAsList().
-  EXPECT_THAT(GV0->getAttributesAsList(0u),
-              testing::ContainerEq(LLVMGV0->getAttributesAsList(0u)));
-  // Check hasImplicitSection().
-  EXPECT_EQ(GV0->hasImplicitSection(), LLVMGV0->hasImplicitSection());
-  // Check getCodeModelRaw().
-  EXPECT_EQ(GV0->getCodeModelRaw(), LLVMGV0->getCodeModelRaw());
-  // Check getCodeModel().
-  EXPECT_EQ(GV0->getCodeModel(), LLVMGV0->getCodeModel());
-  // Check getAlign().
-  EXPECT_EQ(GV0->getAlign(), LLVMGV0->getAlign());
-  // Check setAlignment().
-  auto OrigMaybeAlign = GV0->getAlign();
-  auto NewMaybeAlign = MaybeAlign(128);
-  EXPECT_NE(NewMaybeAlign, OrigMaybeAlign);
-  GV0->setAlignment(NewMaybeAlign);
-  EXPECT_EQ(GV0->getAlign(), NewMaybeAlign);
-  GV0->setAlignment(OrigMaybeAlign);
-  EXPECT_EQ(GV0->getAlign(), OrigMaybeAlign);
-}
-
-TEST_F(SandboxIRTest, GlobalAlias) {
-  parseIR(C, R"IR(
- at alias0 = dso_local alias void(), ptr @foo
- at alias1 = dso_local alias void(), ptr @foo
-declare void @bar();
-define void @foo() {
-  call void @alias0()
-  call void @alias1()
-  call void @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMCall0 = cast<llvm::CallInst>(&*LLVMIt++);
-  auto *LLVMAlias0 = cast<llvm::GlobalAlias>(LLVMCall0->getCalledOperand());
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call0 = cast<sandboxir::CallInst>(&*It++);
-  auto *Call1 = cast<sandboxir::CallInst>(&*It++);
-  auto *CallBar = cast<sandboxir::CallInst>(&*It++);
-  auto *CalleeBar = cast<sandboxir::Constant>(CallBar->getCalledOperand());
-  // Check classof(), creation.
-  auto *Alias0 = cast<sandboxir::GlobalAlias>(Call0->getCalledOperand());
-  auto *Alias1 = cast<sandboxir::GlobalAlias>(Call1->getCalledOperand());
-  // Check getIterator().
-  {
-    auto It0 = Alias0->getIterator();
-    auto It1 = Alias1->getIterator();
-    EXPECT_EQ(&*It0, Alias0);
-    EXPECT_EQ(&*It1, Alias1);
-    EXPECT_EQ(std::next(It0), It1);
-    EXPECT_EQ(std::prev(It1), It0);
-    EXPECT_EQ(&*std::next(It0), Alias1);
-    EXPECT_EQ(&*std::prev(It1), Alias0);
-  }
-  // Check getReverseIterator().
-  {
-    auto RevIt0 = Alias0->getReverseIterator();
-    auto RevIt1 = Alias1->getReverseIterator();
-    EXPECT_EQ(&*RevIt0, Alias0);
-    EXPECT_EQ(&*RevIt1, Alias1);
-    EXPECT_EQ(std::prev(RevIt0), RevIt1);
-    EXPECT_EQ(std::next(RevIt1), RevIt0);
-    EXPECT_EQ(&*std::prev(RevIt0), Alias1);
-    EXPECT_EQ(&*std::next(RevIt1), Alias0);
-  }
-  // Check getAliasee().
-  EXPECT_EQ(Alias0->getAliasee(), Ctx.getValue(LLVMAlias0->getAliasee()));
-  // Check setAliasee().
-  auto *OrigAliasee = Alias0->getAliasee();
-  auto *NewAliasee = CalleeBar;
-  EXPECT_NE(NewAliasee, OrigAliasee);
-  Alias0->setAliasee(NewAliasee);
-  EXPECT_EQ(Alias0->getAliasee(), NewAliasee);
-  Alias0->setAliasee(OrigAliasee);
-  EXPECT_EQ(Alias0->getAliasee(), OrigAliasee);
-  // Check getAliaseeObject().
-  EXPECT_EQ(Alias0->getAliaseeObject(),
-            Ctx.getValue(LLVMAlias0->getAliaseeObject()));
-}
-
-TEST_F(SandboxIRTest, NoCFIValue) {
-  parseIR(C, R"IR(
-define void @foo() {
-  call void no_cfi @foo()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call = cast<sandboxir::CallInst>(&*It++);
-  // Check classof(), creation.
-  auto *NoCFI = cast<sandboxir::NoCFIValue>(Call->getCalledOperand());
-  // Check get().
-  auto *NewNoCFI = sandboxir::NoCFIValue::get(&F);
-  EXPECT_EQ(NewNoCFI, NoCFI);
-  // Check getGlobalValue().
-  EXPECT_EQ(NoCFI->getGlobalValue(), &F);
-  // Check getType().
-  EXPECT_EQ(NoCFI->getType(), F.getType());
-}
-
-TEST_F(SandboxIRTest, ConstantPtrAuth) {
-  parseIR(C, R"IR(
-define ptr @foo() {
-  ret ptr ptrauth (ptr @foo, i32 2, i64 1234)
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMBB->begin());
-  auto *LLVMPtrAuth = cast<llvm::ConstantPtrAuth>(LLVMRet->getReturnValue());
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  // Check classof(), creation.
-  auto *PtrAuth = cast<sandboxir::ConstantPtrAuth>(Ret->getReturnValue());
-  // Check get(), getKey(), getDiscriminator(), getAddrDiscriminator().
-  auto *NewPtrAuth = sandboxir::ConstantPtrAuth::get(
-      &F, PtrAuth->getKey(), PtrAuth->getDiscriminator(),
-      PtrAuth->getAddrDiscriminator());
-  EXPECT_EQ(NewPtrAuth, PtrAuth);
-  // Check hasAddressDiscriminator().
-  EXPECT_EQ(PtrAuth->hasAddressDiscriminator(),
-            LLVMPtrAuth->hasAddressDiscriminator());
-  // Check hasSpecialAddressDiscriminator().
-  EXPECT_EQ(PtrAuth->hasSpecialAddressDiscriminator(0u),
-            LLVMPtrAuth->hasSpecialAddressDiscriminator(0u));
-  // Check isKnownCompatibleWith().
-  const DataLayout &DL = M->getDataLayout();
-  EXPECT_TRUE(PtrAuth->isKnownCompatibleWith(PtrAuth->getKey(),
-                                             PtrAuth->getDiscriminator(), DL));
-  // Check getWithSameSchema().
-  EXPECT_EQ(PtrAuth->getWithSameSchema(&F), PtrAuth);
-}
-
-TEST_F(SandboxIRTest, ConstantExpr) {
-  parseIR(C, R"IR(
-define i32 @foo() {
-  ret i32 ptrtoint (ptr @foo to i32)
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  // Check classof(), creation.
-  [[maybe_unused]] auto *ConstExpr =
-      cast<sandboxir::ConstantExpr>(Ret->getReturnValue());
-}
-
-TEST_F(SandboxIRTest, BlockAddress) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-bb0:
-  store ptr blockaddress(@foo, %bb0), ptr %ptr
-  ret void
-bb1:
-  ret void
-bb2:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *BB2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
-  auto It = BB0->begin();
-  auto *SI = cast<sandboxir::StoreInst>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check classof(), creation, getFunction(), getBasicBlock().
-  auto *BB0Addr = cast<sandboxir::BlockAddress>(SI->getValueOperand());
-  EXPECT_EQ(BB0Addr->getBasicBlock(), BB0);
-  EXPECT_EQ(BB0Addr->getFunction(), &F);
-  // Check get(F, BB).
-  auto *NewBB0Addr = sandboxir::BlockAddress::get(&F, BB0);
-  EXPECT_EQ(NewBB0Addr, BB0Addr);
-  // Check get(BB).
-  auto *NewBB0Addr2 = sandboxir::BlockAddress::get(BB0);
-  EXPECT_EQ(NewBB0Addr2, BB0Addr);
-  auto *BB1Addr = sandboxir::BlockAddress::get(BB1);
-  EXPECT_EQ(BB1Addr->getBasicBlock(), BB1);
-  EXPECT_NE(BB1Addr, BB0Addr);
-  // Check lookup().
-  auto *LookupBB0Addr = sandboxir::BlockAddress::lookup(BB0);
-  EXPECT_EQ(LookupBB0Addr, BB0Addr);
-  auto *LookupBB1Addr = sandboxir::BlockAddress::lookup(BB1);
-  EXPECT_EQ(LookupBB1Addr, BB1Addr);
-  auto *LookupBB2Addr = sandboxir::BlockAddress::lookup(BB2);
-  EXPECT_EQ(LookupBB2Addr, nullptr);
-}
-
-TEST_F(SandboxIRTest, DSOLocalEquivalent) {
-  parseIR(C, R"IR(
-declare void @bar()
-define void @foo() {
-  call void dso_local_equivalent @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *CI = cast<sandboxir::CallInst>(&*It++);
-  // Check classof().
-  auto *DSOLE = cast<sandboxir::DSOLocalEquivalent>(CI->getCalledOperand());
-  // Check getGlobalValue().
-  auto *GV = DSOLE->getGlobalValue();
-  // Check get().
-  auto *NewDSOLE = sandboxir::DSOLocalEquivalent::get(GV);
-  EXPECT_EQ(NewDSOLE, DSOLE);
-}
-
-TEST_F(SandboxIRTest, ConstantTokenNone) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
- bb0:
-   %cs = catchswitch within none [label %handler] unwind to caller
- handler:
-   ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *CS = cast<sandboxir::CatchSwitchInst>(&*BB0->begin());
-
-  // Check classof(), creation, getFunction(), getBasicBlock().
-  auto *CTN = cast<sandboxir::ConstantTokenNone>(CS->getParentPad());
-  // Check get().
-  auto *NewCTN = sandboxir::ConstantTokenNone::get(Ctx);
-  EXPECT_EQ(NewCTN, CTN);
-}
-
-TEST_F(SandboxIRTest, Use) {
-  parseIR(C, R"IR(
-define i32 @foo(i32 %v0, i32 %v1) {
-  %add0 = add i32 %v0, %v1
-  ret i32 %add0
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  BasicBlock *LLVMBB = &*LLVMF.begin();
-  auto LLVMBBIt = LLVMBB->begin();
-  Instruction *LLVMI0 = &*LLVMBBIt++;
-  Instruction *LLVMRet = &*LLVMBBIt++;
-  Argument *LLVMArg0 = LLVMF.getArg(0);
-  Argument *LLVMArg1 = LLVMF.getArg(1);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto *Arg0 = F.getArg(0);
-  auto *Arg1 = F.getArg(1);
-  auto It = BB.begin();
-  auto *I0 = &*It++;
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  SmallVector<sandboxir::Argument *> Args{Arg0, Arg1};
-  unsigned OpIdx = 0;
-  for (sandboxir::Use Use : I0->operands()) {
-    // Check Use.getOperandNo().
-    EXPECT_EQ(Use.getOperandNo(), OpIdx);
-    // Check Use.getUser().
-    EXPECT_EQ(Use.getUser(), I0);
-    // Check Use.getContext().
-    EXPECT_EQ(Use.getContext(), &Ctx);
-    // Check Use.get().
-    sandboxir::Value *Op = Use.get();
-    EXPECT_EQ(Op, Ctx.getValue(LLVMI0->getOperand(OpIdx)));
-    // Check Use.getUser().
-    EXPECT_EQ(Use.getUser(), I0);
-    // Check implicit cast to Value.
-    sandboxir::Value *Cast = Use;
-    EXPECT_EQ(Cast, Op);
-    // Check that Use points to the correct operand.
-    EXPECT_EQ(Op, Args[OpIdx]);
-    // Check getOperand().
-    EXPECT_EQ(Op, I0->getOperand(OpIdx));
-    // Check getOperandUse().
-    EXPECT_EQ(Use, I0->getOperandUse(OpIdx));
-    ++OpIdx;
-  }
-  EXPECT_EQ(OpIdx, 2u);
-
-  // Check Use.operator==() and Use.operator!=().
-  sandboxir::Use UseA = I0->getOperandUse(0);
-  sandboxir::Use UseB = I0->getOperandUse(0);
-  EXPECT_TRUE(UseA == UseB);
-  EXPECT_FALSE(UseA != UseB);
-
-  // Check getNumOperands().
-  EXPECT_EQ(I0->getNumOperands(), 2u);
-  EXPECT_EQ(Ret->getNumOperands(), 1u);
-
-  EXPECT_EQ(Ret->getOperand(0), I0);
-
-#ifndef NDEBUG
-  // Check Use.dump(()
-  std::string Buff;
-  raw_string_ostream BS(Buff);
-  BS << "\n";
-  I0->getOperandUse(0).dumpOS(BS);
-  EXPECT_EQ(Buff, R"IR(
-Def:  i32 %v0 ; SB2. (Argument)
-User:   %add0 = add i32 %v0, %v1 ; SB5. (BinaryOperator)
-OperandNo: 0
-)IR");
-#endif // NDEBUG
-
-  // Check Value.user_begin().
-  sandboxir::Value::user_iterator UIt = I0->user_begin();
-  sandboxir::User *U = *UIt;
-  EXPECT_EQ(U, Ret);
-  // Check Value.uses().
-  EXPECT_EQ(range_size(I0->uses()), 1u);
-  EXPECT_EQ((*I0->uses().begin()).getUser(), Ret);
-  // Check Value.users().
-  EXPECT_EQ(range_size(I0->users()), 1u);
-  EXPECT_EQ(*I0->users().begin(), Ret);
-  // Check Value.getNumUses().
-  EXPECT_EQ(I0->getNumUses(), 1u);
-  // Check Value.hasNUsesOrMore().
-  EXPECT_TRUE(I0->hasNUsesOrMore(0u));
-  EXPECT_TRUE(I0->hasNUsesOrMore(1u));
-  EXPECT_FALSE(I0->hasNUsesOrMore(2u));
-  // Check Value.hasNUses().
-  EXPECT_FALSE(I0->hasNUses(0u));
-  EXPECT_TRUE(I0->hasNUses(1u));
-  EXPECT_FALSE(I0->hasNUses(2u));
-
-  // Check Value.getExpectedType
-
-  // Check User.setOperand().
-  Ret->setOperand(0, Arg0);
-  EXPECT_EQ(Ret->getOperand(0), Arg0);
-  EXPECT_EQ(Ret->getOperandUse(0).get(), Arg0);
-  EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg0);
-
-  Ret->setOperand(0, Arg1);
-  EXPECT_EQ(Ret->getOperand(0), Arg1);
-  EXPECT_EQ(Ret->getOperandUse(0).get(), Arg1);
-  EXPECT_EQ(LLVMRet->getOperand(0), LLVMArg1);
-}
-
-TEST_F(SandboxIRTest, RUOW) {
-  parseIR(C, R"IR(
-declare void @bar0()
-declare void @bar1()
-
- at glob0 = global ptr @bar0
- at glob1 = global ptr @bar1
-
-define i32 @foo(i32 %arg0, i32 %arg1) {
-  %add0 = add i32 %arg0, %arg1
-  %gep1 = getelementptr i8, ptr @glob0, i32 1
-  %gep2 = getelementptr i8, ptr @glob1, i32 1
-  ret i32 %add0
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto *Arg0 = F.getArg(0);
-  auto *Arg1 = F.getArg(1);
-  auto It = BB.begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  bool Replaced;
-  // Try to replace an operand that doesn't match.
-  Replaced = I0->replaceUsesOfWith(Ret, Arg1);
-  EXPECT_FALSE(Replaced);
-  EXPECT_EQ(I0->getOperand(0), Arg0);
-  EXPECT_EQ(I0->getOperand(1), Arg1);
-
-  // Replace I0 operands when operands differ.
-  Replaced = I0->replaceUsesOfWith(Arg0, Arg1);
-  EXPECT_TRUE(Replaced);
-  EXPECT_EQ(I0->getOperand(0), Arg1);
-  EXPECT_EQ(I0->getOperand(1), Arg1);
-
-  // Replace I0 operands when operands are the same.
-  Replaced = I0->replaceUsesOfWith(Arg1, Arg0);
-  EXPECT_TRUE(Replaced);
-  EXPECT_EQ(I0->getOperand(0), Arg0);
-  EXPECT_EQ(I0->getOperand(1), Arg0);
-
-  // Replace Ret operand.
-  Replaced = Ret->replaceUsesOfWith(I0, Arg0);
-  EXPECT_TRUE(Replaced);
-  EXPECT_EQ(Ret->getOperand(0), Arg0);
-  // Check RAUW on constant.
-  auto *Glob0 = cast<sandboxir::Constant>(I1->getOperand(0));
-  auto *Glob1 = cast<sandboxir::Constant>(I2->getOperand(0));
-  auto *Glob0Op = Glob0->getOperand(0);
-  Glob0->replaceUsesOfWith(Glob0Op, Glob1);
-  EXPECT_EQ(Glob0->getOperand(0), Glob1);
-}
-
-TEST_F(SandboxIRTest, RAUW_RUWIf) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %ld0 = load float, ptr %ptr
-  %ld1 = load float, ptr %ptr
-  store float %ld0, ptr %ptr
-  store float %ld0, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
-
-  Ctx.createFunction(&LLVMF);
-  auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
-  auto It = BB->begin();
-  sandboxir::Instruction *Ld0 = &*It++;
-  sandboxir::Instruction *Ld1 = &*It++;
-  sandboxir::Instruction *St0 = &*It++;
-  sandboxir::Instruction *St1 = &*It++;
-  // Check RUWIf when the lambda returns false.
-  Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; });
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-  // Check RUWIf when the lambda returns true.
-  Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; });
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-  EXPECT_EQ(St1->getOperand(0), Ld1);
-  St0->setOperand(0, Ld0);
-  St1->setOperand(0, Ld0);
-  // Check RUWIf user == St0.
-  Ld0->replaceUsesWithIf(
-      Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; });
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-  St0->setOperand(0, Ld0);
-  // Check RUWIf user == St1.
-  Ld0->replaceUsesWithIf(
-      Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; });
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld1);
-  St1->setOperand(0, Ld0);
-  // Check RAUW.
-  Ld1->replaceAllUsesWith(Ld0);
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-}
-
-// Check that the operands/users are counted correctly.
-//  I1
-// /  \
-// \  /
-//  I2
-TEST_F(SandboxIRTest, DuplicateUses) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v) {
-  %I1 = add i8 %v, %v
-  %I2 = add i8 %I1, %I1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  EXPECT_EQ(range_size(I1->users()), 2u);
-  EXPECT_EQ(range_size(I2->operands()), 2u);
-}
-
-TEST_F(SandboxIRTest, Function) {
-  parseIR(C, R"IR(
-define void @foo0(i32 %arg0, i32 %arg1) {
-bb0:
-  br label %bb1
-bb1:
-  ret void
-}
-define void @foo1() {
-  ret void
-}
-
-)IR");
-  llvm::Function *LLVMF0 = &*M->getFunction("foo0");
-  llvm::Function *LLVMF1 = &*M->getFunction("foo1");
-  llvm::Argument *LLVMArg0 = LLVMF0->getArg(0);
-  llvm::Argument *LLVMArg1 = LLVMF0->getArg(1);
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F0 = Ctx.createFunction(LLVMF0);
-  sandboxir::Function *F1 = Ctx.createFunction(LLVMF1);
-
-  // Check getIterator().
-  {
-    auto It0 = F0->getIterator();
-    auto It1 = F1->getIterator();
-    EXPECT_EQ(&*It0, F0);
-    EXPECT_EQ(&*It1, F1);
-    EXPECT_EQ(std::next(It0), It1);
-    EXPECT_EQ(std::prev(It1), It0);
-    EXPECT_EQ(&*std::next(It0), F1);
-    EXPECT_EQ(&*std::prev(It1), F0);
-  }
-  // Check getReverseIterator().
-  {
-    auto RevIt0 = F0->getReverseIterator();
-    auto RevIt1 = F1->getReverseIterator();
-    EXPECT_EQ(&*RevIt0, F0);
-    EXPECT_EQ(&*RevIt1, F1);
-    EXPECT_EQ(std::prev(RevIt0), RevIt1);
-    EXPECT_EQ(std::next(RevIt1), RevIt0);
-    EXPECT_EQ(&*std::prev(RevIt0), F1);
-    EXPECT_EQ(&*std::next(RevIt1), F0);
-  }
-
-  // Check F arguments
-  EXPECT_EQ(F0->arg_size(), 2u);
-  EXPECT_FALSE(F0->arg_empty());
-  EXPECT_EQ(F0->getArg(0), Ctx.getValue(LLVMArg0));
-  EXPECT_EQ(F0->getArg(1), Ctx.getValue(LLVMArg1));
-
-  // Check F.begin(), F.end(), Function::iterator
-  llvm::BasicBlock *LLVMBB = &*LLVMF0->begin();
-  for (sandboxir::BasicBlock &BB : *F0) {
-    EXPECT_EQ(&BB, Ctx.getValue(LLVMBB));
-    LLVMBB = LLVMBB->getNextNode();
-  }
-
-#ifndef NDEBUG
-  {
-    // Check F.dumpNameAndArgs()
-    std::string Buff;
-    raw_string_ostream BS(Buff);
-    F0->dumpNameAndArgs(BS);
-    EXPECT_EQ(Buff, "void @foo0(i32 %arg0, i32 %arg1)");
-  }
-  {
-    // Check F.dump()
-    std::string Buff;
-    raw_string_ostream BS(Buff);
-    BS << "\n";
-    F0->dumpOS(BS);
-    EXPECT_EQ(Buff, R"IR(
-void @foo0(i32 %arg0, i32 %arg1) {
-bb0:
-  br label %bb1 ; SB4. (Br)
-
-bb1:
-  ret void ; SB6. (Ret)
-}
-)IR");
-  }
-#endif // NDEBUG
-
-  // Check getAlign().
-  EXPECT_EQ(F0->getAlign(), F0->getAlign());
-  // Check setAlignment().
-  auto OrigMaybeAlign = F0->getAlign();
-  auto NewMaybeAlign = MaybeAlign(128);
-  EXPECT_NE(NewMaybeAlign, OrigMaybeAlign);
-  F0->setAlignment(NewMaybeAlign);
-  EXPECT_EQ(F0->getAlign(), NewMaybeAlign);
-  F0->setAlignment(OrigMaybeAlign);
-  EXPECT_EQ(F0->getAlign(), OrigMaybeAlign);
-}
-
-TEST_F(SandboxIRTest, Module) {
-  parseIR(C, R"IR(
- at glob0 = global i32 42
- at glob1 = global i32 43
- at internal0 = internal global i32 42
- at const0 = constant i32 42
- at alias0 = dso_local alias void(), ptr @foo
- at ifunc = ifunc void(), ptr @foo
-define void @foo() {
-  ret void
-}
-define void @bar() {
-  ret void
-}
-)IR");
-  llvm::Module *LLVMM = &*M;
-  llvm::Function *LLVMFFoo = &*M->getFunction("foo");
-  llvm::Function *LLVMFBar = &*M->getFunction("bar");
-
-  sandboxir::Context Ctx(C);
-  auto *M = Ctx.createModule(LLVMM);
-  // Check getContext().
-  EXPECT_EQ(&M->getContext(), &Ctx);
-  // Check getFunction().
-  auto *FFoo = M->getFunction("foo");
-  auto *FBar = M->getFunction("bar");
-  EXPECT_EQ(FFoo, Ctx.getValue(LLVMFFoo));
-  EXPECT_EQ(FBar, Ctx.getValue(LLVMFBar));
-  // Check getDataLayout().
-  EXPECT_EQ(&M->getDataLayout(), &LLVMM->getDataLayout());
-  // Check getSourceFileName().
-  EXPECT_EQ(M->getSourceFileName(), LLVMM->getSourceFileName());
-  // Check getGlobalVariable().
-  for (const char *Name : {"global0", "global1", "internal0"})
-    EXPECT_EQ(M->getGlobalVariable(Name),
-              Ctx.getValue(LLVMM->getGlobalVariable(Name)));
-  // Check getGlobalVariable(AllowInternal).
-  {
-    auto *Internal0 = M->getGlobalVariable("internal0", /*AllowInternal=*/true);
-    EXPECT_TRUE(Internal0 != nullptr);
-    EXPECT_EQ(Internal0, Ctx.getValue(LLVMM->getNamedGlobal("internal0")));
-  }
-  // Check getNamedGlobal().
-  {
-    auto *Internal = M->getNamedGlobal("internal0");
-    EXPECT_TRUE(Internal != nullptr);
-    EXPECT_EQ(Internal, Ctx.getValue(LLVMM->getNamedGlobal("internal0")));
-  }
-  // Check getNamedAlias().
-  auto *Alias0 = M->getNamedAlias("alias0");
-  EXPECT_EQ(Alias0, Ctx.getValue(LLVMM->getNamedAlias("alias0")));
-  EXPECT_EQ(M->getNamedAlias("aliasFOO"), nullptr);
-  // Check getNamedIFunc().
-  auto *IFunc0 = M->getNamedIFunc("ifunc0");
-  EXPECT_EQ(IFunc0, Ctx.getValue(LLVMM->getNamedAlias("ifunc0")));
-  EXPECT_EQ(M->getNamedIFunc("ifuncFOO"), nullptr);
-}
-
-TEST_F(SandboxIRTest, BasicBlock) {
-  parseIR(C, R"IR(
-define void @foo(i32 %v1) {
-bb0:
-  br label %bb1
-bb1:
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB0 = getBasicBlockByName(*LLVMF, "bb0");
-  llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto &BB0 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB0));
-  auto &BB1 = cast<sandboxir::BasicBlock>(*Ctx.getValue(LLVMBB1));
-
-  // Check BB::classof()
-  EXPECT_TRUE(isa<sandboxir::Value>(BB0));
-  EXPECT_FALSE(isa<sandboxir::User>(BB0));
-  EXPECT_FALSE(isa<sandboxir::Instruction>(BB0));
-  EXPECT_FALSE(isa<sandboxir::Constant>(BB0));
-  EXPECT_FALSE(isa<sandboxir::Argument>(BB0));
-
-  // Check BB.getParent()
-  EXPECT_EQ(BB0.getParent(), F);
-  EXPECT_EQ(BB1.getParent(), F);
-
-  // Check BBIterator, BB.begin(), BB.end().
-  llvm::Instruction *LLVMI = &*LLVMBB0->begin();
-  for (sandboxir::Instruction &I : BB0) {
-    EXPECT_EQ(&I, Ctx.getValue(LLVMI));
-    LLVMI = LLVMI->getNextNode();
-    // Check getNodeParent().
-    EXPECT_EQ(I.getIterator().getNodeParent(), &BB0);
-  }
-  LLVMI = &*LLVMBB1->begin();
-  for (sandboxir::Instruction &I : BB1) {
-    EXPECT_EQ(&I, Ctx.getValue(LLVMI));
-    LLVMI = LLVMI->getNextNode();
-  }
-  // Check NodeParent() for BB::end().
-  EXPECT_EQ(BB0.end().getNodeParent(), &BB0);
-
-  // Check BB.getTerminator()
-  EXPECT_EQ(BB0.getTerminator(), Ctx.getValue(LLVMBB0->getTerminator()));
-  EXPECT_EQ(BB1.getTerminator(), Ctx.getValue(LLVMBB1->getTerminator()));
-
-  // Check BB.rbegin(), BB.rend()
-  EXPECT_EQ(&*BB0.rbegin(), BB0.getTerminator());
-  EXPECT_EQ(&*std::prev(BB0.rend()), &*BB0.begin());
-
-#ifndef NDEBUG
-  {
-    // Check BB.dump()
-    std::string Buff;
-    raw_string_ostream BS(Buff);
-    BS << "\n";
-    BB0.dumpOS(BS);
-    EXPECT_EQ(Buff, R"IR(
-bb0:
-  br label %bb1 ; SB3. (Br)
-)IR");
-  }
-#endif // NDEBUG
-}
-
-TEST_F(SandboxIRTest, Instruction) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v1, ptr %ptr) {
-bb0:
-  %add0 = add i8 %v1, %v1
-  %sub1 = sub i8 %add0, %v1
-  ret void
-
-bb1:
-  %add1 = add i8 %v1, %v1
-  %sub2 = sub i8 %add1, %v1
-  %ld0 = load i8, ptr %ptr
-  store i8 %ld0, ptr %ptr
-  store volatile i8 %ld0, ptr %ptr
-  %atomicrmw = atomicrmw add ptr %ptr, i8 %v1 acquire
-  %udiv = udiv i8 %ld0, %v1
-  %urem = urem i8 %ld0, %v1
-  call void @foo(), !dbg !1
-  ret void, !tbaa !2
-}
-
-!1 = !{}
-!2 = !{}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB1 = getBasicBlockByName(*LLVMF, "bb1");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Arg = F->getArg(0);
-  auto *BB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0")));
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check getPrevNode().
-  EXPECT_EQ(Ret->getPrevNode(), I1);
-  EXPECT_EQ(I1->getPrevNode(), I0);
-  EXPECT_EQ(I0->getPrevNode(), nullptr);
-
-  // Check getNextNode().
-  EXPECT_EQ(I0->getNextNode(), I1);
-  EXPECT_EQ(I1->getNextNode(), Ret);
-  EXPECT_EQ(Ret->getNextNode(), nullptr);
-
-  // Check getIterator().
-  EXPECT_EQ(I0->getIterator(), std::next(BB->begin(), 0));
-  EXPECT_EQ(I1->getIterator(), std::next(BB->begin(), 1));
-  EXPECT_EQ(Ret->getIterator(), std::next(BB->begin(), 2));
-
-  // Check getOpcode().
-  EXPECT_EQ(I0->getOpcode(), sandboxir::Instruction::Opcode::Add);
-  EXPECT_EQ(I1->getOpcode(), sandboxir::Instruction::Opcode::Sub);
-  EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
-
-  // Check getOpcodeName().
-  EXPECT_STREQ(I0->getOpcodeName(), "Add");
-  EXPECT_STREQ(I1->getOpcodeName(), "Sub");
-  EXPECT_STREQ(Ret->getOpcodeName(), "Ret");
-
-  EXPECT_STREQ(sandboxir::Instruction::getOpcodeName(
-                   sandboxir::Instruction::Opcode::Alloca),
-               "Alloca");
-
-  // Check moveBefore(I).
-  I1->moveBefore(I0);
-  EXPECT_EQ(I0->getPrevNode(), I1);
-  EXPECT_EQ(I1->getNextNode(), I0);
-
-  // Check moveAfter(I).
-  I1->moveAfter(I0);
-  EXPECT_EQ(I0->getNextNode(), I1);
-  EXPECT_EQ(I1->getPrevNode(), I0);
-
-  // Check comesBefore(I).
-  EXPECT_TRUE(I0->comesBefore(I1));
-  EXPECT_FALSE(I1->comesBefore(I0));
-
-  // Check moveBefore(BB, It).
-  I1->moveBefore(*BB, BB->begin());
-  EXPECT_EQ(I1->getPrevNode(), nullptr);
-  EXPECT_EQ(I1->getNextNode(), I0);
-  I1->moveBefore(*BB, BB->end());
-  EXPECT_EQ(I1->getNextNode(), nullptr);
-  EXPECT_EQ(Ret->getNextNode(), I1);
-  I1->moveBefore(*BB, std::next(BB->begin()));
-  EXPECT_EQ(I0->getNextNode(), I1);
-  EXPECT_EQ(I1->getNextNode(), Ret);
-
-  // Check removeFromParent().
-  I0->removeFromParent();
-#ifndef NDEBUG
-  EXPECT_DEATH(I0->getPrevNode(), ".*Detached.*");
-  EXPECT_DEATH(I0->getNextNode(), ".*Detached.*");
-#endif // NDEBUG
-  EXPECT_EQ(I0->getParent(), nullptr);
-  EXPECT_EQ(I1->getPrevNode(), nullptr);
-  EXPECT_EQ(I0->getOperand(0), Arg);
-
-  // Check insertBefore().
-  I0->insertBefore(I1);
-  EXPECT_EQ(I1->getPrevNode(), I0);
-
-  // Check insertInto().
-  I0->removeFromParent();
-  I0->insertInto(BB, BB->end());
-  EXPECT_EQ(Ret->getNextNode(), I0);
-  I0->moveBefore(I1);
-  EXPECT_EQ(I0->getNextNode(), I1);
-
-  // Check eraseFromParent().
-#ifndef NDEBUG
-  EXPECT_DEATH(I0->eraseFromParent(), "Still connected to users.*");
-#endif
-  I1->eraseFromParent();
-  EXPECT_EQ(I0->getNumUses(), 0u);
-  EXPECT_EQ(I0->getNextNode(), Ret);
-
-  for (auto &LLVMI : *LLVMBB1) {
-    auto &I = cast<sandboxir::Instruction>(*Ctx.getValue(&LLVMI));
-    // Check isTerminator().
-    EXPECT_EQ(LLVMI.isTerminator(), I.isTerminator());
-    // Check isUnaryOp().
-    EXPECT_EQ(LLVMI.isUnaryOp(), I.isUnaryOp());
-    // Check isBinaryOp().
-    EXPECT_EQ(LLVMI.isBinaryOp(), I.isBinaryOp());
-    // Check isIntDivRem().
-    EXPECT_EQ(LLVMI.isIntDivRem(), I.isIntDivRem());
-    // Check isShift().
-    EXPECT_EQ(LLVMI.isShift(), I.isShift());
-    // Check isCast().
-    EXPECT_EQ(LLVMI.isCast(), I.isCast());
-    // Check isFuncletPad().
-    EXPECT_EQ(LLVMI.isFuncletPad(), I.isFuncletPad());
-    // Check isSpecialTerminator().
-    EXPECT_EQ(LLVMI.isSpecialTerminator(), I.isSpecialTerminator());
-    // Check isOnlyUserOfAnyOperand().
-    EXPECT_EQ(LLVMI.isOnlyUserOfAnyOperand(), I.isOnlyUserOfAnyOperand());
-    // Check isLogicalShift().
-    EXPECT_EQ(LLVMI.isLogicalShift(), I.isLogicalShift());
-    // Check hasMetadata().
-    EXPECT_EQ(LLVMI.hasMetadata(), I.hasMetadata());
-    // Check hasMetadataOtherThanDebugLoc().
-    EXPECT_EQ(LLVMI.hasMetadataOtherThanDebugLoc(),
-              I.hasMetadataOtherThanDebugLoc());
-    // Check isAssociative().
-    EXPECT_EQ(LLVMI.isAssociative(), I.isAssociative());
-    // Check isCommutative().
-    EXPECT_EQ(LLVMI.isCommutative(), I.isCommutative());
-    // Check isIdempotent().
-    EXPECT_EQ(LLVMI.isIdempotent(), I.isIdempotent());
-    // Check isNilpotent().
-    EXPECT_EQ(LLVMI.isNilpotent(), I.isNilpotent());
-    // Check mayWriteToMemory().
-    EXPECT_EQ(LLVMI.mayWriteToMemory(), I.mayWriteToMemory());
-    // Check mayReadFromMemory().
-    EXPECT_EQ(LLVMI.mayReadFromMemory(), I.mayReadFromMemory());
-    // Check mayReadOrWriteMemory().
-    EXPECT_EQ(LLVMI.mayReadOrWriteMemory(), I.mayReadOrWriteMemory());
-    // Check isAtomic().
-    EXPECT_EQ(LLVMI.isAtomic(), I.isAtomic());
-    if (I.isAtomic()) {
-      // Check hasAtomicLoad().
-      EXPECT_EQ(LLVMI.hasAtomicLoad(), I.hasAtomicLoad());
-      // Check hasAtomicStore().
-      EXPECT_EQ(LLVMI.hasAtomicStore(), I.hasAtomicStore());
-    }
-    // Check isVolatile().
-    EXPECT_EQ(LLVMI.isVolatile(), I.isVolatile());
-    // Check getAccessType().
-    EXPECT_EQ(Ctx.getType(LLVMI.getAccessType()), I.getAccessType());
-    // Check mayThrow().
-    EXPECT_EQ(LLVMI.mayThrow(), I.mayThrow());
-    // Check isFenceLike().
-    EXPECT_EQ(LLVMI.isFenceLike(), I.isFenceLike());
-    // Check mayHaveSideEffects().
-    EXPECT_EQ(LLVMI.mayHaveSideEffects(), I.mayHaveSideEffects());
-  }
-}
-
-TEST_F(SandboxIRTest, VAArgInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %va) {
-  %va_arg = va_arg ptr %va, i32
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Arg = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *VA = cast<sandboxir::VAArgInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check getPointerOperand().
-  EXPECT_EQ(VA->getPointerOperand(), Arg);
-  // Check getPOinterOperandIndex().
-  EXPECT_EQ(sandboxir::VAArgInst::getPointerOperandIndex(),
-            llvm::VAArgInst::getPointerOperandIndex());
-  // Check create().
-  auto *NewVATy = sandboxir::Type::getInt8Ty(Ctx);
-  auto *NewVA = sandboxir::VAArgInst::create(Arg, NewVATy, Ret->getIterator(),
-                                             Ctx, "NewVA");
-  EXPECT_EQ(NewVA->getNextNode(), Ret);
-  EXPECT_EQ(NewVA->getType(), NewVATy);
-#ifndef NDEBUG
-  EXPECT_EQ(NewVA->getName(), "NewVA");
-#endif // NDEBUG
-}
-
-TEST_F(SandboxIRTest, FreezeInst) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg) {
-  freeze i8 %arg
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Arg = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Freeze = cast<sandboxir::FreezeInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Freeze));
-  EXPECT_EQ(Freeze->getOperand(0), Arg);
-
-  // Check create().
-  auto *NewFreeze =
-      sandboxir::FreezeInst::create(Arg, Ret->getIterator(), Ctx, "NewFreeze");
-  EXPECT_EQ(NewFreeze->getNextNode(), Ret);
-#ifndef NDEBUG
-  EXPECT_EQ(NewFreeze->getName(), "NewFreeze");
-#endif // NDEBUG
-}
-
-TEST_F(SandboxIRTest, FenceInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-  fence syncscope("singlethread") seq_cst
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB = &*LLVMF->begin();
-  auto *LLVMFence = cast<llvm::FenceInst>(&*LLVMBB->begin());
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Fence = cast<sandboxir::FenceInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check getOrdering().
-  EXPECT_EQ(Fence->getOrdering(), LLVMFence->getOrdering());
-  // Check setOrdering().
-  auto OrigOrdering = Fence->getOrdering();
-  auto NewOrdering = AtomicOrdering::Release;
-  EXPECT_NE(NewOrdering, OrigOrdering);
-  Fence->setOrdering(NewOrdering);
-  EXPECT_EQ(Fence->getOrdering(), NewOrdering);
-  Fence->setOrdering(OrigOrdering);
-  EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
-  // Check getSyncScopeID().
-  EXPECT_EQ(Fence->getSyncScopeID(), LLVMFence->getSyncScopeID());
-  // Check setSyncScopeID().
-  auto OrigSSID = Fence->getSyncScopeID();
-  auto NewSSID = SyncScope::System;
-  EXPECT_NE(NewSSID, OrigSSID);
-  Fence->setSyncScopeID(NewSSID);
-  EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
-  Fence->setSyncScopeID(OrigSSID);
-  EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
-  // Check create().
-  auto *NewFence =
-      sandboxir::FenceInst::create(AtomicOrdering::Release, Ret->getIterator(),
-                                   Ctx, SyncScope::SingleThread);
-  EXPECT_EQ(NewFence->getNextNode(), Ret);
-  EXPECT_EQ(NewFence->getOrdering(), AtomicOrdering::Release);
-  EXPECT_EQ(NewFence->getSyncScopeID(), SyncScope::SingleThread);
-}
-
-TEST_F(SandboxIRTest, SelectInst) {
-  parseIR(C, R"IR(
-define void @foo(i1 %c0, i8 %v0, i8 %v1, i1 %c1) {
-  %sel = select i1 %c0, i8 %v0, i8 %v1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Cond0 = F->getArg(0);
-  auto *V0 = F->getArg(1);
-  auto *V1 = F->getArg(2);
-  auto *Cond1 = F->getArg(3);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Select = cast<sandboxir::SelectInst>(&*It++);
-  const auto *ConstSelect = Select; // To test the const getters.
-  auto *Ret = &*It++;
-
-  // Check getCondition().
-  EXPECT_EQ(Select->getCondition(), Cond0);
-  EXPECT_EQ(ConstSelect->getCondition(), Cond0);
-  // Check getTrueValue().
-  EXPECT_EQ(Select->getTrueValue(), V0);
-  EXPECT_EQ(ConstSelect->getTrueValue(), V0);
-  // Check getFalseValue().
-  EXPECT_EQ(Select->getFalseValue(), V1);
-  EXPECT_EQ(ConstSelect->getFalseValue(), V1);
-  // Check setCondition().
-  Select->setCondition(Cond1);
-  EXPECT_EQ(Select->getCondition(), Cond1);
-  // Check setTrueValue().
-  Select->setTrueValue(V1);
-  EXPECT_EQ(Select->getTrueValue(), V1);
-  // Check setFalseValue().
-  Select->setFalseValue(V0);
-  EXPECT_EQ(Select->getFalseValue(), V0);
-  // Check swapValues().
-  Select->swapValues();
-  EXPECT_EQ(Select->getTrueValue(), V0);
-  EXPECT_EQ(Select->getFalseValue(), V1);
-  // Check areInvalidOperands.
-  EXPECT_EQ(sandboxir::SelectInst::areInvalidOperands(Cond0, V0, V1), nullptr);
-  EXPECT_NE(sandboxir::SelectInst::areInvalidOperands(V0, V1, Cond0), nullptr);
-
-  {
-    // Check SelectInst::create() InsertBefore.
-    auto *NewSel = cast<sandboxir::SelectInst>(sandboxir::SelectInst::create(
-        Cond0, V0, V1, /*InsertBefore=*/Ret->getIterator(), Ctx));
-    EXPECT_EQ(NewSel->getCondition(), Cond0);
-    EXPECT_EQ(NewSel->getTrueValue(), V0);
-    EXPECT_EQ(NewSel->getFalseValue(), V1);
-    EXPECT_EQ(NewSel->getNextNode(), Ret);
-  }
-  {
-    // Check SelectInst::create() InsertAtEnd.
-    auto *NewSel = cast<sandboxir::SelectInst>(
-        sandboxir::SelectInst::create(Cond0, V0, V1, /*InsertAtEnd=*/BB, Ctx));
-    EXPECT_EQ(NewSel->getCondition(), Cond0);
-    EXPECT_EQ(NewSel->getTrueValue(), V0);
-    EXPECT_EQ(NewSel->getFalseValue(), V1);
-    EXPECT_EQ(NewSel->getPrevNode(), Ret);
-  }
-  {
-    // Check SelectInst::create() Folded.
-    auto *False = sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx),
-                                              0, /*IsSigned=*/false);
-    auto *FortyTwo =
-        sandboxir::ConstantInt::get(sandboxir::Type::getInt1Ty(Ctx), 42,
-                                    /*IsSigned=*/false);
-    auto *NewSel = sandboxir::SelectInst::create(False, FortyTwo, FortyTwo,
-                                                 Ret->getIterator(), Ctx);
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewSel));
-    EXPECT_EQ(NewSel, FortyTwo);
-  }
-}
-
-TEST_F(SandboxIRTest, ExtractElementInst) {
-  parseIR(C, R"IR(
-define void @foo(<2 x i8> %vec, i32 %idx) {
-  %ins0 = extractelement <2 x i8> %vec, i32 %idx
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *ArgVec = F.getArg(0);
-  auto *ArgIdx = F.getArg(1);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *EI = cast<sandboxir::ExtractElementInst>(&*It++);
-  auto *Ret = &*It++;
-
-  EXPECT_EQ(EI->getOpcode(), sandboxir::Instruction::Opcode::ExtractElement);
-  EXPECT_EQ(EI->getOperand(0), ArgVec);
-  EXPECT_EQ(EI->getOperand(1), ArgIdx);
-  EXPECT_EQ(EI->getVectorOperand(), ArgVec);
-  EXPECT_EQ(EI->getIndexOperand(), ArgIdx);
-  EXPECT_EQ(EI->getVectorOperandType(), ArgVec->getType());
-
-  auto *NewI1 =
-      cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create(
-          ArgVec, ArgIdx, Ret->getIterator(), Ctx, "NewExtrBeforeRet"));
-  EXPECT_EQ(NewI1->getOperand(0), ArgVec);
-  EXPECT_EQ(NewI1->getOperand(1), ArgIdx);
-  EXPECT_EQ(NewI1->getNextNode(), Ret);
-
-  auto *NewI2 =
-      cast<sandboxir::ExtractElementInst>(sandboxir::ExtractElementInst::create(
-          ArgVec, ArgIdx, BB, Ctx, "NewExtrAtEndOfBB"));
-  EXPECT_EQ(NewI2->getPrevNode(), Ret);
-
-  auto *LLVMArgVec = LLVMF.getArg(0);
-  auto *LLVMArgIdx = LLVMF.getArg(1);
-  EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgVec, ArgIdx),
-            llvm::ExtractElementInst::isValidOperands(LLVMArgVec, LLVMArgIdx));
-  EXPECT_EQ(sandboxir::ExtractElementInst::isValidOperands(ArgIdx, ArgVec),
-            llvm::ExtractElementInst::isValidOperands(LLVMArgIdx, LLVMArgVec));
-}
-
-TEST_F(SandboxIRTest, InsertElementInst) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0, i8 %v1, <2 x i8> %vec) {
-  %ins0 = insertelement <2 x i8> poison, i8 %v0, i32 0
-  %ins1 = insertelement <2 x i8> %ins0, i8 %v1, i32 1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Arg0 = F.getArg(0);
-  auto *Arg1 = F.getArg(1);
-  auto *ArgVec = F.getArg(2);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Ins0 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *Ins1 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *Ret = &*It++;
-
-  EXPECT_EQ(Ins0->getOpcode(), sandboxir::Instruction::Opcode::InsertElement);
-  EXPECT_EQ(Ins0->getOperand(1), Arg0);
-  EXPECT_EQ(Ins1->getOperand(1), Arg1);
-  EXPECT_EQ(Ins1->getOperand(0), Ins0);
-  auto *Poison = Ins0->getOperand(0);
-  auto *Idx = Ins0->getOperand(2);
-  auto *NewI1 =
-      cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create(
-          Poison, Arg0, Idx, Ret->getIterator(), Ctx, "NewIns1"));
-  EXPECT_EQ(NewI1->getOperand(0), Poison);
-  EXPECT_EQ(NewI1->getNextNode(), Ret);
-
-  auto *NewI2 =
-      cast<sandboxir::InsertElementInst>(sandboxir::InsertElementInst::create(
-          Poison, Arg0, Idx, BB, Ctx, "NewIns2"));
-  EXPECT_EQ(NewI2->getPrevNode(), Ret);
-
-  auto *LLVMArg0 = LLVMF.getArg(0);
-  auto *LLVMArgVec = LLVMF.getArg(2);
-  auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt8Ty(Ctx), 0);
-  auto *LLVMZero = llvm::ConstantInt::get(Type::getInt8Ty(C), 0);
-  EXPECT_EQ(
-      sandboxir::InsertElementInst::isValidOperands(ArgVec, Arg0, Zero),
-      llvm::InsertElementInst::isValidOperands(LLVMArgVec, LLVMArg0, LLVMZero));
-  EXPECT_EQ(
-      sandboxir::InsertElementInst::isValidOperands(Arg0, ArgVec, Zero),
-      llvm::InsertElementInst::isValidOperands(LLVMArg0, LLVMArgVec, LLVMZero));
-}
-
-TEST_F(SandboxIRTest, ShuffleVectorInst) {
-  parseIR(C, R"IR(
-define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
-  %shuf = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 0, i32 2>
-  %extr = extractelement <2 x i8> <i8 0, i8 1>, i32 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *ArgV1 = F.getArg(0);
-  auto *ArgV2 = F.getArg(1);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *SVI = cast<sandboxir::ShuffleVectorInst>(&*It++);
-  auto *EEI = cast<sandboxir::ExtractElementInst>(&*It++);
-  auto *Ret = &*It++;
-
-  EXPECT_EQ(SVI->getOpcode(), sandboxir::Instruction::Opcode::ShuffleVector);
-  EXPECT_EQ(SVI->getOperand(0), ArgV1);
-  EXPECT_EQ(SVI->getOperand(1), ArgV2);
-
-  // In order to test all the methods we need masks of different lengths, so we
-  // can't simply reuse one of the instructions created above. This helper
-  // creates a new `shufflevector %v1, %2, <mask>` with the given mask indices.
-  auto CreateShuffleWithMask = [&](auto &&...Indices) {
-    SmallVector<int, 4> Mask = {Indices...};
-    return cast<sandboxir::ShuffleVectorInst>(
-        sandboxir::ShuffleVectorInst::create(ArgV1, ArgV2, Mask,
-                                             Ret->getIterator(), Ctx));
-  };
-
-  // create (InsertBefore)
-  auto *NewI1 =
-      cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
-          ArgV1, ArgV2, ArrayRef<int>({0, 2, 1, 3}), Ret->getIterator(), Ctx,
-          "NewShuffleBeforeRet"));
-  EXPECT_EQ(NewI1->getOperand(0), ArgV1);
-  EXPECT_EQ(NewI1->getOperand(1), ArgV2);
-  EXPECT_EQ(NewI1->getNextNode(), Ret);
-#ifndef NDEBUG
-  EXPECT_EQ(NewI1->getName(), "NewShuffleBeforeRet");
-#endif
-
-  // create (InsertAtEnd)
-  auto *NewI2 =
-      cast<sandboxir::ShuffleVectorInst>(sandboxir::ShuffleVectorInst::create(
-          ArgV1, ArgV2, ArrayRef<int>({0, 1}), BB, Ctx, "NewShuffleAtEndOfBB"));
-  EXPECT_EQ(NewI2->getPrevNode(), Ret);
-
-  // Test the path that creates a folded constant. We're currently using an
-  // extractelement instruction with a constant operand in the textual IR above
-  // to obtain a constant vector to work with.
-  // TODO: Refactor this once sandboxir::ConstantVector lands.
-  auto *ShouldBeConstant = sandboxir::ShuffleVectorInst::create(
-      EEI->getOperand(0), EEI->getOperand(0), ArrayRef<int>({0, 3}), BB, Ctx);
-  EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
-
-  // isValidOperands
-  auto *LLVMArgV1 = LLVMF.getArg(0);
-  auto *LLVMArgV2 = LLVMF.getArg(1);
-  SmallVector<int, 2> Mask({1, 2});
-  EXPECT_EQ(
-      sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV2, Mask),
-      llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV2, Mask));
-  EXPECT_EQ(sandboxir::ShuffleVectorInst::isValidOperands(ArgV1, ArgV1, ArgV1),
-            llvm::ShuffleVectorInst::isValidOperands(LLVMArgV1, LLVMArgV1,
-                                                     LLVMArgV1));
-
-  // commute
-  {
-    auto *I = CreateShuffleWithMask(0, 2);
-    I->commute();
-    EXPECT_EQ(I->getOperand(0), ArgV2);
-    EXPECT_EQ(I->getOperand(1), ArgV1);
-    EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 0));
-  }
-
-  // getType
-  EXPECT_EQ(SVI->getType(), ArgV1->getType());
-
-  // getMaskValue
-  EXPECT_EQ(SVI->getMaskValue(0), 0);
-  EXPECT_EQ(SVI->getMaskValue(1), 2);
-
-  // getShuffleMask / getShuffleMaskForBitcode
-  {
-    EXPECT_THAT(SVI->getShuffleMask(), testing::ElementsAre(0, 2));
-
-    SmallVector<int, 2> Result;
-    SVI->getShuffleMask(Result);
-    EXPECT_THAT(Result, testing::ElementsAre(0, 2));
-
-    Result.clear();
-    sandboxir::ShuffleVectorInst::getShuffleMask(
-        SVI->getShuffleMaskForBitcode(), Result);
-    EXPECT_THAT(Result, testing::ElementsAre(0, 2));
-  }
-
-  // convertShuffleMaskForBitcode
-  {
-    auto *C = sandboxir::ShuffleVectorInst::convertShuffleMaskForBitcode(
-        ArrayRef<int>({2, 3}), ArgV1->getType());
-    SmallVector<int, 2> Result;
-    sandboxir::ShuffleVectorInst::getShuffleMask(C, Result);
-    EXPECT_THAT(Result, testing::ElementsAre(2, 3));
-  }
-
-  // setShuffleMask
-  {
-    auto *I = CreateShuffleWithMask(0, 1);
-    I->setShuffleMask(ArrayRef<int>({2, 3}));
-    EXPECT_THAT(I->getShuffleMask(), testing::ElementsAre(2, 3));
-  }
-
-  // The following functions check different mask properties. Note that most
-  // of these come in three different flavors: a method that checks the mask
-  // in the current instructions and two static member functions that check
-  // a mask given as an ArrayRef<int> or Constant*, so there's quite a bit of
-  // repetition in order to check all of them.
-
-  // changesLength / increasesLength
-  {
-    auto *I = CreateShuffleWithMask(1);
-    EXPECT_TRUE(I->changesLength());
-    EXPECT_FALSE(I->increasesLength());
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 1);
-    EXPECT_FALSE(I->changesLength());
-    EXPECT_FALSE(I->increasesLength());
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 1, 1);
-    EXPECT_TRUE(I->changesLength());
-    EXPECT_TRUE(I->increasesLength());
-  }
-
-  // isSingleSource / isSingleSourceMask
-  {
-    auto *I = CreateShuffleWithMask(0, 1);
-    EXPECT_TRUE(I->isSingleSource());
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
-        I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(0, 2);
-    EXPECT_FALSE(I->isSingleSource());
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSingleSourceMask(
-        I->getShuffleMask(), 2));
-  }
-
-  // isIdentity / isIdentityMask
-  {
-    auto *I = CreateShuffleWithMask(0, 1);
-    EXPECT_TRUE(I->isIdentity());
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isIdentityMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_TRUE(
-        sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 0);
-    EXPECT_FALSE(I->isIdentity());
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isIdentityMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_FALSE(
-        sandboxir::ShuffleVectorInst::isIdentityMask(I->getShuffleMask(), 2));
-  }
-
-  // isIdentityWithPadding
-  EXPECT_TRUE(CreateShuffleWithMask(0, 1, -1, -1)->isIdentityWithPadding());
-  EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithPadding());
-
-  // isIdentityWithExtract
-  EXPECT_TRUE(CreateShuffleWithMask(0)->isIdentityWithExtract());
-  EXPECT_FALSE(CreateShuffleWithMask(0, 1)->isIdentityWithExtract());
-  EXPECT_FALSE(CreateShuffleWithMask(0, 1, 2)->isIdentityWithExtract());
-  EXPECT_FALSE(CreateShuffleWithMask(1)->isIdentityWithExtract());
-
-  // isConcat
-  EXPECT_TRUE(CreateShuffleWithMask(0, 1, 2, 3)->isConcat());
-  EXPECT_FALSE(CreateShuffleWithMask(0, 3)->isConcat());
-
-  // isSelect / isSelectMask
-  {
-    auto *I = CreateShuffleWithMask(0, 3);
-    EXPECT_TRUE(I->isSelect());
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSelectMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_TRUE(
-        sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(0, 2);
-    EXPECT_FALSE(I->isSelect());
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSelectMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_FALSE(
-        sandboxir::ShuffleVectorInst::isSelectMask(I->getShuffleMask(), 2));
-  }
-
-  // isReverse / isReverseMask
-  {
-    auto *I = CreateShuffleWithMask(1, 0);
-    EXPECT_TRUE(I->isReverse());
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReverseMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_TRUE(
-        sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 2);
-    EXPECT_FALSE(I->isReverse());
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReverseMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_FALSE(
-        sandboxir::ShuffleVectorInst::isReverseMask(I->getShuffleMask(), 2));
-  }
-
-  // isZeroEltSplat / isZeroEltSplatMask
-  {
-    auto *I = CreateShuffleWithMask(0, 0);
-    EXPECT_TRUE(I->isZeroEltSplat());
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
-        I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 1);
-    EXPECT_FALSE(I->isZeroEltSplat());
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isZeroEltSplatMask(
-        I->getShuffleMask(), 2));
-  }
-
-  // isTranspose / isTransposeMask
-  {
-    auto *I = CreateShuffleWithMask(0, 2);
-    EXPECT_TRUE(I->isTranspose());
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isTransposeMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_TRUE(
-        sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 1);
-    EXPECT_FALSE(I->isTranspose());
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isTransposeMask(
-        I->getShuffleMaskForBitcode(), 2));
-    EXPECT_FALSE(
-        sandboxir::ShuffleVectorInst::isTransposeMask(I->getShuffleMask(), 2));
-  }
-
-  // isSplice / isSpliceMask
-  {
-    auto *I = CreateShuffleWithMask(1, 2);
-    int Index;
-    EXPECT_TRUE(I->isSplice(Index));
-    EXPECT_EQ(Index, 1);
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(
-        I->getShuffleMaskForBitcode(), 2, Index));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(),
-                                                           2, Index));
-  }
-  {
-    auto *I = CreateShuffleWithMask(2, 1);
-    int Index;
-    EXPECT_FALSE(I->isSplice(Index));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(
-        I->getShuffleMaskForBitcode(), 2, Index));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isSpliceMask(I->getShuffleMask(),
-                                                            2, Index));
-  }
-
-  // isExtractSubvectorMask
-  {
-    auto *I = CreateShuffleWithMask(1);
-    int Index;
-    EXPECT_TRUE(I->isExtractSubvectorMask(Index));
-    EXPECT_EQ(Index, 1);
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
-        I->getShuffleMaskForBitcode(), 2, Index));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
-        I->getShuffleMask(), 2, Index));
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 2);
-    int Index;
-    EXPECT_FALSE(I->isExtractSubvectorMask(Index));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
-        I->getShuffleMaskForBitcode(), 2, Index));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isExtractSubvectorMask(
-        I->getShuffleMask(), 2, Index));
-  }
-
-  // isInsertSubvectorMask
-  {
-    auto *I = CreateShuffleWithMask(0, 2);
-    int NumSubElts, Index;
-    EXPECT_TRUE(I->isInsertSubvectorMask(NumSubElts, Index));
-    EXPECT_EQ(Index, 1);
-    EXPECT_EQ(NumSubElts, 1);
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
-        I->getShuffleMaskForBitcode(), 2, NumSubElts, Index));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
-        I->getShuffleMask(), 2, NumSubElts, Index));
-  }
-  {
-    auto *I = CreateShuffleWithMask(0, 1);
-    int NumSubElts, Index;
-    EXPECT_FALSE(I->isInsertSubvectorMask(NumSubElts, Index));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
-        I->getShuffleMaskForBitcode(), 2, NumSubElts, Index));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInsertSubvectorMask(
-        I->getShuffleMask(), 2, NumSubElts, Index));
-  }
-
-  // isReplicationMask
-  {
-    auto *I = CreateShuffleWithMask(0, 0, 0, 1, 1, 1);
-    int ReplicationFactor, VF;
-    EXPECT_TRUE(I->isReplicationMask(ReplicationFactor, VF));
-    EXPECT_EQ(ReplicationFactor, 3);
-    EXPECT_EQ(VF, 2);
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask(
-        I->getShuffleMaskForBitcode(), ReplicationFactor, VF));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isReplicationMask(
-        I->getShuffleMask(), ReplicationFactor, VF));
-  }
-  {
-    auto *I = CreateShuffleWithMask(1, 2);
-    int ReplicationFactor, VF;
-    EXPECT_FALSE(I->isReplicationMask(ReplicationFactor, VF));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask(
-        I->getShuffleMaskForBitcode(), ReplicationFactor, VF));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isReplicationMask(
-        I->getShuffleMask(), ReplicationFactor, VF));
-  }
-
-  // isOneUseSingleSourceMask
-  {
-    auto *I = CreateShuffleWithMask(0, 1, 1, 0);
-    EXPECT_TRUE(I->isOneUseSingleSourceMask(2));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask(
-        I->getShuffleMask(), 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(0, 1, 0, 0);
-    EXPECT_FALSE(I->isOneUseSingleSourceMask(2));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isOneUseSingleSourceMask(
-        I->getShuffleMask(), 2));
-  }
-
-  // commuteShuffleMask
-  {
-    SmallVector<int, 4> M = {0, 2, 1, 3};
-    ShuffleVectorInst::commuteShuffleMask(M, 2);
-    EXPECT_THAT(M, testing::ElementsAre(2, 0, 3, 1));
-  }
-
-  // isInterleave / isInterleaveMask
-  {
-    auto *I = CreateShuffleWithMask(0, 2, 1, 3);
-    EXPECT_TRUE(I->isInterleave(2));
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask(
-        I->getShuffleMask(), 2, 4));
-    SmallVector<unsigned, 4> StartIndexes;
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isInterleaveMask(
-        I->getShuffleMask(), 2, 4, StartIndexes));
-    EXPECT_THAT(StartIndexes, testing::ElementsAre(0, 2));
-  }
-  {
-    auto *I = CreateShuffleWithMask(0, 3, 1, 2);
-    EXPECT_FALSE(I->isInterleave(2));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isInterleaveMask(
-        I->getShuffleMask(), 2, 4));
-  }
-
-  // isDeInterleaveMaskOfFactor
-  {
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
-        ArrayRef<int>({0, 2}), 2));
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
-        ArrayRef<int>({0, 1}), 2));
-
-    unsigned Index;
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isDeInterleaveMaskOfFactor(
-        ArrayRef<int>({1, 3}), 2, Index));
-    EXPECT_EQ(Index, 1u);
-  }
-
-  // isBitRotateMask
-  {
-    unsigned NumSubElts, RotateAmt;
-    EXPECT_TRUE(sandboxir::ShuffleVectorInst::isBitRotateMask(
-        ArrayRef<int>({1, 0, 3, 2, 5, 4, 7, 6}), 8, 2, 2, NumSubElts,
-        RotateAmt));
-    EXPECT_EQ(NumSubElts, 2u);
-    EXPECT_EQ(RotateAmt, 8u);
-
-    EXPECT_FALSE(sandboxir::ShuffleVectorInst::isBitRotateMask(
-        ArrayRef<int>({0, 7, 1, 6, 2, 5, 3, 4}), 8, 2, 2, NumSubElts,
-        RotateAmt));
-  }
-}
-
-TEST_F(SandboxIRTest, ExtractValueInst) {
-  parseIR(C, R"IR(
-define void @foo({i32, float} %agg) {
-  %ext_simple = extractvalue {i32, float} %agg, 0
-  %ext_nested = extractvalue {float, {i32}} undef, 1, 0
-  %const1 = extractvalue {i32, float} {i32 0, float 99.0}, 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  [[maybe_unused]] auto *LLVMExtSimple =
-      cast<llvm::ExtractValueInst>(&*LLVMIt++);
-  auto *LLVMExtNested = cast<llvm::ExtractValueInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *ArgAgg = F.getArg(0);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *ExtSimple = cast<sandboxir::ExtractValueInst>(&*It++);
-  auto *ExtNested = cast<sandboxir::ExtractValueInst>(&*It++);
-  auto *Const1 = cast<sandboxir::ExtractValueInst>(&*It++);
-  auto *Ret = &*It++;
-
-  EXPECT_EQ(ExtSimple->getOperand(0), ArgAgg);
-
-  // create before instruction
-  auto *NewExtBeforeRet =
-      cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
-          ArgAgg, ArrayRef<unsigned>({0}), Ret->getIterator(), Ctx,
-          "NewExtBeforeRet"));
-  EXPECT_EQ(NewExtBeforeRet->getNextNode(), Ret);
-#ifndef NDEBUG
-  EXPECT_EQ(NewExtBeforeRet->getName(), "NewExtBeforeRet");
-#endif // NDEBUG
-
-  // create at end of BB
-  auto *NewExtAtEnd =
-      cast<sandboxir::ExtractValueInst>(sandboxir::ExtractValueInst::create(
-          ArgAgg, ArrayRef<unsigned>({0}), BB->end(), Ctx, "NewExtAtEnd"));
-  EXPECT_EQ(NewExtAtEnd->getPrevNode(), Ret);
-#ifndef NDEBUG
-  EXPECT_EQ(NewExtAtEnd->getName(), "NewExtAtEnd");
-#endif // NDEBUG
-
-  // Test the path that creates a folded constant.
-  auto *ShouldBeConstant = sandboxir::ExtractValueInst::create(
-      Const1->getOperand(0), ArrayRef<unsigned>({0}), BB->end(), Ctx);
-  EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
-
-  auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
-  EXPECT_EQ(ShouldBeConstant, Zero);
-
-  // getIndexedType
-  sandboxir::Type *AggType = ExtNested->getAggregateOperand()->getType();
-  llvm::Type *LLVMAggType = LLVMExtNested->getAggregateOperand()->getType();
-  EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
-                AggType, ArrayRef<unsigned>({1, 0})),
-            Ctx.getType(llvm::ExtractValueInst::getIndexedType(
-                LLVMAggType, ArrayRef<unsigned>({1, 0}))));
-
-  EXPECT_EQ(sandboxir::ExtractValueInst::getIndexedType(
-                AggType, ArrayRef<unsigned>({2})),
-            nullptr);
-
-  // idx_begin / idx_end
-  {
-    SmallVector<int, 2> IndicesSimple(ExtSimple->idx_begin(),
-                                      ExtSimple->idx_end());
-    EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
-
-    SmallVector<int, 2> IndicesNested(ExtNested->idx_begin(),
-                                      ExtNested->idx_end());
-    EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
-  }
-
-  // indices
-  {
-    SmallVector<int, 2> IndicesSimple(ExtSimple->indices());
-    EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
-
-    SmallVector<int, 2> IndicesNested(ExtNested->indices());
-    EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
-  }
-
-  // getAggregateOperand
-  EXPECT_EQ(ExtSimple->getAggregateOperand(), ArgAgg);
-  const auto *ConstExtSimple = ExtSimple;
-  EXPECT_EQ(ConstExtSimple->getAggregateOperand(), ArgAgg);
-
-  // getAggregateOperandIndex
-  EXPECT_EQ(sandboxir::ExtractValueInst::getAggregateOperandIndex(),
-            llvm::ExtractValueInst::getAggregateOperandIndex());
-
-  // getIndices
-  EXPECT_EQ(ExtSimple->getIndices().size(), 1u);
-  EXPECT_EQ(ExtSimple->getIndices()[0], 0u);
-
-  // getNumIndices
-  EXPECT_EQ(ExtSimple->getNumIndices(), 1u);
-
-  // hasIndices
-  EXPECT_EQ(ExtSimple->hasIndices(), true);
-}
-
-TEST_F(SandboxIRTest, InsertValueInst) {
-  parseIR(C, R"IR(
-define void @foo({i32, float} %agg, i32 %i) {
-  %ins_simple = insertvalue {i32, float} %agg, i32 %i, 0
-  %ins_nested = insertvalue {float, {i32}} undef, i32 %i, 1, 0
-  %const1 = insertvalue {i32, float} {i32 99, float 99.0}, i32 %i, 0
-  %const2 = insertvalue {i32, float} {i32 0, float 99.0}, i32 %i, 0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *ArgAgg = F.getArg(0);
-  auto *ArgInt = F.getArg(1);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *InsSimple = cast<sandboxir::InsertValueInst>(&*It++);
-  auto *InsNested = cast<sandboxir::InsertValueInst>(&*It++);
-  // These "const" instructions are helpers to create constant struct operands.
-  // TODO: Remove them once sandboxir::ConstantStruct gets added.
-  auto *Const1 = cast<sandboxir::InsertValueInst>(&*It++);
-  auto *Const2 = cast<sandboxir::InsertValueInst>(&*It++);
-  auto *Ret = &*It++;
-
-  EXPECT_EQ(InsSimple->getOperand(0), ArgAgg);
-  EXPECT_EQ(InsSimple->getOperand(1), ArgInt);
-
-  // create before instruction
-  auto *NewInsBeforeRet =
-      cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
-          ArgAgg, ArgInt, ArrayRef<unsigned>({0}), Ret->getIterator(), Ctx,
-          "NewInsBeforeRet"));
-  EXPECT_EQ(NewInsBeforeRet->getNextNode(), Ret);
-#ifndef NDEBUG
-  EXPECT_EQ(NewInsBeforeRet->getName(), "NewInsBeforeRet");
-#endif // NDEBUG
-
-  // create at end of BB
-  auto *NewInsAtEnd =
-      cast<sandboxir::InsertValueInst>(sandboxir::InsertValueInst::create(
-          ArgAgg, ArgInt, ArrayRef<unsigned>({0}), BB, Ctx, "NewInsAtEnd"));
-  EXPECT_EQ(NewInsAtEnd->getPrevNode(), Ret);
-#ifndef NDEBUG
-  EXPECT_EQ(NewInsAtEnd->getName(), "NewInsAtEnd");
-#endif // NDEBUG
-
-  // Test the path that creates a folded constant.
-  auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
-  auto *ShouldBeConstant = sandboxir::InsertValueInst::create(
-      Const1->getOperand(0), Zero, ArrayRef<unsigned>({0}), BB, Ctx);
-  auto *ExpectedConstant = Const2->getOperand(0);
-  EXPECT_TRUE(isa<sandboxir::Constant>(ShouldBeConstant));
-  EXPECT_EQ(ShouldBeConstant, ExpectedConstant);
-
-  // idx_begin / idx_end
-  {
-    SmallVector<int, 2> IndicesSimple(InsSimple->idx_begin(),
-                                      InsSimple->idx_end());
-    EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
-
-    SmallVector<int, 2> IndicesNested(InsNested->idx_begin(),
-                                      InsNested->idx_end());
-    EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
-  }
-
-  // indices
-  {
-    SmallVector<int, 2> IndicesSimple(InsSimple->indices());
-    EXPECT_THAT(IndicesSimple, testing::ElementsAre(0u));
-
-    SmallVector<int, 2> IndicesNested(InsNested->indices());
-    EXPECT_THAT(IndicesNested, testing::ElementsAre(1u, 0u));
-  }
-
-  // getAggregateOperand
-  EXPECT_EQ(InsSimple->getAggregateOperand(), ArgAgg);
-  const auto *ConstInsSimple = InsSimple;
-  EXPECT_EQ(ConstInsSimple->getAggregateOperand(), ArgAgg);
-
-  // getAggregateOperandIndex
-  EXPECT_EQ(sandboxir::InsertValueInst::getAggregateOperandIndex(),
-            llvm::InsertValueInst::getAggregateOperandIndex());
-
-  // getInsertedValueOperand
-  EXPECT_EQ(InsSimple->getInsertedValueOperand(), ArgInt);
-  EXPECT_EQ(ConstInsSimple->getInsertedValueOperand(), ArgInt);
-
-  // getInsertedValueOperandIndex
-  EXPECT_EQ(sandboxir::InsertValueInst::getInsertedValueOperandIndex(),
-            llvm::InsertValueInst::getInsertedValueOperandIndex());
-
-  // getIndices
-  EXPECT_EQ(InsSimple->getIndices().size(), 1u);
-  EXPECT_EQ(InsSimple->getIndices()[0], 0u);
-
-  // getNumIndices
-  EXPECT_EQ(InsSimple->getNumIndices(), 1u);
-
-  // hasIndices
-  EXPECT_EQ(InsSimple->hasIndices(), true);
-}
-
-TEST_F(SandboxIRTest, BranchInst) {
-  parseIR(C, R"IR(
-define void @foo(i1 %cond0, i1 %cond2) {
- bb0:
-   br i1 %cond0, label %bb1, label %bb2
- bb1:
-   ret void
- bb2:
-   ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Cond0 = F->getArg(0);
-  auto *Cond1 = F->getArg(1);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(*LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(*LLVMF, "bb1")));
-  auto *Ret1 = BB1->getTerminator();
-  auto *BB2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(*LLVMF, "bb2")));
-  auto *Ret2 = BB2->getTerminator();
-  auto It = BB0->begin();
-  auto *Br0 = cast<sandboxir::BranchInst>(&*It++);
-  // Check isUnconditional().
-  EXPECT_FALSE(Br0->isUnconditional());
-  // Check isConditional().
-  EXPECT_TRUE(Br0->isConditional());
-  // Check getCondition().
-  EXPECT_EQ(Br0->getCondition(), Cond0);
-  // Check setCondition().
-  Br0->setCondition(Cond1);
-  EXPECT_EQ(Br0->getCondition(), Cond1);
-  // Check getNumSuccessors().
-  EXPECT_EQ(Br0->getNumSuccessors(), 2u);
-  // Check getSuccessor().
-  EXPECT_EQ(Br0->getSuccessor(0), BB1);
-  EXPECT_EQ(Br0->getSuccessor(1), BB2);
-  // Check swapSuccessors().
-  Br0->swapSuccessors();
-  EXPECT_EQ(Br0->getSuccessor(0), BB2);
-  EXPECT_EQ(Br0->getSuccessor(1), BB1);
-  // Check successors().
-  EXPECT_EQ(range_size(Br0->successors()), 2u);
-  unsigned SuccIdx = 0;
-  SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1, BB2});
-  for (sandboxir::BasicBlock *Succ : Br0->successors())
-    EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-
-  {
-    // Check unconditional BranchInst::create() InsertBefore.
-    auto *Br = sandboxir::BranchInst::create(BB1, Ret1->getIterator(), Ctx);
-    EXPECT_FALSE(Br->isConditional());
-    EXPECT_TRUE(Br->isUnconditional());
-#ifndef NDEBUG
-    EXPECT_DEATH(Br->getCondition(), ".*condition.*");
-#endif // NDEBUG
-    unsigned SuccIdx = 0;
-    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
-    for (sandboxir::BasicBlock *Succ : Br->successors())
-      EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-    EXPECT_EQ(Br->getNextNode(), Ret1);
-  }
-  {
-    // Check unconditional BranchInst::create() InsertAtEnd.
-    auto *Br = sandboxir::BranchInst::create(BB1, /*InsertAtEnd=*/BB1, Ctx);
-    EXPECT_FALSE(Br->isConditional());
-    EXPECT_TRUE(Br->isUnconditional());
-#ifndef NDEBUG
-    EXPECT_DEATH(Br->getCondition(), ".*condition.*");
-#endif // NDEBUG
-    unsigned SuccIdx = 0;
-    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB1});
-    for (sandboxir::BasicBlock *Succ : Br->successors())
-      EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-    EXPECT_EQ(Br->getPrevNode(), Ret1);
-  }
-  {
-    // Check conditional BranchInst::create() InsertBefore.
-    auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
-                                             Ret1->getIterator(), Ctx);
-    EXPECT_TRUE(Br->isConditional());
-    EXPECT_EQ(Br->getCondition(), Cond0);
-    unsigned SuccIdx = 0;
-    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
-    for (sandboxir::BasicBlock *Succ : Br->successors())
-      EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-    EXPECT_EQ(Br->getNextNode(), Ret1);
-  }
-  {
-    // Check conditional BranchInst::create() InsertAtEnd.
-    auto *Br = sandboxir::BranchInst::create(BB1, BB2, Cond0,
-                                             /*InsertAtEnd=*/BB2, Ctx);
-    EXPECT_TRUE(Br->isConditional());
-    EXPECT_EQ(Br->getCondition(), Cond0);
-    unsigned SuccIdx = 0;
-    SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
-    for (sandboxir::BasicBlock *Succ : Br->successors())
-      EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-    EXPECT_EQ(Br->getPrevNode(), Ret2);
-  }
-}
-
-TEST_F(SandboxIRTest, LoadInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %arg0, ptr %arg1) {
-  %ld = load i8, ptr %arg0, align 64
-  %vld = load volatile i8, ptr %arg0, align 64
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Arg0 = F->getArg(0);
-  auto *Arg1 = F->getArg(1);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Ld = cast<sandboxir::LoadInst>(&*It++);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Ld));
-  auto *VLd = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  bool OrigVolatileValue;
-
-  // Check isVolatile()
-  EXPECT_FALSE(Ld->isVolatile());
-  // Check isVolatile()
-  EXPECT_TRUE(VLd->isVolatile());
-  // Check getPointerOperand()
-  EXPECT_EQ(Ld->getPointerOperand(), Arg0);
-  // Check getAlign()
-  EXPECT_EQ(Ld->getAlign(), 64);
-  // Check create(InsertBefore)
-  sandboxir::LoadInst *NewLd = sandboxir::LoadInst::create(
-      Ld->getType(), Arg1, Align(8), Ret->getIterator(), Ctx, "NewLd");
-  EXPECT_FALSE(NewLd->isVolatile());
-  OrigVolatileValue = NewLd->isVolatile();
-  NewLd->setVolatile(true);
-  EXPECT_TRUE(NewLd->isVolatile());
-  NewLd->setVolatile(OrigVolatileValue);
-  EXPECT_FALSE(NewLd->isVolatile());
-  EXPECT_EQ(NewLd->getType(), Ld->getType());
-  EXPECT_EQ(NewLd->getPointerOperand(), Arg1);
-  EXPECT_EQ(NewLd->getAlign(), 8);
-  EXPECT_EQ(NewLd->getName(), "NewLd");
-  // Check create(InsertBefore, IsVolatile=true)
-  sandboxir::LoadInst *NewVLd = sandboxir::LoadInst::create(
-      VLd->getType(), Arg1, Align(8), Ret->getIterator(),
-      /*IsVolatile=*/true, Ctx, "NewVLd");
-
-  EXPECT_TRUE(NewVLd->isVolatile());
-  OrigVolatileValue = NewVLd->isVolatile();
-  NewVLd->setVolatile(false);
-  EXPECT_FALSE(NewVLd->isVolatile());
-  NewVLd->setVolatile(OrigVolatileValue);
-  EXPECT_TRUE(NewVLd->isVolatile());
-  EXPECT_EQ(NewVLd->getName(), "NewVLd");
-  // Check create(InsertAtEnd)
-  sandboxir::LoadInst *NewLdEnd =
-      sandboxir::LoadInst::create(Ld->getType(), Arg1, Align(8),
-                                  /*InsertAtEnd=*/BB, Ctx, "NewLdEnd");
-  EXPECT_FALSE(NewLdEnd->isVolatile());
-  EXPECT_EQ(NewLdEnd->getName(), "NewLdEnd");
-  EXPECT_EQ(NewLdEnd->getType(), Ld->getType());
-  EXPECT_EQ(NewLdEnd->getPointerOperand(), Arg1);
-  EXPECT_EQ(NewLdEnd->getAlign(), 8);
-  EXPECT_EQ(NewLdEnd->getParent(), BB);
-  EXPECT_EQ(NewLdEnd->getNextNode(), nullptr);
-  // Check create(InsertAtEnd, IsVolatile=true)
-  sandboxir::LoadInst *NewVLdEnd =
-      sandboxir::LoadInst::create(VLd->getType(), Arg1, Align(8),
-                                  /*InsertAtEnd=*/BB,
-                                  /*IsVolatile=*/true, Ctx, "NewVLdEnd");
-  EXPECT_TRUE(NewVLdEnd->isVolatile());
-  EXPECT_EQ(NewVLdEnd->getName(), "NewVLdEnd");
-  EXPECT_EQ(NewVLdEnd->getType(), VLd->getType());
-  EXPECT_EQ(NewVLdEnd->getPointerOperand(), Arg1);
-  EXPECT_EQ(NewVLdEnd->getAlign(), 8);
-  EXPECT_EQ(NewVLdEnd->getParent(), BB);
-  EXPECT_EQ(NewVLdEnd->getNextNode(), nullptr);
-}
-
-TEST_F(SandboxIRTest, StoreInst) {
-  parseIR(C, R"IR(
-define void @foo(i8 %val, ptr %ptr) {
-  store i8 %val, ptr %ptr, align 64
-  store volatile i8 %val, ptr %ptr, align 64
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Val = F->getArg(0);
-  auto *Ptr = F->getArg(1);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *St = cast<sandboxir::StoreInst>(&*It++);
-  auto *VSt = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  bool OrigVolatileValue;
-
-  // Check that the StoreInst has been created correctly.
-  EXPECT_FALSE(St->isVolatile());
-  EXPECT_TRUE(VSt->isVolatile());
-  // Check getPointerOperand()
-  EXPECT_EQ(St->getValueOperand(), Val);
-  EXPECT_EQ(St->getPointerOperand(), Ptr);
-  // Check getAlign()
-  EXPECT_EQ(St->getAlign(), 64);
-  // Check create(InsertBefore)
-  sandboxir::StoreInst *NewSt =
-      sandboxir::StoreInst::create(Val, Ptr, Align(8), Ret->getIterator(), Ctx);
-  EXPECT_FALSE(NewSt->isVolatile());
-  OrigVolatileValue = NewSt->isVolatile();
-  NewSt->setVolatile(true);
-  EXPECT_TRUE(NewSt->isVolatile());
-  NewSt->setVolatile(OrigVolatileValue);
-  EXPECT_FALSE(NewSt->isVolatile());
-  EXPECT_EQ(NewSt->getType(), St->getType());
-  EXPECT_EQ(NewSt->getValueOperand(), Val);
-  EXPECT_EQ(NewSt->getPointerOperand(), Ptr);
-  EXPECT_EQ(NewSt->getAlign(), 8);
-  EXPECT_EQ(NewSt->getNextNode(), Ret);
-  // Check create(InsertBefore, IsVolatile=true)
-  sandboxir::StoreInst *NewVSt =
-      sandboxir::StoreInst::create(Val, Ptr, Align(8), Ret->getIterator(),
-                                   /*IsVolatile=*/true, Ctx);
-  EXPECT_TRUE(NewVSt->isVolatile());
-  OrigVolatileValue = NewVSt->isVolatile();
-  NewVSt->setVolatile(false);
-  EXPECT_FALSE(NewVSt->isVolatile());
-  NewVSt->setVolatile(OrigVolatileValue);
-  EXPECT_TRUE(NewVSt->isVolatile());
-  EXPECT_EQ(NewVSt->getType(), VSt->getType());
-  EXPECT_EQ(NewVSt->getValueOperand(), Val);
-  EXPECT_EQ(NewVSt->getPointerOperand(), Ptr);
-  EXPECT_EQ(NewVSt->getAlign(), 8);
-  EXPECT_EQ(NewVSt->getNextNode(), Ret);
-  // Check create(InsertAtEnd)
-  sandboxir::StoreInst *NewStEnd =
-      sandboxir::StoreInst::create(Val, Ptr, Align(8),
-                                   /*InsertAtEnd=*/BB, Ctx);
-  EXPECT_FALSE(NewStEnd->isVolatile());
-  EXPECT_EQ(NewStEnd->getType(), St->getType());
-  EXPECT_EQ(NewStEnd->getValueOperand(), Val);
-  EXPECT_EQ(NewStEnd->getPointerOperand(), Ptr);
-  EXPECT_EQ(NewStEnd->getAlign(), 8);
-  EXPECT_EQ(NewStEnd->getParent(), BB);
-  EXPECT_EQ(NewStEnd->getNextNode(), nullptr);
-  // Check create(InsertAtEnd, IsVolatile=true)
-  sandboxir::StoreInst *NewVStEnd =
-      sandboxir::StoreInst::create(Val, Ptr, Align(8),
-                                   /*InsertAtEnd=*/BB,
-                                   /*IsVolatile=*/true, Ctx);
-  EXPECT_TRUE(NewVStEnd->isVolatile());
-  EXPECT_EQ(NewVStEnd->getType(), VSt->getType());
-  EXPECT_EQ(NewVStEnd->getValueOperand(), Val);
-  EXPECT_EQ(NewVStEnd->getPointerOperand(), Ptr);
-  EXPECT_EQ(NewVStEnd->getAlign(), 8);
-  EXPECT_EQ(NewVStEnd->getParent(), BB);
-  EXPECT_EQ(NewVStEnd->getNextNode(), nullptr);
-}
-
-TEST_F(SandboxIRTest, ReturnInst) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %val) {
-  %add = add i8 %val, 42
-  ret i8 %val
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *Val = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  It++;
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check that the ReturnInst has been created correctly.
-  // Check getReturnValue().
-  EXPECT_EQ(Ret->getReturnValue(), Val);
-
-  // Check create(InsertBefore) a void ReturnInst.
-  auto *NewRet1 = cast<sandboxir::ReturnInst>(
-      sandboxir::ReturnInst::create(nullptr, Ret->getIterator(), Ctx));
-  EXPECT_EQ(NewRet1->getReturnValue(), nullptr);
-  // Check create(InsertBefore) a non-void ReturnInst.
-  auto *NewRet2 = cast<sandboxir::ReturnInst>(
-      sandboxir::ReturnInst::create(Val, Ret->getIterator(), Ctx));
-  EXPECT_EQ(NewRet2->getReturnValue(), Val);
-
-  // Check create(InsertAtEnd) a void ReturnInst.
-  auto *NewRet3 = cast<sandboxir::ReturnInst>(
-      sandboxir::ReturnInst::create(nullptr, /*InsertAtEnd=*/BB, Ctx));
-  EXPECT_EQ(NewRet3->getReturnValue(), nullptr);
-  // Check create(InsertAtEnd) a non-void ReturnInst.
-  auto *NewRet4 = cast<sandboxir::ReturnInst>(
-      sandboxir::ReturnInst::create(Val, /*InsertAtEnd=*/BB, Ctx));
-  EXPECT_EQ(NewRet4->getReturnValue(), Val);
-}
-
-TEST_F(SandboxIRTest, CallBase) {
-  parseIR(C, R"IR(
-declare void @bar1(i8)
-declare void @bar2()
-declare void @bar3()
-declare void @variadic(ptr, ...)
-
-define i8 @foo(i8 %arg0, i32 %arg1, ptr %indirectFoo) {
-  %call = call i8 @foo(i8 %arg0, i32 %arg1)
-  call void @bar1(i8 %arg0)
-  call void @bar2()
-  call void %indirectFoo()
-  call void @bar2() noreturn
-  tail call fastcc void @bar2()
-  call void (ptr, ...) @variadic(ptr %indirectFoo, i32 1)
-  ret i8 %call
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  unsigned ArgIdx = 0;
-  llvm::Argument *LLVMArg0 = LLVMF.getArg(ArgIdx++);
-  llvm::Argument *LLVMArg1 = LLVMF.getArg(ArgIdx++);
-  llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
-  SmallVector<llvm::CallBase *, 8> LLVMCalls;
-  auto LLVMIt = LLVMBB->begin();
-  while (isa<llvm::CallBase>(&*LLVMIt))
-    LLVMCalls.push_back(cast<llvm::CallBase>(&*LLVMIt++));
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function &F = *Ctx.createFunction(&LLVMF);
-
-  for (llvm::CallBase *LLVMCall : LLVMCalls) {
-    // Check classof(Instruction *).
-    auto *Call = cast<sandboxir::CallBase>(Ctx.getValue(LLVMCall));
-    // Check classof(Value *).
-    EXPECT_TRUE(isa<sandboxir::CallBase>((sandboxir::Value *)Call));
-    // Check getFunctionType().
-    EXPECT_EQ(Call->getFunctionType(),
-              Ctx.getType(LLVMCall->getFunctionType()));
-    // Check data_ops().
-    EXPECT_EQ(range_size(Call->data_ops()), range_size(LLVMCall->data_ops()));
-    auto DataOpIt = Call->data_operands_begin();
-    for (llvm::Use &LLVMUse : LLVMCall->data_ops()) {
-      Value *LLVMOp = LLVMUse.get();
-      sandboxir::Use Use = *DataOpIt++;
-      EXPECT_EQ(Ctx.getValue(LLVMOp), Use.get());
-      // Check isDataOperand().
-      EXPECT_EQ(Call->isDataOperand(Use), LLVMCall->isDataOperand(&LLVMUse));
-      // Check getDataOperandNo().
-      EXPECT_EQ(Call->getDataOperandNo(Use),
-                LLVMCall->getDataOperandNo(&LLVMUse));
-      // Check isArgOperand().
-      EXPECT_EQ(Call->isArgOperand(Use), LLVMCall->isArgOperand(&LLVMUse));
-      // Check isCallee().
-      EXPECT_EQ(Call->isCallee(Use), LLVMCall->isCallee(&LLVMUse));
-    }
-    // Check data_operands_empty().
-    EXPECT_EQ(Call->data_operands_empty(), LLVMCall->data_operands_empty());
-    // Check data_operands_size().
-    EXPECT_EQ(Call->data_operands_size(), LLVMCall->data_operands_size());
-    // Check getNumTotalBundleOperands().
-    EXPECT_EQ(Call->getNumTotalBundleOperands(),
-              LLVMCall->getNumTotalBundleOperands());
-    // Check args().
-    EXPECT_EQ(range_size(Call->args()), range_size(LLVMCall->args()));
-    auto ArgIt = Call->arg_begin();
-    for (llvm::Use &LLVMUse : LLVMCall->args()) {
-      Value *LLVMArg = LLVMUse.get();
-      sandboxir::Use Use = *ArgIt++;
-      EXPECT_EQ(Ctx.getValue(LLVMArg), Use.get());
-    }
-    // Check arg_empty().
-    EXPECT_EQ(Call->arg_empty(), LLVMCall->arg_empty());
-    // Check arg_size().
-    EXPECT_EQ(Call->arg_size(), LLVMCall->arg_size());
-    for (unsigned ArgIdx = 0, E = Call->arg_size(); ArgIdx != E; ++ArgIdx) {
-      // Check getArgOperand().
-      EXPECT_EQ(Call->getArgOperand(ArgIdx),
-                Ctx.getValue(LLVMCall->getArgOperand(ArgIdx)));
-      // Check getArgOperandUse().
-      sandboxir::Use Use = Call->getArgOperandUse(ArgIdx);
-      llvm::Use &LLVMUse = LLVMCall->getArgOperandUse(ArgIdx);
-      EXPECT_EQ(Use.get(), Ctx.getValue(LLVMUse.get()));
-      // Check getArgOperandNo().
-      EXPECT_EQ(Call->getArgOperandNo(Use),
-                LLVMCall->getArgOperandNo(&LLVMUse));
-    }
-    // Check hasArgument().
-    SmallVector<llvm::Value *> TestArgs(
-        {LLVMArg0, LLVMArg1, &LLVMF, LLVMBB, LLVMCall});
-    for (llvm::Value *LLVMV : TestArgs) {
-      sandboxir::Value *V = Ctx.getValue(LLVMV);
-      EXPECT_EQ(Call->hasArgument(V), LLVMCall->hasArgument(LLVMV));
-    }
-    // Check getCalledOperand().
-    EXPECT_EQ(Call->getCalledOperand(),
-              Ctx.getValue(LLVMCall->getCalledOperand()));
-    // Check getCalledOperandUse().
-    EXPECT_EQ(Call->getCalledOperandUse().get(),
-              Ctx.getValue(LLVMCall->getCalledOperandUse()));
-    // Check getCalledFunction().
-    if (LLVMCall->getCalledFunction() == nullptr)
-      EXPECT_EQ(Call->getCalledFunction(), nullptr);
-    else {
-      auto *LLVMCF = cast<llvm::Function>(LLVMCall->getCalledFunction());
-      (void)LLVMCF;
-      EXPECT_EQ(Call->getCalledFunction(),
-                cast<sandboxir::Function>(
-                    Ctx.getValue(LLVMCall->getCalledFunction())));
-    }
-    // Check isIndirectCall().
-    EXPECT_EQ(Call->isIndirectCall(), LLVMCall->isIndirectCall());
-    // Check getCaller().
-    EXPECT_EQ(Call->getCaller(), Ctx.getValue(LLVMCall->getCaller()));
-    // Check isMustTailCall().
-    EXPECT_EQ(Call->isMustTailCall(), LLVMCall->isMustTailCall());
-    // Check isTailCall().
-    EXPECT_EQ(Call->isTailCall(), LLVMCall->isTailCall());
-    // Check getIntrinsicID().
-    EXPECT_EQ(Call->getIntrinsicID(), LLVMCall->getIntrinsicID());
-    // Check getCallingConv().
-    EXPECT_EQ(Call->getCallingConv(), LLVMCall->getCallingConv());
-    // Check isInlineAsm().
-    EXPECT_EQ(Call->isInlineAsm(), LLVMCall->isInlineAsm());
-  }
-
-  auto *Arg0 = F.getArg(0);
-  auto *Arg1 = F.getArg(1);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call0 = cast<sandboxir::CallBase>(&*It++);
-  [[maybe_unused]] auto *Call1 = cast<sandboxir::CallBase>(&*It++);
-  auto *Call2 = cast<sandboxir::CallBase>(&*It++);
-  // Check setArgOperand
-  Call0->setArgOperand(0, Arg1);
-  EXPECT_EQ(Call0->getArgOperand(0), Arg1);
-  Call0->setArgOperand(0, Arg0);
-  EXPECT_EQ(Call0->getArgOperand(0), Arg0);
-
-  auto *Bar3F = Ctx.createFunction(M->getFunction("bar3"));
-
-  // Check setCalledOperand
-  auto *SvOp = Call0->getCalledOperand();
-  Call0->setCalledOperand(Bar3F);
-  EXPECT_EQ(Call0->getCalledOperand(), Bar3F);
-  Call0->setCalledOperand(SvOp);
-  // Check setCalledFunction
-  Call2->setCalledFunction(Bar3F);
-  EXPECT_EQ(Call2->getCalledFunction(), Bar3F);
-}
-
-TEST_F(SandboxIRTest, CallInst) {
-  parseIR(C, R"IR(
-define i8 @foo(i8 %arg) {
-  %call = call i8 @foo(i8 %arg)
-  ret i8 %call
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  unsigned ArgIdx = 0;
-  auto *Arg0 = F.getArg(ArgIdx++);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call = cast<sandboxir::CallInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  EXPECT_EQ(Call->getNumOperands(), 2u);
-  EXPECT_EQ(Ret->getOpcode(), sandboxir::Instruction::Opcode::Ret);
-  sandboxir::FunctionType *FTy = F.getFunctionType();
-  SmallVector<sandboxir::Value *, 1> Args;
-  Args.push_back(Arg0);
-  {
-    // Check create() WhereIt.
-    auto *Call = cast<sandboxir::CallInst>(sandboxir::CallInst::create(
-        FTy, &F, Args, /*WhereIt=*/Ret->getIterator(), Ctx));
-    EXPECT_EQ(Call->getNextNode(), Ret);
-    EXPECT_EQ(Call->getCalledFunction(), &F);
-    EXPECT_EQ(range_size(Call->args()), 1u);
-    EXPECT_EQ(Call->getArgOperand(0), Arg0);
-  }
-  {
-    // Check create() InsertBefore.
-    auto *Call = cast<sandboxir::CallInst>(
-        sandboxir::CallInst::create(FTy, &F, Args, Ret->getIterator(), Ctx));
-    EXPECT_EQ(Call->getNextNode(), Ret);
-    EXPECT_EQ(Call->getCalledFunction(), &F);
-    EXPECT_EQ(range_size(Call->args()), 1u);
-    EXPECT_EQ(Call->getArgOperand(0), Arg0);
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *Call = cast<sandboxir::CallInst>(
-        sandboxir::CallInst::create(FTy, &F, Args, /*InsertAtEnd=*/BB, Ctx));
-    EXPECT_EQ(Call->getPrevNode(), Ret);
-    EXPECT_EQ(Call->getCalledFunction(), &F);
-    EXPECT_EQ(range_size(Call->args()), 1u);
-    EXPECT_EQ(Call->getArgOperand(0), Arg0);
-  }
-}
-
-TEST_F(SandboxIRTest, InvokeInst) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg) {
- bb0:
-   invoke i8 @foo(i8 %arg) to label %normal_bb
-                       unwind label %exception_bb
- normal_bb:
-   ret void
- exception_bb:
-   %lpad = landingpad { ptr, i32}
-           cleanup
-   ret void
- other_bb:
-   ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Arg = F.getArg(0);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *NormalBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "normal_bb")));
-  auto *ExceptionBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "exception_bb")));
-  auto *LandingPad = &*ExceptionBB->begin();
-  auto *OtherBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
-  auto It = BB0->begin();
-  // Check classof(Instruction *).
-  auto *Invoke = cast<sandboxir::InvokeInst>(&*It++);
-
-  // Check getNormalDest().
-  EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
-  // Check getUnwindDest().
-  EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
-  // Check getSuccessor().
-  EXPECT_EQ(Invoke->getSuccessor(0), NormalBB);
-  EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB);
-  // Check setNormalDest().
-  Invoke->setNormalDest(OtherBB);
-  EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
-  EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
-  // Check setUnwindDest().
-  Invoke->setUnwindDest(OtherBB);
-  EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
-  EXPECT_EQ(Invoke->getUnwindDest(), OtherBB);
-  // Check setSuccessor().
-  Invoke->setSuccessor(0, NormalBB);
-  EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
-  Invoke->setSuccessor(1, ExceptionBB);
-  EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
-  // Check getLandingPadInst().
-  EXPECT_EQ(Invoke->getLandingPadInst(), LandingPad);
-
-  {
-    // Check create() WhereIt, WhereBB.
-    SmallVector<sandboxir::Value *> Args({Arg});
-    auto *InsertBefore = &*BB0->begin();
-    auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
-        F.getFunctionType(), &F, NormalBB, ExceptionBB, Args,
-        InsertBefore->getIterator(), Ctx));
-    EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
-    EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
-    EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore);
-  }
-  {
-    // Check create() InsertBefore.
-    SmallVector<sandboxir::Value *> Args({Arg});
-    auto *InsertBefore = &*BB0->begin();
-    auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
-        F.getFunctionType(), &F, NormalBB, ExceptionBB, Args,
-        InsertBefore->getIterator(), Ctx));
-    EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
-    EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
-    EXPECT_EQ(NewInvoke->getNextNode(), InsertBefore);
-  }
-  {
-    // Check create() InsertAtEnd.
-    SmallVector<sandboxir::Value *> Args({Arg});
-    auto *NewInvoke = cast<sandboxir::InvokeInst>(sandboxir::InvokeInst::create(
-        F.getFunctionType(), &F, NormalBB, ExceptionBB, Args, BB0, Ctx));
-    EXPECT_EQ(NewInvoke->getNormalDest(), NormalBB);
-    EXPECT_EQ(NewInvoke->getUnwindDest(), ExceptionBB);
-    EXPECT_EQ(NewInvoke->getParent(), BB0);
-    EXPECT_EQ(NewInvoke->getNextNode(), nullptr);
-  }
-}
-
-TEST_F(SandboxIRTest, CallBrInst) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg) {
- bb0:
-   callbr void asm "", ""()
-               to label %bb1 [label %bb2]
- bb1:
-   ret void
- bb2:
-   ret void
- other_bb:
-   ret void
- bb3:
-   callbr void @foo(i8 %arg)
-               to label %bb1 [label %bb2]
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0");
-  auto *LLVMCallBr = cast<llvm::CallBrInst>(&*LLVMBB0->begin());
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Arg = F.getArg(0);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *BB2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
-  auto *BB3 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb3")));
-  auto *OtherBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
-  auto It = BB0->begin();
-  // Check classof(Instruction *).
-  auto *CallBr0 = cast<sandboxir::CallBrInst>(&*It++);
-
-  It = BB3->begin();
-  auto *CallBr1 = cast<sandboxir::CallBrInst>(&*It++);
-  for (sandboxir::CallBrInst *CallBr : {CallBr0, CallBr1}) {
-    // Check getNumIndirectDests().
-    EXPECT_EQ(CallBr->getNumIndirectDests(), 1u);
-    // Check getIndirectDestLabel().
-    EXPECT_EQ(CallBr->getIndirectDestLabel(0),
-              Ctx.getValue(LLVMCallBr->getIndirectDestLabel(0)));
-    // Check getIndirectDestLabelUse().
-    EXPECT_EQ(CallBr->getIndirectDestLabelUse(0),
-              Ctx.getValue(LLVMCallBr->getIndirectDestLabelUse(0)));
-    // Check getDefaultDest().
-    EXPECT_EQ(CallBr->getDefaultDest(),
-              Ctx.getValue(LLVMCallBr->getDefaultDest()));
-    // Check getIndirectDest().
-    EXPECT_EQ(CallBr->getIndirectDest(0),
-              Ctx.getValue(LLVMCallBr->getIndirectDest(0)));
-    // Check getIndirectDests().
-    auto Dests = CallBr->getIndirectDests();
-    EXPECT_EQ(Dests.size(), LLVMCallBr->getIndirectDests().size());
-    EXPECT_EQ(Dests[0], Ctx.getValue(LLVMCallBr->getIndirectDests()[0]));
-    // Check getNumSuccessors().
-    EXPECT_EQ(CallBr->getNumSuccessors(), LLVMCallBr->getNumSuccessors());
-    // Check getSuccessor().
-    for (unsigned SuccIdx = 0, E = CallBr->getNumSuccessors(); SuccIdx != E;
-         ++SuccIdx)
-      EXPECT_EQ(CallBr->getSuccessor(SuccIdx),
-                Ctx.getValue(LLVMCallBr->getSuccessor(SuccIdx)));
-    // Check setDefaultDest().
-    auto *SvDefaultDest = CallBr->getDefaultDest();
-    CallBr->setDefaultDest(OtherBB);
-    EXPECT_EQ(CallBr->getDefaultDest(), OtherBB);
-    CallBr->setDefaultDest(SvDefaultDest);
-    // Check setIndirectDest().
-    auto *SvIndirectDest = CallBr->getIndirectDest(0);
-    CallBr->setIndirectDest(0, OtherBB);
-    EXPECT_EQ(CallBr->getIndirectDest(0), OtherBB);
-    CallBr->setIndirectDest(0, SvIndirectDest);
-  }
-
-  {
-    // Check create() WhereIt, WhereBB.
-    SmallVector<sandboxir::Value *> Args({Arg});
-    auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create(
-        F.getFunctionType(), &F, BB1, {BB2}, Args, BB0->end(), Ctx));
-    EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
-    EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
-    EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
-    EXPECT_EQ(NewCallBr->getNextNode(), nullptr);
-    EXPECT_EQ(NewCallBr->getParent(), BB0);
-  }
-  {
-    // Check create() InsertBefore
-    SmallVector<sandboxir::Value *> Args({Arg});
-    auto *InsertBefore = &*BB0->rbegin();
-    auto *NewCallBr = cast<sandboxir::CallBrInst>(
-        sandboxir::CallBrInst::create(F.getFunctionType(), &F, BB1, {BB2}, Args,
-                                      InsertBefore->getIterator(), Ctx));
-    EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
-    EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
-    EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
-    EXPECT_EQ(NewCallBr->getNextNode(), InsertBefore);
-  }
-  {
-    // Check create() InsertAtEnd.
-    SmallVector<sandboxir::Value *> Args({Arg});
-    auto *NewCallBr = cast<sandboxir::CallBrInst>(sandboxir::CallBrInst::create(
-        F.getFunctionType(), &F, BB1, {BB2}, Args, BB0, Ctx));
-    EXPECT_EQ(NewCallBr->getDefaultDest(), BB1);
-    EXPECT_EQ(NewCallBr->getIndirectDests().size(), 1u);
-    EXPECT_EQ(NewCallBr->getIndirectDests()[0], BB2);
-    EXPECT_EQ(NewCallBr->getNextNode(), nullptr);
-    EXPECT_EQ(NewCallBr->getParent(), BB0);
-  }
-}
-
-TEST_F(SandboxIRTest, LandingPadInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-entry:
-  invoke void @foo()
-      to label %bb unwind label %unwind
-unwind:
-  %lpad = landingpad { ptr, i32 }
-            catch ptr null
-  ret void
-bb:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMUnwind = getBasicBlockByName(LLVMF, "unwind");
-  auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMUnwind->begin());
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Unwind = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwind));
-  auto *BB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb")));
-  auto It = Unwind->begin();
-  auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check isCleanup().
-  EXPECT_EQ(LPad->isCleanup(), LLVMLPad->isCleanup());
-  // Check setCleanup().
-  auto OrigIsCleanup = LPad->isCleanup();
-  auto NewIsCleanup = true;
-  EXPECT_NE(NewIsCleanup, OrigIsCleanup);
-  LPad->setCleanup(NewIsCleanup);
-  EXPECT_EQ(LPad->isCleanup(), NewIsCleanup);
-  LPad->setCleanup(OrigIsCleanup);
-  EXPECT_EQ(LPad->isCleanup(), OrigIsCleanup);
-  // Check getNumClauses().
-  EXPECT_EQ(LPad->getNumClauses(), LLVMLPad->getNumClauses());
-  // Check getClause().
-  for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
-    EXPECT_EQ(LPad->getClause(Idx), Ctx.getValue(LLVMLPad->getClause(Idx)));
-  // Check isCatch().
-  for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
-    EXPECT_EQ(LPad->isCatch(Idx), LLVMLPad->isCatch(Idx));
-  // Check isFilter().
-  for (auto Idx : seq<unsigned>(0, LPad->getNumClauses()))
-    EXPECT_EQ(LPad->isFilter(Idx), LLVMLPad->isFilter(Idx));
-  // Check create().
-  auto *BBRet = &*BB->begin();
-  auto *NewLPad = cast<sandboxir::LandingPadInst>(
-      sandboxir::LandingPadInst::create(sandboxir::Type::getInt8Ty(Ctx), 0,
-                                        BBRet->getIterator(), Ctx, "NewLPad"));
-  EXPECT_EQ(NewLPad->getNextNode(), BBRet);
-  EXPECT_FALSE(NewLPad->isCleanup());
-#ifndef NDEBUG
-  EXPECT_EQ(NewLPad->getName(), "NewLPad");
-#endif // NDEBUG
-}
-
-TEST_F(SandboxIRTest, FuncletPadInst_CatchPadInst_CleanupPadInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-dispatch:
-  %cs = catchswitch within none [label %handler0] unwind to caller
-handler0:
-  %catchpad = catchpad within %cs [ptr @foo]
-  ret void
-handler1:
-  %cleanuppad = cleanuppad within %cs [ptr @foo]
-  ret void
-bb:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMDispatch = getBasicBlockByName(LLVMF, "dispatch");
-  BasicBlock *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0");
-  BasicBlock *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1");
-  auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMHandler0->begin());
-  auto *LLVMCLP = cast<llvm::CleanupPadInst>(&*LLVMHandler1->begin());
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Dispatch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMDispatch));
-  auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0));
-  auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1));
-  auto *BB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb")));
-  auto *BBRet = cast<sandboxir::ReturnInst>(&*BB->begin());
-  auto *CS = cast<sandboxir::CatchSwitchInst>(&*Dispatch->begin());
-  [[maybe_unused]] auto *CP =
-      cast<sandboxir::CatchPadInst>(&*Handler0->begin());
-  [[maybe_unused]] auto *CLP =
-      cast<sandboxir::CleanupPadInst>(&*Handler1->begin());
-
-  // Check getCatchSwitch().
-  EXPECT_EQ(CP->getCatchSwitch(), CS);
-  EXPECT_EQ(CP->getCatchSwitch(), Ctx.getValue(LLVMCP->getCatchSwitch()));
-
-  for (llvm::FuncletPadInst *LLVMFPI :
-       {static_cast<llvm::FuncletPadInst *>(LLVMCP),
-        static_cast<llvm::FuncletPadInst *>(LLVMCLP)}) {
-    auto *FPI = cast<sandboxir::FuncletPadInst>(Ctx.getValue(LLVMFPI));
-    // Check arg_size().
-    EXPECT_EQ(FPI->arg_size(), LLVMFPI->arg_size());
-    // Check getParentPad().
-    EXPECT_EQ(FPI->getParentPad(), Ctx.getValue(LLVMFPI->getParentPad()));
-    // Check setParentPad().
-    auto *OrigParentPad = FPI->getParentPad();
-    auto *NewParentPad = Dispatch;
-    EXPECT_NE(NewParentPad, OrigParentPad);
-    FPI->setParentPad(NewParentPad);
-    EXPECT_EQ(FPI->getParentPad(), NewParentPad);
-    FPI->setParentPad(OrigParentPad);
-    EXPECT_EQ(FPI->getParentPad(), OrigParentPad);
-    // Check getArgOperand().
-    for (auto Idx : seq<unsigned>(0, FPI->arg_size()))
-      EXPECT_EQ(FPI->getArgOperand(Idx),
-                Ctx.getValue(LLVMFPI->getArgOperand(Idx)));
-    // Check setArgOperand().
-    auto *OrigArgOperand = FPI->getArgOperand(0);
-    auto *NewArgOperand = Dispatch;
-    EXPECT_NE(NewArgOperand, OrigArgOperand);
-    FPI->setArgOperand(0, NewArgOperand);
-    EXPECT_EQ(FPI->getArgOperand(0), NewArgOperand);
-    FPI->setArgOperand(0, OrigArgOperand);
-    EXPECT_EQ(FPI->getArgOperand(0), OrigArgOperand);
-  }
-  // Check CatchPadInst::create().
-  auto *NewCPI = cast<sandboxir::CatchPadInst>(sandboxir::CatchPadInst::create(
-      CS, {}, BBRet->getIterator(), Ctx, "NewCPI"));
-  EXPECT_EQ(NewCPI->getCatchSwitch(), CS);
-  EXPECT_EQ(NewCPI->arg_size(), 0u);
-  EXPECT_EQ(NewCPI->getNextNode(), BBRet);
-#ifndef NDEBUG
-  EXPECT_EQ(NewCPI->getName(), "NewCPI");
-#endif // NDEBUG
-  // Check CleanupPadInst::create().
-  auto *NewCLPI =
-      cast<sandboxir::CleanupPadInst>(sandboxir::CleanupPadInst::create(
-          CS, {}, BBRet->getIterator(), Ctx, "NewCLPI"));
-  EXPECT_EQ(NewCLPI->getParentPad(), CS);
-  EXPECT_EQ(NewCLPI->arg_size(), 0u);
-  EXPECT_EQ(NewCLPI->getNextNode(), BBRet);
-#ifndef NDEBUG
-  EXPECT_EQ(NewCLPI->getName(), "NewCLPI");
-#endif // NDEBUG
-}
-
-TEST_F(SandboxIRTest, CatchReturnInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-dispatch:
-  %cs = catchswitch within none [label %catch] unwind to caller
-catch:
-  %catchpad = catchpad within %cs [ptr @foo]
-  catchret from %catchpad to label %continue
-continue:
-  ret void
-catch2:
-  %catchpad2 = catchpad within %cs [ptr @foo]
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch");
-  auto LLVMIt = LLVMCatch->begin();
-  [[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++);
-  auto *LLVMCR = cast<llvm::CatchReturnInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch));
-  auto *Catch2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "catch2")));
-  auto It = Catch->begin();
-  [[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++);
-  auto *CR = cast<sandboxir::CatchReturnInst>(&*It++);
-  auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin());
-
-  // Check getCatchPad().
-  EXPECT_EQ(CR->getCatchPad(), Ctx.getValue(LLVMCR->getCatchPad()));
-  // Check setCatchPad().
-  auto *OrigCP = CR->getCatchPad();
-  auto *NewCP = CP2;
-  EXPECT_NE(NewCP, OrigCP);
-  CR->setCatchPad(NewCP);
-  EXPECT_EQ(CR->getCatchPad(), NewCP);
-  CR->setCatchPad(OrigCP);
-  EXPECT_EQ(CR->getCatchPad(), OrigCP);
-  // Check getSuccessor().
-  EXPECT_EQ(CR->getSuccessor(), Ctx.getValue(LLVMCR->getSuccessor()));
-  // Check setSuccessor().
-  auto *OrigSucc = CR->getSuccessor();
-  auto *NewSucc = Catch;
-  EXPECT_NE(NewSucc, OrigSucc);
-  CR->setSuccessor(NewSucc);
-  EXPECT_EQ(CR->getSuccessor(), NewSucc);
-  CR->setSuccessor(OrigSucc);
-  EXPECT_EQ(CR->getSuccessor(), OrigSucc);
-  // Check getNumSuccessors().
-  EXPECT_EQ(CR->getNumSuccessors(), LLVMCR->getNumSuccessors());
-  // Check getCatchSwitchParentPad().
-  EXPECT_EQ(CR->getCatchSwitchParentPad(),
-            Ctx.getValue(LLVMCR->getCatchSwitchParentPad()));
-  // Check create().
-  auto *CRI = cast<sandboxir::CatchReturnInst>(
-      sandboxir::CatchReturnInst::create(CP, Catch, CP->getIterator(), Ctx));
-  EXPECT_EQ(CRI->getNextNode(), CP);
-  EXPECT_EQ(CRI->getCatchPad(), CP);
-  EXPECT_EQ(CRI->getSuccessor(), Catch);
-}
-
-TEST_F(SandboxIRTest, CleanupReturnInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-dispatch:
-  invoke void @foo()
-              to label %throw unwind label %cleanup
-throw:
-  ret void
-cleanup:
-  %cleanuppad = cleanuppad within none []
-  cleanupret from %cleanuppad unwind label %cleanup2
-cleanup2:
-  %cleanuppad2 = cleanuppad within none []
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
-  auto LLVMIt = LLVMCleanup->begin();
-  [[maybe_unused]] auto *LLVMCP = cast<llvm::CleanupPadInst>(&*LLVMIt++);
-  auto *LLVMCRI = cast<llvm::CleanupReturnInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Throw = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
-  auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
-  auto *Cleanup2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
-  auto It = Cleanup->begin();
-  [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
-  auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
-  It = Cleanup2->begin();
-  auto *CP2 = cast<sandboxir::CleanupPadInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check hasUnwindDest().
-  EXPECT_EQ(CRI->hasUnwindDest(), LLVMCRI->hasUnwindDest());
-  // Check unwindsToCaller().
-  EXPECT_EQ(CRI->unwindsToCaller(), LLVMCRI->unwindsToCaller());
-  // Check getCleanupPad().
-  EXPECT_EQ(CRI->getCleanupPad(), Ctx.getValue(LLVMCRI->getCleanupPad()));
-  // Check setCleanupPad().
-  auto *OrigCleanupPad = CRI->getCleanupPad();
-  auto *NewCleanupPad = CP2;
-  EXPECT_NE(NewCleanupPad, OrigCleanupPad);
-  CRI->setCleanupPad(NewCleanupPad);
-  EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
-  CRI->setCleanupPad(OrigCleanupPad);
-  EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
-  // Check setNumSuccessors().
-  EXPECT_EQ(CRI->getNumSuccessors(), LLVMCRI->getNumSuccessors());
-  // Check getUnwindDest().
-  EXPECT_EQ(CRI->getUnwindDest(), Ctx.getValue(LLVMCRI->getUnwindDest()));
-  // Check setUnwindDest().
-  auto *OrigUnwindDest = CRI->getUnwindDest();
-  auto *NewUnwindDest = Throw;
-  EXPECT_NE(NewUnwindDest, OrigUnwindDest);
-  CRI->setUnwindDest(NewUnwindDest);
-  EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
-  CRI->setUnwindDest(OrigUnwindDest);
-  EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
-  // Check create().
-  auto *UnwindBB = Cleanup;
-  auto *NewCRI = sandboxir::CleanupReturnInst::create(CP2, UnwindBB,
-                                                      Ret->getIterator(), Ctx);
-  EXPECT_EQ(NewCRI->getCleanupPad(), CP2);
-  EXPECT_EQ(NewCRI->getUnwindDest(), UnwindBB);
-  EXPECT_EQ(NewCRI->getNextNode(), Ret);
-}
-
-TEST_F(SandboxIRTest, GetElementPtrInstruction) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, <2 x ptr> %ptrs) {
-  %gep0 = getelementptr i8, ptr %ptr, i32 0
-  %gep1 = getelementptr nusw i8, ptr %ptr, i32 0
-  %gep2 = getelementptr nuw i8, ptr %ptr, i32 0
-  %gep3 = getelementptr inbounds {i32, {i32, i8}}, ptr %ptr, i32 1, i32 0
-  %gep4 = getelementptr inbounds {i8, i8, {i32, i16}}, <2 x ptr> %ptrs, i32 2, <2 x i32> <i32 0, i32 0>
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  SmallVector<llvm::GetElementPtrInst *, 4> LLVMGEPs;
-  while (isa<llvm::GetElementPtrInst>(&*LLVMIt))
-    LLVMGEPs.push_back(cast<llvm::GetElementPtrInst>(&*LLVMIt++));
-  auto *LLVMRet = cast<llvm::ReturnInst>(&*LLVMIt++);
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-
-  for (llvm::GetElementPtrInst *LLVMGEP : LLVMGEPs) {
-    // Check classof().
-    auto *GEP = cast<sandboxir::GetElementPtrInst>(Ctx.getValue(LLVMGEP));
-    // Check getSourceElementType().
-    EXPECT_EQ(GEP->getSourceElementType(),
-              Ctx.getType(LLVMGEP->getSourceElementType()));
-    // Check getResultElementType().
-    EXPECT_EQ(GEP->getResultElementType(),
-              Ctx.getType(LLVMGEP->getResultElementType()));
-    // Check getAddressSpace().
-    EXPECT_EQ(GEP->getAddressSpace(), LLVMGEP->getAddressSpace());
-    // Check indices().
-    EXPECT_EQ(range_size(GEP->indices()), range_size(LLVMGEP->indices()));
-    auto IdxIt = GEP->idx_begin();
-    for (llvm::Value *LLVMIdxV : LLVMGEP->indices()) {
-      sandboxir::Value *IdxV = *IdxIt++;
-      EXPECT_EQ(IdxV, Ctx.getValue(LLVMIdxV));
-    }
-    // Check getPointerOperand().
-    EXPECT_EQ(GEP->getPointerOperand(),
-              Ctx.getValue(LLVMGEP->getPointerOperand()));
-    // Check getPointerOperandIndex().
-    EXPECT_EQ(GEP->getPointerOperandIndex(), LLVMGEP->getPointerOperandIndex());
-    // Check getPointerOperandType().
-    EXPECT_EQ(GEP->getPointerOperandType(),
-              Ctx.getType(LLVMGEP->getPointerOperandType()));
-    // Check getPointerAddressSpace().
-    EXPECT_EQ(GEP->getPointerAddressSpace(), LLVMGEP->getPointerAddressSpace());
-    // Check getNumIndices().
-    EXPECT_EQ(GEP->getNumIndices(), LLVMGEP->getNumIndices());
-    // Check hasIndices().
-    EXPECT_EQ(GEP->hasIndices(), LLVMGEP->hasIndices());
-    // Check hasAllConstantIndices().
-    EXPECT_EQ(GEP->hasAllConstantIndices(), LLVMGEP->hasAllConstantIndices());
-    // Check getNoWrapFlags().
-    EXPECT_EQ(GEP->getNoWrapFlags(), LLVMGEP->getNoWrapFlags());
-    // Check isInBounds().
-    EXPECT_EQ(GEP->isInBounds(), LLVMGEP->isInBounds());
-    // Check hasNoUnsignedWrap().
-    EXPECT_EQ(GEP->hasNoUnsignedWrap(), LLVMGEP->hasNoUnsignedWrap());
-    // Check accumulateConstantOffset().
-    const DataLayout &DL = M->getDataLayout();
-    APInt Offset1 =
-        APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace()));
-    APInt Offset2 =
-        APInt::getZero(DL.getIndexSizeInBits(GEP->getPointerAddressSpace()));
-    EXPECT_EQ(GEP->accumulateConstantOffset(DL, Offset1),
-              LLVMGEP->accumulateConstantOffset(DL, Offset2));
-    EXPECT_EQ(Offset1, Offset2);
-  }
-
-  auto *BB = &*F.begin();
-  auto *GEP0 = cast<sandboxir::GetElementPtrInst>(&*BB->begin());
-  auto *Ret = cast<sandboxir::ReturnInst>(Ctx.getValue(LLVMRet));
-  SmallVector<sandboxir::Value *> Indices(GEP0->indices());
-
-  // Check create() WhereIt, WhereBB.
-  auto *NewGEP0 =
-      cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
-          GEP0->getType(), GEP0->getPointerOperand(), Indices,
-          Ret->getIterator(), Ctx, "NewGEP0"));
-  EXPECT_EQ(NewGEP0->getName(), "NewGEP0");
-  EXPECT_EQ(NewGEP0->getType(), GEP0->getType());
-  EXPECT_EQ(NewGEP0->getPointerOperand(), GEP0->getPointerOperand());
-  EXPECT_EQ(range_size(NewGEP0->indices()), range_size(GEP0->indices()));
-  for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
-            OldIt = GEP0->idx_begin();
-       NewIt != NewItE; ++NewIt) {
-    sandboxir::Value *NewIdxV = *NewIt;
-    sandboxir::Value *OldIdxV = *OldIt;
-    EXPECT_EQ(NewIdxV, OldIdxV);
-  }
-  EXPECT_EQ(NewGEP0->getNextNode(), Ret);
-
-  // Check create() InsertBefore.
-  auto *NewGEP1 =
-      cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
-          GEP0->getType(), GEP0->getPointerOperand(), Indices,
-          Ret->getIterator(), Ctx, "NewGEP1"));
-  EXPECT_EQ(NewGEP1->getName(), "NewGEP1");
-  EXPECT_EQ(NewGEP1->getType(), GEP0->getType());
-  EXPECT_EQ(NewGEP1->getPointerOperand(), GEP0->getPointerOperand());
-  EXPECT_EQ(range_size(NewGEP1->indices()), range_size(GEP0->indices()));
-  for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
-            OldIt = GEP0->idx_begin();
-       NewIt != NewItE; ++NewIt) {
-    sandboxir::Value *NewIdxV = *NewIt;
-    sandboxir::Value *OldIdxV = *OldIt;
-    EXPECT_EQ(NewIdxV, OldIdxV);
-  }
-  EXPECT_EQ(NewGEP1->getNextNode(), Ret);
-
-  // Check create() InsertAtEnd.
-  auto *NewGEP2 =
-      cast<sandboxir::GetElementPtrInst>(sandboxir::GetElementPtrInst::create(
-          GEP0->getType(), GEP0->getPointerOperand(), Indices, BB, Ctx,
-          "NewGEP2"));
-  EXPECT_EQ(NewGEP2->getName(), "NewGEP2");
-  EXPECT_EQ(NewGEP2->getType(), GEP0->getType());
-  EXPECT_EQ(NewGEP2->getPointerOperand(), GEP0->getPointerOperand());
-  EXPECT_EQ(range_size(NewGEP2->indices()), range_size(GEP0->indices()));
-  for (auto NewIt = NewGEP0->idx_begin(), NewItE = NewGEP0->idx_end(),
-            OldIt = GEP0->idx_begin();
-       NewIt != NewItE; ++NewIt) {
-    sandboxir::Value *NewIdxV = *NewIt;
-    sandboxir::Value *OldIdxV = *OldIt;
-    EXPECT_EQ(NewIdxV, OldIdxV);
-  }
-  EXPECT_EQ(NewGEP2->getPrevNode(), Ret);
-  EXPECT_EQ(NewGEP2->getNextNode(), nullptr);
-}
-
-TEST_F(SandboxIRTest, Flags) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg, float %farg) {
-  %add = add i32 %arg, %arg
-  %fadd = fadd float %farg, %farg
-  %udiv = udiv i32 %arg, %arg
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMAdd = &*LLVMIt++;
-  auto *LLVMFAdd = &*LLVMIt++;
-  auto *LLVMUDiv = &*LLVMIt++;
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Add = &*It++;
-  auto *FAdd = &*It++;
-  auto *UDiv = &*It++;
-
-#define CHECK_FLAG(I, LLVMI, GETTER, SETTER)                                   \
-  {                                                                            \
-    EXPECT_EQ(I->GETTER(), LLVMI->GETTER());                                   \
-    bool NewFlagVal = !I->GETTER();                                            \
-    I->SETTER(NewFlagVal);                                                     \
-    EXPECT_EQ(I->GETTER(), NewFlagVal);                                        \
-    EXPECT_EQ(I->GETTER(), LLVMI->GETTER());                                   \
-  }
-
-  CHECK_FLAG(Add, LLVMAdd, hasNoUnsignedWrap, setHasNoUnsignedWrap);
-  CHECK_FLAG(Add, LLVMAdd, hasNoSignedWrap, setHasNoSignedWrap);
-  CHECK_FLAG(FAdd, LLVMFAdd, isFast, setFast);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReassoc, setHasAllowReassoc);
-  CHECK_FLAG(UDiv, LLVMUDiv, isExact, setIsExact);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasNoNaNs, setHasNoNaNs);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasNoInfs, setHasNoInfs);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasNoSignedZeros, setHasNoSignedZeros);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasAllowReciprocal, setHasAllowReciprocal);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasAllowContract, setHasAllowContract);
-  CHECK_FLAG(FAdd, LLVMFAdd, hasApproxFunc, setHasApproxFunc);
-
-  // Check getFastMathFlags(), copyFastMathFlags().
-  FAdd->setFastMathFlags(FastMathFlags::getFast());
-  EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags());
-  FastMathFlags OrigFMF = FAdd->getFastMathFlags();
-  FastMathFlags NewFMF;
-  NewFMF.setAllowReassoc(true);
-  EXPECT_TRUE(NewFMF != OrigFMF);
-  FAdd->setFastMathFlags(NewFMF);
-  EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF);
-  FAdd->copyFastMathFlags(NewFMF);
-  EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF);
-  EXPECT_FALSE(FAdd->getFastMathFlags() != LLVMFAdd->getFastMathFlags());
-}
-
-TEST_F(SandboxIRTest, CatchSwitchInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %cond0, i32 %cond1) {
-  bb0:
-    %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller
-  bb1:
-    %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup
-  handler0:
-    ret void
-  handler1:
-    ret void
-  cleanup:
-    ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB0 = getBasicBlockByName(LLVMF, "bb0");
-  auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
-  auto *LLVMHandler0 = getBasicBlockByName(LLVMF, "handler0");
-  auto *LLVMHandler1 = getBasicBlockByName(LLVMF, "handler1");
-  auto *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
-  auto *LLVMCS0 = cast<llvm::CatchSwitchInst>(&*LLVMBB0->begin());
-  auto *LLVMCS1 = cast<llvm::CatchSwitchInst>(&*LLVMBB1->begin());
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB0));
-  auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
-  auto *Handler0 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler0));
-  auto *Handler1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMHandler1));
-  auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
-  auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin());
-  auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin());
-
-  // Check getParentPad().
-  EXPECT_EQ(CS0->getParentPad(), Ctx.getValue(LLVMCS0->getParentPad()));
-  EXPECT_EQ(CS1->getParentPad(), Ctx.getValue(LLVMCS1->getParentPad()));
-  // Check setParentPad().
-  auto *OrigPad = CS0->getParentPad();
-  auto *NewPad = CS1;
-  EXPECT_NE(NewPad, OrigPad);
-  CS0->setParentPad(NewPad);
-  EXPECT_EQ(CS0->getParentPad(), NewPad);
-  CS0->setParentPad(OrigPad);
-  EXPECT_EQ(CS0->getParentPad(), OrigPad);
-  // Check hasUnwindDest().
-  EXPECT_EQ(CS0->hasUnwindDest(), LLVMCS0->hasUnwindDest());
-  EXPECT_EQ(CS1->hasUnwindDest(), LLVMCS1->hasUnwindDest());
-  // Check unwindsToCaller().
-  EXPECT_EQ(CS0->unwindsToCaller(), LLVMCS0->unwindsToCaller());
-  EXPECT_EQ(CS1->unwindsToCaller(), LLVMCS1->unwindsToCaller());
-  // Check getUnwindDest().
-  EXPECT_EQ(CS0->getUnwindDest(), Ctx.getValue(LLVMCS0->getUnwindDest()));
-  EXPECT_EQ(CS1->getUnwindDest(), Ctx.getValue(LLVMCS1->getUnwindDest()));
-  // Check setUnwindDest().
-  auto *OrigUnwindDest = CS1->getUnwindDest();
-  auto *NewUnwindDest = BB0;
-  EXPECT_NE(NewUnwindDest, OrigUnwindDest);
-  CS1->setUnwindDest(NewUnwindDest);
-  EXPECT_EQ(CS1->getUnwindDest(), NewUnwindDest);
-  CS1->setUnwindDest(OrigUnwindDest);
-  EXPECT_EQ(CS1->getUnwindDest(), OrigUnwindDest);
-  // Check getNumHandlers().
-  EXPECT_EQ(CS0->getNumHandlers(), LLVMCS0->getNumHandlers());
-  EXPECT_EQ(CS1->getNumHandlers(), LLVMCS1->getNumHandlers());
-  // Check handler_begin(), handler_end().
-  auto It = CS0->handler_begin();
-  EXPECT_EQ(*It++, Handler0);
-  EXPECT_EQ(*It++, Handler1);
-  EXPECT_EQ(It, CS0->handler_end());
-  // Check handlers().
-  SmallVector<sandboxir::BasicBlock *, 2> Handlers;
-  for (sandboxir::BasicBlock *Handler : CS0->handlers())
-    Handlers.push_back(Handler);
-  EXPECT_EQ(Handlers.size(), 2u);
-  EXPECT_EQ(Handlers[0], Handler0);
-  EXPECT_EQ(Handlers[1], Handler1);
-  // Check addHandler().
-  CS0->addHandler(BB0);
-  EXPECT_EQ(CS0->getNumHandlers(), 3u);
-  EXPECT_EQ(*std::next(CS0->handler_begin(), 2), BB0);
-  // Check getNumSuccessors().
-  EXPECT_EQ(CS0->getNumSuccessors(), LLVMCS0->getNumSuccessors());
-  EXPECT_EQ(CS1->getNumSuccessors(), LLVMCS1->getNumSuccessors());
-  // Check getSuccessor().
-  for (auto SuccIdx : seq<unsigned>(0, CS0->getNumSuccessors()))
-    EXPECT_EQ(CS0->getSuccessor(SuccIdx),
-              Ctx.getValue(LLVMCS0->getSuccessor(SuccIdx)));
-  // Check setSuccessor().
-  auto *OrigSuccessor = CS0->getSuccessor(0);
-  auto *NewSuccessor = BB0;
-  EXPECT_NE(NewSuccessor, OrigSuccessor);
-  CS0->setSuccessor(0, NewSuccessor);
-  EXPECT_EQ(CS0->getSuccessor(0), NewSuccessor);
-  CS0->setSuccessor(0, OrigSuccessor);
-  EXPECT_EQ(CS0->getSuccessor(0), OrigSuccessor);
-  // Check create().
-  CS1->eraseFromParent();
-  auto *NewCSI = sandboxir::CatchSwitchInst::create(
-      CS0, Cleanup, 2, BB1->begin(), Ctx, "NewCSI");
-  EXPECT_TRUE(isa<sandboxir::CatchSwitchInst>(NewCSI));
-  EXPECT_EQ(NewCSI->getParentPad(), CS0);
-}
-
-TEST_F(SandboxIRTest, ResumeInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-entry:
-  invoke void @foo()
-      to label %bb unwind label %unwind
-bb:
-  ret void
-unwind:
-  %lpad = landingpad { ptr, i32 }
-          cleanup
-  resume { ptr, i32 } %lpad
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMUnwindBB = getBasicBlockByName(LLVMF, "unwind");
-  auto LLVMIt = LLVMUnwindBB->begin();
-  [[maybe_unused]] auto *LLVMLPad = cast<llvm::LandingPadInst>(&*LLVMIt++);
-  auto *LLVMResume = cast<llvm::ResumeInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *UnwindBB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwindBB));
-  auto It = UnwindBB->begin();
-  auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
-  auto *Resume = cast<sandboxir::ResumeInst>(&*It++);
-  // Check getValue().
-  EXPECT_EQ(Resume->getValue(), LPad);
-  EXPECT_EQ(Resume->getValue(), Ctx.getValue(LLVMResume->getValue()));
-  // Check getNumSuccessors().
-  EXPECT_EQ(Resume->getNumSuccessors(), LLVMResume->getNumSuccessors());
-  // Check create().
-  auto *NewResume = sandboxir::ResumeInst::create(LPad, UnwindBB->end(), Ctx);
-  EXPECT_EQ(NewResume->getValue(), LPad);
-  EXPECT_EQ(NewResume->getParent(), UnwindBB);
-  EXPECT_EQ(NewResume->getNextNode(), nullptr);
-}
-
-TEST_F(SandboxIRTest, SwitchInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %cond0, i32 %cond1) {
-  entry:
-    switch i32 %cond0, label %default [ i32 0, label %bb0
-                                        i32 1, label %bb1 ]
-  bb0:
-    ret void
-  bb1:
-    ret void
-  default:
-    ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry");
-  auto *LLVMSwitch = cast<llvm::SwitchInst>(&*LLVMEntry->begin());
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Cond1 = F.getArg(1);
-  auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry));
-  auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin());
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *Default = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "default")));
-
-  // Check getCondition().
-  EXPECT_EQ(Switch->getCondition(), Ctx.getValue(LLVMSwitch->getCondition()));
-  // Check setCondition().
-  auto *OrigCond = Switch->getCondition();
-  auto *NewCond = Cond1;
-  EXPECT_NE(NewCond, OrigCond);
-  Switch->setCondition(NewCond);
-  EXPECT_EQ(Switch->getCondition(), NewCond);
-  Switch->setCondition(OrigCond);
-  EXPECT_EQ(Switch->getCondition(), OrigCond);
-  // Check getDefaultDest().
-  EXPECT_EQ(Switch->getDefaultDest(),
-            Ctx.getValue(LLVMSwitch->getDefaultDest()));
-  EXPECT_EQ(Switch->getDefaultDest(), Default);
-  // Check defaultDestUnreachable().
-  EXPECT_EQ(Switch->defaultDestUnreachable(),
-            LLVMSwitch->defaultDestUnreachable());
-  // Check setDefaultDest().
-  auto *OrigDefaultDest = Switch->getDefaultDest();
-  auto *NewDefaultDest = Entry;
-  EXPECT_NE(NewDefaultDest, OrigDefaultDest);
-  Switch->setDefaultDest(NewDefaultDest);
-  EXPECT_EQ(Switch->getDefaultDest(), NewDefaultDest);
-  Switch->setDefaultDest(OrigDefaultDest);
-  EXPECT_EQ(Switch->getDefaultDest(), OrigDefaultDest);
-  // Check getNumCases().
-  EXPECT_EQ(Switch->getNumCases(), LLVMSwitch->getNumCases());
-  // Check getNumSuccessors().
-  EXPECT_EQ(Switch->getNumSuccessors(), LLVMSwitch->getNumSuccessors());
-  // Check getSuccessor().
-  for (auto SuccIdx : seq<unsigned>(0, Switch->getNumSuccessors()))
-    EXPECT_EQ(Switch->getSuccessor(SuccIdx),
-              Ctx.getValue(LLVMSwitch->getSuccessor(SuccIdx)));
-  // Check setSuccessor().
-  auto *OrigSucc = Switch->getSuccessor(0);
-  auto *NewSucc = Entry;
-  EXPECT_NE(NewSucc, OrigSucc);
-  Switch->setSuccessor(0, NewSucc);
-  EXPECT_EQ(Switch->getSuccessor(0), NewSucc);
-  Switch->setSuccessor(0, OrigSucc);
-  EXPECT_EQ(Switch->getSuccessor(0), OrigSucc);
-  // Check case_begin(), case_end(), CaseIt.
-  auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
-  auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1);
-  auto CaseIt = Switch->case_begin();
-  {
-    sandboxir::SwitchInst::CaseHandle Case = *CaseIt++;
-    EXPECT_EQ(Case.getCaseValue(), Zero);
-    EXPECT_EQ(Case.getCaseSuccessor(), BB0);
-    EXPECT_EQ(Case.getCaseIndex(), 0u);
-    EXPECT_EQ(Case.getSuccessorIndex(), 1u);
-  }
-  {
-    sandboxir::SwitchInst::CaseHandle Case = *CaseIt++;
-    EXPECT_EQ(Case.getCaseValue(), One);
-    EXPECT_EQ(Case.getCaseSuccessor(), BB1);
-    EXPECT_EQ(Case.getCaseIndex(), 1u);
-    EXPECT_EQ(Case.getSuccessorIndex(), 2u);
-  }
-  EXPECT_EQ(CaseIt, Switch->case_end());
-  // Check cases().
-  unsigned CntCase = 0;
-  for (auto &Case : Switch->cases()) {
-    EXPECT_EQ(Case.getCaseIndex(), CntCase);
-    ++CntCase;
-  }
-  EXPECT_EQ(CntCase, 2u);
-  // Check case_default().
-  auto CaseDefault = *Switch->case_default();
-  EXPECT_EQ(CaseDefault.getCaseSuccessor(), Default);
-  EXPECT_EQ(CaseDefault.getCaseIndex(),
-            sandboxir::SwitchInst::DefaultPseudoIndex);
-  // Check findCaseValue().
-  EXPECT_EQ(Switch->findCaseValue(Zero)->getCaseIndex(), 0u);
-  EXPECT_EQ(Switch->findCaseValue(One)->getCaseIndex(), 1u);
-  // Check findCaseDest().
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  EXPECT_EQ(Switch->findCaseDest(Entry), nullptr);
-  // Check addCase().
-  auto *Two = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 2);
-  Switch->addCase(Two, Entry);
-  auto CaseTwoIt = Switch->findCaseValue(Two);
-  auto CaseTwo = *CaseTwoIt;
-  EXPECT_EQ(CaseTwo.getCaseValue(), Two);
-  EXPECT_EQ(CaseTwo.getCaseSuccessor(), Entry);
-  EXPECT_EQ(Switch->getNumCases(), 3u);
-  // Check removeCase().
-  auto RemovedIt = Switch->removeCase(CaseTwoIt);
-  EXPECT_EQ(RemovedIt, Switch->case_end());
-  EXPECT_EQ(Switch->getNumCases(), 2u);
-  // Check create().
-  auto NewSwitch = sandboxir::SwitchInst::create(
-      Cond1, Default, 1, Default->begin(), Ctx, "NewSwitch");
-  EXPECT_TRUE(isa<sandboxir::SwitchInst>(NewSwitch));
-  EXPECT_EQ(NewSwitch->getCondition(), Cond1);
-  EXPECT_EQ(NewSwitch->getDefaultDest(), Default);
-}
-
-TEST_F(SandboxIRTest, UnaryOperator) {
-  parseIR(C, R"IR(
-define void @foo(float %arg0) {
-  %fneg = fneg float %arg0
-  %copyfrom = fadd reassoc float %arg0, 42.0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Arg0 = F.getArg(0);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I = cast<sandboxir::UnaryOperator>(&*It++);
-  auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Ret = &*It++;
-  EXPECT_EQ(I->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-  EXPECT_EQ(I->getOperand(0), Arg0);
-
-  {
-    // Check create() WhereIt, WhereBB.
-    auto *NewI =
-        cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
-            sandboxir::Instruction::Opcode::FNeg, Arg0, Ret->getIterator(), Ctx,
-            "New1"));
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "New1");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertBefore.
-    auto *NewI =
-        cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
-            sandboxir::Instruction::Opcode::FNeg, Arg0, Ret->getIterator(), Ctx,
-            "New2"));
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "New2");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI =
-        cast<sandboxir::UnaryOperator>(sandboxir::UnaryOperator::create(
-            sandboxir::Instruction::Opcode::FNeg, Arg0, BB, Ctx, "New3"));
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "New3");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getParent(), BB);
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-  }
-  {
-    // Check create() when it gets folded.
-    auto *FortyTwo = CopyFrom->getOperand(1);
-    auto *NewV = sandboxir::UnaryOperator::create(
-        sandboxir::Instruction::Opcode::FNeg, FortyTwo, Ret->getIterator(), Ctx,
-        "Folded");
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
-  }
-
-  {
-    // Check createWithCopiedFlags() WhereIt, WhereBB.
-    auto *NewI = cast<sandboxir::UnaryOperator>(
-        sandboxir::UnaryOperator::createWithCopiedFlags(
-            sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
-            Ret->getIterator(), Ctx, "NewCopyFrom1"));
-    EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "NewCopyFrom1");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check createWithCopiedFlags() InsertBefore,
-    auto *NewI = cast<sandboxir::UnaryOperator>(
-        sandboxir::UnaryOperator::createWithCopiedFlags(
-            sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom,
-            Ret->getIterator(), Ctx, "NewCopyFrom2"));
-    EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "NewCopyFrom2");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check createWithCopiedFlags() InsertAtEnd,
-    auto *NewI = cast<sandboxir::UnaryOperator>(
-        sandboxir::UnaryOperator::createWithCopiedFlags(
-            sandboxir::Instruction::Opcode::FNeg, Arg0, CopyFrom, BB, Ctx,
-            "NewCopyFrom3"));
-    EXPECT_EQ(NewI->hasAllowReassoc(), CopyFrom->hasAllowReassoc());
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::FNeg);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "NewCopyFrom3");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getParent(), BB);
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-  }
-  {
-    // Check createWithCopiedFlags() when it gets folded.
-    auto *FortyTwo = CopyFrom->getOperand(1);
-    auto *NewV = sandboxir::UnaryOperator::createWithCopiedFlags(
-        sandboxir::Instruction::Opcode::FNeg, FortyTwo, CopyFrom, BB, Ctx,
-        "Folded");
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
-  }
-}
-
-TEST_F(SandboxIRTest, BinaryOperator) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg0, i8 %arg1, float %farg0, float %farg1) {
-  %add = add i8 %arg0, %arg1
-  %fadd = fadd float %farg0, %farg1
-  %sub = sub i8 %arg0, %arg1
-  %fsub = fsub float %farg0, %farg1
-  %mul = mul i8 %arg0, %arg1
-  %fmul = fmul float %farg0, %farg1
-  %udiv = udiv i8 %arg0, %arg1
-  %sdiv = sdiv i8 %arg0, %arg1
-  %fdiv = fdiv float %farg0, %farg1
-  %urem = urem i8 %arg0, %arg1
-  %srem = srem i8 %arg0, %arg1
-  %frem = frem float %farg0, %farg1
-  %shl = shl i8 %arg0, %arg1
-  %lshr = lshr i8 %arg0, %arg1
-  %ashr = ashr i8 %arg0, %arg1
-  %and = and i8 %arg0, %arg1
-  %or = or i8 %arg0, %arg1
-  %xor = xor i8 %arg0, %arg1
-
-  %copyfrom = add nsw i8 %arg0, %arg1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Arg0 = F.getArg(0);
-  auto *Arg1 = F.getArg(1);
-  auto *FArg0 = F.getArg(2);
-  auto *FArg1 = F.getArg(3);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-
-#define CHECK_IBINOP(OPCODE)                                                   \
-  {                                                                            \
-    auto *I = cast<sandboxir::BinaryOperator>(&*It++);                         \
-    EXPECT_EQ(I->getOpcode(), OPCODE);                                         \
-    EXPECT_EQ(I->getOperand(0), Arg0);                                         \
-    EXPECT_EQ(I->getOperand(1), Arg1);                                         \
-  }
-#define CHECK_FBINOP(OPCODE)                                                   \
-  {                                                                            \
-    auto *I = cast<sandboxir::BinaryOperator>(&*It++);                         \
-    EXPECT_EQ(I->getOpcode(), OPCODE);                                         \
-    EXPECT_EQ(I->getOperand(0), FArg0);                                        \
-    EXPECT_EQ(I->getOperand(1), FArg1);                                        \
-  }
-
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::Add);
-  CHECK_FBINOP(sandboxir::Instruction::Opcode::FAdd);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::Sub);
-  CHECK_FBINOP(sandboxir::Instruction::Opcode::FSub);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::Mul);
-  CHECK_FBINOP(sandboxir::Instruction::Opcode::FMul);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::UDiv);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::SDiv);
-  CHECK_FBINOP(sandboxir::Instruction::Opcode::FDiv);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::URem);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::SRem);
-  CHECK_FBINOP(sandboxir::Instruction::Opcode::FRem);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::Shl);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::LShr);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::AShr);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::And);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::Or);
-  CHECK_IBINOP(sandboxir::Instruction::Opcode::Xor);
-
-  auto *CopyFrom = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  {
-    // Check create() WhereIt, WhereBB.
-    auto *NewI =
-        cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
-            sandboxir::Instruction::Opcode::Add, Arg0, Arg1, Ret->getIterator(),
-            Ctx, "New1"));
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-    EXPECT_EQ(NewI->getOperand(1), Arg1);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "New1");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertBefore.
-    auto *NewI =
-        cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
-            sandboxir::Instruction::Opcode::Add, Arg0, Arg1, Ret->getIterator(),
-            Ctx, "New2"));
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-    EXPECT_EQ(NewI->getOperand(1), Arg1);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "New2");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI =
-        cast<sandboxir::BinaryOperator>(sandboxir::BinaryOperator::create(
-            sandboxir::Instruction::Opcode::Add, Arg0, Arg1,
-            /*InsertAtEnd=*/BB, Ctx, "New3"));
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-    EXPECT_EQ(NewI->getOperand(1), Arg1);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "New3");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    EXPECT_EQ(NewI->getParent(), BB);
-  }
-  {
-    // Check create() when it gets folded.
-    auto *FortyTwo =
-        sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
-    auto *NewV = sandboxir::BinaryOperator::create(
-        sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo,
-        Ret->getIterator(), Ctx, "Folded");
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
-  }
-
-  {
-    // Check createWithCopiedFlags() WhereIt, WhereBB.
-    auto *NewI = cast<sandboxir::BinaryOperator>(
-        sandboxir::BinaryOperator::createWithCopiedFlags(
-            sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
-            Ret->getIterator(), Ctx, "NewNSW1"));
-    EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-    EXPECT_EQ(NewI->getOperand(1), Arg1);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "NewNSW1");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check createWithCopiedFlags() InsertBefore.
-    auto *NewI = cast<sandboxir::BinaryOperator>(
-        sandboxir::BinaryOperator::createWithCopiedFlags(
-            sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom,
-            Ret->getIterator(), Ctx, "NewNSW2"));
-    EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-    EXPECT_EQ(NewI->getOperand(1), Arg1);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "NewNSW2");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check createWithCopiedFlags() InsertAtEnd.
-    auto *NewI = cast<sandboxir::BinaryOperator>(
-        sandboxir::BinaryOperator::createWithCopiedFlags(
-            sandboxir::Instruction::Opcode::Add, Arg0, Arg1, CopyFrom, BB, Ctx,
-            "NewNSW3"));
-    EXPECT_EQ(NewI->hasNoSignedWrap(), CopyFrom->hasNoSignedWrap());
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Add);
-    EXPECT_EQ(NewI->getOperand(0), Arg0);
-    EXPECT_EQ(NewI->getOperand(1), Arg1);
-#ifndef NDEBUG
-    EXPECT_EQ(NewI->getName(), "NewNSW3");
-#endif // NDEBUG
-    EXPECT_EQ(NewI->getParent(), BB);
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-  }
-  {
-    // Check createWithCopiedFlags() when it gets folded.
-    auto *FortyTwo =
-        sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
-    auto *NewV = sandboxir::BinaryOperator::createWithCopiedFlags(
-        sandboxir::Instruction::Opcode::Add, FortyTwo, FortyTwo, CopyFrom,
-        Ret->getIterator(), Ctx, "Folded");
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewV));
-  }
-}
-
-TEST_F(SandboxIRTest, PossiblyDisjointInst) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg0, i8 %arg1) {
-  %or = or i8 %arg0, %arg1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *PDI = cast<sandboxir::PossiblyDisjointInst>(&*It++);
-
-  // Check setIsDisjoint(), isDisjoint().
-  auto OrigIsDisjoint = PDI->isDisjoint();
-  auto NewIsDisjoint = true;
-  EXPECT_NE(NewIsDisjoint, OrigIsDisjoint);
-  PDI->setIsDisjoint(NewIsDisjoint);
-  EXPECT_EQ(PDI->isDisjoint(), NewIsDisjoint);
-  PDI->setIsDisjoint(OrigIsDisjoint);
-  EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint);
-}
-
-TEST_F(SandboxIRTest, AtomicRMWInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %arg) {
-  %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128
-  ret void
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMRMW = cast<llvm::AtomicRMWInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  auto *Ptr = F->getArg(0);
-  auto *Arg = F->getArg(1);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *RMW = cast<sandboxir::AtomicRMWInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check getOperationName().
-  EXPECT_EQ(
-      sandboxir::AtomicRMWInst::getOperationName(
-          sandboxir::AtomicRMWInst::BinOp::Add),
-      llvm::AtomicRMWInst::getOperationName(llvm::AtomicRMWInst::BinOp::Add));
-  // Check isFPOperation().
-  EXPECT_EQ(
-      sandboxir::AtomicRMWInst::isFPOperation(
-          sandboxir::AtomicRMWInst::BinOp::Add),
-      llvm::AtomicRMWInst::isFPOperation(llvm::AtomicRMWInst::BinOp::Add));
-  EXPECT_FALSE(sandboxir::AtomicRMWInst::isFPOperation(
-      sandboxir::AtomicRMWInst::BinOp::Add));
-  EXPECT_TRUE(sandboxir::AtomicRMWInst::isFPOperation(
-      sandboxir::AtomicRMWInst::BinOp::FAdd));
-  // Check setOperation(), getOperation().
-  EXPECT_EQ(RMW->getOperation(), LLVMRMW->getOperation());
-  RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Sub);
-  EXPECT_EQ(RMW->getOperation(), sandboxir::AtomicRMWInst::BinOp::Sub);
-  RMW->setOperation(sandboxir::AtomicRMWInst::BinOp::Add);
-  // Check getAlign().
-  EXPECT_EQ(RMW->getAlign(), LLVMRMW->getAlign());
-  auto OrigAlign = RMW->getAlign();
-  Align NewAlign(256);
-  EXPECT_NE(NewAlign, OrigAlign);
-  RMW->setAlignment(NewAlign);
-  EXPECT_EQ(RMW->getAlign(), NewAlign);
-  RMW->setAlignment(OrigAlign);
-  EXPECT_EQ(RMW->getAlign(), OrigAlign);
-  // Check isVolatile(), setVolatile().
-  EXPECT_EQ(RMW->isVolatile(), LLVMRMW->isVolatile());
-  bool OrigV = RMW->isVolatile();
-  bool NewV = true;
-  EXPECT_NE(NewV, OrigV);
-  RMW->setVolatile(NewV);
-  EXPECT_EQ(RMW->isVolatile(), NewV);
-  RMW->setVolatile(OrigV);
-  EXPECT_EQ(RMW->isVolatile(), OrigV);
-  // Check getOrdering(), setOrdering().
-  EXPECT_EQ(RMW->getOrdering(), LLVMRMW->getOrdering());
-  auto OldOrdering = RMW->getOrdering();
-  auto NewOrdering = AtomicOrdering::Monotonic;
-  EXPECT_NE(NewOrdering, OldOrdering);
-  RMW->setOrdering(NewOrdering);
-  EXPECT_EQ(RMW->getOrdering(), NewOrdering);
-  RMW->setOrdering(OldOrdering);
-  EXPECT_EQ(RMW->getOrdering(), OldOrdering);
-  // Check getSyncScopeID(), setSyncScopeID().
-  EXPECT_EQ(RMW->getSyncScopeID(), LLVMRMW->getSyncScopeID());
-  auto OrigSSID = RMW->getSyncScopeID();
-  SyncScope::ID NewSSID = SyncScope::SingleThread;
-  EXPECT_NE(NewSSID, OrigSSID);
-  RMW->setSyncScopeID(NewSSID);
-  EXPECT_EQ(RMW->getSyncScopeID(), NewSSID);
-  RMW->setSyncScopeID(OrigSSID);
-  EXPECT_EQ(RMW->getSyncScopeID(), OrigSSID);
-  // Check getPointerOperand().
-  EXPECT_EQ(RMW->getPointerOperand(),
-            Ctx.getValue(LLVMRMW->getPointerOperand()));
-  // Check getValOperand().
-  EXPECT_EQ(RMW->getValOperand(), Ctx.getValue(LLVMRMW->getValOperand()));
-  // Check getPointerAddressSpace().
-  EXPECT_EQ(RMW->getPointerAddressSpace(), LLVMRMW->getPointerAddressSpace());
-  // Check isFloatingPointOperation().
-  EXPECT_EQ(RMW->isFloatingPointOperation(),
-            LLVMRMW->isFloatingPointOperation());
-
-  Align Align(1024);
-  auto Ordering = AtomicOrdering::Acquire;
-  auto SSID = SyncScope::System;
-  {
-    // Check create() WhereIt, WhereBB.
-    auto *NewI =
-        cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
-            sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
-            Ret->getIterator(), Ctx, SSID, "NewAtomicRMW1"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
-    // Check getAlign().
-    EXPECT_EQ(NewI->getAlign(), Align);
-    // Check getSuccessOrdering().
-    EXPECT_EQ(NewI->getOrdering(), Ordering);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-    // Check getPointerOperand().
-    EXPECT_EQ(NewI->getPointerOperand(), Ptr);
-    // Check getValOperand().
-    EXPECT_EQ(NewI->getValOperand(), Arg);
-#ifndef NDEBUG
-    // Check getName().
-    EXPECT_EQ(NewI->getName(), "NewAtomicRMW1");
-#endif // NDEBUG
-  }
-  {
-    // Check create() InsertBefore.
-    auto *NewI =
-        cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
-            sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering,
-            Ret->getIterator(), Ctx, SSID, "NewAtomicRMW2"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
-    // Check getAlign().
-    EXPECT_EQ(NewI->getAlign(), Align);
-    // Check getSuccessOrdering().
-    EXPECT_EQ(NewI->getOrdering(), Ordering);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-    // Check getPointerOperand().
-    EXPECT_EQ(NewI->getPointerOperand(), Ptr);
-    // Check getValOperand().
-    EXPECT_EQ(NewI->getValOperand(), Arg);
-#ifndef NDEBUG
-    // Check getName().
-    EXPECT_EQ(NewI->getName(), "NewAtomicRMW2");
-#endif // NDEBUG
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI =
-        cast<sandboxir::AtomicRMWInst>(sandboxir::AtomicRMWInst::create(
-            sandboxir::AtomicRMWInst::BinOp::Sub, Ptr, Arg, Align, Ordering, BB,
-            Ctx, SSID, "NewAtomicRMW3"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicRMW);
-    // Check getAlign().
-    EXPECT_EQ(NewI->getAlign(), Align);
-    // Check getSuccessOrdering().
-    EXPECT_EQ(NewI->getOrdering(), Ordering);
-    // Check instr position.
-    EXPECT_EQ(NewI->getParent(), BB);
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    // Check getPointerOperand().
-    EXPECT_EQ(NewI->getPointerOperand(), Ptr);
-    // Check getValOperand().
-    EXPECT_EQ(NewI->getValOperand(), Arg);
-#ifndef NDEBUG
-    // Check getName().
-    EXPECT_EQ(NewI->getName(), "NewAtomicRMW3");
-#endif // NDEBUG
-  }
-}
-
-TEST_F(SandboxIRTest, AtomicCmpXchgInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %cmp, i8 %new) {
-  %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128
-  ret void
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMCmpXchg = cast<llvm::AtomicCmpXchgInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  auto *Ptr = F->getArg(0);
-  auto *Cmp = F->getArg(1);
-  auto *New = F->getArg(2);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *CmpXchg = cast<sandboxir::AtomicCmpXchgInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check getAlign(), setAlignment().
-  EXPECT_EQ(CmpXchg->getAlign(), LLVMCmpXchg->getAlign());
-  auto OrigAlign = CmpXchg->getAlign();
-  Align NewAlign(256);
-  EXPECT_NE(NewAlign, OrigAlign);
-  CmpXchg->setAlignment(NewAlign);
-  EXPECT_EQ(CmpXchg->getAlign(), NewAlign);
-  CmpXchg->setAlignment(OrigAlign);
-  EXPECT_EQ(CmpXchg->getAlign(), OrigAlign);
-  // Check isVolatile(), setVolatile().
-  EXPECT_EQ(CmpXchg->isVolatile(), LLVMCmpXchg->isVolatile());
-  bool OrigV = CmpXchg->isVolatile();
-  bool NewV = true;
-  EXPECT_NE(NewV, OrigV);
-  CmpXchg->setVolatile(NewV);
-  EXPECT_EQ(CmpXchg->isVolatile(), NewV);
-  CmpXchg->setVolatile(OrigV);
-  EXPECT_EQ(CmpXchg->isVolatile(), OrigV);
-  // Check isWeak(), setWeak().
-  EXPECT_EQ(CmpXchg->isWeak(), LLVMCmpXchg->isWeak());
-  bool OrigWeak = CmpXchg->isWeak();
-  bool NewWeak = true;
-  EXPECT_NE(NewWeak, OrigWeak);
-  CmpXchg->setWeak(NewWeak);
-  EXPECT_EQ(CmpXchg->isWeak(), NewWeak);
-  CmpXchg->setWeak(OrigWeak);
-  EXPECT_EQ(CmpXchg->isWeak(), OrigWeak);
-  // Check isValidSuccessOrdering(), isValidFailureOrdering().
-  SmallVector<AtomicOrdering> AllOrderings(
-      {AtomicOrdering::NotAtomic, AtomicOrdering::Unordered,
-       AtomicOrdering::Monotonic, AtomicOrdering::Acquire,
-       AtomicOrdering::Release, AtomicOrdering::AcquireRelease,
-       AtomicOrdering::SequentiallyConsistent});
-  for (auto Ordering : AllOrderings) {
-    EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering),
-              llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering));
-    EXPECT_EQ(sandboxir::AtomicCmpXchgInst::isValidFailureOrdering(Ordering),
-              llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering));
-  }
-  // Check getSuccessOrdering(), setSuccessOrdering().
-  EXPECT_EQ(CmpXchg->getSuccessOrdering(), LLVMCmpXchg->getSuccessOrdering());
-  auto OldSuccOrdering = CmpXchg->getSuccessOrdering();
-  auto NewSuccOrdering = AtomicOrdering::Acquire;
-  EXPECT_NE(NewSuccOrdering, OldSuccOrdering);
-  CmpXchg->setSuccessOrdering(NewSuccOrdering);
-  EXPECT_EQ(CmpXchg->getSuccessOrdering(), NewSuccOrdering);
-  CmpXchg->setSuccessOrdering(OldSuccOrdering);
-  EXPECT_EQ(CmpXchg->getSuccessOrdering(), OldSuccOrdering);
-  // Check getFailureOrdering(), setFailureOrdering().
-  EXPECT_EQ(CmpXchg->getFailureOrdering(), LLVMCmpXchg->getFailureOrdering());
-  auto OldFailOrdering = CmpXchg->getFailureOrdering();
-  auto NewFailOrdering = AtomicOrdering::Acquire;
-  EXPECT_NE(NewFailOrdering, OldFailOrdering);
-  CmpXchg->setFailureOrdering(NewFailOrdering);
-  EXPECT_EQ(CmpXchg->getFailureOrdering(), NewFailOrdering);
-  CmpXchg->setFailureOrdering(OldFailOrdering);
-  EXPECT_EQ(CmpXchg->getFailureOrdering(), OldFailOrdering);
-  // Check getMergedOrdering().
-  EXPECT_EQ(CmpXchg->getMergedOrdering(), LLVMCmpXchg->getMergedOrdering());
-  // Check getSyncScopeID(), setSyncScopeID().
-  EXPECT_EQ(CmpXchg->getSyncScopeID(), LLVMCmpXchg->getSyncScopeID());
-  auto OrigSSID = CmpXchg->getSyncScopeID();
-  SyncScope::ID NewSSID = SyncScope::SingleThread;
-  EXPECT_NE(NewSSID, OrigSSID);
-  CmpXchg->setSyncScopeID(NewSSID);
-  EXPECT_EQ(CmpXchg->getSyncScopeID(), NewSSID);
-  CmpXchg->setSyncScopeID(OrigSSID);
-  EXPECT_EQ(CmpXchg->getSyncScopeID(), OrigSSID);
-  // Check getPointerOperand().
-  EXPECT_EQ(CmpXchg->getPointerOperand(),
-            Ctx.getValue(LLVMCmpXchg->getPointerOperand()));
-  // Check getCompareOperand().
-  EXPECT_EQ(CmpXchg->getCompareOperand(),
-            Ctx.getValue(LLVMCmpXchg->getCompareOperand()));
-  // Check getNewValOperand().
-  EXPECT_EQ(CmpXchg->getNewValOperand(),
-            Ctx.getValue(LLVMCmpXchg->getNewValOperand()));
-  // Check getPointerAddressSpace().
-  EXPECT_EQ(CmpXchg->getPointerAddressSpace(),
-            LLVMCmpXchg->getPointerAddressSpace());
-
-  Align Align(1024);
-  auto SuccOrdering = AtomicOrdering::Acquire;
-  auto FailOrdering = AtomicOrdering::Monotonic;
-  auto SSID = SyncScope::System;
-  {
-    // Check create() WhereIt, WhereBB.
-    auto *NewI =
-        cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
-            Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
-            Ret->getIterator(), Ctx, SSID, "NewAtomicCmpXchg1"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
-    // Check getAlign().
-    EXPECT_EQ(NewI->getAlign(), Align);
-    // Check getSuccessOrdering().
-    EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
-    // Check getFailureOrdering().
-    EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-    // Check getPointerOperand().
-    EXPECT_EQ(NewI->getPointerOperand(), Ptr);
-    // Check getCompareOperand().
-    EXPECT_EQ(NewI->getCompareOperand(), Cmp);
-    // Check getNewValOperand().
-    EXPECT_EQ(NewI->getNewValOperand(), New);
-#ifndef NDEBUG
-    // Check getName().
-    EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg1");
-#endif // NDEBUG
-  }
-  {
-    // Check create() InsertBefore.
-    auto *NewI =
-        cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
-            Ptr, Cmp, New, Align, SuccOrdering, FailOrdering,
-            Ret->getIterator(), Ctx, SSID, "NewAtomicCmpXchg2"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
-    // Check getAlign().
-    EXPECT_EQ(NewI->getAlign(), Align);
-    // Check getSuccessOrdering().
-    EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
-    // Check getFailureOrdering().
-    EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-    // Check getPointerOperand().
-    EXPECT_EQ(NewI->getPointerOperand(), Ptr);
-    // Check getCompareOperand().
-    EXPECT_EQ(NewI->getCompareOperand(), Cmp);
-    // Check getNewValOperand().
-    EXPECT_EQ(NewI->getNewValOperand(), New);
-#ifndef NDEBUG
-    // Check getName().
-    EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg2");
-#endif // NDEBUG
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI =
-        cast<sandboxir::AtomicCmpXchgInst>(sandboxir::AtomicCmpXchgInst::create(
-            Ptr, Cmp, New, Align, SuccOrdering, FailOrdering, BB, Ctx, SSID,
-            "NewAtomicCmpXchg3"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::AtomicCmpXchg);
-    // Check getAlign().
-    EXPECT_EQ(NewI->getAlign(), Align);
-    // Check getSuccessOrdering().
-    EXPECT_EQ(NewI->getSuccessOrdering(), SuccOrdering);
-    // Check getFailureOrdering().
-    EXPECT_EQ(NewI->getFailureOrdering(), FailOrdering);
-    // Check instr position.
-    EXPECT_EQ(NewI->getParent(), BB);
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    // Check getPointerOperand().
-    EXPECT_EQ(NewI->getPointerOperand(), Ptr);
-    // Check getCompareOperand().
-    EXPECT_EQ(NewI->getCompareOperand(), Cmp);
-    // Check getNewValOperand().
-    EXPECT_EQ(NewI->getNewValOperand(), New);
-#ifndef NDEBUG
-    // Check getName().
-    EXPECT_EQ(NewI->getName(), "NewAtomicCmpXchg3");
-#endif // NDEBUG
-  }
-}
-
-TEST_F(SandboxIRTest, AllocaInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-  %allocaScalar = alloca i32, align 1024
-  %allocaArray = alloca i32, i32 42
-  ret void
-}
-)IR");
-  const DataLayout &DL = M->getDataLayout();
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
-  auto LLVMIt = LLVMBB->begin();
-  auto *LLVMAllocaScalar = cast<llvm::AllocaInst>(&*LLVMIt++);
-  auto *LLVMAllocaArray = cast<llvm::AllocaInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *AllocaScalar = cast<sandboxir::AllocaInst>(&*It++);
-  auto *AllocaArray = cast<sandboxir::AllocaInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check isArrayAllocation().
-  EXPECT_EQ(AllocaScalar->isArrayAllocation(),
-            LLVMAllocaScalar->isArrayAllocation());
-  EXPECT_EQ(AllocaArray->isArrayAllocation(),
-            LLVMAllocaArray->isArrayAllocation());
-  // Check getArraySize().
-  EXPECT_EQ(AllocaScalar->getArraySize(),
-            Ctx.getValue(LLVMAllocaScalar->getArraySize()));
-  EXPECT_EQ(AllocaArray->getArraySize(),
-            Ctx.getValue(LLVMAllocaArray->getArraySize()));
-  // Check getType().
-  EXPECT_EQ(AllocaScalar->getType(), Ctx.getType(LLVMAllocaScalar->getType()));
-  EXPECT_EQ(AllocaArray->getType(), Ctx.getType(LLVMAllocaArray->getType()));
-  // Check getAddressSpace().
-  EXPECT_EQ(AllocaScalar->getAddressSpace(),
-            LLVMAllocaScalar->getAddressSpace());
-  EXPECT_EQ(AllocaArray->getAddressSpace(), LLVMAllocaArray->getAddressSpace());
-  // Check getAllocationSize().
-  EXPECT_EQ(AllocaScalar->getAllocationSize(DL),
-            LLVMAllocaScalar->getAllocationSize(DL));
-  EXPECT_EQ(AllocaArray->getAllocationSize(DL),
-            LLVMAllocaArray->getAllocationSize(DL));
-  // Check getAllocationSizeInBits().
-  EXPECT_EQ(AllocaScalar->getAllocationSizeInBits(DL),
-            LLVMAllocaScalar->getAllocationSizeInBits(DL));
-  EXPECT_EQ(AllocaArray->getAllocationSizeInBits(DL),
-            LLVMAllocaArray->getAllocationSizeInBits(DL));
-  // Check getAllocatedType().
-  EXPECT_EQ(AllocaScalar->getAllocatedType(),
-            Ctx.getType(LLVMAllocaScalar->getAllocatedType()));
-  EXPECT_EQ(AllocaArray->getAllocatedType(),
-            Ctx.getType(LLVMAllocaArray->getAllocatedType()));
-  // Check setAllocatedType().
-  auto *OrigType = AllocaScalar->getAllocatedType();
-  auto *NewType = sandboxir::PointerType::get(Ctx, 0);
-  EXPECT_NE(NewType, OrigType);
-  AllocaScalar->setAllocatedType(NewType);
-  EXPECT_EQ(AllocaScalar->getAllocatedType(), NewType);
-  AllocaScalar->setAllocatedType(OrigType);
-  EXPECT_EQ(AllocaScalar->getAllocatedType(), OrigType);
-  // Check getAlign().
-  EXPECT_EQ(AllocaScalar->getAlign(), LLVMAllocaScalar->getAlign());
-  EXPECT_EQ(AllocaArray->getAlign(), LLVMAllocaArray->getAlign());
-  // Check setAlignment().
-  Align OrigAlign = AllocaScalar->getAlign();
-  Align NewAlign(16);
-  EXPECT_NE(NewAlign, OrigAlign);
-  AllocaScalar->setAlignment(NewAlign);
-  EXPECT_EQ(AllocaScalar->getAlign(), NewAlign);
-  AllocaScalar->setAlignment(OrigAlign);
-  EXPECT_EQ(AllocaScalar->getAlign(), OrigAlign);
-  // Check isStaticAlloca().
-  EXPECT_EQ(AllocaScalar->isStaticAlloca(), LLVMAllocaScalar->isStaticAlloca());
-  EXPECT_EQ(AllocaArray->isStaticAlloca(), LLVMAllocaArray->isStaticAlloca());
-  // Check isUsedWithInAlloca(), setUsedWithInAlloca().
-  EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(),
-            LLVMAllocaScalar->isUsedWithInAlloca());
-  bool OrigUsedWithInAlloca = AllocaScalar->isUsedWithInAlloca();
-  bool NewUsedWithInAlloca = true;
-  EXPECT_NE(NewUsedWithInAlloca, OrigUsedWithInAlloca);
-  AllocaScalar->setUsedWithInAlloca(NewUsedWithInAlloca);
-  EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), NewUsedWithInAlloca);
-  AllocaScalar->setUsedWithInAlloca(OrigUsedWithInAlloca);
-  EXPECT_EQ(AllocaScalar->isUsedWithInAlloca(), OrigUsedWithInAlloca);
-
-  auto *Ty = sandboxir::Type::getInt32Ty(Ctx);
-  unsigned AddrSpace = 42;
-  auto *PtrTy = sandboxir::PointerType::get(Ctx, AddrSpace);
-  auto *ArraySize = sandboxir::ConstantInt::get(Ty, 43);
-  {
-    // Check create() WhereIt, WhereBB.
-    auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
-        Ty, AddrSpace, Ret->getIterator(), Ctx, ArraySize, "NewAlloca1"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
-    // Check getType().
-    EXPECT_EQ(NewI->getType(), PtrTy);
-    // Check getArraySize().
-    EXPECT_EQ(NewI->getArraySize(), ArraySize);
-    // Check getAddrSpace().
-    EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertBefore.
-    auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
-        Ty, AddrSpace, Ret->getIterator(), Ctx, ArraySize, "NewAlloca2"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
-    // Check getType().
-    EXPECT_EQ(NewI->getType(), PtrTy);
-    // Check getArraySize().
-    EXPECT_EQ(NewI->getArraySize(), ArraySize);
-    // Check getAddrSpace().
-    EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI = cast<sandboxir::AllocaInst>(sandboxir::AllocaInst::create(
-        Ty, AddrSpace, BB, Ctx, ArraySize, "NewAlloca3"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::Alloca);
-    // Check getType().
-    EXPECT_EQ(NewI->getType(), PtrTy);
-    // Check getArraySize().
-    EXPECT_EQ(NewI->getArraySize(), ArraySize);
-    // Check getAddrSpace().
-    EXPECT_EQ(NewI->getAddressSpace(), AddrSpace);
-    // Check instr position.
-    EXPECT_EQ(NewI->getParent(), BB);
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-  }
-}
-
-TEST_F(SandboxIRTest, CastInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
-  %zext = zext i32 %arg to i64
-  %sext = sext i32 %arg to i64
-  %fptoui = fptoui float %farg to i32
-  %fptosi = fptosi float %farg to i32
-  %fpext = fpext float %farg to double
-  %ptrtoint = ptrtoint ptr %ptr to i32
-  %inttoptr = inttoptr i32 %arg to ptr
-  %sitofp = sitofp i32 %arg to float
-  %uitofp = uitofp i32 %arg to float
-  %trunc = trunc i32 %arg to i16
-  %fptrunc = fptrunc double %darg to float
-  %bitcast = bitcast i32 %arg to float
-  %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  unsigned ArgIdx = 0;
-  auto *Arg = F->getArg(ArgIdx++);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-
-  auto *Ti64 = sandboxir::Type::getInt64Ty(Ctx);
-  auto *Ti32 = sandboxir::Type::getInt32Ty(Ctx);
-  auto *Ti16 = sandboxir::Type::getInt16Ty(Ctx);
-  auto *Tdouble = sandboxir::Type::getDoubleTy(Ctx);
-  auto *Tfloat = sandboxir::Type::getFloatTy(Ctx);
-  auto *Tptr = sandboxir::PointerType::get(Ctx, 0);
-  auto *Tptr1 = sandboxir::PointerType::get(Ctx, 1);
-
-  // Check classof(), getOpcode(), getSrcTy(), getDstTy()
-  auto *ZExt = cast<sandboxir::CastInst>(&*It++);
-  auto *ZExtI = cast<sandboxir::ZExtInst>(ZExt);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(ZExtI));
-  EXPECT_EQ(ZExt->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
-  EXPECT_EQ(ZExt->getSrcTy(), Ti32);
-  EXPECT_EQ(ZExt->getDestTy(), Ti64);
-
-  auto *SExt = cast<sandboxir::CastInst>(&*It++);
-  auto *SExtI = cast<sandboxir::SExtInst>(SExt);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExt));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SExtI));
-  EXPECT_EQ(SExt->getOpcode(), sandboxir::Instruction::Opcode::SExt);
-  EXPECT_EQ(SExt->getSrcTy(), Ti32);
-  EXPECT_EQ(SExt->getDestTy(), Ti64);
-
-  auto *FPToUI = cast<sandboxir::CastInst>(&*It++);
-  auto *FPToUII = cast<sandboxir::FPToUIInst>(FPToUI);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUI));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToUII));
-  EXPECT_EQ(FPToUI->getOpcode(), sandboxir::Instruction::Opcode::FPToUI);
-  EXPECT_EQ(FPToUI->getSrcTy(), Tfloat);
-  EXPECT_EQ(FPToUI->getDestTy(), Ti32);
-
-  auto *FPToSI = cast<sandboxir::CastInst>(&*It++);
-  auto *FPToSII = cast<sandboxir::FPToSIInst>(FPToSI);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSI));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPToSII));
-  EXPECT_EQ(FPToSI->getOpcode(), sandboxir::Instruction::Opcode::FPToSI);
-  EXPECT_EQ(FPToSI->getSrcTy(), Tfloat);
-  EXPECT_EQ(FPToSI->getDestTy(), Ti32);
-
-  auto *FPExt = cast<sandboxir::CastInst>(&*It++);
-  auto *FPExtI = cast<sandboxir::FPExtInst>(FPExt);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExt));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPExtI));
-  EXPECT_EQ(FPExt->getOpcode(), sandboxir::Instruction::Opcode::FPExt);
-  EXPECT_EQ(FPExt->getSrcTy(), Tfloat);
-  EXPECT_EQ(FPExt->getDestTy(), Tdouble);
-
-  auto *PtrToInt = cast<sandboxir::CastInst>(&*It++);
-  auto *PtrToIntI = cast<sandboxir::PtrToIntInst>(PtrToInt);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToInt));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(PtrToIntI));
-  EXPECT_EQ(PtrToInt->getOpcode(), sandboxir::Instruction::Opcode::PtrToInt);
-  EXPECT_EQ(PtrToInt->getSrcTy(), Tptr);
-  EXPECT_EQ(PtrToInt->getDestTy(), Ti32);
-
-  auto *IntToPtr = cast<sandboxir::CastInst>(&*It++);
-  auto *IntToPtrI = cast<sandboxir::IntToPtrInst>(IntToPtr);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtr));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(IntToPtrI));
-  EXPECT_EQ(IntToPtr->getOpcode(), sandboxir::Instruction::Opcode::IntToPtr);
-  EXPECT_EQ(IntToPtr->getSrcTy(), Ti32);
-  EXPECT_EQ(IntToPtr->getDestTy(), Tptr);
-
-  auto *SIToFP = cast<sandboxir::CastInst>(&*It++);
-  auto *SIToFPI = cast<sandboxir::SIToFPInst>(SIToFP);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFP));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(SIToFPI));
-  EXPECT_EQ(SIToFP->getOpcode(), sandboxir::Instruction::Opcode::SIToFP);
-  EXPECT_EQ(SIToFP->getSrcTy(), Ti32);
-  EXPECT_EQ(SIToFP->getDestTy(), Tfloat);
-
-  auto *UIToFP = cast<sandboxir::CastInst>(&*It++);
-  auto *UIToFPI = cast<sandboxir::UIToFPInst>(UIToFP);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFP));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(UIToFPI));
-  EXPECT_EQ(UIToFP->getOpcode(), sandboxir::Instruction::Opcode::UIToFP);
-  EXPECT_EQ(UIToFP->getSrcTy(), Ti32);
-  EXPECT_EQ(UIToFP->getDestTy(), Tfloat);
-
-  auto *Trunc = cast<sandboxir::CastInst>(&*It++);
-  auto *TruncI = cast<sandboxir::TruncInst>(Trunc);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(Trunc));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(TruncI));
-  EXPECT_EQ(Trunc->getOpcode(), sandboxir::Instruction::Opcode::Trunc);
-  EXPECT_EQ(Trunc->getSrcTy(), Ti32);
-  EXPECT_EQ(Trunc->getDestTy(), Ti16);
-
-  auto *FPTrunc = cast<sandboxir::CastInst>(&*It++);
-  auto *FPTruncI = cast<sandboxir::FPTruncInst>(FPTrunc);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTrunc));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(FPTruncI));
-  EXPECT_EQ(FPTrunc->getOpcode(), sandboxir::Instruction::Opcode::FPTrunc);
-  EXPECT_EQ(FPTrunc->getSrcTy(), Tdouble);
-  EXPECT_EQ(FPTrunc->getDestTy(), Tfloat);
-
-  auto *BitCast = cast<sandboxir::CastInst>(&*It++);
-  auto *BitCastI = cast<sandboxir::BitCastInst>(BitCast);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCast));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(BitCastI));
-  EXPECT_EQ(BitCast->getOpcode(), sandboxir::Instruction::Opcode::BitCast);
-  EXPECT_EQ(BitCast->getSrcTy(), Ti32);
-  EXPECT_EQ(BitCast->getDestTy(), Tfloat);
-
-  auto *AddrSpaceCast = cast<sandboxir::CastInst>(&*It++);
-  auto *AddrSpaceCastI = cast<sandboxir::AddrSpaceCastInst>(AddrSpaceCast);
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCast));
-  EXPECT_TRUE(isa<sandboxir::UnaryInstruction>(AddrSpaceCastI));
-  EXPECT_EQ(AddrSpaceCast->getOpcode(),
-            sandboxir::Instruction::Opcode::AddrSpaceCast);
-  EXPECT_EQ(AddrSpaceCast->getSrcTy(), Tptr);
-  EXPECT_EQ(AddrSpaceCast->getDestTy(), Tptr1);
-
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  {
-    // Check create() WhereIt, WhereBB
-    auto *NewI = cast<sandboxir::CastInst>(
-        sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::SExt,
-                                    Arg, BB->end(), Ctx, "SExt"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::SExt);
-    // Check getSrcTy().
-    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
-    // Check getDestTy().
-    EXPECT_EQ(NewI->getDestTy(), Ti64);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    EXPECT_EQ(NewI->getPrevNode(), Ret);
-  }
-
-  {
-    // Check create() InsertBefore.
-    auto *NewI = cast<sandboxir::CastInst>(
-        sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::ZExt,
-                                    Arg, Ret->getIterator(), Ctx, "ZExt"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
-    // Check getSrcTy().
-    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
-    // Check getDestTy().
-    EXPECT_EQ(NewI->getDestTy(), Ti64);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI = cast<sandboxir::CastInst>(sandboxir::CastInst::create(
-        Ti64, sandboxir::Instruction::Opcode::ZExt, Arg, BB, Ctx, "ZExt"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), sandboxir::Instruction::Opcode::ZExt);
-    // Check getSrcTy().
-    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
-    // Check getDestTy().
-    EXPECT_EQ(NewI->getDestTy(), Ti64);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    EXPECT_EQ(NewI->getParent(), BB);
-  }
-
-  {
-#ifndef NDEBUG
-    // Check that passing a non-cast opcode crashes.
-    EXPECT_DEATH(
-        sandboxir::CastInst::create(Ti64, sandboxir::Instruction::Opcode::Store,
-                                    Arg, Ret->getIterator(), Ctx, "Bad"),
-        ".*Opcode.*");
-#endif // NDEBUG
-  }
-}
-
-TEST_F(SandboxIRTest, PossiblyNonNegInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg, float %farg, double %darg, ptr %ptr) {
-  %zext = zext i32 %arg to i64
-  %uitofp = uitofp i32 %arg to float
-
-  %sext = sext i32 %arg to i64
-  %fptoui = fptoui float %farg to i32
-  %fptosi = fptosi float %farg to i32
-  %fpext = fpext float %farg to double
-  %ptrtoint = ptrtoint ptr %ptr to i32
-  %inttoptr = inttoptr i32 %arg to ptr
-  %sitofp = sitofp i32 %arg to float
-  %trunc = trunc i32 %arg to i16
-  %fptrunc = fptrunc double %darg to float
-  %bitcast = bitcast i32 %arg to float
-  %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *PNNI0 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
-  auto *PNNI1 = cast<sandboxir::PossiblyNonNegInst>(&*It++);
-  for (auto ItE = BB->end(); It != ItE; ++It)
-    EXPECT_FALSE(isa<sandboxir::PossiblyNonNegInst>(&*It++));
-
-  for (auto *PNNI : {PNNI0, PNNI1}) {
-    // Check setNonNeg(), hasNonNeg().
-    auto OrigNonNeg = PNNI->hasNonNeg();
-    auto NewNonNeg = true;
-    EXPECT_NE(NewNonNeg, OrigNonNeg);
-    PNNI->setNonNeg(NewNonNeg);
-    EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg);
-    PNNI->setNonNeg(OrigNonNeg);
-    EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg);
-  }
-}
-
-/// CastInst's subclasses are very similar so we can use a common test function
-/// for them.
-template <typename SubclassT, sandboxir::Instruction::Opcode OpcodeT>
-void testCastInst(llvm::Module &M, llvm::Type *LLVMSrcTy,
-                  llvm::Type *LLVMDstTy) {
-  Function &LLVMF = *M.getFunction("foo");
-  sandboxir::Context Ctx(M.getContext());
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  sandboxir::Type *SrcTy = Ctx.getType(LLVMSrcTy);
-  sandboxir::Type *DstTy = Ctx.getType(LLVMDstTy);
-  unsigned ArgIdx = 0;
-  auto *Arg = F->getArg(ArgIdx++);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-
-  auto *CI = cast<SubclassT>(&*It++);
-  EXPECT_EQ(CI->getOpcode(), OpcodeT);
-  EXPECT_EQ(CI->getSrcTy(), SrcTy);
-  EXPECT_EQ(CI->getDestTy(), DstTy);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  {
-    // Check create() WhereIt, WhereBB
-    auto *NewI =
-        cast<SubclassT>(SubclassT::create(Arg, DstTy, BB->end(), Ctx, "NewCI"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), OpcodeT);
-    // Check getSrcTy().
-    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
-    // Check getDestTy().
-    EXPECT_EQ(NewI->getDestTy(), DstTy);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    EXPECT_EQ(NewI->getPrevNode(), Ret);
-    // Check instr name.
-    EXPECT_EQ(NewI->getName(), "NewCI");
-  }
-  {
-    // Check create() InsertBefore.
-    auto *NewI = cast<SubclassT>(
-        SubclassT::create(Arg, DstTy, Ret->getIterator(), Ctx, "NewCI"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), OpcodeT);
-    // Check getSrcTy().
-    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
-    // Check getDestTy().
-    EXPECT_EQ(NewI->getDestTy(), DstTy);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), Ret);
-  }
-  {
-    // Check create() InsertAtEnd.
-    auto *NewI =
-        cast<SubclassT>(SubclassT::create(Arg, DstTy,
-                                          /*InsertAtEnd=*/BB, Ctx, "NewCI"));
-    // Check getOpcode().
-    EXPECT_EQ(NewI->getOpcode(), OpcodeT);
-    // Check getSrcTy().
-    EXPECT_EQ(NewI->getSrcTy(), Arg->getType());
-    // Check getDestTy().
-    EXPECT_EQ(NewI->getDestTy(), DstTy);
-    // Check instr position.
-    EXPECT_EQ(NewI->getNextNode(), nullptr);
-    EXPECT_EQ(NewI->getParent(), BB);
-  }
-}
-
-TEST_F(SandboxIRTest, TruncInst) {
-  parseIR(C, R"IR(
-define void @foo(i64 %arg) {
-  %trunc = trunc i64 %arg to i32
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::TruncInst, sandboxir::Instruction::Opcode::Trunc>(
-      *M,
-      /*SrcTy=*/Type::getInt64Ty(C), /*DstTy=*/Type::getInt32Ty(C));
-}
-
-TEST_F(SandboxIRTest, ZExtInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %zext = zext i32 %arg to i64
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::ZExtInst, sandboxir::Instruction::Opcode::ZExt>(
-      *M,
-      /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C));
-}
-
-TEST_F(SandboxIRTest, SExtInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %sext = sext i32 %arg to i64
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::SExtInst, sandboxir::Instruction::Opcode::SExt>(
-      *M,
-      /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getInt64Ty(C));
-}
-
-TEST_F(SandboxIRTest, FPTruncInst) {
-  parseIR(C, R"IR(
-define void @foo(double %arg) {
-  %fptrunc = fptrunc double %arg to float
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::FPTruncInst, sandboxir::Instruction::Opcode::FPTrunc>(
-      *M,
-      /*SrcTy=*/Type::getDoubleTy(C), /*DstTy=*/Type::getFloatTy(C));
-}
-
-TEST_F(SandboxIRTest, FPExtInst) {
-  parseIR(C, R"IR(
-define void @foo(float %arg) {
-  %fpext = fpext float %arg to double
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::FPExtInst, sandboxir::Instruction::Opcode::FPExt>(
-      *M,
-      /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getDoubleTy(C));
-}
-
-TEST_F(SandboxIRTest, UIToFPInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %uitofp = uitofp i32 %arg to float
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::UIToFPInst, sandboxir::Instruction::Opcode::UIToFP>(
-      *M,
-      /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C));
-}
-
-TEST_F(SandboxIRTest, SIToFPInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %sitofp = sitofp i32 %arg to float
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::SIToFPInst, sandboxir::Instruction::Opcode::SIToFP>(
-      *M,
-      /*SrcTy=*/Type::getInt32Ty(C),
-      /*DstTy=*/Type::getFloatTy(C));
-}
-
-TEST_F(SandboxIRTest, FPToUIInst) {
-  parseIR(C, R"IR(
-define void @foo(float %arg) {
-  %fptoui = fptoui float %arg to i32
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::FPToUIInst, sandboxir::Instruction::Opcode::FPToUI>(
-
-      *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C));
-}
-
-TEST_F(SandboxIRTest, FPToSIInst) {
-  parseIR(C, R"IR(
-define void @foo(float %arg) {
-  %fptosi = fptosi float %arg to i32
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::FPToSIInst, sandboxir::Instruction::Opcode::FPToSI>(
-      *M, /*SrcTy=*/Type::getFloatTy(C), /*DstTy=*/Type::getInt32Ty(C));
-}
-
-TEST_F(SandboxIRTest, IntToPtrInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %inttoptr = inttoptr i32 %arg to ptr
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::IntToPtrInst,
-               sandboxir::Instruction::Opcode::IntToPtr>(
-      *M,
-      /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/PointerType::get(C, 0));
-}
-
-TEST_F(SandboxIRTest, PtrToIntInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %ptrtoint = ptrtoint ptr %ptr to i32
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::PtrToIntInst,
-               sandboxir::Instruction::Opcode::PtrToInt>(
-      *M, /*SrcTy=*/PointerType::get(C, 0), /*DstTy=*/Type::getInt32Ty(C));
-}
-
-TEST_F(SandboxIRTest, BitCastInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %bitcast = bitcast i32 %arg to float
-  ret void
-}
-)IR");
-  testCastInst<sandboxir::BitCastInst, sandboxir::Instruction::Opcode::BitCast>(
-      *M,
-      /*SrcTy=*/Type::getInt32Ty(C), /*DstTy=*/Type::getFloatTy(C));
-}
-
-TEST_F(SandboxIRTest, AddrSpaceCastInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %addrspacecast = addrspacecast ptr %ptr to ptr addrspace(1)
-  ret void
-}
-)IR");
-  Type *Tptr0 = PointerType::get(C, 0);
-  Type *Tptr1 = PointerType::get(C, 1);
-  testCastInst<sandboxir::AddrSpaceCastInst,
-               sandboxir::Instruction::Opcode::AddrSpaceCast>(*M,
-                                                              /*SrcTy=*/Tptr0,
-                                                              /*DstTy=*/Tptr1);
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  unsigned ArgIdx = 0;
-  auto *Arg = F->getArg(ArgIdx++);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-
-  auto *AddrSpaceCast = cast<sandboxir::AddrSpaceCastInst>(&*It++);
-  EXPECT_EQ(AddrSpaceCast->getOpcode(),
-            sandboxir::Instruction::Opcode::AddrSpaceCast);
-  EXPECT_EQ(AddrSpaceCast->getPointerOperand(), Arg);
-  EXPECT_EQ(sandboxir::AddrSpaceCastInst::getPointerOperandIndex(), 0u);
-  EXPECT_EQ(AddrSpaceCast->getSrcAddressSpace(),
-            cast<PointerType>(Tptr0)->getPointerAddressSpace());
-  EXPECT_EQ(AddrSpaceCast->getDestAddressSpace(),
-            cast<PointerType>(Tptr1)->getPointerAddressSpace());
-}
-
-TEST_F(SandboxIRTest, PHINode) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-bb1:
-  br label %bb2
-
-bb2:
-  %phi = phi i32 [ %arg, %bb1 ], [ 0, %bb2 ], [ 1, %bb3 ], [ 2, %bb4 ], [ 3, %bb5 ]
-  br label %bb2
-
-bb3:
-  br label %bb2
-
-bb4:
-  br label %bb2
-
-bb5:
-  br label %bb2
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
-  auto *LLVMBB2 = getBasicBlockByName(LLVMF, "bb2");
-  auto *LLVMBB3 = getBasicBlockByName(LLVMF, "bb3");
-  auto LLVMIt = LLVMBB2->begin();
-  auto *LLVMPHI = cast<llvm::PHINode>(&*LLVMIt++);
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&LLVMF);
-  auto *Arg = F->getArg(0);
-  auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
-  auto *BB2 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB2));
-  auto *BB3 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB3));
-  auto It = BB2->begin();
-  // Check classof().
-  auto *PHI = cast<sandboxir::PHINode>(&*It++);
-  auto *Br = cast<sandboxir::BranchInst>(&*It++);
-  // Check blocks().
-  EXPECT_EQ(range_size(PHI->blocks()), range_size(LLVMPHI->blocks()));
-  auto BlockIt = PHI->block_begin();
-  for (llvm::BasicBlock *LLVMBB : LLVMPHI->blocks()) {
-    sandboxir::BasicBlock *BB = *BlockIt++;
-    EXPECT_EQ(BB, Ctx.getValue(LLVMBB));
-  }
-  // Check incoming_values().
-  EXPECT_EQ(range_size(PHI->incoming_values()),
-            range_size(LLVMPHI->incoming_values()));
-  auto IncIt = PHI->incoming_values().begin();
-  for (llvm::Value *LLVMV : LLVMPHI->incoming_values()) {
-    sandboxir::Value *IncV = *IncIt++;
-    EXPECT_EQ(IncV, Ctx.getValue(LLVMV));
-  }
-  // Check getNumIncomingValues().
-  EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues());
-  // Check getIncomingValue().
-  EXPECT_EQ(PHI->getIncomingValue(0),
-            Ctx.getValue(LLVMPHI->getIncomingValue(0)));
-  EXPECT_EQ(PHI->getIncomingValue(1),
-            Ctx.getValue(LLVMPHI->getIncomingValue(1)));
-  // Check setIncomingValue().
-  auto *OrigV = PHI->getIncomingValue(0);
-  PHI->setIncomingValue(0, PHI);
-  EXPECT_EQ(PHI->getIncomingValue(0), PHI);
-  PHI->setIncomingValue(0, OrigV);
-  // Check getOperandNumForIncomingValue().
-  EXPECT_EQ(sandboxir::PHINode::getOperandNumForIncomingValue(0),
-            llvm::PHINode::getOperandNumForIncomingValue(0));
-  // Check getIncomingValueNumForOperand().
-  EXPECT_EQ(sandboxir::PHINode::getIncomingValueNumForOperand(0),
-            llvm::PHINode::getIncomingValueNumForOperand(0));
-  // Check getIncomingBlock(unsigned).
-  EXPECT_EQ(PHI->getIncomingBlock(0),
-            Ctx.getValue(LLVMPHI->getIncomingBlock(0)));
-  // Check getIncomingBlock(Use).
-  llvm::Use &LLVMUse = LLVMPHI->getOperandUse(0);
-  sandboxir::Use Use = PHI->getOperandUse(0);
-  EXPECT_EQ(PHI->getIncomingBlock(Use),
-            Ctx.getValue(LLVMPHI->getIncomingBlock(LLVMUse)));
-  // Check setIncomingBlock().
-  sandboxir::BasicBlock *OrigBB = PHI->getIncomingBlock(0);
-  EXPECT_NE(OrigBB, BB2);
-  PHI->setIncomingBlock(0, BB2);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB2);
-  PHI->setIncomingBlock(0, OrigBB);
-  EXPECT_EQ(PHI->getIncomingBlock(0), OrigBB);
-  // Check addIncoming().
-  unsigned OrigNumIncoming = PHI->getNumIncomingValues();
-  PHI->addIncoming(Arg, BB3);
-  EXPECT_EQ(PHI->getNumIncomingValues(), LLVMPHI->getNumIncomingValues());
-  EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming + 1);
-  EXPECT_EQ(PHI->getIncomingValue(OrigNumIncoming), Arg);
-  EXPECT_EQ(PHI->getIncomingBlock(OrigNumIncoming), BB3);
-  // Check removeIncomingValue(unsigned).
-  PHI->removeIncomingValue(OrigNumIncoming);
-  EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming);
-  // Check removeIncomingValue(BasicBlock *).
-  PHI->addIncoming(Arg, BB3);
-  PHI->removeIncomingValue(BB3);
-  EXPECT_EQ(PHI->getNumIncomingValues(), OrigNumIncoming);
-  // Check getBasicBlockIndex().
-  EXPECT_EQ(PHI->getBasicBlockIndex(BB1), LLVMPHI->getBasicBlockIndex(LLVMBB1));
-  // Check getIncomingValueForBlock().
-  EXPECT_EQ(PHI->getIncomingValueForBlock(BB1),
-            Ctx.getValue(LLVMPHI->getIncomingValueForBlock(LLVMBB1)));
-  // Check hasConstantValue().
-  llvm::Value *ConstV = LLVMPHI->hasConstantValue();
-  EXPECT_EQ(PHI->hasConstantValue(),
-            ConstV != nullptr ? Ctx.getValue(ConstV) : nullptr);
-  // Check hasConstantOrUndefValue().
-  EXPECT_EQ(PHI->hasConstantOrUndefValue(), LLVMPHI->hasConstantOrUndefValue());
-  // Check isComplete().
-  EXPECT_EQ(PHI->isComplete(), LLVMPHI->isComplete());
-  // Check replaceIncomingValueIf
-  EXPECT_EQ(PHI->getNumIncomingValues(), 5u);
-  auto *RemainBB0 = PHI->getIncomingBlock(0);
-  auto *RemoveBB0 = PHI->getIncomingBlock(1);
-  auto *RemainBB1 = PHI->getIncomingBlock(2);
-  auto *RemoveBB1 = PHI->getIncomingBlock(3);
-  auto *RemainBB2 = PHI->getIncomingBlock(4);
-  PHI->removeIncomingValueIf([&](unsigned Idx) {
-    return PHI->getIncomingBlock(Idx) == RemoveBB0 ||
-           PHI->getIncomingBlock(Idx) == RemoveBB1;
-  });
-  EXPECT_EQ(PHI->getNumIncomingValues(), 3u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), RemainBB0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
-  EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
-  // Check replaceIncomingBlockWith
-  OrigBB = RemainBB0;
-  auto *NewBB = RemainBB1;
-  EXPECT_NE(NewBB, OrigBB);
-  PHI->replaceIncomingBlockWith(OrigBB, NewBB);
-  EXPECT_EQ(PHI->getIncomingBlock(0), NewBB);
-  EXPECT_EQ(PHI->getIncomingBlock(1), RemainBB1);
-  EXPECT_EQ(PHI->getIncomingBlock(2), RemainBB2);
-  // Check create().
-  auto *NewPHI = cast<sandboxir::PHINode>(sandboxir::PHINode::create(
-      PHI->getType(), 0, Br->getIterator(), Ctx, "NewPHI"));
-  EXPECT_EQ(NewPHI->getType(), PHI->getType());
-  EXPECT_EQ(NewPHI->getNextNode(), Br);
-  EXPECT_EQ(NewPHI->getName(), "NewPHI");
-  EXPECT_EQ(NewPHI->getNumIncomingValues(), 0u);
-  for (auto [Idx, V] : enumerate(PHI->incoming_values())) {
-    sandboxir::BasicBlock *IncBB = PHI->getIncomingBlock(Idx);
-    NewPHI->addIncoming(V, IncBB);
-  }
-  EXPECT_EQ(NewPHI->getNumIncomingValues(), PHI->getNumIncomingValues());
-}
-
-static void checkSwapOperands(sandboxir::Context &Ctx,
-                              llvm::sandboxir::CmpInst *Cmp,
-                              llvm::CmpInst *LLVMCmp) {
-  auto OrigOp0 = Cmp->getOperand(0);
-  auto OrigOp1 = Cmp->getOperand(1);
-  EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp0);
-  EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp1);
-  // This checks the dispatch mechanism in CmpInst, as well as
-  // the specific implementations.
-  Cmp->swapOperands();
-  EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(1)), OrigOp0);
-  EXPECT_EQ(Ctx.getValue(LLVMCmp->getOperand(0)), OrigOp1);
-  EXPECT_EQ(Cmp->getOperand(0), OrigOp1);
-  EXPECT_EQ(Cmp->getOperand(1), OrigOp0);
-  // Undo it to keep the rest of the test consistent
-  Cmp->swapOperands();
-}
-
-static void checkCommonPredicates(sandboxir::CmpInst *Cmp,
-                                  llvm::CmpInst *LLVMCmp) {
-  // Check proper creation
-  auto Pred = Cmp->getPredicate();
-  auto LLVMPred = LLVMCmp->getPredicate();
-  EXPECT_EQ(Pred, LLVMPred);
-  // Check setPredicate
-  Cmp->setPredicate(llvm::CmpInst::FCMP_FALSE);
-  EXPECT_EQ(Cmp->getPredicate(), llvm::CmpInst::FCMP_FALSE);
-  EXPECT_EQ(LLVMCmp->getPredicate(), llvm::CmpInst::FCMP_FALSE);
-  Cmp->setPredicate(Pred);
-  EXPECT_EQ(LLVMCmp->getPredicate(), Pred);
-  // Ensure the accessors properly forward to the underlying implementation
-  EXPECT_STREQ(sandboxir::CmpInst::getPredicateName(Pred).data(),
-               llvm::CmpInst::getPredicateName(LLVMPred).data());
-  EXPECT_EQ(Cmp->isFPPredicate(), LLVMCmp->isFPPredicate());
-  EXPECT_EQ(Cmp->isIntPredicate(), LLVMCmp->isIntPredicate());
-  EXPECT_EQ(Cmp->getInversePredicate(), LLVMCmp->getInversePredicate());
-  EXPECT_EQ(Cmp->getOrderedPredicate(), LLVMCmp->getOrderedPredicate());
-  EXPECT_EQ(Cmp->getUnorderedPredicate(), LLVMCmp->getUnorderedPredicate());
-  EXPECT_EQ(Cmp->getSwappedPredicate(), LLVMCmp->getSwappedPredicate());
-  EXPECT_EQ(Cmp->isStrictPredicate(), LLVMCmp->isStrictPredicate());
-  EXPECT_EQ(Cmp->isNonStrictPredicate(), LLVMCmp->isNonStrictPredicate());
-  EXPECT_EQ(Cmp->isRelational(), LLVMCmp->isRelational());
-  if (Cmp->isRelational()) {
-    EXPECT_EQ(Cmp->getFlippedStrictnessPredicate(),
-              LLVMCmp->getFlippedStrictnessPredicate());
-  }
-  EXPECT_EQ(Cmp->isCommutative(), LLVMCmp->isCommutative());
-  EXPECT_EQ(Cmp->isTrueWhenEqual(), LLVMCmp->isTrueWhenEqual());
-  EXPECT_EQ(Cmp->isFalseWhenEqual(), LLVMCmp->isFalseWhenEqual());
-  EXPECT_EQ(sandboxir::CmpInst::isOrdered(Pred),
-            llvm::CmpInst::isOrdered(LLVMPred));
-  EXPECT_EQ(sandboxir::CmpInst::isUnordered(Pred),
-            llvm::CmpInst::isUnordered(LLVMPred));
-}
-
-TEST_F(SandboxIRTest, ICmpInst) {
-  SCOPED_TRACE("SandboxIRTest sandboxir::ICmpInst tests");
-  parseIR(C, R"IR(
-define void @foo(i32 %i0, i32 %i1) {
- bb:
-  %ine  = icmp ne i32 %i0, %i1
-  %iugt = icmp ugt i32 %i0, %i1
-  %iuge = icmp uge i32 %i0, %i1
-  %iult = icmp ult i32 %i0, %i1
-  %iule = icmp ule i32 %i0, %i1
-  %isgt = icmp sgt i32 %i0, %i1
-  %isle = icmp sle i32 %i0, %i1
-  %ieg  = icmp eq i32 %i0, %i1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-
-  auto *LLVMBB = getBasicBlockByName(LLVMF, "bb");
-  auto LLVMIt = LLVMBB->begin();
-  auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
-  auto It = BB->begin();
-  // Check classof()
-  while (auto *ICmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) {
-    auto *LLVMICmp = cast<llvm::ICmpInst>(&*LLVMIt++);
-    checkSwapOperands(Ctx, ICmp, LLVMICmp);
-    checkCommonPredicates(ICmp, LLVMICmp);
-    EXPECT_EQ(ICmp->isSigned(), LLVMICmp->isSigned());
-    EXPECT_EQ(ICmp->isUnsigned(), LLVMICmp->isUnsigned());
-    EXPECT_EQ(ICmp->getSignedPredicate(), LLVMICmp->getSignedPredicate());
-    EXPECT_EQ(ICmp->getUnsignedPredicate(), LLVMICmp->getUnsignedPredicate());
-  }
-  auto *NewCmp = cast<sandboxir::CmpInst>(
-      sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, F.getArg(0),
-                                 F.getArg(1), BB->begin(), Ctx, "NewCmp"));
-  EXPECT_EQ(NewCmp, &*BB->begin());
-  EXPECT_EQ(NewCmp->getPredicate(), llvm::CmpInst::ICMP_ULE);
-  EXPECT_EQ(NewCmp->getOperand(0), F.getArg(0));
-  EXPECT_EQ(NewCmp->getOperand(1), F.getArg(1));
-#ifndef NDEBUG
-  EXPECT_EQ(NewCmp->getName(), "NewCmp");
-#endif // NDEBUG
-  // TODO: Improve this test when sandboxir::VectorType is more completely
-  // implemented.
-  sandboxir::Type *RT =
-      sandboxir::CmpInst::makeCmpResultType(F.getArg(0)->getType());
-  EXPECT_TRUE(RT->isIntegerTy(1)); // Only one bit in a single comparison
-
-  {
-    // Check create() when operands are constant.
-    auto *Const42 =
-        sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
-    auto *NewConstCmp =
-        sandboxir::CmpInst::create(llvm::CmpInst::ICMP_ULE, Const42, Const42,
-                                   BB->begin(), Ctx, "NewConstCmp");
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewConstCmp));
-  }
-}
-
-TEST_F(SandboxIRTest, FCmpInst) {
-  SCOPED_TRACE("SandboxIRTest sandboxir::FCmpInst tests");
-  parseIR(C, R"IR(
-define void @foo(float %f0, float %f1) {
-bb:
-  %ffalse = fcmp false float %f0, %f1
-  %foeq = fcmp oeq float %f0, %f1
-  %fogt = fcmp ogt float %f0, %f1
-  %folt = fcmp olt float %f0, %f1
-  %fole = fcmp ole float %f0, %f1
-  %fone = fcmp one float %f0, %f1
-  %ford = fcmp ord float %f0, %f1
-  %funo = fcmp uno float %f0, %f1
-  %fueq = fcmp ueq float %f0, %f1
-  %fugt = fcmp ugt float %f0, %f1
-  %fuge = fcmp uge float %f0, %f1
-  %fult = fcmp ult float %f0, %f1
-  %fule = fcmp ule float %f0, %f1
-  %fune = fcmp une float %f0, %f1
-  %ftrue = fcmp true float %f0, %f1
-  ret void
-bb1:
-  %copyfrom = fadd reassoc float %f0, 42.0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-
-  auto *LLVMBB = getBasicBlockByName(LLVMF, "bb");
-  auto LLVMIt = LLVMBB->begin();
-  auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
-  auto It = BB->begin();
-  // Check classof()
-  while (auto *FCmp = dyn_cast<sandboxir::ICmpInst>(&*It++)) {
-    auto *LLVMFCmp = cast<llvm::ICmpInst>(&*LLVMIt++);
-    checkSwapOperands(Ctx, FCmp, LLVMFCmp);
-    checkCommonPredicates(FCmp, LLVMFCmp);
-  }
-
-  auto *LLVMBB1 = getBasicBlockByName(LLVMF, "bb1");
-  auto *BB1 = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB1));
-  auto It1 = BB1->begin();
-  auto *CopyFrom = &*It1++;
-  CopyFrom->setFastMathFlags(FastMathFlags::getFast());
-
-  // create with default flags
-  auto *NewFCmp = cast<sandboxir::CmpInst>(sandboxir::CmpInst::create(
-      llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), It1, Ctx, "NewFCmp"));
-  EXPECT_EQ(NewFCmp->getPredicate(), llvm::CmpInst::FCMP_ONE);
-  EXPECT_EQ(NewFCmp->getOperand(0), F.getArg(0));
-  EXPECT_EQ(NewFCmp->getOperand(1), F.getArg(1));
-#ifndef NDEBUG
-  EXPECT_EQ(NewFCmp->getName(), "NewFCmp");
-#endif // NDEBUG
-  FastMathFlags DefaultFMF = NewFCmp->getFastMathFlags();
-  EXPECT_TRUE(CopyFrom->getFastMathFlags() != DefaultFMF);
-  // create with copied flags
-  auto *NewFCmpFlags =
-      cast<sandboxir::CmpInst>(sandboxir::CmpInst::createWithCopiedFlags(
-          llvm::CmpInst::FCMP_ONE, F.getArg(0), F.getArg(1), CopyFrom, It1, Ctx,
-          "NewFCmpFlags"));
-  EXPECT_FALSE(NewFCmpFlags->getFastMathFlags() !=
-               CopyFrom->getFastMathFlags());
-  EXPECT_EQ(NewFCmpFlags->getPredicate(), llvm::CmpInst::FCMP_ONE);
-  EXPECT_EQ(NewFCmpFlags->getOperand(0), F.getArg(0));
-  EXPECT_EQ(NewFCmpFlags->getOperand(1), F.getArg(1));
-#ifndef NDEBUG
-  EXPECT_EQ(NewFCmpFlags->getName(), "NewFCmpFlags");
-#endif // NDEBUG
-
-  {
-    // Check create() when operands are constant.
-    auto *Const42 =
-        sandboxir::ConstantFP::get(sandboxir::Type::getFloatTy(Ctx), 42.0);
-    auto *NewConstCmp =
-        sandboxir::CmpInst::create(llvm::CmpInst::FCMP_ULE, Const42, Const42,
-                                   BB->begin(), Ctx, "NewConstCmp");
-    EXPECT_TRUE(isa<sandboxir::Constant>(NewConstCmp));
-  }
-}
-
-TEST_F(SandboxIRTest, UnreachableInst) {
-  parseIR(C, R"IR(
-define void @foo() {
-  unreachable
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *UI = cast<sandboxir::UnreachableInst>(&*It++);
-
-  EXPECT_EQ(UI->getNumSuccessors(), 0u);
-  EXPECT_EQ(UI->getNumOfIRInstrs(), 1u);
-  // Check create(InsertBefore)
-  sandboxir::UnreachableInst *NewUI =
-      sandboxir::UnreachableInst::create(UI->getIterator(), Ctx);
-  EXPECT_EQ(NewUI->getNextNode(), UI);
-  // Check create(InsertAtEnd)
-  sandboxir::UnreachableInst *NewUIEnd =
-      sandboxir::UnreachableInst::create(/*InsertAtEnd=*/BB, Ctx);
-  EXPECT_EQ(NewUIEnd->getParent(), BB);
-  EXPECT_EQ(NewUIEnd->getNextNode(), nullptr);
-}
-
-/// Makes sure that all Instruction sub-classes have a classof().
-TEST_F(SandboxIRTest, CheckClassof) {
-#define DEF_INSTR(ID, OPC, CLASS)                                              \
-  EXPECT_NE(&sandboxir::CLASS::classof, &sandboxir::Instruction::classof);
-#include "llvm/SandboxIR/Values.def"
-}
-
-TEST_F(SandboxIRTest, InstructionCallbacks) {
-  parseIR(C, R"IR(
-    define void @foo(ptr %ptr, i8 %val) {
-      ret void
-    }
-  )IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  sandboxir::Argument *Ptr = F.getArg(0);
-  sandboxir::Argument *Val = F.getArg(1);
-  sandboxir::Instruction *Ret = &BB.front();
-
-  SmallVector<sandboxir::Instruction *> Inserted;
-  auto InsertCbId = Ctx.registerCreateInstrCallback(
-      [&Inserted](sandboxir::Instruction *I) { Inserted.push_back(I); });
-
-  SmallVector<sandboxir::Instruction *> Removed;
-  auto RemoveCbId = Ctx.registerEraseInstrCallback(
-      [&Removed](sandboxir::Instruction *I) { Removed.push_back(I); });
-
-  // Keep the moved instruction and the instruction pointed by the Where
-  // iterator so we can check both callback arguments work as expected.
-  SmallVector<std::pair<sandboxir::Instruction *, sandboxir::Instruction *>>
-      Moved;
-  auto MoveCbId = Ctx.registerMoveInstrCallback(
-      [&Moved](sandboxir::Instruction *I, const sandboxir::BBIterator &Where) {
-        // Use a nullptr to signal "move to end" to keep it single. We only
-        // have a basic block in this test case anyway.
-        if (Where == Where.getNodeParent()->end())
-          Moved.push_back(std::make_pair(I, nullptr));
-        else
-          Moved.push_back(std::make_pair(I, &*Where));
-      });
-
-  // Two more insertion callbacks, to check that they're called in registration
-  // order.
-  SmallVector<int> Order;
-  auto CheckOrderInsertCbId1 = Ctx.registerCreateInstrCallback(
-      [&Order](sandboxir::Instruction *I) { Order.push_back(1); });
-
-  auto CheckOrderInsertCbId2 = Ctx.registerCreateInstrCallback(
-      [&Order](sandboxir::Instruction *I) { Order.push_back(2); });
-
-  Ctx.save();
-  auto *NewI = sandboxir::StoreInst::create(Val, Ptr, /*Align=*/std::nullopt,
-                                            Ret->getIterator(), Ctx);
-  EXPECT_THAT(Inserted, testing::ElementsAre(NewI));
-  EXPECT_THAT(Removed, testing::IsEmpty());
-  EXPECT_THAT(Moved, testing::IsEmpty());
-  EXPECT_THAT(Order, testing::ElementsAre(1, 2));
-
-  Ret->moveBefore(NewI);
-  EXPECT_THAT(Inserted, testing::ElementsAre(NewI));
-  EXPECT_THAT(Removed, testing::IsEmpty());
-  EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI)));
-
-  Ret->eraseFromParent();
-  EXPECT_THAT(Inserted, testing::ElementsAre(NewI));
-  EXPECT_THAT(Removed, testing::ElementsAre(Ret));
-  EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI)));
-
-  NewI->eraseFromParent();
-  EXPECT_THAT(Inserted, testing::ElementsAre(NewI));
-  EXPECT_THAT(Removed, testing::ElementsAre(Ret, NewI));
-  EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI)));
-
-  // Check that after revert the callbacks have been called for the inverse
-  // operations of the changes made so far.
-  Ctx.revert();
-  EXPECT_THAT(Inserted, testing::ElementsAre(NewI, NewI, Ret));
-  EXPECT_THAT(Removed, testing::ElementsAre(Ret, NewI, NewI));
-  EXPECT_THAT(Moved, testing::ElementsAre(std::make_pair(Ret, NewI),
-                                          std::make_pair(Ret, nullptr)));
-  EXPECT_THAT(Order, testing::ElementsAre(1, 2, 1, 2, 1, 2));
-
-  // Check that deregistration works. Do an operation of each type after
-  // deregistering callbacks and check.
-  Inserted.clear();
-  Removed.clear();
-  Moved.clear();
-  Ctx.unregisterCreateInstrCallback(InsertCbId);
-  Ctx.unregisterEraseInstrCallback(RemoveCbId);
-  Ctx.unregisterMoveInstrCallback(MoveCbId);
-  Ctx.unregisterCreateInstrCallback(CheckOrderInsertCbId1);
-  Ctx.unregisterCreateInstrCallback(CheckOrderInsertCbId2);
-  auto *NewI2 = sandboxir::StoreInst::create(Val, Ptr, /*Align=*/std::nullopt,
-                                             Ret->getIterator(), Ctx);
-  Ret->moveBefore(NewI2);
-  Ret->eraseFromParent();
-  EXPECT_THAT(Inserted, testing::IsEmpty());
-  EXPECT_THAT(Removed, testing::IsEmpty());
-  EXPECT_THAT(Moved, testing::IsEmpty());
-}
-
-// Check callbacks when we set a Use.
-TEST_F(SandboxIRTest, SetUseCallbacks) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0, i8 %v1) {
-  %add0 = add i8 %v0, %v1
-  %add1 = add i8 %add0, %v1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *Arg0 = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-
-  SmallVector<std::pair<sandboxir::Use, sandboxir::Value *>> UsesSet;
-  auto Id = Ctx.registerSetUseCallback(
-      [&UsesSet](sandboxir::Use U, sandboxir::Value *NewSrc) {
-        UsesSet.push_back({U, NewSrc});
-      });
-
-  // Now change %add1 operand to not use %add0.
-  Add1->setOperand(0, Arg0);
-  EXPECT_EQ(UsesSet.size(), 1u);
-  EXPECT_EQ(UsesSet[0].first.get(), Add1->getOperandUse(0).get());
-  EXPECT_EQ(UsesSet[0].second, Arg0);
-  // Restore to previous state.
-  Add1->setOperand(0, Add0);
-  UsesSet.clear();
-
-  // RAUW
-  Add0->replaceAllUsesWith(Arg0);
-  EXPECT_EQ(UsesSet.size(), 1u);
-  EXPECT_EQ(UsesSet[0].first.get(), Add1->getOperandUse(0).get());
-  EXPECT_EQ(UsesSet[0].second, Arg0);
-  // Restore to previous state.
-  Add1->setOperand(0, Add0);
-  UsesSet.clear();
-
-  // RUWIf
-  Add0->replaceUsesWithIf(Arg0, [](const auto &U) { return true; });
-  EXPECT_EQ(UsesSet.size(), 1u);
-  EXPECT_EQ(UsesSet[0].first.get(), Add1->getOperandUse(0).get());
-  EXPECT_EQ(UsesSet[0].second, Arg0);
-  // Restore to previous state.
-  Add1->setOperand(0, Add0);
-  UsesSet.clear();
-
-  // RUOW
-  Add1->replaceUsesOfWith(Add0, Arg0);
-  EXPECT_EQ(UsesSet.size(), 1u);
-  EXPECT_EQ(UsesSet[0].first.get(), Add1->getOperandUse(0).get());
-  EXPECT_EQ(UsesSet[0].second, Arg0);
-  // Restore to previous state.
-  Add1->setOperand(0, Add0);
-  UsesSet.clear();
-
-  // Check unregister.
-  Ctx.unregisterSetUseCallback(Id);
-  Add0->replaceAllUsesWith(Arg0);
-  EXPECT_TRUE(UsesSet.empty());
-}
-
-TEST_F(SandboxIRTest, FunctionObjectAlreadyExists) {
-  parseIR(C, R"IR(
-define void @foo() {
-  call void @bar()
-  ret void
-}
-define void @bar() {
-  ret void
-}
-)IR");
-  Function &LLVMFoo = *M->getFunction("foo");
-  Function &LLVMBar = *M->getFunction("bar");
-  sandboxir::Context Ctx(C);
-  // This will create a Function object for @bar().
-  Ctx.createFunction(&LLVMFoo);
-  EXPECT_NE(Ctx.getValue(&LLVMBar), nullptr);
-  // This should not crash, even though there is already a value for LLVMBar.
-  Ctx.createFunction(&LLVMBar);
-}
-
-TEST_F(SandboxIRTest, OpaqueValue) {
-  parseIR(C, R"IR(
-declare void @bar(metadata)
-define void @foo() {
-  call void @bar(metadata !1)
-  call void asm "asm", ""()
-  ret void
-}
-!1 = !{}
-)IR");
-  Function &LLVMFoo = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(&LLVMFoo);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Call = cast<sandboxir::CallInst>(&*It++);
-  auto *Op0 = Call->getOperand(0);
-  EXPECT_TRUE(isa<sandboxir::OpaqueValue>(Op0));
-  auto *Asm = cast<sandboxir::CallInst>(&*It++);
-  auto *AsmOp0 = Asm->getOperand(0);
-  EXPECT_TRUE(isa<sandboxir::OpaqueValue>(AsmOp0));
-}
diff --git a/llvm/unittests/SandboxIR/TrackerTest.cpp b/llvm/unittests/SandboxIR/TrackerTest.cpp
deleted file mode 100644
index 9c18247b6b96d..0000000000000
--- a/llvm/unittests/SandboxIR/TrackerTest.cpp
+++ /dev/null
@@ -1,1920 +0,0 @@
-//===- TrackerTest.cpp ----------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock-matchers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct TrackerTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("TrackerTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-TEST_F(TrackerTest, SetOperand) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr float, ptr %ptr, i32 0
-  %gep1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %gep0
-  store float undef, ptr %gep0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto &Tracker = Ctx.getTracker();
-  // Check empty().
-  EXPECT_TRUE(Ctx.getTracker().empty());
-
-  Tracker.save();
-  auto It = BB->begin();
-  auto *Gep0 = &*It++;
-  auto *Gep1 = &*It++;
-  auto *Ld = &*It++;
-  auto *St = &*It++;
-  St->setOperand(0, Ld);
-  St->setOperand(1, Gep1);
-  Ld->setOperand(0, Gep1);
-  EXPECT_EQ(St->getOperand(0), Ld);
-  EXPECT_EQ(St->getOperand(1), Gep1);
-  EXPECT_EQ(Ld->getOperand(0), Gep1);
-
-  // Check empty().
-  EXPECT_FALSE(Ctx.getTracker().empty());
-
-  Ctx.getTracker().revert();
-  EXPECT_NE(St->getOperand(0), Ld);
-  EXPECT_EQ(St->getOperand(1), Gep0);
-  EXPECT_EQ(Ld->getOperand(0), Gep0);
-}
-
-TEST_F(TrackerTest, SetUse) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %arg) {
-  %ld = load i8, ptr %ptr
-  %add = add i8 %ld, %arg
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(&LLVMF);
-  unsigned ArgIdx = 0;
-  auto *Arg0 = F->getArg(ArgIdx++);
-  auto *BB = &*F->begin();
-  auto &Tracker = Ctx.getTracker();
-  Tracker.save();
-  auto It = BB->begin();
-  auto *Ld = &*It++;
-  auto *Add = &*It++;
-
-  Ctx.save();
-  sandboxir::Use Use = Add->getOperandUse(0);
-  Use.set(Arg0);
-  EXPECT_EQ(Add->getOperand(0), Arg0);
-  Ctx.revert();
-  EXPECT_EQ(Add->getOperand(0), Ld);
-}
-
-TEST_F(TrackerTest, SwapOperands) {
-  parseIR(C, R"IR(
-define void @foo(i1 %cond) {
- bb0:
-   br i1 %cond, label %bb1, label %bb2
- bb1:
-   ret void
- bb2:
-   ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *BB2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
-  auto &Tracker = Ctx.getTracker();
-  Tracker.save();
-  auto It = BB0->begin();
-  auto *Br = cast<sandboxir::BranchInst>(&*It++);
-
-  unsigned SuccIdx = 0;
-  SmallVector<sandboxir::BasicBlock *> ExpectedSuccs({BB2, BB1});
-  for (auto *Succ : Br->successors())
-    EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-
-  // This calls User::swapOperandsInternal() internally.
-  Br->swapSuccessors();
-
-  SuccIdx = 0;
-  for (auto *Succ : reverse(Br->successors()))
-    EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-
-  Ctx.getTracker().revert();
-  SuccIdx = 0;
-  for (auto *Succ : Br->successors())
-    EXPECT_EQ(Succ, ExpectedSuccs[SuccIdx++]);
-}
-
-TEST_F(TrackerTest, RUWIf_RAUW_RUOW) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %ld0 = load float, ptr %ptr
-  %ld1 = load float, ptr %ptr
-  store float %ld0, ptr %ptr
-  store float %ld0, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  llvm::BasicBlock *LLVMBB = &*LLVMF.begin();
-  Ctx.createFunction(&LLVMF);
-  auto *BB = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMBB));
-  auto It = BB->begin();
-  sandboxir::Instruction *Ld0 = &*It++;
-  sandboxir::Instruction *Ld1 = &*It++;
-  sandboxir::Instruction *St0 = &*It++;
-  sandboxir::Instruction *St1 = &*It++;
-  Ctx.save();
-  // Check RUWIf when the lambda returns false.
-  Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return false; });
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-
-  // Check RUWIf when the lambda returns true.
-  Ld0->replaceUsesWithIf(Ld1, [](const sandboxir::Use &Use) { return true; });
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-  EXPECT_EQ(St1->getOperand(0), Ld1);
-  Ctx.revert();
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-
-  // Check RUWIf user == St0.
-  Ctx.save();
-  Ld0->replaceUsesWithIf(
-      Ld1, [St0](const sandboxir::Use &Use) { return Use.getUser() == St0; });
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-  Ctx.revert();
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-
-  // Check RUWIf user == St1.
-  Ctx.save();
-  Ld0->replaceUsesWithIf(
-      Ld1, [St1](const sandboxir::Use &Use) { return Use.getUser() == St1; });
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld1);
-  Ctx.revert();
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-
-  // Check RAUW.
-  Ctx.save();
-  Ld1->replaceAllUsesWith(Ld0);
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-  Ctx.revert();
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-  EXPECT_EQ(St1->getOperand(0), Ld0);
-
-  // Check RUOW.
-  Ctx.save();
-  St0->replaceUsesOfWith(Ld0, Ld1);
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-  Ctx.revert();
-  EXPECT_EQ(St0->getOperand(0), Ld0);
-
-  // Check accept().
-  Ctx.save();
-  St0->replaceUsesOfWith(Ld0, Ld1);
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-  Ctx.accept();
-  EXPECT_EQ(St0->getOperand(0), Ld1);
-}
-
-// TODO: Test multi-instruction patterns.
-TEST_F(TrackerTest, EraseFromParent) {
-  parseIR(C, R"IR(
-define void @foo(i32 %v1) {
-  %add0 = add i32 %v1, %v1
-  %add1 = add i32 %add0, %v1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::Instruction *Add0 = &*It++;
-  sandboxir::Instruction *Add1 = &*It++;
-  sandboxir::Instruction *Ret = &*It++;
-
-  Ctx.save();
-  // Check erase.
-  Add1->eraseFromParent();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  EXPECT_EQ(Add0->getNumUses(), 0u);
-
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  EXPECT_EQ(Add1->getOperand(0), Add0);
-
-  // Same for the last instruction in the block.
-  Ctx.save();
-  Ret->eraseFromParent();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(It, BB->end());
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-}
-
-// TODO: Test multi-instruction patterns.
-TEST_F(TrackerTest, RemoveFromParent) {
-  parseIR(C, R"IR(
-define i32 @foo(i32 %arg) {
-  %add0 = add i32 %arg, %arg
-  %add1 = add i32 %add0, %arg
-  ret i32 %add1
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *Arg = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::Instruction *Add0 = &*It++;
-  sandboxir::Instruction *Add1 = &*It++;
-  sandboxir::Instruction *Ret = &*It++;
-
-  Ctx.save();
-  // Check removeFromParent().
-  Add1->removeFromParent();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Removed instruction still be connected to operands and users.
-  EXPECT_EQ(Add1->getOperand(0), Add0);
-  EXPECT_EQ(Add1->getOperand(1), Arg);
-  EXPECT_EQ(Add0->getNumUses(), 1u);
-
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  EXPECT_EQ(Add1->getOperand(0), Add0);
-
-  // Same for the last instruction in the block.
-  Ctx.save();
-  Ret->removeFromParent();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(It, BB->end());
-  EXPECT_EQ(Ret->getOperand(0), Add1);
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-}
-
-// TODO: Test multi-instruction patterns.
-TEST_F(TrackerTest, MoveInstr) {
-  parseIR(C, R"IR(
-define i32 @foo(i32 %arg) {
-  %add0 = add i32 %arg, %arg
-  %add1 = add i32 %add0, %arg
-  ret i32 %add1
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::Instruction *Add0 = &*It++;
-  sandboxir::Instruction *Add1 = &*It++;
-  sandboxir::Instruction *Ret = &*It++;
-
-  // Check moveBefore(Instruction *) with tracking enabled.
-  Ctx.save();
-  Add1->moveBefore(Add0);
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Same for the last instruction in the block.
-  Ctx.save();
-  Ret->moveBefore(Add0);
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(It, BB->end());
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Check moveBefore(BasicBlock &, BasicBlock::iterator) with tracking enabled.
-  Ctx.save();
-  Add1->moveBefore(*BB, Add0->getIterator());
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Same for the last instruction in the block.
-  Ctx.save();
-  Ret->moveBefore(*BB, Add0->getIterator());
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Check moveAfter(Instruction *) with tracking enabled.
-  Ctx.save();
-  Add0->moveAfter(Add1);
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Same for the last instruction in the block.
-  Ctx.save();
-  Ret->moveAfter(Add0);
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Add1);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-}
-
-// TODO: Test multi-instruction patterns.
-TEST_F(TrackerTest, InsertIntoBB) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %add0 = add i32 %arg, %arg
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::Instruction *Add0 = &*It++;
-  sandboxir::Instruction *Ret = &*It++;
-  // Detach `Add0` before we save.
-  Add0->removeFromParent();
-
-  // Check insertBefore(Instruction *) with tracking enabled.
-  Ctx.save();
-  Add0->insertBefore(Ret);
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Check insertAfter(Instruction *) with tracking enabled.
-  Ctx.save();
-  Add0->insertAfter(Ret);
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // Check insertInto(BasicBlock *, BasicBlock::iterator) with tracking enabled.
-  Ctx.save();
-  Add0->insertInto(BB, Ret->getIterator());
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Add0);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-
-  // To make sure we don't leak memory insert `Add0` back into the BB before the
-  // end of the test.
-  Add0->insertBefore(Ret);
-}
-
-// TODO: Test multi-instruction patterns.
-TEST_F(TrackerTest, CreateAndInsertInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %ld = load i8, ptr %ptr, align 64
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *Ptr = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Ld = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ret = &*It++;
-
-  Ctx.save();
-  // Check create(InsertBefore) with tracking enabled.
-  sandboxir::LoadInst *NewLd = sandboxir::LoadInst::create(
-      Ld->getType(), Ptr, Align(8),
-      /*InsertBefore=*/Ld->getIterator(), Ctx, "NewLd");
-  It = BB->begin();
-  EXPECT_EQ(&*It++, NewLd);
-  EXPECT_EQ(&*It++, Ld);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-  // Check revert().
-  Ctx.revert();
-  It = BB->begin();
-  EXPECT_EQ(&*It++, Ld);
-  EXPECT_EQ(&*It++, Ret);
-  EXPECT_EQ(It, BB->end());
-}
-
-TEST_F(TrackerTest, FenceInstSetters) {
-  parseIR(C, R"IR(
-define void @foo() {
-  fence syncscope("singlethread") seq_cst
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Fence = cast<sandboxir::FenceInst>(&*It++);
-
-  // Check setOrdering().
-  auto OrigOrdering = Fence->getOrdering();
-  auto NewOrdering = AtomicOrdering::Release;
-  EXPECT_NE(NewOrdering, OrigOrdering);
-  Ctx.save();
-  Fence->setOrdering(NewOrdering);
-  EXPECT_EQ(Fence->getOrdering(), NewOrdering);
-  Ctx.revert();
-  EXPECT_EQ(Fence->getOrdering(), OrigOrdering);
-  // Check setSyncScopeID().
-  auto OrigSSID = Fence->getSyncScopeID();
-  auto NewSSID = SyncScope::System;
-  EXPECT_NE(NewSSID, OrigSSID);
-  Ctx.save();
-  Fence->setSyncScopeID(NewSSID);
-  EXPECT_EQ(Fence->getSyncScopeID(), NewSSID);
-  Ctx.revert();
-  EXPECT_EQ(Fence->getSyncScopeID(), OrigSSID);
-}
-
-TEST_F(TrackerTest, CallBaseSetters) {
-  parseIR(C, R"IR(
-declare void @bar1(i8)
-declare void @bar2(i8)
-
-define void @foo(i8 %arg0, i8 %arg1) {
-  call void @bar1(i8 %arg0)
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  unsigned ArgIdx = 0;
-  auto *Arg0 = F->getArg(ArgIdx++);
-  auto *Arg1 = F->getArg(ArgIdx++);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Call = cast<sandboxir::CallBase>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check setArgOperand().
-  Ctx.save();
-  Call->setArgOperand(0, Arg1);
-  EXPECT_EQ(Call->getArgOperand(0), Arg1);
-  Ctx.revert();
-  EXPECT_EQ(Call->getArgOperand(0), Arg0);
-
-  auto *Bar1F = Call->getCalledFunction();
-  auto *Bar2F = Ctx.createFunction(M->getFunction("bar2"));
-
-  // Check setCalledOperand().
-  Ctx.save();
-  Call->setCalledOperand(Bar2F);
-  EXPECT_EQ(Call->getCalledOperand(), Bar2F);
-  Ctx.revert();
-  EXPECT_EQ(Call->getCalledOperand(), Bar1F);
-
-  // Check setCalledFunction().
-  Ctx.save();
-  Call->setCalledFunction(Bar2F);
-  EXPECT_EQ(Call->getCalledFunction(), Bar2F);
-  Ctx.revert();
-  EXPECT_EQ(Call->getCalledFunction(), Bar1F);
-}
-
-TEST_F(TrackerTest, InvokeSetters) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg) {
- bb0:
-   invoke i8 @foo(i8 %arg) to label %normal_bb
-                       unwind label %exception_bb
- normal_bb:
-   ret void
- exception_bb:
-   ret void
- other_bb:
-   ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *NormalBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "normal_bb")));
-  auto *ExceptionBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "exception_bb")));
-  auto *OtherBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
-  auto It = BB0->begin();
-  auto *Invoke = cast<sandboxir::InvokeInst>(&*It++);
-
-  // Check setNormalDest().
-  Ctx.save();
-  Invoke->setNormalDest(OtherBB);
-  EXPECT_EQ(Invoke->getNormalDest(), OtherBB);
-  Ctx.revert();
-  EXPECT_EQ(Invoke->getNormalDest(), NormalBB);
-
-  // Check setUnwindDest().
-  Ctx.save();
-  Invoke->setUnwindDest(OtherBB);
-  EXPECT_EQ(Invoke->getUnwindDest(), OtherBB);
-  Ctx.revert();
-  EXPECT_EQ(Invoke->getUnwindDest(), ExceptionBB);
-
-  // Check setSuccessor().
-  Ctx.save();
-  Invoke->setSuccessor(0, OtherBB);
-  EXPECT_EQ(Invoke->getSuccessor(0), OtherBB);
-  Ctx.revert();
-  EXPECT_EQ(Invoke->getSuccessor(0), NormalBB);
-
-  Ctx.save();
-  Invoke->setSuccessor(1, OtherBB);
-  EXPECT_EQ(Invoke->getSuccessor(1), OtherBB);
-  Ctx.revert();
-  EXPECT_EQ(Invoke->getSuccessor(1), ExceptionBB);
-}
-
-TEST_F(TrackerTest, CatchSwitchInst) {
-  parseIR(C, R"IR(
-define void @foo(i32 %cond0, i32 %cond1) {
-  bb0:
-    %cs0 = catchswitch within none [label %handler0, label %handler1] unwind to caller
-  bb1:
-    %cs1 = catchswitch within %cs0 [label %handler0, label %handler1] unwind label %cleanup
-  handler0:
-    ret void
-  handler1:
-    ret void
-  cleanup:
-    ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *Handler0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "handler0")));
-  auto *Handler1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "handler1")));
-  auto *CS0 = cast<sandboxir::CatchSwitchInst>(&*BB0->begin());
-  auto *CS1 = cast<sandboxir::CatchSwitchInst>(&*BB1->begin());
-
-  // Check setParentPad().
-  auto *OrigPad = CS0->getParentPad();
-  auto *NewPad = CS1;
-  EXPECT_NE(NewPad, OrigPad);
-  Ctx.save();
-  CS0->setParentPad(NewPad);
-  EXPECT_EQ(CS0->getParentPad(), NewPad);
-  Ctx.revert();
-  EXPECT_EQ(CS0->getParentPad(), OrigPad);
-  // Check setUnwindDest().
-  auto *OrigUnwindDest = CS1->getUnwindDest();
-  auto *NewUnwindDest = BB0;
-  EXPECT_NE(NewUnwindDest, OrigUnwindDest);
-  Ctx.save();
-  CS1->setUnwindDest(NewUnwindDest);
-  EXPECT_EQ(CS1->getUnwindDest(), NewUnwindDest);
-  Ctx.revert();
-  EXPECT_EQ(CS1->getUnwindDest(), OrigUnwindDest);
-  // Check setSuccessor().
-  auto *OrigSuccessor = CS0->getSuccessor(0);
-  auto *NewSuccessor = BB0;
-  EXPECT_NE(NewSuccessor, OrigSuccessor);
-  Ctx.save();
-  CS0->setSuccessor(0, NewSuccessor);
-  EXPECT_EQ(CS0->getSuccessor(0), NewSuccessor);
-  Ctx.revert();
-  EXPECT_EQ(CS0->getSuccessor(0), OrigSuccessor);
-  // Check addHandler().
-  Ctx.save();
-  CS0->addHandler(BB0);
-  EXPECT_EQ(CS0->getNumHandlers(), 3u);
-  Ctx.revert();
-  EXPECT_EQ(CS0->getNumHandlers(), 2u);
-  auto HIt = CS0->handler_begin();
-  EXPECT_EQ(*HIt++, Handler0);
-  EXPECT_EQ(*HIt++, Handler1);
-}
-
-TEST_F(TrackerTest, LandingPadInstSetters) {
-  parseIR(C, R"IR(
-define void @foo() {
-entry:
-  invoke void @foo()
-      to label %bb unwind label %unwind
-unwind:
-  %lpad = landingpad { ptr, i32 }
-            catch ptr null
-  ret void
-bb:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMUnwind = getBasicBlockByName(LLVMF, "unwind");
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Unwind = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMUnwind));
-  auto It = Unwind->begin();
-  auto *LPad = cast<sandboxir::LandingPadInst>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  // Check setCleanup().
-  auto OrigIsCleanup = LPad->isCleanup();
-  auto NewIsCleanup = true;
-  EXPECT_NE(NewIsCleanup, OrigIsCleanup);
-  Ctx.save();
-  LPad->setCleanup(NewIsCleanup);
-  EXPECT_EQ(LPad->isCleanup(), NewIsCleanup);
-  Ctx.revert();
-  EXPECT_EQ(LPad->isCleanup(), OrigIsCleanup);
-}
-
-TEST_F(TrackerTest, CatchReturnInstSetters) {
-  parseIR(C, R"IR(
-define void @foo() {
-dispatch:
-  %cs = catchswitch within none [label %catch] unwind to caller
-catch:
-  %catchpad = catchpad within %cs [ptr @foo]
-  catchret from %catchpad to label %continue
-continue:
-  ret void
-catch2:
-  %catchpad2 = catchpad within %cs [ptr @foo]
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMCatch = getBasicBlockByName(LLVMF, "catch");
-  auto LLVMIt = LLVMCatch->begin();
-  [[maybe_unused]] auto *LLVMCP = cast<llvm::CatchPadInst>(&*LLVMIt++);
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Catch = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCatch));
-  auto *Catch2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "catch2")));
-  auto It = Catch->begin();
-  [[maybe_unused]] auto *CP = cast<sandboxir::CatchPadInst>(&*It++);
-  auto *CR = cast<sandboxir::CatchReturnInst>(&*It++);
-  auto *CP2 = cast<sandboxir::CatchPadInst>(&*Catch2->begin());
-
-  // Check setCatchPad().
-  auto *OrigCP = CR->getCatchPad();
-  auto *NewCP = CP2;
-  EXPECT_NE(NewCP, OrigCP);
-  Ctx.save();
-  CR->setCatchPad(NewCP);
-  EXPECT_EQ(CR->getCatchPad(), NewCP);
-  Ctx.revert();
-  EXPECT_EQ(CR->getCatchPad(), OrigCP);
-  // Check setSuccessor().
-  auto *OrigSucc = CR->getSuccessor();
-  auto *NewSucc = Catch;
-  EXPECT_NE(NewSucc, OrigSucc);
-  Ctx.save();
-  CR->setSuccessor(NewSucc);
-  EXPECT_EQ(CR->getSuccessor(), NewSucc);
-  Ctx.revert();
-  EXPECT_EQ(CR->getSuccessor(), OrigSucc);
-}
-
-TEST_F(TrackerTest, CleanupReturnInstSetters) {
-  parseIR(C, R"IR(
-define void @foo() {
-dispatch:
-  invoke void @foo()
-              to label %throw unwind label %cleanup
-throw:
-  ret void
-cleanup:
-  %cleanuppad = cleanuppad within none []
-  cleanupret from %cleanuppad unwind label %cleanup2
-cleanup2:
-  %cleanuppad2 = cleanuppad within none []
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  BasicBlock *LLVMCleanup = getBasicBlockByName(LLVMF, "cleanup");
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Throw = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "throw")));
-  auto *Cleanup = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMCleanup));
-  auto *Cleanup2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "cleanup2")));
-  auto It = Cleanup->begin();
-  [[maybe_unused]] auto *CP = cast<sandboxir::CleanupPadInst>(&*It++);
-  auto *CRI = cast<sandboxir::CleanupReturnInst>(&*It++);
-  auto *CP2 = cast<sandboxir::CleanupPadInst>(&*Cleanup2->begin());
-
-  // Check setCleanupPad().
-  auto *OrigCleanupPad = CRI->getCleanupPad();
-  auto *NewCleanupPad = CP2;
-  EXPECT_NE(NewCleanupPad, OrigCleanupPad);
-  Ctx.save();
-  CRI->setCleanupPad(NewCleanupPad);
-  EXPECT_EQ(CRI->getCleanupPad(), NewCleanupPad);
-  Ctx.revert();
-  EXPECT_EQ(CRI->getCleanupPad(), OrigCleanupPad);
-  // Check setUnwindDest().
-  auto *OrigUnwindDest = CRI->getUnwindDest();
-  auto *NewUnwindDest = Throw;
-  EXPECT_NE(NewUnwindDest, OrigUnwindDest);
-  Ctx.save();
-  CRI->setUnwindDest(NewUnwindDest);
-  EXPECT_EQ(CRI->getUnwindDest(), NewUnwindDest);
-  Ctx.revert();
-  EXPECT_EQ(CRI->getUnwindDest(), OrigUnwindDest);
-}
-
-TEST_F(TrackerTest, SwitchInstSetters) {
-  parseIR(C, R"IR(
-define void @foo(i32 %cond0, i32 %cond1) {
-  entry:
-    switch i32 %cond0, label %default [ i32 0, label %bb0
-                                        i32 1, label %bb1 ]
-  bb0:
-    ret void
-  bb1:
-    ret void
-  default:
-    ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry");
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Cond1 = F.getArg(1);
-  auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry));
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin());
-
-  // Check setCondition().
-  auto *OrigCond = Switch->getCondition();
-  auto *NewCond = Cond1;
-  EXPECT_NE(NewCond, OrigCond);
-  Ctx.save();
-  Switch->setCondition(NewCond);
-  EXPECT_EQ(Switch->getCondition(), NewCond);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getCondition(), OrigCond);
-  // Check setDefaultDest().
-  auto *OrigDefaultDest = Switch->getDefaultDest();
-  auto *NewDefaultDest = Entry;
-  EXPECT_NE(NewDefaultDest, OrigDefaultDest);
-  Ctx.save();
-  Switch->setDefaultDest(NewDefaultDest);
-  EXPECT_EQ(Switch->getDefaultDest(), NewDefaultDest);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getDefaultDest(), OrigDefaultDest);
-  // Check setSuccessor().
-  auto *OrigSucc = Switch->getSuccessor(0);
-  auto *NewSucc = Entry;
-  EXPECT_NE(NewSucc, OrigSucc);
-  Ctx.save();
-  Switch->setSuccessor(0, NewSucc);
-  EXPECT_EQ(Switch->getSuccessor(0), NewSucc);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getSuccessor(0), OrigSucc);
-  // Check addCase().
-  auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
-  auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1);
-  auto *FortyTwo =
-      sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 42);
-  Ctx.save();
-  Switch->addCase(FortyTwo, Entry);
-  EXPECT_EQ(Switch->getNumCases(), 3u);
-  EXPECT_EQ(Switch->findCaseDest(Entry), FortyTwo);
-  EXPECT_EQ(Switch->findCaseValue(FortyTwo)->getCaseSuccessor(), Entry);
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getNumCases(), 2u);
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  // Check removeCase().
-  Ctx.save();
-  Switch->removeCase(Switch->findCaseValue(Zero));
-  EXPECT_EQ(Switch->getNumCases(), 1u);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getNumCases(), 2u);
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-}
-
-TEST_F(TrackerTest, SwitchInstPreservesSuccesorOrder) {
-  parseIR(C, R"IR(
-define void @foo(i32 %cond0) {
-  entry:
-    switch i32 %cond0, label %default [ i32 0, label %bb0
-                                        i32 1, label %bb1
-                                        i32 2, label %bb2 ]
-  bb0:
-    ret void
-  bb1:
-    ret void
-  bb2:
-    ret void
-  default:
-    ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  auto *LLVMEntry = getBasicBlockByName(LLVMF, "entry");
-
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Entry = cast<sandboxir::BasicBlock>(Ctx.getValue(LLVMEntry));
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *BB2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
-  auto *Switch = cast<sandboxir::SwitchInst>(&*Entry->begin());
-
-  auto *DefaultDest = Switch->getDefaultDest();
-  auto *Zero = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 0);
-  auto *One = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 1);
-  auto *Two = sandboxir::ConstantInt::get(sandboxir::Type::getInt32Ty(Ctx), 2);
-
-  // Check that we can properly revert a removeCase multiple positions apart
-  // from the end of the operand list.
-  Ctx.save();
-  Switch->removeCase(Switch->findCaseValue(Zero));
-  EXPECT_EQ(Switch->getNumCases(), 2u);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getNumCases(), 3u);
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  EXPECT_EQ(Switch->findCaseDest(BB2), Two);
-  EXPECT_EQ(Switch->getSuccessor(0), DefaultDest);
-  EXPECT_EQ(Switch->getSuccessor(1), BB0);
-  EXPECT_EQ(Switch->getSuccessor(2), BB1);
-  EXPECT_EQ(Switch->getSuccessor(3), BB2);
-
-  // Check that we can properly revert a removeCase of the last case.
-  Ctx.save();
-  Switch->removeCase(Switch->findCaseValue(Two));
-  EXPECT_EQ(Switch->getNumCases(), 2u);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getNumCases(), 3u);
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  EXPECT_EQ(Switch->findCaseDest(BB2), Two);
-  EXPECT_EQ(Switch->getSuccessor(0), DefaultDest);
-  EXPECT_EQ(Switch->getSuccessor(1), BB0);
-  EXPECT_EQ(Switch->getSuccessor(2), BB1);
-  EXPECT_EQ(Switch->getSuccessor(3), BB2);
-
-  // Check order is preserved after reverting multiple removeCase invocations.
-  Ctx.save();
-  Switch->removeCase(Switch->findCaseValue(One));
-  Switch->removeCase(Switch->findCaseValue(Zero));
-  Switch->removeCase(Switch->findCaseValue(Two));
-  EXPECT_EQ(Switch->getNumCases(), 0u);
-  Ctx.revert();
-  EXPECT_EQ(Switch->getNumCases(), 3u);
-  EXPECT_EQ(Switch->findCaseDest(BB0), Zero);
-  EXPECT_EQ(Switch->findCaseDest(BB1), One);
-  EXPECT_EQ(Switch->findCaseDest(BB2), Two);
-  EXPECT_EQ(Switch->getSuccessor(0), DefaultDest);
-  EXPECT_EQ(Switch->getSuccessor(1), BB0);
-  EXPECT_EQ(Switch->getSuccessor(2), BB1);
-  EXPECT_EQ(Switch->getSuccessor(3), BB2);
-}
-
-TEST_F(TrackerTest, SelectInst) {
-  parseIR(C, R"IR(
-define void @foo(i1 %c0, i8 %v0, i8 %v1) {
-  %sel = select i1 %c0, i8 %v0, i8 %v1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *V0 = F->getArg(1);
-  auto *V1 = F->getArg(2);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Select = cast<sandboxir::SelectInst>(&*It++);
-
-  // Check tracking for swapValues.
-  Ctx.save();
-  Select->swapValues();
-  EXPECT_EQ(Select->getTrueValue(), V1);
-  EXPECT_EQ(Select->getFalseValue(), V0);
-  Ctx.revert();
-  EXPECT_EQ(Select->getTrueValue(), V0);
-  EXPECT_EQ(Select->getFalseValue(), V1);
-}
-
-TEST_F(TrackerTest, ShuffleVectorInst) {
-  parseIR(C, R"IR(
-define void @foo(<2 x i8> %v1, <2 x i8> %v2) {
-  %shuf = shufflevector <2 x i8> %v1, <2 x i8> %v2, <2 x i32> <i32 1, i32 2>
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *SVI = cast<sandboxir::ShuffleVectorInst>(&*It++);
-
-  // Check setShuffleMask.
-  SmallVector<int, 2> OrigMask(SVI->getShuffleMask());
-  Ctx.save();
-  SVI->setShuffleMask(ArrayRef<int>({0, 0}));
-  EXPECT_NE(SVI->getShuffleMask(), ArrayRef<int>(OrigMask));
-  Ctx.revert();
-  EXPECT_EQ(SVI->getShuffleMask(), ArrayRef<int>(OrigMask));
-
-  // Check commute.
-  auto *Op0 = SVI->getOperand(0);
-  auto *Op1 = SVI->getOperand(1);
-  Ctx.save();
-  SVI->commute();
-  EXPECT_EQ(SVI->getOperand(0), Op1);
-  EXPECT_EQ(SVI->getOperand(1), Op0);
-  EXPECT_NE(SVI->getShuffleMask(), ArrayRef<int>(OrigMask));
-  Ctx.revert();
-  EXPECT_EQ(SVI->getOperand(0), Op0);
-  EXPECT_EQ(SVI->getOperand(1), Op1);
-  EXPECT_EQ(SVI->getShuffleMask(), ArrayRef<int>(OrigMask));
-}
-
-TEST_F(TrackerTest, PossiblyDisjointInstSetters) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg0, i8 %arg1) {
-  %or = or i8 %arg0, %arg1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *PDI = cast<sandboxir::PossiblyDisjointInst>(&*It++);
-
-  // Check setIsDisjoint().
-  auto OrigIsDisjoint = PDI->isDisjoint();
-  auto NewIsDisjoint = true;
-  EXPECT_NE(NewIsDisjoint, OrigIsDisjoint);
-  Ctx.save();
-  PDI->setIsDisjoint(NewIsDisjoint);
-  EXPECT_EQ(PDI->isDisjoint(), NewIsDisjoint);
-  Ctx.revert();
-  EXPECT_EQ(PDI->isDisjoint(), OrigIsDisjoint);
-}
-
-TEST_F(TrackerTest, PossiblyNonNegInstSetters) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg) {
-  %zext = zext i32 %arg to i64
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *PNNI = cast<sandboxir::PossiblyNonNegInst>(&*It++);
-
-  // Check setNonNeg().
-  auto OrigNonNeg = PNNI->hasNonNeg();
-  auto NewNonNeg = true;
-  EXPECT_NE(NewNonNeg, OrigNonNeg);
-  Ctx.save();
-  PNNI->setNonNeg(NewNonNeg);
-  EXPECT_EQ(PNNI->hasNonNeg(), NewNonNeg);
-  Ctx.revert();
-  EXPECT_EQ(PNNI->hasNonNeg(), OrigNonNeg);
-}
-
-TEST_F(TrackerTest, AtomicRMWSetters) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %arg) {
-  %atomicrmw = atomicrmw add ptr %ptr, i8 %arg acquire, align 128
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *RMW = cast<sandboxir::AtomicRMWInst>(&*It++);
-
-  // Check setAlignment().
-  Ctx.save();
-  auto OrigAlign = RMW->getAlign();
-  Align NewAlign(1024);
-  EXPECT_NE(NewAlign, OrigAlign);
-  RMW->setAlignment(NewAlign);
-  EXPECT_EQ(RMW->getAlign(), NewAlign);
-  Ctx.revert();
-  EXPECT_EQ(RMW->getAlign(), OrigAlign);
-
-  // Check setVolatile().
-  Ctx.save();
-  auto OrigIsVolatile = RMW->isVolatile();
-  bool NewIsVolatile = true;
-  EXPECT_NE(NewIsVolatile, OrigIsVolatile);
-  RMW->setVolatile(NewIsVolatile);
-  EXPECT_EQ(RMW->isVolatile(), NewIsVolatile);
-  Ctx.revert();
-  EXPECT_EQ(RMW->isVolatile(), OrigIsVolatile);
-
-  // Check setOrdering().
-  Ctx.save();
-  auto OrigOrdering = RMW->getOrdering();
-  auto NewOrdering = AtomicOrdering::SequentiallyConsistent;
-  EXPECT_NE(NewOrdering, OrigOrdering);
-  RMW->setOrdering(NewOrdering);
-  EXPECT_EQ(RMW->getOrdering(), NewOrdering);
-  Ctx.revert();
-  EXPECT_EQ(RMW->getOrdering(), OrigOrdering);
-
-  // Check setSyncScopeID().
-  Ctx.save();
-  auto OrigSSID = RMW->getSyncScopeID();
-  auto NewSSID = SyncScope::SingleThread;
-  EXPECT_NE(NewSSID, OrigSSID);
-  RMW->setSyncScopeID(NewSSID);
-  EXPECT_EQ(RMW->getSyncScopeID(), NewSSID);
-  Ctx.revert();
-  EXPECT_EQ(RMW->getSyncScopeID(), OrigSSID);
-}
-
-TEST_F(TrackerTest, AtomicCmpXchgSetters) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %cmp, i8 %new) {
-  %cmpxchg = cmpxchg ptr %ptr, i8 %cmp, i8 %new monotonic monotonic, align 128
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *CmpXchg = cast<sandboxir::AtomicCmpXchgInst>(&*It++);
-
-  // Check setAlignment().
-  Ctx.save();
-  auto OrigAlign = CmpXchg->getAlign();
-  Align NewAlign(1024);
-  EXPECT_NE(NewAlign, OrigAlign);
-  CmpXchg->setAlignment(NewAlign);
-  EXPECT_EQ(CmpXchg->getAlign(), NewAlign);
-  Ctx.revert();
-  EXPECT_EQ(CmpXchg->getAlign(), OrigAlign);
-
-  // Check setVolatile().
-  Ctx.save();
-  auto OrigIsVolatile = CmpXchg->isVolatile();
-  bool NewIsVolatile = true;
-  EXPECT_NE(NewIsVolatile, OrigIsVolatile);
-  CmpXchg->setVolatile(NewIsVolatile);
-  EXPECT_EQ(CmpXchg->isVolatile(), NewIsVolatile);
-  Ctx.revert();
-  EXPECT_EQ(CmpXchg->isVolatile(), OrigIsVolatile);
-
-  // Check setWeak().
-  Ctx.save();
-  auto OrigIsWeak = CmpXchg->isWeak();
-  bool NewIsWeak = true;
-  EXPECT_NE(NewIsWeak, OrigIsWeak);
-  CmpXchg->setWeak(NewIsWeak);
-  EXPECT_EQ(CmpXchg->isWeak(), NewIsWeak);
-  Ctx.revert();
-  EXPECT_EQ(CmpXchg->isWeak(), OrigIsWeak);
-
-  // Check setSuccessOrdering().
-  Ctx.save();
-  auto OrigSuccessOrdering = CmpXchg->getSuccessOrdering();
-  auto NewSuccessOrdering = AtomicOrdering::SequentiallyConsistent;
-  EXPECT_NE(NewSuccessOrdering, OrigSuccessOrdering);
-  CmpXchg->setSuccessOrdering(NewSuccessOrdering);
-  EXPECT_EQ(CmpXchg->getSuccessOrdering(), NewSuccessOrdering);
-  Ctx.revert();
-  EXPECT_EQ(CmpXchg->getSuccessOrdering(), OrigSuccessOrdering);
-
-  // Check setFailureOrdering().
-  Ctx.save();
-  auto OrigFailureOrdering = CmpXchg->getFailureOrdering();
-  auto NewFailureOrdering = AtomicOrdering::SequentiallyConsistent;
-  EXPECT_NE(NewFailureOrdering, OrigFailureOrdering);
-  CmpXchg->setFailureOrdering(NewFailureOrdering);
-  EXPECT_EQ(CmpXchg->getFailureOrdering(), NewFailureOrdering);
-  Ctx.revert();
-  EXPECT_EQ(CmpXchg->getFailureOrdering(), OrigFailureOrdering);
-
-  // Check setSyncScopeID().
-  Ctx.save();
-  auto OrigSSID = CmpXchg->getSyncScopeID();
-  auto NewSSID = SyncScope::SingleThread;
-  EXPECT_NE(NewSSID, OrigSSID);
-  CmpXchg->setSyncScopeID(NewSSID);
-  EXPECT_EQ(CmpXchg->getSyncScopeID(), NewSSID);
-  Ctx.revert();
-  EXPECT_EQ(CmpXchg->getSyncScopeID(), OrigSSID);
-}
-
-TEST_F(TrackerTest, AllocaInstSetters) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg) {
-  %alloca = alloca i32, align 64
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Alloca = cast<sandboxir::AllocaInst>(&*It++);
-
-  // Check setAllocatedType().
-  Ctx.save();
-  auto *OrigTy = Alloca->getAllocatedType();
-  auto *NewTy = sandboxir::Type::getInt64Ty(Ctx);
-  EXPECT_NE(NewTy, OrigTy);
-  Alloca->setAllocatedType(NewTy);
-  EXPECT_EQ(Alloca->getAllocatedType(), NewTy);
-  Ctx.revert();
-  EXPECT_EQ(Alloca->getAllocatedType(), OrigTy);
-
-  // Check setAlignment().
-  Ctx.save();
-  auto OrigAlign = Alloca->getAlign();
-  Align NewAlign(128);
-  EXPECT_NE(NewAlign, OrigAlign);
-  Alloca->setAlignment(NewAlign);
-  EXPECT_EQ(Alloca->getAlign(), NewAlign);
-  Ctx.revert();
-  EXPECT_EQ(Alloca->getAlign(), OrigAlign);
-
-  // Check setUsedWithInAlloca().
-  Ctx.save();
-  auto OrigWIA = Alloca->isUsedWithInAlloca();
-  bool NewWIA = true;
-  EXPECT_NE(NewWIA, OrigWIA);
-  Alloca->setUsedWithInAlloca(NewWIA);
-  EXPECT_EQ(Alloca->isUsedWithInAlloca(), NewWIA);
-  Ctx.revert();
-  EXPECT_EQ(Alloca->isUsedWithInAlloca(), OrigWIA);
-}
-
-TEST_F(TrackerTest, CallBrSetters) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg) {
- bb0:
-   callbr void @foo(i8 %arg)
-               to label %bb1 [label %bb2]
- bb1:
-   ret void
- bb2:
-   ret void
- other_bb:
-   ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *OtherBB = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "other_bb")));
-  auto It = BB0->begin();
-  auto *CallBr = cast<sandboxir::CallBrInst>(&*It++);
-  // Check setDefaultDest().
-  Ctx.save();
-  auto *OrigDefaultDest = CallBr->getDefaultDest();
-  CallBr->setDefaultDest(OtherBB);
-  EXPECT_EQ(CallBr->getDefaultDest(), OtherBB);
-  Ctx.revert();
-  EXPECT_EQ(CallBr->getDefaultDest(), OrigDefaultDest);
-
-  // Check setIndirectDest().
-  Ctx.save();
-  auto *OrigIndirectDest = CallBr->getIndirectDest(0);
-  CallBr->setIndirectDest(0, OtherBB);
-  EXPECT_EQ(CallBr->getIndirectDest(0), OtherBB);
-  Ctx.revert();
-  EXPECT_EQ(CallBr->getIndirectDest(0), OrigIndirectDest);
-}
-
-TEST_F(TrackerTest, FuncletPadInstSetters) {
-  parseIR(C, R"IR(
-define void @foo() {
-dispatch:
-  %cs = catchswitch within none [label %handler0] unwind to caller
-handler0:
-  %catchpad = catchpad within %cs [ptr @foo]
-  ret void
-handler1:
-  %cleanuppad = cleanuppad within %cs [ptr @foo]
-  ret void
-bb:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  [[maybe_unused]] auto &F = *Ctx.createFunction(&LLVMF);
-  auto *Dispatch = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "dispatch")));
-  auto *Handler0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "handler0")));
-  auto *Handler1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "handler1")));
-  auto *CP = cast<sandboxir::CatchPadInst>(&*Handler0->begin());
-  auto *CLP = cast<sandboxir::CleanupPadInst>(&*Handler1->begin());
-
-  for (auto *FPI : {static_cast<sandboxir::FuncletPadInst *>(CP),
-                    static_cast<sandboxir::FuncletPadInst *>(CLP)}) {
-    // Check setParentPad().
-    auto *OrigParentPad = FPI->getParentPad();
-    auto *NewParentPad = Dispatch;
-    EXPECT_NE(NewParentPad, OrigParentPad);
-    Ctx.save();
-    FPI->setParentPad(NewParentPad);
-    EXPECT_EQ(FPI->getParentPad(), NewParentPad);
-    Ctx.revert();
-    EXPECT_EQ(FPI->getParentPad(), OrigParentPad);
-
-    // Check setArgOperand().
-    auto *OrigArgOperand = FPI->getArgOperand(0);
-    auto *NewArgOperand = Dispatch;
-    EXPECT_NE(NewArgOperand, OrigArgOperand);
-    Ctx.save();
-    FPI->setArgOperand(0, NewArgOperand);
-    EXPECT_EQ(FPI->getArgOperand(0), NewArgOperand);
-    Ctx.revert();
-    EXPECT_EQ(FPI->getArgOperand(0), OrigArgOperand);
-  }
-}
-
-TEST_F(TrackerTest, PHINodeSetters) {
-  parseIR(C, R"IR(
-define void @foo(i8 %arg0, i8 %arg1, i8 %arg2) {
-bb0:
-  br label %bb2
-
-bb1:
-  %phi = phi i8 [ %arg0, %bb0 ], [ %arg1, %bb1 ]
-  br label %bb1
-
-bb2:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  unsigned ArgIdx = 0;
-  auto *Arg0 = F.getArg(ArgIdx++);
-  auto *Arg1 = F.getArg(ArgIdx++);
-  auto *Arg2 = F.getArg(ArgIdx++);
-  auto *BB0 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb0")));
-  auto *BB1 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb1")));
-  auto *BB2 = cast<sandboxir::BasicBlock>(
-      Ctx.getValue(getBasicBlockByName(LLVMF, "bb2")));
-  auto *PHI = cast<sandboxir::PHINode>(&*BB1->begin());
-
-  // Check setIncomingValue().
-  Ctx.save();
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  PHI->setIncomingValue(0, Arg2);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg2);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-
-  // Check setIncomingBlock().
-  Ctx.save();
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  PHI->setIncomingBlock(0, BB2);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB2);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-
-  // Check addIncoming().
-  Ctx.save();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  PHI->addIncoming(Arg1, BB2);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 3u);
-  EXPECT_EQ(PHI->getIncomingBlock(2), BB2);
-  EXPECT_EQ(PHI->getIncomingValue(2), Arg1);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-
-  // Check removeIncomingValue(1).
-  Ctx.save();
-  PHI->removeIncomingValue(1);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 1u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-
-  // Check removeIncomingValue(0).
-  Ctx.save();
-  PHI->removeIncomingValue(0u);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 1u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg1);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-
-  // Check removeIncomingValueIf(FromBB1).
-  Ctx.save();
-  PHI->removeIncomingValueIf(
-      [&](unsigned Idx) { return PHI->getIncomingBlock(Idx) == BB1; });
-  EXPECT_EQ(PHI->getNumIncomingValues(), 1u);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  // Check removeIncomingValue() remove all.
-  Ctx.save();
-  PHI->removeIncomingValue(0u);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 1u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg1);
-  PHI->removeIncomingValue(0u);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 0u);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-
-  // Check removeIncomingValue(BasicBlock *).
-  Ctx.save();
-  PHI->removeIncomingValue(BB1);
-  EXPECT_EQ(PHI->getNumIncomingValues(), 1u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  Ctx.revert();
-  EXPECT_EQ(PHI->getNumIncomingValues(), 2u);
-  EXPECT_EQ(PHI->getIncomingBlock(0), BB0);
-  EXPECT_EQ(PHI->getIncomingValue(0), Arg0);
-  EXPECT_EQ(PHI->getIncomingBlock(1), BB1);
-  EXPECT_EQ(PHI->getIncomingValue(1), Arg1);
-}
-
-void checkCmpInst(sandboxir::Context &Ctx, sandboxir::CmpInst *Cmp) {
-  Ctx.save();
-  auto OrigP = Cmp->getPredicate();
-  auto NewP = Cmp->getSwappedPredicate();
-  Cmp->setPredicate(NewP);
-  EXPECT_EQ(Cmp->getPredicate(), NewP);
-  Ctx.revert();
-  EXPECT_EQ(Cmp->getPredicate(), OrigP);
-
-  Ctx.save();
-  auto OrigOp0 = Cmp->getOperand(0);
-  auto OrigOp1 = Cmp->getOperand(1);
-  Cmp->swapOperands();
-  EXPECT_EQ(Cmp->getPredicate(), NewP);
-  EXPECT_EQ(Cmp->getOperand(0), OrigOp1);
-  EXPECT_EQ(Cmp->getOperand(1), OrigOp0);
-  Ctx.revert();
-  EXPECT_EQ(Cmp->getPredicate(), OrigP);
-  EXPECT_EQ(Cmp->getOperand(0), OrigOp0);
-  EXPECT_EQ(Cmp->getOperand(1), OrigOp1);
-}
-
-TEST_F(TrackerTest, CmpInst) {
-  SCOPED_TRACE("TrackerTest sandboxir::CmpInst tests");
-  parseIR(C, R"IR(
-define void @foo(i64 %i0, i64 %i1, float %f0, float %f1) {
-  %foeq = fcmp ogt float %f0, %f1
-  %ioeq = icmp uge i64 %i0, %i1
-
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *FCmp = cast<sandboxir::CmpInst>(&*It++);
-  checkCmpInst(Ctx, FCmp);
-  auto *ICmp = cast<sandboxir::CmpInst>(&*It++);
-  checkCmpInst(Ctx, ICmp);
-}
-
-TEST_F(TrackerTest, GlobalValueSetters) {
-  parseIR(C, R"IR(
-define void @foo() {
-  call void @foo()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto *Call = cast<sandboxir::CallInst>(&*BB->begin());
-
-  auto *GV = cast<sandboxir::GlobalValue>(Call->getCalledOperand());
-  // Check setUnnamedAddr().
-  auto OrigUnnamedAddr = GV->getUnnamedAddr();
-  auto NewUnnamedAddr = sandboxir::GlobalValue::UnnamedAddr::Global;
-  EXPECT_NE(NewUnnamedAddr, OrigUnnamedAddr);
-  Ctx.save();
-  GV->setUnnamedAddr(NewUnnamedAddr);
-  EXPECT_EQ(GV->getUnnamedAddr(), NewUnnamedAddr);
-  Ctx.revert();
-  EXPECT_EQ(GV->getUnnamedAddr(), OrigUnnamedAddr);
-
-  // Check setVisibility().
-  auto OrigVisibility = GV->getVisibility();
-  auto NewVisibility =
-      sandboxir::GlobalValue::VisibilityTypes::ProtectedVisibility;
-  EXPECT_NE(NewVisibility, OrigVisibility);
-  Ctx.save();
-  GV->setVisibility(NewVisibility);
-  EXPECT_EQ(GV->getVisibility(), NewVisibility);
-  Ctx.revert();
-  EXPECT_EQ(GV->getVisibility(), OrigVisibility);
-}
-
-TEST_F(TrackerTest, GlobalIFuncSetters) {
-  parseIR(C, R"IR(
-declare external void @bar()
- at ifunc = ifunc void(), ptr @foo
-define void @foo() {
-  call void @ifunc()
-  call void @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call0 = cast<sandboxir::CallInst>(&*It++);
-  auto *Call1 = cast<sandboxir::CallInst>(&*It++);
-  // Check classof(), creation.
-  auto *IFunc = cast<sandboxir::GlobalIFunc>(Call0->getCalledOperand());
-  auto *Bar = cast<sandboxir::Function>(Call1->getCalledOperand());
-  // Check setResolver().
-  auto *OrigResolver = IFunc->getResolver();
-  auto *NewResolver = Bar;
-  EXPECT_NE(NewResolver, OrigResolver);
-  Ctx.save();
-  IFunc->setResolver(NewResolver);
-  EXPECT_EQ(IFunc->getResolver(), NewResolver);
-  Ctx.revert();
-  EXPECT_EQ(IFunc->getResolver(), OrigResolver);
-}
-
-TEST_F(TrackerTest, GlobalVariableSetters) {
-  parseIR(C, R"IR(
- at glob0 = global i32 42
- at glob1 = global i32 43
-define void @foo() {
-  %ld0 = load i32, ptr @glob0
-  %ld1 = load i32, ptr @glob1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
-  // Check classof(), creation.
-  auto *GV0 = cast<sandboxir::GlobalVariable>(Ld0->getPointerOperand());
-  auto *GV1 = cast<sandboxir::GlobalVariable>(Ld1->getPointerOperand());
-  // Check setInitializer().
-  auto *OrigInitializer = GV0->getInitializer();
-  auto *NewInitializer = GV1->getInitializer();
-  EXPECT_NE(NewInitializer, OrigInitializer);
-  Ctx.save();
-  GV0->setInitializer(NewInitializer);
-  EXPECT_EQ(GV0->getInitializer(), NewInitializer);
-  Ctx.revert();
-  EXPECT_EQ(GV0->getInitializer(), OrigInitializer);
-  // Check setConstant().
-  bool OrigIsConstant = GV0->isConstant();
-  bool NewIsConstant = !OrigIsConstant;
-  Ctx.save();
-  GV0->setConstant(NewIsConstant);
-  EXPECT_EQ(GV0->isConstant(), NewIsConstant);
-  Ctx.revert();
-  EXPECT_EQ(GV0->isConstant(), OrigIsConstant);
-  // Check setExternallyInitialized().
-  bool OrigIsExtInit = GV0->isExternallyInitialized();
-  bool NewIsExtInit = !OrigIsExtInit;
-  Ctx.save();
-  GV0->setExternallyInitialized(NewIsExtInit);
-  EXPECT_EQ(GV0->isExternallyInitialized(), NewIsExtInit);
-  Ctx.revert();
-  EXPECT_EQ(GV0->isExternallyInitialized(), OrigIsExtInit);
-}
-
-TEST_F(TrackerTest, GlobalAliasSetters) {
-  parseIR(C, R"IR(
- at alias = dso_local alias void(), ptr @foo
-declare void @bar();
-define void @foo() {
-  call void @alias()
-  call void @bar()
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Call0 = cast<sandboxir::CallInst>(&*It++);
-  auto *Call1 = cast<sandboxir::CallInst>(&*It++);
-  auto *Callee1 = cast<sandboxir::Constant>(Call1->getCalledOperand());
-  auto *Alias = cast<sandboxir::GlobalAlias>(Call0->getCalledOperand());
-  // Check setAliasee().
-  auto *OrigAliasee = Alias->getAliasee();
-  auto *NewAliasee = Callee1;
-  EXPECT_NE(NewAliasee, OrigAliasee);
-  Ctx.save();
-  Alias->setAliasee(NewAliasee);
-  EXPECT_EQ(Alias->getAliasee(), NewAliasee);
-  Ctx.revert();
-  EXPECT_EQ(Alias->getAliasee(), OrigAliasee);
-}
-
-TEST_F(TrackerTest, SetVolatile) {
-  parseIR(C, R"IR(
-define void @foo(ptr %arg0, i8 %val) {
-  %ld = load i8, ptr %arg0, align 64
-  store i8 %val, ptr %arg0, align 64
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Load = cast<sandboxir::LoadInst>(&*It++);
-  auto *Store = cast<sandboxir::StoreInst>(&*It++);
-
-  EXPECT_FALSE(Load->isVolatile());
-  Ctx.save();
-  Load->setVolatile(true);
-  EXPECT_TRUE(Load->isVolatile());
-  Ctx.revert();
-  EXPECT_FALSE(Load->isVolatile());
-
-  EXPECT_FALSE(Store->isVolatile());
-  Ctx.save();
-  Store->setVolatile(true);
-  EXPECT_TRUE(Store->isVolatile());
-  Ctx.revert();
-  EXPECT_FALSE(Store->isVolatile());
-}
-
-TEST_F(TrackerTest, Flags) {
-  parseIR(C, R"IR(
-define void @foo(i32 %arg, float %farg) {
-  %add = add i32 %arg, %arg
-  %fadd = fadd float %farg, %farg
-  %udiv = udiv i32 %arg, %arg
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *Add = &*It++;
-  auto *FAdd = &*It++;
-  auto *UDiv = &*It++;
-
-#define CHECK_FLAG(I, GETTER, SETTER)                                          \
-  {                                                                            \
-    Ctx.save();                                                                \
-    bool OrigFlag = I->GETTER();                                               \
-    bool NewFlag = !OrigFlag;                                                  \
-    I->SETTER(NewFlag);                                                        \
-    EXPECT_EQ(I->GETTER(), NewFlag);                                           \
-    Ctx.revert();                                                              \
-    EXPECT_EQ(I->GETTER(), OrigFlag);                                          \
-  }
-
-  CHECK_FLAG(Add, hasNoUnsignedWrap, setHasNoUnsignedWrap);
-  CHECK_FLAG(Add, hasNoSignedWrap, setHasNoSignedWrap);
-  CHECK_FLAG(FAdd, isFast, setFast);
-  CHECK_FLAG(FAdd, hasAllowReassoc, setHasAllowReassoc);
-  CHECK_FLAG(UDiv, isExact, setIsExact);
-  CHECK_FLAG(FAdd, hasNoNaNs, setHasNoNaNs);
-  CHECK_FLAG(FAdd, hasNoInfs, setHasNoInfs);
-  CHECK_FLAG(FAdd, hasNoSignedZeros, setHasNoSignedZeros);
-  CHECK_FLAG(FAdd, hasAllowReciprocal, setHasAllowReciprocal);
-  CHECK_FLAG(FAdd, hasAllowContract, setHasAllowContract);
-  CHECK_FLAG(FAdd, hasApproxFunc, setHasApproxFunc);
-
-  // Check setFastMathFlags().
-  FastMathFlags OrigFMF = FAdd->getFastMathFlags();
-  FastMathFlags NewFMF;
-  NewFMF.setAllowReassoc(true);
-  EXPECT_TRUE(NewFMF != OrigFMF);
-
-  Ctx.save();
-  FAdd->setFastMathFlags(NewFMF);
-  EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF);
-  Ctx.revert();
-  EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF);
-
-  // Check copyFastMathFlags().
-  Ctx.save();
-  FAdd->copyFastMathFlags(NewFMF);
-  EXPECT_FALSE(FAdd->getFastMathFlags() != NewFMF);
-  Ctx.revert();
-  EXPECT_FALSE(FAdd->getFastMathFlags() != OrigFMF);
-}
-
-// IRSnapshotChecker is only defined in debug mode.
-#ifndef NDEBUG
-
-TEST_F(TrackerTest, IRSnapshotCheckerNoChanges) {
-  parseIR(C, R"IR(
-define i32 @foo(i32 %arg) {
-  %add0 = add i32 %arg, %arg
-  ret i32 %add0
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  [[maybe_unused]] auto *F = Ctx.createFunction(&LLVMF);
-  sandboxir::IRSnapshotChecker Checker(Ctx);
-  Checker.save();
-  Checker.expectNoDiff();
-}
-
-TEST_F(TrackerTest, IRSnapshotCheckerDiesWithUnexpectedChanges) {
-  parseIR(C, R"IR(
-define i32 @foo(i32 %arg) {
-  %add0 = add i32 %arg, %arg
-  %add1 = add i32 %add0, %arg
-  ret i32 %add1
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::Instruction *Add0 = &*It++;
-  sandboxir::Instruction *Add1 = &*It++;
-  sandboxir::IRSnapshotChecker Checker(Ctx);
-  Checker.save();
-  Add1->setOperand(1, Add0);
-  EXPECT_DEATH(Checker.expectNoDiff(), "Found IR difference");
-}
-
-TEST_F(TrackerTest, IRSnapshotCheckerSaveMultipleTimes) {
-  parseIR(C, R"IR(
-define i32 @foo(i32 %arg) {
-  %add0 = add i32 %arg, %arg
-  %add1 = add i32 %add0, %arg
-  ret i32 %add1
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(&LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::Instruction *Add0 = &*It++;
-  sandboxir::Instruction *Add1 = &*It++;
-  sandboxir::IRSnapshotChecker Checker(Ctx);
-  Checker.save();
-  Add1->setOperand(1, Add0);
-  // Now IR differs from the last snapshot. Let's take a new snapshot.
-  Checker.save();
-  // The new snapshot should have replaced the old one, so this should succeed.
-  Checker.expectNoDiff();
-}
-
-#endif // NDEBUG
diff --git a/llvm/unittests/SandboxIR/TypesTest.cpp b/llvm/unittests/SandboxIR/TypesTest.cpp
deleted file mode 100644
index 880caa7137a44..0000000000000
--- a/llvm/unittests/SandboxIR/TypesTest.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-//===- TypesTest.cpp ------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct SandboxTypeTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("SandboxTypeTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-TEST_F(SandboxTypeTest, Type) {
-  parseIR(C, R"IR(
-define void @foo(i32 %v0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  sandboxir::Type *I32Ty = F->getArg(0)->getType();
-
-  auto *LLVMInt32Ty = llvm::Type::getInt32Ty(C);
-  auto *LLVMFloatTy = llvm::Type::getFloatTy(C);
-  auto *LLVMInt8Ty = llvm::Type::getInt8Ty(C);
-
-  auto *Int32Ty = Ctx.getType(LLVMInt32Ty);
-  auto *FloatTy = Ctx.getType(LLVMFloatTy);
-
-  // Check print().
-  std::string Buff1;
-  raw_string_ostream BS1(Buff1);
-  Int32Ty->print(BS1, /*IsForDebug=*/true, /*NoDetails=*/false);
-  std::string Buff2;
-  raw_string_ostream BS2(Buff2);
-  LLVMInt32Ty->print(BS2, /*IsForDebug=*/true, /*NoDetails=*/false);
-  EXPECT_EQ(Buff1, Buff2);
-
-  // Check getContext().
-  EXPECT_EQ(&I32Ty->getContext(), &Ctx);
-  // Check that Ctx.getType(nullptr) == nullptr.
-  EXPECT_EQ(Ctx.getType(nullptr), nullptr);
-
-#define CHK(LLVMCreate, SBCheck)                                               \
-  Ctx.getType(llvm::Type::LLVMCreate(C))->SBCheck()
-  // Check isVoidTy().
-  EXPECT_TRUE(Ctx.getType(llvm::Type::getVoidTy(C))->isVoidTy());
-  EXPECT_TRUE(CHK(getVoidTy, isVoidTy));
-  // Check isHalfTy().
-  EXPECT_TRUE(CHK(getHalfTy, isHalfTy));
-  // Check isBFloatTy().
-  EXPECT_TRUE(CHK(getBFloatTy, isBFloatTy));
-  // Check is16bitFPTy().
-  EXPECT_TRUE(CHK(getHalfTy, is16bitFPTy));
-  // Check isFloatTy().
-  EXPECT_TRUE(CHK(getFloatTy, isFloatTy));
-  // Check isDoubleTy().
-  EXPECT_TRUE(CHK(getDoubleTy, isDoubleTy));
-  // Check isX86_FP80Ty().
-  EXPECT_TRUE(CHK(getX86_FP80Ty, isX86_FP80Ty));
-  // Check isFP128Ty().
-  EXPECT_TRUE(CHK(getFP128Ty, isFP128Ty));
-  // Check isPPC_FP128Ty().
-  EXPECT_TRUE(CHK(getPPC_FP128Ty, isPPC_FP128Ty));
-  // Check isIEEELikeFPTy().
-  EXPECT_TRUE(CHK(getFloatTy, isIEEELikeFPTy));
-  // Check isFloatingPointTy().
-  EXPECT_TRUE(CHK(getFloatTy, isFloatingPointTy));
-  EXPECT_TRUE(CHK(getDoubleTy, isFloatingPointTy));
-  // Check isMultiUnitFPType().
-  EXPECT_TRUE(CHK(getPPC_FP128Ty, isMultiUnitFPType));
-  EXPECT_FALSE(CHK(getFloatTy, isMultiUnitFPType));
-  // Check getFltSemantics().
-  EXPECT_EQ(&sandboxir::Type::getFloatTy(Ctx)->getFltSemantics(),
-            &llvm::Type::getFloatTy(C)->getFltSemantics());
-  // Check isX86_AMXTy().
-  EXPECT_TRUE(CHK(getX86_AMXTy, isX86_AMXTy));
-  // Check isTargetExtTy().
-  EXPECT_TRUE(Ctx.getType(llvm::TargetExtType::get(C, "foo"))->isTargetExtTy());
-  // Check isScalableTargetExtTy().
-  EXPECT_TRUE(Ctx.getType(llvm::TargetExtType::get(C, "aarch64.svcount"))
-                  ->isScalableTargetExtTy());
-  // Check isScalableTy().
-  EXPECT_TRUE(Ctx.getType(llvm::ScalableVectorType::get(LLVMInt32Ty, 2u))
-                  ->isScalableTy());
-  // Check isFPOrFPVectorTy().
-  EXPECT_TRUE(CHK(getFloatTy, isFPOrFPVectorTy));
-  EXPECT_FALSE(CHK(getInt32Ty, isFPOrFPVectorTy));
-  // Check isLabelTy().
-  EXPECT_TRUE(CHK(getLabelTy, isLabelTy));
-  // Check isMetadataTy().
-  EXPECT_TRUE(CHK(getMetadataTy, isMetadataTy));
-  // Check isTokenTy().
-  EXPECT_TRUE(CHK(getTokenTy, isTokenTy));
-  // Check isIntegerTy().
-  EXPECT_TRUE(CHK(getInt32Ty, isIntegerTy));
-  EXPECT_FALSE(CHK(getFloatTy, isIntegerTy));
-  // Check isIntegerTy(Bitwidth).
-  EXPECT_TRUE(LLVMInt32Ty->isIntegerTy(32u));
-  EXPECT_FALSE(LLVMInt32Ty->isIntegerTy(31u));
-  EXPECT_FALSE(Ctx.getType(llvm::Type::getFloatTy(C))->isIntegerTy(32u));
-  // Check isIntOrIntVectorTy().
-  EXPECT_TRUE(LLVMInt32Ty->isIntOrIntVectorTy());
-  EXPECT_TRUE(Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8))
-                  ->isIntOrIntVectorTy());
-  EXPECT_FALSE(Ctx.getType(LLVMFloatTy)->isIntOrIntVectorTy());
-  EXPECT_FALSE(Ctx.getType(llvm::FixedVectorType::get(LLVMFloatTy, 8))
-                   ->isIntOrIntVectorTy());
-  // Check isIntOrPtrTy().
-  EXPECT_TRUE(Int32Ty->isIntOrPtrTy());
-  EXPECT_TRUE(Ctx.getType(llvm::PointerType::get(C, 0u))->isIntOrPtrTy());
-  EXPECT_FALSE(FloatTy->isIntOrPtrTy());
-  // Check isFunctionTy().
-  EXPECT_TRUE(Ctx.getType(llvm::FunctionType::get(LLVMInt32Ty, {}, false))
-                  ->isFunctionTy());
-  // Check isStructTy().
-  EXPECT_TRUE(Ctx.getType(llvm::StructType::get(C))->isStructTy());
-  // Check isArrayTy().
-  EXPECT_TRUE(Ctx.getType(llvm::ArrayType::get(LLVMInt32Ty, 10))->isArrayTy());
-  // Check isPointerTy().
-  EXPECT_TRUE(Ctx.getType(llvm::PointerType::get(C, 0u))->isPointerTy());
-  // Check isPtrOrPtrVectroTy().
-  EXPECT_TRUE(
-      Ctx.getType(llvm::FixedVectorType::get(llvm::PointerType::get(C, 0u), 8u))
-          ->isPtrOrPtrVectorTy());
-  // Check isVectorTy().
-  EXPECT_TRUE(
-      Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8u))->isVectorTy());
-  // Check canLosslesslyBitCastTo().
-  auto *VecTy32x4 = Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 4u));
-  auto *VecTy32x2 = Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 2u));
-  auto *VecTy8x16 = Ctx.getType(llvm::FixedVectorType::get(LLVMInt8Ty, 16u));
-  EXPECT_TRUE(VecTy32x4->canLosslesslyBitCastTo(VecTy8x16));
-  EXPECT_FALSE(VecTy32x4->canLosslesslyBitCastTo(VecTy32x2));
-  // Check isEmptyTy().
-  EXPECT_TRUE(Ctx.getType(llvm::StructType::get(C))->isEmptyTy());
-  // Check isFirstClassType().
-  EXPECT_TRUE(Int32Ty->isFirstClassType());
-  // Check isSingleValueType().
-  EXPECT_TRUE(Int32Ty->isSingleValueType());
-  // Check isAggregateType().
-  EXPECT_FALSE(Int32Ty->isAggregateType());
-  // Check isSized().
-  SmallPtrSet<sandboxir::Type *, 1> Visited;
-  EXPECT_TRUE(Int32Ty->isSized(&Visited));
-  // Check getPrimitiveSizeInBits().
-  EXPECT_EQ(VecTy32x2->getPrimitiveSizeInBits(), 32u * 2);
-  // Check getScalarSizeInBits().
-  EXPECT_EQ(VecTy32x2->getScalarSizeInBits(), 32u);
-  // Check getFPMantissaWidth().
-  EXPECT_EQ(FloatTy->getFPMantissaWidth(), LLVMFloatTy->getFPMantissaWidth());
-  // Check isIEEELikeFPTy().
-  EXPECT_EQ(FloatTy->isIEEELikeFPTy(), LLVMFloatTy->isIEEELikeFPTy());
-  // Check getScalarType().
-  EXPECT_EQ(
-      Ctx.getType(llvm::FixedVectorType::get(LLVMInt32Ty, 8u))->getScalarType(),
-      Int32Ty);
-
-#define CHK_GET(TY)                                                            \
-  EXPECT_EQ(Ctx.getType(llvm::Type::get##TY##Ty(C)),                           \
-            sandboxir::Type::get##TY##Ty(Ctx))
-  // Check getInt64Ty().
-  CHK_GET(Int64);
-  // Check getInt32Ty().
-  CHK_GET(Int32);
-  // Check getInt16Ty().
-  CHK_GET(Int16);
-  // Check getInt8Ty().
-  CHK_GET(Int8);
-  // Check getInt1Ty().
-  CHK_GET(Int1);
-  // Check getDoubleTy().
-  CHK_GET(Double);
-  // Check getFloatTy().
-  CHK_GET(Float);
-}
-
-TEST_F(SandboxTypeTest, PointerType) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation.
-  auto *PtrTy = cast<sandboxir::PointerType>(F->getArg(0)->getType());
-  // Check get(Ctx, AddressSpace).
-  auto *NewPtrTy2 = sandboxir::PointerType::get(Ctx, 0u);
-  EXPECT_EQ(NewPtrTy2, PtrTy);
-}
-
-TEST_F(SandboxTypeTest, ArrayType) {
-  parseIR(C, R"IR(
-define void @foo([2 x i8] %v0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation.
-  [[maybe_unused]] auto *ArrayTy =
-      cast<sandboxir::ArrayType>(F->getArg(0)->getType());
-  // Check get().
-  auto *NewArrayTy =
-      sandboxir::ArrayType::get(sandboxir::Type::getInt8Ty(Ctx), 2u);
-  EXPECT_EQ(NewArrayTy, ArrayTy);
-}
-
-TEST_F(SandboxTypeTest, StructType) {
-  parseIR(C, R"IR(
-define void @foo({i32, i8} %v0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
-  auto *Int8Ty = sandboxir::Type::getInt8Ty(Ctx);
-  // Check classof(), creation.
-  [[maybe_unused]] auto *StructTy =
-      cast<sandboxir::StructType>(F->getArg(0)->getType());
-  // Check get().
-  auto *NewStructTy = sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty});
-  EXPECT_EQ(NewStructTy, StructTy);
-  // Check get(Packed).
-  auto *NewStructTyPacked =
-      sandboxir::StructType::get(Ctx, {Int32Ty, Int8Ty}, /*Packed=*/true);
-  EXPECT_NE(NewStructTyPacked, StructTy);
-  EXPECT_TRUE(NewStructTyPacked->isPacked());
-}
-
-TEST_F(SandboxTypeTest, VectorType) {
-  parseIR(C, R"IR(
-define void @foo(<4 x i16> %vi0, <4 x float> %vf1, i8 %i0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation, accessors
-  auto *VecTy = cast<sandboxir::VectorType>(F->getArg(0)->getType());
-  EXPECT_TRUE(VecTy->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(VecTy->getElementCount(), ElementCount::getFixed(4));
-
-  // get(ElementType, NumElements, Scalable)
-  EXPECT_EQ(sandboxir::VectorType::get(sandboxir::Type::getInt16Ty(Ctx), 4,
-                                       /*Scalable=*/false),
-            F->getArg(0)->getType());
-  // get(ElementType, Other)
-  EXPECT_EQ(sandboxir::VectorType::get(
-                sandboxir::Type::getInt16Ty(Ctx),
-                cast<sandboxir::VectorType>(F->getArg(0)->getType())),
-            F->getArg(0)->getType());
-  auto *FVecTy = cast<sandboxir::VectorType>(F->getArg(1)->getType());
-  EXPECT_TRUE(FVecTy->getElementType()->isFloatTy());
-  // getInteger
-  auto *IVecTy = sandboxir::VectorType::getInteger(FVecTy);
-  EXPECT_TRUE(IVecTy->getElementType()->isIntegerTy(32));
-  EXPECT_EQ(IVecTy->getElementCount(), FVecTy->getElementCount());
-  // getExtendedElementCountVectorType
-  auto *ExtVecTy = sandboxir::VectorType::getExtendedElementVectorType(IVecTy);
-  EXPECT_TRUE(ExtVecTy->getElementType()->isIntegerTy(64));
-  EXPECT_EQ(ExtVecTy->getElementCount(), VecTy->getElementCount());
-  // getTruncatedElementVectorType
-  auto *TruncVecTy =
-      sandboxir::VectorType::getTruncatedElementVectorType(IVecTy);
-  EXPECT_TRUE(TruncVecTy->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(TruncVecTy->getElementCount(), VecTy->getElementCount());
-  // getSubdividedVectorType
-  auto *SubVecTy = sandboxir::VectorType::getSubdividedVectorType(VecTy, 1);
-  EXPECT_TRUE(SubVecTy->getElementType()->isIntegerTy(8));
-  EXPECT_EQ(SubVecTy->getElementCount(), ElementCount::getFixed(8));
-  // getHalfElementsVectorType
-  auto *HalfVecTy = sandboxir::VectorType::getHalfElementsVectorType(VecTy);
-  EXPECT_TRUE(HalfVecTy->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(HalfVecTy->getElementCount(), ElementCount::getFixed(2));
-  // getDoubleElementsVectorType
-  auto *DoubleVecTy = sandboxir::VectorType::getDoubleElementsVectorType(VecTy);
-  EXPECT_TRUE(DoubleVecTy->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(DoubleVecTy->getElementCount(), ElementCount::getFixed(8));
-  // isValidElementType
-  auto *I8Type = F->getArg(2)->getType();
-  EXPECT_TRUE(I8Type->isIntegerTy());
-  EXPECT_TRUE(sandboxir::VectorType::isValidElementType(I8Type));
-  EXPECT_FALSE(sandboxir::VectorType::isValidElementType(FVecTy));
-}
-
-TEST_F(SandboxTypeTest, FixedVectorType) {
-  parseIR(C, R"IR(
-define void @foo(<4 x i16> %vi0, <4 x float> %vf1, i8 %i0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation, accessors
-  auto *Vec4i16Ty = cast<sandboxir::FixedVectorType>(F->getArg(0)->getType());
-  EXPECT_TRUE(Vec4i16Ty->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(Vec4i16Ty->getElementCount(), ElementCount::getFixed(4));
-
-  // get(ElementType, NumElements)
-  EXPECT_EQ(
-      sandboxir::FixedVectorType::get(sandboxir::Type::getInt16Ty(Ctx), 4),
-      F->getArg(0)->getType());
-  // get(ElementType, Other)
-  EXPECT_EQ(sandboxir::FixedVectorType::get(
-                sandboxir::Type::getInt16Ty(Ctx),
-                cast<sandboxir::FixedVectorType>(F->getArg(0)->getType())),
-            F->getArg(0)->getType());
-  auto *Vec4FTy = cast<sandboxir::FixedVectorType>(F->getArg(1)->getType());
-  EXPECT_TRUE(Vec4FTy->getElementType()->isFloatTy());
-  // getInteger
-  auto *Vec4i32Ty = sandboxir::FixedVectorType::getInteger(Vec4FTy);
-  EXPECT_TRUE(Vec4i32Ty->getElementType()->isIntegerTy(32));
-  EXPECT_EQ(Vec4i32Ty->getElementCount(), Vec4FTy->getElementCount());
-  // getExtendedElementCountVectorType
-  auto *Vec4i64Ty =
-      sandboxir::FixedVectorType::getExtendedElementVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec4i64Ty->getElementType()->isIntegerTy(32));
-  EXPECT_EQ(Vec4i64Ty->getElementCount(), Vec4i16Ty->getElementCount());
-  // getTruncatedElementVectorType
-  auto *Vec4i8Ty =
-      sandboxir::FixedVectorType::getTruncatedElementVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec4i8Ty->getElementType()->isIntegerTy(8));
-  EXPECT_EQ(Vec4i8Ty->getElementCount(), Vec4i8Ty->getElementCount());
-  // getSubdividedVectorType
-  auto *Vec8i8Ty =
-      sandboxir::FixedVectorType::getSubdividedVectorType(Vec4i16Ty, 1);
-  EXPECT_TRUE(Vec8i8Ty->getElementType()->isIntegerTy(8));
-  EXPECT_EQ(Vec8i8Ty->getElementCount(), ElementCount::getFixed(8));
-  // getNumElements
-  EXPECT_EQ(Vec8i8Ty->getNumElements(), 8u);
-  // getHalfElementsVectorType
-  auto *Vec2i16Ty =
-      sandboxir::FixedVectorType::getHalfElementsVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec2i16Ty->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(Vec2i16Ty->getElementCount(), ElementCount::getFixed(2));
-  // getDoubleElementsVectorType
-  auto *Vec8i16Ty =
-      sandboxir::FixedVectorType::getDoubleElementsVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec8i16Ty->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(Vec8i16Ty->getElementCount(), ElementCount::getFixed(8));
-}
-
-TEST_F(SandboxTypeTest, ScalableVectorType) {
-  parseIR(C, R"IR(
-define void @foo(<vscale x 4 x i16> %vi0, <vscale x 4 x float> %vf1, i8 %i0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation, accessors
-  auto *Vec4i16Ty =
-      cast<sandboxir::ScalableVectorType>(F->getArg(0)->getType());
-  EXPECT_TRUE(Vec4i16Ty->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(Vec4i16Ty->getMinNumElements(), 4u);
-
-  // get(ElementType, NumElements)
-  EXPECT_EQ(
-      sandboxir::ScalableVectorType::get(sandboxir::Type::getInt16Ty(Ctx), 4),
-      F->getArg(0)->getType());
-  // get(ElementType, Other)
-  EXPECT_EQ(sandboxir::ScalableVectorType::get(
-                sandboxir::Type::getInt16Ty(Ctx),
-                cast<sandboxir::ScalableVectorType>(F->getArg(0)->getType())),
-            F->getArg(0)->getType());
-  auto *Vec4FTy = cast<sandboxir::ScalableVectorType>(F->getArg(1)->getType());
-  EXPECT_TRUE(Vec4FTy->getElementType()->isFloatTy());
-  // getInteger
-  auto *Vec4i32Ty = sandboxir::ScalableVectorType::getInteger(Vec4FTy);
-  EXPECT_TRUE(Vec4i32Ty->getElementType()->isIntegerTy(32));
-  EXPECT_EQ(Vec4i32Ty->getMinNumElements(), Vec4FTy->getMinNumElements());
-  // getExtendedElementCountVectorType
-  auto *Vec4i64Ty =
-      sandboxir::ScalableVectorType::getExtendedElementVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec4i64Ty->getElementType()->isIntegerTy(32));
-  EXPECT_EQ(Vec4i64Ty->getMinNumElements(), Vec4i16Ty->getMinNumElements());
-  // getTruncatedElementVectorType
-  auto *Vec4i8Ty =
-      sandboxir::ScalableVectorType::getTruncatedElementVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec4i8Ty->getElementType()->isIntegerTy(8));
-  EXPECT_EQ(Vec4i8Ty->getMinNumElements(), Vec4i8Ty->getMinNumElements());
-  // getSubdividedVectorType
-  auto *Vec8i8Ty =
-      sandboxir::ScalableVectorType::getSubdividedVectorType(Vec4i16Ty, 1);
-  EXPECT_TRUE(Vec8i8Ty->getElementType()->isIntegerTy(8));
-  EXPECT_EQ(Vec8i8Ty->getMinNumElements(), 8u);
-  // getMinNumElements
-  EXPECT_EQ(Vec8i8Ty->getMinNumElements(), 8u);
-  // getHalfElementsVectorType
-  auto *Vec2i16Ty =
-      sandboxir::ScalableVectorType::getHalfElementsVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec2i16Ty->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(Vec2i16Ty->getMinNumElements(), 2u);
-  // getDoubleElementsVectorType
-  auto *Vec8i16Ty =
-      sandboxir::ScalableVectorType::getDoubleElementsVectorType(Vec4i16Ty);
-  EXPECT_TRUE(Vec8i16Ty->getElementType()->isIntegerTy(16));
-  EXPECT_EQ(Vec8i16Ty->getMinNumElements(), 8u);
-}
-
-TEST_F(SandboxTypeTest, FunctionType) {
-  parseIR(C, R"IR(
-define void @foo() {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation.
-  [[maybe_unused]] auto *FTy =
-      cast<sandboxir::FunctionType>(F->getFunctionType());
-}
-
-TEST_F(SandboxTypeTest, IntegerType) {
-  parseIR(C, R"IR(
-define void @foo(i32 %v0) {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  // Check classof(), creation.
-  auto *Int32Ty = cast<sandboxir::IntegerType>(F->getArg(0)->getType());
-  // Check get().
-  auto *NewInt32Ty = sandboxir::IntegerType::get(Ctx, 32u);
-  EXPECT_EQ(NewInt32Ty, Int32Ty);
-}
diff --git a/llvm/unittests/SandboxIR/UtilsTest.cpp b/llvm/unittests/SandboxIR/UtilsTest.cpp
deleted file mode 100644
index 2bef48616beb7..0000000000000
--- a/llvm/unittests/SandboxIR/UtilsTest.cpp
+++ /dev/null
@@ -1,249 +0,0 @@
-//===- UtilsTest.cpp ------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/SandboxIR/Utils.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/BasicBlock.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/IR/Module.h"
-#include "llvm/SandboxIR/Constant.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct UtilsTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("UtilsTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-TEST_F(UtilsTest, getMemoryLocation) {
-  parseIR(C, R"IR(
-define void @foo(ptr %arg0) {
-  %ld = load i8, ptr %arg0
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  auto *LLVMBB = &*LLVMF->begin();
-  auto *LLVMLd = cast<llvm::LoadInst>(&*LLVMBB->begin());
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto *Ld = cast<sandboxir::LoadInst>(&*BB->begin());
-  EXPECT_EQ(sandboxir::Utils::memoryLocationGetOrNone(Ld),
-            MemoryLocation::getOrNone(LLVMLd));
-}
-
-TEST_F(UtilsTest, GetPointerDiffInBytes) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr inbounds float, ptr %ptr, i64 0
-  %gep1 = getelementptr inbounds float, ptr %ptr, i64 1
-  %gep2 = getelementptr inbounds float, ptr %ptr, i64 2
-  %gep3 = getelementptr inbounds float, ptr %ptr, i64 3
-
-  %ld0 = load float, ptr %gep0
-  %ld1 = load float, ptr %gep1
-  %ld2 = load float, ptr %gep2
-  %ld3 = load float, ptr %gep3
-
-  %v2ld0 = load <2 x float>, ptr %gep0
-  %v2ld1 = load <2 x float>, ptr %gep1
-  %v2ld2 = load <2 x float>, ptr %gep2
-  %v2ld3 = load <2 x float>, ptr %gep3
-
-  %v3ld0 = load <3 x float>, ptr %gep0
-  %v3ld1 = load <3 x float>, ptr %gep1
-  %v3ld2 = load <3 x float>, ptr %gep2
-  %v3ld3 = load <3 x float>, ptr %gep3
-  ret void
-}
-)IR");
-  llvm::Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  AssumptionCache AC(LLVMF);
-  BasicAAResult BAA(DL, LLVMF, TLI, AC, &DT);
-  AAResults AA(TLI);
-  AA.addAAResult(BAA);
-  LoopInfo LI(DT);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-  sandboxir::Context Ctx(C);
-
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = std::next(BB.begin(), 4);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  [[maybe_unused]] auto *L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  [[maybe_unused]] auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);
-  [[maybe_unused]] auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);
-  [[maybe_unused]] auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  // getPointerDiffInBytes
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, L1, SE), 4);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, L2, SE), 8);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L1, L0, SE), -4);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V2L0, SE), 0);
-
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V2L1, SE), 4);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(L0, V3L1, SE), 4);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L0, V2L2, SE), 8);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L0, V2L3, SE), 12);
-  EXPECT_EQ(*sandboxir::Utils::getPointerDiffInBytes(V2L3, V2L0, SE), -12);
-
-  // atLowerAddress
-  EXPECT_TRUE(sandboxir::Utils::atLowerAddress(L0, L1, SE));
-  EXPECT_FALSE(sandboxir::Utils::atLowerAddress(L1, L0, SE));
-  EXPECT_FALSE(sandboxir::Utils::atLowerAddress(L3, V3L3, SE));
-}
-
-TEST_F(UtilsTest, GetExpected) {
-  parseIR(C, R"IR(
-define float @foo(float %v, ptr %ptr) {
-  %add = fadd float %v, %v
-  store float %v, ptr %ptr
-  ret float %v
-}
-define void @bar(float %v, ptr %ptr) {
-  ret void
-}
-)IR");
-  llvm::Function &Foo = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  Ctx.createFunction(&Foo);
-  auto *FooBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Foo.begin()));
-  auto FooIt = FooBB->begin();
-  auto Add = cast<sandboxir::Instruction>(&*FooIt++);
-  auto *S0 = cast<sandboxir::Instruction>(&*FooIt++);
-  auto *RetF = cast<sandboxir::Instruction>(&*FooIt++);
-  // getExpectedValue
-  EXPECT_EQ(sandboxir::Utils::getExpectedValue(Add), Add);
-  EXPECT_EQ(sandboxir::Utils::getExpectedValue(S0),
-            cast<sandboxir::StoreInst>(S0)->getValueOperand());
-  EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetF),
-            cast<sandboxir::ReturnInst>(RetF)->getReturnValue());
-  // getExpectedType
-  EXPECT_EQ(sandboxir::Utils::getExpectedType(Add), Add->getType());
-  EXPECT_EQ(sandboxir::Utils::getExpectedType(S0),
-            cast<sandboxir::StoreInst>(S0)->getValueOperand()->getType());
-  EXPECT_EQ(sandboxir::Utils::getExpectedType(RetF),
-            cast<sandboxir::ReturnInst>(RetF)->getReturnValue()->getType());
-
-  // getExpectedValue for void returns
-  llvm::Function &Bar = *M->getFunction("bar");
-  Ctx.createFunction(&Bar);
-  auto *BarBB = cast<sandboxir::BasicBlock>(Ctx.getValue(&*Bar.begin()));
-  auto BarIt = BarBB->begin();
-  auto *RetV = cast<sandboxir::Instruction>(&*BarIt++);
-  EXPECT_EQ(sandboxir::Utils::getExpectedValue(RetV), nullptr);
-}
-
-TEST_F(UtilsTest, GetNumBits) {
-  parseIR(C, R"IR(
-define void @foo(float %arg0, double %arg1, i8 %arg2, i64 %arg3, ptr %arg4) {
-bb0:
-  %ld0 = load float, ptr %arg4
-  %ld1 = load double, ptr %arg4
-  %ld2 = load i8, ptr %arg4
-  %ld3 = load i64, ptr %arg4
-  ret void
-}
-)IR");
-  llvm::Function &Foo = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&Foo);
-  const DataLayout &DL = M->getDataLayout();
-  // getNumBits for scalars via the Value overload
-  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(0), DL),
-            DL.getTypeSizeInBits(Type::getFloatTy(C)));
-  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(1), DL),
-            DL.getTypeSizeInBits(Type::getDoubleTy(C)));
-  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(2), DL), 8u);
-  EXPECT_EQ(sandboxir::Utils::getNumBits(F->getArg(3), DL), 64u);
-
-  auto &BB = *F->begin();
-  auto It = BB.begin();
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L3 = cast<sandboxir::LoadInst>(&*It++);
-  // getNumBits for scalars via the Instruction overload
-  EXPECT_EQ(sandboxir::Utils::getNumBits(L0),
-            DL.getTypeSizeInBits(Type::getFloatTy(C)));
-  EXPECT_EQ(sandboxir::Utils::getNumBits(L1),
-            DL.getTypeSizeInBits(Type::getDoubleTy(C)));
-  EXPECT_EQ(sandboxir::Utils::getNumBits(L2), 8u);
-  EXPECT_EQ(sandboxir::Utils::getNumBits(L3), 64u);
-}
-
-TEST_F(UtilsTest, GetMemBase) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptrA, float %val, ptr %ptrB) {
-bb:
-  %gepA0 = getelementptr float, ptr %ptrA, i32 0
-  %gepA1 = getelementptr float, ptr %ptrA, i32 1
-  %gepB0 = getelementptr float, ptr %ptrB, i32 0
-  %gepB1 = getelementptr float, ptr %ptrB, i32 1
-  store float %val, ptr %gepA0
-  store float %val, ptr %gepA1
-  store float %val, ptr %gepB0
-  store float %val, ptr %gepB1
-  ret void
-}
-)IR");
-  llvm::Function &Foo = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(&Foo);
-
-  auto It = std::next(F->begin()->begin(), 4);
-  auto *St0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *St1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *St2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *St3 = cast<sandboxir::StoreInst>(&*It++);
-  EXPECT_EQ(sandboxir::Utils::getMemInstructionBase(St0),
-            sandboxir::Utils::getMemInstructionBase(St1));
-  EXPECT_EQ(sandboxir::Utils::getMemInstructionBase(St2),
-            sandboxir::Utils::getMemInstructionBase(St3));
-  EXPECT_NE(sandboxir::Utils::getMemInstructionBase(St0),
-            sandboxir::Utils::getMemInstructionBase(St3));
-}
diff --git a/llvm/unittests/Transforms/Vectorize/CMakeLists.txt b/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
index af111a29b90e5..6158cf2f2be93 100644
--- a/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
+++ b/llvm/unittests/Transforms/Vectorize/CMakeLists.txt
@@ -1,5 +1,3 @@
-add_subdirectory(SandboxVectorizer)
-
 set(LLVM_LINK_COMPONENTS
   Analysis
   Core
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
deleted file mode 100644
index 104a27975cfc0..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-set(LLVM_LINK_COMPONENTS
-  Analysis
-  Core
-  Vectorize
-  AsmParser
-  TargetParser
-  SandboxIR
-  )
-
-add_llvm_unittest(SandboxVectorizerTests
-  DependencyGraphTest.cpp
-  InstrMapsTest.cpp
-  IntervalTest.cpp
-  LegalityTest.cpp
-  SandboxVectorizerTest.cpp
-  SchedulerTest.cpp
-  SeedCollectorTest.cpp	
-  VecUtilsTest.cpp
-)
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp
deleted file mode 100644
index 721eda16c7e11..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/DependencyGraphTest.cpp
+++ /dev/null
@@ -1,1192 +0,0 @@
-//===- DependencyGraphTest.cpp --------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/DependencyGraph.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock-matchers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct DependencyGraphTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-  std::unique_ptr<AssumptionCache> AC;
-  std::unique_ptr<DominatorTree> DT;
-  std::unique_ptr<BasicAAResult> BAA;
-  std::unique_ptr<AAResults> AA;
-  std::unique_ptr<TargetLibraryInfoImpl> TLII;
-  std::unique_ptr<TargetLibraryInfo> TLI;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M) {
-      Err.print("DependencyGraphTest", errs());
-      return;
-    }
-
-    TLII = std::make_unique<TargetLibraryInfoImpl>(M->getTargetTriple());
-    TLI = std::make_unique<TargetLibraryInfo>(*TLII);
-  }
-
-  AAResults &getAA(llvm::Function &LLVMF) {
-    AA = std::make_unique<AAResults>(*TLI);
-    AC = std::make_unique<AssumptionCache>(LLVMF);
-    DT = std::make_unique<DominatorTree>(LLVMF);
-    BAA = std::make_unique<BasicAAResult>(M->getDataLayout(), LLVMF, *TLI, *AC,
-                                          DT.get());
-    AA->addAAResult(*BAA);
-    return *AA;
-  }
-  /// \Returns true if there is a dependency: SrcN->DstN.
-  bool memDependency(sandboxir::DGNode *SrcN, sandboxir::DGNode *DstN) {
-    if (auto *MemDstN = dyn_cast<sandboxir::MemDGNode>(DstN))
-      return MemDstN->hasMemPred(SrcN);
-    return false;
-  }
-};
-
-TEST_F(DependencyGraphTest, isStackSaveOrRestoreIntrinsic) {
-  parseIR(C, R"IR(
-declare void @llvm.sideeffect()
-define void @foo(i8 %v1, ptr %ptr) {
-  %add = add i8 %v1, %v1
-  %stacksave = call ptr @llvm.stacksave()
-  call void @llvm.stackrestore(ptr %stacksave)
-  call void @llvm.sideeffect()
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *StackSave = cast<sandboxir::CallInst>(&*It++);
-  auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
-  auto *Other = cast<sandboxir::CallInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  using DGNode = sandboxir::DGNode;
-  EXPECT_FALSE(DGNode::isStackSaveOrRestoreIntrinsic(Add));
-  EXPECT_TRUE(DGNode::isStackSaveOrRestoreIntrinsic(StackSave));
-  EXPECT_TRUE(DGNode::isStackSaveOrRestoreIntrinsic(StackRestore));
-  EXPECT_FALSE(DGNode::isStackSaveOrRestoreIntrinsic(Other));
-  EXPECT_FALSE(DGNode::isStackSaveOrRestoreIntrinsic(Ret));
-}
-
-TEST_F(DependencyGraphTest, Instruction_isMemDepCandidate) {
-  parseIR(C, R"IR(
-declare void @llvm.fake.use(...)
-declare void @llvm.sideeffect()
-declare void @llvm.pseudoprobe(i64, i64, i32, i64)
-declare void @bar()
-define void @foo(i8 %v1, ptr %ptr) {
-  %add0 = add i8 %v1, %v1
-  %ld0 = load i8, ptr %ptr
-  store i8 %v1, ptr %ptr
-  call void @llvm.sideeffect()
-  call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
-  call void @llvm.fake.use(ptr %ptr)
-  call void @bar()
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *St0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *SideEffect0 = cast<sandboxir::CallInst>(&*It++);
-  auto *PseudoProbe0 = cast<sandboxir::CallInst>(&*It++);
-  auto *OtherIntrinsic0 = cast<sandboxir::CallInst>(&*It++);
-  auto *CallBar = cast<sandboxir::CallInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  using DGNode = sandboxir::DGNode;
-
-  EXPECT_FALSE(DGNode::isMemDepCandidate(Add0));
-  EXPECT_TRUE(DGNode::isMemDepCandidate(Ld0));
-  EXPECT_TRUE(DGNode::isMemDepCandidate(St0));
-  EXPECT_FALSE(DGNode::isMemDepCandidate(SideEffect0));
-  EXPECT_FALSE(DGNode::isMemDepCandidate(PseudoProbe0));
-  EXPECT_TRUE(DGNode::isMemDepCandidate(OtherIntrinsic0));
-  EXPECT_TRUE(DGNode::isMemDepCandidate(CallBar));
-  EXPECT_FALSE(DGNode::isMemDepCandidate(Ret));
-}
-
-TEST_F(DependencyGraphTest, Instruction_isMemIntrinsic) {
-  parseIR(C, R"IR(
-declare void @llvm.sideeffect()
-declare void @llvm.pseudoprobe(i64)
-declare void @llvm.assume(i1)
-
-define void @foo(ptr %ptr, i1 %cond) {
-  call void @llvm.sideeffect()
-  call void @llvm.pseudoprobe(i64 42)
-  call void @llvm.assume(i1 %cond)
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  sandboxir::Function *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *SideEffect = cast<sandboxir::IntrinsicInst>(&*It++);
-  auto *PseudoProbe = cast<sandboxir::IntrinsicInst>(&*It++);
-  auto *OtherIntrinsic = cast<sandboxir::IntrinsicInst>(&*It++);
-
-  using DGNode = sandboxir::DGNode;
-  EXPECT_FALSE(DGNode::isMemIntrinsic(SideEffect));
-  EXPECT_FALSE(DGNode::isMemIntrinsic(PseudoProbe));
-  EXPECT_TRUE(DGNode::isMemIntrinsic(OtherIntrinsic));
-}
-
-TEST_F(DependencyGraphTest, MemDGNode) {
-  parseIR(C, R"IR(
-declare void @llvm.sideeffect()
-declare void @llvm.pseudoprobe(i64, i64, i32, i64)
-declare void @llvm.fake.use(...)
-declare void @bar()
-define void @foo(i8 %v1, ptr %ptr) {
-  store i8 %v1, ptr %ptr
-  %ld0 = load i8, ptr %ptr
-  %add = add i8 %v1, %v1
-  %stacksave = call ptr @llvm.stacksave()
-  call void @llvm.stackrestore(ptr %stacksave)
-  call void @llvm.sideeffect()
-  call void @llvm.pseudoprobe(i64 42, i64 1, i32 0, i64 -1)
-  call void @llvm.fake.use(ptr %ptr)
-  call void @bar()
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Store = cast<sandboxir::StoreInst>(&*It++);
-  auto *Load = cast<sandboxir::LoadInst>(&*It++);
-  auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *StackSave = cast<sandboxir::CallInst>(&*It++);
-  auto *StackRestore = cast<sandboxir::CallInst>(&*It++);
-  auto *SideEffect = cast<sandboxir::CallInst>(&*It++);
-  auto *PseudoProbe = cast<sandboxir::CallInst>(&*It++);
-  auto *FakeUse = cast<sandboxir::CallInst>(&*It++);
-  auto *Call = cast<sandboxir::CallInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  EXPECT_TRUE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(Store)));
-  EXPECT_TRUE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(Load)));
-  EXPECT_FALSE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(Add)));
-  EXPECT_TRUE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(StackSave)));
-  EXPECT_TRUE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(StackRestore)));
-  EXPECT_FALSE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(SideEffect)));
-  EXPECT_FALSE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(PseudoProbe)));
-  EXPECT_TRUE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(FakeUse)));
-  EXPECT_TRUE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(Call)));
-  EXPECT_FALSE(isa<llvm::sandboxir::MemDGNode>(DAG.getNode(Ret)));
-}
-
-TEST_F(DependencyGraphTest, Basic) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  auto Span = DAG.extend({&*BB->begin(), BB->getTerminator()});
-  // Check extend().
-  EXPECT_EQ(Span.top(), &*BB->begin());
-  EXPECT_EQ(Span.bottom(), BB->getTerminator());
-
-  auto *N0 = cast<sandboxir::MemDGNode>(DAG.getNode(S0));
-  auto *N1 = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-  auto *N2 = DAG.getNode(Ret);
-
-  // Check getInstruction().
-  EXPECT_EQ(N0->getInstruction(), S0);
-  EXPECT_EQ(N1->getInstruction(), S1);
-  // Check hasMemPred()
-  EXPECT_TRUE(N1->hasMemPred(N0));
-  EXPECT_FALSE(N0->hasMemPred(N1));
-
-  // Check preds().
-  EXPECT_TRUE(N0->preds(DAG).empty());
-  EXPECT_THAT(N1->preds(DAG), testing::ElementsAre(N0));
-
-  // Check memPreds().
-  EXPECT_TRUE(N0->memPreds().empty());
-  EXPECT_THAT(N1->memPreds(), testing::ElementsAre(N0));
-  EXPECT_TRUE(N2->preds(DAG).empty());
-
-  // Check memSuccs().
-  EXPECT_THAT(N0->memSuccs(), testing::ElementsAre(N1));
-
-  // Check UnscheduledSuccs.
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u); // N1
-  EXPECT_EQ(N1->getNumUnscheduledSuccs(), 0u);
-  EXPECT_EQ(N2->getNumUnscheduledSuccs(), 0u);
-
-  // Check decrUnscheduledSuccs.
-  N0->decrUnscheduledSuccs();
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
-#ifndef NDEBUG
-  EXPECT_DEATH(N0->decrUnscheduledSuccs(), ".*Counting.*");
-#endif // NDEBUG
-
-  // Check scheduled(), setScheduled().
-  EXPECT_FALSE(N0->scheduled());
-  N0->setScheduled(true);
-  EXPECT_TRUE(N0->scheduled());
-}
-
-TEST_F(DependencyGraphTest, AddRemoveMemPred) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto *N0 = cast<sandboxir::MemDGNode>(DAG.getNode(S0));
-  auto *N1 = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-
-  // Check removeMemPred().
-  EXPECT_FALSE(N0->memSuccs().empty());
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
-  N1->removeMemPred(N0);
-  EXPECT_TRUE(N1->memPreds().empty());
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
-
-  // Check addMemPred().
-  N1->addMemPred(N0);
-  EXPECT_THAT(N1->memPreds(), testing::UnorderedElementsAre(N0));
-  EXPECT_THAT(N0->memSuccs(), testing::UnorderedElementsAre(N1));
-  EXPECT_THAT(N0->getNumUnscheduledSuccs(), 1u);
-}
-
-TEST_F(DependencyGraphTest, Preds) {
-  parseIR(C, R"IR(
-declare ptr @bar(i8)
-define i8 @foo(i8 %v0, i8 %v1) {
-  %add0 = add i8 %v0, %v0
-  %add1 = add i8 %v1, %v1
-  %add2 = add i8 %add0, %add1
-  %ptr = call ptr @bar(i8 %add1)
-  store i8 %add2, ptr %ptr
-  ret i8 %add2
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-
-  auto *AddN0 = DAG.getNode(cast<sandboxir::BinaryOperator>(&*It++));
-  auto *AddN1 = DAG.getNode(cast<sandboxir::BinaryOperator>(&*It++));
-  auto *AddN2 = DAG.getNode(cast<sandboxir::BinaryOperator>(&*It++));
-  auto *CallN = DAG.getNode(cast<sandboxir::CallInst>(&*It++));
-  auto *StN = DAG.getNode(cast<sandboxir::StoreInst>(&*It++));
-  auto *RetN = DAG.getNode(cast<sandboxir::ReturnInst>(&*It++));
-
-  // Check preds().
-  EXPECT_THAT(AddN0->preds(DAG), testing::ElementsAre());
-  EXPECT_THAT(AddN1->preds(DAG), testing::ElementsAre());
-  EXPECT_THAT(AddN2->preds(DAG), testing::ElementsAre(AddN0, AddN1));
-  EXPECT_THAT(CallN->preds(DAG), testing::ElementsAre(AddN1));
-  EXPECT_THAT(StN->preds(DAG),
-              testing::UnorderedElementsAre(CallN, CallN, AddN2));
-  EXPECT_THAT(RetN->preds(DAG), testing::ElementsAre(AddN2));
-
-  // Check UnscheduledSuccs.
-  EXPECT_EQ(AddN0->getNumUnscheduledSuccs(), 1u); // AddN2
-  EXPECT_EQ(AddN1->getNumUnscheduledSuccs(), 2u); // AddN2, CallN
-  EXPECT_EQ(AddN2->getNumUnscheduledSuccs(), 2u); // StN, RetN
-  EXPECT_EQ(CallN->getNumUnscheduledSuccs(), 2u); // StN, StN
-  EXPECT_EQ(StN->getNumUnscheduledSuccs(), 0u);
-  EXPECT_EQ(RetN->getNumUnscheduledSuccs(), 0u);
-}
-
-// Make sure we don't get null predecessors even if they are outside the DAG.
-TEST_F(DependencyGraphTest, NonNullPreds) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %val) {
-  %gep = getelementptr i8, ptr %ptr, i32 0
-  store i8 %val, ptr %gep
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  [[maybe_unused]] auto *GEP = cast<sandboxir::GetElementPtrInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  // The DAG doesn't include GEP.
-  DAG.extend({S0, Ret});
-
-  auto *S0N = DAG.getNode(S0);
-  // S0 has one operand (the GEP) that is outside the DAG and no memory
-  // predecessors. So pred_begin() should be == pred_end().
-  auto PredIt = S0N->preds_begin(DAG);
-  auto PredItE = S0N->preds_end(DAG);
-  EXPECT_EQ(PredIt, PredItE);
-  // Check preds().
-  for (auto *PredN : S0N->preds(DAG))
-    EXPECT_NE(PredN, nullptr);
-}
-
-TEST_F(DependencyGraphTest, MemDGNode_getPrevNode_getNextNode) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr
-  add i8 %v0, %v0
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  [[maybe_unused]] auto *Add = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-
-  auto *S0N = cast<sandboxir::MemDGNode>(DAG.getNode(S0));
-  auto *S1N = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-
-  EXPECT_EQ(S0N->getPrevNode(), nullptr);
-  EXPECT_EQ(S0N->getNextNode(), S1N);
-
-  EXPECT_EQ(S1N->getPrevNode(), S0N);
-  EXPECT_EQ(S1N->getNextNode(), nullptr);
-}
-
-TEST_F(DependencyGraphTest, DGNodeRange) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  add i8 %v0, %v0
-  store i8 %v0, ptr %ptr
-  add i8 %v0, %v0
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-
-  auto *S0N = cast<sandboxir::MemDGNode>(DAG.getNode(S0));
-  auto *S1N = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-
-  // Check getTopMemDGNode().
-  using B = sandboxir::MemDGNodeIntervalBuilder;
-  using InstrInterval = sandboxir::Interval<sandboxir::Instruction>;
-  EXPECT_EQ(B::getTopMemDGNode(InstrInterval(S0, S0), DAG), S0N);
-  EXPECT_EQ(B::getTopMemDGNode(InstrInterval(S0, Ret), DAG), S0N);
-  EXPECT_EQ(B::getTopMemDGNode(InstrInterval(Add0, Add1), DAG), S0N);
-  EXPECT_EQ(B::getTopMemDGNode(InstrInterval(Add0, Add0), DAG), nullptr);
-
-  // Check getBotMemDGNode().
-  EXPECT_EQ(B::getBotMemDGNode(InstrInterval(S1, S1), DAG), S1N);
-  EXPECT_EQ(B::getBotMemDGNode(InstrInterval(Add0, S1), DAG), S1N);
-  EXPECT_EQ(B::getBotMemDGNode(InstrInterval(Add0, Ret), DAG), S1N);
-  EXPECT_EQ(B::getBotMemDGNode(InstrInterval(Ret, Ret), DAG), nullptr);
-
-  // Check empty range.
-  EXPECT_THAT(sandboxir::MemDGNodeIntervalBuilder::makeEmpty(),
-              testing::ElementsAre());
-
-  // Returns the pointers in Range.
-  auto getPtrVec = [](const auto &Range) {
-    SmallVector<const sandboxir::DGNode *> Vec;
-    for (const sandboxir::DGNode &N : Range)
-      Vec.push_back(&N);
-    return Vec;
-  };
-  // Both TopN and BotN are memory.
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({S0, S1}, DAG)),
-      testing::ElementsAre(S0N, S1N));
-  // Only TopN is memory.
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({S0, Ret}, DAG)),
-      testing::ElementsAre(S0N, S1N));
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({S0, Add1}, DAG)),
-      testing::ElementsAre(S0N));
-  // Only BotN is memory.
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({Add0, S1}, DAG)),
-      testing::ElementsAre(S0N, S1N));
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({Add0, S0}, DAG)),
-      testing::ElementsAre(S0N));
-  // Neither TopN or BotN is memory.
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({Add0, Ret}, DAG)),
-      testing::ElementsAre(S0N, S1N));
-  EXPECT_THAT(
-      getPtrVec(sandboxir::MemDGNodeIntervalBuilder::make({Add0, Add0}, DAG)),
-      testing::ElementsAre());
-}
-
-TEST_F(DependencyGraphTest, AliasingStores) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto It = BB->begin();
-  auto *Store0N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::StoreInst>(&*It++)));
-  auto *Store1N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::StoreInst>(&*It++)));
-  auto *RetN = DAG.getNode(cast<sandboxir::ReturnInst>(&*It++));
-  EXPECT_TRUE(Store0N->memPreds().empty());
-  EXPECT_THAT(Store1N->memPreds(), testing::ElementsAre(Store0N));
-  EXPECT_TRUE(RetN->preds(DAG).empty());
-}
-
-TEST_F(DependencyGraphTest, NonAliasingStores) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr0
-  store i8 %v1, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto It = BB->begin();
-  auto *Store0N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::StoreInst>(&*It++)));
-  auto *Store1N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::StoreInst>(&*It++)));
-  auto *RetN = DAG.getNode(cast<sandboxir::ReturnInst>(&*It++));
-  // We expect no dependencies because the stores don't alias.
-  EXPECT_TRUE(Store0N->memPreds().empty());
-  EXPECT_TRUE(Store1N->memPreds().empty());
-  EXPECT_TRUE(RetN->preds(DAG).empty());
-}
-
-TEST_F(DependencyGraphTest, VolatileLoads) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) {
-  %ld0 = load volatile i8, ptr %ptr0
-  %ld1 = load volatile i8, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto It = BB->begin();
-  auto *Ld0N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::LoadInst>(&*It++)));
-  auto *Ld1N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::LoadInst>(&*It++)));
-  auto *RetN = DAG.getNode(cast<sandboxir::ReturnInst>(&*It++));
-  EXPECT_TRUE(Ld0N->memPreds().empty());
-  EXPECT_THAT(Ld1N->memPreds(), testing::ElementsAre(Ld0N));
-  EXPECT_TRUE(RetN->preds(DAG).empty());
-}
-
-TEST_F(DependencyGraphTest, VolatileStores) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %v) {
-  store volatile i8 %v, ptr %ptr0
-  store volatile i8 %v, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto It = BB->begin();
-  auto *Store0N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::StoreInst>(&*It++)));
-  auto *Store1N = cast<sandboxir::MemDGNode>(
-      DAG.getNode(cast<sandboxir::StoreInst>(&*It++)));
-  auto *RetN = DAG.getNode(cast<sandboxir::ReturnInst>(&*It++));
-  EXPECT_TRUE(Store0N->memPreds().empty());
-  EXPECT_THAT(Store1N->memPreds(), testing::ElementsAre(Store0N));
-  EXPECT_TRUE(RetN->preds(DAG).empty());
-}
-
-TEST_F(DependencyGraphTest, Call) {
-  parseIR(C, R"IR(
-declare void @bar1()
-declare void @bar2()
-define void @foo(float %v1, float %v2) {
-  call void @bar1()
-  %add = fadd float %v1, %v2
-  call void @bar2()
-  ret void
-}
-)IR");
-  Function *LLVMF = M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()->getPrevNode()});
-
-  auto It = BB->begin();
-  auto *Call1N = cast<sandboxir::MemDGNode>(DAG.getNode(&*It++));
-  auto *AddN = DAG.getNode(&*It++);
-  auto *Call2N = cast<sandboxir::MemDGNode>(DAG.getNode(&*It++));
-
-  EXPECT_THAT(Call1N->memPreds(), testing::ElementsAre());
-  EXPECT_THAT(AddN->preds(DAG), testing::ElementsAre());
-  EXPECT_THAT(Call2N->memPreds(), testing::ElementsAre(Call1N));
-}
-
-// Check that there is a dependency: stacksave -> alloca -> stackrestore.
-TEST_F(DependencyGraphTest, StackSaveRestoreInAlloca) {
-  parseIR(C, R"IR(
-declare ptr @llvm.stacksave()
-declare void @llvm.stackrestore(ptr %ptr)
-
-define void @foo() {
-  %stack0 = call ptr @llvm.stacksave()        ; Should depend on store
-  %alloca0 = alloca inalloca i8               ; Should depend on stacksave
-  call void @llvm.stackrestore(ptr %stack0)   ; Should depend transiently on %alloca0
-  ret void
-}
-)IR");
-  Function *LLVMF = M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()->getPrevNode()});
-
-  auto It = BB->begin();
-  auto *StackSaveN = DAG.getNode(&*It++);
-  auto *AllocaN = DAG.getNode(&*It++);
-  auto *StackRestoreN = DAG.getNode(&*It++);
-
-  EXPECT_TRUE(memDependency(AllocaN, StackRestoreN));
-  EXPECT_TRUE(memDependency(StackSaveN, AllocaN));
-}
-
-// Checks that stacksave and stackrestore depend on other mem instrs.
-TEST_F(DependencyGraphTest, StackSaveRestoreDependOnOtherMem) {
-  parseIR(C, R"IR(
-declare ptr @llvm.stacksave()
-declare void @llvm.stackrestore(ptr %ptr)
-
-define void @foo(i8 %v0, i8 %v1, ptr %ptr) {
-  store volatile i8 %v0, ptr %ptr, align 4
-  %stack0 = call ptr @llvm.stacksave()       ; Should depend on store
-  call void @llvm.stackrestore(ptr %stack0)  ; Should depend on stacksave
-  store volatile i8 %v1, ptr %ptr, align 4   ; Should depend on stackrestore
-  ret void
-}
-)IR");
-  Function *LLVMF = M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()->getPrevNode()});
-
-  auto It = BB->begin();
-  auto *Store0N = DAG.getNode(&*It++);
-  auto *StackSaveN = DAG.getNode(&*It++);
-  auto *StackRestoreN = DAG.getNode(&*It++);
-  auto *Store1N = DAG.getNode(&*It++);
-
-  EXPECT_TRUE(memDependency(Store0N, StackSaveN));
-  EXPECT_TRUE(memDependency(StackSaveN, StackRestoreN));
-  EXPECT_TRUE(memDependency(StackRestoreN, Store1N));
-}
-
-// Make sure there is a dependency between a stackrestore and an alloca.
-TEST_F(DependencyGraphTest, StackRestoreAndInAlloca) {
-  parseIR(C, R"IR(
-declare void @llvm.stackrestore(ptr %ptr)
-
-define void @foo(ptr %ptr) {
-  call void @llvm.stackrestore(ptr %ptr)
-  %alloca0 = alloca inalloca i8              ; Should depend on stackrestore
-  ret void
-}
-)IR");
-  Function *LLVMF = M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()->getPrevNode()});
-
-  auto It = BB->begin();
-  auto *StackRestoreN = DAG.getNode(&*It++);
-  auto *AllocaN = DAG.getNode(&*It++);
-
-  EXPECT_TRUE(memDependency(StackRestoreN, AllocaN));
-}
-
-// Make sure there is a dependency between the alloca and stacksave
-TEST_F(DependencyGraphTest, StackSaveAndInAlloca) {
-  parseIR(C, R"IR(
-declare ptr @llvm.stacksave()
-
-define void @foo(ptr %ptr) {
-  %alloca0 = alloca inalloca i8              ; Should depend on stackrestore
-  %stack0 = call ptr @llvm.stacksave()       ; Should depend on alloca0
-  ret void
-}
-)IR");
-  Function *LLVMF = M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()->getPrevNode()});
-
-  auto It = BB->begin();
-  auto *AllocaN = DAG.getNode(&*It++);
-  auto *StackSaveN = DAG.getNode(&*It++);
-
-  EXPECT_TRUE(memDependency(AllocaN, StackSaveN));
-}
-
-// A non-InAlloca in a stacksave-stackrestore region does not need extra
-// dependencies.
-TEST_F(DependencyGraphTest, StackSaveRestoreNoInAlloca) {
-  parseIR(C, R"IR(
-declare ptr @llvm.stacksave()
-declare void @llvm.stackrestore(ptr %ptr)
-declare void @use(ptr %ptr)
-
-define void @foo() {
-  %stack = call ptr @llvm.stacksave()
-  %alloca1 = alloca i8                         ; No dependency
-  call void @llvm.stackrestore(ptr %stack)
-  ret void
-}
-)IR");
-  Function *LLVMF = M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()->getPrevNode()});
-
-  auto It = BB->begin();
-  auto *StackSaveN = DAG.getNode(&*It++);
-  auto *AllocaN = DAG.getNode(&*It++);
-  auto *StackRestoreN = DAG.getNode(&*It++);
-
-  EXPECT_FALSE(memDependency(StackSaveN, AllocaN));
-  EXPECT_FALSE(memDependency(AllocaN, StackRestoreN));
-}
-
-TEST_F(DependencyGraphTest, Extend) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %v5) {
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  store i8 %v3, ptr %ptr
-  store i8 %v4, ptr %ptr
-  store i8 %v5, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S4 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S5 = cast<sandboxir::StoreInst>(&*It++);
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  {
-    // Scenario 1: Build new DAG
-    auto NewIntvl = DAG.extend({S3, S3});
-    EXPECT_EQ(NewIntvl, sandboxir::Interval<sandboxir::Instruction>(S3, S3));
-    EXPECT_EQ(DAG.getInterval().top(), S3);
-    EXPECT_EQ(DAG.getInterval().bottom(), S3);
-    [[maybe_unused]] auto *S3N = cast<sandboxir::MemDGNode>(DAG.getNode(S3));
-    // Check UnscheduledSuccs.
-    EXPECT_EQ(S3N->getNumUnscheduledSuccs(), 0u);
-  }
-  {
-    // Scenario 2: Extend below
-    auto NewIntvl = DAG.extend({S5, S5});
-    EXPECT_EQ(NewIntvl, sandboxir::Interval<sandboxir::Instruction>(S4, S5));
-    auto *S3N = cast<sandboxir::MemDGNode>(DAG.getNode(S3));
-    auto *S4N = cast<sandboxir::MemDGNode>(DAG.getNode(S4));
-    auto *S5N = cast<sandboxir::MemDGNode>(DAG.getNode(S5));
-    EXPECT_TRUE(S4N->hasMemPred(S3N));
-    EXPECT_TRUE(S5N->hasMemPred(S4N));
-    EXPECT_TRUE(S5N->hasMemPred(S3N));
-    // Check UnscheduledSuccs.
-    EXPECT_EQ(S3N->getNumUnscheduledSuccs(), 2u); // S4N, S5N
-    EXPECT_EQ(S4N->getNumUnscheduledSuccs(), 1u); // S5N
-    EXPECT_EQ(S5N->getNumUnscheduledSuccs(), 0u);
-  }
-  {
-    // Scenario 3: Extend above
-    auto NewIntvl = DAG.extend({S1, S2});
-    EXPECT_EQ(NewIntvl, sandboxir::Interval<sandboxir::Instruction>(S1, S2));
-    auto *S1N = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-    auto *S2N = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-    auto *S3N = cast<sandboxir::MemDGNode>(DAG.getNode(S3));
-    auto *S4N = cast<sandboxir::MemDGNode>(DAG.getNode(S4));
-    auto *S5N = cast<sandboxir::MemDGNode>(DAG.getNode(S5));
-
-    EXPECT_TRUE(S2N->hasMemPred(S1N));
-
-    EXPECT_TRUE(S3N->hasMemPred(S2N));
-    EXPECT_TRUE(S3N->hasMemPred(S1N));
-
-    EXPECT_TRUE(S4N->hasMemPred(S3N));
-    EXPECT_TRUE(S4N->hasMemPred(S2N));
-    EXPECT_TRUE(S4N->hasMemPred(S1N));
-
-    EXPECT_TRUE(S5N->hasMemPred(S4N));
-    EXPECT_TRUE(S5N->hasMemPred(S3N));
-    EXPECT_TRUE(S5N->hasMemPred(S2N));
-    EXPECT_TRUE(S5N->hasMemPred(S1N));
-
-    // Check UnscheduledSuccs.
-    EXPECT_EQ(S1N->getNumUnscheduledSuccs(), 4u); // S2N, S3N, S4N, S5N
-    EXPECT_EQ(S2N->getNumUnscheduledSuccs(), 3u); // S3N, S4N, S5N
-    EXPECT_EQ(S3N->getNumUnscheduledSuccs(), 2u); // S4N, S5N
-    EXPECT_EQ(S4N->getNumUnscheduledSuccs(), 1u); // S5N
-    EXPECT_EQ(S5N->getNumUnscheduledSuccs(), 0u);
-  }
-
-  {
-    // Check UnscheduledSuccs when a node is scheduled
-    sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-    DAG.extend({S2, S2});
-    auto *S2N = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-    S2N->setScheduled(true);
-
-    DAG.extend({S1, S1});
-    auto *S1N = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-    EXPECT_EQ(S1N->getNumUnscheduledSuccs(), 0u); // S1 is scheduled
-  }
-}
-
-// Check that the DAG gets updated when we create a new instruction.
-TEST_F(DependencyGraphTest, CreateInstrCallback) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %new1, i8 %new2) {
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  store i8 %v3, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  // Create a DAG spanning S1 to S3.
-  DAG.extend({S1, S3});
-  auto *ArgNew1 = F->getArg(4);
-  auto *ArgNew2 = F->getArg(5);
-  auto *Ptr = S1->getPointerOperand();
-
-  auto *S1MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-  auto *S2MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-  auto *S3MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S3));
-  sandboxir::MemDGNode *New1MemN = nullptr;
-  sandboxir::MemDGNode *New2MemN = nullptr;
-  {
-    // Create a new store before S3 (within the span of the DAG).
-    sandboxir::StoreInst *NewS =
-        sandboxir::StoreInst::create(ArgNew1, Ptr, Align(8), S3->getIterator(),
-                                     /*IsVolatile=*/true, Ctx);
-    // Check the MemDGNode chain.
-    New1MemN = cast<sandboxir::MemDGNode>(DAG.getNode(NewS));
-    EXPECT_EQ(S2MemN->getNextNode(), New1MemN);
-    EXPECT_EQ(New1MemN->getPrevNode(), S2MemN);
-    EXPECT_EQ(New1MemN->getNextNode(), S3MemN);
-    EXPECT_EQ(S3MemN->getPrevNode(), New1MemN);
-
-    // Check dependencies.
-    EXPECT_TRUE(memDependency(S1MemN, New1MemN));
-    EXPECT_TRUE(memDependency(S2MemN, New1MemN));
-    EXPECT_TRUE(memDependency(New1MemN, S3MemN));
-  }
-  {
-    // Create a new store before Ret (outside the current DAG).
-    sandboxir::StoreInst *NewS =
-        sandboxir::StoreInst::create(ArgNew2, Ptr, Align(8), Ret->getIterator(),
-                                     /*IsVolatile=*/true, Ctx);
-    // Check the MemDGNode chain.
-    New2MemN = cast<sandboxir::MemDGNode>(DAG.getNode(NewS));
-    EXPECT_EQ(S3MemN->getNextNode(), New2MemN);
-    EXPECT_EQ(New2MemN->getPrevNode(), S3MemN);
-    EXPECT_EQ(New2MemN->getNextNode(), nullptr);
-
-    // Check dependencies.
-    EXPECT_TRUE(memDependency(S1MemN, New2MemN));
-    EXPECT_TRUE(memDependency(S2MemN, New2MemN));
-    EXPECT_TRUE(memDependency(New1MemN, New2MemN));
-    EXPECT_TRUE(memDependency(S3MemN, New2MemN));
-  }
-}
-
-TEST_F(DependencyGraphTest, EraseInstrCallback) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %arg) {
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  store i8 %v3, ptr %ptr
-  store i8 %v4, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S4NotInDAG = cast<sandboxir::StoreInst>(&*It++);
-
-  // Check erase instruction callback.
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({S1, S3});
-  auto *S1MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-  auto *S2MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-  auto *S3MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S3));
-  EXPECT_EQ(S1MemN->getNumUnscheduledSuccs(), 2u);
-  EXPECT_EQ(S2MemN->getNumUnscheduledSuccs(), 1u);
-  EXPECT_EQ(S3MemN->getNumUnscheduledSuccs(), 0u);
-  S2->eraseFromParent();
-  // Check that the DAG Node for S2 no longer exists.
-  auto *DeletedN = DAG.getNode(S2);
-  EXPECT_TRUE(DeletedN == nullptr);
-  // Check that dependencies are maintained.
-  EXPECT_THAT(S3MemN->preds(DAG), testing::UnorderedElementsAre(S1MemN));
-  // Also check that UnscheduledSuccs was updated for S1.
-  EXPECT_EQ(S1MemN->getNumUnscheduledSuccs(), 1u);
-
-  // Check the MemDGNode chain.
-  EXPECT_EQ(S1MemN->getNextNode(), S3MemN);
-  EXPECT_EQ(S3MemN->getPrevNode(), S1MemN);
-
-  // Check the chain when we erase the top node.
-  S1->eraseFromParent();
-  EXPECT_EQ(S3MemN->getPrevNode(), nullptr);
-
-  // Check that we don't crash if we erase a node not in the DAG.
-  S4NotInDAG->eraseFromParent();
-}
-
-// Same but check that we don't update UnscheduledSuccs when Node is scheduled.
-TEST_F(DependencyGraphTest, EraseInstrCallbackScheduled) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %v3, i8 %v4, i8 %arg) {
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({S1, S2});
-  auto *S1MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-  auto *S2MemN = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-  EXPECT_EQ(S1MemN->getNumUnscheduledSuccs(), 1u);
-  EXPECT_EQ(S2MemN->getNumUnscheduledSuccs(), 0u);
-  // Mark S2 as scheduled and erase it.
-  S2MemN->setScheduled(true);
-  S2->eraseFromParent();
-  EXPECT_EQ(DAG.getNode(S2), nullptr);
-  // Check that we did not update S1's UnscheduledSuccs
-  EXPECT_EQ(S1MemN->getNumUnscheduledSuccs(), 1u);
-}
-
-TEST_F(DependencyGraphTest, MoveInstrCallback) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, ptr %ptr2, i8 %v1, i8 %v2, i8 %v3, i8 %arg) {
-  %ld0 = load i8, ptr %ptr2
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  store i8 %v3, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Ld = cast<sandboxir::LoadInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({Ld, S3});
-  auto *LdN = cast<sandboxir::MemDGNode>(DAG.getNode(Ld));
-  auto *S1N = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-  auto *S2N = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-  EXPECT_EQ(S1N->getPrevNode(), LdN);
-  S1->moveBefore(Ld);
-  EXPECT_EQ(S1N->getPrevNode(), nullptr);
-  EXPECT_EQ(S1N->getNextNode(), LdN);
-  EXPECT_EQ(LdN->getPrevNode(), S1N);
-  EXPECT_EQ(LdN->getNextNode(), S2N);
-}
-
-// Check that the mem chain is maintained correctly when the move destination is
-// not a mem node.
-TEST_F(DependencyGraphTest, MoveInstrCallbackWithNonMemInstrs) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v1, i8 %v2, i8 %arg) {
-  %ld = load i8, ptr %ptr
-  %zext1 = zext i8 %arg to i32
-  %zext2 = zext i8 %arg to i32
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Ld = cast<sandboxir::LoadInst>(&*It++);
-  [[maybe_unused]] auto *Zext1 = cast<sandboxir::CastInst>(&*It++);
-  auto *Zext2 = cast<sandboxir::CastInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({Ld, S2});
-  auto *LdN = cast<sandboxir::MemDGNode>(DAG.getNode(Ld));
-  auto *S1N = cast<sandboxir::MemDGNode>(DAG.getNode(S1));
-  auto *S2N = cast<sandboxir::MemDGNode>(DAG.getNode(S2));
-  EXPECT_EQ(LdN->getNextNode(), S1N);
-  EXPECT_EQ(S1N->getNextNode(), S2N);
-
-  S1->moveBefore(Zext2);
-  EXPECT_EQ(LdN->getNextNode(), S1N);
-  EXPECT_EQ(S1N->getNextNode(), S2N);
-
-  // Try move right after the end of the DAGInterval.
-  S1->moveBefore(Ret);
-  EXPECT_EQ(S2N->getNextNode(), S1N);
-  EXPECT_EQ(S1N->getNextNode(), nullptr);
-}
-
-// Extending an "Old" interval with no mem instructions.
-TEST_F(DependencyGraphTest, ExtendDAGWithNoMem) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  %zext1 = zext i8 %v to i32
-  %zext2 = zext i8 %v to i32
-  store i8 %v2, ptr %ptr
-  store i8 %v3, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Z1 = cast<sandboxir::CastInst>(&*It++);
-  auto *Z2 = cast<sandboxir::CastInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  // Create a non-empty DAG that contains no memory instructions.
-  DAG.extend({Z1, Z2});
-  // Now extend it downwards.
-  DAG.extend({S2, S3});
-  EXPECT_TRUE(memDependency(DAG.getNode(S2), DAG.getNode(S3)));
-
-  // Same but upwards.
-  DAG.clear();
-  DAG.extend({Z1, Z2});
-  DAG.extend({S0, S1});
-  EXPECT_TRUE(memDependency(DAG.getNode(S0), DAG.getNode(S1)));
-}
-
-// Setting a Use with a setOperand(), RUW, RAUW etc. can add/remove use-def
-// edges. This needs to maintain the UnscheduledSuccs counter.
-TEST_F(DependencyGraphTest, MaintainUnscheduledSuccsOnUseSet) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0, i8 %v1) {
-  %add0 = add i8 %v0, %v1
-  %add1 = add i8 %add0, %v1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *Arg0 = F->getArg(0);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({Add0, Add1});
-  auto *N0 = DAG.getNode(Add0);
-
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
-  // Now change %add1 operand to not use %add0.
-  Add1->setOperand(0, Arg0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
-  // Restore it: %add0 is now used by %add1.
-  Add1->setOperand(0, Add0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
-
-  // RAUW
-  Add0->replaceAllUsesWith(Arg0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
-  // Restore it: %add0 is now used by %add1.
-  Add1->setOperand(0, Add0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
-
-  // RUWIf
-  Add0->replaceUsesWithIf(Arg0, [](const auto &U) { return true; });
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
-  // Restore it: %add0 is now used by %add1.
-  Add1->setOperand(0, Add0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
-
-  // RUOW
-  Add1->replaceUsesOfWith(Add0, Arg0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 0u);
-  // Restore it: %add0 is now used by %add1.
-  Add1->setOperand(0, Add0);
-  EXPECT_EQ(N0->getNumUnscheduledSuccs(), 1u);
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrMapsTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrMapsTest.cpp
deleted file mode 100644
index c8fee1c24dbcb..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/InstrMapsTest.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-//===- InstrMapsTest.cpp --------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct InstrMapsTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("InstrMapsTest", errs());
-  }
-};
-
-TEST_F(InstrMapsTest, Basic) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0, i8 %v1, i8 %v2, i8 %v3, <2 x i8> %vec) {
-  %add0 = add i8 %v0, %v0
-  %add1 = add i8 %v1, %v1
-  %add2 = add i8 %v2, %v2
-  %add3 = add i8 %v3, %v3
-  %vadd0 = add <2 x i8> %vec, %vec
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add2 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add3 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *VAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
-  [[maybe_unused]] auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::InstrMaps IMaps;
-  {
-    // Check with empty IMaps.
-    sandboxir::Action A(nullptr, {Add0}, {}, 0);
-    EXPECT_EQ(IMaps.getVectorForOrig(Add0), nullptr);
-    EXPECT_EQ(IMaps.getVectorForOrig(Add1), nullptr);
-    EXPECT_FALSE(IMaps.getOrigLane(&A, Add0));
-  }
-  {
-    // Check with 1 match.
-    sandboxir::Action A(nullptr, {Add0, Add1}, {}, 0);
-    sandboxir::Action OtherA(nullptr, {}, {}, 0);
-    IMaps.registerVector({Add0, Add1}, &A);
-    EXPECT_EQ(IMaps.getVectorForOrig(Add0), &A);
-    EXPECT_EQ(IMaps.getVectorForOrig(Add1), &A);
-    EXPECT_FALSE(IMaps.getOrigLane(&A, VAdd0));     // Bad Orig value
-    EXPECT_FALSE(IMaps.getOrigLane(&OtherA, Add0)); // Bad Vector value
-    EXPECT_EQ(*IMaps.getOrigLane(&A, Add0), 0U);
-    EXPECT_EQ(*IMaps.getOrigLane(&A, Add1), 1U);
-  }
-  {
-    // Check when the same vector maps to different original values (which is
-    // common for vector constants).
-    sandboxir::Action A(nullptr, {Add2, Add3}, {}, 0);
-    IMaps.registerVector({Add2, Add3}, &A);
-    EXPECT_EQ(*IMaps.getOrigLane(&A, Add2), 0U);
-    EXPECT_EQ(*IMaps.getOrigLane(&A, Add3), 1U);
-  }
-  {
-    // Check when we register for a second time.
-    sandboxir::Action A(nullptr, {Add2, Add3}, {}, 0);
-#ifndef NDEBUG
-    EXPECT_DEATH(IMaps.registerVector({Add1, Add0}, &A), ".*exists.*");
-#endif // NDEBUG
-  }
-}
-
-TEST_F(InstrMapsTest, VectorLanes) {
-  parseIR(C, R"IR(
-define void @foo(<2 x i8> %v0, <2 x i8> %v1, <4 x i8> %v2, <4 x i8> %v3) {
-  %vadd0 = add <2 x i8> %v0, %v1
-  %vadd1 = add <2 x i8> %v0, %v1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-
-  auto *VAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *VAdd1 = cast<sandboxir::BinaryOperator>(&*It++);
-
-  sandboxir::InstrMaps IMaps;
-
-  {
-    // Check that the vector lanes are calculated correctly.
-    sandboxir::Action A(nullptr, {VAdd0, VAdd1}, {}, 0);
-    IMaps.registerVector({VAdd0, VAdd1}, &A);
-    EXPECT_EQ(*IMaps.getOrigLane(&A, VAdd0), 0U);
-    EXPECT_EQ(*IMaps.getOrigLane(&A, VAdd1), 2U);
-  }
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp
deleted file mode 100644
index ea09fba85ba6a..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/IntervalTest.cpp
+++ /dev/null
@@ -1,449 +0,0 @@
-//===- IntervalTest.cpp ---------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Interval.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock-matchers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct IntervalTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("InstrIntervalTest", errs());
-  }
-};
-
-TEST_F(IntervalTest, Basic) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0) {
-  %add0 = add i8 %v0, %v0
-  %add1 = add i8 %v0, %v0
-  %add2 = add i8 %v0, %v0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *Ret = &*It++;
-
-  sandboxir::Interval<sandboxir::Instruction> Intvl(I0, Ret);
-#ifndef NDEBUG
-  EXPECT_DEATH(sandboxir::Interval<sandboxir::Instruction>(I1, I0),
-               ".*before.*");
-#endif // NDEBUG
-  // Check Interval<sandboxir::Instruction>(ArrayRef), from(), to().
-  {
-    sandboxir::Interval<sandboxir::Instruction> Intvl(
-        SmallVector<sandboxir::Instruction *>({I0, Ret}));
-    EXPECT_EQ(Intvl.top(), I0);
-    EXPECT_EQ(Intvl.bottom(), Ret);
-  }
-  {
-    sandboxir::Interval<sandboxir::Instruction> Intvl(
-        SmallVector<sandboxir::Instruction *>({Ret, I0}));
-    EXPECT_EQ(Intvl.top(), I0);
-    EXPECT_EQ(Intvl.bottom(), Ret);
-  }
-  {
-    sandboxir::Interval<sandboxir::Instruction> Intvl(
-        SmallVector<sandboxir::Instruction *>({I0, I0}));
-    EXPECT_EQ(Intvl.top(), I0);
-    EXPECT_EQ(Intvl.bottom(), I0);
-  }
-
-  // Check empty().
-  EXPECT_FALSE(Intvl.empty());
-  sandboxir::Interval<sandboxir::Instruction> Empty;
-  EXPECT_TRUE(Empty.empty());
-  sandboxir::Interval<sandboxir::Instruction> One(I0, I0);
-  EXPECT_FALSE(One.empty());
-  // Check contains().
-  for (auto &I : *BB) {
-    EXPECT_TRUE(Intvl.contains(&I));
-    EXPECT_FALSE(Empty.contains(&I));
-  }
-  EXPECT_FALSE(One.contains(I1));
-  EXPECT_FALSE(One.contains(I2));
-  EXPECT_FALSE(One.contains(Ret));
-  // Check touches().
-  {
-    sandboxir::Interval<sandboxir::Instruction> Intvl(I2, I2);
-    EXPECT_TRUE(Intvl.touches(I1));
-    EXPECT_TRUE(Intvl.contains(I2));
-    EXPECT_FALSE(Intvl.touches(I2));
-    EXPECT_TRUE(Intvl.touches(Ret));
-    EXPECT_FALSE(Intvl.touches(I0));
-  }
-  // Check iterator.
-  auto BBIt = BB->begin();
-  for (auto &I : Intvl)
-    EXPECT_EQ(&I, &*BBIt++);
-  {
-    // Check equality.
-    EXPECT_TRUE(Empty == Empty);
-    EXPECT_FALSE(Empty == One);
-    EXPECT_TRUE(One == One);
-    sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2);
-    sandboxir::Interval<sandboxir::Instruction> Intvl2(I0, I2);
-    EXPECT_TRUE(Intvl1 == Intvl1);
-    EXPECT_TRUE(Intvl1 == Intvl2);
-  }
-  {
-    // Check inequality.
-    EXPECT_FALSE(Empty != Empty);
-    EXPECT_TRUE(Empty != One);
-    EXPECT_FALSE(One != One);
-    sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2);
-    sandboxir::Interval<sandboxir::Instruction> Intvl2(I0, I2);
-    EXPECT_FALSE(Intvl1 != Intvl1);
-    EXPECT_FALSE(Intvl1 != Intvl2);
-  }
-  {
-    // Check disjoint().
-    EXPECT_TRUE(Empty.disjoint(Empty));
-    EXPECT_TRUE(One.disjoint(Empty));
-    EXPECT_TRUE(Empty.disjoint(One));
-    sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2);
-    sandboxir::Interval<sandboxir::Instruction> Intvl2(I1, Ret);
-    EXPECT_FALSE(Intvl1.disjoint(Intvl2));
-    sandboxir::Interval<sandboxir::Instruction> Intvl3(I2, I2);
-    EXPECT_FALSE(Intvl1.disjoint(Intvl3));
-    EXPECT_TRUE(Intvl1.disjoint(Empty));
-  }
-  {
-    // Check comesBefore().
-    sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I0);
-    sandboxir::Interval<sandboxir::Instruction> Intvl2(I2, I2);
-    EXPECT_TRUE(Intvl1.comesBefore(Intvl2));
-    EXPECT_FALSE(Intvl2.comesBefore(Intvl1));
-
-    sandboxir::Interval<sandboxir::Instruction> Intvl12(I1, I2);
-    EXPECT_TRUE(Intvl1.comesBefore(Intvl12));
-    EXPECT_FALSE(Intvl12.comesBefore(Intvl1));
-    {
-#ifndef NDEBUG
-      // Check comesBefore() with non-disjoint intervals.
-      sandboxir::Interval<sandboxir::Instruction> Intvl1(I0, I2);
-      sandboxir::Interval<sandboxir::Instruction> Intvl2(I2, I2);
-      EXPECT_DEATH(Intvl1.comesBefore(Intvl2), ".*disjoint.*");
-#endif // NDEBUG
-    }
-  }
-}
-
-// Helper function for returning a vector of instruction pointers from a range
-// of references.
-template <typename RangeT>
-static SmallVector<sandboxir::Instruction *> getPtrVec(RangeT Range) {
-  SmallVector<sandboxir::Instruction *> PtrVec(llvm::make_pointer_range(Range));
-  return PtrVec;
-}
-
-TEST_F(IntervalTest, Difference) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0) {
-  %I0 = add i8 %v0, %v0
-  %I1 = add i8 %v0, %v0
-  %I2 = add i8 %v0, %v0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *Ret = &*It++;
-
-  {
-    // Check [I0,Ret] - []
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    sandboxir::Interval<sandboxir::Instruction> Empty;
-    auto Diffs = I0Ret - Empty;
-    EXPECT_EQ(Diffs.size(), 1u);
-    const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0];
-    EXPECT_THAT(getPtrVec(Diff), testing::ElementsAre(I0, I1, I2, Ret));
-
-    // Check getSingleDiff().
-    EXPECT_EQ(I0Ret.getSingleDiff(Empty), Diff);
-  }
-  {
-    // Check [] - [I0,Ret]
-    sandboxir::Interval<sandboxir::Instruction> Empty;
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    auto Diffs = Empty - I0Ret;
-    EXPECT_EQ(Diffs.size(), 1u);
-    const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0];
-    EXPECT_TRUE(Diff.empty());
-
-    // Check getSingleDiff().
-    EXPECT_EQ(Empty.getSingleDiff(I0Ret), Diff);
-  }
-  {
-    // Check [I0,Ret] - [I0].
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
-    auto Diffs = I0Ret - I0I0;
-    EXPECT_EQ(Diffs.size(), 1u);
-    const sandboxir::Interval<sandboxir::Instruction> &Diff = Diffs[0];
-    EXPECT_THAT(getPtrVec(Diff), testing::ElementsAre(I1, I2, Ret));
-
-    // Check getSingleDiff().
-    EXPECT_EQ(I0Ret.getSingleDiff(I0I0), Diff);
-  }
-  {
-    // Check [I0,Ret] - [I1].
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1);
-    auto Diffs = I0Ret - I1I1;
-    EXPECT_EQ(Diffs.size(), 2u);
-    const sandboxir::Interval<sandboxir::Instruction> &Diff0 = Diffs[0];
-    EXPECT_THAT(getPtrVec(Diff0), testing::ElementsAre(I0));
-    const sandboxir::Interval<sandboxir::Instruction> &Diff1 = Diffs[1];
-    EXPECT_THAT(getPtrVec(Diff1), testing::ElementsAre(I2, Ret));
-
-#ifndef NDEBUG
-    // Check getSingleDiff().
-    EXPECT_DEATH(I0Ret.getSingleDiff(I1I1), ".*single.*");
-#endif // NDEBUG
-  }
-}
-
-TEST_F(IntervalTest, Intersection) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0) {
-  %I0 = add i8 %v0, %v0
-  %I1 = add i8 %v0, %v0
-  %I2 = add i8 %v0, %v0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  [[maybe_unused]] auto *I2 = &*It++;
-  auto *Ret = &*It++;
-
-  {
-    // Check [I0,Ret] ^ []
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    sandboxir::Interval<sandboxir::Instruction> Empty;
-    auto Intersection = I0Ret.intersection(Empty);
-    EXPECT_TRUE(Intersection.empty());
-  }
-  {
-    // Check [] ^ [I0,Ret]
-    sandboxir::Interval<sandboxir::Instruction> Empty;
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    auto Intersection = Empty.intersection(I0Ret);
-    EXPECT_TRUE(Intersection.empty());
-  }
-  {
-    // Check [I0,Ret] ^ [I0]
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
-    auto Intersection = I0Ret.intersection(I0I0);
-    EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I0));
-  }
-  {
-    // Check [I0] ^ [I0,Ret]
-    sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    auto Intersection = I0I0.intersection(I0Ret);
-    EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I0));
-  }
-  {
-    // Check [I0,Ret] ^ [I1].
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1);
-    auto Intersection = I0Ret.intersection(I1I1);
-    EXPECT_THAT(getPtrVec(Intersection), testing::ElementsAre(I1));
-  }
-}
-
-TEST_F(IntervalTest, UnionInterval) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0) {
-  %I0 = add i8 %v0, %v0
-  %I1 = add i8 %v0, %v0
-  %I2 = add i8 %v0, %v0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  [[maybe_unused]] auto *I2 = &*It++;
-  auto *Ret = &*It++;
-
-  {
-    // Check [I0] unionInterval [I2].
-    sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
-    sandboxir::Interval<sandboxir::Instruction> I2I2(I2, I2);
-    auto SingleUnion = I0I0.getUnionInterval(I2I2);
-    EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1, I2));
-  }
-  {
-    // Check [I0] unionInterval Empty.
-    sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
-    sandboxir::Interval<sandboxir::Instruction> Empty;
-    auto SingleUnion = I0I0.getUnionInterval(Empty);
-    EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0));
-  }
-  {
-    // Check [I0,I1] unionInterval [I1].
-    sandboxir::Interval<sandboxir::Instruction> I0I1(I0, I1);
-    sandboxir::Interval<sandboxir::Instruction> I1I1(I1, I1);
-    auto SingleUnion = I0I1.getUnionInterval(I1I1);
-    EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1));
-  }
-  {
-    // Check [I2,Ret] unionInterval [I0].
-    sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret);
-    sandboxir::Interval<sandboxir::Instruction> I0I0(I0, I0);
-    auto SingleUnion = I2Ret.getUnionInterval(I0I0);
-    EXPECT_THAT(getPtrVec(SingleUnion), testing::ElementsAre(I0, I1, I2, Ret));
-  }
-}
-
-TEST_F(IntervalTest, NotifyMoveInstr) {
-  parseIR(C, R"IR(
-define void @foo(i8 %v0) {
-  %I0 = add i8 %v0, %v0
-  %I1 = add i8 %v0, %v0
-  %I2 = add i8 %v0, %v0
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  auto *I2 = &*It++;
-  auto *Ret = &*It++;
-  {
-    // Assert that we don't try to move external instr to the interval.
-    sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret);
-#ifndef NDEBUG
-    EXPECT_DEATH(I2Ret.notifyMoveInstr(I0, Ret->getIterator()), ".*interval.*");
-#endif // NDEBUG
-  }
-  {
-    // Assert that we don't move before self.
-    sandboxir::Interval<sandboxir::Instruction> I2Ret(I2, Ret);
-#ifndef NDEBUG
-    EXPECT_DEATH(I2Ret.notifyMoveInstr(Ret, Ret->getIterator()), ".*self.*");
-#endif // NDEBUG
-  }
-  {
-    // Single-element interval.
-    sandboxir::Interval<sandboxir::Instruction> I2I2(I2, I2);
-    I2I2.notifyMoveInstr(I2, Ret->getIterator());
-    EXPECT_EQ(I2I2.top(), I2);
-    EXPECT_EQ(I2I2.bottom(), I2);
-  }
-  {
-    // Two-element interval swap.
-    sandboxir::Interval<sandboxir::Instruction> I1I2(I1, I2);
-    I1I2.notifyMoveInstr(I2, I1->getIterator());
-    I2->moveBefore(I1);
-    EXPECT_EQ(I1I2.top(), I2);
-    EXPECT_EQ(I1I2.bottom(), I1);
-
-    I2->moveAfter(I1);
-  }
-  {
-    // Move to same position.
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    I0Ret.notifyMoveInstr(I0, I1->getIterator());
-    I0->moveBefore(I1);
-    EXPECT_EQ(I0Ret.top(), I0);
-    EXPECT_EQ(I0Ret.bottom(), Ret);
-  }
-  {
-    // Move internal to internal.
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    I0Ret.notifyMoveInstr(I2, I1->getIterator());
-    I2->moveBefore(I1);
-    EXPECT_EQ(I0Ret.top(), I0);
-    EXPECT_EQ(I0Ret.bottom(), Ret);
-
-    I2->moveAfter(I1);
-  }
-  {
-    // Move internal before top.
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    I0Ret.notifyMoveInstr(I2, I0->getIterator());
-    I2->moveBefore(I0);
-    EXPECT_EQ(I0Ret.top(), I2);
-    EXPECT_EQ(I0Ret.bottom(), Ret);
-
-    I2->moveAfter(I1);
-  }
-  {
-    // Move internal to bottom.
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    I0Ret.notifyMoveInstr(I2, BB->end());
-    I2->moveAfter(Ret);
-    EXPECT_EQ(I0Ret.top(), I0);
-    EXPECT_EQ(I0Ret.bottom(), I2);
-
-    I2->moveAfter(I1);
-  }
-  {
-    // Move bottom before internal.
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    I0Ret.notifyMoveInstr(Ret, I2->getIterator());
-    Ret->moveBefore(I2);
-    EXPECT_EQ(I0Ret.top(), I0);
-    EXPECT_EQ(I0Ret.bottom(), I2);
-
-    Ret->moveAfter(I2);
-  }
-  {
-    // Move bottom before top.
-    sandboxir::Interval<sandboxir::Instruction> I0Ret(I0, Ret);
-    I0Ret.notifyMoveInstr(Ret, I0->getIterator());
-    Ret->moveBefore(I0);
-    EXPECT_EQ(I0Ret.top(), Ret);
-    EXPECT_EQ(I0Ret.bottom(), I2);
-
-    Ret->moveAfter(I2);
-  }
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp
deleted file mode 100644
index 586f846caf267..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/LegalityTest.cpp
+++ /dev/null
@@ -1,506 +0,0 @@
-//===- LegalityTest.cpp ---------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Legality.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/InstrMaps.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct LegalityTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-  std::unique_ptr<DominatorTree> DT;
-  std::unique_ptr<TargetLibraryInfoImpl> TLII;
-  std::unique_ptr<TargetLibraryInfo> TLI;
-  std::unique_ptr<AssumptionCache> AC;
-  std::unique_ptr<LoopInfo> LI;
-  std::unique_ptr<ScalarEvolution> SE;
-  std::unique_ptr<BasicAAResult> BAA;
-  std::unique_ptr<AAResults> AA;
-
-  void getAnalyses(llvm::Function &LLVMF) {
-    DT = std::make_unique<DominatorTree>(LLVMF);
-    AC = std::make_unique<AssumptionCache>(LLVMF);
-    LI = std::make_unique<LoopInfo>(*DT);
-    SE = std::make_unique<ScalarEvolution>(LLVMF, *TLI, *AC, *DT, *LI);
-    BAA = std::make_unique<BasicAAResult>(LLVMF.getParent()->getDataLayout(),
-                                          LLVMF, *TLI, *AC, DT.get());
-    AA = std::make_unique<AAResults>(*TLI);
-    AA->addAAResult(*BAA);
-  }
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M) {
-      Err.print("LegalityTest", errs());
-      return;
-    }
-
-    TLII = std::make_unique<TargetLibraryInfoImpl>(M->getTargetTriple());
-    TLI = std::make_unique<TargetLibraryInfo>(*TLII);
-  }
-};
-
-static sandboxir::BasicBlock *getBasicBlockByName(sandboxir::Function *F,
-                                                  StringRef Name) {
-  for (sandboxir::BasicBlock &BB : *F)
-    if (BB.getName() == Name)
-      return &BB;
-  llvm_unreachable("Expected to find basic block!");
-}
-
-TEST_F(LegalityTest, LegalitySkipSchedule) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, <2 x float> %vec2, <3 x float> %vec3, i8 %arg, float %farg0, float %farg1, i64 %v0, i64 %v1, i32 %v2, i1 %c0, i1 %c1) {
-entry:
-  %gep0 = getelementptr float, ptr %ptr, i32 0
-  %gep1 = getelementptr float, ptr %ptr, i32 1
-  store float %farg0, ptr %gep1
-  br label %bb
-
-bb:
-  %gep3 = getelementptr float, ptr %ptr, i32 3
-  %ld0 = load float, ptr %gep0
-  %ld0b = load float, ptr %gep0
-  %ld1 = load float, ptr %gep1
-  %ld3 = load float, ptr %gep3
-  store float %ld0, ptr %gep0
-  store float %ld1, ptr %gep1
-  store <2 x float> %vec2, ptr %gep1
-  store <3 x float> %vec3, ptr %gep3
-  store i8 %arg, ptr %gep1
-  %fadd0 = fadd float %farg0, %farg0
-  %fadd1 = fadd fast float %farg1, %farg1
-  %trunc0 = trunc nuw nsw i64 %v0 to i8
-  %trunc1 = trunc nsw i64 %v1 to i8
-  %trunc64to8 = trunc i64 %v0 to i8
-  %trunc32to8 = trunc i32 %v2 to i8
-  %cmpSLT = icmp slt i64 %v0, %v1
-  %cmpSGT = icmp sgt i64 %v0, %v1
-  %sel0 = select i1 %c0, <2 x float> %vec2, <2 x float> %vec2
-  %sel1 = select i1 %c1, <2 x float> %vec2, <2 x float> %vec2
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  getAnalyses(*LLVMF);
-  const auto &DL = M->getDataLayout();
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *EntryBB = getBasicBlockByName(F, "entry");
-  auto It = EntryBB->begin();
-  [[maybe_unused]] auto *Gep0 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  [[maybe_unused]] auto *Gep1 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  auto *St1Entry = cast<sandboxir::StoreInst>(&*It++);
-
-  auto *BB = getBasicBlockByName(F, "bb");
-  It = BB->begin();
-  [[maybe_unused]] auto *Gep3 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ld0b = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ld3 = cast<sandboxir::LoadInst>(&*It++);
-  auto *St0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *St1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *StVec2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *StVec3 = cast<sandboxir::StoreInst>(&*It++);
-  auto *StI8 = cast<sandboxir::StoreInst>(&*It++);
-  auto *FAdd0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *FAdd1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Trunc0 = cast<sandboxir::TruncInst>(&*It++);
-  auto *Trunc1 = cast<sandboxir::TruncInst>(&*It++);
-  auto *Trunc64to8 = cast<sandboxir::TruncInst>(&*It++);
-  auto *Trunc32to8 = cast<sandboxir::TruncInst>(&*It++);
-  auto *CmpSLT = cast<sandboxir::CmpInst>(&*It++);
-  auto *CmpSGT = cast<sandboxir::CmpInst>(&*It++);
-  auto *Sel0 = cast<sandboxir::SelectInst>(&*It++);
-  auto *Sel1 = cast<sandboxir::SelectInst>(&*It++);
-
-  llvm::sandboxir::InstrMaps IMaps;
-  sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps);
-  const auto &Result =
-      Legality.canVectorize({St0, St1}, /*SkipScheduling=*/true);
-  EXPECT_TRUE(isa<sandboxir::Widen>(Result));
-
-  {
-    // Check NotInstructions
-    auto &Result = Legality.canVectorize({F, St0}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::NotInstructions);
-  }
-  {
-    // Check DiffOpcodes
-    const auto &Result =
-        Legality.canVectorize({St0, Ld0}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffOpcodes);
-  }
-  {
-    // Check DiffTypes
-    EXPECT_TRUE(isa<sandboxir::Widen>(
-        Legality.canVectorize({St0, StVec2}, /*SkipScheduling=*/true)));
-    EXPECT_TRUE(isa<sandboxir::Widen>(
-        Legality.canVectorize({StVec2, StVec3}, /*SkipScheduling=*/true)));
-
-    const auto &Result =
-        Legality.canVectorize({St0, StI8}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffTypes);
-  }
-  {
-    // Check DiffMathFlags
-    const auto &Result =
-        Legality.canVectorize({FAdd0, FAdd1}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffMathFlags);
-  }
-  {
-    // Check DiffWrapFlags
-    const auto &Result =
-        Legality.canVectorize({Trunc0, Trunc1}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffWrapFlags);
-  }
-  {
-    // Check DiffBBs
-    const auto &Result =
-        Legality.canVectorize({St0, St1Entry}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffBBs);
-  }
-  {
-    // Check DiffTypes for unary operands that have a different type.
-    const auto &Result = Legality.canVectorize({Trunc64to8, Trunc32to8},
-                                               /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffTypes);
-  }
-  {
-    // Check DiffOpcodes for CMPs with different predicates.
-    const auto &Result =
-        Legality.canVectorize({CmpSLT, CmpSGT}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::DiffOpcodes);
-  }
-  {
-    // Check NotConsecutive Ld0,Ld0b
-    const auto &Result =
-        Legality.canVectorize({Ld0, Ld0b}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::NotConsecutive);
-  }
-  {
-    // Check NotConsecutive Ld0,Ld3
-    const auto &Result =
-        Legality.canVectorize({Ld0, Ld3}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::NotConsecutive);
-  }
-  {
-    // Check Widen Ld0,Ld1
-    const auto &Result =
-        Legality.canVectorize({Ld0, Ld1}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Widen>(Result));
-  }
-  {
-    // Check Repeated instructions (splat)
-    const auto &Result =
-        Legality.canVectorize({Ld0, Ld0}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::RepeatedInstrs);
-  }
-  {
-    // Check Repeated instructions (not splat)
-    const auto &Result =
-        Legality.canVectorize({Ld0, Ld1, Ld0}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::RepeatedInstrs);
-  }
-  {
-    // For now don't vectorize Selects when the number of elements of conditions
-    // doesn't match the operands.
-    const auto &Result =
-        Legality.canVectorize({Sel0, Sel1}, /*SkipScheduling=*/true);
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::Unimplemented);
-  }
-}
-
-TEST_F(LegalityTest, LegalitySchedule) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr float, ptr %ptr, i32 0
-  %gep1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %gep0
-  store float %ld0, ptr %gep1
-  %ld1 = load float, ptr %gep1
-  store float %ld0, ptr %gep0
-  store float %ld1, ptr %gep1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  getAnalyses(*LLVMF);
-  const auto &DL = M->getDataLayout();
-
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  [[maybe_unused]] auto *Gep0 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  [[maybe_unused]] auto *Gep1 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  [[maybe_unused]] auto *ConflictingSt = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *St0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *St1 = cast<sandboxir::StoreInst>(&*It++);
-
-  llvm::sandboxir::InstrMaps IMaps;
-  sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps);
-  {
-    // Can vectorize St0,St1.
-    const auto &Result = Legality.canVectorize({St0, St1});
-    EXPECT_TRUE(isa<sandboxir::Widen>(Result));
-  }
-  {
-    // Can't vectorize Ld0,Ld1 because of conflicting store.
-    auto &Result = Legality.canVectorize({Ld0, Ld1});
-    EXPECT_TRUE(isa<sandboxir::Pack>(Result));
-    EXPECT_EQ(cast<sandboxir::Pack>(Result).getReason(),
-              sandboxir::ResultReason::CantSchedule);
-  }
-}
-
-#ifndef NDEBUG
-TEST_F(LegalityTest, LegalityResultDump) {
-  parseIR(C, R"IR(
-define void @foo() {
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  getAnalyses(*LLVMF);
-  const auto &DL = M->getDataLayout();
-
-  auto Matches = [](const sandboxir::LegalityResult &Result,
-                    const std::string &ExpectedStr) -> bool {
-    std::string Buff;
-    raw_string_ostream OS(Buff);
-    Result.print(OS);
-    return Buff == ExpectedStr;
-  };
-
-  sandboxir::Context Ctx(C);
-  llvm::sandboxir::InstrMaps IMaps;
-  sandboxir::LegalityAnalysis Legality(*AA, *SE, DL, Ctx, IMaps);
-  EXPECT_TRUE(
-      Matches(Legality.createLegalityResult<sandboxir::Widen>(), "Widen"));
-  EXPECT_TRUE(Matches(Legality.createLegalityResult<sandboxir::Pack>(
-                          sandboxir::ResultReason::NotInstructions),
-                      "Pack Reason: NotInstructions"));
-  EXPECT_TRUE(Matches(Legality.createLegalityResult<sandboxir::Pack>(
-                          sandboxir::ResultReason::DiffOpcodes),
-                      "Pack Reason: DiffOpcodes"));
-  EXPECT_TRUE(Matches(Legality.createLegalityResult<sandboxir::Pack>(
-                          sandboxir::ResultReason::DiffTypes),
-                      "Pack Reason: DiffTypes"));
-  EXPECT_TRUE(Matches(Legality.createLegalityResult<sandboxir::Pack>(
-                          sandboxir::ResultReason::DiffMathFlags),
-                      "Pack Reason: DiffMathFlags"));
-  EXPECT_TRUE(Matches(Legality.createLegalityResult<sandboxir::Pack>(
-                          sandboxir::ResultReason::DiffWrapFlags),
-                      "Pack Reason: DiffWrapFlags"));
-}
-#endif // NDEBUG
-
-TEST_F(LegalityTest, CollectDescr) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr float, ptr %ptr, i32 0
-  %gep1 = getelementptr float, ptr %ptr, i32 1
-  %ld0 = load float, ptr %gep0
-  %ld1 = load float, ptr %gep1
-  %vld = load <4 x float>, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  getAnalyses(*LLVMF);
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  [[maybe_unused]] auto *Gep0 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  [[maybe_unused]] auto *Gep1 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  [[maybe_unused]] auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *VLd = cast<sandboxir::LoadInst>(&*It++);
-
-  sandboxir::CollectDescr::DescrVecT Descrs;
-  using EEDescr = sandboxir::CollectDescr::ExtractElementDescr;
-  SmallVector<sandboxir::Value *> Bndl({VLd});
-  SmallVector<sandboxir::Value *> UB;
-  sandboxir::Action VLdA(nullptr, Bndl, UB, 0);
-  {
-    // Check single input, no shuffle.
-    Descrs.push_back(EEDescr(&VLdA, 0));
-    Descrs.push_back(EEDescr(&VLdA, 1));
-    sandboxir::CollectDescr CD(std::move(Descrs));
-    EXPECT_TRUE(CD.getSingleInput());
-    EXPECT_EQ(CD.getSingleInput()->first, &VLdA);
-    EXPECT_THAT(CD.getSingleInput()->second, testing::ElementsAre(0, 1));
-    EXPECT_TRUE(CD.hasVectorInputs());
-  }
-  {
-    // Check single input, shuffle.
-    Descrs.push_back(EEDescr(&VLdA, 1));
-    Descrs.push_back(EEDescr(&VLdA, 0));
-    sandboxir::CollectDescr CD(std::move(Descrs));
-    EXPECT_TRUE(CD.getSingleInput());
-    EXPECT_EQ(CD.getSingleInput()->first, &VLdA);
-    EXPECT_THAT(CD.getSingleInput()->second, testing::ElementsAre(1, 0));
-    EXPECT_TRUE(CD.hasVectorInputs());
-  }
-  {
-    // Check multiple inputs.
-    Descrs.push_back(EEDescr(Ld0));
-    Descrs.push_back(EEDescr(&VLdA, 0));
-    Descrs.push_back(EEDescr(&VLdA, 1));
-    sandboxir::CollectDescr CD(std::move(Descrs));
-    EXPECT_FALSE(CD.getSingleInput());
-    EXPECT_TRUE(CD.hasVectorInputs());
-  }
-  {
-    // Check multiple inputs only scalars.
-    Descrs.push_back(EEDescr(Ld0));
-    Descrs.push_back(EEDescr(Ld1));
-    sandboxir::CollectDescr CD(std::move(Descrs));
-    EXPECT_FALSE(CD.getSingleInput());
-    EXPECT_FALSE(CD.hasVectorInputs());
-  }
-}
-
-TEST_F(LegalityTest, ShuffleMask) {
-  {
-    // Check SmallVector constructor.
-    SmallVector<int> Indices({0, 1, 2, 3});
-    sandboxir::ShuffleMask Mask(std::move(Indices));
-    EXPECT_THAT(Mask, testing::ElementsAre(0, 1, 2, 3));
-  }
-  {
-    // Check initializer_list constructor.
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    EXPECT_THAT(Mask, testing::ElementsAre(0, 1, 2, 3));
-  }
-  {
-    // Check ArrayRef constructor.
-    sandboxir::ShuffleMask Mask(ArrayRef<int>({0, 1, 2, 3}));
-    EXPECT_THAT(Mask, testing::ElementsAre(0, 1, 2, 3));
-  }
-  {
-    // Check operator ArrayRef<int>().
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    ArrayRef<int> Array = Mask;
-    EXPECT_THAT(Array, testing::ElementsAre(0, 1, 2, 3));
-  }
-  {
-    // Check getIdentity().
-    auto IdentityMask = sandboxir::ShuffleMask::getIdentity(4);
-    EXPECT_THAT(IdentityMask, testing::ElementsAre(0, 1, 2, 3));
-    EXPECT_TRUE(IdentityMask.isIdentity());
-  }
-  {
-    // Check isIdentity().
-    sandboxir::ShuffleMask Mask1({0, 1, 2, 3});
-    EXPECT_TRUE(Mask1.isIdentity());
-    sandboxir::ShuffleMask Mask2({1, 2, 3, 4});
-    EXPECT_FALSE(Mask2.isIdentity());
-  }
-  {
-    // Check operator==().
-    sandboxir::ShuffleMask Mask1({0, 1, 2, 3});
-    sandboxir::ShuffleMask Mask2({0, 1, 2, 3});
-    EXPECT_TRUE(Mask1 == Mask2);
-    EXPECT_FALSE(Mask1 != Mask2);
-  }
-  {
-    // Check operator!=().
-    sandboxir::ShuffleMask Mask1({0, 1, 2, 3});
-    sandboxir::ShuffleMask Mask2({0, 1, 2, 4});
-    EXPECT_TRUE(Mask1 != Mask2);
-    EXPECT_FALSE(Mask1 == Mask2);
-  }
-  {
-    // Check size().
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    EXPECT_EQ(Mask.size(), 4u);
-  }
-  {
-    // Check operator[].
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    for (auto [Idx, Elm] : enumerate(Mask)) {
-      EXPECT_EQ(Elm, Mask[Idx]);
-    }
-  }
-  {
-    // Check begin(), end().
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    sandboxir::ShuffleMask::const_iterator Begin = Mask.begin();
-    sandboxir::ShuffleMask::const_iterator End = Mask.begin();
-    int Idx = 0;
-    for (auto It = Begin; It != End; ++It) {
-      EXPECT_EQ(*It, Mask[Idx++]);
-    }
-  }
-#ifndef NDEBUG
-  {
-    // Check print(OS).
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    std::string Str;
-    raw_string_ostream OS(Str);
-    Mask.print(OS);
-    EXPECT_EQ(Str, "0,1,2,3");
-  }
-  {
-    // Check operator<<().
-    sandboxir::ShuffleMask Mask({0, 1, 2, 3});
-    std::string Str;
-    raw_string_ostream OS(Str);
-    OS << Mask;
-    EXPECT_EQ(Str, "0,1,2,3");
-  }
-#endif // NDEBUG
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerTest.cpp
deleted file mode 100644
index e9b304618a06c..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizerTest.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-//===- SandboxVectorizerTest.cpp ------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SandboxVectorizer.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/Analysis/TargetTransformInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/IR/PassInstrumentation.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct SandboxVectorizerTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("SandboxVectorizerTest", errs());
-  }
-};
-
-// Check that we can run the pass on the same function more than once without
-// issues. This basically checks that Sandbox IR Context gets cleared after we
-// run the function pass.
-TEST_F(SandboxVectorizerTest, ContextCleared) {
-  parseIR(C, R"IR(
-define void @foo() {
-  ret void
-}
-)IR");
-  auto &LLVMF = *M->getFunction("foo");
-  SandboxVectorizerPass SVecPass;
-  FunctionAnalysisManager AM;
-  AM.registerPass([] { return TargetIRAnalysis(); });
-  AM.registerPass([] { return AAManager(); });
-  AM.registerPass([] { return ScalarEvolutionAnalysis(); });
-  AM.registerPass([] { return PassInstrumentationAnalysis(); });
-  AM.registerPass([] { return TargetLibraryAnalysis(); });
-  AM.registerPass([] { return AssumptionAnalysis(); });
-  AM.registerPass([] { return DominatorTreeAnalysis(); });
-  AM.registerPass([] { return LoopAnalysis(); });
-  SVecPass.run(LLVMF, AM);
-  // This shouldn't crash.
-  SVecPass.run(LLVMF, AM);
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp
deleted file mode 100644
index 4c38fa069ba66..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SchedulerTest.cpp
+++ /dev/null
@@ -1,881 +0,0 @@
-//===- SchedulerTest.cpp --------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/Scheduler.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock-matchers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct SchedulerTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-  std::unique_ptr<AssumptionCache> AC;
-  std::unique_ptr<DominatorTree> DT;
-  std::unique_ptr<BasicAAResult> BAA;
-  std::unique_ptr<AAResults> AA;
-  std::unique_ptr<TargetLibraryInfoImpl> TLII;
-  std::unique_ptr<TargetLibraryInfo> TLI;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M) {
-      Err.print("SchedulerTest", errs());
-      return;
-    }
-
-    TLII = std::make_unique<TargetLibraryInfoImpl>(M->getTargetTriple());
-    TLI = std::make_unique<TargetLibraryInfo>(*TLII);
-  }
-
-  AAResults &getAA(llvm::Function &LLVMF) {
-    AA = std::make_unique<AAResults>(*TLI);
-    AC = std::make_unique<AssumptionCache>(LLVMF);
-    DT = std::make_unique<DominatorTree>(LLVMF);
-    BAA = std::make_unique<BasicAAResult>(M->getDataLayout(), LLVMF, *TLI, *AC,
-                                          DT.get());
-    AA->addAAResult(*BAA);
-    return *AA;
-  }
-};
-
-static sandboxir::BasicBlock *getBasicBlockByName(sandboxir::Function *F,
-                                                  StringRef Name) {
-  for (sandboxir::BasicBlock &BB : *F)
-    if (BB.getName() == Name)
-      return &BB;
-  llvm_unreachable("Expected to find basic block!");
-}
-
-TEST_F(SchedulerTest, SchedBundle) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr
-  %other = add i8 %v0, %v1
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Other = &*It++;
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto *SN0 = DAG.getNode(S0);
-  auto *SN1 = DAG.getNode(S1);
-  sandboxir::SchedBundle Bndl({SN0, SN1});
-
-  // Check getTop().
-  EXPECT_EQ(Bndl.getTop(), SN0);
-  // Check getBot().
-  EXPECT_EQ(Bndl.getBot(), SN1);
-  // Check cluster().
-  Bndl.cluster(S1->getIterator());
-  {
-    auto It = BB->begin();
-    EXPECT_EQ(&*It++, Other);
-    EXPECT_EQ(&*It++, S0);
-    EXPECT_EQ(&*It++, S1);
-    EXPECT_EQ(&*It++, Ret);
-    S0->moveBefore(Other);
-  }
-
-  Bndl.cluster(S0->getIterator());
-  {
-    auto It = BB->begin();
-    EXPECT_EQ(&*It++, S0);
-    EXPECT_EQ(&*It++, S1);
-    EXPECT_EQ(&*It++, Other);
-    EXPECT_EQ(&*It++, Ret);
-    S1->moveAfter(Other);
-  }
-
-  Bndl.cluster(Other->getIterator());
-  {
-    auto It = BB->begin();
-    EXPECT_EQ(&*It++, S0);
-    EXPECT_EQ(&*It++, S1);
-    EXPECT_EQ(&*It++, Other);
-    EXPECT_EQ(&*It++, Ret);
-    S1->moveAfter(Other);
-  }
-
-  Bndl.cluster(Ret->getIterator());
-  {
-    auto It = BB->begin();
-    EXPECT_EQ(&*It++, Other);
-    EXPECT_EQ(&*It++, S0);
-    EXPECT_EQ(&*It++, S1);
-    EXPECT_EQ(&*It++, Ret);
-    Other->moveBefore(S1);
-  }
-
-  Bndl.cluster(BB->end());
-  {
-    auto It = BB->begin();
-    EXPECT_EQ(&*It++, Other);
-    EXPECT_EQ(&*It++, Ret);
-    EXPECT_EQ(&*It++, S0);
-    EXPECT_EQ(&*It++, S1);
-    Ret->moveAfter(S1);
-    Other->moveAfter(S0);
-  }
-  // Check iterators.
-  EXPECT_THAT(Bndl, testing::ElementsAre(SN0, SN1));
-  EXPECT_THAT((const sandboxir::SchedBundle &)Bndl,
-              testing::ElementsAre(SN0, SN1));
-}
-
-// Check that when we erase a DAG node its SchedBundle gets updated.
-TEST_F(SchedulerTest, SchedBundleEraseDGNode) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1, i8 %v2, i8 %v3) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  store i8 %v3, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto *SN0 = DAG.getNode(S0);
-  auto *SN1 = DAG.getNode(S1);
-  auto *SN2 = DAG.getNode(S2);
-  auto *SN3 = DAG.getNode(S3);
-  {
-    // Check the common case, when the bundle contains unique nodes.
-    sandboxir::SchedBundle Bndl({SN0, SN1});
-    S0->eraseFromParent();
-    EXPECT_THAT(Bndl, testing::ElementsAre(SN1));
-  }
-  {
-    // Check corner case when the node appears more than once.
-    sandboxir::SchedBundle Bndl({SN2, SN3, SN2});
-    S2->eraseFromParent();
-    EXPECT_THAT(Bndl, testing::ElementsAre(SN3));
-  }
-}
-
-// Check that assigning a bundle to a DAG Node that is already assigned to a
-// bundle, removes the node from the old bundle.
-TEST_F(SchedulerTest, SchedBundleReassign) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1, i8 %v2) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  store i8 %v2, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto *SN0 = DAG.getNode(S0);
-  auto *SN1 = DAG.getNode(S1);
-  auto *SN2 = DAG.getNode(S2);
-  sandboxir::SchedBundle BndlOld({SN0, SN1});
-  sandboxir::SchedBundle BndlNew({SN0, SN2});
-  EXPECT_THAT(BndlOld, testing::ElementsAre(SN1));
-  EXPECT_THAT(BndlNew, testing::ElementsAre(SN0, SN2));
-}
-
-TEST_F(SchedulerTest, Basic) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i8 %v0, i8 %v1) {
-  store i8 %v0, ptr %ptr
-  store i8 %v1, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  {
-    // Schedule all instructions in sequence.
-    sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-    EXPECT_TRUE(Sched.trySchedule({Ret}));
-    EXPECT_TRUE(Sched.trySchedule({S1}));
-    EXPECT_TRUE(Sched.trySchedule({S0}));
-  }
-  {
-    // Skip instructions.
-    sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-    EXPECT_TRUE(Sched.trySchedule({Ret}));
-    EXPECT_TRUE(Sched.trySchedule({S0}));
-  }
-  {
-    // Try invalid scheduling. Dependency S0->S1.
-    sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-    EXPECT_TRUE(Sched.trySchedule({Ret}));
-    EXPECT_FALSE(Sched.trySchedule({S0, S1}));
-  }
-}
-
-TEST_F(SchedulerTest, Bundles) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1) {
-  %ld0 = load i8, ptr %ptr0
-  %ld1 = load i8, ptr %ptr1
-  store i8 %ld0, ptr %ptr0
-  store i8 %ld1, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({Ret}));
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-}
-
-TEST_F(SchedulerTest, TrimSchedule) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %arg) {
-  %zext = zext i8 0 to i32
-  %ld0 = load i8, ptr %ptr0
-  %ld1 = load i8, ptr %ptr1
-  %add0 = add i8 %ld0, %ld0
-  %add1 = add i8 %ld1, %ld1
-  store i8 %add0, ptr %ptr0
-  store i8 %add1, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *Z = cast<sandboxir::CastInst>(&*It++);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({Ret}));
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-  // At this point Add0 and Add1 should have been individually scheduled
-  // as singleton bundles, but {S0,S1} and {L0,L1} as vector bundles.
-  // Check if rescheduling works.
-  EXPECT_TRUE(Sched.trySchedule({Add0, Add1}));
-  // These should fail because {L0,L1} is a vector bundle.
-  EXPECT_FALSE(Sched.trySchedule({L0, Z}));
-  EXPECT_FALSE(Sched.trySchedule({L1, Z}));
-  // This should succeed because it matches the original vec bundle.
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-}
-
-// Make sure that instructions in  SchedBundles are always scheduled
-// back-to-back
-TEST_F(SchedulerTest, SchedBundleBackToBack) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr, i16 %arg) {
-  %gep0 = getelementptr i32, ptr %ptr, i64 0
-  %gep1 = getelementptr i32, ptr %ptr, i64 1
-  %zextX = zext i16 0 to i32
-  %zext1 = zext i16 0 to i32
-  %zext0 = zext i16 %arg to i32
-  %shl1 = shl i32 %zextX, 0
-  %shl0 = shl i32 %zext1, 0
-  %sub1 = sub i32 %zext1, %shl1
-  %sub0 = sub i32 %zext0, %shl0
-  store i32 %sub1, ptr %gep1
-  store i32 %sub0, ptr %gep0
-  ret void
-})IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  [[maybe_unused]] auto *Gep0 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  [[maybe_unused]] auto *Gep1 = cast<sandboxir::GetElementPtrInst>(&*It++);
-  [[maybe_unused]] auto *ZextX = cast<sandboxir::CastInst>(&*It++);
-  auto *Zext1 = cast<sandboxir::CastInst>(&*It++);
-  auto *Zext0 = cast<sandboxir::CastInst>(&*It++);
-  auto *Shl1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Shl0 = cast<sandboxir::BinaryOperator>(&*It++);
-  [[maybe_unused]] auto *Sub1 = cast<sandboxir::BinaryOperator>(&*It++);
-  [[maybe_unused]] auto *Sub0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({Zext0, Zext1}));
-  EXPECT_TRUE(Sched.trySchedule({Shl0, Shl1}));
-  auto BackToBack = [](sandboxir::Instruction *I1, sandboxir::Instruction *I2) {
-    return I1->getNextNode() == I2 || I2->getNextNode() == I1;
-  };
-  EXPECT_TRUE(BackToBack(S0, S1));
-  EXPECT_TRUE(BackToBack(Zext0, Zext1));
-  EXPECT_TRUE(BackToBack(Shl0, Shl1));
-}
-
-// Test that an instruction can't belong in two bundles!
-TEST_F(SchedulerTest, CheckBundles) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) {
-  %L0 = load i8, ptr %ptr0
-  %L1 = load i8, ptr %ptr1 ; This belongs in 2 bundles!
-  %L2 = load i8, ptr %ptr2
-  %add0 = add i8 %L0, %L1
-  %add1 = add i8 %L1, %L2
-  store i8 %add0, ptr %ptr0
-  store i8 %add1, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({Add0, Add1}));
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-  // This should fail because L1 is already part of {L0,L1}
-  EXPECT_FALSE(Sched.trySchedule({L1, L2}));
-  EXPECT_FALSE(Sched.trySchedule({L2, L1}));
-}
-
-// Try schedule a bundle {L1,L2} where L1 is already scheduled in {L0,L1}
-// but L2 is not in the DAG at all
-TEST_F(SchedulerTest, CheckBundles2) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) {
-  %L2 = load i8, ptr %ptr2 ; This is not in the DAG
-  %L1 = load i8, ptr %ptr1 ; This belongs in 2 bundles!
-  %L0 = load i8, ptr %ptr0
-  %add1 = add i8 %L1, %L2
-  %add0 = add i8 %L0, %L1
-  store i8 %add1, ptr %ptr1
-  store i8 %add0, ptr %ptr0
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({Add0, Add1}));
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-  // This should fail because L1 is already part of {L0,L1}.
-  EXPECT_FALSE(Sched.trySchedule({L1, L2}));
-  EXPECT_FALSE(Sched.trySchedule({L2, L1}));
-}
-
-// Try schedule a bundle {L1,L2} where L1 is already scheduled in {L0,L1}
-// but L2 is in the DAG but isn't scheduled.
-TEST_F(SchedulerTest, CheckBundles3) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) {
-  %L2 = load i8, ptr %ptr2 ; This is not in the DAG
-  %L1 = load i8, ptr %ptr1 ; This belongs in 2 bundles!
-  %L0 = load i8, ptr %ptr0
-  %add1 = add i8 %L1, %L2
-  %add0 = add i8 %L0, %L1
-  store i8 %add1, ptr %ptr1
-  store i8 %add0, ptr %ptr0
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({Add0, Add1}));
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-  // Add L2 to the DAG, but don't schedule it.
-  auto &DAG = sandboxir::SchedulerInternalsAttorney::getDAG(Sched);
-  DAG.extend(L2);
-  // This should fail because L1 is already part of {L0,L1}.
-  EXPECT_FALSE(Sched.trySchedule({L1, L2}));
-  EXPECT_FALSE(Sched.trySchedule({L2, L1}));
-}
-
-// Check that Scheduler::getBndlSchedState() works correctly.
-TEST_F(SchedulerTest, GetBndlSchedState) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, ptr noalias %ptr2) {
-  %L2 = load i8, ptr %ptr2 ; This is not in the DAG
-  %L1 = load i8, ptr %ptr1 ; This belongs in 2 bundles!
-  %L0 = load i8, ptr %ptr0
-  %add1 = add i8 %L1, %L2
-  %add0 = add i8 %L0, %L1
-  store i8 %add1, ptr %ptr1
-  store i8 %add0, ptr %ptr0
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Add1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  auto &DAG = sandboxir::SchedulerInternalsAttorney::getDAG(Sched);
-  auto GetBndlSchedState = [&Sched](ArrayRef<sandboxir::Instruction *> Instrs) {
-    return sandboxir::SchedulerInternalsAttorney::getBndlSchedState(Sched,
-                                                                    Instrs);
-  };
-  using BndlSchedState = sandboxir::SchedulerInternalsAttorney::BndlSchedState;
-  // Check when instructions are not in the DAG.
-  EXPECT_EQ(GetBndlSchedState({S0}), BndlSchedState::NoneScheduled);
-  EXPECT_EQ(GetBndlSchedState({S0, S1}), BndlSchedState::NoneScheduled);
-  EXPECT_EQ(GetBndlSchedState({S0, S1}), BndlSchedState::NoneScheduled);
-  // Check when instructions are in the DAG.
-  DAG.extend({S0, S1});
-  EXPECT_EQ(GetBndlSchedState({S0}), BndlSchedState::NoneScheduled);
-  EXPECT_EQ(GetBndlSchedState({S0, S1}), BndlSchedState::NoneScheduled);
-  EXPECT_EQ(GetBndlSchedState({S0, S1}), BndlSchedState::NoneScheduled);
-  // One instruction in the DAG and the other not in the DAG.
-  EXPECT_EQ(GetBndlSchedState({S0, Add0}), BndlSchedState::NoneScheduled);
-
-  // Check with scheduled instructions.
-  Sched.clear(); // Manually extending the DAG messes with the scheduler.
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  // Check fully scheduled.
-  EXPECT_EQ(GetBndlSchedState({S0, S1}), BndlSchedState::FullyScheduled);
-  // Check scheduled + not in DAG.
-  EXPECT_EQ(GetBndlSchedState({S0, Add0}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add0, S0}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add0, S1}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add0, Add1}), BndlSchedState::NoneScheduled);
-  // Extend DAG such that Add0 and Add1 are in the DAG but are not scheduled.
-  DAG.extend({Add0, Add1});
-  // Check both in DAG but not scheduled.
-  EXPECT_EQ(GetBndlSchedState({Add0, Add1}), BndlSchedState::NoneScheduled);
-  // Check scheduled + in DAG but not scheduled.
-  EXPECT_EQ(GetBndlSchedState({S0, Add0}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add0, S0}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add0, S1}), BndlSchedState::AlreadyScheduled);
-
-  Sched.clear(); // Manually extending the DAG messes with the scheduler.
-  // Schedule instructions towards the top so that intermediate instructions
-  // (namely Add0, Add1) get temporarily scheduled in singleton bundles.
-  EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-  EXPECT_TRUE(Sched.trySchedule({L0, L1}));
-  // Check fully scheduled.
-  EXPECT_EQ(GetBndlSchedState({L0, L1}), BndlSchedState::FullyScheduled);
-  // Check both singletons.
-  EXPECT_EQ(GetBndlSchedState({Add0, Add1}),
-            BndlSchedState::TemporarilyScheduled);
-  // Check single singleton.
-  EXPECT_EQ(GetBndlSchedState({Add0}), BndlSchedState::TemporarilyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add1}), BndlSchedState::TemporarilyScheduled);
-  // Check singleton + scheduled.
-  EXPECT_EQ(GetBndlSchedState({L0, S1}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({S1, L0}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({L0, Add1}), BndlSchedState::AlreadyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add1, L0}), BndlSchedState::AlreadyScheduled);
-  // Check singleton + not in DAG.
-  EXPECT_EQ(GetBndlSchedState({Add1, L2}),
-            BndlSchedState::TemporarilyScheduled);
-  EXPECT_EQ(GetBndlSchedState({L2, Add0}),
-            BndlSchedState::TemporarilyScheduled);
-
-  // Check duplicates.
-  // TODO: Should duplicates be allowed?
-  EXPECT_EQ(GetBndlSchedState({L2, L2}), BndlSchedState::NoneScheduled);
-  EXPECT_EQ(GetBndlSchedState({S0, S0}), BndlSchedState::FullyScheduled);
-  EXPECT_EQ(GetBndlSchedState({Add0, Add1}),
-            BndlSchedState::TemporarilyScheduled);
-}
-
-// Check scheduling in the following order: {A0,A1},{B0,B1},{C0,C1},{D0,D1}
-// assuming program order: B0,B1,C0,C1,D0,D1,E0,D1.
-// This will effectively schedule nodes below already scheduled nodes, which
-// can expose issues in the code that adds nodes to the ready list.
-// For example, we schedule {D0,D1} while {C0,C1} are scheduled and there is
-// a dependency D0->C0 and D1->C1.
-//
-//                   {A0,A1}  {B0,B1}  {C0,C1}  {D0,D1}
-//   B0,B1                    | S
-//   |\                       |
-//   | C0,C1                  |        | S      | S
-//   |  | \                   |                 |
-//   |  |  D0,D1              |                 | S
-//   | /                      |
-//   A0,A1             | S    | S
-//                 +------------------------+
-//                 | Legend   |: DAG        |
-//                 |          S: Scheduled  |
-TEST_F(SchedulerTest, ScheduledPredecessors) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptrA0, ptr noalias %ptrA1,
-                 ptr noalias %ptrB0, ptr noalias %ptrB1,
-                 ptr noalias %ptrD0, ptr noalias %ptrD1) {
-  %B0 = load i8, ptr %ptrB0
-  %B1 = load i8, ptr %ptrB1
-  %C0 = add i8 %B0, 0
-  %C1 = add i8 %B1, 1
-  store i8 %C0, ptr %ptrD0
-  store i8 %C1, ptr %ptrD1
-  store i8 %B0, ptr %ptrA0
-  store i8 %B1, ptr %ptrA1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *B1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *B0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *C1 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *C0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *D1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *D0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *A1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *A0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  (void)Ret;
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  EXPECT_TRUE(Sched.trySchedule({A0, A1}));
-  // NOTE: We schedule the intermediate nodes between {A0,A1} and {B0,B1} by
-  // hand one by one to make sure they are scheduled in that order because
-  // the scheduler may reorder them a bit if we let it do it.
-  EXPECT_TRUE(Sched.trySchedule(D0));
-  EXPECT_TRUE(Sched.trySchedule(D1));
-  EXPECT_TRUE(Sched.trySchedule(C0));
-  EXPECT_TRUE(Sched.trySchedule(C1));
-  EXPECT_TRUE(Sched.trySchedule({B0, B1}));
-  // At this point all nodes must have been scheduled from B0,B1 to A0,A1.
-  // The ones in between are scheduled as single-instruction nodes.
-  // So when we attempt to schedule {C0,C1} we will need to reschedule.
-  // At this point we will trim the schedule from {C0,C1} upwards.
-  EXPECT_TRUE(Sched.trySchedule({C0, C1}));
-  // Now the schedule should only contain {C0,C1} which should be marked as
-  // "scheduled".
-  // {D0,D1} are below {C0,C1}, so we grow the DAG downwards, while
-  // {C0,C1} are marked as "scheduled" above them.
-  EXPECT_TRUE(Sched.trySchedule({D0, D1}));
-}
-
-TEST_F(SchedulerTest, DontCrossBBs) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr0, ptr noalias %ptr1, i8 %v0, i8 %v1) {
-bb0:
-  %add0 = add i8 %v0, 0
-  %add1 = add i8 %v1, 1
-  br label %bb1
-
-bb1:
-  store i8 %add0, ptr %ptr0
-  store i8 %add1, ptr %ptr1
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB0 = getBasicBlockByName(F, "bb0");
-  auto *BB1 = getBasicBlockByName(F, "bb1");
-  auto It = BB0->begin();
-  auto *Add0 = &*It++;
-  auto *Add1 = &*It++;
-
-  It = BB1->begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  {
-    // Schedule bottom-up
-    sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-    EXPECT_TRUE(Sched.trySchedule({Ret}));
-    EXPECT_TRUE(Sched.trySchedule({S0, S1}));
-    // Scheduling across blocks should fail.
-    EXPECT_FALSE(Sched.trySchedule({Add0, Add1}));
-  }
-  {
-    // Schedule top-down
-    sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-    EXPECT_TRUE(Sched.trySchedule({Add0, Add1}));
-    // Scheduling across blocks should fail.
-    EXPECT_FALSE(Sched.trySchedule({S0, S1}));
-  }
-}
-
-TEST_F(SchedulerTest, NotifyCreateInst) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, ptr noalias %ptr1, ptr noalias %ptr2) {
-  %ld0 = load i8, ptr %ptr
-  store i8 %ld0, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  auto *Ptr1 = F->getArg(1);
-  auto *Ptr2 = F->getArg(2);
-
-  sandboxir::Scheduler Sched(getAA(*LLVMF), Ctx);
-  // Schedule Ret and S0. The top of schedule should be at S0.
-  EXPECT_TRUE(Sched.trySchedule({Ret}));
-  EXPECT_TRUE(Sched.trySchedule({S0}));
-  auto &DAG = sandboxir::SchedulerInternalsAttorney::getDAG(Sched);
-  DAG.extend({L0});
-  auto *L0N = DAG.getNode(L0);
-  EXPECT_EQ(L0N->getNumUnscheduledSuccs(), 0u);
-  // We should have DAG nodes for all instructions at this point
-
-  // Now create a new instruction below S0.
-  sandboxir::StoreInst *NewS1 =
-      sandboxir::StoreInst::create(L0, Ptr1, Align(8), Ret->getIterator(),
-                                   /*IsVolatile=*/false, Ctx);
-  // Check that it is marked as "scheduled".
-  auto *NewS1N = DAG.getNode(NewS1);
-  EXPECT_TRUE(NewS1N->scheduled());
-  // Check that L0's UnscheduledSuccs are still == 0 since NewS1 is "scheduled".
-  EXPECT_EQ(L0N->getNumUnscheduledSuccs(), 0u);
-
-  // Now create a new instruction above S0.
-  sandboxir::StoreInst *NewS2 =
-      sandboxir::StoreInst::create(L0, Ptr2, Align(8), S0->getIterator(),
-                                   /*IsVolatile=*/false, Ctx);
-  // Check that it is not marked as "scheduled".
-  auto *NewS2N = DAG.getNode(NewS2);
-  EXPECT_FALSE(NewS2N->scheduled());
-  // Check that L0's UnscheduledSuccs got updated because of NewS2.
-  EXPECT_EQ(L0N->getNumUnscheduledSuccs(), 1u);
-
-  sandboxir::ReadyListContainer ReadyList;
-  // Check empty().
-  EXPECT_TRUE(ReadyList.empty());
-}
-
-TEST_F(SchedulerTest, ReadyList) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-  %ld0 = load i8, ptr %ptr
-  store i8 %ld0, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB = &*F->begin();
-  auto It = BB->begin();
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB->begin(), BB->getTerminator()});
-  auto *L0N = DAG.getNode(L0);
-  auto *S0N = DAG.getNode(S0);
-  auto *RetN = DAG.getNode(Ret);
-
-  sandboxir::ReadyListContainer ReadyList;
-  // Check empty().
-  EXPECT_TRUE(ReadyList.empty());
-  // Check insert(), pop().
-  ReadyList.insert(L0N);
-  EXPECT_FALSE(ReadyList.empty());
-  EXPECT_EQ(ReadyList.pop(), L0N);
-  // Check clear().
-  ReadyList.insert(L0N);
-  EXPECT_FALSE(ReadyList.empty());
-  ReadyList.clear();
-  EXPECT_TRUE(ReadyList.empty());
-  // Check remove().
-  EXPECT_TRUE(ReadyList.empty());
-  ReadyList.remove(L0N); // Removing a non-existing node should be valid.
-  ReadyList.insert(L0N);
-  ReadyList.insert(S0N);
-  ReadyList.insert(RetN);
-  ReadyList.remove(S0N);
-  DenseSet<sandboxir::DGNode *> Nodes;
-  Nodes.insert(ReadyList.pop());
-  Nodes.insert(ReadyList.pop());
-  EXPECT_TRUE(ReadyList.empty());
-  EXPECT_THAT(Nodes, testing::UnorderedElementsAre(L0N, RetN));
-}
-
-TEST_F(SchedulerTest, ReadyListPriorities) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptr) {
-bb0:
-  br label %bb1
-
-bb1:
-  %phi0 = phi i8 [0, %bb0], [1, %bb1]
-  %phi1 = phi i8 [0, %bb0], [1, %bb1]
-  %ld0 = load i8, ptr %ptr
-  store i8 %ld0, ptr %ptr
-  ret void
-}
-)IR");
-  llvm::Function *LLVMF = &*M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto *F = Ctx.createFunction(LLVMF);
-  auto *BB1 = getBasicBlockByName(F, "bb1");
-  auto It = BB1->begin();
-  auto *Phi0 = cast<sandboxir::PHINode>(&*It++);
-  auto *Phi1 = cast<sandboxir::PHINode>(&*It++);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-
-  sandboxir::DependencyGraph DAG(getAA(*LLVMF), Ctx);
-  DAG.extend({&*BB1->begin(), BB1->getTerminator()});
-  auto *Phi0N = DAG.getNode(Phi0);
-  auto *Phi1N = DAG.getNode(Phi1);
-  auto *L0N = DAG.getNode(L0);
-  auto *S0N = DAG.getNode(S0);
-  auto *RetN = DAG.getNode(Ret);
-
-  sandboxir::ReadyListContainer ReadyList;
-  // Check PHI vs non-PHI.
-  ReadyList.insert(S0N);
-  ReadyList.insert(Phi0N);
-  EXPECT_EQ(ReadyList.pop(), Phi0N);
-  EXPECT_EQ(ReadyList.pop(), S0N);
-  ReadyList.insert(Phi0N);
-  ReadyList.insert(S0N);
-  EXPECT_EQ(ReadyList.pop(), Phi0N);
-  EXPECT_EQ(ReadyList.pop(), S0N);
-  // Check PHI vs terminator.
-  ReadyList.insert(RetN);
-  ReadyList.insert(Phi1N);
-  EXPECT_EQ(ReadyList.pop(), Phi1N);
-  EXPECT_EQ(ReadyList.pop(), RetN);
-  ReadyList.insert(Phi1N);
-  ReadyList.insert(RetN);
-  EXPECT_EQ(ReadyList.pop(), Phi1N);
-  EXPECT_EQ(ReadyList.pop(), RetN);
-  // Check terminator vs non-terminator.
-  ReadyList.insert(RetN);
-  ReadyList.insert(L0N);
-  EXPECT_EQ(ReadyList.pop(), L0N);
-  EXPECT_EQ(ReadyList.pop(), RetN);
-  ReadyList.insert(L0N);
-  ReadyList.insert(RetN);
-  EXPECT_EQ(ReadyList.pop(), L0N);
-  EXPECT_EQ(ReadyList.pop(), RetN);
-  // Check all, program order.
-  ReadyList.insert(RetN);
-  ReadyList.insert(L0N);
-  ReadyList.insert(Phi1N);
-  ReadyList.insert(S0N);
-  ReadyList.insert(Phi0N);
-  EXPECT_EQ(ReadyList.pop(), Phi0N);
-  EXPECT_EQ(ReadyList.pop(), Phi1N);
-  EXPECT_EQ(ReadyList.pop(), L0N);
-  EXPECT_EQ(ReadyList.pop(), S0N);
-  EXPECT_EQ(ReadyList.pop(), RetN);
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SeedCollectorTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SeedCollectorTest.cpp
deleted file mode 100644
index 31b4a5ec9e391..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/SeedCollectorTest.cpp
+++ /dev/null
@@ -1,565 +0,0 @@
-//===- SeedCollectorTest.cpp ----------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/SeedCollector.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Instruction.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Testing/Support/SupportHelpers.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-// TODO: gcc-10 has a bug that causes the below line not to compile due to some
-// macro-magic in gunit in combination with a class with pure-virtual
-// function. Once gcc-10 is no longer supported, replace this function with
-// something like the following:
-//
-// EXPECT_THAT(SB, testing::ElementsAre(St0, St1, St2, St3));
-static void
-ExpectThatElementsAre(sandboxir::SeedBundle &SR,
-                      llvm::ArrayRef<sandboxir::Instruction *> Contents) {
-  EXPECT_EQ(range_size(SR), Contents.size());
-  auto CI = Contents.begin();
-  if (range_size(SR) == Contents.size())
-    for (auto &S : SR)
-      EXPECT_EQ(S, *CI++);
-}
-
-struct SeedBundleTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-
-  void parseIR(LLVMContext &C, const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M)
-      Err.print("LegalityTest", errs());
-  }
-  BasicBlock *getBasicBlockByName(Function &F, StringRef Name) {
-    for (BasicBlock &BB : F)
-      if (BB.getName() == Name)
-        return &BB;
-    llvm_unreachable("Expected to find basic block!");
-  }
-};
-
-// Stub class to make the abstract base class testable.
-class SeedBundleForTest : public sandboxir::SeedBundle {
-public:
-  using sandboxir::SeedBundle::SeedBundle;
-  void insert(sandboxir::Instruction *I, ScalarEvolution &SE) override {
-    insertAt(Seeds.end(), I);
-  }
-};
-
-TEST_F(SeedBundleTest, SeedBundle) {
-  parseIR(C, R"IR(
-define void @foo(float %v0, i32 %i0, i16 %i1, i8 %i2) {
-bb:
-  %add0 = fadd float %v0, %v0
-  %add1 = fadd float %v0, %v0
-  %add2 = add i8 %i2, %i2
-  %add3 = add i16 %i1, %i1
-  %add4 = add i32 %i0, %i0
-  %add5 = add i16 %i1, %i1
-  %add6 = add i8 %i2, %i2
-  %add7 = add i8 %i2, %i2
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  DataLayout DL(M->getDataLayout());
-  auto *BB = &*F.begin();
-  auto It = BB->begin();
-  auto *I0 = &*It++;
-  auto *I1 = &*It++;
-  // Assume first two instructions are identical in the number of bits.
-  const unsigned IOBits = sandboxir::Utils::getNumBits(I0, DL);
-  // Constructor
-  SeedBundleForTest SBO(I0);
-  EXPECT_EQ(*SBO.begin(), I0);
-  // getNumUnusedBits after constructor
-  EXPECT_EQ(SBO.getNumUnusedBits(), IOBits);
-  // setUsed
-  SBO.setUsed(I0);
-  // allUsed
-  EXPECT_TRUE(SBO.allUsed());
-  // isUsed
-  EXPECT_TRUE(SBO.isUsed(0));
-  // getNumUnusedBits after setUsed
-  EXPECT_EQ(SBO.getNumUnusedBits(), 0u);
-  // insertAt
-  SBO.insertAt(SBO.end(), I1);
-  EXPECT_NE(*SBO.begin(), I1);
-  // getNumUnusedBits after insertAt
-  EXPECT_EQ(SBO.getNumUnusedBits(), IOBits);
-  // allUsed
-  EXPECT_FALSE(SBO.allUsed());
-  // getFirstUnusedElement
-  EXPECT_EQ(SBO.getFirstUnusedElementIdx(), 1u);
-
-  SmallVector<sandboxir::Instruction *> Insts;
-  // add2 through add7
-  Insts.push_back(&*It++);
-  Insts.push_back(&*It++);
-  Insts.push_back(&*It++);
-  Insts.push_back(&*It++);
-  Insts.push_back(&*It++);
-  Insts.push_back(&*It++);
-  unsigned BundleBits = 0;
-  for (auto &S : Insts)
-    BundleBits += sandboxir::Utils::getNumBits(S);
-  // Ensure the instructions are as expected.
-  EXPECT_EQ(BundleBits, 88u);
-  auto Seeds = Insts;
-  // Constructor
-  SeedBundleForTest SB1(std::move(Seeds));
-  // getNumUnusedBits after constructor
-  EXPECT_EQ(SB1.getNumUnusedBits(), BundleBits);
-  // setUsed with index
-  SB1.setUsed(1);
-  // getFirstUnusedElementIdx
-  EXPECT_EQ(SB1.getFirstUnusedElementIdx(), 0u);
-  SB1.setUsed(unsigned(0));
-  // getFirstUnusedElementIdx not at end
-  EXPECT_EQ(SB1.getFirstUnusedElementIdx(), 2u);
-
-  // getSlice is (StartIdx, MaxVecRegBits, ForcePowerOf2). It's easier to
-  // compare test cases without the parameter-name comments inline.
-  auto Slice0 = SB1.getSlice(2, 64, true);
-  EXPECT_THAT(Slice0,
-              testing::ElementsAre(Insts[2], Insts[3], Insts[4], Insts[5]));
-  auto Slice1 = SB1.getSlice(2, 72, true);
-  EXPECT_THAT(Slice1,
-              testing::ElementsAre(Insts[2], Insts[3], Insts[4], Insts[5]));
-  auto Slice2 = SB1.getSlice(2, 80, true);
-  EXPECT_THAT(Slice2,
-              testing::ElementsAre(Insts[2], Insts[3], Insts[4], Insts[5]));
-
-  SB1.setUsed(2);
-  auto Slice3 = SB1.getSlice(3, 64, false);
-  EXPECT_THAT(Slice3, testing::ElementsAre(Insts[3], Insts[4], Insts[5]));
-  // getSlice empty case
-  SB1.setUsed(3);
-  auto Slice4 = SB1.getSlice(4, /* MaxVecRegBits */ 8,
-                             /* ForcePowerOf2 */ true);
-  EXPECT_EQ(Slice4.size(), 0u);
-}
-
-TEST_F(SeedBundleTest, MemSeedBundle) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptrA, float %val, ptr %ptr) {
-bb:
-  %gep0 = getelementptr float, ptr %ptr, i32 0
-  %gep1 = getelementptr float, ptr %ptr, i32 1
-  %gep2 = getelementptr float, ptr %ptr, i32 3
-  %gep3 = getelementptr float, ptr %ptr, i32 4
-  store float %val, ptr %gep0
-  store float %val, ptr %gep1
-  store float %val, ptr %gep2
-  store float %val, ptr %gep3
-
-  load float, ptr %gep0
-  load float, ptr %gep1
-  load float, ptr %gep2
-  load float, ptr %gep3
-
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto *BB = &*F.begin();
-  auto It = std::next(BB->begin(), 4);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-
-  // Single instruction constructor; test insert out of memory order
-  sandboxir::StoreSeedBundle SB(S3);
-  SB.insert(S1, SE);
-  SB.insert(S2, SE);
-  SB.insert(S0, SE);
-  EXPECT_THAT(SB, testing::ElementsAre(S0, S1, S2, S3));
-
-  // Instruction list constructor; test list out of order
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L3 = cast<sandboxir::LoadInst>(&*It++);
-  SmallVector<sandboxir::Instruction *> Loads;
-  Loads.push_back(L1);
-  Loads.push_back(L3);
-  Loads.push_back(L2);
-  Loads.push_back(L0);
-  sandboxir::LoadSeedBundle LB(std::move(Loads), SE);
-  EXPECT_THAT(LB, testing::ElementsAre(L0, L1, L2, L3));
-}
-
-TEST_F(SeedBundleTest, Container) {
-  parseIR(C, R"IR(
-define void @foo(ptr %ptrA, float %val, ptr %ptrB) {
-bb:
-  %gepA0 = getelementptr float, ptr %ptrA, i32 0
-  %gepA1 = getelementptr float, ptr %ptrA, i32 1
-  %gepB0 = getelementptr float, ptr %ptrB, i32 0
-  %gepB1 = getelementptr float, ptr %ptrB, i32 1
-  store float %val, ptr %gepA0
-  store float %val, ptr %gepA1
-  store float %val, ptr %gepB0
-  store float %val, ptr %gepB1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = std::next(BB.begin(), 4);
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S2 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S3 = cast<sandboxir::StoreInst>(&*It++);
-  sandboxir::SeedContainer SC(SE);
-  // Check begin() end() when empty.
-  EXPECT_EQ(SC.begin(), SC.end());
-
-  SC.insert(S0, /*AllowDiffTypes=*/false);
-  SC.insert(S1, /*AllowDiffTypes=*/false);
-  SC.insert(S2, /*AllowDiffTypes=*/false);
-  SC.insert(S3, /*AllowDiffTypes=*/false);
-  unsigned Cnt = 0;
-  SmallVector<sandboxir::SeedBundle *> Bndls;
-  for (auto &SeedBndl : SC) {
-    EXPECT_EQ(SeedBndl.size(), 2u);
-    ++Cnt;
-    Bndls.push_back(&SeedBndl);
-  }
-  EXPECT_EQ(Cnt, 2u);
-
-  // Mark them "Used" to check if operator++ skips them in the next loop.
-  for (auto *SeedBndl : Bndls)
-    for (auto Lane : seq<unsigned>(SeedBndl->size()))
-      SeedBndl->setUsed(Lane);
-  // Check if iterator::operator++ skips used lanes.
-  Cnt = 0;
-  for (auto &SeedBndl : SC) {
-    (void)SeedBndl;
-    ++Cnt;
-  }
-  EXPECT_EQ(Cnt, 0u);
-}
-
-TEST_F(SeedBundleTest, ConsecutiveStores) {
-  // Where "Consecutive" means the stores address consecutive locations in
-  // memory, but not in program order. Check to see that the collector puts them
-  // in the proper order for vectorization.
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, float %val) {
-bb:
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptr2 = getelementptr float, ptr %ptr, i32 2
-  %ptr3 = getelementptr float, ptr %ptr, i32 3
-  store float %val, ptr %ptr0
-  store float %val, ptr %ptr2
-  store float %val, ptr %ptr1
-  store float %val, ptr %ptr3
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto BB = F.begin();
-  sandboxir::SeedCollector SC(&*BB, SE, /*CollectStores=*/true,
-                              /*CollectLoads=*/false);
-
-  // Find the stores
-  auto It = std::next(BB->begin(), 4);
-  // StX with X as the order by offset in memory
-  auto *St0 = &*It++;
-  auto *St2 = &*It++;
-  auto *St1 = &*It++;
-  auto *St3 = &*It++;
-
-  auto StoreSeedsRange = SC.getStoreSeeds();
-  auto &SB = *StoreSeedsRange.begin();
-  //  Expect just one vector of store seeds
-  EXPECT_EQ(range_size(StoreSeedsRange), 1u);
-  ExpectThatElementsAre(SB, {St0, St1, St2, St3});
-}
-
-TEST_F(SeedBundleTest, StoresWithGaps) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, float %val) {
-bb:
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 3
-  %ptr2 = getelementptr float, ptr %ptr, i32 5
-  %ptr3 = getelementptr float, ptr %ptr, i32 7
-  store float %val, ptr %ptr0
-  store float %val, ptr %ptr2
-  store float %val, ptr %ptr1
-  store float %val, ptr %ptr3
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto BB = F.begin();
-  sandboxir::SeedCollector SC(&*BB, SE, /*CollectStores=*/true,
-                              /*CollectLoads=*/false);
-
-  // Find the stores
-  auto It = std::next(BB->begin(), 4);
-  // StX with X as the order by offset in memory
-  auto *St0 = &*It++;
-  auto *St2 = &*It++;
-  auto *St1 = &*It++;
-  auto *St3 = &*It++;
-
-  auto StoreSeedsRange = SC.getStoreSeeds();
-  auto &SB = *StoreSeedsRange.begin();
-  // Expect just one vector of store seeds
-  EXPECT_EQ(range_size(StoreSeedsRange), 1u);
-  ExpectThatElementsAre(SB, {St0, St1, St2, St3});
-  // Check that the EraseInstr callback works.
-
-  // TODO: Range_size counts fully used-bundles even though the iterator skips
-  // them. Further, iterating over anything other than the Bundles in a
-  // SeedContainer includes used seeds. So for now just check that removing all
-  // the seeds from a bundle also empties the bundle.
-  St0->eraseFromParent();
-  St1->eraseFromParent();
-  St2->eraseFromParent();
-  St3->eraseFromParent();
-  size_t nonEmptyBundleCount = 0;
-  for (auto &B : SC.getStoreSeeds()) {
-    (void)B;
-    nonEmptyBundleCount++;
-  }
-  EXPECT_EQ(nonEmptyBundleCount, 0u);
-}
-
-TEST_F(SeedBundleTest, VectorStores) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, <2 x float> %val0, i64 %val1) {
-bb:
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptr2 = getelementptr i64, ptr %ptr, i32 2
-  store <2 x float> %val0, ptr %ptr1
-  store <2 x float> %val0, ptr %ptr0
-  store atomic i64 %val1, ptr %ptr2 unordered, align 8
-  store volatile i64 %val1, ptr %ptr2
-
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto BB = F.begin();
-  sandboxir::SeedCollector SC(&*BB, SE, /*CollectStores=*/true,
-                              /*CollectLoads=*/false);
-
-  // Find the stores
-  auto It = std::next(BB->begin(), 3);
-  // StX with X as the order by offset in memory
-  auto *St1 = &*It++;
-  auto *St0 = &*It++;
-
-  auto StoreSeedsRange = SC.getStoreSeeds();
-  EXPECT_EQ(range_size(StoreSeedsRange), 1u);
-  auto &SB = *StoreSeedsRange.begin();
-  // isValidMemSeed check: The atomic and volatile stores should not
-  // be included in the bundle, but the vector stores should be.
-  ExpectThatElementsAre(SB, {St0, St1});
-}
-
-TEST_F(SeedBundleTest, MixedScalarVectors) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, float %v, <2 x float> %val) {
-bb:
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %ptr3 = getelementptr float, ptr %ptr, i32 3
-  store float %v, ptr %ptr0
-  store float %v, ptr %ptr3
-  store <2 x float> %val, ptr %ptr1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto BB = F.begin();
-  sandboxir::SeedCollector SC(&*BB, SE, /*CollectStores=*/true,
-                              /*CollectLoads=*/false);
-
-  // Find the stores
-  auto It = std::next(BB->begin(), 3);
-  // StX with X as the order by offset in memory
-  auto *St0 = &*It++;
-  auto *St3 = &*It++;
-  auto *St1 = &*It++;
-
-  auto StoreSeedsRange = SC.getStoreSeeds();
-  EXPECT_EQ(range_size(StoreSeedsRange), 1u);
-  auto &SB = *StoreSeedsRange.begin();
-  // isValidMemSeedCheck here: all of the three stores should be included.
-  ExpectThatElementsAre(SB, {St0, St1, St3});
-}
-
-TEST_F(SeedBundleTest, DiffTypes) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, i8 %v, i16 %v16) {
-bb:
-  %ptr0 = getelementptr i8, ptr %ptr, i32 0
-  %ptr1 = getelementptr i8, ptr %ptr, i32 1
-  %ptr3 = getelementptr i8, ptr %ptr, i32 3
-  store i8 %v, ptr %ptr0
-  store i8 %v, ptr %ptr3
-  store i16 %v16, ptr %ptr1
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto BB = F.begin();
-  auto It = std::next(BB->begin(), 3);
-  auto *St0 = &*It++;
-  auto *St3 = &*It++;
-  auto *St1 = &*It++;
-
-  sandboxir::SeedCollector SC(&*BB, SE, /*CollectStores=*/true,
-                              /*CollectLoads=*/false, /*AllowDiffTypes=*/true);
-
-  auto StoreSeedsRange = SC.getStoreSeeds();
-  EXPECT_EQ(range_size(StoreSeedsRange), 1u);
-  auto &SB = *StoreSeedsRange.begin();
-  ExpectThatElementsAre(SB, {St0, St1, St3});
-}
-
-TEST_F(SeedBundleTest, VectorLoads) {
-  parseIR(C, R"IR(
-define void @foo(ptr noalias %ptr, <2 x float> %val0) {
-bb:
-  %ptr0 = getelementptr float, ptr %ptr, i32 0
-  %ptr1 = getelementptr float, ptr %ptr, i32 1
-  %r0 = load <2 x float>, ptr %ptr0
-  %r1 = load <2 x float>, ptr %ptr1
-  %r2 = load atomic i64, ptr %ptr0 unordered, align 8
-  %r3 = load volatile i64, ptr %ptr1
-  %r4 = load void()*, ptr %ptr1
-
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  DominatorTree DT(LLVMF);
-  TargetLibraryInfoImpl TLII(M->getTargetTriple());
-  TargetLibraryInfo TLI(TLII);
-  DataLayout DL(M->getDataLayout());
-  LoopInfo LI(DT);
-  AssumptionCache AC(LLVMF);
-  ScalarEvolution SE(LLVMF, TLI, AC, DT, LI);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto BB = F.begin();
-  sandboxir::SeedCollector SC(&*BB, SE, /*CollectStores=*/false,
-                              /*CollectLoads=*/true);
-
-  // Find the loads
-  auto It = std::next(BB->begin(), 2);
-  // StX with X as the order by offset in memory
-  auto *Ld0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *Ld1 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto LoadSeedsRange = SC.getLoadSeeds();
-  EXPECT_EQ(range_size(LoadSeedsRange), 2u);
-  auto &SB = *LoadSeedsRange.begin();
-  // isValidMemSeed check: The atomic and volatile loads should not
-  // be included in the bundle, the vector stores should be, but the
-  // void-typed load should not.
-  ExpectThatElementsAre(SB, {Ld0, Ld1});
-}
diff --git a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp b/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp
deleted file mode 100644
index 2bfea6908305c..0000000000000
--- a/llvm/unittests/Transforms/Vectorize/SandboxVectorizer/VecUtilsTest.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-//===- VecUtilsTest.cpp --------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/Transforms/Vectorize/SandboxVectorizer/VecUtils.h"
-#include "llvm/Analysis/AliasAnalysis.h"
-#include "llvm/Analysis/AssumptionCache.h"
-#include "llvm/Analysis/BasicAliasAnalysis.h"
-#include "llvm/Analysis/LoopInfo.h"
-#include "llvm/Analysis/ScalarEvolution.h"
-#include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/AsmParser/Parser.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/Dominators.h"
-#include "llvm/SandboxIR/Context.h"
-#include "llvm/SandboxIR/Function.h"
-#include "llvm/SandboxIR/Type.h"
-#include "llvm/Support/SourceMgr.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-using namespace llvm;
-
-struct VecUtilsTest : public testing::Test {
-  LLVMContext C;
-  std::unique_ptr<Module> M;
-  std::unique_ptr<AssumptionCache> AC;
-  std::unique_ptr<TargetLibraryInfoImpl> TLII;
-  std::unique_ptr<TargetLibraryInfo> TLI;
-  std::unique_ptr<DominatorTree> DT;
-  std::unique_ptr<LoopInfo> LI;
-  std::unique_ptr<ScalarEvolution> SE;
-  void parseIR(const char *IR) {
-    SMDiagnostic Err;
-    M = parseAssemblyString(IR, Err, C);
-    if (!M) {
-      Err.print("VecUtilsTest", errs());
-      return;
-    }
-
-    TLII = std::make_unique<TargetLibraryInfoImpl>(M->getTargetTriple());
-    TLI = std::make_unique<TargetLibraryInfo>(*TLII);
-  }
-
-  ScalarEvolution &getSE(llvm::Function &LLVMF) {
-    AC = std::make_unique<AssumptionCache>(LLVMF);
-    DT = std::make_unique<DominatorTree>(LLVMF);
-    LI = std::make_unique<LoopInfo>(*DT);
-    SE = std::make_unique<ScalarEvolution>(LLVMF, *TLI, *AC, *DT, *LI);
-    return *SE;
-  }
-};
-
-sandboxir::BasicBlock &getBasicBlockByName(sandboxir::Function &F,
-                                           StringRef Name) {
-  for (sandboxir::BasicBlock &BB : F)
-    if (BB.getName() == Name)
-      return BB;
-  llvm_unreachable("Expected to find basic block!");
-}
-
-TEST_F(VecUtilsTest, GetNumElements) {
-  sandboxir::Context Ctx(C);
-  auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx);
-  EXPECT_EQ(sandboxir::VecUtils::getNumElements(ElemTy), 1);
-  auto *VTy = sandboxir::FixedVectorType::get(ElemTy, 2);
-  EXPECT_EQ(sandboxir::VecUtils::getNumElements(VTy), 2);
-  auto *VTy1 = sandboxir::FixedVectorType::get(ElemTy, 1);
-  EXPECT_EQ(sandboxir::VecUtils::getNumElements(VTy1), 1);
-}
-
-TEST_F(VecUtilsTest, GetElementType) {
-  sandboxir::Context Ctx(C);
-  auto *ElemTy = sandboxir::Type::getInt32Ty(Ctx);
-  EXPECT_EQ(sandboxir::VecUtils::getElementType(ElemTy), ElemTy);
-  auto *VTy = sandboxir::FixedVectorType::get(ElemTy, 2);
-  EXPECT_EQ(sandboxir::VecUtils::getElementType(VTy), ElemTy);
-}
-
-TEST_F(VecUtilsTest, AreConsecutive_gep_float) {
-  parseIR(R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr inbounds float, ptr %ptr, i64 0
-  %gep1 = getelementptr inbounds float, ptr %ptr, i64 1
-  %gep2 = getelementptr inbounds float, ptr %ptr, i64 2
-  %gep3 = getelementptr inbounds float, ptr %ptr, i64 3
-
-  %ld0 = load float, ptr %gep0
-  %ld1 = load float, ptr %gep1
-  %ld2 = load float, ptr %gep2
-  %ld3 = load float, ptr %gep3
-
-  %v2ld0 = load <2 x float>, ptr %gep0
-  %v2ld1 = load <2 x float>, ptr %gep1
-  %v2ld2 = load <2 x float>, ptr %gep2
-  %v2ld3 = load <2 x float>, ptr %gep3
-
-  %v3ld0 = load <3 x float>, ptr %gep0
-  %v3ld1 = load <3 x float>, ptr %gep1
-  %v3ld2 = load <3 x float>, ptr %gep2
-  %v3ld3 = load <3 x float>, ptr %gep3
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  const DataLayout &DL = M->getDataLayout();
-  auto &SE = getSE(LLVMF);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-
-  auto &BB = *F.begin();
-  auto It = std::next(BB.begin(), 4);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  // Scalar
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL));
-
-  // Check 2-wide loads
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL));
-
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-
-  // Check 3-wide loads
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL));
-
-  // Check mixes of vectors and scalar
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL));
-
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL));
-}
-
-TEST_F(VecUtilsTest, AreConsecutive_gep_i8) {
-  parseIR(R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr inbounds i8, ptr %ptr, i64 0
-  %gep1 = getelementptr inbounds i8, ptr %ptr, i64 4
-  %gep2 = getelementptr inbounds i8, ptr %ptr, i64 8
-  %gep3 = getelementptr inbounds i8, ptr %ptr, i64 12
-
-  %ld0 = load float, ptr %gep0
-  %ld1 = load float, ptr %gep1
-  %ld2 = load float, ptr %gep2
-  %ld3 = load float, ptr %gep3
-
-  %v2ld0 = load <2 x float>, ptr %gep0
-  %v2ld1 = load <2 x float>, ptr %gep1
-  %v2ld2 = load <2 x float>, ptr %gep2
-  %v2ld3 = load <2 x float>, ptr %gep3
-
-  %v3ld0 = load <3 x float>, ptr %gep0
-  %v3ld1 = load <3 x float>, ptr %gep1
-  %v3ld2 = load <3 x float>, ptr %gep2
-  %v3ld3 = load <3 x float>, ptr %gep3
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  const DataLayout &DL = M->getDataLayout();
-  auto &SE = getSE(LLVMF);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = std::next(BB.begin(), 4);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  // Scalar
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL));
-
-  // Check 2-wide loads
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL));
-
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-
-  // Check 3-wide loads
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL));
-
-  // Check mixes of vectors and scalar
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL));
-
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL));
-}
-
-TEST_F(VecUtilsTest, AreConsecutive_gep_i1) {
-  parseIR(R"IR(
-define void @foo(ptr %ptr) {
-  %gep0 = getelementptr inbounds i1, ptr %ptr, i64 0
-  %gep1 = getelementptr inbounds i2, ptr %ptr, i64 4
-  %gep2 = getelementptr inbounds i3, ptr %ptr, i64 8
-  %gep3 = getelementptr inbounds i7, ptr %ptr, i64 12
-
-  %ld0 = load float, ptr %gep0
-  %ld1 = load float, ptr %gep1
-  %ld2 = load float, ptr %gep2
-  %ld3 = load float, ptr %gep3
-
-  %v2ld0 = load <2 x float>, ptr %gep0
-  %v2ld1 = load <2 x float>, ptr %gep1
-  %v2ld2 = load <2 x float>, ptr %gep2
-  %v2ld3 = load <2 x float>, ptr %gep3
-
-  %v3ld0 = load <3 x float>, ptr %gep0
-  %v3ld1 = load <3 x float>, ptr %gep1
-  %v3ld2 = load <3 x float>, ptr %gep2
-  %v3ld3 = load <3 x float>, ptr %gep3
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-  const DataLayout &DL = M->getDataLayout();
-  auto &SE = getSE(LLVMF);
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = std::next(BB.begin(), 4);
-  auto *L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V2L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V2L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  auto *V3L0 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L1 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L2 = cast<sandboxir::LoadInst>(&*It++);
-  auto *V3L3 = cast<sandboxir::LoadInst>(&*It++);
-
-  // Scalar
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, L1, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L2, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L1, L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L2, L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L3, L1, SE, DL));
-
-  // Check 2-wide loads
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V2L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L1, V2L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L2, V2L3, SE, DL));
-
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L3, V2L1, SE, DL));
-
-  // Check 3-wide loads
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, V3L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L1, V3L0, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L2, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L3, V3L2, SE, DL));
-
-  // Check mixes of vectors and scalar
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L0, V2L1, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(L1, V2L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, L2, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V3L0, L3, SE, DL));
-  EXPECT_TRUE(sandboxir::VecUtils::areConsecutive(V2L0, V3L2, SE, DL));
-
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V3L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(L0, V2L3, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L0, V3L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L1, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V3L0, V2L2, SE, DL));
-  EXPECT_FALSE(sandboxir::VecUtils::areConsecutive(V2L1, L0, SE, DL));
-}
-
-TEST_F(VecUtilsTest, GetNumLanes) {
-  parseIR(R"IR(
-define <4 x float> @foo(float %v, <2 x float> %v2, <4 x float> %ret, ptr %ptr) {
-  store float %v, ptr %ptr
-  store <2 x float> %v2, ptr %ptr
-  ret <4 x float> %ret
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-
-  auto It = BB.begin();
-  auto *S0 = cast<sandboxir::StoreInst>(&*It++);
-  auto *S1 = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S0->getValueOperand()->getType()),
-            1u);
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S0), 1u);
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S1->getValueOperand()->getType()),
-            2u);
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(S1), 2u);
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Ret->getReturnValue()->getType()),
-            4u);
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Ret), 4u);
-
-  SmallVector<sandboxir::Value *> Bndl({S0, S1, Ret});
-  EXPECT_EQ(sandboxir::VecUtils::getNumLanes(Bndl), 7u);
-}
-
-TEST_F(VecUtilsTest, GetWideType) {
-  sandboxir::Context Ctx(C);
-
-  auto *Int32Ty = sandboxir::Type::getInt32Ty(Ctx);
-  auto *Int32X4Ty = sandboxir::FixedVectorType::get(Int32Ty, 4);
-  EXPECT_EQ(sandboxir::VecUtils::getWideType(Int32Ty, 4), Int32X4Ty);
-  auto *Int32X8Ty = sandboxir::FixedVectorType::get(Int32Ty, 8);
-  EXPECT_EQ(sandboxir::VecUtils::getWideType(Int32X4Ty, 2), Int32X8Ty);
-}
-
-TEST_F(VecUtilsTest, GetLowest) {
-  parseIR(R"IR(
-define void @foo(i8 %v) {
-bb0:
-  br label %bb1
-bb1:
-  %A = add i8 %v, 1
-  %B = add i8 %v, 2
-  %C = add i8 %v, 3
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB0 = getBasicBlockByName(F, "bb0");
-  auto It = BB0.begin();
-  auto *BB0I = cast<sandboxir::BranchInst>(&*It++);
-
-  auto &BB = getBasicBlockByName(F, "bb1");
-  It = BB.begin();
-  auto *IA = cast<sandboxir::Instruction>(&*It++);
-  auto *C1 = cast<sandboxir::Constant>(IA->getOperand(1));
-  auto *IB = cast<sandboxir::Instruction>(&*It++);
-  auto *C2 = cast<sandboxir::Constant>(IB->getOperand(1));
-  auto *IC = cast<sandboxir::Instruction>(&*It++);
-  auto *C3 = cast<sandboxir::Constant>(IC->getOperand(1));
-  // Check getLowest(ArrayRef<Instruction *>)
-  SmallVector<sandboxir::Instruction *> A({IA});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(A), IA);
-  SmallVector<sandboxir::Instruction *> ABC({IA, IB, IC});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC), IC);
-  SmallVector<sandboxir::Instruction *> ACB({IA, IC, IB});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(ACB), IC);
-  SmallVector<sandboxir::Instruction *> CAB({IC, IA, IB});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(CAB), IC);
-  SmallVector<sandboxir::Instruction *> CBA({IC, IB, IA});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(CBA), IC);
-
-  // Check getLowest(ArrayRef<Value *>)
-  SmallVector<sandboxir::Value *> C1Only({C1});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(C1Only, &BB), nullptr);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(C1Only, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> AOnly({IA});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AOnly, &BB), IA);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AOnly, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> AC1({IA, C1});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1, &BB), IA);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> C1A({C1, IA});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(C1A, &BB), IA);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(C1A, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> AC1B({IA, C1, IB});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1B, &BB), IB);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1B, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> ABC1({IA, IB, C1});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC1, &BB), IB);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(ABC1, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> AC1C2({IA, C1, C2});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1C2, &BB), IA);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(AC1C2, &BB0), nullptr);
-  SmallVector<sandboxir::Value *> C1C2C3({C1, C2, C3});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(C1C2C3, &BB), nullptr);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(C1C2C3, &BB0), nullptr);
-
-  SmallVector<sandboxir::Value *> DiffBBs({BB0I, IA});
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(DiffBBs, &BB0), BB0I);
-  EXPECT_EQ(sandboxir::VecUtils::getLowest(DiffBBs, &BB), IA);
-}
-
-TEST_F(VecUtilsTest, GetLastPHIOrSelf) {
-  parseIR(R"IR(
-define void @foo(i8 %v) {
-entry:
-  br label %bb1
-
-bb1:
-  %phi1 = phi i8 [0, %entry], [1, %bb1]
-  %phi2 = phi i8 [0, %entry], [1, %bb1]
-  br label %bb1
-
-bb2:
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = getBasicBlockByName(F, "bb1");
-  auto It = BB.begin();
-  auto *PHI1 = cast<sandboxir::PHINode>(&*It++);
-  auto *PHI2 = cast<sandboxir::PHINode>(&*It++);
-  auto *Br = cast<sandboxir::BranchInst>(&*It++);
-  EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(PHI1), PHI2);
-  EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(PHI2), PHI2);
-  EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(Br), Br);
-  EXPECT_EQ(sandboxir::VecUtils::getLastPHIOrSelf(nullptr), nullptr);
-}
-
-TEST_F(VecUtilsTest, GetCommonScalarType) {
-  parseIR(R"IR(
-define void @foo(i8 %v, ptr %ptr) {
-bb0:
-  %add0 = add i8 %v, %v
-  store i8 %v, ptr %ptr
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = *F.begin();
-  auto It = BB.begin();
-  auto *Add0 = cast<sandboxir::BinaryOperator>(&*It++);
-  auto *Store = cast<sandboxir::StoreInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  {
-    SmallVector<sandboxir::Value *> Vec = {Add0, Store};
-    EXPECT_EQ(sandboxir::VecUtils::tryGetCommonScalarType(Vec),
-              Add0->getType());
-    EXPECT_EQ(sandboxir::VecUtils::getCommonScalarType(Vec), Add0->getType());
-  }
-  {
-    SmallVector<sandboxir::Value *> Vec = {Add0, Ret};
-    EXPECT_EQ(sandboxir::VecUtils::tryGetCommonScalarType(Vec), nullptr);
-#ifndef NDEBUG
-    EXPECT_DEATH(sandboxir::VecUtils::getCommonScalarType(Vec), ".*common.*");
-#endif // NDEBUG
-  }
-}
-
-TEST_F(VecUtilsTest, FloorPowerOf2) {
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(0), 0u);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(1 << 0), 1u << 0);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(3), 2u);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(4), 4u);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(5), 4u);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(7), 4u);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(8), 8u);
-  EXPECT_EQ(sandboxir::VecUtils::getFloorPowerOf2(9), 8u);
-}
-
-TEST_F(VecUtilsTest, MatchPackScalar) {
-  parseIR(R"IR(
-define void @foo(i8 %v0, i8 %v1) {
-bb0:
-  %NotPack = insertelement <2 x i8> poison, i8 %v0, i64 0
-  br label %bb1
-
-bb1:
-  %Pack0 = insertelement <2 x i8> poison, i8 %v0, i64 0
-  %Pack1 = insertelement <2 x i8> %Pack0, i8 %v1, i64 1
-
-  %NotPack0 = insertelement <2 x i8> poison, i8 %v0, i64 0
-  %NotPack1 = insertelement <2 x i8> %NotPack0, i8 %v1, i64 0
-  %NotPack2 = insertelement <2 x i8> %NotPack1, i8 %v1, i64 1
-
-  %NotPackBB = insertelement <2 x i8> %NotPack, i8 %v1, i64 1
-
-  ret void
-}
-)IR");
-  Function &LLVMF = *M->getFunction("foo");
-
-  sandboxir::Context Ctx(C);
-  auto &F = *Ctx.createFunction(&LLVMF);
-  auto &BB = getBasicBlockByName(F, "bb1");
-  auto It = BB.begin();
-  auto *Pack0 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *Pack1 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *NotPack0 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *NotPack1 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *NotPack2 = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *NotPackBB = cast<sandboxir::InsertElementInst>(&*It++);
-  auto *Ret = cast<sandboxir::ReturnInst>(&*It++);
-  auto *Arg0 = F.getArg(0);
-  auto *Arg1 = F.getArg(1);
-  EXPECT_FALSE(sandboxir::VecUtils::matchPack(Pack0));
-  EXPECT_FALSE(sandboxir::VecUtils::matchPack(Ret));
-  {
-    auto PackOpt = sandboxir::VecUtils::matchPack(Pack1);
-    EXPECT_TRUE(PackOpt);
-    EXPECT_THAT(PackOpt->Instrs, testing::ElementsAre(Pack1, Pack0));
-    EXPECT_THAT(PackOpt->Operands, testing::ElementsAre(Arg0, Arg1));
-  }
-  {
-    for (auto *NotPack : {NotPack0, NotPack1, NotPack2, NotPackBB})
-      EXPECT_FALSE(sandboxir::VecUtils::matchPack(NotPack));
-  }
-}



More information about the llvm-commits mailing list