Migrate LLVMCPU vectorization to its own pass. (#12837)

The below related code are deprecated because they are no longer used by
anyone.

- Deprecate SingleTilingExpert
- Deprecate StrategyVectorize pass

The VectorizationPattern and LinalgVectorizationPattern are not deleted
because they are used by LLVMGPU.
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/BUILD.bazel b/compiler/src/iree/compiler/Codegen/LLVMCPU/BUILD.bazel
index 57b2f91..0a8cc1f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/BUILD.bazel
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/BUILD.bazel
@@ -34,6 +34,7 @@
         "LLVMCPUTile.cpp",
         "LLVMCPUTileAndFuse.cpp",
         "LLVMCPUUnfuseFMAOps.cpp",
+        "LLVMCPUVectorization.cpp",
         "Passes.cpp",
         "TargetMLTransformInfo.cpp",
         "Utils.cpp",
@@ -74,6 +75,7 @@
         "@llvm-project//llvm:TargetParser",
         "@llvm-project//mlir:AffineDialect",
         "@llvm-project//mlir:AffineToStandard",
+        "@llvm-project//mlir:AffineUtils",
         "@llvm-project//mlir:Analysis",
         "@llvm-project//mlir:ArithDialect",
         "@llvm-project//mlir:ArithToLLVM",
@@ -108,6 +110,7 @@
         "@llvm-project//mlir:SCFDialect",
         "@llvm-project//mlir:SCFToControlFlow",
         "@llvm-project//mlir:SCFTransforms",
+        "@llvm-project//mlir:SCFUtils",
         "@llvm-project//mlir:TensorDialect",
         "@llvm-project//mlir:TensorTransforms",
         "@llvm-project//mlir:TosaDialect",
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/CMakeLists.txt b/compiler/src/iree/compiler/Codegen/LLVMCPU/CMakeLists.txt
index acac23d..da0f65b 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/CMakeLists.txt
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/CMakeLists.txt
@@ -38,6 +38,7 @@
     "LLVMCPUTile.cpp"
     "LLVMCPUTileAndFuse.cpp"
     "LLVMCPUUnfuseFMAOps.cpp"
+    "LLVMCPUVectorization.cpp"
     "Passes.cpp"
     "TargetMLTransformInfo.cpp"
     "Utils.cpp"
@@ -53,6 +54,7 @@
     LLVMTargetParser
     MLIRAffineDialect
     MLIRAffineToStandard
+    MLIRAffineUtils
     MLIRAnalysis
     MLIRArithDialect
     MLIRArithToLLVM
@@ -86,6 +88,7 @@
     MLIRSCFDialect
     MLIRSCFToControlFlow
     MLIRSCFTransforms
+    MLIRSCFUtils
     MLIRTensorDialect
     MLIRTensorTransforms
     MLIRTosaDialect
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPUVectorization.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPUVectorization.cpp
new file mode 100644
index 0000000..47440d0
--- /dev/null
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/LLVMCPUVectorization.cpp
@@ -0,0 +1,230 @@
+// Copyright 2023 The IREE Authors
+//
+// Licensed 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 "iree/compiler/Codegen/PassDetail.h"
+#include "iree/compiler/Codegen/Passes.h"
+#include "mlir/Dialect/Affine/IR/AffineOps.h"
+#include "mlir/Dialect/Affine/LoopUtils.h"
+#include "mlir/Dialect/Linalg/Transforms/Hoisting.h"
+#include "mlir/Dialect/Linalg/Transforms/Transforms.h"
+#include "mlir/Dialect/Linalg/Utils/Utils.h"
+#include "mlir/Dialect/MemRef/IR/MemRef.h"
+#include "mlir/Dialect/MemRef/Transforms/Passes.h"
+#include "mlir/Dialect/SCF/Utils/Utils.h"
+#include "mlir/Dialect/Vector/Transforms/LoweringPatterns.h"
+#include "mlir/Dialect/Vector/Transforms/Passes.h"
+#include "mlir/Pass/Pass.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+#define DEBUG_TYPE "iree-llvmcpu-vectorization"
+
+namespace mlir {
+namespace iree_compiler {
+namespace {
+/// Returns the op that contains lowering config. Checks whether the provided op
+/// contains the lowering config and returns it. Otherwise, tries to find the
+/// lowering config across the function. If there are multiple ops with the same
+/// lowering configs, returns the first one found. Returns failure if there are
+/// multiple op with different lowering config.
+/// TODO(hanchung): This is copied from LinalgTensorCodegenDriver.cpp. We should
+/// refactor it to Utils.h.
+static FailureOr<Operation *> getRootOp(Operation *op) {
+  // Check for self first.
+  if (iree_compiler::getLoweringConfig(op)) {
+    return op;
+  }
+
+  // Get the function op.
+  auto funcOp = dyn_cast<func::FuncOp>(op);
+  if (!funcOp) {
+    funcOp = op->getParentOfType<func::FuncOp>();
+  }
+
+  assert(funcOp && "Missing funcOp");
+
+  Operation *rootOp = nullptr;
+  mlir::iree_compiler::IREE::Codegen::LoweringConfigAttr rootLoweringConfig;
+  auto result = funcOp.walk([&](Operation *op) -> WalkResult {
+    auto loweringConfig = iree_compiler::getLoweringConfig(op);
+    if (!loweringConfig) {
+      return WalkResult::advance();
+    }
+    if (rootLoweringConfig) {
+      if (rootLoweringConfig != loweringConfig) {
+        return WalkResult::interrupt();
+      }
+    } else {
+      rootOp = op;
+      rootLoweringConfig = loweringConfig;
+    }
+    return WalkResult::advance();
+  });
+
+  if (!rootOp || result.wasInterrupted()) {
+    return failure();
+  }
+  return rootOp;
+}
+
+/// Computes the canonical shape used to vectorize this dispatch. Retrieves
+/// the vectorization tile sizes (parallel and reduction levels) out of the
+/// lowering config and adjusts them to the format expected by the Linalg
+/// vectorizer.
+static SmallVector<int64_t> getCanonicalVectorShape(func::FuncOp funcOp) {
+  FailureOr<Operation *> rootOp = getRootOp(funcOp);
+  if (failed(rootOp)) {
+    return {};
+  }
+
+  unsigned numTileLevels =
+      mlir::iree_compiler::getNumTileLevels(rootOp.value());
+  if (numTileLevels < 3) {
+    return {};
+  }
+
+  // Retrieve the tile sizes from the last two tiling levels (parallel and
+  // reduction) used for vectorization.
+  SmallVector<int64_t> canonicalVectorShape =
+      mlir::iree_compiler::getTileSizes(rootOp.value(), numTileLevels - 2);
+  SmallVector<int64_t> reductionTileSizes =
+      mlir::iree_compiler::getTileSizes(rootOp.value(), numTileLevels - 1);
+
+  if (!reductionTileSizes.empty()) {
+    assert(canonicalVectorShape.size() == reductionTileSizes.size() &&
+           "Unexpected tile sizes");
+
+    // Combine the reduction tile sizes with the parallel tile sizes already in
+    // the canonical vector shape.
+    for (int i = 0, end = canonicalVectorShape.size(); i < end; ++i) {
+      if (reductionTileSizes[i] > 0)
+        canonicalVectorShape[i] = reductionTileSizes[i];
+    }
+  }
+
+  // Replace zeros in canonical vector shape to turn it into a valid shape.
+  std::replace(canonicalVectorShape.begin(), canonicalVectorShape.end(), 0, 1);
+  return canonicalVectorShape;
+}
+
+// Give the canonical vector shape of a dispatch, returns the vector sizes for a
+// particular linalg op within that dispatch.
+static SmallVector<int64_t> getVectorSizes(
+    linalg::LinalgOp linalgOp, ArrayRef<int64_t> canonicalVectorShape) {
+  FailureOr<Operation *> rootOp = getRootOp(linalgOp);
+  if (failed(rootOp)) {
+    return {};
+  }
+
+  // TODO: Infer the tiles sizes for an op that is not the root op.
+  if (*rootOp != linalgOp.getOperation()) {
+    return {};
+  }
+
+  if (canonicalVectorShape.empty()) {
+    return {};
+  }
+
+  assert(canonicalVectorShape.size() >= linalgOp.getNumLoops() &&
+         "Unexpected canonical vector shape or number of loops");
+
+  // Return the valid canonical vector shape subset based on the number of loops
+  // of the linalg op.
+  SmallVector<int64_t> vecSize(
+      canonicalVectorShape.take_front(linalgOp.getNumLoops()));
+  for (auto [idx, val] : llvm::enumerate(linalgOp.getStaticLoopRanges())) {
+    if (ShapedType::isDynamic(val)) continue;
+    vecSize[idx] = std::max(vecSize[idx], val);
+  }
+
+  return vecSize;
+}
+
+class LLVMCPUVectorizationPass
+    : public LLVMCPUVectorizationBase<LLVMCPUVectorizationPass> {
+ public:
+  using LLVMCPUVectorizationBase::LLVMCPUVectorizationBase;
+  LLVMCPUVectorizationPass(const LLVMCPUVectorizationPassOptions &options) {
+    this->enableVectorMasking.setValue(options.enableVectorMasking);
+    this->vectorizePadding.setValue(options.vectorizePadding);
+    this->vectorizeGatherAccesses.setValue(options.vectorizeGatherAccesses);
+  }
+
+  void getDependentDialects(DialectRegistry &registry) const override {
+    registry.insert<tensor::TensorDialect, linalg::LinalgDialect,
+                    vector::VectorDialect>();
+  }
+  void runOnOperation() override;
+};
+
+void LLVMCPUVectorizationPass::runOnOperation() {
+  MLIRContext *context = &getContext();
+  auto funcOp = getOperation();
+  SmallVector<int64_t> canonicalVectorShape;
+  if (enableVectorMasking) {
+    canonicalVectorShape = getCanonicalVectorShape(funcOp);
+  }
+
+  IRRewriter rewriter(context);
+  SmallVector<linalg::LinalgOp> candidates;
+  funcOp.walk(
+      [&](linalg::LinalgOp linalgOp) { candidates.push_back(linalgOp); });
+  for (auto linalgOp : candidates) {
+    SmallVector<int64_t> vectorSizes;
+    if (enableVectorMasking) {
+      vectorSizes.append(getVectorSizes(linalgOp, canonicalVectorShape));
+    }
+    (void)linalg::vectorize(rewriter, linalgOp, vectorSizes,
+                            vectorizeGatherAccesses);
+  };
+
+  // TODO: Move this down the pipeline once we have the ODM-based masking
+  // representation.
+  RewritePatternSet vectorizationPatterns(funcOp.getContext());
+  vector::populateVectorMaskLoweringPatternsForSideEffectingOps(
+      vectorizationPatterns);
+  vector::populateVectorTransferPermutationMapLoweringPatterns(
+      vectorizationPatterns);
+  vector::populateVectorReductionToContractPatterns(vectorizationPatterns);
+  vectorizationPatterns.add<linalg::LinalgCopyVTRForwardingPattern,
+                            linalg::LinalgCopyVTWForwardingPattern>(
+      funcOp.getContext(), /*benefit=*/2);
+  vector::TransferReadOp::getCanonicalizationPatterns(vectorizationPatterns,
+                                                      funcOp.getContext());
+  vector::TransferWriteOp::getCanonicalizationPatterns(vectorizationPatterns,
+                                                       funcOp.getContext());
+  (void)applyPatternsAndFoldGreedily(funcOp, std::move(vectorizationPatterns));
+
+  // Apply the pad tensor op vectorization separately to avoid running the
+  // GenericPadOpVectorizationPattern too early.
+  // TODO: Improve once we have better infrastructure to control pattern
+  // application.
+  if (vectorizePadding) {
+    RewritePatternSet patterns(funcOp.getContext());
+    linalg::populatePadOpVectorizationPatterns(patterns);
+    (void)applyPatternsAndFoldGreedily(funcOp, std::move(patterns));
+  }
+
+  // Gathers all innermost loops through a post order pruned walk.
+  funcOp.walk([](Operation *op) {
+    if (auto forOp = dyn_cast<AffineForOp>(op))
+      (void)promoteIfSingleIteration(forOp);
+    else if (auto forOp = dyn_cast<scf::ForOp>(op))
+      (void)promoteIfSingleIteration(forOp);
+  });
+  linalg::hoistRedundantVectorTransfers(funcOp);
+  linalg::hoistRedundantVectorTransfersOnTensor(funcOp);
+}
+}  // namespace
+
+std::unique_ptr<OperationPass<func::FuncOp>> createLLVMCPUVectorizationPass() {
+  return std::make_unique<LLVMCPUVectorizationPass>();
+}
+std::unique_ptr<OperationPass<func::FuncOp>> createLLVMCPUVectorizationPass(
+    const LLVMCPUVectorizationPassOptions &options) {
+  return std::make_unique<LLVMCPUVectorizationPass>(options);
+}
+}  // namespace iree_compiler
+}  // namespace mlir
diff --git a/compiler/src/iree/compiler/Codegen/LLVMCPU/Passes.cpp b/compiler/src/iree/compiler/Codegen/LLVMCPU/Passes.cpp
index f7b0e01..021b61f 100644
--- a/compiler/src/iree/compiler/Codegen/LLVMCPU/Passes.cpp
+++ b/compiler/src/iree/compiler/Codegen/LLVMCPU/Passes.cpp
@@ -339,12 +339,11 @@
       static_cast<int64_t>(StrategyTilingLevel::ParallelTiles)));
   nestedModulePM.addNestedPass<func::FuncOp>(createLLVMCPUPeelPass());
   {
-    LinalgSingleTilingExpertPassOptions options;
-    options.vectorize = true;
+    LLVMCPUVectorizationPassOptions options;
     options.enableVectorMasking = enableVectorMasking;
     options.vectorizeGatherAccesses = true;
     nestedModulePM.addNestedPass<func::FuncOp>(
-        createLinalgSingleTilingExpertPass(options));
+        createLLVMCPUVectorizationPass(options));
     nestedModulePM.addNestedPass<func::FuncOp>(createCanonicalizerPass());
     nestedModulePM.addNestedPass<func::FuncOp>(createCSEPass());
   }
@@ -378,13 +377,12 @@
       createLLVMCPUTensorPadPass(LLVMCPUTensorPadOption::ReductionDims));
 
   {
-    LinalgSingleTilingExpertPassOptions options;
-    options.vectorize = true;
+    LLVMCPUVectorizationPassOptions options;
     options.enableVectorMasking = enableVectorMasking;
     options.vectorizePadding = true;
     options.vectorizeGatherAccesses = true;
     nestedModulePM.addNestedPass<func::FuncOp>(
-        createLinalgSingleTilingExpertPass(options));
+        createLLVMCPUVectorizationPass(options));
     nestedModulePM.addNestedPass<func::FuncOp>(createCanonicalizerPass());
     nestedModulePM.addNestedPass<func::FuncOp>(createCSEPass());
   }
@@ -478,17 +476,13 @@
         createDecomposePackUnPackOpsPass());
     nestedModulePM.addNestedPass<func::FuncOp>(createCanonicalizerPass());
     nestedModulePM.addNestedPass<func::FuncOp>(createCSEPass());
-    LinalgSingleTilingExpertPassOptions options;
-    options.vectorize = true;
+    LLVMCPUVectorizationPassOptions options;
     options.enableVectorMasking = enableVectorMasking;
     options.vectorizeGatherAccesses = true;
     nestedModulePM.addNestedPass<func::FuncOp>(
-        createLinalgSingleTilingExpertPass(options));
+        createLLVMCPUVectorizationPass(options));
     nestedModulePM.addNestedPass<func::FuncOp>(createCanonicalizerPass());
     nestedModulePM.addNestedPass<func::FuncOp>(createCSEPass());
-    // TODO(hanchung): Merge two vectorization passes into a pass. All the ops
-    // should be vectorized altogether. Otherwise, there would be tensor.empty
-    // ops which becomes a stack allocation in bufferization.
   }
 
   addBufferizePasses(nestedModulePM);
@@ -538,18 +532,13 @@
     nestedModulePM.addNestedPass<func::FuncOp>(createVectorizePadPass());
   }
 
-  // Add the sandbox single tiling expert to vectorize.
-  // We can't do the vectorization in the tiling expert above due to an issue in
-  // codegen strategy pipeline. Since we are moving to the transform dialect, we
-  // choose to have a workaround here by splitting them into two stages.
   {
-    LinalgSingleTilingExpertPassOptions options;
-    options.vectorize = true;
+    LLVMCPUVectorizationPassOptions options;
     options.enableVectorMasking = enableVectorMasking;
     options.vectorizePadding = true;
     options.vectorizeGatherAccesses = true;
     nestedModulePM.addNestedPass<func::FuncOp>(
-        createLinalgSingleTilingExpertPass(options));
+        createLLVMCPUVectorizationPass(options));
     nestedModulePM.addNestedPass<func::FuncOp>(createCanonicalizerPass());
     nestedModulePM.addNestedPass<func::FuncOp>(createCSEPass());
   }
@@ -582,12 +571,9 @@
   nestedModulePM.addNestedPass<func::FuncOp>(createLLVMCPUTilePass(
       static_cast<int64_t>(StrategyTilingLevel::ReductionTiles)));
 
-  {
-    LinalgSingleTilingExpertPassOptions options;
-    options.vectorize = true;
-    nestedModulePM.addNestedPass<func::FuncOp>(
-        createLinalgSingleTilingExpertPass(options));
-  }
+  nestedModulePM.addNestedPass<func::FuncOp>(createLLVMCPUVectorizationPass());
+  nestedModulePM.addNestedPass<func::FuncOp>(createCanonicalizerPass());
+  nestedModulePM.addNestedPass<func::FuncOp>(createCSEPass());
 
   addBufferizePasses(nestedModulePM);
 
diff --git a/compiler/src/iree/compiler/Codegen/Passes.h b/compiler/src/iree/compiler/Codegen/Passes.h
index 5011d07..489d956 100644
--- a/compiler/src/iree/compiler/Codegen/Passes.h
+++ b/compiler/src/iree/compiler/Codegen/Passes.h
@@ -333,6 +333,15 @@
 std::unique_ptr<OperationPass<func::FuncOp>> createLLVMCPUSplitReductionPass(
     bool enableReassociateFpReductions = false);
 
+struct LLVMCPUVectorizationPassOptions {
+  bool enableVectorMasking = false;
+  bool vectorizePadding = false;
+  bool vectorizeGatherAccesses = false;
+};
+std::unique_ptr<OperationPass<func::FuncOp>> createLLVMCPUVectorizationPass();
+std::unique_ptr<OperationPass<func::FuncOp>> createLLVMCPUVectorizationPass(
+    const LLVMCPUVectorizationPassOptions &options);
+
 /// Performs the final conversion to LLVM dialect.
 std::unique_ptr<OperationPass<ModuleOp>> createConvertToLLVMPass(
     bool reassociateFpReordering = false);
diff --git a/compiler/src/iree/compiler/Codegen/Passes.td b/compiler/src/iree/compiler/Codegen/Passes.td
index 573df9e..84e553a 100644
--- a/compiler/src/iree/compiler/Codegen/Passes.td
+++ b/compiler/src/iree/compiler/Codegen/Passes.td
@@ -526,6 +526,22 @@
   ];
 }
 
+def LLVMCPUVectorization :
+    Pass<"iree-llvmcpu-vectorization", "func::FuncOp"> {
+  let summary = "Pass to perform vectorization on tensor/linalg ops.";
+  let constructor = "mlir::createLinalgVectorizationExpertPass()";
+  let options = [
+    Option<"enableVectorMasking", "enable-vector-masking", "bool",/*default=*/"false",
+      "Enable vector masking during vectorization.">,
+    Option<"vectorizePadding", "vectorize-padding", "bool", /*default=*/"false",
+      "Rewrite all tensor.pad ops in the function to vector form.">,
+    Option<"vectorizeGatherAccesses", "vectorize-gather-accesses", "bool", /*default=*/"false",
+      "Enable vectorizaiton of operations that may generate vector.gather operations.">,
+  ];
+  let constructor =
+      "mlir::iree_compiler::createLLVMCPUVectorizationPass()";
+}
+
 def ConvertToLLVM :
     Pass<"iree-convert-to-llvm", "ModuleOp"> {
   let summary =
diff --git a/compiler/src/iree/compiler/Codegen/Sandbox/LinalgTensorCodegenDriver.cpp b/compiler/src/iree/compiler/Codegen/Sandbox/LinalgTensorCodegenDriver.cpp
index a86526b..10dbcb9 100644
--- a/compiler/src/iree/compiler/Codegen/Sandbox/LinalgTensorCodegenDriver.cpp
+++ b/compiler/src/iree/compiler/Codegen/Sandbox/LinalgTensorCodegenDriver.cpp
@@ -31,194 +31,15 @@
 using mlir::iree_compiler::IREE::LinalgExt::CodegenStrategy;
 using mlir::iree_compiler::IREE::LinalgExt::LinalgTransformationFilter;
 using mlir::iree_compiler::IREE::LinalgExt::LinalgTransforms;
-using mlir::iree_compiler::IREE::LinalgExt::LinalgVectorizationOptions;
 using mlir::iree_compiler::IREE::LinalgExt::LinalgVectorLoweringOptions;
 
 #define DEBUG_TYPE "iree-linalg-tensor-codegen-driver"
 
 //===----------------------------------------------------------------------===//
-// IREE specific functions
-//===----------------------------------------------------------------------===//
-
-/// Returns the op that contains lowering config. Checks whether the provided op
-/// contains the lowering config and returns it. Otherwise, tries to find the
-/// lowering config across the function. If there are multiple ops with the same
-/// lowering configs, returns the first one found. Returns failure if there are
-/// multiple op with different lowering config.
-static FailureOr<Operation *> getRootOp(Operation *op) {
-  // Check for self first.
-  if (iree_compiler::getLoweringConfig(op)) {
-    return op;
-  }
-
-  // Get the function op.
-  auto funcOp = dyn_cast<func::FuncOp>(op);
-  if (!funcOp) {
-    funcOp = op->getParentOfType<func::FuncOp>();
-  }
-
-  assert(funcOp && "Missing funcOp");
-
-  Operation *rootOp = nullptr;
-  mlir::iree_compiler::IREE::Codegen::LoweringConfigAttr rootLoweringConfig;
-  auto result = funcOp.walk([&](Operation *op) -> WalkResult {
-    auto loweringConfig = iree_compiler::getLoweringConfig(op);
-    if (!loweringConfig) {
-      return WalkResult::advance();
-    }
-    if (rootLoweringConfig) {
-      if (rootLoweringConfig != loweringConfig) {
-        return WalkResult::interrupt();
-      }
-    } else {
-      rootOp = op;
-      rootLoweringConfig = loweringConfig;
-    }
-    return WalkResult::advance();
-  });
-
-  if (!rootOp || result.wasInterrupted()) {
-    return failure();
-  }
-  return rootOp;
-}
-
-/// Computes the canonical shape used to vectorize this dispatch. Retrieves
-/// the vectorization tile sizes (parallel and reduction levels) out of the
-/// lowering config and adjusts them to the format expected by the Linalg
-/// vectorizer.
-static SmallVector<int64_t> getCanonicalVectorShape(func::FuncOp funcOp) {
-  FailureOr<Operation *> rootOp = getRootOp(funcOp);
-  if (failed(rootOp)) {
-    return {};
-  }
-
-  unsigned numTileLevels =
-      mlir::iree_compiler::getNumTileLevels(rootOp.value());
-  if (numTileLevels < 3) {
-    return {};
-  }
-
-  // Retrieve the tile sizes from the last two tiling levels (parallel and
-  // reduction) used for vectorization.
-  SmallVector<int64_t> canonicalVectorShape =
-      mlir::iree_compiler::getTileSizes(rootOp.value(), numTileLevels - 2);
-  SmallVector<int64_t> reductionTileSizes =
-      mlir::iree_compiler::getTileSizes(rootOp.value(), numTileLevels - 1);
-
-  if (!reductionTileSizes.empty()) {
-    assert(canonicalVectorShape.size() == reductionTileSizes.size() &&
-           "Unexpected tile sizes");
-
-    // Combine the reduction tile sizes with the parallel tile sizes already in
-    // the canonical vector shape.
-    for (int i = 0, end = canonicalVectorShape.size(); i < end; ++i) {
-      if (reductionTileSizes[i] > 0)
-        canonicalVectorShape[i] = reductionTileSizes[i];
-    }
-  }
-
-  // Replace zeros in canonical vector shape to turn it into a valid shape.
-  std::replace(canonicalVectorShape.begin(), canonicalVectorShape.end(), 0, 1);
-  return canonicalVectorShape;
-}
-
-// Give the canonical vector shape of a dispatch, returns the vector sizes for a
-// particular linalg op within that dispatch.
-static SmallVector<int64_t> getVectorSizes(
-    linalg::LinalgOp linalgOp, ArrayRef<int64_t> canonicalVectorShape) {
-  FailureOr<Operation *> rootOp = getRootOp(linalgOp);
-  if (failed(rootOp)) {
-    return {};
-  }
-
-  // TODO: Infer the tiles sizes for an op that is not the root op.
-  if (*rootOp != linalgOp.getOperation()) {
-    return {};
-  }
-
-  if (canonicalVectorShape.empty()) {
-    return {};
-  }
-
-  assert(canonicalVectorShape.size() >= linalgOp.getNumLoops() &&
-         "Unexpected canonical vector shape or number of loops");
-
-  // Return the valid canonical vector shape subset based on the number of loops
-  // of the linalg op.
-  SmallVector<int64_t> vecSize(
-      canonicalVectorShape.take_front(linalgOp.getNumLoops()));
-  for (auto [idx, val] : llvm::enumerate(linalgOp.getStaticLoopRanges())) {
-    if (ShapedType::isDynamic(val)) continue;
-    vecSize[idx] = std::max(vecSize[idx], val);
-  }
-
-  return vecSize;
-}
-
-/// Default method to get tile sizes for tile-and-fuse in IREE. These could be
-/// ovveridden by the command line options if specified.
-static LogicalResult getTileAndFuseOptionsFromConfig(
-    func::FuncOp funcOp, int64_t tilingLevel,
-    SmallVector<int64_t> &tileAndFuseSizes, SmallVector<int64_t> &tileOnlySizes,
-    SmallVector<int64_t> &tileInterchange) {
-  if (tilingLevel == -1) {
-    return success();
-  }
-
-  FailureOr<Operation *> rootOp = getRootOp(funcOp);
-  if (failed(rootOp) || !rootOp.value()) return failure();
-  auto tilingOp = cast<TilingInterface>(rootOp.value());
-
-  iree_compiler::IREE::Codegen::LoweringConfigAttr loweringConfig =
-      iree_compiler::getLoweringConfig(tilingOp);
-  SmallVector<int64_t> tileSizes = loweringConfig.getTileSizeVals(tilingLevel);
-
-  auto iteratorTypes = tilingOp.getLoopIteratorTypes();
-  tileAndFuseSizes = SmallVector<int64_t>(iteratorTypes.size(), /*default=*/0);
-  tileOnlySizes = SmallVector<int64_t>(iteratorTypes.size(), /*default=*/0);
-  // Splits the tileSizes into two sizes vectors. We want to tile-and-fuse on
-  // parallel dims and tile-only on reduction dims.
-  for (size_t i = 0; i < tileSizes.size() && i < iteratorTypes.size(); ++i) {
-    if (iteratorTypes[i] == utils::IteratorType::parallel) {
-      tileAndFuseSizes[i] = tileSizes[i];
-    } else {
-      tileOnlySizes[i] = tileSizes[i];
-    }
-  }
-
-  tileInterchange = loweringConfig.getTileInterchangeVals(tilingLevel);
-
-  return success();
-}
-
-//===----------------------------------------------------------------------===//
 // From Sandbox
 //===----------------------------------------------------------------------===//
 
 namespace {
-
-struct LinalgSingleTilingExpertPass
-    : public LinalgSingleTilingExpertBase<LinalgSingleTilingExpertPass> {
-  LinalgSingleTilingExpertPass() = default;
-  LinalgSingleTilingExpertPass(
-      const LinalgSingleTilingExpertPassOptions &options) {
-    this->anchorFuncOpName = options.anchorFuncOpName;
-    this->anchorOpName = options.anchorOpName;
-    this->generalize = options.generalize;
-    this->iteratorInterchange = options.iteratorInterchange;
-    this->vectorize = options.vectorize;
-    this->enableVectorMasking = options.enableVectorMasking;
-    this->vectorizePadding = options.vectorizePadding;
-    this->vectorizeGatherAccesses = options.vectorizeGatherAccesses;
-    this->tilingLevel = options.tilingLevel;
-  }
-  LinalgSingleTilingExpertPass(const LinalgSingleTilingExpertPass &pass) {}
-
-  /// Function pass entry point.
-  void runOnOperation() override;
-};
-
 struct LinalgVectorLoweringPass
     : public LinalgVectorLoweringBase<LinalgVectorLoweringPass> {
   LinalgVectorLoweringPass(int64_t vectorLoweringStage = 0) {
@@ -240,34 +61,6 @@
 };
 }  // namespace
 
-void LinalgSingleTilingExpertPass::runOnOperation() {
-  func::FuncOp funcOp = getOperation();
-
-  LinalgVectorizationOptions vectorizationOptions;
-  vectorizationOptions.setVectorizePadding(vectorizePadding);
-  vectorizationOptions.setVectorizeGatherAccesses(vectorizeGatherAccesses);
-  vectorizationOptions.setEnableVectorMasking(enableVectorMasking);
-  if (enableVectorMasking) {
-    vectorizationOptions.setCanonicalVectorSizes(
-        getCanonicalVectorShape(funcOp));
-    vectorizationOptions.setVectorSizeComputationFunction(getVectorSizes);
-  }
-
-  CodegenStrategy strategy;
-  StringRef genericOpName = linalg::GenericOp::getOperationName();
-  strategy.vectorizeIf(vectorize, generalize ? genericOpName : anchorOpName,
-                       vectorizationOptions);
-
-  // Created a nested OpPassManager and run.
-  OpPassManager dynamicPM(func::FuncOp::getOperationName());
-  strategy.configurePassPipeline(dynamicPM, funcOp.getContext());
-  dynamicPM.addPass(
-      iree_compiler::IREE::LinalgExt::createLinalgStrategyEnablePass());
-  if (failed(runPipeline(dynamicPM, funcOp))) {
-    return signalPassFailure();
-  }
-}
-
 void LinalgVectorLoweringPass::runOnOperation() {
   LLVM_DEBUG(llvm::dbgs() << "\n ---- Stage : " << vectorLoweringStage;);
   vector::VectorTransposeLowering vectorTransposeLowering =
@@ -352,16 +145,6 @@
 }
 
 std::unique_ptr<OperationPass<func::FuncOp>>
-mlir::createLinalgSingleTilingExpertPass() {
-  return std::make_unique<LinalgSingleTilingExpertPass>();
-}
-std::unique_ptr<OperationPass<func::FuncOp>>
-mlir::createLinalgSingleTilingExpertPass(
-    const LinalgSingleTilingExpertPassOptions &passOptions) {
-  return std::make_unique<LinalgSingleTilingExpertPass>(passOptions);
-}
-
-std::unique_ptr<OperationPass<func::FuncOp>>
 mlir::createLinalgVectorLoweringPass(int64_t vectorLoweringStage) {
   return std::make_unique<LinalgVectorLoweringPass>(vectorLoweringStage);
 }
diff --git a/compiler/src/iree/compiler/Codegen/Sandbox/Passes.h b/compiler/src/iree/compiler/Codegen/Sandbox/Passes.h
index 6cd9d85..f309365 100644
--- a/compiler/src/iree/compiler/Codegen/Sandbox/Passes.h
+++ b/compiler/src/iree/compiler/Codegen/Sandbox/Passes.h
@@ -12,25 +12,6 @@
 
 namespace mlir {
 
-/// Struct to control pass options for `LinalgSingleTilingExpert` pass.
-struct LinalgSingleTilingExpertPassOptions {
-  std::string anchorFuncOpName = "";
-  std::string anchorOpName = "";
-  bool generalize = false;
-  SmallVector<int64_t> iteratorInterchange = {};
-  bool vectorize = false;
-  bool enableVectorMasking = false;
-  bool vectorizePadding = false;
-  bool vectorizeGatherAccesses = false;
-  int64_t tilingLevel = -1;
-};
-
-/// Creates a pass to drive one level tiling + vectorization of `LinalgOp`s.
-std::unique_ptr<OperationPass<func::FuncOp>>
-createLinalgSingleTilingExpertPass();
-std::unique_ptr<OperationPass<func::FuncOp>> createLinalgSingleTilingExpertPass(
-    const LinalgSingleTilingExpertPassOptions &passOptions);
-
 /// Struct to control pass options for `LinalgVectorLoweringPass` pass.
 struct LinalgVectorLoweringPassOptions {
   int vectorLoweringStage = 0;
@@ -65,12 +46,6 @@
 //===----------------------------------------------------------------------===//
 
 namespace iree_compiler {
-/// Creates a pass to drive one level tiling + vectorization of `LinalgOp`s with
-/// additional parameters that allow controlling the value of the pass options
-/// when building the pipeline.
-std::unique_ptr<OperationPass<func::FuncOp>> createLinalgSingleTilingExpertPass(
-    int64_t tilingLevel, bool vectorize);
-
 //===----------------------------------------------------------------------===//
 // Registration
 //===----------------------------------------------------------------------===//
diff --git a/compiler/src/iree/compiler/Codegen/Sandbox/Passes.td b/compiler/src/iree/compiler/Codegen/Sandbox/Passes.td
index 6601c58..54e618f 100644
--- a/compiler/src/iree/compiler/Codegen/Sandbox/Passes.td
+++ b/compiler/src/iree/compiler/Codegen/Sandbox/Passes.td
@@ -9,46 +9,6 @@
 
 include "mlir/Pass/PassBase.td"
 
-def LinalgSingleTilingExpert
-    : Pass<"linalg-single-tiling-expert-driver", "func::FuncOp"> {
-  let summary = "Pass to drive transformations on Linalg on tensors.";
-  let constructor = "mlir::createLinalgSingleTilingExpertPass()";
-  let options = [
-    // Func / op targeting options.
-    Option<"anchorFuncOpName", "anchor-func", "std::string", /*default=*/"",
-      "Which func op is the anchor to latch on.">,
-    Option<"anchorOpName", "anchor-op", "std::string", /*default=*/"",
-      "Which linalg op within the func is the anchor to latch on.">,
-
-    // Generalization options.
-    Option<"generalize", "generalize", "bool", /*default=*/"false",
-      "Convert named operations to their generic form.">,
-    ListOption<"iteratorInterchange", "iterator-interchange", "int64_t",
-               "Interator interchange.",
-               "llvm::cl::ZeroOrMore">,
-
-    // Vectorization options.
-    Option<"vectorize", "vectorize", "bool", /*default=*/"false",
-      "Rewrite the linalg op as a vector operation.">,
-    Option<"enableVectorMasking", "enableVectorMasking", "bool", /*default=*/"false",
-      "Enable vector masking during vectorization.">,
-    Option<"vectorizePadding", "vectorize-padding", "bool", /*default=*/"false",
-      "Rewrite all tensor.pad ops in the function to vector form.">,
-    Option<"vectorizeGatherAccesses", "vectorize-gather-accesses", "bool", /*default=*/"false",
-      "Enable vectorizaiton of operations that may generate vector.gather operations.">,
-
-    // IREE specific options
-    Option<"tilingLevel", "tiling-level", "int64_t", /*default=*/"-1",
-      "Use default tiling level used to retrieve the configuration from lowering_config">
-  ];
-  let dependentDialects = [
-    "::mlir::arith::ArithDialect", "::mlir::AffineDialect",
-    "::mlir::linalg::LinalgDialect", "::mlir::scf::SCFDialect",
-    "::mlir::cf::ControlFlowDialect", "::mlir::tensor::TensorDialect",
-    "::mlir::vector::VectorDialect"
-  ];
-}
-
 def LinalgVectorLowering : Pass<"linalg-vector-lowering", "func::FuncOp"> {
   let summary = "Run transformations that lower high-level vectors.";
   let constructor = "mlir::createLinalgVectorLoweringPass()";
diff --git a/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.h b/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.h
index 1067e5b..2f41d05 100644
--- a/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.h
+++ b/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.h
@@ -210,16 +210,8 @@
   }
 };
 
-/// Create a LinalgStrategyDecomposePass.
-// TODO: if/when we need finer control add an `opName` parameter.
-std::unique_ptr<OperationPass<func::FuncOp>> createLinalgStrategyDecomposePass(
-    const LinalgExt::LinalgTransformationFilter &filter =
-        LinalgExt::LinalgTransformationFilter());
-
-/// Create a LinalgStrategyVectorizePass.
 using VectorSizeComputationFunction =
     std::function<SmallVector<int64_t>(linalg::LinalgOp, ArrayRef<int64_t>)>;
-
 struct LinalgVectorizationOptions {
   /// Enable vector masking during vectorization.
   bool enableVectorMasking = false;
@@ -268,12 +260,6 @@
   }
 };
 
-std::unique_ptr<OperationPass<func::FuncOp>> createLinalgStrategyVectorizePass(
-    StringRef opName = "",
-    const LinalgVectorizationOptions &options = LinalgVectorizationOptions(),
-    const LinalgExt::LinalgTransformationFilter &filter =
-        LinalgExt::LinalgTransformationFilter());
-
 /// Create a LinalgStrategyEnablePass.
 std::unique_ptr<OperationPass<func::FuncOp>> createLinalgStrategyEnablePass(
     LinalgEnablingOptions opt = LinalgEnablingOptions(),
diff --git a/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.td b/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.td
index 71fd062..6f2fada 100644
--- a/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.td
+++ b/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Passes/Passes.td
@@ -100,21 +100,6 @@
 // TODO: Deprecate all this.
 //===---------------------------------------------------------------------====//
 
-def LinalgStrategyVectorizePass
-    : Pass<"iree-linalg-strategy-vectorize-pass", "func::FuncOp"> {
-  let summary = "Configurable pass to apply pattern-based linalg vectorization.";
-  let constructor = "createLinalgStrategyVectorizePass()";
-  let dependentDialects = ["linalg::LinalgDialect", "vector::VectorDialect"];
-  let options = [
-    Option<"anchorFuncName", "anchor-func", "std::string", /*default=*/"",
-      "Which func op is the anchor to latch on.">,
-    Option<"anchorOpName", "anchor-op", "std::string", /*default=*/"",
-      "Which linalg op within the func is the anchor to latch on.">,
-    Option<"vectorizePadding", "vectorize-padding", "bool", "false",
-      "Enable vectorization of padding ops.">,
-  ];
-}
-
 def LinalgStrategyEnablePass
     : Pass<"iree-linalg-strategy-enable-pass", "func::FuncOp"> {
   let summary = "Configurable pass to enable the application of other "
diff --git a/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Transforms/CodegenStrategy.h b/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Transforms/CodegenStrategy.h
index d19b3d4..35a8ac1 100644
--- a/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Transforms/CodegenStrategy.h
+++ b/llvm-external-projects/iree-dialects/include/iree-dialects/Dialect/LinalgExt/Transforms/CodegenStrategy.h
@@ -37,28 +37,6 @@
   LinalgExt::LinalgTransformationFilter::FilterFunction filter = nullptr;
 };
 
-/// Represent one application of createLinalgStrategyVectorizePass.
-struct Vectorize : public Transformation {
-  explicit Vectorize(
-      LinalgVectorizationOptions opts = LinalgVectorizationOptions(),
-      LinalgExt::LinalgTransformationFilter::FilterFunction f = nullptr)
-      : Transformation(std::move(f)), options(std::move(opts)) {}
-
-  Vectorize(StringRef name, LinalgVectorizationOptions opts,
-            LinalgExt::LinalgTransformationFilter::FilterFunction f = nullptr)
-      : Transformation(std::move(f)), opName(name), options(std::move(opts)) {}
-
-  void
-  addToPassPipeline(OpPassManager &pm,
-                    LinalgExt::LinalgTransformationFilter m) const override {
-    pm.addPass(createLinalgStrategyVectorizePass(opName, options, m));
-  }
-
-private:
-  std::string opName;
-  LinalgVectorizationOptions options;
-};
-
 /// Represent one application of createLinalgStrategyLowerVectorsPass.
 struct VectorLowering : public Transformation {
   explicit VectorLowering(
@@ -78,24 +56,6 @@
 
 /// Codegen strategy controls how a Linalg op is progressively lowered.
 struct CodegenStrategy {
-  /// Append a pattern to rewrite `LinalgOpType` as a vector operation.
-  CodegenStrategy &vectorize(
-      StringRef opName,
-      const LinalgVectorizationOptions &options = LinalgVectorizationOptions(),
-      const LinalgExt::LinalgTransformationFilter::FilterFunction &f =
-          nullptr) {
-    transformationSequence.emplace_back(
-        std::make_unique<Vectorize>(opName, options, f));
-    return *this;
-  }
-  /// Conditionally append a pattern to rewrite `LinalgOpType` as a vector
-  /// operation.
-  CodegenStrategy &vectorizeIf(
-      bool b, StringRef opName,
-      LinalgVectorizationOptions options = LinalgVectorizationOptions(),
-      LinalgExt::LinalgTransformationFilter::FilterFunction f = nullptr) {
-    return b ? vectorize(opName, std::move(options), std::move(f)) : *this;
-  }
   /// Append a pattern to lower all vector operations.
   CodegenStrategy &vectorLowering(LinalgVectorLoweringOptions options) {
     transformationSequence.emplace_back(
diff --git a/llvm-external-projects/iree-dialects/lib/Dialect/LinalgExt/Transforms/Transforms.cpp b/llvm-external-projects/iree-dialects/lib/Dialect/LinalgExt/Transforms/Transforms.cpp
index ea7d0d2..c8b0510 100644
--- a/llvm-external-projects/iree-dialects/lib/Dialect/LinalgExt/Transforms/Transforms.cpp
+++ b/llvm-external-projects/iree-dialects/lib/Dialect/LinalgExt/Transforms/Transforms.cpp
@@ -126,65 +126,6 @@
 }
 
 namespace {
-/// Configurable pass to apply pattern-based linalg vectorization.
-struct LinalgStrategyVectorizePass
-    : public LinalgStrategyVectorizePassBase<LinalgStrategyVectorizePass> {
-
-  LinalgStrategyVectorizePass() = default;
-
-  LinalgStrategyVectorizePass(StringRef opName, LinalgVectorizationOptions opts,
-                              LinalgExt::LinalgTransformationFilter filt)
-      : options(std::move(opts)), filter(std::move(filt)) {
-    this->vectorizePadding = opts.vectorizePadding;
-  };
-
-  void runOnOperation() override {
-    auto funcOp = getOperation();
-    if (!anchorFuncName.empty() && funcOp.getName() != anchorFuncName)
-      return;
-
-    RewritePatternSet vectorizationPatterns(funcOp.getContext());
-    if (!anchorOpName.empty()) {
-      vectorizationPatterns.add<LinalgVectorizationPattern>(
-          anchorOpName, funcOp.getContext(), options, filter);
-    } else {
-      vectorizationPatterns.add<LinalgVectorizationPattern>(funcOp.getContext(),
-                                                            options, filter);
-    }
-
-    // TODO: Move this down the pipeline once we have the ODM-based masking
-    // representation.
-    vector::populateVectorMaskLoweringPatternsForSideEffectingOps(
-        vectorizationPatterns);
-
-    vector::populateVectorTransferPermutationMapLoweringPatterns(
-        vectorizationPatterns);
-    vector::populateVectorReductionToContractPatterns(vectorizationPatterns);
-    vectorizationPatterns.add<linalg::LinalgCopyVTRForwardingPattern,
-                              linalg::LinalgCopyVTWForwardingPattern>(
-        funcOp.getContext(), /*benefit=*/2);
-    vector::TransferReadOp::getCanonicalizationPatterns(vectorizationPatterns,
-                                                        funcOp.getContext());
-    vector::TransferWriteOp::getCanonicalizationPatterns(vectorizationPatterns,
-                                                         funcOp.getContext());
-    (void)applyPatternsAndFoldGreedily(funcOp,
-                                       std::move(vectorizationPatterns));
-
-    // Apply the pad tensor op vectorization separately to avoid running the
-    // GenericPadOpVectorizationPattern too early.
-    // TODO: Improve once we have better infrastructure to control pattern
-    // application.
-    if (vectorizePadding) {
-      RewritePatternSet patterns(funcOp.getContext());
-      linalg::populatePadOpVectorizationPatterns(patterns);
-      (void)applyPatternsAndFoldGreedily(funcOp, std::move(patterns));
-    }
-  }
-
-  LinalgVectorizationOptions options;
-  LinalgExt::LinalgTransformationFilter filter;
-};
-
 /// Configurable pass to enable the application of other pattern-based linalg
 /// passes.
 struct LinalgStrategyEnablePass
@@ -324,13 +265,6 @@
 };
 } // namespace
 
-/// Create a LinalgStrategyVectorizePass.
-std::unique_ptr<OperationPass<func::FuncOp>> createLinalgStrategyVectorizePass(
-    StringRef opName, const LinalgVectorizationOptions &options,
-    const LinalgExt::LinalgTransformationFilter &filter) {
-  return std::make_unique<LinalgStrategyVectorizePass>(opName, options, filter);
-}
-
 /// Create a LinalgStrategyEnablePass.
 std::unique_ptr<OperationPass<func::FuncOp>> createLinalgStrategyEnablePass(
     LinalgEnablingOptions opt,