[Mlir-commits] [mlir] 0d37546 - [mlir][linalg] Remove abandoned `Detensorize` pass (#177579)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Feb 10 04:29:24 PST 2026


Author: Matthias Springer
Date: 2026-02-10T13:29:19+01:00
New Revision: 0d375463ebdc9cc72e186f2366983c8053debb27

URL: https://github.com/llvm/llvm-project/commit/0d375463ebdc9cc72e186f2366983c8053debb27
DIFF: https://github.com/llvm/llvm-project/commit/0d375463ebdc9cc72e186f2366983c8053debb27.diff

LOG: [mlir][linalg] Remove abandoned `Detensorize` pass (#177579)

RFC:
https://discourse.llvm.org/t/how-to-deal-with-abandoned-unmaintained-code/89560

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/Linalg/Passes.td
    mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt

Removed: 
    mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
    mlir/test/Dialect/Linalg/detensorize_0d.mlir
    mlir/test/Dialect/Linalg/detensorize_br_operands.mlir
    mlir/test/Dialect/Linalg/detensorize_entry_block.mlir
    mlir/test/Dialect/Linalg/detensorize_if.mlir
    mlir/test/Dialect/Linalg/detensorize_trivial.mlir
    mlir/test/Dialect/Linalg/detensorize_while.mlir
    mlir/test/Dialect/Linalg/detensorize_while_impure_cf.mlir
    mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Linalg/Passes.td b/mlir/include/mlir/Dialect/Linalg/Passes.td
index 42d4d2083fc1c..f48ea9849e237 100644
--- a/mlir/include/mlir/Dialect/Linalg/Passes.td
+++ b/mlir/include/mlir/Dialect/Linalg/Passes.td
@@ -178,43 +178,6 @@ def LinalgFoldIntoElementwisePass : Pass<"linalg-fold-into-elementwise"> {
   }];
 }
 
-def LinalgDetensorizePass : InterfacePass<"linalg-detensorize", "FunctionOpInterface"> {
-  let summary = "Detensorize linalg ops";
-  let dependentDialects = [];
-
-  let description = [{
-    Detensoring is the process through which a tensor value is converted to one
-    or potentially more primitive value(s). During this process, operations with
-    such detensored operands are also converted to an equivalent form that works
-    on primitives.
-
-    The detensoring process is driven by linalg-on-tensor ops. In particular, a
-    linalg-on-tensor op is checked to see whether *all* its operands can be
-    detensored. If so, those operands are converted to their primitive
-    counterparts and the linalg op is replaced by an equivalent op that takes
-    those new primitive values as operands. Therefore, detensoring an op can be
-    divided into 2 main logical phases:
-
-    1. Detect/match an op that can be detensored.
-    2. Detensor the operands of the op and replace it with a primitive
-       equivalent.
-
-    In addition to detensoring individual ops, this pass detensors internal
-    control flow inside a function. All blocks except for the entry block are
-    detensored by converting their arguments whenever possible.
-
-    This can be run on any FunctionOpInterface op and must not be
-    run on others. This is because it performs specific legalization of the
-    blocks that make up the body, which it assumes has is a FunctionOpInterface.
-  }];
-  let options = [
-    Option<"aggressiveMode", "aggressive-mode", "bool", /*default=*/"false",
-           "Detensorize all ops that qualify for detensoring along with branch"
-           " operands and basic-block arguments.">
-
-  ];
-}
-
 def LinalgBlockPackMatmul : Pass<"linalg-block-pack-matmul"> {
   let summary = "Convert linalg matmul ops to block layout and back";
   let description = [{

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
index fb39e18691e03..a2149478e4c2d 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/Linalg/Transforms/CMakeLists.txt
@@ -7,7 +7,6 @@ add_mlir_dialect_library(MLIRLinalgTransforms
   ConvertConv2DToImg2Col.cpp
   DataLayoutPropagation.cpp
   DecomposeLinalgOps.cpp
-  Detensorize.cpp
   DropUnitDims.cpp
   ElementwiseOpFusion.cpp
   ElementwiseToLinalg.cpp

diff  --git a/mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp b/mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
deleted file mode 100644
index 830905495e759..0000000000000
--- a/mlir/lib/Dialect/Linalg/Transforms/Detensorize.cpp
+++ /dev/null
@@ -1,569 +0,0 @@
-//===- Detensorize.cpp - Linalg transformations as patterns ----------===//
-//
-// 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 "mlir/Dialect/Linalg/Passes.h"
-
-#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
-#include "mlir/Dialect/Func/Transforms/FuncConversions.h"
-#include "mlir/Dialect/Linalg/IR/Linalg.h"
-#include "mlir/Dialect/Tensor/IR/Tensor.h"
-#include "mlir/IR/OpDefinition.h"
-#include "mlir/Transforms/DialectConversion.h"
-#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
-#include <utility>
-
-namespace mlir {
-#define GEN_PASS_DEF_LINALGDETENSORIZEPASS
-#include "mlir/Dialect/Linalg/Passes.h.inc"
-} // namespace mlir
-
-using namespace mlir;
-using namespace mlir::linalg;
-
-static Value sourceMaterializationCallback(OpBuilder &builder, Type type,
-                                           ValueRange inputs, Location loc) {
-  assert(inputs.size() == 1);
-  auto inputType = inputs[0].getType();
-  if (isa<TensorType>(inputType))
-    return nullptr;
-
-  // A detensored value is converted back by creating a new tensor from its
-  // element(s).
-  return tensor::FromElementsOp::create(
-      builder, loc, RankedTensorType::get({}, inputType), inputs[0]);
-}
-
-namespace {
-/// Defines the criteria a TensorType must follow in order to be considered
-/// "detensorable".
-///
-/// NOTE: For now, only 0-D tensors are supported.
-///
-/// Returns true if tensorType can be detensored.
-bool canBeDetensored(TensorType tensorType) {
-  return tensorType.hasRank() && tensorType.getRank() == 0;
-}
-
-bool shouldBeDetensored(Operation *op, TypeConverter typeConverter) {
-  GenericOp genericOp = dyn_cast_or_null<GenericOp>(op);
-  return genericOp &&
-         llvm::all_of(genericOp->getOpOperands(), [&](OpOperand &opOperand) {
-           return !typeConverter.isLegal(opOperand.get().getType());
-         });
-}
-
-/// A conversion pattern for detensoring `linalg.generic` ops.
-class DetensorizeGenericOp : public OpConversionPattern<GenericOp> {
-public:
-  using OpConversionPattern::OpConversionPattern;
-  LogicalResult
-  matchAndRewrite(GenericOp op, OpAdaptor adaptor,
-                  ConversionPatternRewriter &rewriter) const override {
-    Block *originalBlock = op->getBlock();
-
-    // Gather some information about the op before inlining its region.
-    Block *opEntryBlock = &*op.getRegion().begin();
-    YieldOp yieldOp = dyn_cast<YieldOp>(op.getRegion().back().getTerminator());
-
-    // Split the op's region before the op. This way, we have a clear insertion
-    // point in which the op can be inlined.
-    Block *newBlock = rewriter.splitBlock(originalBlock, Block::iterator(op));
-    rewriter.inlineRegionBefore(op.getRegion(), newBlock);
-    // Now that op's region is inlined, the operands of its YieldOp are mapped
-    // to the materialized target values. Therefore, we can replace the op's
-    // uses with those of its YielOp's operands.
-    rewriter.replaceOp(op, yieldOp->getOperands());
-
-    // No need for these intermediate blocks, merge them into 1.
-    rewriter.mergeBlocks(opEntryBlock, originalBlock, adaptor.getOperands());
-    rewriter.mergeBlocks(newBlock, originalBlock, {});
-
-    rewriter.eraseOp(&*Block::iterator(yieldOp));
-
-    return success();
-  }
-};
-
-/// A conversion pattern for detensoring internal (non-entry) blocks within a
-/// function.
-struct FunctionNonEntryBlockConversion
-    : public OpInterfaceConversionPattern<FunctionOpInterface> {
-  FunctionNonEntryBlockConversion(MLIRContext *ctx, TypeConverter &converter,
-                                  DenseSet<BlockArgument> blockArgsToDetensor)
-      : OpInterfaceConversionPattern(converter, ctx),
-        blockArgsToDetensor(std::move(blockArgsToDetensor)) {}
-
-  LogicalResult
-  matchAndRewrite(FunctionOpInterface op, ArrayRef<Value> operands,
-                  ConversionPatternRewriter &rewriter) const override {
-    rewriter.startOpModification(op);
-    Region &region = op.getFunctionBody();
-
-    for (Block &block :
-         llvm::make_early_inc_range(llvm::drop_begin(region, 1))) {
-      TypeConverter::SignatureConversion conversion(
-          /*numOrigInputs=*/block.getNumArguments());
-
-      for (BlockArgument blockArgument : block.getArguments()) {
-        int idx = blockArgument.getArgNumber();
-
-        if (blockArgsToDetensor.count(blockArgument))
-          conversion.addInputs(idx, {getTypeConverter()->convertType(
-                                        block.getArgumentTypes()[idx])});
-        else
-          conversion.addInputs(idx, {block.getArgumentTypes()[idx]});
-      }
-
-      rewriter.applySignatureConversion(&block, conversion, getTypeConverter());
-    }
-
-    rewriter.finalizeOpModification(op);
-    return success();
-  }
-
-private:
-  const DenseSet<BlockArgument> blockArgsToDetensor;
-};
-
-class DetensorizeTypeConverter : public TypeConverter {
-public:
-  DetensorizeTypeConverter() {
-    addConversion([](Type type) { return type; });
-
-    // A TensorType that can be detensored, is converted to the underlying
-    // element type.
-    addConversion([](TensorType tensorType) -> Type {
-      if (canBeDetensored(tensorType))
-        return tensorType.getElementType();
-
-      return tensorType;
-    });
-
-    // A tensor value is detensoried by extracting its element(s).
-    addTargetMaterialization([](OpBuilder &builder, Type type,
-                                ValueRange inputs, Location loc) -> Value {
-      return tensor::ExtractOp::create(builder, loc, inputs[0], ValueRange{});
-    });
-
-    addSourceMaterialization(sourceMaterializationCallback);
-  }
-};
-
-/// @see LinalgDetensorize in Linalg/Passes.td for more details.
-struct LinalgDetensorize
-    : public impl::LinalgDetensorizePassBase<LinalgDetensorize> {
-  using impl::LinalgDetensorizePassBase<
-      LinalgDetensorize>::LinalgDetensorizePassBase;
-  LinalgDetensorize() = default;
-
-  class CostModel {
-  public:
-    virtual ~CostModel() = default;
-
-    /// A cost model algorithm computes the following outputs:
-    ///
-    /// - opsToDetensor: the list of linalg ops that should be
-    /// detensored.
-    ///
-    /// - blockArgsToDetensor: since the operands and results of detensored
-    /// linalg ops can cross the BB boundary (e.g. a linalg op's input can come
-    /// from a BB argument and a linalg op's output can be passed to successor
-    /// BBs), we need to maintain the sub-set of arguments that should be
-    /// detensored (i.e. converted by typeConverter) for each affected BB.
-    ///
-    /// Example:
-    ///
-    /// For the following snippet:
-    /// ...
-    /// ^bb1(%6: tensor<i32>, %9: tensor<i32>):
-    ///   %7 = tensor.empty() : tensor<i32>
-    ///   %8 = linalg.generic #attrs
-    ///     ins(%6, %6 : tensor<i32>, tensor<i32>)
-    ///     outs(%7 : tensor<i32>) {
-    ///     ^bb0(%arg0: i32, %arg1: i32, %arg2: i32):
-    ///       %9 = arith.addi %arg0, %arg1 : i32
-    ///       linalg.yield %9 : i32
-    ///   } -> tensor<i32>
-    ///   %10 = "some.op"(%9)
-    ///   br ^bb2(%8 : tensor<i32>)
-    /// ...
-    ///
-    /// if the cost model decides that the linalg.generic op should be
-    /// detensored, then:
-    /// - opsToDetensor should be = {linalg.generic{add}}.
-    /// - blockArgsToDetensor should be = {bb1 -> {0}, bb2 -> {0}}.
-    virtual void compute(FunctionOpInterface func,
-                         DetensorizeTypeConverter typeConverter,
-                         DenseSet<Operation *> &opsToDetensor,
-                         DenseSet<BlockArgument> &blockArgsToDetensor) = 0;
-
-    /// From the blockArgsToDetensor set computed by a CostModel
-    /// implementation, this method computes the corresponding branch op
-    /// detensoring. The result is a map from a branch op to a subset of indices
-    /// of its operands. The indices specify which of the branch op's operands
-    /// should be detensored.
-    ///
-    /// For the previous example, this method would compute: {bb2 -> {0}}.
-    static DenseMap<Operation *, DenseSet<int>> computeBranchOpDetensoring(
-        const DenseSet<BlockArgument> &blockArgsToDetensor) {
-      DenseMap<Operation *, DenseSet<int>> detensorableBranchOps;
-
-      for (auto blockArgumentElem : blockArgsToDetensor) {
-        Block *block = blockArgumentElem.getOwner();
-
-        for (PredecessorIterator pred = block->pred_begin();
-             pred != block->pred_end(); ++pred) {
-          BranchOpInterface terminator =
-              dyn_cast<BranchOpInterface>((*pred)->getTerminator());
-          auto blockOperands =
-              terminator.getSuccessorOperands(pred.getSuccessorIndex());
-
-          if (blockOperands.empty() ||
-              blockOperands.isOperandProduced(blockArgumentElem.getArgNumber()))
-            continue;
-
-          detensorableBranchOps[terminator].insert(
-              blockOperands.getOperandIndex(blockArgumentElem.getArgNumber()));
-        }
-      }
-
-      return detensorableBranchOps;
-    }
-  };
-
-  /// Detensorize linalg ops involved in control-flow within a function.
-  ///
-  /// This model starts from BranchOps and CondBranchOps within a function. For
-  /// each such branch, the model then walks the use-def chain for the branch's
-  /// condition backwards in order to understand where the condition's value
-  /// comes from. If the condition value is (indirectly) computed by a linalg op
-  /// that can be detensored, the model then continues walking the use-def chain
-  /// in order to understand where the linalg op's operands come from. This
-  /// leads to discovering a "detensoring component". A detensoring component is
-  /// the set of operations + block arguments that are involved in control-flow
-  /// AND can be detensored.
-  class ControlFlowDetectionModel : public CostModel {
-  public:
-    void compute(FunctionOpInterface func,
-                 DetensorizeTypeConverter typeConverter,
-                 DenseSet<Operation *> &opsToDetensor,
-                 DenseSet<BlockArgument> &blockArgsToDetensor) override {
-      SmallVector<Value> workList;
-
-      func->walk([&](cf::CondBranchOp condBr) {
-        llvm::append_range(workList, condBr.getOperands());
-      });
-
-      func->walk([&](cf::BranchOp br) {
-        llvm::append_range(workList, br.getOperands());
-      });
-
-      DenseSet<Value> visitedValues;
-      DenseSet<Operation *> visitedOps;
-
-      // For a (to-be-detesored) value, check if it "escapes" the block by being
-      // passed to terminator. If it does, then workList is updated with the
-      // corresponding argument to the successor block.
-      auto updateWorkListWithSuccessorArguments =
-          [&](Value value, BranchOpInterface terminator) {
-            if (!terminator)
-              return;
-
-            for (auto operandIdx :
-                 llvm::seq<unsigned>(0, terminator->getOperands().size())) {
-              Value operand = terminator->getOperand(operandIdx);
-
-              if (operand == value) {
-                auto succBlockArg =
-                    terminator.getSuccessorBlockArgument(operandIdx);
-
-                if (succBlockArg && !blockArgsToDetensor.count(*succBlockArg))
-                  workList.push_back(*succBlockArg);
-              }
-            }
-          };
-
-      while (!workList.empty()) {
-        Value currentItem = workList.pop_back_val();
-
-        if (!visitedValues.insert(currentItem).second)
-          continue;
-
-        // 1   - Look forward:
-        // 1.1 - If currentItem escapes to one or more successors, add
-        // the corresponding successor arguments to workList.
-        updateWorkListWithSuccessorArguments(
-            currentItem, dyn_cast<BranchOpInterface>(
-                             currentItem.getParentBlock()->getTerminator()));
-
-        // 1.2 - For each user of currentItem, add the defined values to
-        // workList. This way, the user ops can be inspected later if they are
-        // detensorable and if so, their operands will be added to workList to
-        // potentially discover other parts of the detensorable component.
-        for (auto *user : currentItem.getUsers())
-          llvm::append_range(workList, user->getResults());
-
-        // 2   - Look backward:
-        // 2.1 - The current item is defined by a block argument. If the owner
-        // block is a non-entry one, then:
-        //       * Add the argument to blockArgsToDetensor.
-        //       * Walk the use-def chain backwards to add each predecessor's
-        //       terminator-operands corresponding to currentItem to workList.
-        if (auto currentItemBlockArgument =
-                dyn_cast<BlockArgument>(currentItem)) {
-          Block *ownerBlock = currentItemBlockArgument.getOwner();
-
-          // Function arguments are not detensored/converted.
-          if (&*ownerBlock->getParent()->begin() == ownerBlock)
-            continue;
-
-          // This inner-block argument is involved in control-flow, it should be
-          // detensored.
-          blockArgsToDetensor.insert(currentItemBlockArgument);
-
-          for (PredecessorIterator pred = ownerBlock->pred_begin();
-               pred != ownerBlock->pred_end(); ++pred) {
-            BranchOpInterface predTerminator =
-                dyn_cast<BranchOpInterface>((*pred)->getTerminator());
-
-            // TODO: For now, we give up if any of the control-flow components
-            // in a function is not detensorable. Fix that.
-            if (!predTerminator) {
-              opsToDetensor.clear();
-              blockArgsToDetensor.clear();
-              return;
-            }
-
-            auto ownerBlockOperands =
-                predTerminator.getSuccessorOperands(pred.getSuccessorIndex());
-
-            if (ownerBlockOperands.empty() ||
-                ownerBlockOperands.isOperandProduced(
-                    currentItemBlockArgument.getArgNumber()))
-              continue;
-
-            // For each predecessor, add the value it passes to that argument to
-            // workList to find out how it's computed.
-            workList.push_back(
-                ownerBlockOperands[currentItemBlockArgument.getArgNumber()]);
-          }
-
-          continue;
-        }
-
-        Operation *currentItemDefiningOp = currentItem.getDefiningOp();
-
-        if (!visitedOps.insert(currentItemDefiningOp).second)
-          continue;
-
-        // 2.2 - The current item is computed by a GenericOp. If the op should
-        // be detensored, then:
-        //       * Add it to opsToDetensor.
-        //       * Add its operands to workList to discover other parts of the
-        //       potentially detensorable component.
-        if (auto genericOp = dyn_cast<GenericOp>(currentItemDefiningOp)) {
-          // The op was encountered already, no need to inspect it again.
-          if (opsToDetensor.count(genericOp))
-            continue;
-
-          // The op should not be detensored, give up on it but continue with
-          // discovering the rest of the control-flow component.
-          if (!shouldBeDetensored(genericOp, typeConverter)) {
-            continue;
-          }
-
-          opsToDetensor.insert(genericOp);
-          llvm::append_range(workList, genericOp.getInputs());
-          continue;
-        }
-
-        // 2.3 - The current item is the result of a FromElementsOp, it will be
-        // trivially detensored later as part of canonicalization patterns
-        // applied at the end of detensoring.
-        //
-        // Note: No need to check whether the result type of this op is
-        // detensorable since if it wasn't we wouldn't reach that point in the
-        // work list.
-        if (isa<tensor::FromElementsOp>(currentItemDefiningOp))
-          continue;
-
-        // 2.4 - The current item is the result of a scalar op, add all its
-        // operands to the work list.
-        if (llvm::all_of(
-                currentItemDefiningOp->getResultTypes(),
-                [&](Type resultType) { return resultType.isIntOrFloat(); }))
-          llvm::append_range(workList, currentItemDefiningOp->getOperands());
-      }
-
-      // Since the cost model gives up on some ops (see the details of step 2.2
-      // above), block arguments that correspond to the values produced by those
-      // ops should not be detensored as well.
-
-      DenseSet<BlockArgument> blockArgsToRemove;
-
-      for (auto &blockArg : blockArgsToDetensor) {
-        Block *block = blockArg.getParentBlock();
-
-        // For the potentially detensorable block argument, find the
-        // corresponding operands in predecessor blocks.
-        for (PredecessorIterator pred = block->pred_begin();
-             pred != block->pred_end(); ++pred) {
-          BranchOpInterface terminator =
-              dyn_cast<BranchOpInterface>((*pred)->getTerminator());
-          auto blockOperands =
-              terminator.getSuccessorOperands(pred.getSuccessorIndex());
-
-          if (blockOperands.empty() ||
-              blockOperands.isOperandProduced(blockArg.getArgNumber()))
-            continue;
-
-          Operation *definingOp =
-              blockOperands[blockArg.getArgNumber()].getDefiningOp();
-
-          // If the operand is defined by a GenericOp that will not be
-          // detensored, then do not detensor the corresponding block argument.
-          if (isa_and_nonnull<GenericOp>(definingOp) &&
-              opsToDetensor.count(definingOp) == 0) {
-            blockArgsToRemove.insert(blockArg);
-            break;
-          }
-        }
-      }
-
-      for (auto &blockArg : blockArgsToRemove) {
-        blockArgsToDetensor.erase(blockArg);
-      }
-    }
-  };
-
-  /// Detensorize everything that can detensored.
-  class AggressiveDetensoringModel : public CostModel {
-  public:
-    void compute(FunctionOpInterface func,
-                 DetensorizeTypeConverter typeConverter,
-                 DenseSet<Operation *> &opsToDetensor,
-                 DenseSet<BlockArgument> &blockArgsToDetensor) override {
-      func->walk([&](GenericOp genericOp) {
-        if (shouldBeDetensored(genericOp, typeConverter))
-          opsToDetensor.insert(genericOp);
-      });
-
-      for (Block &block : llvm::drop_begin(func.getFunctionBody(), 1))
-        blockArgsToDetensor.insert_range(block.getArguments());
-    }
-  };
-
-  void runOnOperation() override {
-    MLIRContext *context = &getContext();
-    DetensorizeTypeConverter typeConverter;
-    RewritePatternSet patterns(context);
-    ConversionTarget target(*context);
-    DenseSet<Operation *> opsToDetensor;
-    DenseMap<Operation *, DenseSet<int>> detensorableBranchOps;
-    DenseSet<BlockArgument> blockArgsToDetensor;
-    FunctionOpInterface funcOp = getOperation();
-
-    if (funcOp.getFunctionBody().empty())
-      return;
-
-    // Make sure the entry block of the function doesn't contain any Linalg ops.
-    // Otherwise, it may lead to the signature of the block being changed by the
-    // dialect conversion below, which would make the function op invalid
-    // because its type shouldn't change.
-    IRRewriter rewriter(funcOp->getContext());
-    Block *entryBlock = &funcOp.getFunctionBody().front();
-    Block *postEntryBlock =
-        rewriter.splitBlock(entryBlock, entryBlock->begin());
-    rewriter.setInsertionPointToStart(entryBlock);
-    auto branch = cf::BranchOp::create(rewriter, rewriter.getUnknownLoc(),
-                                       postEntryBlock);
-
-    if (aggressiveMode.getValue()) {
-      AggressiveDetensoringModel costModel;
-      costModel.compute(funcOp, typeConverter, opsToDetensor,
-                        blockArgsToDetensor);
-    } else {
-      ControlFlowDetectionModel costModel;
-      costModel.compute(funcOp, typeConverter, opsToDetensor,
-                        blockArgsToDetensor);
-    }
-
-    detensorableBranchOps =
-        CostModel::computeBranchOpDetensoring(blockArgsToDetensor);
-
-    target.addDynamicallyLegalOp<GenericOp>(
-        [&](GenericOp op) { return !opsToDetensor.count(op); });
-
-    target.markUnknownOpDynamicallyLegal([&](Operation *op) {
-      // A function is legal if all of its non-entry blocks are legal. We
-      // don't legalize the entry block (i.e. the function's signature)
-      // since detensoring can't happen along external calling convention
-      // boundaries, which we conservatively approximate as all function
-      // signatures.
-      if (auto funcOp = dyn_cast<FunctionOpInterface>(op)) {
-        Region &body = funcOp.getFunctionBody();
-        return llvm::all_of(llvm::drop_begin(body, 1), [&](Block &block) {
-          return !llvm::any_of(
-              blockArgsToDetensor, [&](BlockArgument blockArgument) {
-                return blockArgument.getOwner() == &block &&
-                       !typeConverter.isLegal(blockArgument.getType());
-              });
-        });
-      }
-
-      if (isNotBranchOpInterfaceOrReturnLikeOp(op) ||
-          isLegalForReturnOpTypeConversionPattern(op, typeConverter,
-                                                  /*returnOpAlwaysLegal*/ true))
-        return true;
-
-      if (auto branchOp = dyn_cast<BranchOpInterface>(op)) {
-        if (!detensorableBranchOps.count(branchOp))
-          return true;
-
-        for (auto operandIdx : detensorableBranchOps[branchOp])
-          if (!typeConverter.isLegal(
-                  branchOp->getOperand(operandIdx).getType()))
-            return false;
-
-        return true;
-      }
-
-      return false;
-    });
-
-    patterns.add<DetensorizeGenericOp>(typeConverter, context);
-    patterns.add<FunctionNonEntryBlockConversion>(context, typeConverter,
-                                                  blockArgsToDetensor);
-    // Since non-entry block arguments get detensorized, we also need to
-    // update the control flow inside the function to reflect the correct
-    // types.
-    auto shouldConvertBranchOperand = [&](BranchOpInterface branchOp,
-                                          int operandIdx) -> bool {
-      return detensorableBranchOps.count(branchOp) &&
-             detensorableBranchOps[branchOp].count(operandIdx);
-    };
-
-    populateBranchOpInterfaceTypeConversionPattern(patterns, typeConverter,
-                                                   shouldConvertBranchOperand);
-
-    if (failed(
-            applyFullConversion(getOperation(), target, std::move(patterns))))
-      signalPassFailure();
-
-    RewritePatternSet canonPatterns(context);
-    tensor::FromElementsOp::getCanonicalizationPatterns(canonPatterns, context);
-    if (failed(applyPatternsGreedily(getOperation(), std::move(canonPatterns))))
-      signalPassFailure();
-
-    // Get rid of the dummy entry block we created in the beginning to work
-    // around dialect conversion signature rewriting.
-    rewriter.eraseOp(branch);
-    rewriter.mergeBlocks(postEntryBlock, entryBlock);
-  }
-};
-} // namespace

diff  --git a/mlir/test/Dialect/Linalg/detensorize_0d.mlir b/mlir/test/Dialect/Linalg/detensorize_0d.mlir
deleted file mode 100644
index 74931cb0830bc..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_0d.mlir
+++ /dev/null
@@ -1,102 +0,0 @@
-// RUN: mlir-opt %s -allow-unregistered-dialect -pass-pipeline="builtin.module(func.func(linalg-detensorize{aggressive-mode}))" | FileCheck %s
-
-#map = affine_map<() -> ()>
-
-func.func @detensor_simple(%arg1: tensor<f32>, %arg2: tensor<f32>) -> tensor<f32> {
-  %0 = tensor.empty() : tensor<f32>
-  %1 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []}
-    ins(%arg1, %arg2 : tensor<f32>, tensor<f32>)
-    outs(%0 : tensor<f32>) {
-  ^bb0(%arg3: f32, %arg4: f32, %arg5: f32):
-    %2 = arith.addf %arg3, %arg4 : f32
-    linalg.yield %2 : f32
-  } -> tensor<f32>
-  return %1: tensor<f32>
-}
-// CHECK-LABEL: func @detensor_simple
-// CHECK-SAME:    (%[[arg1:.*]]: tensor<f32>, %[[arg2:.*]]: tensor<f32>)
-// CHECK-DAG:     %[[arg1_val:.*]] = tensor.extract %[[arg1]]
-// CHECK-DAG:     %[[arg2_val:.*]] = tensor.extract %[[arg2]]
-// CHECK:         %[[detensored_res:.*]] = arith.addf %[[arg1_val]], %[[arg2_val]]
-// CHECK:         %[[new_tensor_res:.*]] = tensor.from_elements %[[detensored_res]]
-// CHECK:         return %[[new_tensor_res]]
-
-func.func @detensor_op_sequence(%arg1: tensor<f32>, %arg2: tensor<f32>) -> tensor<f32> {
-  %0 = tensor.empty() : tensor<f32>
-  %1 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []}
-    ins(%arg1, %arg2 : tensor<f32>, tensor<f32>)
-    outs(%0 : tensor<f32>) {
-  ^bb0(%arg3: f32, %arg4: f32, %arg5: f32):
-    %2 = arith.addf %arg3, %arg4 : f32
-    linalg.yield %2 : f32
-  } -> tensor<f32>
-
-  %3 = tensor.empty() : tensor<f32>
-  %4 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []}
-    ins(%arg1, %1 : tensor<f32>, tensor<f32>)
-    outs(%3 : tensor<f32>) {
-  ^bb0(%arg3: f32, %arg4: f32, %arg5: f32):
-    %5 = arith.mulf %arg3, %arg4 : f32
-    linalg.yield %5 : f32
-  } -> tensor<f32>
-
-  %6 = tensor.empty() : tensor<f32>
-  %7 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []}
-    ins(%1, %4 : tensor<f32>, tensor<f32>)
-    outs(%6 : tensor<f32>) {
-  ^bb0(%arg3: f32, %arg4: f32, %arg5: f32):
-    %5 = arith.divf %arg3, %arg4 : f32
-    linalg.yield %5 : f32
-  } -> tensor<f32>
-
-  return %7: tensor<f32>
-}
-// CHECK-LABEL: func @detensor_op_sequence
-// CHECK-SAME:    (%[[arg1:.*]]: tensor<f32>, %[[arg2:.*]]: tensor<f32>)
-// CHECK-DAG:     %[[arg1_val:.*]] = tensor.extract %[[arg1]]
-// CHECK-DAG:     %[[arg2_val:.*]] = tensor.extract %[[arg2]]
-// CHECK:         %[[detensored_res:.*]] = arith.addf %[[arg1_val]], %[[arg2_val]]
-// CHECK:         %[[detensored_res2:.*]] = arith.mulf %[[arg1_val]], %[[detensored_res]]
-// CHECK:         %[[detensored_res3:.*]] = arith.divf %[[detensored_res]], %[[detensored_res2]]
-// CHECK:         %[[new_tensor_res:.*]] = tensor.from_elements %[[detensored_res3]]
-// CHECK:         return %[[new_tensor_res]]
-
-func.func @detensor_multiple_ops(%arg1: tensor<f32>, %arg2: tensor<f32>) -> tensor<f32> {
-  %0 = tensor.empty() : tensor<f32>
-  %1 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []}
-    ins(%arg1, %arg2 : tensor<f32>, tensor<f32>)
-    outs(%0 : tensor<f32>) {
-  ^bb0(%arg3: f32, %arg4: f32, %arg5: f32):
-    %2 = arith.addf %arg3, %arg4 : f32
-    %3 = arith.mulf %2, %arg4 : f32
-    linalg.yield %3 : f32
-  } -> tensor<f32>
-  return %1: tensor<f32>
-}
-// CHECK-LABEL: func @detensor_multiple_ops
-// CHECK-SAME:    (%[[arg1:.*]]: tensor<f32>, %[[arg2:.*]]: tensor<f32>)
-// CHECK-DAG:     %[[arg1_val:.*]] = tensor.extract %[[arg1]]
-// CHECK-DAG:     %[[arg2_val:.*]] = tensor.extract %[[arg2]]
-// CHECK:         %[[detensored_res:.*]] = arith.addf %[[arg1_val]], %[[arg2_val]]
-// CHECK:         %[[detensored_res2:.*]] = arith.mulf %[[detensored_res]], %[[arg2_val]]
-// CHECK:         %[[new_tensor_res:.*]] = tensor.from_elements %[[detensored_res2]]
-// CHECK:         return %[[new_tensor_res]]
-
-func.func @detensor_foreign_op(%arg1: tensor<f32>, %arg2: tensor<f32>) -> tensor<f32> {
-  %0 = tensor.empty() : tensor<f32>
-  %1 = linalg.generic {indexing_maps = [#map, #map, #map], iterator_types = []}
-    ins(%arg1, %arg2 : tensor<f32>, tensor<f32>)
-    outs(%0 : tensor<f32>) {
-  ^bb0(%arg3: f32, %arg4: f32, %arg5: f32):
-    %2 = "foreign.do_something"(%arg3, %arg4) {} : (f32, f32) -> f32
-    linalg.yield %2 : f32
-  } -> tensor<f32>
-  return %1: tensor<f32>
-}
-// CHECK-LABEL: func @detensor_foreign_op
-// CHECK-SAME:    (%[[arg1:.*]]: tensor<f32>, %[[arg2:.*]]: tensor<f32>)
-// CHECK-DAG:     %[[arg1_val:.*]] = tensor.extract %[[arg1]]
-// CHECK-DAG:     %[[arg2_val:.*]] = tensor.extract %[[arg2]]
-// CHECK:         %[[detensored_res:.*]] = "foreign.do_something"(%[[arg1_val]], %[[arg2_val]])
-// CHECK:         %[[new_tensor_res:.*]] = tensor.from_elements %[[detensored_res]]
-// CHECK:         return %[[new_tensor_res]]

diff  --git a/mlir/test/Dialect/Linalg/detensorize_br_operands.mlir b/mlir/test/Dialect/Linalg/detensorize_br_operands.mlir
deleted file mode 100644
index f36f72a340445..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_br_operands.mlir
+++ /dev/null
@@ -1,45 +0,0 @@
-// RUN: mlir-opt %s -split-input-file -allow-unregistered-dialect -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s
-
-// TODO: Detensoring breaks if %arg0 or %arg1 are passed directly as tensors. Fix that.
-func.func @if_true_test(%arg0: i1, %arg1: i32) -> tensor<i32> attributes {} {
-  %arg0_t = tensor.from_elements %arg0 : tensor<i1>
-  %arg1_t = tensor.from_elements %arg1 : tensor<i32>
-
-  %cst = arith.constant dense<10> : tensor<i32>
-  %2 = tensor.empty() : tensor<i8>
-  %3 = linalg.generic
-    {indexing_maps = [affine_map<() -> ()>, affine_map<() -> ()>], iterator_types = []}
-    ins(%arg0_t : tensor<i1>)
-    outs(%2 : tensor<i8>) {
-  ^bb0(%arg2: i1, %arg3: i8):
-    %10 = arith.extui %arg2 : i1 to i8
-    linalg.yield %10 : i8
-  } -> tensor<i8>
-  %4 = tensor.extract %3[] : tensor<i8>
-  %5 = arith.trunci %4 : i8 to i1
-  cf.cond_br %5, ^bb1, ^bb2(%arg1_t : tensor<i32>)
-^bb1:
-  %6 = tensor.empty() : tensor<i32>
-  %7 = linalg.generic
-    {indexing_maps = [affine_map<() -> ()>, affine_map<() -> ()>, affine_map<() -> ()>], iterator_types = []}
-    ins(%arg1_t, %cst : tensor<i32>, tensor<i32>)
-    outs(%6 : tensor<i32>) {
-  ^bb0(%arg2: i32, %arg3: i32, %arg4: i32):
-    %10 = arith.addi %arg2, %arg3 : i32
-    linalg.yield %10 : i32
-  } -> tensor<i32>
-  cf.br ^bb2(%7 : tensor<i32>)
-^bb2(%8: tensor<i32>):
-  return %8 : tensor<i32>
-}
-
-// CHECK-LABEL:  func @if_true_test
-// CHECK-SAME:     (%[[arg0:.*]]: i1, %[[arg1:.*]]: i32)
-// CHECK-NEXT:     arith.constant 10 : i32
-// CHECK-NEXT:     cf.cond_br %[[arg0]], ^[[bb1:.*]], ^[[bb2:.*]](%[[arg1]] : i32)
-// CHECK-NEXT:   ^[[bb1]]:
-// CHECK-NEXT:     %[[add_res:.*]] = arith.addi
-// CHECK-NEXT:     cf.br ^[[bb2]](%[[add_res]] : i32)
-// CHECK-NEXT:   ^[[bb2]]
-// CHECK-NEXT:     %[[func_res:.*]] = tensor.from_elements
-// CHECK-NEXT:     return %[[func_res]]

diff  --git a/mlir/test/Dialect/Linalg/detensorize_entry_block.mlir b/mlir/test/Dialect/Linalg/detensorize_entry_block.mlir
deleted file mode 100644
index 50a2d6bf532aa..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_entry_block.mlir
+++ /dev/null
@@ -1,21 +0,0 @@
-// RUN: mlir-opt %s -allow-unregistered-dialect -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s
-
-#map = affine_map<() -> ()>
-func.func @main(%arg0: tensor<f32>) -> tensor<f32> {
-  %0 = tensor.empty() : tensor<f32>
-  %1 = linalg.generic {indexing_maps = [#map, #map], iterator_types = []} ins(%arg0 : tensor<f32>) outs(%0 : tensor<f32>) {
-  ^bb0(%in: f32, %out: f32):
-    linalg.yield %in : f32
-  } -> tensor<f32>
-  cf.br ^bb1(%1 : tensor<f32>)
-^bb1(%2: tensor<f32>):  // pred: ^bb0
-  return %2 : tensor<f32>
-}
-
-// CHECK-LABEL: @main
-// CHECK-SAME:       (%[[ARG0:.+]]: tensor<f32>) -> tensor<f32>
-// CHECK:   %[[EXTRACTED:.+]] = tensor.extract %[[ARG0]][] : tensor<f32>
-// CHECK: cf.br ^{{.*}}
-// CHECK: ^{{.*}}:
-// CHECK:   %[[ELEMENTS:.+]] = tensor.from_elements %[[EXTRACTED]] : tensor<f32>
-// CHECK:   return %[[ELEMENTS]] : tensor<f32>

diff  --git a/mlir/test/Dialect/Linalg/detensorize_if.mlir b/mlir/test/Dialect/Linalg/detensorize_if.mlir
deleted file mode 100644
index c728ad21d2209..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_if.mlir
+++ /dev/null
@@ -1,177 +0,0 @@
-// RUN: mlir-opt %s -split-input-file -allow-unregistered-dialect -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s
-
-#map0 = affine_map<() -> ()>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-func.func @main() -> (tensor<i32>) attributes {} {
-  %c0 = arith.constant 0 : i32
-  %0 = tensor.from_elements %c0 : tensor<i32>
-  %c10 = arith.constant 10 : i32
-  %1 = tensor.from_elements %c10 : tensor<i32>
-  cf.br ^bb1(%0 : tensor<i32>)
-
-^bb1(%2: tensor<i32>):  // 2 preds: ^bb0, ^bb2
-  %3 = tensor.empty() : tensor<i1>
-  %4 = linalg.generic #attrs
-    ins(%2, %1 : tensor<i32>, tensor<i32>)
-    outs(%3 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  %5 = tensor.extract %4[] : tensor<i1>
-  cf.cond_br %5, ^bb2(%2 : tensor<i32>), ^bb3(%2 : tensor<i32>)
-
-^bb2(%6: tensor<i32>):  // pred: ^bb1
-  %7 = tensor.empty() : tensor<i32>
-  %8 = linalg.generic #attrs
-    ins(%6, %6 : tensor<i32>, tensor<i32>)
-    outs(%7 : tensor<i32>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i32):
-      %9 = arith.addi %arg0, %arg1 : i32
-      linalg.yield %9 : i32
-  } -> tensor<i32>
-  cf.br ^bb3(%8 : tensor<i32>)
-
-^bb3(%10: tensor<i32>):  // pred: ^bb1
-  return %10 : tensor<i32>
-}
-
-// CHECK-LABEL:  func @main()
-// CHECK-DAG:     %[[cst:.*]] = arith.constant dense<0>
-// CHECK-DAG:     arith.constant true
-// CHECK:         cf.br
-// CHECK-NEXT:   ^[[bb1:.*]]:
-// CHECK-NEXT:     cf.cond_br %{{.*}}, ^[[bb2:.*]], ^bb3
-// CHECK-NEXT:   ^[[bb2]]
-// CHECK-NEXT:     cf.br ^[[bb3:.*]]
-// CHECK-NEXT:   ^[[bb3]]
-// CHECK-NEXT:     return %[[cst]]
-// CHECK-NEXT:   }
-
-// -----
-
-// Similar to the above test with one change: one of the block after the
-// if-condition passes/forwards its tensor argument to another block.
-
-#map0 = affine_map<() -> ()>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-func.func @main() -> (tensor<i32>) attributes {} {
-  %c0 = arith.constant 0 : i32
-  %0 = tensor.from_elements %c0 : tensor<i32>
-  %c10 = arith.constant 10 : i32
-  %1 = tensor.from_elements %c10 : tensor<i32>
-  cf.br ^bb1(%0 : tensor<i32>)
-
-^bb1(%2: tensor<i32>):  // 2 preds: ^bb0, ^bb2
-  %3 = tensor.empty() : tensor<i1>
-  %4 = linalg.generic #attrs
-    ins(%2, %1 : tensor<i32>, tensor<i32>)
-    outs(%3 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  %5 = tensor.extract %4[] : tensor<i1>
-  cf.cond_br %5, ^bb2(%2 : tensor<i32>), ^bb3(%2 : tensor<i32>)
-
-^bb2(%6: tensor<i32>):  // pred: ^bb1
-  %7 = tensor.empty() : tensor<i32>
-  %8 = linalg.generic #attrs
-    ins(%6, %6 : tensor<i32>, tensor<i32>)
-    outs(%7 : tensor<i32>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i32):
-      %9 = arith.addi %arg0, %arg1 : i32
-      linalg.yield %9 : i32
-  } -> tensor<i32>
-  cf.br ^bb3(%8 : tensor<i32>)
-
-^bb3(%10: tensor<i32>):  // pred: ^bb1
-  cf.br ^bb4(%10 : tensor<i32>)
-
-^bb4(%11: tensor<i32>):  // pred: ^bb1
-  return %11 : tensor<i32>
-}
-
-// CHECK-LABEL:  func @main()
-// CHECK-DAG:     %[[cst:.*]] = arith.constant dense<0>
-// CHECK-DAG:     arith.constant true
-// CHECK:         cf.br ^[[bb1:.*]]
-// CHECK-NEXT:   ^[[bb1:.*]]:
-// CHECK-NEXT:     cf.cond_br %{{.*}}, ^[[bb2:.*]], ^bb3
-// CHECK-NEXT:   ^[[bb2]]:
-// CHECK-NEXT:     cf.br ^[[bb3:.*]]
-// CHECK-NEXT:   ^[[bb3]]:
-// CHECK-NEXT:     cf.br ^[[bb4:.*]]
-// CHECK-NEXT:   ^[[bb4]]:
-// CHECK-NEXT:     return %[[cst]]
-// CHECK-NEXT:   }
-
-// -----
-
-#map0 = affine_map<() -> ()>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-func.func @main() -> (tensor<i32>) attributes {} {
-  %c0 = arith.constant 0 : i32
-  %0 = tensor.from_elements %c0 : tensor<i32>
-  %c10 = arith.constant 10 : i32
-  %1 = tensor.from_elements %c10 : tensor<i32>
-  cf.br ^bb1(%0 : tensor<i32>)
-
-^bb1(%2: tensor<i32>):  // 2 preds: ^bb0, ^bb2
-  %3 = tensor.empty() : tensor<i1>
-  %4 = linalg.generic #attrs
-    ins(%2, %1 : tensor<i32>, tensor<i32>)
-    outs(%3 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  %5 = tensor.extract %4[] : tensor<i1>
-  // This cf.cond_br intentionally has bb2 as it's target for both branches. This
-  // is to make sure that the "forward phase" of the cost-model correctly adds
-  // the users of a block argument (in this case bb2's argument) to the work
-  // list.
-  cf.cond_br %5, ^bb2(%2 : tensor<i32>), ^bb2(%2 : tensor<i32>)
-
-^bb2(%6: tensor<i32>):  // pred: ^bb1
-  %12 = tensor.from_elements %c10 : tensor<i32>
-  %7 = tensor.empty() : tensor<i32>
-  %8 = linalg.generic #attrs
-    ins(%6, %12 : tensor<i32>, tensor<i32>)
-    outs(%7 : tensor<i32>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i32):
-      %9 = arith.addi %arg0, %arg1 : i32
-      linalg.yield %9 : i32
-  } -> tensor<i32>
-  cf.br ^bb3(%8 : tensor<i32>)
-
-^bb3(%10: tensor<i32>):  // pred: ^bb1
-  return %10 : tensor<i32>
-}
-
-// CHECK-LABEL:  func @main()
-// CHECK-DAG:     %[[cst:.*]] = arith.constant dense<10>
-// CHECK-DAG:     arith.constant true
-// CHECK:         cf.br ^[[bb1:.*]]
-// CHECK-NEXT:   ^[[bb1]]:
-// CHECK-NEXT:     cf.cond_br %{{.*}}, ^[[bb2:.*]], ^bb2
-// CHECK-NEXT:   ^[[bb2]]
-// CHECK-NEXT:     cf.br ^[[bb3:.*]]
-// CHECK-NEXT:   ^[[bb3]]
-// CHECK-NEXT:     return %[[cst]]
-// CHECK-NEXT:   }

diff  --git a/mlir/test/Dialect/Linalg/detensorize_trivial.mlir b/mlir/test/Dialect/Linalg/detensorize_trivial.mlir
deleted file mode 100644
index 02fa7ace13b9d..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_trivial.mlir
+++ /dev/null
@@ -1,44 +0,0 @@
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(linalg-detensorize{aggressive-mode}))" | FileCheck %s -check-prefix=DET-ALL
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s -check-prefix=DET-CF
-
-
-#map0 = affine_map<() -> ()>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-func.func @main(%farg0 : tensor<i32>) -> (tensor<i1>) attributes {} {
-  %c10 = arith.constant 10 : i32
-  %1 = tensor.from_elements %c10 : tensor<i32>
-  %3 = tensor.empty() : tensor<i1>
-  %4 = linalg.generic #attrs
-    ins(%farg0, %1 : tensor<i32>, tensor<i32>)
-    outs(%3 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  return %4 : tensor<i1>
-}
-
-
-// DET-ALL-LABEL: func @main(%{{.*}}: tensor<i32>)
-// DET-ALL-NEXT:    arith.constant 10
-// DET-ALL-NEXT:    tensor.extract %{{.*}}[]
-// DET-ALL-NEXT:    arith.cmpi slt, %{{.*}}, %{{.*}}
-// DET-ALL-NEXT:    tensor.from_elements %{{.*}}
-// DET-ALL-NEXT:    return %{{.*}} : tensor<i1>
-// DET-ALL-NEXT:  }
-
-// DET-CF-LABEL: func @main(%{{.*}}: tensor<i32>)
-// DET-CF-NEXT:    arith.constant dense<10> : tensor<i32>
-// DET-CF-NEXT:    tensor.empty() : tensor<i1>
-// DET-CF-NEXT:    linalg.generic
-// DET-CF-NEXT:    ^{{.*}}(%{{.*}}: i32, %{{.*}}: i32, %{{.*}}: i1)
-// DET-CF-NEXT:      arith.cmpi slt, %{{.*}}, %{{.*}}
-// DET-CF-NEXT:      linalg.yield %{{.*}}
-// DET-CF-NEXT:    } -> tensor<i1>
-// DET-CF-NEXT:    return %{{.*}}
-// DET-CF-NEXT:  }

diff  --git a/mlir/test/Dialect/Linalg/detensorize_while.mlir b/mlir/test/Dialect/Linalg/detensorize_while.mlir
deleted file mode 100644
index 580a97d3a851b..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_while.mlir
+++ /dev/null
@@ -1,71 +0,0 @@
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(linalg-detensorize{aggressive-mode}))" | FileCheck %s -check-prefix=DET-ALL
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s -check-prefix=DET-CF
-
-#map0 = affine_map<() -> ()>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-func.func @main(%farg0: tensor<i32>, %farg1: tensor<i32>) -> tensor<i32> attributes {} {
-  cf.br ^bb1(%farg0 : tensor<i32>)
-
-^bb1(%0: tensor<i32>):  // 2 preds: ^bb0, ^bb2
-  %1 = tensor.empty() : tensor<i1>
-  %2 = linalg.generic #attrs
-    ins(%0, %farg1 : tensor<i32>, tensor<i32>)
-    outs(%1 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  %3 = tensor.extract %2[] : tensor<i1>
-  cf.cond_br %3, ^bb2(%0 : tensor<i32>), ^bb3(%0 : tensor<i32>)
-
-^bb2(%4: tensor<i32>):  // pred: ^bb1
-  %5 = tensor.empty() : tensor<i32>
-  %6 = linalg.generic #attrs
-    ins(%4, %4 : tensor<i32>, tensor<i32>)
-    outs(%5 : tensor<i32>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i32):
-      %8 = arith.addi %arg0, %arg1 : i32
-      linalg.yield %8 : i32
-  } -> tensor<i32>
-  cf.br ^bb1(%6 : tensor<i32>)
-
-^bb3(%7: tensor<i32>):  // pred: ^bb1
-  return %7 : tensor<i32>
-}
-
-// Test aggresively detensoring all detensorable ops.
-//
-// DET-ALL-LABEL: func @main
-// DET-ALL-SAME:    (%{{.*}}: tensor<i32>, %{{.*}}: tensor<i32>)
-// DET-ALL:         tensor.extract {{.*}}
-// DET-ALL:         cf.br ^[[bb1:.*]](%{{.*}} : i32)
-// DET-ALL:       ^[[bb1]](%{{.*}}: i32)
-// DET-ALL:         arith.cmpi slt, {{.*}}
-// DET-ALL:         cf.cond_br {{.*}}, ^[[bb2:.*]], ^[[bb3:.*]]
-// DET-ALL:       ^[[bb2]]
-// DET-ALL:         arith.addi {{.*}}
-// DET-ALL:         cf.br ^[[bb1]](%{{.*}} : i32)
-// DET-ALL:       ^[[bb3]]:
-// DET-ALL:         tensor.from_elements {{.*}}
-// DET-ALL:         return %{{.*}} : tensor<i32>
-
-// Test detensoring only ops involed in control-flow.
-//
-// DET-CF-LABEL: func @main
-// DET-CF-SAME:    (%{{.*}}: tensor<i32>, %{{.*}}: tensor<i32>)
-// DET-CF:         tensor.extract {{.*}}
-// DET-CF:         cf.br ^[[bb1:.*]](%{{.*}} : i32)
-// DET-CF:       ^[[bb1]](%{{.*}}: i32)
-// DET-CF:         arith.cmpi slt, {{.*}}
-// DET-CF:         cf.cond_br {{.*}}, ^[[bb2:.*]], ^[[bb3:.*]]
-// DET-CF:       ^[[bb2]]:
-// DET-CF:         arith.addi {{.*}}
-// DET-CF:         cf.br ^[[bb1]](%{{.*}} : i32)
-// DET-CF:       ^[[bb3]]:
-// DET-CF:         tensor.from_elements %{{.*}} : tensor<i32>
-// DET-CF:         return %{{.*}} : tensor<i32>

diff  --git a/mlir/test/Dialect/Linalg/detensorize_while_impure_cf.mlir b/mlir/test/Dialect/Linalg/detensorize_while_impure_cf.mlir
deleted file mode 100644
index 414d9b94cbf53..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_while_impure_cf.mlir
+++ /dev/null
@@ -1,104 +0,0 @@
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(linalg-detensorize{aggressive-mode}))" | FileCheck %s -check-prefix=DET-ALL
-// RUN: mlir-opt %s -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s -check-prefix=DET-CF
-
-#map0 = affine_map<() -> ()>
-#map1 = affine_map<(i) -> ()>
-#map2 = affine_map<(i) -> (i)>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-#sum_reduction_attrs = {
-  indexing_maps = [#map2, #map1],
-  iterator_types = ["reduction"]
-}
-
-
-#broadcast_attrs = {
-  indexing_maps = [#map1, #map2],
-  iterator_types = ["parallel"]
-}
-
-func.func @main(%farg0: tensor<10xi32>, %farg1: tensor<i32>) -> tensor<i32> attributes {} {
-  cf.br ^bb1(%farg0 : tensor<10xi32>)
-
-^bb1(%0: tensor<10xi32>):  // 2 preds: ^bb0, ^bb2
-  %1 = tensor.empty() : tensor<i32>
-  %2 = linalg.generic #sum_reduction_attrs
-    ins(%0: tensor<10xi32>)
-    outs(%1: tensor<i32>) {
-      ^bb(%a: i32, %x: i32):
-        %b = arith.addi %x, %a : i32
-        linalg.yield %b : i32
-  } -> tensor<i32>
-
-  %3 = tensor.empty() : tensor<i1>
-  %4 = linalg.generic #attrs
-    ins(%2, %farg1 : tensor<i32>, tensor<i32>)
-    outs(%3 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  %5 = tensor.extract %4[] : tensor<i1>
-  cf.cond_br %5, ^bb2(%2 : tensor<i32>), ^bb3(%2 : tensor<i32>)
-
-^bb2(%6: tensor<i32>):  // pred: ^bb1
-  %7 = tensor.empty() : tensor<10xi32>
-  %9 = linalg.generic #broadcast_attrs
-       ins(%6: tensor<i32>)
-      outs(%7: tensor<10xi32>) {
-    ^bb(%a: i32, %b: i32) :
-      linalg.yield %a : i32
-  } -> tensor<10xi32>
-
-  cf.br ^bb1(%9 : tensor<10xi32>)
-
-^bb3(%10: tensor<i32>):  // pred: ^bb1
-  return %10 : tensor<i32>
-}
-
-// Test aggresively detensoring all detensorable ops.
-//
-// DET-ALL-LABEL: func @main
-// DET-ALL-SAME:    (%{{.*}}: tensor<10xi32>, %{{.*}}: tensor<i32>)
-// DET-ALL:         cf.br ^[[bb1:.*]](%{{.*}} : tensor<10xi32>)
-// DET-ALL:       ^[[bb1]](%{{.*}}: tensor<10xi32>)
-// DET-ALL:         tensor.empty() : tensor<i32>
-// DET-ALL:         linalg.generic {{{.*}}} ins(%{{.*}} : tensor<10xi32>) outs(%{{.*}} : tensor<i32>) {
-// DET-ALL:         ^bb0(%{{.*}}: i32, %{{.*}}: i32):
-// DET-ALL:           %{{.*}} = arith.addi %{{.*}}, %{{.*}}
-// DET-ALL:           linalg.yield %{{.*}} : i32
-// DET-ALL:         } -> tensor<i32>
-// DET-ALL:         tensor.extract %{{.*}}[] : tensor<i32>
-// DET-ALL:         cmpi slt, %{{.*}}, %{{.*}} : i32
-// DET-ALL:         cf.cond_br %{{.*}}, ^[[bb2:.*]], ^[[bb3:.*]]
-// DET-ALL:       ^[[bb2]]:
-// DET-ALL:         tensor.from_elements %{{.*}} : tensor<i32>
-// DET-ALL:         tensor.empty() : tensor<10xi32>
-// DET-ALL:         linalg.generic {{{.*}}} ins(%{{.*}} : tensor<i32>) outs(%{{.*}} : tensor<10xi32>) {
-// DET-ALL:         ^bb0(%{{.*}}: i32, %{{.*}}: i32):
-// DET-ALL:           linalg.yield %{{.*}} : i32
-// DET-ALL:         } -> tensor<10xi32>
-// DET-ALL:         cf.br ^[[bb1]](%{{.*}} : tensor<10xi32>)
-// DET-ALL:       ^[[bb3]]
-// DET-ALL:         tensor.from_elements %{{.*}} : tensor<i32>
-// DET-ALL:         return %{{.*}} : tensor<i32>
-// DET-ALL:       }
-
-// DET-CF-LABEL: func @main
-// DET-CF-SAME:    (%{{.*}}: tensor<10xi32>, %{{.*}}: tensor<i32>)
-// DET-CF:         cf.br ^[[bb1:.*]](%{{.*}} : tensor<10xi32>)
-// DET-CF:       ^bb1(%{{.*}}: tensor<10xi32>)
-// DET-CF:         %{{.*}} = linalg.generic {{{.*}}} ins(%{{.*}} : tensor<10xi32>) outs(%{{.*}} : tensor<i32>) {
-// DET-CF:         tensor.extract %{{.*}}[] : tensor<i32>
-// DET-CF:         cmpi slt, %{{.*}}, %{{.*}} : i32
-// DET-CF:         cf.cond_br %{{.*}}, ^bb2, ^bb3
-// DET-CF:       ^bb2:
-// DET-CF:         %{{.*}} = linalg.generic {{{.*}}} ins(%{{.*}} : tensor<i32>) outs(%{{.*}} : tensor<10xi32>) {
-// DET-CF:         cf.br ^bb1(%{{.*}} : tensor<10xi32>)
-// DET-CF:       ^bb3:
-// DET-CF:         return %{{.*}} : tensor<i32>
-// DET-CF:       }

diff  --git a/mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir b/mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir
deleted file mode 100644
index 913e78272db79..0000000000000
--- a/mlir/test/Dialect/Linalg/detensorize_while_pure_cf.mlir
+++ /dev/null
@@ -1,58 +0,0 @@
-// RUN: mlir-opt %s -allow-unregistered-dialect -pass-pipeline="builtin.module(func.func(linalg-detensorize))" | FileCheck %s
-
-#map0 = affine_map<() -> ()>
-
-#attrs = {
-  indexing_maps = [#map0, #map0, #map0],
-  iterator_types = []
-}
-
-func.func @main() -> () attributes {} {
-  %c0 = arith.constant 0 : i32
-  %0 = tensor.from_elements %c0 : tensor<1xi32>
-  %reshaped0 = tensor.collapse_shape %0 [] : tensor<1xi32> into tensor<i32>
-  %c10 = arith.constant 10 : i32
-  %1 = tensor.from_elements %c10 : tensor<1xi32>
-  %reshaped1 = tensor.collapse_shape %1 [] : tensor<1xi32> into tensor<i32>
-  cf.br ^bb1(%reshaped0 : tensor<i32>)
-
-^bb1(%2: tensor<i32>):  // 2 preds: ^bb0, ^bb2
-  %3 = tensor.empty() : tensor<i1>
-  %4 = linalg.generic #attrs
-    ins(%2, %reshaped1 : tensor<i32>, tensor<i32>)
-    outs(%3 : tensor<i1>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i1):
-      %8 = arith.cmpi slt, %arg0, %arg1 : i32
-      linalg.yield %8 : i1
-  } -> tensor<i1>
-  %5 = tensor.extract %4[] : tensor<i1>
-  cf.cond_br %5, ^bb2(%2 : tensor<i32>), ^bb3
-
-^bb2(%6: tensor<i32>):  // pred: ^bb1
-  %7 = tensor.empty() : tensor<i32>
-  %8 = linalg.generic #attrs
-    ins(%6, %6 : tensor<i32>, tensor<i32>)
-    outs(%7 : tensor<i32>) {
-    ^bb0(%arg0: i32, %arg1: i32, %arg2: i32):
-      %9 = arith.addi %arg0, %arg1 : i32
-      linalg.yield %9 : i32
-  } -> tensor<i32>
-  cf.br ^bb1(%8 : tensor<i32>)
-
-^bb3:  // pred: ^bb1
-  return
-}
-
-// CHECK-LABEL: func @main
-// CHECK-DAG:    arith.constant 0 : i32
-// CHECK-DAG:    arith.constant 10
-// CHECK-NEXT:    cf.br ^[[bb1:.*]](%{{.*}} : i32)
-// CHECK-NEXT:  ^[[bb1]](%{{.*}}: i32)
-// CHECK-NEXT:    %{{.*}} = arith.cmpi slt, %{{.*}}, %{{.*}}
-// CHECK-NEXT:    cf.cond_br %{{.*}}, ^[[bb2:.*]], ^[[bb3:.*]]
-// CHECK-NEXT:  ^[[bb2]]
-// CHECK-NEXT:    %{{.*}} = arith.addi %{{.*}}, %{{.*}}
-// CHECK-NEXT:    cf.br ^[[bb1]](%{{.*}} : i32)
-// CHECK-NEXT:  ^[[bb3]]:
-// CHECK-NEXT:    return
-// CHECK-NEXT:  }


        


More information about the Mlir-commits mailing list