[clang-tools-extra] [clang] [mlir] [llvm] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-15 Thread Han-Chung Wang via cfe-commits


@@ -362,14 +362,21 @@ mlir::scf::tileUsingSCFForOp(RewriterBase &rewriter, 
TilingInterface op,
   auto clonedOp = cast(
   cloneOpAndUpdateDestinationArgs(rewriter, op, clonedOpDestination));
 
-  // 5b. Tile the cloned operation.
+  // 5b. Early return cloned op if tiling is not happenning.
+  if (llvm::all_of(tileSizeVector,
+   [](OpFoldResult v) { return isZeroIndex(v); })) {

hanhanW wrote:

Really good point! 

https://github.com/llvm/llvm-project/pull/75410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [clang-tools-extra] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-15 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW updated 
https://github.com/llvm/llvm-project/pull/75410

>From c07f7e1c5c6f8bbc7189e96096004d39a0a1aa3f Mon Sep 17 00:00:00 2001
From: hanhanW 
Date: Wed, 13 Dec 2023 15:59:48 -0800
Subject: [PATCH 1/2] [mlir][TilingInterface] Early return cloned ops if tile
 sizes are zeros.

It is a trivial early-return case. If the cloned ops are not returned,
it will generate `extract_slice` op that extracts the whole slice.
However, it is not folded away. Early-return to avoid the case.

E.g.,

```mlir
func.func @matmul_tensors(
  %arg0: tensor, %arg1: tensor, %arg2: tensor)
-> tensor {
  %0 = linalg.matmul  ins(%arg0, %arg1: tensor, tensor)
 outs(%arg2: tensor)
-> tensor
  return %0 : tensor
}

module attributes {transform.with_named_sequence} {
  transform.named_sequence @__transform_main(%arg1: !transform.any_op 
{transform.readonly}) {
%0 = transform.structured.match ops{["linalg.matmul"]} in %arg1 : 
(!transform.any_op) -> !transform.any_op
%1 = transform.structured.tile_using_for %0 [0, 0, 0] : (!transform.any_op) 
-> (!transform.any_op)
transform.yield
  }
}
```

Apply the transforms and canonicalize the IR:

```
mlir-opt --transform-interpreter -canonicalize input.mlir
```

we will get

```mlir
module {
  func.func @matmul_tensors(%arg0: tensor, %arg1: tensor, 
%arg2: tensor) -> tensor {
%c1 = arith.constant 1 : index
%c0 = arith.constant 0 : index
%dim = tensor.dim %arg0, %c0 : tensor
%dim_0 = tensor.dim %arg0, %c1 : tensor
%dim_1 = tensor.dim %arg1, %c1 : tensor
%extracted_slice = tensor.extract_slice %arg0[0, 0] [%dim, %dim_0] [1, 1] : 
tensor to tensor
%extracted_slice_2 = tensor.extract_slice %arg1[0, 0] [%dim_0, %dim_1] [1, 
1] : tensor to tensor
%extracted_slice_3 = tensor.extract_slice %arg2[0, 0] [%dim, %dim_1] [1, 1] 
: tensor to tensor
%0 = linalg.matmul ins(%extracted_slice, %extracted_slice_2 : 
tensor, tensor) outs(%extracted_slice_3 : tensor) -> 
tensor
return %0 : tensor
  }
}
```
---
 .../SCF/Transforms/TileUsingInterface.cpp | 11 ++--
 mlir/test/Dialect/Linalg/tile-tensors.mlir| 27 +++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp 
b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
index 8057b3898012d4..20413aba8730be 100644
--- a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
@@ -362,14 +362,21 @@ mlir::scf::tileUsingSCFForOp(RewriterBase &rewriter, 
TilingInterface op,
   auto clonedOp = cast(
   cloneOpAndUpdateDestinationArgs(rewriter, op, clonedOpDestination));
 
-  // 5b. Tile the cloned operation.
+  // 5b. Early return cloned op if tiling is not happenning.
+  if (llvm::all_of(tileSizeVector,
+   [](OpFoldResult v) { return isZeroIndex(v); })) {
+return scf::SCFTilingResult{/*tiledOps=*/{clonedOp}, /*loops=*/{},
+clonedOp->getResults()};
+  }
+
+  // 5c. Tile the cloned operation.
   FailureOr tiledImplementation =
   clonedOp.getTiledImplementation(rewriter, offsets, sizes);
   if (failed(tiledImplementation)) {
 return rewriter.notifyMatchFailure(op, "failed to tile operation");
   }
 
-  // 5c. Delete the cloned operation.
+  // 5d. Delete the cloned operation.
   rewriter.eraseOp(clonedOp);
 
   // If loops are empty, the tiled op is used as the replacement for the 
untiled
diff --git a/mlir/test/Dialect/Linalg/tile-tensors.mlir 
b/mlir/test/Dialect/Linalg/tile-tensors.mlir
index e0429b1f873298..e8e63302286400 100644
--- a/mlir/test/Dialect/Linalg/tile-tensors.mlir
+++ b/mlir/test/Dialect/Linalg/tile-tensors.mlir
@@ -37,6 +37,33 @@ module attributes {transform.with_named_sequence} {
 
 // -
 
+// CHECK-LABEL: func @matmul_tensors_with_size_zeros(
+// CHECK-SAME:%[[TA:[0-9a-z]+]]: tensor
+// CHECK-SAME:%[[TB:[0-9a-z]+]]: tensor
+// CHECK-SAME:%[[TC:[0-9a-z]+]]: tensor) -> tensor {
+func.func @matmul_tensors_with_size_zeros(
+  %arg0: tensor, %arg1: tensor, %arg2: tensor)
+-> tensor {
+
+//  CHECK: %[[RES:.*]] = linalg.matmul ins(%[[TA]], %[[TB]] : 
tensor, tensor)
+// CHECK-SAME:outs(%[[TC]] : tensor)  
-> tensor
+//  CHECK: return %[[RES]]
+  %0 = linalg.matmul  ins(%arg0, %arg1: tensor, tensor)
+ outs(%arg2: tensor)
+-> tensor
+  return %0 : tensor
+}
+
+module attributes {transform.with_named_sequence} {
+  transform.named_sequence @__transform_main(%arg1: !transform.any_op 
{transform.readonly}) {
+%0 = transform.structured.match ops{["linalg.matmul"]} in %arg1 : 
(!transform.any_op) -> !transform.any_op
+%1 = transform.structured.tile_using_for %0 [0, 0, 0] : 
(!transform.any_op) -> (!transform.any_op)
+transform.yield
+  }
+}
+
+// -
+
 func.func @generic_op_tensors(
   %arg0 : tensor, %arg1 : tensor) -> tensor {
   %c0 = arit

[llvm] [clang] [clang-tools-extra] [mlir] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-18 Thread Han-Chung Wang via cfe-commits


@@ -362,14 +362,20 @@ mlir::scf::tileUsingSCFForOp(RewriterBase &rewriter, 
TilingInterface op,
   auto clonedOp = cast(
   cloneOpAndUpdateDestinationArgs(rewriter, op, clonedOpDestination));
 
-  // 5b. Tile the cloned operation.
+  // 5b. Early return cloned op if tiling is not happening.

hanhanW wrote:

I actually tried that, but it crashes about rewriter states. I did not dig into 
details because I have less experience about that...

https://github.com/llvm/llvm-project/pull/75410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [clang] [clang-tools-extra] [mlir] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-18 Thread Han-Chung Wang via cfe-commits


@@ -362,14 +362,20 @@ mlir::scf::tileUsingSCFForOp(RewriterBase &rewriter, 
TilingInterface op,
   auto clonedOp = cast(
   cloneOpAndUpdateDestinationArgs(rewriter, op, clonedOpDestination));
 
-  // 5b. Tile the cloned operation.
+  // 5b. Early return cloned op if tiling is not happening.

hanhanW wrote:

My take is that there are issues about replace op with itself. Do you want me 
to look into the crash further or add more comments to the code and commit?

https://github.com/llvm/llvm-project/pull/75410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [llvm] [mlir] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-18 Thread Han-Chung Wang via cfe-commits


@@ -362,14 +362,20 @@ mlir::scf::tileUsingSCFForOp(RewriterBase &rewriter, 
TilingInterface op,
   auto clonedOp = cast(
   cloneOpAndUpdateDestinationArgs(rewriter, op, clonedOpDestination));
 
-  // 5b. Tile the cloned operation.
+  // 5b. Early return cloned op if tiling is not happening.

hanhanW wrote:

I just tested it locally, and think it makes sense to return the cloned op. The 
suggestion will lead to `rewriter.replace(op, op->getResults())` and get the 
crash. Returning the cloned op instead of `op` itself or `failure` makes more 
sense in this case. I will add some comments to it.

https://github.com/llvm/llvm-project/pull/75410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [clang-tools-extra] [llvm] [mlir] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-18 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW updated 
https://github.com/llvm/llvm-project/pull/75410

>From c07f7e1c5c6f8bbc7189e96096004d39a0a1aa3f Mon Sep 17 00:00:00 2001
From: hanhanW 
Date: Wed, 13 Dec 2023 15:59:48 -0800
Subject: [PATCH 1/3] [mlir][TilingInterface] Early return cloned ops if tile
 sizes are zeros.

It is a trivial early-return case. If the cloned ops are not returned,
it will generate `extract_slice` op that extracts the whole slice.
However, it is not folded away. Early-return to avoid the case.

E.g.,

```mlir
func.func @matmul_tensors(
  %arg0: tensor, %arg1: tensor, %arg2: tensor)
-> tensor {
  %0 = linalg.matmul  ins(%arg0, %arg1: tensor, tensor)
 outs(%arg2: tensor)
-> tensor
  return %0 : tensor
}

module attributes {transform.with_named_sequence} {
  transform.named_sequence @__transform_main(%arg1: !transform.any_op 
{transform.readonly}) {
%0 = transform.structured.match ops{["linalg.matmul"]} in %arg1 : 
(!transform.any_op) -> !transform.any_op
%1 = transform.structured.tile_using_for %0 [0, 0, 0] : (!transform.any_op) 
-> (!transform.any_op)
transform.yield
  }
}
```

Apply the transforms and canonicalize the IR:

```
mlir-opt --transform-interpreter -canonicalize input.mlir
```

we will get

```mlir
module {
  func.func @matmul_tensors(%arg0: tensor, %arg1: tensor, 
%arg2: tensor) -> tensor {
%c1 = arith.constant 1 : index
%c0 = arith.constant 0 : index
%dim = tensor.dim %arg0, %c0 : tensor
%dim_0 = tensor.dim %arg0, %c1 : tensor
%dim_1 = tensor.dim %arg1, %c1 : tensor
%extracted_slice = tensor.extract_slice %arg0[0, 0] [%dim, %dim_0] [1, 1] : 
tensor to tensor
%extracted_slice_2 = tensor.extract_slice %arg1[0, 0] [%dim_0, %dim_1] [1, 
1] : tensor to tensor
%extracted_slice_3 = tensor.extract_slice %arg2[0, 0] [%dim, %dim_1] [1, 1] 
: tensor to tensor
%0 = linalg.matmul ins(%extracted_slice, %extracted_slice_2 : 
tensor, tensor) outs(%extracted_slice_3 : tensor) -> 
tensor
return %0 : tensor
  }
}
```
---
 .../SCF/Transforms/TileUsingInterface.cpp | 11 ++--
 mlir/test/Dialect/Linalg/tile-tensors.mlir| 27 +++
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp 
b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
index 8057b3898012d4..20413aba8730be 100644
--- a/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/TileUsingInterface.cpp
@@ -362,14 +362,21 @@ mlir::scf::tileUsingSCFForOp(RewriterBase &rewriter, 
TilingInterface op,
   auto clonedOp = cast(
   cloneOpAndUpdateDestinationArgs(rewriter, op, clonedOpDestination));
 
-  // 5b. Tile the cloned operation.
+  // 5b. Early return cloned op if tiling is not happenning.
+  if (llvm::all_of(tileSizeVector,
+   [](OpFoldResult v) { return isZeroIndex(v); })) {
+return scf::SCFTilingResult{/*tiledOps=*/{clonedOp}, /*loops=*/{},
+clonedOp->getResults()};
+  }
+
+  // 5c. Tile the cloned operation.
   FailureOr tiledImplementation =
   clonedOp.getTiledImplementation(rewriter, offsets, sizes);
   if (failed(tiledImplementation)) {
 return rewriter.notifyMatchFailure(op, "failed to tile operation");
   }
 
-  // 5c. Delete the cloned operation.
+  // 5d. Delete the cloned operation.
   rewriter.eraseOp(clonedOp);
 
   // If loops are empty, the tiled op is used as the replacement for the 
untiled
diff --git a/mlir/test/Dialect/Linalg/tile-tensors.mlir 
b/mlir/test/Dialect/Linalg/tile-tensors.mlir
index e0429b1f873298..e8e63302286400 100644
--- a/mlir/test/Dialect/Linalg/tile-tensors.mlir
+++ b/mlir/test/Dialect/Linalg/tile-tensors.mlir
@@ -37,6 +37,33 @@ module attributes {transform.with_named_sequence} {
 
 // -
 
+// CHECK-LABEL: func @matmul_tensors_with_size_zeros(
+// CHECK-SAME:%[[TA:[0-9a-z]+]]: tensor
+// CHECK-SAME:%[[TB:[0-9a-z]+]]: tensor
+// CHECK-SAME:%[[TC:[0-9a-z]+]]: tensor) -> tensor {
+func.func @matmul_tensors_with_size_zeros(
+  %arg0: tensor, %arg1: tensor, %arg2: tensor)
+-> tensor {
+
+//  CHECK: %[[RES:.*]] = linalg.matmul ins(%[[TA]], %[[TB]] : 
tensor, tensor)
+// CHECK-SAME:outs(%[[TC]] : tensor)  
-> tensor
+//  CHECK: return %[[RES]]
+  %0 = linalg.matmul  ins(%arg0, %arg1: tensor, tensor)
+ outs(%arg2: tensor)
+-> tensor
+  return %0 : tensor
+}
+
+module attributes {transform.with_named_sequence} {
+  transform.named_sequence @__transform_main(%arg1: !transform.any_op 
{transform.readonly}) {
+%0 = transform.structured.match ops{["linalg.matmul"]} in %arg1 : 
(!transform.any_op) -> !transform.any_op
+%1 = transform.structured.tile_using_for %0 [0, 0, 0] : 
(!transform.any_op) -> (!transform.any_op)
+transform.yield
+  }
+}
+
+// -
+
 func.func @generic_op_tensors(
   %arg0 : tensor, %arg1 : tensor) -> tensor {
   %c0 = arit

[mlir] [clang-tools-extra] [llvm] [clang] [mlir][TilingInterface] Early return cloned ops if tile sizes are zeros. (PR #75410)

2023-12-19 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW closed 
https://github.com/llvm/llvm-project/pull/75410
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [compiler-rt] [libc] [flang] [clang-tools-extra] [mlir] [llvm] [libcxx] [mlir][Linalg] Support dynamic tiles in `lower_pack` transform (PR #76003)

2024-01-04 Thread Han-Chung Wang via cfe-commits

hanhanW wrote:

I'm -1 on using `tensor.reshape` op. IMO, we should only use 
tensor.expand/collapse_shape; they work much better with existing 
transformations.

Out of curiosity, what use case do you have in mind? Why do we lower fully 
dynamic pack op? If it is at high level graph level, we can just use 
`tensor.pack` which carries more meaningful information. If it is at low level 
stage (e.g., around vectorization), I think the inner tile sizes should already 
be resolved to static values? In this context, we can still use 
`tensor.expand_shape`. It supports the case where one dynamic extent can be 
expanded into a single dynamic extent and other static extents (e.g., `? -> 
?x4`).

https://github.com/llvm/llvm-project/pull/76003
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [flang] [clang-tools-extra] [compiler-rt] [libc] [libcxx] [llvm] [mlir] [mlir][Linalg] Support dynamic tiles in `lower_pack` transform (PR #76003)

2024-01-04 Thread Han-Chung Wang via cfe-commits

hanhanW wrote:

> I am curious though, what do you mean by more powerful expand_shape op? 
> Wouldn't that just be exactly reshape? We don't need a more powerful 
> expand_shape to cover all the cases you mention above.

That could be tensor.reshape, but I don't see a scenario about using it. To be 
honest, I don't have an answer. Bailing out the case is fine to me. If someday 
people think it is needed, this will help bring up the discussion. To be clear, 
I am not saying that this is not useful. I just don't know why this is needed.

https://github.com/llvm/llvm-project/pull/76003
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[llvm] [lldb] [clang-tools-extra] [clang] [libunwind] [libc] [compiler-rt] [flang] [lld] [libclc] [mlir] [libcxx] [mlir][tensor] Enhance pack/unpack simplification for identity outer_dims_perm cases.

2024-01-10 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW updated 
https://github.com/llvm/llvm-project/pull/77409

>From e74b859897cdf1b1effbbd48a4e5376a231f7132 Mon Sep 17 00:00:00 2001
From: hanhanW 
Date: Mon, 8 Jan 2024 20:17:30 -0800
Subject: [PATCH 1/2] [mlir][tensor] Enhance pack/unpack simplication patterns
 for identity outer_dims_perm cases.

They can be simplified to reshape ops if outer_dims_perm is an identity
permutation. The revision adds a `isIdentityPermutation` method to
IndexingUtils.
---
 .../mlir/Dialect/Utils/IndexingUtils.h|  3 +++
 .../Dialect/Tensor/Transforms/CMakeLists.txt  |  1 +
 .../Transforms/PackAndUnpackPatterns.cpp  | 17 +
 mlir/lib/Dialect/Utils/IndexingUtils.cpp  |  8 +++
 .../Dialect/Tensor/simplify-pack-unpack.mlir  | 24 +++
 5 files changed, 48 insertions(+), 5 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Utils/IndexingUtils.h 
b/mlir/include/mlir/Dialect/Utils/IndexingUtils.h
index f51a8b28b7548e..2453d841f633e4 100644
--- a/mlir/include/mlir/Dialect/Utils/IndexingUtils.h
+++ b/mlir/include/mlir/Dialect/Utils/IndexingUtils.h
@@ -228,6 +228,9 @@ void applyPermutationToVector(SmallVector &inVec,
 /// Helper method to apply to inverse a permutation.
 SmallVector invertPermutationVector(ArrayRef permutation);
 
+/// Returns true if `permutation` is an identity permutation.
+bool isIdentityPermutation(ArrayRef permutation);
+
 /// Method to check if an interchange vector is a permutation.
 bool isPermutationVector(ArrayRef interchange);
 
diff --git a/mlir/lib/Dialect/Tensor/Transforms/CMakeLists.txt 
b/mlir/lib/Dialect/Tensor/Transforms/CMakeLists.txt
index cbc0d499d9d52c..c6ef6ed86e0d9d 100644
--- a/mlir/lib/Dialect/Tensor/Transforms/CMakeLists.txt
+++ b/mlir/lib/Dialect/Tensor/Transforms/CMakeLists.txt
@@ -27,6 +27,7 @@ add_mlir_dialect_library(MLIRTensorTransforms
   MLIRArithUtils
   MLIRBufferizationDialect
   MLIRBufferizationTransforms
+  MLIRDialectUtils
   MLIRIR
   MLIRLinalgDialect
   MLIRMemRefDialect
diff --git a/mlir/lib/Dialect/Tensor/Transforms/PackAndUnpackPatterns.cpp 
b/mlir/lib/Dialect/Tensor/Transforms/PackAndUnpackPatterns.cpp
index cfd838e85c1b80..2853cb8fe77a3b 100644
--- a/mlir/lib/Dialect/Tensor/Transforms/PackAndUnpackPatterns.cpp
+++ b/mlir/lib/Dialect/Tensor/Transforms/PackAndUnpackPatterns.cpp
@@ -9,6 +9,7 @@
 #include "mlir/Dialect/Linalg/IR/Linalg.h"
 #include "mlir/Dialect/Tensor/IR/Tensor.h"
 #include "mlir/Dialect/Tensor/Transforms/Transforms.h"
+#include "mlir/Dialect/Utils/IndexingUtils.h"
 #include "mlir/IR/PatternMatch.h"
 #include "llvm/Support/Debug.h"
 
@@ -38,8 +39,12 @@ struct SimplifyPackToExpandShape : public 
OpRewritePattern {
 if (packOp.getPaddingValue())
   return rewriter.notifyMatchFailure(packOp, "expects no padding value");
 
-if (!packOp.getOuterDimsPerm().empty())
-  return rewriter.notifyMatchFailure(packOp, "expects no outer_dims_perm");
+auto outerDimsPerm = packOp.getOuterDimsPerm();
+if (!outerDimsPerm.empty() && !isIdentityPermutation(outerDimsPerm)) {
+  return rewriter.notifyMatchFailure(
+  packOp,
+  "expects outer_dims_perm is empty or an identity permutation");
+}
 
 RankedTensorType sourceType = packOp.getSourceType();
 RankedTensorType destType = packOp.getDestType();
@@ -74,9 +79,11 @@ struct SimplifyUnPackToCollapseShape : public 
OpRewritePattern {
 
   LogicalResult matchAndRewrite(UnPackOp unpackOp,
 PatternRewriter &rewriter) const override {
-if (!unpackOp.getOuterDimsPerm().empty()) {
-  return rewriter.notifyMatchFailure(unpackOp,
- "expects no outer_dims_perm");
+auto outerDimsPerm = unpackOp.getOuterDimsPerm();
+if (!outerDimsPerm.empty() && !isIdentityPermutation(outerDimsPerm)) {
+  return rewriter.notifyMatchFailure(
+  unpackOp,
+  "expects outer_dims_perm is empty or an identity permutation");
 }
 
 RankedTensorType sourceType = unpackOp.getSourceType();
diff --git a/mlir/lib/Dialect/Utils/IndexingUtils.cpp 
b/mlir/lib/Dialect/Utils/IndexingUtils.cpp
index bb8a0d5912d7c1..f3de454dc4b81a 100644
--- a/mlir/lib/Dialect/Utils/IndexingUtils.cpp
+++ b/mlir/lib/Dialect/Utils/IndexingUtils.cpp
@@ -213,6 +213,14 @@ mlir::invertPermutationVector(ArrayRef 
permutation) {
   return inversion;
 }
 
+bool mlir::isIdentityPermutation(ArrayRef permutation) {
+  int n = permutation.size();
+  for (int i = 0; i < n; ++i)
+if (permutation[i] != i)
+  return false;
+  return true;
+}
+
 bool mlir::isPermutationVector(ArrayRef interchange) {
   assert(llvm::all_of(interchange, [](int64_t s) { return s >= 0; }) &&
  "permutation must be non-negative");
diff --git a/mlir/test/Dialect/Tensor/simplify-pack-unpack.mlir 
b/mlir/test/Dialect/Tensor/simplify-pack-unpack.mlir
index b78ab9bb3fd87e..ffbb2278a2e327 100644
--- a/mlir/test/Dialect/Tensor/simplify-pack-unpack.mlir
+++ b/mlir/test/Dialect/Tenso

[libcxx] [libc] [lld] [clang-tools-extra] [libclc] [lldb] [llvm] [clang] [compiler-rt] [flang] [mlir] [libunwind] [mlir][tensor] Enhance pack/unpack simplification for identity outer_dims_perm cases.

2024-01-10 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW closed 
https://github.com/llvm/llvm-project/pull/77409
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Reland "[mlir][arith] Canonicalization patterns for `arith.select` (#67809)" (PR #68941)

2023-10-13 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW updated 
https://github.com/llvm/llvm-project/pull/68941

>From 877111a139b2f01037fdbe7c0cb120a2f4e64562 Mon Sep 17 00:00:00 2001
From: hanhanW 
Date: Thu, 12 Oct 2023 17:14:29 -0700
Subject: [PATCH 1/2] Reland "[mlir][arith] Canonicalization patterns for
 `arith.select` (#67809)"

This cherry-picks the changes in
llvm-project/5bf701a6687a46fd898621f5077959ff202d716b with limiting
types to i1.
---
 .../Dialect/Arith/IR/ArithCanonicalization.td | 46 +++
 mlir/lib/Dialect/Arith/IR/ArithOps.cpp|  4 +-
 mlir/test/Dialect/Arith/canonicalize.mlir | 76 +++
 3 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td 
b/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td
index f3d84d0b261e8dd..817de0e06c661b9 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td
+++ b/mlir/lib/Dialect/Arith/IR/ArithCanonicalization.td
@@ -233,6 +233,52 @@ def CmpIExtUI :
 CPred<"$0.getValue() == arith::CmpIPredicate::eq || "
   "$0.getValue() == arith::CmpIPredicate::ne">> $pred)]>;
 
+//===--===//
+// SelectOp
+//===--===//
+
+// select(not(pred), a, b) => select(pred, b, a)
+def SelectNotCond :
+Pat<(SelectOp (Arith_XOrIOp $pred, (ConstantLikeMatcher APIntAttr:$ones)), 
$a, $b),
+(SelectOp $pred, $b, $a),
+[(IsScalarOrSplatNegativeOne $ones)]>;
+
+// select(pred, select(pred, a, b), c) => select(pred, a, c)
+def RedundantSelectTrue :
+Pat<(SelectOp $pred, (SelectOp $pred, $a, $b), $c),
+(SelectOp $pred, $a, $c)>;
+
+// select(pred, a, select(pred, b, c)) => select(pred, a, c)
+def RedundantSelectFalse :
+Pat<(SelectOp $pred, $a, (SelectOp $pred, $b, $c)),
+(SelectOp $pred, $a, $c)>;
+
+// select(predA, select(predB, x, y), y) => select(and(predA, predB), x, y)
+def SelectAndCond :
+Pat<(SelectOp $predA, (SelectOp $predB, $x, $y), $y),
+(SelectOp (Arith_AndIOp $predA, $predB), $x, $y)>;
+
+// select(predA, select(predB, y, x), y) => select(and(predA, not(predB)), x, 
y)
+def SelectAndNotCond :
+Pat<(SelectOp $predA, (SelectOp $predB, $y, $x), $y),
+(SelectOp (Arith_AndIOp $predA,
+(Arith_XOrIOp $predB, (Arith_ConstantOp 
ConstantAttr))),
+  $x, $y),
+[(Constraint> $predB)]>;
+
+// select(predA, x, select(predB, x, y)) => select(or(predA, predB), x, y)
+def SelectOrCond :
+Pat<(SelectOp $predA, $x, (SelectOp $predB, $x, $y)),
+(SelectOp (Arith_OrIOp $predA, $predB), $x, $y)>;
+
+// select(predA, x, select(predB, y, x)) => select(or(predA, not(predB)), x, y)
+def SelectOrNotCond :
+Pat<(SelectOp $predA, $x, (SelectOp $predB, $y, $x)),
+(SelectOp (Arith_OrIOp $predA,
+   (Arith_XOrIOp $predB, (Arith_ConstantOp 
ConstantAttr))),
+  $x, $y),
+[(Constraint> $predB)]>;
+
 
//===--===//
 // IndexCastOp
 
//===--===//
diff --git a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp 
b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
index ae8a6ef350ce191..0ecc288f3b07701 100644
--- a/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
+++ b/mlir/lib/Dialect/Arith/IR/ArithOps.cpp
@@ -2212,7 +2212,9 @@ struct SelectToExtUI : public 
OpRewritePattern {
 
 void arith::SelectOp::getCanonicalizationPatterns(RewritePatternSet &results,
   MLIRContext *context) {
-  results.add(context);
+  results.add(context);
 }
 
 OpFoldResult arith::SelectOp::fold(FoldAdaptor adaptor) {
diff --git a/mlir/test/Dialect/Arith/canonicalize.mlir 
b/mlir/test/Dialect/Arith/canonicalize.mlir
index f697f3d01458eee..1b0547c9e8f804a 100644
--- a/mlir/test/Dialect/Arith/canonicalize.mlir
+++ b/mlir/test/Dialect/Arith/canonicalize.mlir
@@ -128,6 +128,82 @@ func.func @selToArith(%arg0: i1, %arg1 : i1, %arg2 : i1) 
-> i1 {
   return %res : i1
 }
 
+// CHECK-LABEL: @redundantSelectTrue
+//   CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg1, %arg3
+//   CHECK-NEXT: return %[[res]]
+func.func @redundantSelectTrue(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : 
i32) -> i32 {
+  %0 = arith.select %arg0, %arg1, %arg2 : i32
+  %res = arith.select %arg0, %0, %arg3 : i32
+  return %res : i32
+}
+
+// CHECK-LABEL: @redundantSelectFalse
+//   CHECK-NEXT: %[[res:.+]] = arith.select %arg0, %arg3, %arg2
+//   CHECK-NEXT: return %[[res]]
+func.func @redundantSelectFalse(%arg0: i1, %arg1 : i32, %arg2 : i32, %arg3 : 
i32) -> i32 {
+  %0 = arith.select %arg0, %arg1, %arg2 : i32
+  %res = arith.select %arg0, %arg3, %0 : i32
+  return %res : i32
+}
+
+// CHECK-LABEL: @selNotCond
+//   CHECK-NEXT: %[[res1:.+]] = arith.select %arg0, %arg2, %arg1

[clang] Reland "[mlir][arith] Canonicalization patterns for `arith.select` (#67809)" (PR #68941)

2023-10-13 Thread Han-Chung Wang via cfe-commits


@@ -233,6 +233,52 @@ def CmpIExtUI :
 CPred<"$0.getValue() == arith::CmpIPredicate::eq || "
   "$0.getValue() == arith::CmpIPredicate::ne">> $pred)]>;
 
+//===--===//
+// SelectOp
+//===--===//
+
+// select(not(pred), a, b) => select(pred, b, a)
+def SelectNotCond :
+Pat<(SelectOp (Arith_XOrIOp $pred, (ConstantLikeMatcher APIntAttr:$ones)), 
$a, $b),
+(SelectOp $pred, $b, $a),
+[(IsScalarOrSplatNegativeOne $ones)]>;
+
+// select(pred, select(pred, a, b), c) => select(pred, a, c)
+def RedundantSelectTrue :
+Pat<(SelectOp $pred, (SelectOp $pred, $a, $b), $c),
+(SelectOp $pred, $a, $c)>;
+
+// select(pred, a, select(pred, b, c)) => select(pred, a, c)
+def RedundantSelectFalse :
+Pat<(SelectOp $pred, $a, (SelectOp $pred, $b, $c)),
+(SelectOp $pred, $a, $c)>;
+
+// select(predA, select(predB, x, y), y) => select(and(predA, predB), x, y)
+def SelectAndCond :
+Pat<(SelectOp $predA, (SelectOp $predB, $x, $y), $y),
+(SelectOp (Arith_AndIOp $predA, $predB), $x, $y)>;
+
+// select(predA, select(predB, y, x), y) => select(and(predA, not(predB)), x, 
y)
+def SelectAndNotCond :
+Pat<(SelectOp $predA, (SelectOp $predB, $y, $x), $y),
+(SelectOp (Arith_AndIOp $predA,
+(Arith_XOrIOp $predB, (Arith_ConstantOp 
ConstantAttr))),

hanhanW wrote:

done

https://github.com/llvm/llvm-project/pull/68941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Reland "[mlir][arith] Canonicalization patterns for `arith.select` (#67809)" (PR #68941)

2023-10-13 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW edited 
https://github.com/llvm/llvm-project/pull/68941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Reland "[mlir][arith] Canonicalization patterns for `arith.select` (#67809)" (PR #68941)

2023-10-13 Thread Han-Chung Wang via cfe-commits

hanhanW wrote:

thanks for the review!

https://github.com/llvm/llvm-project/pull/68941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] Reland "[mlir][arith] Canonicalization patterns for `arith.select` (#67809)" (PR #68941)

2023-10-13 Thread Han-Chung Wang via cfe-commits

https://github.com/hanhanW closed 
https://github.com/llvm/llvm-project/pull/68941
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [NVPTX] Convert vector function nvvm.annotations to attributes (PR #127736)

2025-02-25 Thread Han-Chung Wang via cfe-commits

hanhanW wrote:

Thanks for the heads-up! We do have few cases like:

```cpp
  setMetadataValueI32("maxntidx", workgroupSize[0]);
  setMetadataValueI32("maxntidy", workgroupSize[1]);
  setMetadataValueI32("maxntidz", workgroupSize[2]);

https://github.com/llvm/llvm-project/pull/127736
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [llvm] [mlir] [NVPTX] Convert vector function nvvm.annotations to attributes (PR #127736)

2025-02-25 Thread Han-Chung Wang via cfe-commits

hanhanW wrote:

> > I think they will become something like:
> > ```c++
> > llvmFunc->addFnAttr("nvvm.maxntid", llvm::utostr(workgroupSize[0]));
> > llvmFunc->addFnAttr("nvvm.maxntid", llvm::utostr(workgroupSize[1]));
> > llvmFunc->addFnAttr("nvvm.maxntid", llvm::utostr(workgroupSize[2]));
> > ```
> 
> Not quite, this would successively overwrite the "nvvm.maxntid" attribute 
> three times. I think something like this should work:
> 
> ```c++
> std::string maxntid = llvm::formatv("{0},{1},{2}", workgroupSize[0], 
> workgroupSize[1], workgroupSize[2]);
> llvmFunc->addFnAttr("nvvm.maxntid", maxntid)
> ```

I see, thanks!

https://github.com/llvm/llvm-project/pull/127736
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits