[Mlir-commits] [mlir] [MLIR] Fuse locations of hoisted / merged constants (PR #74670)

Billy Zhu llvmlistbot at llvm.org
Fri Dec 8 15:40:34 PST 2023


https://github.com/zyx-billy updated https://github.com/llvm/llvm-project/pull/74670

>From 90c1e7b4c9a65cff7724775fc7fc4fbcac0a3e2c Mon Sep 17 00:00:00 2001
From: Billy Zhu <billyzhu at modular.com>
Date: Wed, 6 Dec 2023 13:10:57 -0800
Subject: [PATCH 1/4] fuse locations for hoisted and merged constants

---
 mlir/lib/Transforms/Utils/FoldUtils.cpp       | 54 +++++++++++++++++--
 .../Transforms/canonicalize-debuginfo.mlir    | 42 +++++++++++++++
 2 files changed, 91 insertions(+), 5 deletions(-)
 create mode 100644 mlir/test/Transforms/canonicalize-debuginfo.mlir

diff --git a/mlir/lib/Transforms/Utils/FoldUtils.cpp b/mlir/lib/Transforms/Utils/FoldUtils.cpp
index 90ee5ba51de3ad..23fcb4796892d6 100644
--- a/mlir/lib/Transforms/Utils/FoldUtils.cpp
+++ b/mlir/lib/Transforms/Utils/FoldUtils.cpp
@@ -19,6 +19,38 @@
 
 using namespace mlir;
 
+// Fuse `foldedLocation` into the Location of `retainedOp`.
+// This will result in `retainedOp` having a FusedLoc with a StringAttr tag
+// "OpFold" to help trace the source of the fusion. If `retainedOp` already had
+// a FusedLoc with the same tag, `foldedLocation` will simply be appended to it.
+// Usage:
+// - When an op is deduplicated, fuse the location of the op to be removed into
+//   the op that is retained.
+// - When an op is hoisted to the front/back of a block, fuse the location of
+//   the parent region of the block into the hoisted op.
+static void appendFoldedLocation(Operation *retainedOp,
+                                 Location foldedLocation) {
+  constexpr std::string_view tag = "OpFold";
+  // Append into existing fused location if it has the same tag.
+  if (auto existingFusedLoc =
+          retainedOp->getLoc().dyn_cast<FusedLocWith<StringAttr>>()) {
+    StringAttr existingMetadata = existingFusedLoc.getMetadata();
+    if (existingMetadata.strref().equals(tag)) {
+      SmallVector<Location> locations(existingFusedLoc.getLocations());
+      locations.push_back(foldedLocation);
+      Location newFusedLoc =
+          FusedLoc::get(retainedOp->getContext(), locations, existingMetadata);
+      retainedOp->setLoc(newFusedLoc);
+      return;
+    }
+  }
+  // Create a new fusedloc with retainedOp's loc and foldedLocation.
+  Location newFusedLoc = FusedLoc::get(
+      retainedOp->getContext(), {retainedOp->getLoc(), foldedLocation},
+      StringAttr::get(retainedOp->getContext(), tag));
+  retainedOp->setLoc(newFusedLoc);
+}
+
 /// Given an operation, find the parent region that folded constants should be
 /// inserted into.
 static Region *
@@ -77,8 +109,10 @@ LogicalResult OperationFolder::tryToFold(Operation *op, bool *inPlaceUpdate) {
     // Check to see if we should rehoist, i.e. if a non-constant operation was
     // inserted before this one.
     Block *opBlock = op->getBlock();
-    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode()))
+    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode())) {
       op->moveBefore(&opBlock->front());
+      appendFoldedLocation(op, opBlock->getParent()->getLoc());
+    }
     return failure();
   }
 
@@ -112,8 +146,10 @@ bool OperationFolder::insertKnownConstant(Operation *op, Attribute constValue) {
   // If this is a constant we unique'd, we don't need to insert, but we can
   // check to see if we should rehoist it.
   if (isFolderOwnedConstant(op)) {
-    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode()))
+    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode())) {
       op->moveBefore(&opBlock->front());
+      appendFoldedLocation(op, opBlock->getParent()->getLoc());
+    }
     return true;
   }
 
@@ -141,6 +177,7 @@ bool OperationFolder::insertKnownConstant(Operation *op, Attribute constValue) {
   // If there is an existing constant, replace `op`.
   if (folderConstOp) {
     notifyRemoval(op);
+    appendFoldedLocation(folderConstOp, op->getLoc());
     rewriter.replaceOp(op, folderConstOp->getResults());
     return false;
   }
@@ -151,8 +188,10 @@ bool OperationFolder::insertKnownConstant(Operation *op, Attribute constValue) {
   // anything. Otherwise, we move the constant to the insertion block.
   Block *insertBlock = &insertRegion->front();
   if (opBlock != insertBlock || (&insertBlock->front() != op &&
-                                 !isFolderOwnedConstant(op->getPrevNode())))
+                                 !isFolderOwnedConstant(op->getPrevNode()))) {
     op->moveBefore(&insertBlock->front());
+    appendFoldedLocation(op, insertBlock->getParent()->getLoc());
+  }
 
   folderConstOp = op;
   referencedDialects[op].push_back(op->getDialect());
@@ -264,8 +303,10 @@ OperationFolder::processFoldResults(Operation *op,
       // with. This may not automatically happen if the operation being folded
       // was inserted before the constant within the insertion block.
       Block *opBlock = op->getBlock();
-      if (opBlock == constOp->getBlock() && &opBlock->front() != constOp)
+      if (opBlock == constOp->getBlock() && &opBlock->front() != constOp) {
         constOp->moveBefore(&opBlock->front());
+        appendFoldedLocation(constOp, opBlock->getParent()->getLoc());
+      }
 
       results.push_back(constOp->getResult(0));
       continue;
@@ -294,8 +335,10 @@ OperationFolder::tryGetOrCreateConstant(ConstantMap &uniquedConstants,
   // Check if an existing mapping already exists.
   auto constKey = std::make_tuple(dialect, value, type);
   Operation *&constOp = uniquedConstants[constKey];
-  if (constOp)
+  if (constOp) {
+    appendFoldedLocation(constOp, loc);
     return constOp;
+  }
 
   // If one doesn't exist, try to materialize one.
   if (!(constOp = materializeConstant(dialect, rewriter, value, type, loc)))
@@ -316,6 +359,7 @@ OperationFolder::tryGetOrCreateConstant(ConstantMap &uniquedConstants,
   // materialized operation in favor of the existing one.
   if (auto *existingOp = uniquedConstants.lookup(newKey)) {
     notifyRemoval(constOp);
+    appendFoldedLocation(existingOp, constOp->getLoc());
     rewriter.eraseOp(constOp);
     referencedDialects[existingOp].push_back(dialect);
     return constOp = existingOp;
diff --git a/mlir/test/Transforms/canonicalize-debuginfo.mlir b/mlir/test/Transforms/canonicalize-debuginfo.mlir
new file mode 100644
index 00000000000000..9cee2fec83bad6
--- /dev/null
+++ b/mlir/test/Transforms/canonicalize-debuginfo.mlir
@@ -0,0 +1,42 @@
+// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline='builtin.module(func.func(canonicalize{test-convergence}))' -split-input-file -mlir-print-debuginfo | FileCheck %s
+
+// CHECK-LABEL: func @merge_constants
+func.func @merge_constants() -> (index, index, index) {
+  // CHECK-NEXT: arith.constant 42 : index loc(#[[FusedLoc:.*]])
+  %0 = arith.constant 42 : index loc("merge_constants":0:0)
+  %1 = arith.constant 42 : index loc("merge_constants":1:0)
+  %2 = arith.constant 42 : index loc("merge_constants":2:0)
+  return %0, %1, %2: index, index, index
+}
+
+// CHECK-DAG: #[[LocConst0:.*]] = loc("merge_constants":0:0)
+// CHECK-DAG: #[[LocConst1:.*]] = loc("merge_constants":1:0)
+// CHECK-DAG: #[[LocConst2:.*]] = loc("merge_constants":2:0)
+
+// CHECK: #[[FusedLoc]] = loc(fused<"OpFold">[
+// CHECK-SAME: #[[LocConst0]]
+// CHECK-SAME: #[[LocConst1]]
+// CHECK-SAME: #[[LocConst2]]
+
+// -----
+
+// CHECK-LABEL: func @hoist_constant
+func.func @hoist_constant(%arg0: memref<8xi32>) {
+  // CHECK-NEXT: arith.constant 42 : i32 loc(#[[FusedWithFunction:.*]])
+  affine.for %arg1 = 0 to 8 {
+    %0 = arith.constant 42 : i32 loc("hoist_constant":0:0)
+    %1 = arith.constant 42 : i32 loc("hoist_constant":1:0)
+    memref.store %0, %arg0[%arg1] : memref<8xi32>
+    memref.store %1, %arg0[%arg1] : memref<8xi32>
+  }
+  return
+} loc("hoist_constant":2:0)
+
+// CHECK-DAG: #[[LocConst0:.*]] = loc("hoist_constant":0:0)
+// CHECK-DAG: #[[LocConst1:.*]] = loc("hoist_constant":1:0)
+// CHECK-DAG: #[[LocFunc:.*]] = loc("hoist_constant":2:0)
+
+// CHECK: #[[FusedWithFunction]] = loc(fused<"OpFold">[
+// CHECK-SAME: #[[LocConst0]]
+// CHECK-SAME: #[[LocFunc]]
+// CHECK-SAME: #[[LocConst1]]

>From 8f5b59d8ed5adad97da58b988b158a10f90a2a20 Mon Sep 17 00:00:00 2001
From: Billy Zhu <billyzhu at modular.com>
Date: Thu, 7 Dec 2023 22:17:46 -0800
Subject: [PATCH 2/4] [split pr] remove location fusing when hoisting

---
 mlir/lib/Transforms/Utils/FoldUtils.cpp | 16 ++++------------
 1 file changed, 4 insertions(+), 12 deletions(-)

diff --git a/mlir/lib/Transforms/Utils/FoldUtils.cpp b/mlir/lib/Transforms/Utils/FoldUtils.cpp
index 23fcb4796892d6..a8cf541a5d33b4 100644
--- a/mlir/lib/Transforms/Utils/FoldUtils.cpp
+++ b/mlir/lib/Transforms/Utils/FoldUtils.cpp
@@ -109,10 +109,8 @@ LogicalResult OperationFolder::tryToFold(Operation *op, bool *inPlaceUpdate) {
     // Check to see if we should rehoist, i.e. if a non-constant operation was
     // inserted before this one.
     Block *opBlock = op->getBlock();
-    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode())) {
+    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode()))
       op->moveBefore(&opBlock->front());
-      appendFoldedLocation(op, opBlock->getParent()->getLoc());
-    }
     return failure();
   }
 
@@ -146,10 +144,8 @@ bool OperationFolder::insertKnownConstant(Operation *op, Attribute constValue) {
   // If this is a constant we unique'd, we don't need to insert, but we can
   // check to see if we should rehoist it.
   if (isFolderOwnedConstant(op)) {
-    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode())) {
+    if (&opBlock->front() != op && !isFolderOwnedConstant(op->getPrevNode()))
       op->moveBefore(&opBlock->front());
-      appendFoldedLocation(op, opBlock->getParent()->getLoc());
-    }
     return true;
   }
 
@@ -188,10 +184,8 @@ bool OperationFolder::insertKnownConstant(Operation *op, Attribute constValue) {
   // anything. Otherwise, we move the constant to the insertion block.
   Block *insertBlock = &insertRegion->front();
   if (opBlock != insertBlock || (&insertBlock->front() != op &&
-                                 !isFolderOwnedConstant(op->getPrevNode()))) {
+                                 !isFolderOwnedConstant(op->getPrevNode())))
     op->moveBefore(&insertBlock->front());
-    appendFoldedLocation(op, insertBlock->getParent()->getLoc());
-  }
 
   folderConstOp = op;
   referencedDialects[op].push_back(op->getDialect());
@@ -303,10 +297,8 @@ OperationFolder::processFoldResults(Operation *op,
       // with. This may not automatically happen if the operation being folded
       // was inserted before the constant within the insertion block.
       Block *opBlock = op->getBlock();
-      if (opBlock == constOp->getBlock() && &opBlock->front() != constOp) {
+      if (opBlock == constOp->getBlock() && &opBlock->front() != constOp)
         constOp->moveBefore(&opBlock->front());
-        appendFoldedLocation(constOp, opBlock->getParent()->getLoc());
-      }
 
       results.push_back(constOp->getResult(0));
       continue;

>From d5ab81edc9d09778e4439851309ccad90fd98c0f Mon Sep 17 00:00:00 2001
From: Billy Zhu <billyzhu at modular.com>
Date: Thu, 7 Dec 2023 22:34:50 -0800
Subject: [PATCH 3/4] address comments

---
 mlir/include/mlir/Transforms/FoldUtils.h | 12 ++++-
 mlir/lib/Transforms/Utils/FoldUtils.cpp  | 62 ++++++++++++------------
 2 files changed, 41 insertions(+), 33 deletions(-)

diff --git a/mlir/include/mlir/Transforms/FoldUtils.h b/mlir/include/mlir/Transforms/FoldUtils.h
index 2600da361496cd..28fa18cf942de4 100644
--- a/mlir/include/mlir/Transforms/FoldUtils.h
+++ b/mlir/include/mlir/Transforms/FoldUtils.h
@@ -33,7 +33,8 @@ class Value;
 class OperationFolder {
 public:
   OperationFolder(MLIRContext *ctx, OpBuilder::Listener *listener = nullptr)
-      : interfaces(ctx), rewriter(ctx, listener) {}
+      : fusedLocationTag(StringAttr::get(ctx, "CSE")), interfaces(ctx),
+        rewriter(ctx, listener) {}
 
   /// Tries to perform folding on the given `op`, including unifying
   /// deduplicated constants. If successful, replaces `op`'s uses with
@@ -95,6 +96,15 @@ class OperationFolder {
                                     Dialect *dialect, Attribute value,
                                     Type type, Location loc);
 
+  // Fuse `foldedLocation` into the Location of `retainedOp`. This will result
+  // in `retainedOp` having a FusedLoc with `fusedLocationTag` to help trace the
+  // source of the fusion. If `retainedOp` already had a FusedLoc with the same
+  // tag, `foldedLocation` will simply be appended to it.
+  void appendFoldedLocation(Operation *retainedOp, Location foldedLocation);
+
+  /// Tag for annotating fused locations as a result of merging constants.
+  StringAttr fusedLocationTag;
+
   /// A mapping between an insertion region and the constants that have been
   /// created within it.
   DenseMap<Region *, ConstantMap> foldScopes;
diff --git a/mlir/lib/Transforms/Utils/FoldUtils.cpp b/mlir/lib/Transforms/Utils/FoldUtils.cpp
index a8cf541a5d33b4..c2ec29e5c099fb 100644
--- a/mlir/lib/Transforms/Utils/FoldUtils.cpp
+++ b/mlir/lib/Transforms/Utils/FoldUtils.cpp
@@ -16,41 +16,10 @@
 #include "mlir/IR/Builders.h"
 #include "mlir/IR/Matchers.h"
 #include "mlir/IR/Operation.h"
+#include "llvm/ADT/SmallPtrSet.h"
 
 using namespace mlir;
 
-// Fuse `foldedLocation` into the Location of `retainedOp`.
-// This will result in `retainedOp` having a FusedLoc with a StringAttr tag
-// "OpFold" to help trace the source of the fusion. If `retainedOp` already had
-// a FusedLoc with the same tag, `foldedLocation` will simply be appended to it.
-// Usage:
-// - When an op is deduplicated, fuse the location of the op to be removed into
-//   the op that is retained.
-// - When an op is hoisted to the front/back of a block, fuse the location of
-//   the parent region of the block into the hoisted op.
-static void appendFoldedLocation(Operation *retainedOp,
-                                 Location foldedLocation) {
-  constexpr std::string_view tag = "OpFold";
-  // Append into existing fused location if it has the same tag.
-  if (auto existingFusedLoc =
-          retainedOp->getLoc().dyn_cast<FusedLocWith<StringAttr>>()) {
-    StringAttr existingMetadata = existingFusedLoc.getMetadata();
-    if (existingMetadata.strref().equals(tag)) {
-      SmallVector<Location> locations(existingFusedLoc.getLocations());
-      locations.push_back(foldedLocation);
-      Location newFusedLoc =
-          FusedLoc::get(retainedOp->getContext(), locations, existingMetadata);
-      retainedOp->setLoc(newFusedLoc);
-      return;
-    }
-  }
-  // Create a new fusedloc with retainedOp's loc and foldedLocation.
-  Location newFusedLoc = FusedLoc::get(
-      retainedOp->getContext(), {retainedOp->getLoc(), foldedLocation},
-      StringAttr::get(retainedOp->getContext(), tag));
-  retainedOp->setLoc(newFusedLoc);
-}
-
 /// Given an operation, find the parent region that folded constants should be
 /// inserted into.
 static Region *
@@ -362,3 +331,32 @@ OperationFolder::tryGetOrCreateConstant(ConstantMap &uniquedConstants,
   auto newIt = uniquedConstants.insert({newKey, constOp});
   return newIt.first->second;
 }
+
+void OperationFolder::appendFoldedLocation(Operation *retainedOp,
+                                           Location foldedLocation) {
+  // Append into existing fused location if it has the same tag.
+  if (auto existingFusedLoc =
+          dyn_cast<FusedLocWith<StringAttr>>(retainedOp->getLoc())) {
+    StringAttr existingMetadata = existingFusedLoc.getMetadata();
+    if (existingMetadata == fusedLocationTag) {
+      ArrayRef<Location> existingLocations = existingFusedLoc.getLocations();
+      SetVector<Location> locations(existingLocations.begin(),
+                                    existingLocations.end());
+      locations.insert(foldedLocation);
+      Location newFusedLoc = FusedLoc::get(
+          retainedOp->getContext(), locations.takeVector(), existingMetadata);
+      retainedOp->setLoc(newFusedLoc);
+      return;
+    }
+  }
+
+  // Create a new fusedloc with retainedOp's loc and foldedLocation.
+  // If they're already equal, no need to fuse.
+  if (retainedOp->getLoc() == foldedLocation)
+    return;
+
+  Location newFusedLoc =
+      FusedLoc::get(retainedOp->getContext(),
+                    {retainedOp->getLoc(), foldedLocation}, fusedLocationTag);
+  retainedOp->setLoc(newFusedLoc);
+}

>From 35829ff4af3e0684fb8104ca4e60b0c894c3f229 Mon Sep 17 00:00:00 2001
From: Billy Zhu <billyzhu at modular.com>
Date: Fri, 8 Dec 2023 09:35:43 -0800
Subject: [PATCH 4/4] update tests

---
 .../Transforms/canonicalize-debuginfo.mlir    | 24 +++++--------
 .../Transforms/constant-fold-debuginfo.mlir   | 34 +++++++++++++++++++
 2 files changed, 42 insertions(+), 16 deletions(-)
 create mode 100644 mlir/test/Transforms/constant-fold-debuginfo.mlir

diff --git a/mlir/test/Transforms/canonicalize-debuginfo.mlir b/mlir/test/Transforms/canonicalize-debuginfo.mlir
index 9cee2fec83bad6..034c9163a8059f 100644
--- a/mlir/test/Transforms/canonicalize-debuginfo.mlir
+++ b/mlir/test/Transforms/canonicalize-debuginfo.mlir
@@ -1,28 +1,25 @@
-// RUN: mlir-opt -allow-unregistered-dialect %s -pass-pipeline='builtin.module(func.func(canonicalize{test-convergence}))' -split-input-file -mlir-print-debuginfo | FileCheck %s
+// RUN: mlir-opt %s -pass-pipeline='builtin.module(func.func(canonicalize{test-convergence}))' -split-input-file -mlir-print-debuginfo | FileCheck %s
 
 // CHECK-LABEL: func @merge_constants
-func.func @merge_constants() -> (index, index, index) {
+func.func @merge_constants() -> (index, index, index, index) {
   // CHECK-NEXT: arith.constant 42 : index loc(#[[FusedLoc:.*]])
   %0 = arith.constant 42 : index loc("merge_constants":0:0)
   %1 = arith.constant 42 : index loc("merge_constants":1:0)
   %2 = arith.constant 42 : index loc("merge_constants":2:0)
-  return %0, %1, %2: index, index, index
+  %3 = arith.constant 42 : index loc("merge_constants":2:0) // repeated loc
+  return %0, %1, %2, %3: index, index, index, index
 }
 
 // CHECK-DAG: #[[LocConst0:.*]] = loc("merge_constants":0:0)
 // CHECK-DAG: #[[LocConst1:.*]] = loc("merge_constants":1:0)
 // CHECK-DAG: #[[LocConst2:.*]] = loc("merge_constants":2:0)
-
-// CHECK: #[[FusedLoc]] = loc(fused<"OpFold">[
-// CHECK-SAME: #[[LocConst0]]
-// CHECK-SAME: #[[LocConst1]]
-// CHECK-SAME: #[[LocConst2]]
+// CHECK: #[[FusedLoc]] = loc(fused<"CSE">[#[[LocConst0]], #[[LocConst1]], #[[LocConst2]]])
 
 // -----
 
 // CHECK-LABEL: func @hoist_constant
 func.func @hoist_constant(%arg0: memref<8xi32>) {
-  // CHECK-NEXT: arith.constant 42 : i32 loc(#[[FusedWithFunction:.*]])
+  // CHECK-NEXT: arith.constant 42 : i32 loc(#[[FusedLoc:.*]])
   affine.for %arg1 = 0 to 8 {
     %0 = arith.constant 42 : i32 loc("hoist_constant":0:0)
     %1 = arith.constant 42 : i32 loc("hoist_constant":1:0)
@@ -30,13 +27,8 @@ func.func @hoist_constant(%arg0: memref<8xi32>) {
     memref.store %1, %arg0[%arg1] : memref<8xi32>
   }
   return
-} loc("hoist_constant":2:0)
+}
 
 // CHECK-DAG: #[[LocConst0:.*]] = loc("hoist_constant":0:0)
 // CHECK-DAG: #[[LocConst1:.*]] = loc("hoist_constant":1:0)
-// CHECK-DAG: #[[LocFunc:.*]] = loc("hoist_constant":2:0)
-
-// CHECK: #[[FusedWithFunction]] = loc(fused<"OpFold">[
-// CHECK-SAME: #[[LocConst0]]
-// CHECK-SAME: #[[LocFunc]]
-// CHECK-SAME: #[[LocConst1]]
+// CHECK: #[[FusedLoc]] = loc(fused<"CSE">[#[[LocConst0]], #[[LocConst1]]])
diff --git a/mlir/test/Transforms/constant-fold-debuginfo.mlir b/mlir/test/Transforms/constant-fold-debuginfo.mlir
new file mode 100644
index 00000000000000..79a25f860a4841
--- /dev/null
+++ b/mlir/test/Transforms/constant-fold-debuginfo.mlir
@@ -0,0 +1,34 @@
+// RUN: mlir-opt %s -split-input-file -test-constant-fold -mlir-print-debuginfo | FileCheck %s
+
+// CHECK-LABEL: func @fold_and_merge
+func.func @fold_and_merge() -> (i32, i32) {
+  %0 = arith.constant 1 : i32
+  %1 = arith.constant 5 : i32
+
+  // CHECK-NEXT: [[C:%.+]] = arith.constant 6 : i32 loc(#[[FusedLoc:.*]])
+  %2 = arith.addi %0, %1 : i32 loc("fold_and_merge":0:0)
+
+  %3 = arith.constant 6 : i32 loc("fold_and_merge":1:0)
+
+  return %2, %3: i32, i32
+}
+
+// CHECK-DAG: #[[LocConst0:.*]] = loc("fold_and_merge":0:0)
+// CHECK-DAG: #[[LocConst1:.*]] = loc("fold_and_merge":1:0)
+// CHECK: #[[FusedLoc]] = loc(fused<"CSE">[#[[LocConst1]], #[[LocConst0]]])
+
+// -----
+
+// CHECK-LABEL: func @materialize_different_dialect
+func.func @materialize_different_dialect() -> (f32, f32) {
+  // CHECK: arith.constant 1.{{0*}}e+00 : f32 loc(#[[FusedLoc:.*]])
+  %0 = arith.constant -1.0 : f32
+  %1 = math.absf %0 : f32 loc("materialize_different_dialect":0:0)
+  %2 = arith.constant 1.0 : f32 loc("materialize_different_dialect":1:0)
+
+  return %1, %2: f32, f32
+}
+
+// CHECK-DAG: #[[LocConst0:.*]] = loc("materialize_different_dialect":0:0)
+// CHECK-DAG: #[[LocConst1:.*]] = loc("materialize_different_dialect":1:0)
+// CHECK: #[[FusedLoc]] = loc(fused<"CSE">[#[[LocConst1]], #[[LocConst0]]])



More information about the Mlir-commits mailing list