[Mlir-commits] [mlir] [mlir][ptr] Add the `ptradd` and `type_offset` ops, and `int_space` attr (PR #136434)
Fabian Mora
llvmlistbot at llvm.org
Sun Apr 20 07:34:47 PDT 2025
https://github.com/fabianmcg updated https://github.com/llvm/llvm-project/pull/136434
>From a2cfd2dd4f3e58ee190a9d46e46ad7d4c34cc1b4 Mon Sep 17 00:00:00 2001
From: Fabian Mora <6982088+fabianmcg at users.noreply.github.com>
Date: Sun, 23 Mar 2025 23:09:36 +0000
Subject: [PATCH 1/4] [mlir][ptr] Add the `ptradd` and `type_offset` ops, and
`int_space` attr
This patch adds the `ptr.ptradd` and `ptr.type_offset` operations. Given a `ptr`
value these operations can be used to compute new addresses. For example:
```mlir
func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space>) -> !ptr.ptr<#ptr.int_space> {
%off = ptr.type_offset f32 : index
%res = ptr.ptradd %ptr, %off : !ptr.ptr<#ptr.int_space>, index
return %res : !ptr.ptr<#ptr.int_space>
}
```
Additionally, this patch also adds the `#ptr.int_space`, a memory space that
is identified by a integer. This memory space allows loading and storing values
to all types.
---
.../mlir/Dialect/Ptr/IR/PtrAttrDefs.td | 33 ++++++++++
mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h | 2 +
mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h | 1 +
mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td | 63 +++++++++++++++++++
mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp | 46 ++++++++++++++
mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp | 31 +++++++++
mlir/test/Dialect/Ptr/canonicalize.mlir | 31 +++++++++
mlir/test/Dialect/Ptr/ops.mlir | 11 ++++
8 files changed, 218 insertions(+)
create mode 100644 mlir/test/Dialect/Ptr/canonicalize.mlir
create mode 100644 mlir/test/Dialect/Ptr/ops.mlir
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td
index e75038f300f1a..ac78ee37ab982 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td
@@ -10,6 +10,7 @@
#define PTR_ATTRDEFS
include "mlir/Dialect/Ptr/IR/PtrDialect.td"
+include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
// All of the attributes will extend this class.
@@ -20,6 +21,38 @@ class Ptr_Attr<string name, string attrMnemonic,
let mnemonic = attrMnemonic;
}
+//===----------------------------------------------------------------------===//
+// IAddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+def Ptr_IAddressSpaceAttr :
+ Ptr_Attr<"IAddressSpace", "int_space", [
+ DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
+ ]> {
+ let summary = "Int memory space";
+ let description = [{
+ The `int_as` attribute defines a memory space attribute with the following
+ properties:
+ - Load and store operations are always valid, regardless of the type.
+ - Atomic operations are always valid, regardless of the type.
+ - Cast operations are valid between pointers with `int_space` memory space,
+ or between non-scalable `vector` of pointers with `int_space` memory space.
+
+ The default address spaces is 0.
+
+ Example:
+
+ ```mlir
+ // Default address space: 0.
+ #ptr.int_space
+ // Address space 3.
+ #ptr.int_space<3>
+ ```
+ }];
+ let parameters = (ins DefaultValuedParameter<"int64_t", "0">:$value);
+ let assemblyFormat = "(`<` $value^ `>`)?";
+}
+
//===----------------------------------------------------------------------===//
// SpecAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
index 5ffe23e45fe12..a25885be9915b 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
@@ -15,6 +15,8 @@
#include "mlir/IR/OpImplementation.h"
+#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
+
#define GET_ATTRDEF_CLASSES
#include "mlir/Dialect/Ptr/IR/PtrOpsAttrs.h.inc"
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
index 6a0c1429c6be9..43802a07351e5 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
@@ -18,6 +18,7 @@
#include "mlir/Dialect/Ptr/IR/PtrDialect.h"
#include "mlir/Dialect/Ptr/IR/PtrTypes.h"
#include "mlir/IR/OpDefinition.h"
+#include "mlir/Interfaces/SideEffectInterfaces.h"
#define GET_OP_CLASSES
#include "mlir/Dialect/Ptr/IR/PtrOps.h.inc"
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 02ea71f4322ef..c392765837922 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -12,6 +12,69 @@
include "mlir/Dialect/Ptr/IR/PtrDialect.td"
include "mlir/Dialect/Ptr/IR/PtrAttrDefs.td"
include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
+include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/IR/OpAsmInterface.td"
+//===----------------------------------------------------------------------===//
+// PtrAddOp
+//===----------------------------------------------------------------------===//
+
+def Ptr_PtrAddOp : Pointer_Op<"ptradd", [
+ Pure, AllTypesMatch<["base", "result"]>
+ ]> {
+ let summary = "Pointer add operation";
+ let description = [{
+ The `ptradd` operation adds an integer offset to a pointer to produce a new
+ pointer. The input and output pointer types are always the same.
+
+ Example:
+
+ ```mlir
+ %x_off = ptr.ptradd %x, %off : !ptr.ptr<0>, i32
+ ```
+ }];
+
+ let arguments = (ins Ptr_PtrType:$base, AnySignlessIntegerOrIndex:$offset);
+ let results = (outs Ptr_PtrType:$result);
+ let assemblyFormat = [{
+ $base `,` $offset attr-dict `:` type($base) `,` type($offset)
+ }];
+ let hasFolder = 1;
+}
+
+//===----------------------------------------------------------------------===//
+// TypeOffsetOp
+//===----------------------------------------------------------------------===//
+
+def Ptr_TypeOffsetOp : Pointer_Op<"type_offset", [ConstantLike, Pure]> {
+ let summary = "Type offset operation";
+ let description = [{
+ The `type_offset` operation produces an int or index-typed SSA value
+ equal to a target-specific constant representing the offset of a single
+ element of the given type.
+
+ Example:
+
+ ```mlir
+ %0 = ptr.type_offset f32 : index
+ %1 = ptr.type_offset memref<12 x f64> : i32
+ ```
+ }];
+
+ let arguments = (ins TypeAttr:$element_type);
+ let results = (outs AnySignlessIntegerOrIndex:$result);
+ let builders = [
+ OpBuilder<(ins "TypeAttr":$element_type)>
+ ];
+ let assemblyFormat = [{
+ $element_type attr-dict `:` type($result)
+ }];
+ let extraClassDeclaration = [{
+ /// Returns the type offset according to `maybeLayout`. If `maybeLayout` is
+ /// `nullopt` the nearest layout the op will be used for the computation.
+ llvm::TypeSize getTypeSize(std::optional<DataLayout> layout = std::nullopt);
+ }];
+ let hasFolder = 1;
+}
+
#endif // PTR_OPS
diff --git a/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp b/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp
index f8ce820d0bcbd..d1f778e72395e 100644
--- a/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp
+++ b/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Ptr/IR/PtrAttrs.h"
+#include "mlir/IR/BuiltinTypes.h"
#include "llvm/ADT/TypeSwitch.h"
using namespace mlir;
@@ -18,6 +19,51 @@ using namespace mlir::ptr;
constexpr const static unsigned kBitsInByte = 8;
+//===----------------------------------------------------------------------===//
+// IAddressSpaceAttr
+//===----------------------------------------------------------------------===//
+
+LogicalResult IAddressSpaceAttr::isValidLoad(
+ Type type, ptr::AtomicOrdering ordering, IntegerAttr alignment,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ return success();
+}
+
+LogicalResult IAddressSpaceAttr::isValidStore(
+ Type type, ptr::AtomicOrdering ordering, IntegerAttr alignment,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ return success();
+}
+
+LogicalResult IAddressSpaceAttr::isValidAtomicOp(
+ ptr::AtomicBinOp op, Type type, ptr::AtomicOrdering ordering,
+ IntegerAttr alignment, function_ref<InFlightDiagnostic()> emitError) const {
+ return success();
+}
+
+LogicalResult IAddressSpaceAttr::isValidAtomicXchg(
+ Type type, ptr::AtomicOrdering successOrdering,
+ ptr::AtomicOrdering failureOrdering, IntegerAttr alignment,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ return success();
+}
+
+LogicalResult IAddressSpaceAttr::isValidAddrSpaceCast(
+ Type tgt, Type src, function_ref<InFlightDiagnostic()> emitError) const {
+ // TODO: update this method once the `addrspace_cast` op is added to the
+ // dialect.
+ assert(false && "unimplemented, see TODO in the source.");
+ return failure();
+}
+
+LogicalResult IAddressSpaceAttr::isValidPtrIntCast(
+ Type intLikeTy, Type ptrLikeTy,
+ function_ref<InFlightDiagnostic()> emitError) const {
+ // TODO: update this method once the int-cast ops are added to the dialect.
+ assert(false && "unimplemented, see TODO in the source.");
+ return failure();
+}
+
//===----------------------------------------------------------------------===//
// SpecAttr
//===----------------------------------------------------------------------===//
diff --git a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
index ff231dae60c27..e87496cd1696c 100644
--- a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
+++ b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
@@ -12,7 +12,9 @@
#include "mlir/Dialect/Ptr/IR/PtrOps.h"
#include "mlir/IR/DialectImplementation.h"
+#include "mlir/IR/Matchers.h"
#include "mlir/IR/PatternMatch.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
#include "mlir/Transforms/InliningUtils.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/TypeSwitch.h"
@@ -39,6 +41,35 @@ void PtrDialect::initialize() {
>();
}
+//===----------------------------------------------------------------------===//
+// PtrAddOp
+//===----------------------------------------------------------------------===//
+
+/// Fold the op to the base ptr when the offset is 0.
+OpFoldResult PtrAddOp::fold(FoldAdaptor adaptor) {
+ Attribute attr = adaptor.getOffset();
+ if (!attr)
+ return nullptr;
+ if (llvm::APInt value; m_ConstantInt(&value).match(attr) && value.isZero())
+ return getBase();
+ return nullptr;
+}
+
+//===----------------------------------------------------------------------===//
+// TypeOffsetOp
+//===----------------------------------------------------------------------===//
+
+OpFoldResult TypeOffsetOp::fold(FoldAdaptor adaptor) {
+ return TypeAttr::get(getElementType());
+}
+
+llvm::TypeSize TypeOffsetOp::getTypeSize(std::optional<DataLayout> layout) {
+ if (layout)
+ return layout->getTypeSize(getElementType());
+ DataLayout dl = DataLayout::closest(*this);
+ return dl.getTypeSize(getElementType());
+}
+
//===----------------------------------------------------------------------===//
// Pointer API.
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/Ptr/canonicalize.mlir b/mlir/test/Dialect/Ptr/canonicalize.mlir
new file mode 100644
index 0000000000000..630040cd42442
--- /dev/null
+++ b/mlir/test/Dialect/Ptr/canonicalize.mlir
@@ -0,0 +1,31 @@
+// RUN: mlir-opt --canonicalize %s | FileCheck %s
+
+/// Check `ptradd` and `type_offset` canonicalizer patterns.
+
+// CHECK-LABEL: @ops0
+func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space<3>>, %c: i1) -> !ptr.ptr<#ptr.int_space<3>> {
+ // CHECK: (%[[PTR_0:.*]]: !ptr.ptr<#ptr.int_space<3>>,
+ // CHECK: %[[F32_OFF:.*]] = ptr.type_offset f32 : index
+ // CHECK: %[[PTR_1:.*]] = ptr.ptradd %[[PTR_0]], %[[F32_OFF]] : <#ptr.int_space<3>>, index
+ // CHECK: %[[PTR_2:.*]] = ptr.ptradd %[[PTR_1]], %[[F32_OFF]] : <#ptr.int_space<3>>, index
+ // CHECK: %[[PTR_3:.*]] = scf.if %{{.*}} -> (!ptr.ptr<#ptr.int_space<3>>) {
+ // CHECK: %[[PTR_4:.*]] = ptr.ptradd %[[PTR_2]], %[[F32_OFF]] : <#ptr.int_space<3>>, index
+ // CHECK: scf.yield %[[PTR_4]] : !ptr.ptr<#ptr.int_space<3>>
+ // CHECK: } else {
+ // CHECK: scf.yield %[[PTR_0]] : !ptr.ptr<#ptr.int_space<3>>
+ // CHECK: }
+ // CHECK: return %[[PTR_3]] : !ptr.ptr<#ptr.int_space<3>>
+ // CHECK: }
+ %off0 = ptr.type_offset f32 : index
+ %res0 = ptr.ptradd %ptr, %off0 : !ptr.ptr<#ptr.int_space<3>>, index
+ %off1 = ptr.type_offset f32 : index
+ %res1 = ptr.ptradd %res0, %off1 : !ptr.ptr<#ptr.int_space<3>>, index
+ %res = scf.if %c -> !ptr.ptr<#ptr.int_space<3>> {
+ %off2 = ptr.type_offset f32 : index
+ %res2 = ptr.ptradd %res1, %off2 : !ptr.ptr<#ptr.int_space<3>>, index
+ scf.yield %res2 : !ptr.ptr<#ptr.int_space<3>>
+ } else {
+ scf.yield %ptr : !ptr.ptr<#ptr.int_space<3>>
+ }
+ return %res : !ptr.ptr<#ptr.int_space<3>>
+}
diff --git a/mlir/test/Dialect/Ptr/ops.mlir b/mlir/test/Dialect/Ptr/ops.mlir
new file mode 100644
index 0000000000000..53008cb84d6b0
--- /dev/null
+++ b/mlir/test/Dialect/Ptr/ops.mlir
@@ -0,0 +1,11 @@
+// RUN: mlir-opt %s | FileCheck %s
+
+/// Check op assembly.
+func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space>) -> !ptr.ptr<#ptr.int_space> {
+ // CHECK-LABEL: @ops0
+ // CHECK: ptr.type_offset f32 : index
+ // CHECK-NEXT: ptr.ptradd %{{.*}}, %{{.*}} : <#ptr.int_space>, index
+ %off = ptr.type_offset f32 : index
+ %res = ptr.ptradd %ptr, %off : !ptr.ptr<#ptr.int_space>, index
+ return %res : !ptr.ptr<#ptr.int_space>
+}
>From 133e3ef2a12d13ec123f686488cab5690e03a3a7 Mon Sep 17 00:00:00 2001
From: Fabian Mora <6982088+fabianmcg at users.noreply.github.com>
Date: Sun, 20 Apr 2025 11:49:49 +0000
Subject: [PATCH 2/4] address reviewer comments
---
mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td | 11 +++++++++++
mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h | 1 +
mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td | 16 ++++++++++++----
mlir/lib/Dialect/Ptr/IR/CMakeLists.txt | 1 +
mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp | 2 ++
mlir/test/Dialect/Ptr/canonicalize.mlir | 6 ++++--
mlir/test/Dialect/Ptr/ops.mlir | 6 +++++-
7 files changed, 36 insertions(+), 7 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
index 0a8a7ede5d1ff..3b35da0d280ce 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
@@ -66,4 +66,15 @@ def AtomicOrdering : I64EnumAttr<
let cppNamespace = "::mlir::ptr";
}
+//===----------------------------------------------------------------------===//
+// Ptr add flags enum attr.
+//===----------------------------------------------------------------------===//
+
+def Ptr_PtrAddFlags : I32EnumAttr<"PtrAddFlags", "Pointer add flags", [
+ I32EnumAttrCase<"none", 0>, I32EnumAttrCase<"nusw", 1>,
+ I32EnumAttrCase<"nuw", 2>, I32EnumAttrCase<"inbounds", 3>
+ ]> {
+ let cppNamespace = "::mlir::ptr";
+}
+
#endif // PTR_ENUMS
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
index 43802a07351e5..8686cc7d316d4 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
@@ -19,6 +19,7 @@
#include "mlir/Dialect/Ptr/IR/PtrTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
+#include "mlir/Interfaces/ViewLikeInterface.h"
#define GET_OP_CLASSES
#include "mlir/Dialect/Ptr/IR/PtrOps.h.inc"
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index c392765837922..d172f1574d5a1 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -11,8 +11,10 @@
include "mlir/Dialect/Ptr/IR/PtrDialect.td"
include "mlir/Dialect/Ptr/IR/PtrAttrDefs.td"
+include "mlir/Dialect/Ptr/IR/PtrEnums.td"
include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
+include "mlir/Interfaces/ViewLikeInterface.td"
include "mlir/IR/OpAsmInterface.td"
//===----------------------------------------------------------------------===//
@@ -20,7 +22,8 @@ include "mlir/IR/OpAsmInterface.td"
//===----------------------------------------------------------------------===//
def Ptr_PtrAddOp : Pointer_Op<"ptradd", [
- Pure, AllTypesMatch<["base", "result"]>
+ Pure, AllTypesMatch<["base", "result"]>,
+ DeclareOpInterfaceMethods<ViewLikeOpInterface>
]> {
let summary = "Pointer add operation";
let description = [{
@@ -30,14 +33,19 @@ def Ptr_PtrAddOp : Pointer_Op<"ptradd", [
Example:
```mlir
- %x_off = ptr.ptradd %x, %off : !ptr.ptr<0>, i32
+ %x_off = ptr.ptradd %x, %off : !ptr.ptr<0>, i32
+ %x_off0 = ptr.ptradd nusw %x, %off : !ptr.ptr<0>, i32
```
}];
- let arguments = (ins Ptr_PtrType:$base, AnySignlessIntegerOrIndex:$offset);
+ let arguments = (ins
+ Ptr_PtrType:$base,
+ AnySignlessIntegerOrIndex:$offset,
+ DefaultValuedAttr<Ptr_PtrAddFlags,
+ "::mlir::ptr::PtrAddFlags::none">:$flags);
let results = (outs Ptr_PtrType:$result);
let assemblyFormat = [{
- $base `,` $offset attr-dict `:` type($base) `,` type($offset)
+ ($flags^)? $base `,` $offset attr-dict `:` type($base) `,` type($offset)
}];
let hasFolder = 1;
}
diff --git a/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt b/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt
index ba32a76273ed4..497468b9391db 100644
--- a/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt
+++ b/mlir/lib/Dialect/Ptr/IR/CMakeLists.txt
@@ -14,4 +14,5 @@ add_mlir_dialect_library(
MLIRIR
MLIRDataLayoutInterfaces
MLIRMemorySlotInterfaces
+ MLIRViewLikeInterface
)
diff --git a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
index e87496cd1696c..1ef25211fd2e6 100644
--- a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
+++ b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
@@ -55,6 +55,8 @@ OpFoldResult PtrAddOp::fold(FoldAdaptor adaptor) {
return nullptr;
}
+Value PtrAddOp::getViewSource() { return getBase(); }
+
//===----------------------------------------------------------------------===//
// TypeOffsetOp
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/Ptr/canonicalize.mlir b/mlir/test/Dialect/Ptr/canonicalize.mlir
index 630040cd42442..be6ce673aabdc 100644
--- a/mlir/test/Dialect/Ptr/canonicalize.mlir
+++ b/mlir/test/Dialect/Ptr/canonicalize.mlir
@@ -20,12 +20,14 @@ func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space<3>>, %c: i1) -> !ptr.ptr<#ptr.int_
%res0 = ptr.ptradd %ptr, %off0 : !ptr.ptr<#ptr.int_space<3>>, index
%off1 = ptr.type_offset f32 : index
%res1 = ptr.ptradd %res0, %off1 : !ptr.ptr<#ptr.int_space<3>>, index
- %res = scf.if %c -> !ptr.ptr<#ptr.int_space<3>> {
+ %res3 = scf.if %c -> !ptr.ptr<#ptr.int_space<3>> {
%off2 = ptr.type_offset f32 : index
%res2 = ptr.ptradd %res1, %off2 : !ptr.ptr<#ptr.int_space<3>>, index
scf.yield %res2 : !ptr.ptr<#ptr.int_space<3>>
} else {
scf.yield %ptr : !ptr.ptr<#ptr.int_space<3>>
}
- return %res : !ptr.ptr<#ptr.int_space<3>>
+ %off3 = index.constant 0
+ %res4 = ptr.ptradd %res3, %off3 : !ptr.ptr<#ptr.int_space<3>>, index
+ return %res4 : !ptr.ptr<#ptr.int_space<3>>
}
diff --git a/mlir/test/Dialect/Ptr/ops.mlir b/mlir/test/Dialect/Ptr/ops.mlir
index 53008cb84d6b0..ab1a9dac3a5d9 100644
--- a/mlir/test/Dialect/Ptr/ops.mlir
+++ b/mlir/test/Dialect/Ptr/ops.mlir
@@ -1,4 +1,4 @@
-// RUN: mlir-opt %s | FileCheck %s
+// RUN: mlir-opt %s --verify-roundtrip | FileCheck %s
/// Check op assembly.
func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space>) -> !ptr.ptr<#ptr.int_space> {
@@ -7,5 +7,9 @@ func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space>) -> !ptr.ptr<#ptr.int_space> {
// CHECK-NEXT: ptr.ptradd %{{.*}}, %{{.*}} : <#ptr.int_space>, index
%off = ptr.type_offset f32 : index
%res = ptr.ptradd %ptr, %off : !ptr.ptr<#ptr.int_space>, index
+ %res0 = ptr.ptradd none %ptr, %off : !ptr.ptr<#ptr.int_space>, index
+ %res1 = ptr.ptradd nusw %ptr, %off : !ptr.ptr<#ptr.int_space>, index
+ %res2 = ptr.ptradd nuw %ptr, %off : !ptr.ptr<#ptr.int_space>, index
+ %res3 = ptr.ptradd inbounds %ptr, %off : !ptr.ptr<#ptr.int_space>, index
return %res : !ptr.ptr<#ptr.int_space>
}
>From a789891369486566f5e91e9e01018b9d19fcb2e5 Mon Sep 17 00:00:00 2001
From: Fabian Mora <fmora.dev at gmail.com>
Date: Sun, 20 Apr 2025 08:03:12 -0400
Subject: [PATCH 3/4] Update mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
Co-authored-by: Mehdi Amini <joker.eph at gmail.com>
---
mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
index 1ef25211fd2e6..9a90682865654 100644
--- a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
+++ b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
@@ -45,7 +45,7 @@ void PtrDialect::initialize() {
// PtrAddOp
//===----------------------------------------------------------------------===//
-/// Fold the op to the base ptr when the offset is 0.
+/// Fold: ptradd ptr + 0 -> ptr
OpFoldResult PtrAddOp::fold(FoldAdaptor adaptor) {
Attribute attr = adaptor.getOffset();
if (!attr)
>From 4fb86dc6b4b643297d51e607002202ab150797a1 Mon Sep 17 00:00:00 2001
From: Fabian Mora <6982088+fabianmcg at users.noreply.github.com>
Date: Sun, 20 Apr 2025 14:34:07 +0000
Subject: [PATCH 4/4] address reviewer comments
---
.../mlir/Dialect/Ptr/IR/PtrAttrDefs.td | 69 ++++++++++++++-----
mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h | 3 +
mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td | 2 +-
mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td | 36 ++++++----
mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp | 31 +++++++--
mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp | 10 +--
mlir/test/Dialect/Ptr/canonicalize.mlir | 45 +++++-------
mlir/test/Dialect/Ptr/ops.mlir | 24 ++++---
8 files changed, 136 insertions(+), 84 deletions(-)
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td
index ac78ee37ab982..14d87a1a27fd7 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrDefs.td
@@ -12,6 +12,7 @@
include "mlir/Dialect/Ptr/IR/PtrDialect.td"
include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
+include "mlir/IR/BuiltinAttributeInterfaces.td"
// All of the attributes will extend this class.
class Ptr_Attr<string name, string attrMnemonic,
@@ -22,35 +23,28 @@ class Ptr_Attr<string name, string attrMnemonic,
}
//===----------------------------------------------------------------------===//
-// IAddressSpaceAttr
+// GenericSpaceAttr
//===----------------------------------------------------------------------===//
-def Ptr_IAddressSpaceAttr :
- Ptr_Attr<"IAddressSpace", "int_space", [
+def Ptr_GenericSpaceAttr :
+ Ptr_Attr<"GenericSpace", "generic_space", [
DeclareAttrInterfaceMethods<MemorySpaceAttrInterface>
]> {
- let summary = "Int memory space";
+ let summary = "Generic memory space";
let description = [{
- The `int_as` attribute defines a memory space attribute with the following
- properties:
+ The `generic_space` attribute defines a memory space attribute with the
+ following properties:
- Load and store operations are always valid, regardless of the type.
- Atomic operations are always valid, regardless of the type.
- - Cast operations are valid between pointers with `int_space` memory space,
- or between non-scalable `vector` of pointers with `int_space` memory space.
-
- The default address spaces is 0.
-
+ - Cast operations to `generic_space` are always valid.
+
Example:
```mlir
- // Default address space: 0.
- #ptr.int_space
- // Address space 3.
- #ptr.int_space<3>
+ #ptr.generic_space
```
}];
- let parameters = (ins DefaultValuedParameter<"int64_t", "0">:$value);
- let assemblyFormat = "(`<` $value^ `>`)?";
+ let assemblyFormat = "";
}
//===----------------------------------------------------------------------===//
@@ -100,4 +94,45 @@ def Ptr_SpecAttr : Ptr_Attr<"Spec", "spec"> {
let genVerifyDecl = 1;
}
+//===----------------------------------------------------------------------===//
+// TypeOffsetAttr
+//===----------------------------------------------------------------------===//
+
+def Ptr_TypeOffsetAttr : Ptr_Attr<"TypeOffset", "type_offset", [
+ TypedAttrInterface
+ ]> {
+ let summary = "Type offset constant.";
+ let description = [{
+ The `type_offset` attribute specifies an unrealized target-specific
+ constant representing the offset of a single element of the given type. This
+ attribute eventually has to be materialized using a data layout to an
+ integer constant.
+
+ Furthermore, `type_offset` is a typed attribute, where the type of the
+ attribute must be a sign-less int or index.
+
+ Example:
+
+ ```mlir
+ // The offset between two f32 stored in memory
+ #ptr.type_offset<f32> : i32
+ ```
+ }];
+ let parameters = (ins "::mlir::Type":$element_type,
+ AttributeSelfTypeParameter<"">:$type);
+ let builders = [
+ AttrBuilderWithInferredContext<(ins "::mlir::Type":$elementType,
+ "::mlir::Type":$type), [{
+ return $_get(type.getContext(), elementType, type);
+ }]>,
+ ];
+ let assemblyFormat = "`<` $element_type `>` `:` $type";
+ let skipDefaultBuilders = 1;
+ let genVerifyDecl = 1;
+ let extraClassDeclaration = [{
+ /// Returns the type offset according to `maybeLayout`.
+ llvm::TypeSize getTypeSize(const DataLayout &layout) const;
+ }];
+}
+
#endif // PTR_ATTRDEFS
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
index a25885be9915b..dc0a3ffd4ae33 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrAttrs.h
@@ -13,7 +13,10 @@
#ifndef MLIR_DIALECT_PTR_IR_PTRATTRS_H
#define MLIR_DIALECT_PTR_IR_PTRATTRS_H
+#include "mlir/IR/BuiltinAttributeInterfaces.h"
#include "mlir/IR/OpImplementation.h"
+#include "mlir/Interfaces/DataLayoutInterfaces.h"
+#include "llvm/Support/TypeSize.h"
#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
index 3b35da0d280ce..ffa609285c75d 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
@@ -70,7 +70,7 @@ def AtomicOrdering : I64EnumAttr<
// Ptr add flags enum attr.
//===----------------------------------------------------------------------===//
-def Ptr_PtrAddFlags : I32EnumAttr<"PtrAddFlags", "Pointer add flags", [
+def Ptr_PtrAddFlags : I32Enum<"PtrAddFlags", "Pointer add flags", [
I32EnumAttrCase<"none", 0>, I32EnumAttrCase<"nusw", 1>,
I32EnumAttrCase<"nuw", 2>, I32EnumAttrCase<"inbounds", 3>
]> {
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index d172f1574d5a1..a9f30adca19a3 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -21,40 +21,44 @@ include "mlir/IR/OpAsmInterface.td"
// PtrAddOp
//===----------------------------------------------------------------------===//
-def Ptr_PtrAddOp : Pointer_Op<"ptradd", [
- Pure, AllTypesMatch<["base", "result"]>,
- DeclareOpInterfaceMethods<ViewLikeOpInterface>
+def Ptr_PtrAddOp : Pointer_Op<"ptr_add", [
+ Pure, AllTypesMatch<["base", "result"]>, ViewLikeOpInterface
]> {
let summary = "Pointer add operation";
let description = [{
- The `ptradd` operation adds an integer offset to a pointer to produce a new
+ The `ptr_add` operation adds an integer offset to a pointer to produce a new
pointer. The input and output pointer types are always the same.
Example:
```mlir
- %x_off = ptr.ptradd %x, %off : !ptr.ptr<0>, i32
- %x_off0 = ptr.ptradd nusw %x, %off : !ptr.ptr<0>, i32
+ %x_off = ptr.ptr_add %x, %off : !ptr.ptr<0>, i32
+ %x_off0 = ptr.ptr_add nusw %x, %off : !ptr.ptr<0>, i32
```
}];
let arguments = (ins
Ptr_PtrType:$base,
AnySignlessIntegerOrIndex:$offset,
- DefaultValuedAttr<Ptr_PtrAddFlags,
- "::mlir::ptr::PtrAddFlags::none">:$flags);
+ DefaultValuedProp<EnumProp<Ptr_PtrAddFlags>, "PtrAddFlags::none">:$flags);
let results = (outs Ptr_PtrType:$result);
let assemblyFormat = [{
($flags^)? $base `,` $offset attr-dict `:` type($base) `,` type($offset)
}];
let hasFolder = 1;
+ let extraClassDeclaration = [{
+ /// `ViewLikeOp::getViewSource` method.
+ Value getViewSource() { return getBase(); }
+ }];
}
//===----------------------------------------------------------------------===//
// TypeOffsetOp
//===----------------------------------------------------------------------===//
-def Ptr_TypeOffsetOp : Pointer_Op<"type_offset", [ConstantLike, Pure]> {
+def Ptr_TypeOffsetOp : Pointer_Op<"type_offset", [
+ ConstantLike, Pure, AllTypesMatch<["offset", "result"]>
+ ]> {
let summary = "Type offset operation";
let description = [{
The `type_offset` operation produces an int or index-typed SSA value
@@ -64,25 +68,27 @@ def Ptr_TypeOffsetOp : Pointer_Op<"type_offset", [ConstantLike, Pure]> {
Example:
```mlir
- %0 = ptr.type_offset f32 : index
- %1 = ptr.type_offset memref<12 x f64> : i32
+ // Return the offset between two f32 stored in memory
+ %0 = ptr.type_offset <f32> : index
+ // Return the offset between two memref descriptors stored in memory
+ %1 = ptr.type_offset <memref<12 x f64>> : i32
```
}];
- let arguments = (ins TypeAttr:$element_type);
+ let arguments = (ins Ptr_TypeOffsetAttr:$offset);
let results = (outs AnySignlessIntegerOrIndex:$result);
let builders = [
- OpBuilder<(ins "TypeAttr":$element_type)>
+ OpBuilder<(ins "TypeOffsetAttr":$offset)>
];
let assemblyFormat = [{
- $element_type attr-dict `:` type($result)
+ attr-dict $offset
}];
+ let hasFolder = 1;
let extraClassDeclaration = [{
/// Returns the type offset according to `maybeLayout`. If `maybeLayout` is
/// `nullopt` the nearest layout the op will be used for the computation.
llvm::TypeSize getTypeSize(std::optional<DataLayout> layout = std::nullopt);
}];
- let hasFolder = 1;
}
#endif // PTR_OPS
diff --git a/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp b/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp
index d1f778e72395e..82b5ee5c2a0e8 100644
--- a/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp
+++ b/mlir/lib/Dialect/Ptr/IR/PtrAttrs.cpp
@@ -20,35 +20,35 @@ using namespace mlir::ptr;
constexpr const static unsigned kBitsInByte = 8;
//===----------------------------------------------------------------------===//
-// IAddressSpaceAttr
+// GenericSpaceAttr
//===----------------------------------------------------------------------===//
-LogicalResult IAddressSpaceAttr::isValidLoad(
+LogicalResult GenericSpaceAttr::isValidLoad(
Type type, ptr::AtomicOrdering ordering, IntegerAttr alignment,
function_ref<InFlightDiagnostic()> emitError) const {
return success();
}
-LogicalResult IAddressSpaceAttr::isValidStore(
+LogicalResult GenericSpaceAttr::isValidStore(
Type type, ptr::AtomicOrdering ordering, IntegerAttr alignment,
function_ref<InFlightDiagnostic()> emitError) const {
return success();
}
-LogicalResult IAddressSpaceAttr::isValidAtomicOp(
+LogicalResult GenericSpaceAttr::isValidAtomicOp(
ptr::AtomicBinOp op, Type type, ptr::AtomicOrdering ordering,
IntegerAttr alignment, function_ref<InFlightDiagnostic()> emitError) const {
return success();
}
-LogicalResult IAddressSpaceAttr::isValidAtomicXchg(
+LogicalResult GenericSpaceAttr::isValidAtomicXchg(
Type type, ptr::AtomicOrdering successOrdering,
ptr::AtomicOrdering failureOrdering, IntegerAttr alignment,
function_ref<InFlightDiagnostic()> emitError) const {
return success();
}
-LogicalResult IAddressSpaceAttr::isValidAddrSpaceCast(
+LogicalResult GenericSpaceAttr::isValidAddrSpaceCast(
Type tgt, Type src, function_ref<InFlightDiagnostic()> emitError) const {
// TODO: update this method once the `addrspace_cast` op is added to the
// dialect.
@@ -56,7 +56,7 @@ LogicalResult IAddressSpaceAttr::isValidAddrSpaceCast(
return failure();
}
-LogicalResult IAddressSpaceAttr::isValidPtrIntCast(
+LogicalResult GenericSpaceAttr::isValidPtrIntCast(
Type intLikeTy, Type ptrLikeTy,
function_ref<InFlightDiagnostic()> emitError) const {
// TODO: update this method once the int-cast ops are added to the dialect.
@@ -84,3 +84,20 @@ LogicalResult SpecAttr::verify(function_ref<InFlightDiagnostic()> emitError,
"as large as ABI alignment";
return success();
}
+
+//===----------------------------------------------------------------------===//
+// SpecAttr
+//===----------------------------------------------------------------------===//
+
+LogicalResult
+TypeOffsetAttr::verify(function_ref<InFlightDiagnostic()> emitError,
+ Type elementType, Type type) {
+ if (!type.isSignlessIntOrIndex())
+ return emitError()
+ << "expected a sign-less int or index type for the attr type";
+ return success();
+}
+
+llvm::TypeSize TypeOffsetAttr::getTypeSize(const DataLayout &layout) const {
+ return layout.getTypeSize(getElementType());
+}
diff --git a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
index 9a90682865654..e6c9f8e0e2132 100644
--- a/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
+++ b/mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp
@@ -55,21 +55,17 @@ OpFoldResult PtrAddOp::fold(FoldAdaptor adaptor) {
return nullptr;
}
-Value PtrAddOp::getViewSource() { return getBase(); }
-
//===----------------------------------------------------------------------===//
// TypeOffsetOp
//===----------------------------------------------------------------------===//
-OpFoldResult TypeOffsetOp::fold(FoldAdaptor adaptor) {
- return TypeAttr::get(getElementType());
-}
+OpFoldResult TypeOffsetOp::fold(FoldAdaptor adaptor) { return getOffset(); }
llvm::TypeSize TypeOffsetOp::getTypeSize(std::optional<DataLayout> layout) {
if (layout)
- return layout->getTypeSize(getElementType());
+ return getOffset().getTypeSize(*layout);
DataLayout dl = DataLayout::closest(*this);
- return dl.getTypeSize(getElementType());
+ return getOffset().getTypeSize(dl);
}
//===----------------------------------------------------------------------===//
diff --git a/mlir/test/Dialect/Ptr/canonicalize.mlir b/mlir/test/Dialect/Ptr/canonicalize.mlir
index be6ce673aabdc..63558bf47d1d4 100644
--- a/mlir/test/Dialect/Ptr/canonicalize.mlir
+++ b/mlir/test/Dialect/Ptr/canonicalize.mlir
@@ -1,33 +1,24 @@
// RUN: mlir-opt --canonicalize %s | FileCheck %s
-/// Check `ptradd` and `type_offset` canonicalizer patterns.
+/// Check `ptr_add` and `type_offset` canonicalizer patterns.
// CHECK-LABEL: @ops0
-func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space<3>>, %c: i1) -> !ptr.ptr<#ptr.int_space<3>> {
- // CHECK: (%[[PTR_0:.*]]: !ptr.ptr<#ptr.int_space<3>>,
- // CHECK: %[[F32_OFF:.*]] = ptr.type_offset f32 : index
- // CHECK: %[[PTR_1:.*]] = ptr.ptradd %[[PTR_0]], %[[F32_OFF]] : <#ptr.int_space<3>>, index
- // CHECK: %[[PTR_2:.*]] = ptr.ptradd %[[PTR_1]], %[[F32_OFF]] : <#ptr.int_space<3>>, index
- // CHECK: %[[PTR_3:.*]] = scf.if %{{.*}} -> (!ptr.ptr<#ptr.int_space<3>>) {
- // CHECK: %[[PTR_4:.*]] = ptr.ptradd %[[PTR_2]], %[[F32_OFF]] : <#ptr.int_space<3>>, index
- // CHECK: scf.yield %[[PTR_4]] : !ptr.ptr<#ptr.int_space<3>>
- // CHECK: } else {
- // CHECK: scf.yield %[[PTR_0]] : !ptr.ptr<#ptr.int_space<3>>
- // CHECK: }
- // CHECK: return %[[PTR_3]] : !ptr.ptr<#ptr.int_space<3>>
+func.func @ops0() -> (i32, i32) {
+ // CHECK: %[[F32_OFF:.*]] = ptr.type_offset <f32> : i32
+ // CHECK: return %[[F32_OFF]], %[[F32_OFF]] : i32, i32
+ %off0 = ptr.type_offset <f32> : i32
+ %off1 = ptr.type_offset <f32> : i32
+ return %off0, %off1 : i32, i32
+}
+
+// CHECK-LABEL: @ops1
+func.func @ops1(%ptr: !ptr.ptr<#ptr.generic_space>) -> !ptr.ptr<#ptr.generic_space> {
+ // CHECK: (%[[PTR_0:.*]]: !ptr.ptr<#ptr.generic_space>)
+ // CHECK-NOT: index.constant
+ // CHECK-NOT: ptr.ptr_add
+ // CHECK: return %[[PTR_0]] : !ptr.ptr<#ptr.generic_space>
// CHECK: }
- %off0 = ptr.type_offset f32 : index
- %res0 = ptr.ptradd %ptr, %off0 : !ptr.ptr<#ptr.int_space<3>>, index
- %off1 = ptr.type_offset f32 : index
- %res1 = ptr.ptradd %res0, %off1 : !ptr.ptr<#ptr.int_space<3>>, index
- %res3 = scf.if %c -> !ptr.ptr<#ptr.int_space<3>> {
- %off2 = ptr.type_offset f32 : index
- %res2 = ptr.ptradd %res1, %off2 : !ptr.ptr<#ptr.int_space<3>>, index
- scf.yield %res2 : !ptr.ptr<#ptr.int_space<3>>
- } else {
- scf.yield %ptr : !ptr.ptr<#ptr.int_space<3>>
- }
- %off3 = index.constant 0
- %res4 = ptr.ptradd %res3, %off3 : !ptr.ptr<#ptr.int_space<3>>, index
- return %res4 : !ptr.ptr<#ptr.int_space<3>>
+ %off = index.constant 0
+ %res0 = ptr.ptr_add %ptr, %off : !ptr.ptr<#ptr.generic_space>, index
+ return %res0 : !ptr.ptr<#ptr.generic_space>
}
diff --git a/mlir/test/Dialect/Ptr/ops.mlir b/mlir/test/Dialect/Ptr/ops.mlir
index ab1a9dac3a5d9..848f8014c2c1d 100644
--- a/mlir/test/Dialect/Ptr/ops.mlir
+++ b/mlir/test/Dialect/Ptr/ops.mlir
@@ -1,15 +1,19 @@
// RUN: mlir-opt %s --verify-roundtrip | FileCheck %s
/// Check op assembly.
-func.func @ops0(%ptr: !ptr.ptr<#ptr.int_space>) -> !ptr.ptr<#ptr.int_space> {
+func.func @ops0(%ptr: !ptr.ptr<#ptr.generic_space>) -> !ptr.ptr<#ptr.generic_space> {
// CHECK-LABEL: @ops0
- // CHECK: ptr.type_offset f32 : index
- // CHECK-NEXT: ptr.ptradd %{{.*}}, %{{.*}} : <#ptr.int_space>, index
- %off = ptr.type_offset f32 : index
- %res = ptr.ptradd %ptr, %off : !ptr.ptr<#ptr.int_space>, index
- %res0 = ptr.ptradd none %ptr, %off : !ptr.ptr<#ptr.int_space>, index
- %res1 = ptr.ptradd nusw %ptr, %off : !ptr.ptr<#ptr.int_space>, index
- %res2 = ptr.ptradd nuw %ptr, %off : !ptr.ptr<#ptr.int_space>, index
- %res3 = ptr.ptradd inbounds %ptr, %off : !ptr.ptr<#ptr.int_space>, index
- return %res : !ptr.ptr<#ptr.int_space>
+ // CHECK: ptr.type_offset <f32> : index
+ // CHECK-NEXT: ptr.ptr_add %{{.*}}, %{{.*}} : <#ptr.generic_space>, index
+ // CHECK-NEXT: ptr.ptr_add %{{.*}}, %{{.*}} : <#ptr.generic_space>, index
+ // CHECK-NEXT: ptr.ptr_add nusw %{{.*}}, %{{.*}} : <#ptr.generic_space>, index
+ // CHECK-NEXT: ptr.ptr_add nuw %{{.*}}, %{{.*}} : <#ptr.generic_space>, index
+ // CHECK-NEXT: ptr.ptr_add inbounds %{{.*}}, %{{.*}} : <#ptr.generic_space>, index
+ %off = ptr.type_offset <f32> : index
+ %res = ptr.ptr_add %ptr, %off : !ptr.ptr<#ptr.generic_space>, index
+ %res0 = ptr.ptr_add none %ptr, %off : !ptr.ptr<#ptr.generic_space>, index
+ %res1 = ptr.ptr_add nusw %ptr, %off : !ptr.ptr<#ptr.generic_space>, index
+ %res2 = ptr.ptr_add nuw %ptr, %off : !ptr.ptr<#ptr.generic_space>, index
+ %res3 = ptr.ptr_add inbounds %ptr, %off : !ptr.ptr<#ptr.generic_space>, index
+ return %res : !ptr.ptr<#ptr.generic_space>
}
More information about the Mlir-commits
mailing list