[Mlir-commits] [mlir] [MLIR][Linalg] Remove linalg.select op (PR #215608)
Renato Golin
llvmlistbot at llvm.org
Fri Aug 28 06:06:18 PDT 2026
https://github.com/rengolin updated https://github.com/llvm/llvm-project/pull/215608
>From 35b95ce332d842f2c976fa6b177fd2e3090069fe Mon Sep 17 00:00:00 2001
From: Renato Golin <rengolin at systemcall.eu>
Date: Tue, 11 Aug 2026 17:11:26 +0100
Subject: [PATCH] [MLIR][Linalg] Remove linalg.select op
Removes the named op `select` from the Linalg dialect. This is an
initial PR following the RFC in the forum:
https://discourse.llvm.org/t/rfc-update-semantics-of-linalg-named-operations-unary-binary-ternary/91531
I have also update the ElementwiseOp builder to simplify the default
case: kind + no affine map.
As a first approach, these are the things we'll need to do to all ops:
1. Remove from OpDSL (yaml / python)
2. Remove from morphism transforms (-to-named & named-to-)
3. Replace all uses of linalg::XOp::create with
linalg::ElementwiseOp::create
4. Update affected transforms to match elementwise instead of named ops
5. Update affected tests
---
.../Linalg/IR/LinalgNamedStructuredOps.yaml | 57 -------------------
.../Dialect/Linalg/IR/LinalgStructuredOps.td | 16 +++++-
.../Conversion/TosaToLinalg/TosaToLinalg.cpp | 3 +-
.../Linalg/Transforms/CategoryToNamedOp.cpp | 2 -
.../Linalg/Transforms/NamedToElementwise.cpp | 2 -
.../Dialect/Linalg/Transforms/Specialize.cpp | 3 +-
.../linalg/opdsl/ops/core_named_ops.py | 20 -------
.../elementwise/named-to-elementwise.mlir | 18 ------
.../Dialect/Linalg/generalize-named-ops.mlir | 27 ---------
.../linalg-morph-elementwise-to-named.mlir | 18 ------
mlir/test/Dialect/Linalg/named-ops-fail.mlir | 49 ----------------
mlir/test/Dialect/Linalg/named-ops.mlir | 48 ----------------
12 files changed, 16 insertions(+), 247 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml b/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
index 521afc991063f..12b80760fd2ae 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgNamedStructuredOps.yaml
@@ -894,63 +894,6 @@ structured_op: !LinalgStructuredOpConfig
- !ScalarExpression
scalar_arg: rhs
--- !LinalgOpConfig
-metadata: !LinalgOpMetadata
- name: select
- cpp_class_name: SelectOp
- doc: |-
- Chooses one value based on a binary condition supplied as its first operand.
-
- The shapes and element types must be identical. The appropriate casts,
- broadcasts and reductions should be done previously to calling this op.
-
- This means reduction/broadcast/element cast semantics is explicit. Further
- passes can take that into account when lowering this code. For example,
- a `linalg.broadcast` + `linalg.select` sequence can be lowered to a
- `linalg.generic` with different affine maps for the two operands.
-structured_op: !LinalgStructuredOpConfig
- args:
- - !LinalgOperandDefConfig
- name: cond
- kind: input_tensor
- type_var: U
- shape_map: affine_map<() -> ()>
- - !LinalgOperandDefConfig
- name: lhs
- kind: input_tensor
- type_var: T1
- shape_map: affine_map<() -> ()>
- - !LinalgOperandDefConfig
- name: rhs
- kind: input_tensor
- type_var: T1
- shape_map: affine_map<() -> ()>
- - !LinalgOperandDefConfig
- name: O
- kind: output_tensor
- type_var: T1
- shape_map: affine_map<() -> ()>
- indexing_maps: !LinalgIndexingMapsConfig
- static_indexing_maps:
- - affine_map<() -> ()>
- - affine_map<() -> ()>
- - affine_map<() -> ()>
- - affine_map<() -> ()>
- iterator_types: []
- assignments:
- - !ScalarAssign
- arg: O
- value: !ScalarExpression
- scalar_fn:
- kind: ternary
- fn_name: select
- operands:
- - !ScalarExpression
- scalar_arg: cond
- - !ScalarExpression
- scalar_arg: lhs
- - !ScalarExpression
- scalar_arg: rhs
---- !LinalgOpConfig
metadata: !LinalgOpMetadata
name: quantized_matmul
cpp_class_name: QuantizedMatmulOp
diff --git a/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td b/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
index 51bfcbec5d1a4..37ed9ea6b8a11 100644
--- a/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
+++ b/mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOps.td
@@ -609,11 +609,21 @@ def ElementwiseOp : LinalgStructuredBase_Op<"elementwise", [
}]>,
OpBuilder<(ins "ValueRange":$inputs, "ValueRange":$outputs,
- "ElementwiseKindAttr":$kind,
- "ArrayAttr":$indexingMaps,
+ "ElementwiseKind":$kind,
+ CArg<"ArrayAttr", "{}">:$indexingMaps,
CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
[{
- $_state.addAttribute("kind", kind);
+ assert((unsigned)kind <= getMaxEnumValForElementwiseKind() &&
+ "expected a valid elementwise kind attribute");
+ ElementwiseKindAttr kindAttr = ElementwiseKindAttr::get($_builder.getContext(), kind);
+ $_state.addAttribute("kind", kindAttr);
+ if (!indexingMaps) {
+ auto affineMaps = ElementwiseOp::getDefaultIndexingMaps(
+ inputs.size() + outputs.size(),
+ llvm::cast<ShapedType>(outputs[0].getType()).getRank(),
+ $_builder.getContext());
+ indexingMaps = $_builder.getAffineMapArrayAttr(affineMaps);
+ }
$_state.addAttribute("indexing_maps", indexingMaps);
buildStructuredOp($_builder, $_state, std::nullopt, inputs, outputs,
attributes, ElementwiseOp::getRegionBuilder());
diff --git a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
index b7eb0a3aed546..cebf40bbe2c38 100644
--- a/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
+++ b/mlir/lib/Conversion/TosaToLinalg/TosaToLinalg.cpp
@@ -1321,7 +1321,8 @@ static LogicalResult reduceMatchAndRewriteHelper(OpTy op, uint64_t axis,
ins.push_back(linalgOp->getResult(0));
outs.push_back(finalEmptyTensor);
auto linalgSelect =
- linalg::SelectOp::create(rewriter, op->getLoc(), ins, outs);
+ linalg::ElementwiseOp::create(rewriter, op->getLoc(), ins, outs,
+ mlir::linalg::ElementwiseKind::select);
linalgOp = linalgSelect;
}
diff --git a/mlir/lib/Dialect/Linalg/Transforms/CategoryToNamedOp.cpp b/mlir/lib/Dialect/Linalg/Transforms/CategoryToNamedOp.cpp
index 6d1f61100dbf5..35a35d8da1a01 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/CategoryToNamedOp.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/CategoryToNamedOp.cpp
@@ -88,8 +88,6 @@ struct ElementwiseToNamedPattern : public OpRewritePattern<ElementwiseOp> {
return replaceWith(MinOp{});
case ElementwiseKind::powf:
return replaceWith(PowFOp{});
- case ElementwiseKind::select:
- return replaceWith(SelectOp{});
default:
return failure();
}
diff --git a/mlir/lib/Dialect/Linalg/Transforms/NamedToElementwise.cpp b/mlir/lib/Dialect/Linalg/Transforms/NamedToElementwise.cpp
index c9045566473cb..f75633379ac77 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/NamedToElementwise.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/NamedToElementwise.cpp
@@ -28,7 +28,6 @@ using namespace mlir::linalg;
namespace {
ElementwiseKind getKind(Operation *op) {
return llvm::TypeSwitch<Operation *, ElementwiseKind>(op)
- .Case([](SelectOp) { return ElementwiseKind::select; })
.Case([](AddOp) { return ElementwiseKind::add; })
.Case([](SubOp) { return ElementwiseKind::sub; })
.Case([](MulOp) { return ElementwiseKind::mul; })
@@ -72,7 +71,6 @@ struct NamedToElementwisePattern : public OpRewritePattern<NamedOpTy> {
void mlir::linalg::populateLinalgNamedToElementwisePatterns(
RewritePatternSet &patterns) {
- patterns.add<NamedToElementwisePattern<SelectOp>>(patterns.getContext());
patterns.add<NamedToElementwisePattern<AddOp>>(patterns.getContext());
patterns.add<NamedToElementwisePattern<SubOp>>(patterns.getContext());
patterns.add<NamedToElementwisePattern<MulOp>>(patterns.getContext());
diff --git a/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp b/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
index 1bdcd0be31329..65200d3322af5 100644
--- a/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
+++ b/mlir/lib/Dialect/Linalg/Transforms/Specialize.cpp
@@ -181,8 +181,7 @@ static FailureOr<LinalgOp> specializeLinalgElementwise(RewriterBase &rewriter,
scalarBroadcastMap);
}
newOp = ElementwiseOp::create(
- rewriter, genericOp.getLoc(), inputs, genericOp.getDpsInits(),
- ElementwiseKindAttr::get(rewriter.getContext(), kind),
+ rewriter, genericOp.getLoc(), inputs, genericOp.getDpsInits(), kind,
rewriter.getAffineMapArrayAttr(indexingMaps));
}
diff --git a/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py b/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
index 9c24f94fcf612..e056c354e7e7e 100644
--- a/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
+++ b/mlir/python/mlir/dialects/linalg/opdsl/ops/core_named_ops.py
@@ -332,26 +332,6 @@ def powf(
O[None] = BinaryFn.powf(lhs[None], rhs[None])
- at linalg_structured_op
-def select(
- cond=TensorDef(U),
- lhs=TensorDef(T1),
- rhs=TensorDef(T1),
- O=TensorDef(T1, output=True),
-):
- """Chooses one value based on a binary condition supplied as its first operand.
-
- The shapes and element types must be identical. The appropriate casts,
- broadcasts and reductions should be done previously to calling this op.
-
- This means reduction/broadcast/element cast semantics is explicit. Further
- passes can take that into account when lowering this code. For example,
- a `linalg.broadcast` + `linalg.select` sequence can be lowered to a
- `linalg.generic` with different affine maps for the two operands.
- """
- O[None] = TernaryFn.select(cond[None], lhs[None], rhs[None])
-
-
@linalg_structured_op
def quantized_matmul(
A=TensorDef(T1, S.M, S.K),
diff --git a/mlir/test/Dialect/Linalg/elementwise/named-to-elementwise.mlir b/mlir/test/Dialect/Linalg/elementwise/named-to-elementwise.mlir
index 2332b287ace8d..dd7c9e99161c5 100644
--- a/mlir/test/Dialect/Linalg/elementwise/named-to-elementwise.mlir
+++ b/mlir/test/Dialect/Linalg/elementwise/named-to-elementwise.mlir
@@ -36,21 +36,3 @@ func.func @sub(%A : tensor<16x8xf32>, %B: tensor<16x8xf32>, %C : tensor<16x8xf32
%sub = linalg.sub ins(%A, %B : tensor<16x8xf32>, tensor<16x8xf32>) outs(%C : tensor<16x8xf32>) -> tensor<16x8xf32>
return %sub : tensor<16x8xf32>
}
-
-// ----
-
-// CHECK: @ternary_select(%[[A:.+]]: tensor<4x8x16xi1>, %[[B:.+]]: tensor<4x8x16xf32>, %[[C:.+]]: tensor<4x8x16xf32>)
-// CHECK: %[[E:.+]] = tensor.empty() : tensor<4x8x16xf32>
-// CHECK: {{.*}} = linalg.elementwise
-// CHECK-SAME: kind=#linalg.elementwise_kind<select>
-// CHECK-SAME: ins(%[[A]], %[[B]], %[[C]] : tensor<4x8x16xi1>, tensor<4x8x16xf32>, tensor<4x8x16xf32>)
-// CHECK-SAME: outs(%[[E]] : tensor<4x8x16xf32>) -> tensor<4x8x16xf32>
-//
-func.func @ternary_select(%A: tensor<4x8x16xi1>, %B: tensor<4x8x16xf32>, %C: tensor<4x8x16xf32>)
- -> tensor<4x8x16xf32> {
- %empty = tensor.empty() : tensor<4x8x16xf32>
- %select = linalg.select
- ins(%A, %B, %C : tensor<4x8x16xi1>, tensor<4x8x16xf32>, tensor<4x8x16xf32>)
- outs(%empty: tensor<4x8x16xf32>) -> tensor<4x8x16xf32>
- return %select : tensor<4x8x16xf32>
-}
diff --git a/mlir/test/Dialect/Linalg/generalize-named-ops.mlir b/mlir/test/Dialect/Linalg/generalize-named-ops.mlir
index e346bee901f1d..fb4c82715be48 100644
--- a/mlir/test/Dialect/Linalg/generalize-named-ops.mlir
+++ b/mlir/test/Dialect/Linalg/generalize-named-ops.mlir
@@ -880,33 +880,6 @@ func.func @generalize_powf(%lhs: memref<7x14x21xf32>, %rhs: memref<7x14x21xf32>,
// CHECK-NEXT: %[[powf:.+]] = math.powf %[[BBARG0]], %[[BBARG1]] : f32
// CHECK-NEXT: linalg.yield %[[powf]] : f32
-
-// -----
-
-func.func @generalize_select(%cond: memref<7x14x21xi1>, %lhs: memref<7x14x21xf32>, %rhs: memref<7x14x21xf32>,
- %out: memref<7x14x21xf32>) {
- linalg.select ins(%cond, %lhs, %rhs: memref<7x14x21xi1>, memref<7x14x21xf32>, memref<7x14x21xf32>)
- outs(%out: memref<7x14x21xf32>)
- return
-}
-
-// CHECK: #[[MAP:.+]] = affine_map<(d0, d1, d2) -> (d0, d1, d2)>
-
-// CHECK: func @generalize_select
-// CHECK-SAME: (%[[COND:.+]]: memref<7x14x21xi1>, %[[LHS:.+]]: memref<7x14x21xf32>, %[[RHS:.+]]: memref<7x14x21xf32>,
-// CHECK-SAME: %[[OUT:.+]]: memref<7x14x21xf32>)
-
-// CHECK: linalg.generic
-// CHECK-SAME: indexing_maps = [#[[MAP]], #[[MAP]], #[[MAP]], #[[MAP]]]
-// CHECK-SAME: iterator_types = ["parallel", "parallel", "parallel"]}
-// CHECK-SAME: ins(%[[COND]], %[[LHS]], %[[RHS]] : memref<7x14x21xi1>, memref<7x14x21xf32>, memref<7x14x21xf32>)
-// CHECK-SAME: outs(%[[OUT]] : memref<7x14x21xf32>)
-
-// CHECK: ^{{.+}}(%[[BBARG0:.+]]: i1, %[[BBARG1:.+]]: f32, %[[BBARG2:.+]]: f32, %[[BBARG3:.+]]: f32)
-// CHECK-NEXT: %[[select:.+]] = arith.select %[[BBARG0]], %[[BBARG1]], %[[BBARG2]] : f32
-// CHECK-NEXT: linalg.yield %[[select]] : f32
-
-
// -----
// CHECK-LABEL: func @fill_tensor
diff --git a/mlir/test/Dialect/Linalg/linalg-morph-elementwise-to-named.mlir b/mlir/test/Dialect/Linalg/linalg-morph-elementwise-to-named.mlir
index 82365f5de8f92..00fb62629331f 100644
--- a/mlir/test/Dialect/Linalg/linalg-morph-elementwise-to-named.mlir
+++ b/mlir/test/Dialect/Linalg/linalg-morph-elementwise-to-named.mlir
@@ -189,24 +189,6 @@ func.func @binary_ops_float(%A: tensor<?x?xf32>, %B: tensor<?x?xf32>,
// -----
-func.func @ternary_select(%A: tensor<?x?xi1>, %B: tensor<?x?xf32>,
- %C: tensor<?x?xf32>,
- %Out: tensor<?x?xf32>) -> tensor<?x?xf32> {
- %0 = linalg.elementwise kind=#linalg.elementwise_kind<select>
- ins(%A, %B, %C : tensor<?x?xi1>, tensor<?x?xf32>, tensor<?x?xf32>)
- outs(%Out : tensor<?x?xf32>) -> tensor<?x?xf32>
- return %0 : tensor<?x?xf32>
-}
-
-// CHECK-LABEL: ternary_select
-// CHECK-SAME: %[[A:.+]]: tensor<?x?xi1>, %[[B:.+]]: tensor<?x?xf32>, %[[C:.+]]: tensor<?x?xf32>, %[[OUT:.+]]: tensor<?x?xf32>)
-// CHECK-NOT: linalg.elementwise
-// CHECK: linalg.select
-// CHECK-SAME: ins(%[[A]], %[[B]], %[[C]] : tensor<?x?xi1>, tensor<?x?xf32>, tensor<?x?xf32>)
-// CHECK-SAME: outs(%[[OUT]] : tensor<?x?xf32>) -> tensor<?x?xf32>
-
-// -----
-
// Non-identity indexing maps: should NOT be converted to named op.
func.func @non_identity_maps(%A: tensor<?xf32>, %Out: tensor<?x?xf32>) -> tensor<?x?xf32> {
%0 = linalg.elementwise
diff --git a/mlir/test/Dialect/Linalg/named-ops-fail.mlir b/mlir/test/Dialect/Linalg/named-ops-fail.mlir
index bf9c1b705f157..efb7f771184f3 100644
--- a/mlir/test/Dialect/Linalg/named-ops-fail.mlir
+++ b/mlir/test/Dialect/Linalg/named-ops-fail.mlir
@@ -333,52 +333,3 @@ func.func @powf_broadcast(%arg0: memref<8x16xf32>, %arg1: memref<4x8x16xf32>, %a
linalg.powf ins(%arg0, %arg1 : memref<8x16xf32>, memref<4x8x16xf32>) outs(%arg2: memref<4x8x16xf32>)
return
}
-
-// -----
-
-func.func @select_type_cast(%arg0: memref<4x8x16xi1>, %arg1: memref<4x8x16xf16>, %arg2: memref<4x8x16xf32>, %arg3: memref<4x8x16xf32>) {
- // CHECK: op failed to verify that all of {true_value, false_value, result} have same type
- linalg.select ins(%arg0, %arg1, %arg2 : memref<4x8x16xi1>, memref<4x8x16xf16>, memref<4x8x16xf32>) outs(%arg3: memref<4x8x16xf32>)
- return
-}
-
-// -----
-
-func.func @select_wrong_condition_type(%arg0: memref<4x8x16xf32>, %arg1: memref<4x8x16xf32>, %arg2: memref<4x8x16xf32>, %arg3: memref<4x8x16xf32>) {
- // CHECK: op operand #0 must be bool-like, but got 'f32'
- linalg.select ins(%arg0, %arg1, %arg2 : memref<4x8x16xf32>, memref<4x8x16xf32>, memref<4x8x16xf32>) outs(%arg3: memref<4x8x16xf32>)
- return
-}
-
-// -----
-
-// linalg.select with all-integer operands
-func.func @select_all_integer(%arg0: memref<4x8x16xi32>, %arg1: memref<4x8x16xi32>, %arg2: memref<4x8x16xi32>, %arg3: memref<4x8x16xi32>) {
- // CHECK: op operand #0 must be bool-like, but got 'i32'
- linalg.select ins(%arg0, %arg1, %arg2 : memref<4x8x16xi32>, memref<4x8x16xi32>, memref<4x8x16xi32>) outs(%arg3: memref<4x8x16xi32>)
- return
-}
-
-// -----
-
-// Regression test: linalg.select with index type operands should emit a
-// diagnostic instead of crashing (https://github.com/llvm/llvm-project/issues/179046).
-func.func @select_invalid_index_type(%cond: index, %a: index, %b: index,
- %out: tensor<1xindex>) -> tensor<1xindex> {
- // CHECK: op operand #0 must be bool-like, but got 'index'
- %0 = linalg.select ins(%cond, %a, %b : index, index, index)
- outs(%out : tensor<1xindex>) -> tensor<1xindex>
- return %0 : tensor<1xindex>
-}
-
-// -----
-
-// linalg.select with an integer (non-i1) condition and floating-point values:
-func.func @select_invalid_integer_cond_float_values(%cond: tensor<4xi32>,
- %a: tensor<4xf32>, %b: tensor<4xf32>,
- %out: tensor<4xf32>) -> tensor<4xf32> {
-// CHECK: op operand #0 must be bool-like, but got 'i32'
- %0 = linalg.select ins(%cond, %a, %b : tensor<4xi32>, tensor<4xf32>, tensor<4xf32>)
- outs(%out : tensor<4xf32>) -> tensor<4xf32>
- return %0 : tensor<4xf32>
-}
diff --git a/mlir/test/Dialect/Linalg/named-ops.mlir b/mlir/test/Dialect/Linalg/named-ops.mlir
index 8068c23a4a0fd..d53dc737f678c 100644
--- a/mlir/test/Dialect/Linalg/named-ops.mlir
+++ b/mlir/test/Dialect/Linalg/named-ops.mlir
@@ -2684,54 +2684,6 @@ func.func @fill_tensor(%f: f32, %v: vector<2x4xf32>) -> (tensor<f32>, tensor<vec
return %0, %1: tensor<f32>, tensor<vector<2x4xf32>>
}
-// -----
-
-// CHECK-LABEL: func @select_dynamic
-func.func @select_dynamic(%arg0: memref<?x?x?xi1>, %arg1: memref<?x?x?xf32>, %arg2: memref<?x?x?xf32>, %arg3: memref<?x?x?xf32>) {
- // CHECK: linalg.select
- // CHECK-SAME: ins(%{{.+}}, %{{.+}}, %{{.+}} : memref<?x?x?xi1>, memref<?x?x?xf32>, memref<?x?x?xf32>)
- // CHECK-SAME: outs(%{{.+}} : memref<?x?x?xf32>)
- linalg.select ins(%arg0, %arg1, %arg2 : memref<?x?x?xi1>, memref<?x?x?xf32>, memref<?x?x?xf32>) outs(%arg3: memref<?x?x?xf32>)
- return
-}
-
-// -----
-
-// CHECK-LABEL: func @select_static
-func.func @select_static(%arg0: memref<4x8x16xi1>, %arg1: memref<4x8x16xf32>, %arg2: memref<4x8x16xf32>, %arg3: memref<4x8x16xf32>) {
- // CHECK: linalg.select
- // CHECK-SAME: ins(%{{.+}}, %{{.+}}, %{{.+}} : memref<4x8x16xi1>, memref<4x8x16xf32>, memref<4x8x16xf32>)
- // CHECK-SAME: outs(%{{.+}} : memref<4x8x16xf32>)
- linalg.select ins(%arg0, %arg1, %arg2 : memref<4x8x16xi1>, memref<4x8x16xf32>, memref<4x8x16xf32>) outs(%arg3: memref<4x8x16xf32>)
- return
-}
-
-// -----
-
-// CHECK-LABEL: func @select_tensor
-func.func @select_tensor(%arg0: tensor<4x8x16xi1>, %arg1: tensor<4x8x16xf32>, %arg2: tensor<4x8x16xf32>) -> tensor<4x8x16xf32> {
- %0 = tensor.empty() : tensor<4x8x16xf32>
- // CHECK: linalg.select
- // CHECK-SAME: ins(%{{.+}}, %{{.+}}, %{{.+}} : tensor<4x8x16xi1>, tensor<4x8x16xf32>, tensor<4x8x16xf32>)
- // CHECK-SAME: outs(%{{.+}} : tensor<4x8x16xf32>)
- %1 = linalg.select ins(%arg0, %arg1, %arg2 : tensor<4x8x16xi1>, tensor<4x8x16xf32>, tensor<4x8x16xf32>) outs(%0: tensor<4x8x16xf32>) -> tensor<4x8x16xf32>
- return %1 : tensor<4x8x16xf32>
-}
-
-// -----
-
-// CHECK-LABEL: func @select_integer_values
-// linalg.select with i1 condition and integer values: headBool=true (i1 bitwidth==1)
-// → valid, arith.select accepts i1 as condition regardless of value types.
-func.func @select_integer_values(%arg0: tensor<4x8x16xi1>, %arg1: tensor<4x8x16xi32>, %arg2: tensor<4x8x16xi32>) -> tensor<4x8x16xi32> {
- %0 = tensor.empty() : tensor<4x8x16xi32>
- // CHECK: linalg.select
- // CHECK-SAME: ins(%{{.+}}, %{{.+}}, %{{.+}} : tensor<4x8x16xi1>, tensor<4x8x16xi32>, tensor<4x8x16xi32>)
- // CHECK-SAME: outs(%{{.+}} : tensor<4x8x16xi32>)
- %1 = linalg.select ins(%arg0, %arg1, %arg2 : tensor<4x8x16xi1>, tensor<4x8x16xi32>, tensor<4x8x16xi32>) outs(%0: tensor<4x8x16xi32>) -> tensor<4x8x16xi32>
- return %1 : tensor<4x8x16xi32>
-}
-
//===----------------------------------------------------------------------===//
// linalg.pack + linalg.unpack
//===----------------------------------------------------------------------===//
More information about the Mlir-commits
mailing list