[llvm-branch-commits] [mlir] [clang] [llvm] Refactor ModuleToObject to offer more flexibility to subclass (NFC) (PR #71165)

2023-11-03 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg commented:

Overall LGTM, see the only comment.

https://github.com/llvm/llvm-project/pull/71165
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [mlir] [clang] Refactor ModuleToObject to offer more flexibility to subclass (NFC) (PR #71165)

2023-11-03 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg edited 
https://github.com/llvm/llvm-project/pull/71165
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [llvm] [mlir] [clang] Refactor ModuleToObject to offer more flexibility to subclass (NFC) (PR #71165)

2023-11-03 Thread Fabian Mora via llvm-branch-commits


@@ -39,32 +39,32 @@ ModuleToObject::ModuleToObject(Operation &module, StringRef 
triple,
 : module(module), triple(triple), chip(chip), features(features),
   optLevel(optLevel) {}
 
+ModuleToObject::~ModuleToObject() = default;
+
 Operation &ModuleToObject::getOperation() { return module; }
 
-std::unique_ptr ModuleToObject::createTargetMachine() {
+std::optional
+ModuleToObject::getOrCreateTargetMachine() {
   std::string error;

fabianmcg wrote:

Is there a reason why the cached `targetMachine` is not immediately returned? 
```suggestion
  if (targetMachine)
return targetMachine.get();
  std::string error;
```

https://github.com/llvm/llvm-project/pull/71165
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [libcxxabi] [flang] [libcxx] [llvm] [clang] [mlir] [clang-tools-extra] [lldb] [lld] [compiler-rt] Refactor ModuleToObject to offer more flexibility to subclass (NFC) (PR #71165)

2023-11-03 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg approved this pull request.


https://github.com/llvm/llvm-project/pull/71165
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Add translations to LLVMIR for ptr ops. (PR #156355)

2025-09-01 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg created 
https://github.com/llvm/llvm-project/pull/156355

Implements translation from ptr dialect to LLVM IR for core pointer operations:
- `ptr.ptr_add` -> `getelementptr`
- `ptr.load` -> `load` with atomic ordering, volatility, and metadata support
- `ptr.store` -> `store` with atomic ordering, volatility, and metadata support 
 
- `ptr.type_offset` -> GEP-based size computation

Example:

```mlir
llvm.func @test(%arg0: !ptr.ptr<#llvm.address_space<0>>) {
  %0 = ptr.type_offset f64 : i32
  %1 = ptr.ptr_add inbounds %arg0, %0 : !ptr.ptr<#llvm.address_space<0>>, i32
  %2 = ptr.load volatile %1 : !ptr.ptr<#llvm.address_space<0>> -> f64
  ptr.store %2, %arg0 : f64, !ptr.ptr<#llvm.address_space<0>>
  llvm.return
}
```
Translates to:
```llvm
define void @test(ptr %0) {
  %2 = getelementptr inbounds i8, ptr %0, i32 8
  %3 = load volatile double, ptr %2, align 8
  store double %3, ptr %0, align 8
  ret void
}
```

>From d4befc04b5565fd13cc53694031bf8296fd22312 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Mon, 1 Sep 2025 16:32:01 +
Subject: [PATCH] add translations for ptr ops

---
 .../include/mlir/Dialect/LLVMIR/LLVMOpBase.td |   3 +-
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 210 +-
 mlir/test/Target/LLVMIR/ptr.mlir  |  75 +++
 3 files changed, 278 insertions(+), 10 deletions(-)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
index d6aa9580870a8..bd59319c79ad3 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
@@ -95,8 +95,7 @@ def LLVM_NonLoadableTargetExtType : Type<
 // type that has size (not void, function, opaque struct type or target
 // extension type which does not support memory operations).
 def LLVM_LoadableType : Type<
-  Or<[And<[LLVM_PrimitiveType.predicate, Neg,
-  Neg]>,
+  Or<[CPred<"mlir::LLVM::isLoadableType($_self)">,
   LLVM_PointerElementTypeInterface.predicate]>,
   "LLVM type with size">;
 
diff --git a/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp 
b/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp
index 7b89ec8fcbffb..e3ccf728f25db 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp
@@ -16,11 +16,193 @@
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/Operation.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
 
 using namespace mlir;
 using namespace mlir::ptr;
 
 namespace {
+
+/// Converts ptr::AtomicOrdering to llvm::AtomicOrdering
+static llvm::AtomicOrdering
+convertAtomicOrdering(ptr::AtomicOrdering ordering) {
+  switch (ordering) {
+  case ptr::AtomicOrdering::not_atomic:
+return llvm::AtomicOrdering::NotAtomic;
+  case ptr::AtomicOrdering::unordered:
+return llvm::AtomicOrdering::Unordered;
+  case ptr::AtomicOrdering::monotonic:
+return llvm::AtomicOrdering::Monotonic;
+  case ptr::AtomicOrdering::acquire:
+return llvm::AtomicOrdering::Acquire;
+  case ptr::AtomicOrdering::release:
+return llvm::AtomicOrdering::Release;
+  case ptr::AtomicOrdering::acq_rel:
+return llvm::AtomicOrdering::AcquireRelease;
+  case ptr::AtomicOrdering::seq_cst:
+return llvm::AtomicOrdering::SequentiallyConsistent;
+  }
+  llvm_unreachable("Unknown atomic ordering");
+}
+
+/// Convert ptr.ptr_add operation
+static LogicalResult
+convertPtrAddOp(PtrAddOp ptrAddOp, llvm::IRBuilderBase &builder,
+LLVM::ModuleTranslation &moduleTranslation) {
+  llvm::Value *basePtr = moduleTranslation.lookupValue(ptrAddOp.getBase());
+  llvm::Value *offset = moduleTranslation.lookupValue(ptrAddOp.getOffset());
+
+  if (!basePtr || !offset)
+return ptrAddOp.emitError("Failed to lookup operands");
+
+  // Create GEP instruction for pointer arithmetic
+  llvm::GetElementPtrInst *gep = llvm::GetElementPtrInst::Create(
+  builder.getInt8Ty(), basePtr, {offset}, "", builder.GetInsertBlock());
+
+  // Set the appropriate flags
+  switch (ptrAddOp.getFlags()) {
+  case ptr::PtrAddFlags::none:
+break;
+  case ptr::PtrAddFlags::nusw:
+gep->setNoWrapFlags(llvm::GEPNoWrapFlags::noUnsignedSignedWrap());
+break;
+  case ptr::PtrAddFlags::nuw:
+gep->setNoWrapFlags(llvm::GEPNoWrapFlags::noUnsignedWrap());
+break;
+  case ptr::PtrAddFlags::inbounds:
+gep->setNoWrapFlags(llvm::GEPNoWrapFlags::inBounds());
+break;
+  }
+
+  moduleTranslation.mapValue(ptrAddOp.getResult(), gep);
+  return success();
+}
+
+/// Convert ptr.load operation
+static LogicalResult convertLoadOp(LoadOp loadOp, llvm::IRBuilderBase &builder,
+   LLVM::ModuleTranslation &moduleTranslation) 
{
+  llvm::Value *ptr =

[llvm-branch-commits] [mlir] [mlir][ptr] Extend `ptr_add` operation to support shaped operands (PR #156374)

2025-09-03 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg created 
https://github.com/llvm/llvm-project/pull/156374

This patch extends `ptr_add` to work with shaped types with value semantics, 
both for the offsets and base.

Concretely this patch makes the following changes:
- Supports scalar-to-scalar, scalar-to-shaped, shaped-to-scalar, and 
shaped-to-shaped combinations
- Adds InferTypeOpInterface for automatic result type deduction
- Adds tests for LLVM IR translation with vector operands

Example:
```mlir
func.func @ptr_add_tensor_2d(%ptrs: tensor<4x8x!ptr.ptr<#ptr.generic_space>>, 
%offsets: tensor<4x8xindex>) -> tensor<4x8x!ptr.ptr<#ptr.generic_space>> {
  %res = ptr.ptr_add %ptrs, %offsets : 
tensor<4x8x!ptr.ptr<#ptr.generic_space>>, tensor<4x8xindex>
  %res1 = ptr.ptr_add nuw %ptrs, %offsets : 
tensor<4x8x!ptr.ptr<#ptr.generic_space>>, tensor<4x8xindex>
  return %res : tensor<4x8x!ptr.ptr<#ptr.generic_space>>
}
```

The motivation behind this patch is to lay the groundwork for enabling `triton` 
styled loads and stores, and their variants. 

>From 6b3215582cde39f2c381933b2634029f72b6274a Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Mon, 1 Sep 2025 21:05:55 +
Subject: [PATCH] extend ptr_add op

---
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h |   1 +
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 103 +++---
 mlir/lib/Dialect/Ptr/IR/CMakeLists.txt|   1 +
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp|  40 +++
 .../Conversion/PtrToLLVM/ptr-to-llvm.mlir |  12 +-
 mlir/test/Dialect/Ptr/invalid.mlir|  16 +++
 mlir/test/Dialect/Ptr/ops.mlir|  65 +++
 mlir/test/Target/LLVMIR/ptr.mlir  |  30 +
 8 files changed, 225 insertions(+), 43 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
index 8686cc7d316d4..eaf1e6243a74d 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/InferTypeOpInterface.h"
 #include "mlir/Interfaces/SideEffectInterfaces.h"
 #include "mlir/Interfaces/ViewLikeInterface.h"
 
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 59eaaf7c55cce..43e19d0e2917c 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -13,6 +13,7 @@ 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/InferTypeOpInterface.td"
 include "mlir/Interfaces/SideEffectInterfaces.td"
 include "mlir/Interfaces/ViewLikeInterface.td"
 include "mlir/IR/OpAsmInterface.td"
@@ -34,8 +35,15 @@ class Ptr_ShapedValueType allowedTypes, 
list preds = []> :
 /*descr=*/[{A shaped type with value semantics and rank.}],
 /*cppType=*/"::mlir::ShapedType">;
 
-// A shaped pointer type with value semantics and rank.
-class Ptr_ShapedPtrType : Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>;
+// A ptr-like type, either scalar or shaped type with value semantics.
+def Ptr_PtrLikeType : 
+  AnyTypeOf<[Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>, Ptr_PtrType]>;
+
+// An int-like type, either scalar or shaped type with value semantics.
+def Ptr_IntLikeType :AnyTypeOf<[
+  Ptr_ShapedValueType<[AnySignlessIntegerOrIndex], [HasRankPred]>,
+  AnySignlessIntegerOrIndex
+]>;
 
 // A shaped value type of rank 1 of any element type.
 def Ptr_Any1DType :
@@ -175,41 +183,6 @@ def Ptr_GetMetadataOp : Pointer_Op<"get_metadata", [
   }];
 }
 
-//===--===//
-// PtrAddOp
-//===--===//
-
-def Ptr_PtrAddOp : Pointer_Op<"ptr_add", [
-Pure, AllTypesMatch<["base", "result"]>, ViewLikeOpInterface
-  ]> {
-  let summary = "Pointer add operation";
-  let description = [{
-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.ptr_add %x, %off : !ptr.ptr<#ptr.generic_space>, i32
-%x_off0 = ptr.ptr_add nusw %x, %off : !ptr.ptr<#ptr.generic_space>, i32
-```
-  }];
-
-  let arguments = (ins
-Ptr_PtrType:$base,
-AnySignlessIntegerOrIndex:$offset,
-DefaultValuedProp, "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(); }
-  }];
-}

[llvm-branch-commits] [mlir] [mlir][ptr] Add `gather`, `masked_load`, `masked_store`, and `scatter` ops (PR #156368)

2025-09-03 Thread Fabian Mora via llvm-branch-commits


@@ -17,6 +17,46 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
 include "mlir/Interfaces/ViewLikeInterface.td"
 include "mlir/IR/OpAsmInterface.td"
 
+//===--===//
+// Common props
+//===--===//
+
+def AlignmentProp : OptionalProp;
+
+//===--===//
+// Common types
+//===--===//
+
+// A shaped value type with value semantics and rank.
+class Ptr_ShapedValueType allowedTypes, list preds = []> :
+  ShapedContainerType,
+/*descr=*/[{A shaped type with value semantics and rank.}],
+/*cppType=*/"::mlir::ShapedType">;
+
+// A shaped pointer type with value semantics and rank.
+class Ptr_ShapedPtrType : Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>;
+
+// A shaped value type of rank 1 of any element type.
+def Ptr_Any1DType :
+  Ptr_ShapedValueType<[AnyType], [HasAnyRankOfPred<[1]>]>;
+
+// A shaped value type of rank 1 of `i1` element type.
+def Ptr_Mask1DType :
+  Ptr_ShapedValueType<[I1], [HasAnyRankOfPred<[1]>]>;
+
+// A shaped value type of rank 1 of `i1` element type.
+def Ptr_Ptr1DType :
+  Ptr_ShapedValueType<[Ptr_PtrType], [HasAnyRankOfPred<[1]>]>;
+
+// Gets the type ID of a type.  
+class TypeIDType :
+StrFunc<"$" # name # ".getType().getTypeID()">;
+
+// Checks that all type IDs match.
+class AllTypeIDsMatch names> :

fabianmcg wrote:

I didn't add it to `OpBase.td` because this is the only consumer. I'll move it 
to `OpBase.td`.

https://github.com/llvm/llvm-project/pull/156368
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Add `ptr.ptr_diff` operation (PR #157354)

2025-09-07 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg updated 
https://github.com/llvm/llvm-project/pull/157354

>From 5e4b9843521939d926c7fcc4007d38a8f4c320a6 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Sun, 7 Sep 2025 17:33:04 +
Subject: [PATCH] [mlir][ptr] Add `ptr.ptr_diff` op

Thi patch introduces the `ptr.ptr_diff` operation for computing pointer
differences. The semantics of the operation are given by:
```
The `ptr_diff` operation computes the difference between two pointers,
returning an integer or index value representing the number of bytes
between them. This difference is always computed using signed arithmetic.

The operation supports both scalar and shaped types with value semantics:
- When both operands are scalar: produces a single difference value
- When both are shaped: performs element-wise subtraction,
  shapes must be the same

The operation also supports the following flags:
- `none`: No flags are set.
- `nuw`: No Unsigned Wrap, if the subtraction causes an unsigned overflow,
  the result is a poison value.
- `nsw`: No Signed Wrap, if the subtraction causes a signed overflow, the
  result is a poison value.

NOTE: The pointer difference is calculated using an integer type specified
by the data layout. The final result will be sign-extended or truncated to
fit the result type as necessary.
```

This patch also adds translation to LLVM IR hooks for the `ptr_diff` op.
This translation uses the `ptrtoaddr` builder to compute only index
bits difference.

Example:
```mlir
llvm.func @ptr_diff_vector_i32(%ptrs1: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>, %ptrs2: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>) -> vector<8xi32> {
  %diffs = ptr.ptr_diff %ptrs1, %ptrs2 : 
vector<8x!ptr.ptr<#llvm.address_space<0>>> -> vector<8xi32>
  llvm.return %diffs : vector<8xi32>
}
```
Translation to LLVM IR:
```llvm
define <8 x i32> @ptr_diff_vector_i32(<8 x ptr> %0, <8 x ptr> %1) {
  %3 = ptrtoint <8 x ptr> %0 to <8 x i64>
  %4 = ptrtoint <8 x ptr> %1 to <8 x i64>
  %5 = sub <8 x i64> %3, %4
  %6 = trunc <8 x i64> %5 to <8 x i32>
  ret <8 x i32> %6
}
```
---
 mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td  | 10 ++
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 57 +++
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp| 34 +++
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 37 +++
 mlir/test/Dialect/Ptr/invalid.mlir|  8 ++
 mlir/test/Dialect/Ptr/ops.mlir| 28 ++
 mlir/test/Target/LLVMIR/ptr.mlir  | 96 +++
 7 files changed, 270 insertions(+)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
index c169f48e573d0..c97bd04d32896 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
@@ -79,4 +79,14 @@ def Ptr_PtrAddFlags : I32Enum<"PtrAddFlags", "Pointer add 
flags", [
   let cppNamespace = "::mlir::ptr";
 }
 
+//===--===//
+// Ptr diff flags enum properties.
+//===--===//
+
+def Ptr_PtrDiffFlags : I8BitEnum<"PtrDiffFlags", "Pointer difference flags", [
+I8BitEnumCase<"none", 0>, I8BitEnumCase<"nuw", 1>, I8BitEnumCase<"nsw", 2>
+  ]> {
+  let cppNamespace = "::mlir::ptr";
+}
+
 #endif // PTR_ENUMS
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 468a3004d5c62..7735210e809e3 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -415,6 +415,63 @@ def Ptr_PtrAddOp : Pointer_Op<"ptr_add", [
   }];
 }
 
+//===--===//
+// PtrDiffOp
+//===--===//
+
+def Ptr_PtrDiffOp : Pointer_Op<"ptr_diff", [
+Pure, AllTypesMatch<["lhs", "rhs"]>, SameOperandsAndResultShape
+  ]> {
+  let summary = "Pointer difference operation";
+  let description = [{
+The `ptr_diff` operation computes the difference between two pointers,
+returning an integer or index value representing the number of bytes
+between them. This difference is always computed using signed arithmetic.
+
+The operation supports both scalar and shaped types with value semantics:
+- When both operands are scalar: produces a single difference value
+- When both are shaped: performs element-wise subtraction,
+  shapes must be the same
+
+The operation also supports the following flags:
+- `none`: No flags are set.
+- `nuw`: No Unsigned Wrap, if the subtraction causes an unsigned overflow,
+  the result is a poison value.
+- `nsw`: No Signed Wrap, if the subtraction causes a signed overflow, the
+  result is a poison value.
+
+NOTE: The pointer difference is calculated using an integer type specified
+by the data layout. The 

[llvm-branch-commits] [mlir] [mlir][ptr] Add `ptr.ptr_diff` operation (PR #157354)

2025-09-07 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg edited 
https://github.com/llvm/llvm-project/pull/157354
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Add `ptr.ptr_diff` operation (PR #157354)

2025-09-07 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg created 
https://github.com/llvm/llvm-project/pull/157354

Thi patch introduces the `ptr.ptr_diff` operation for computing pointer 
differences. The semantics of the operation are given by:
```
The `ptr_diff` operation computes the difference between two pointers,
returning an integer or index value representing the number of bytes
between them. This difference is always computed using signed arithmetic.

The operation supports both scalar and shaped types with value semantics:
- When both operands are scalar: produces a single difference value
- When both are shaped: performs element-wise subtraction,
  shapes must be the same

The operation also supports the following flags:
- `none`: No flags are set.
- `nuw`: No Unsigned Wrap, if the addition causes an unsigned overflow,
  the result is a poison value.
- `nsw`: No Signed Wrap, if the addition causes a signed overflow, the
  result is a poison value.

NOTE: The pointer difference is calculated using an integer type specified
by the data layout. The final result will be sign-extended or truncated to
fit the result type as necessary.
```

This patch also adds translation to LLVM IR hooks for the `ptr_diff` op. This 
translation uses the `ptrtoaddr` builder to compute only index bits difference.

Example:
```mlir
llvm.func @ptr_diff_vector_i32(%ptrs1: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>, %ptrs2: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>) -> vector<8xi32> {
  %diffs = ptr.ptr_diff %ptrs1, %ptrs2 : 
vector<8x!ptr.ptr<#llvm.address_space<0>>> -> vector<8xi32>
  llvm.return %diffs : vector<8xi32>
}
```
Translation to LLVM IR:
```llvm
define <8 x i32> @ptr_diff_vector_i32(<8 x ptr> %0, <8 x ptr> %1) {
  %3 = ptrtoint <8 x ptr> %0 to <8 x i64>
  %4 = ptrtoint <8 x ptr> %1 to <8 x i64>
  %5 = sub <8 x i64> %3, %4
  %6 = trunc <8 x i64> %5 to <8 x i32>
  ret <8 x i32> %6
}
```

>From f467d256c653bc62d7cee5d3935b9a1d1f47e3b8 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Sun, 7 Sep 2025 17:33:04 +
Subject: [PATCH] [mlir][ptr] Add `ptr.ptr_diff` op

Thi patch introduces the `ptr.ptr_diff` operation for computing pointer
differences. The semantics of the operation are given by:
```
The `ptr_diff` operation computes the difference between two pointers,
returning an integer or index value representing the number of bytes
between them. This difference is always computed using signed arithmetic.

The operation supports both scalar and shaped types with value semantics:
- When both operands are scalar: produces a single difference value
- When both are shaped: performs element-wise subtraction,
  shapes must be the same

The operation also supports the following flags:
- `none`: No flags are set.
- `nuw`: No Unsigned Wrap, if the addition causes an unsigned overflow,
  the result is a poison value.
- `nsw`: No Signed Wrap, if the addition causes a signed overflow, the
  result is a poison value.

NOTE: The pointer difference is calculated using an integer type specified
by the data layout. The final result will be sign-extended or truncated to
fit the result type as necessary.
```

This patch also adds translation to LLVM IR hooks for the `ptr_diff` op.
This translation uses the `ptrtoaddr` builder to compute only index
bits difference.

Example:
```mlir
llvm.func @ptr_diff_vector_i32(%ptrs1: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>, %ptrs2: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>) -> vector<8xi32> {
  %diffs = ptr.ptr_diff %ptrs1, %ptrs2 : 
vector<8x!ptr.ptr<#llvm.address_space<0>>> -> vector<8xi32>
  llvm.return %diffs : vector<8xi32>
}
```
Translation to LLVM IR:
```llvm
define <8 x i32> @ptr_diff_vector_i32(<8 x ptr> %0, <8 x ptr> %1) {
  %3 = ptrtoint <8 x ptr> %0 to <8 x i64>
  %4 = ptrtoint <8 x ptr> %1 to <8 x i64>
  %5 = sub <8 x i64> %3, %4
  %6 = trunc <8 x i64> %5 to <8 x i32>
  ret <8 x i32> %6
}
```
---
 mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td  | 10 ++
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 57 +++
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp| 34 +++
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 37 +++
 mlir/test/Dialect/Ptr/invalid.mlir|  8 ++
 mlir/test/Dialect/Ptr/ops.mlir| 28 ++
 mlir/test/Target/LLVMIR/ptr.mlir  | 96 +++
 7 files changed, 270 insertions(+)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
index c169f48e573d0..c97bd04d32896 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
@@ -79,4 +79,14 @@ def Ptr_PtrAddFlags : I32Enum<"PtrAddFlags", "Pointer add 
flags", [
   let cppNamespace = "::mlir::ptr";
 }
 
+//===--===//
+// Ptr diff flags enum properties.
+//===--===//
+
+def Ptr_PtrDiffFlags : I8BitEnum<"

[llvm-branch-commits] [mlir] [mlir][ptr] Add `ptr.ptr_diff` operation (PR #157354)

2025-09-14 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg updated 
https://github.com/llvm/llvm-project/pull/157354

>From 4015e6f30fb89b5c0a4bb60ffdc8b3db51b2edc1 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Sun, 7 Sep 2025 17:33:04 +
Subject: [PATCH 1/2] [mlir][ptr] Add `ptr.ptr_diff` op

Thi patch introduces the `ptr.ptr_diff` operation for computing pointer
differences. The semantics of the operation are given by:
```
The `ptr_diff` operation computes the difference between two pointers,
returning an integer or index value representing the number of bytes
between them. This difference is always computed using signed arithmetic.

The operation supports both scalar and shaped types with value semantics:
- When both operands are scalar: produces a single difference value
- When both are shaped: performs element-wise subtraction,
  shapes must be the same

The operation also supports the following flags:
- `none`: No flags are set.
- `nuw`: No Unsigned Wrap, if the subtraction causes an unsigned overflow,
  the result is a poison value.
- `nsw`: No Signed Wrap, if the subtraction causes a signed overflow, the
  result is a poison value.

NOTE: The pointer difference is calculated using an integer type specified
by the data layout. The final result will be sign-extended or truncated to
fit the result type as necessary.
```

This patch also adds translation to LLVM IR hooks for the `ptr_diff` op.
This translation uses the `ptrtoaddr` builder to compute only index
bits difference.

Example:
```mlir
llvm.func @ptr_diff_vector_i32(%ptrs1: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>, %ptrs2: 
vector<8x!ptr.ptr<#llvm.address_space<0>>>) -> vector<8xi32> {
  %diffs = ptr.ptr_diff %ptrs1, %ptrs2 : 
vector<8x!ptr.ptr<#llvm.address_space<0>>> -> vector<8xi32>
  llvm.return %diffs : vector<8xi32>
}
```
Translation to LLVM IR:
```llvm
define <8 x i32> @ptr_diff_vector_i32(<8 x ptr> %0, <8 x ptr> %1) {
  %3 = ptrtoint <8 x ptr> %0 to <8 x i64>
  %4 = ptrtoint <8 x ptr> %1 to <8 x i64>
  %5 = sub <8 x i64> %3, %4
  %6 = trunc <8 x i64> %5 to <8 x i32>
  ret <8 x i32> %6
}
```
---
 mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td  | 10 ++
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 57 +++
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp| 34 +++
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 37 +++
 mlir/test/Dialect/Ptr/invalid.mlir|  8 ++
 mlir/test/Dialect/Ptr/ops.mlir| 28 ++
 mlir/test/Target/LLVMIR/ptr.mlir  | 96 +++
 7 files changed, 270 insertions(+)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
index c169f48e573d0..c97bd04d32896 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrEnums.td
@@ -79,4 +79,14 @@ def Ptr_PtrAddFlags : I32Enum<"PtrAddFlags", "Pointer add 
flags", [
   let cppNamespace = "::mlir::ptr";
 }
 
+//===--===//
+// Ptr diff flags enum properties.
+//===--===//
+
+def Ptr_PtrDiffFlags : I8BitEnum<"PtrDiffFlags", "Pointer difference flags", [
+I8BitEnumCase<"none", 0>, I8BitEnumCase<"nuw", 1>, I8BitEnumCase<"nsw", 2>
+  ]> {
+  let cppNamespace = "::mlir::ptr";
+}
+
 #endif // PTR_ENUMS
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 468a3004d5c62..7735210e809e3 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -415,6 +415,63 @@ def Ptr_PtrAddOp : Pointer_Op<"ptr_add", [
   }];
 }
 
+//===--===//
+// PtrDiffOp
+//===--===//
+
+def Ptr_PtrDiffOp : Pointer_Op<"ptr_diff", [
+Pure, AllTypesMatch<["lhs", "rhs"]>, SameOperandsAndResultShape
+  ]> {
+  let summary = "Pointer difference operation";
+  let description = [{
+The `ptr_diff` operation computes the difference between two pointers,
+returning an integer or index value representing the number of bytes
+between them. This difference is always computed using signed arithmetic.
+
+The operation supports both scalar and shaped types with value semantics:
+- When both operands are scalar: produces a single difference value
+- When both are shaped: performs element-wise subtraction,
+  shapes must be the same
+
+The operation also supports the following flags:
+- `none`: No flags are set.
+- `nuw`: No Unsigned Wrap, if the subtraction causes an unsigned overflow,
+  the result is a poison value.
+- `nsw`: No Signed Wrap, if the subtraction causes a signed overflow, the
+  result is a poison value.
+
+NOTE: The pointer difference is calculated using an integer type specified
+by the data layout. 

[llvm-branch-commits] [mlir] [NFC][mlir][ptr] Clarify pointer dialect semantics (PR #158484)

2025-09-14 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg created 
https://github.com/llvm/llvm-project/pull/158484

This patch adds the following description to the pointer dialect:
```
The pointer dialect provides types and operations for representing and
interacting with pointer values in MLIR, such as loading and storing values
from/to memory addresses.

The dialect's main type is an opaque pointer (`ptr`) that can be
parameterized by a memory space. This type represents a handle to an object
in memory, or target-dependent values like `nullptr`. Further, the dialect
assumes that the minimum addressable unit by a pointer is a byte. However,
the dialect does not make assumptions about the size of a byte, which is
considered a target-specific property.
```

>From 120da3c559522ae1173a35953d92a47e0e4b5421 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Sun, 14 Sep 2025 14:17:38 +
Subject: [PATCH] [NFC][mlir][ptr] Clarify pointer dialect semantics

This patch adds the following description to the pointer dialect:
```
The pointer dialect provides types and operations for representing and
interacting with pointer values in MLIR, such as loading and storing values
from/to memory addresses.

The dialect's main type is an opaque pointer (`ptr`) that can be
parameterized by a memory space. This type represents a handle to an object
in memory, or target-dependent values like `nullptr`. Further, the dialect
assumes that the minimum addressable unit by a pointer is a byte. However,
the dialect does not make assumptions about the size of a byte, which is
considered a target-specific property.
```
---
 mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td | 12 
 1 file changed, 12 insertions(+)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
index 7407d74ce3a87..c98df5775195a 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrDialect.td
@@ -21,6 +21,18 @@ include "mlir/IR/OpBase.td"
 def Ptr_Dialect : Dialect {
   let name = "ptr";
   let summary = "Pointer dialect";
+  let description = [{
+The pointer dialect provides types and operations for representing and
+interacting with pointer values in MLIR, such as loading and storing values
+from/to memory addresses.
+
+The dialect's main type is an opaque pointer (`ptr`) that can be
+parameterized by a memory space. This type represents a handle to an object
+in memory, or target-dependent values like `nullptr`. Further, the dialect
+assumes that the minimum addressable unit by a pointer is a byte. However,
+the dialect does not make assumptions about the size of a byte, which is
+considered a target-specific property.
+  }];
   let cppNamespace = "::mlir::ptr";
   let useDefaultTypePrinterParser = 1;
   let useDefaultAttributePrinterParser = 1;

___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Add translations to LLVMIR for ptr ops. (PR #156355)

2025-09-01 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg updated 
https://github.com/llvm/llvm-project/pull/156355

>From d4befc04b5565fd13cc53694031bf8296fd22312 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Mon, 1 Sep 2025 16:32:01 +
Subject: [PATCH 1/2] add translations for ptr ops

---
 .../include/mlir/Dialect/LLVMIR/LLVMOpBase.td |   3 +-
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 210 +-
 mlir/test/Target/LLVMIR/ptr.mlir  |  75 +++
 3 files changed, 278 insertions(+), 10 deletions(-)

diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td 
b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
index d6aa9580870a8..bd59319c79ad3 100644
--- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
+++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td
@@ -95,8 +95,7 @@ def LLVM_NonLoadableTargetExtType : Type<
 // type that has size (not void, function, opaque struct type or target
 // extension type which does not support memory operations).
 def LLVM_LoadableType : Type<
-  Or<[And<[LLVM_PrimitiveType.predicate, Neg,
-  Neg]>,
+  Or<[CPred<"mlir::LLVM::isLoadableType($_self)">,
   LLVM_PointerElementTypeInterface.predicate]>,
   "LLVM type with size">;
 
diff --git a/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp 
b/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp
index 7b89ec8fcbffb..e3ccf728f25db 100644
--- a/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp
+++ b/mlir/lib/Target/LLVMIR/Dialect/Ptr/PtrToLLVMIRTranslation.cpp
@@ -16,11 +16,193 @@
 #include "mlir/IR/BuiltinAttributes.h"
 #include "mlir/IR/Operation.h"
 #include "mlir/Target/LLVMIR/ModuleTranslation.h"
+#include "llvm/ADT/TypeSwitch.h"
+#include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Type.h"
+#include "llvm/IR/Value.h"
 
 using namespace mlir;
 using namespace mlir::ptr;
 
 namespace {
+
+/// Converts ptr::AtomicOrdering to llvm::AtomicOrdering
+static llvm::AtomicOrdering
+convertAtomicOrdering(ptr::AtomicOrdering ordering) {
+  switch (ordering) {
+  case ptr::AtomicOrdering::not_atomic:
+return llvm::AtomicOrdering::NotAtomic;
+  case ptr::AtomicOrdering::unordered:
+return llvm::AtomicOrdering::Unordered;
+  case ptr::AtomicOrdering::monotonic:
+return llvm::AtomicOrdering::Monotonic;
+  case ptr::AtomicOrdering::acquire:
+return llvm::AtomicOrdering::Acquire;
+  case ptr::AtomicOrdering::release:
+return llvm::AtomicOrdering::Release;
+  case ptr::AtomicOrdering::acq_rel:
+return llvm::AtomicOrdering::AcquireRelease;
+  case ptr::AtomicOrdering::seq_cst:
+return llvm::AtomicOrdering::SequentiallyConsistent;
+  }
+  llvm_unreachable("Unknown atomic ordering");
+}
+
+/// Convert ptr.ptr_add operation
+static LogicalResult
+convertPtrAddOp(PtrAddOp ptrAddOp, llvm::IRBuilderBase &builder,
+LLVM::ModuleTranslation &moduleTranslation) {
+  llvm::Value *basePtr = moduleTranslation.lookupValue(ptrAddOp.getBase());
+  llvm::Value *offset = moduleTranslation.lookupValue(ptrAddOp.getOffset());
+
+  if (!basePtr || !offset)
+return ptrAddOp.emitError("Failed to lookup operands");
+
+  // Create GEP instruction for pointer arithmetic
+  llvm::GetElementPtrInst *gep = llvm::GetElementPtrInst::Create(
+  builder.getInt8Ty(), basePtr, {offset}, "", builder.GetInsertBlock());
+
+  // Set the appropriate flags
+  switch (ptrAddOp.getFlags()) {
+  case ptr::PtrAddFlags::none:
+break;
+  case ptr::PtrAddFlags::nusw:
+gep->setNoWrapFlags(llvm::GEPNoWrapFlags::noUnsignedSignedWrap());
+break;
+  case ptr::PtrAddFlags::nuw:
+gep->setNoWrapFlags(llvm::GEPNoWrapFlags::noUnsignedWrap());
+break;
+  case ptr::PtrAddFlags::inbounds:
+gep->setNoWrapFlags(llvm::GEPNoWrapFlags::inBounds());
+break;
+  }
+
+  moduleTranslation.mapValue(ptrAddOp.getResult(), gep);
+  return success();
+}
+
+/// Convert ptr.load operation
+static LogicalResult convertLoadOp(LoadOp loadOp, llvm::IRBuilderBase &builder,
+   LLVM::ModuleTranslation &moduleTranslation) 
{
+  llvm::Value *ptr = moduleTranslation.lookupValue(loadOp.getPtr());
+  if (!ptr)
+return loadOp.emitError("Failed to lookup pointer operand");
+
+  // Convert result type to LLVM type
+  llvm::Type *resultType =
+  moduleTranslation.convertType(loadOp.getValue().getType());
+  if (!resultType)
+return loadOp.emitError("Failed to convert result type");
+
+  // Create the load instruction.
+  llvm::LoadInst *loadInst = builder.CreateAlignedLoad(
+  resultType, ptr, llvm::MaybeAlign(loadOp.getAlignment().value_or(0)),
+  loadOp.getVolatile_());
+
+  // Set op flags and metadata.
+  loadInst->setAtomic(convertAtomicOrdering(loadOp.getOrdering()));
+  // Set sync scope if specified
+  if (loadOp.getSyncscope().has_value()) {
+llvm::LLVMContext &ctx = builder.getContext();
+llvm::SyncScope::ID syncScope =
+ctx.getOrInsertSyncScopeID(load

[llvm-branch-commits] [mlir] [mlir][ptr] Add `gather`, `masked_load`, `masked_store`, and `scatter` ops (PR #156368)

2025-09-01 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg created 
https://github.com/llvm/llvm-project/pull/156368

This patch adds the `gather`, `masked_load`, `masked_store`, and `scatter` 
operations to the `ptr` dialect. It also implements translation from these 
operations to LLVM intrinsics:
- ptr.gather -> llvm.masked.gather
- ptr.masked_load -> llvm.masked.load  
- ptr.masked_store -> llvm.masked.store
- ptr.scatter -> llvm.masked.scatter

Example:
```mlir
llvm.func @mixed_masked_ops_address_spaces(%ptr: 
!ptr.ptr<#llvm.address_space<3>>, %ptrs: 
vector<4x!ptr.ptr<#llvm.address_space<3>>>, 
  %mask: vector<4xi1>, %value: 
vector<4xf64>, %passthrough: vector<4xf64>) {
  %0 = ptr.gather %ptrs, %mask, %passthrough alignment = 8 : 
vector<4x!ptr.ptr<#llvm.address_space<3>>> -> vector<4xf64>
  ptr.scatter %value, %ptrs, %mask alignment = 8 : vector<4xf64>, 
vector<4x!ptr.ptr<#llvm.address_space<3>>>
  %1 = ptr.masked_load %ptr, %mask, %passthrough alignment = 8 : 
!ptr.ptr<#llvm.address_space<3>> -> vector<4xf64>
  ptr.masked_store %value, %ptr, %mask alignment = 8 : vector<4xf64>, 
!ptr.ptr<#llvm.address_space<3>>
  llvm.return
}
```
Translates to:
```llvm
define void @mixed_masked_ops_address_spaces(ptr addrspace(3) %0, <4 x ptr 
addrspace(3)> %1, <4 x i1> %2, <4 x double> %3, <4 x double> %4) {
  %6 = call <4 x double> @llvm.masked.gather.v4f64.v4p3(<4 x ptr addrspace(3)> 
%1, i32 8, <4 x i1> %2, <4 x double> %4)
  call void @llvm.masked.scatter.v4f64.v4p3(<4 x double> %3, <4 x ptr 
addrspace(3)> %1, i32 8, <4 x i1> %2)
  %7 = call <4 x double> @llvm.masked.load.v4f64.p3(ptr addrspace(3) %0, i32 8, 
<4 x i1> %2, <4 x double> %4)
  call void @llvm.masked.store.v4f64.p3(<4 x double> %3, ptr addrspace(3) %0, 
i32 8, <4 x i1> %2)
  ret void
}
```

>From 1898a4301ca6f9ecd2d125217e28cce2abd20e52 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Sun, 31 Aug 2025 12:01:19 +
Subject: [PATCH] Add load, store variant ops

---
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 238 +-
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp| 156 +++-
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 119 +
 mlir/test/Dialect/Ptr/ops.mlir|  70 ++
 mlir/test/Target/LLVMIR/ptr.mlir  | 114 +
 5 files changed, 682 insertions(+), 15 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 1c88efced950e..170513d57c7be 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -17,6 +17,46 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
 include "mlir/Interfaces/ViewLikeInterface.td"
 include "mlir/IR/OpAsmInterface.td"
 
+//===--===//
+// Common props
+//===--===//
+
+def AlignmentProp : OptionalProp;
+
+//===--===//
+// Common types
+//===--===//
+
+// A shaped value type with value semantics and rank.
+class Ptr_ShapedValueType allowedTypes, list preds = []> :
+  ShapedContainerType,
+/*descr=*/[{A shaped type with value semantics and rank.}],
+/*cppType=*/"::mlir::ShapedType">;
+
+// A shaped pointer type with value semantics and rank.
+class Ptr_ShapedPtrType : Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>;
+
+// A shaped value type of rank 1 of any element type.
+def Ptr_Any1DType :
+  Ptr_ShapedValueType<[AnyType], [HasAnyRankOfPred<[1]>]>;
+
+// A shaped value type of rank 1 of `i1` element type.
+def Ptr_Mask1DType :
+  Ptr_ShapedValueType<[I1], [HasAnyRankOfPred<[1]>]>;
+
+// A shaped value type of rank 1 of `i1` element type.
+def Ptr_Ptr1DType :
+  Ptr_ShapedValueType<[Ptr_PtrType], [HasAnyRankOfPred<[1]>]>;
+
+// Gets the type ID of a type.  
+class TypeIDType :
+StrFunc<"$" # name # ".getType().getTypeID()">;
+
+// Checks that all type IDs match.
+class AllTypeIDsMatch names> :
+AllMatchSameOperatorTrait.result, "type IDs">;
+
 
//===--===//
 // FromPtrOp
 
//===--===//
@@ -56,6 +96,58 @@ def Ptr_FromPtrOp : Pointer_Op<"from_ptr", [
   let hasVerifier = 1;
 }
 
+//===--===//
+// GatherOp
+//===--===//
+
+def Ptr_GatherOp : Pointer_Op<"gather", [
+DeclareOpInterfaceMethods,
+TypesMatchWith<"result and mask must be compatible", "result", "mask", [{
+  ::llvm::cast($_self).clone(
+IntegerType::get($_self.getContext(), 1))
+}]>,
+AllTypesMatch<["result", "passthrough"]>,
+// Check the shapes 

[llvm-branch-commits] [mlir] [mlir][ptr] Add `gather`, `masked_load`, `masked_store`, and `scatter` ops (PR #156368)

2025-09-01 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg updated 
https://github.com/llvm/llvm-project/pull/156368

>From 1898a4301ca6f9ecd2d125217e28cce2abd20e52 Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Sun, 31 Aug 2025 12:01:19 +
Subject: [PATCH 1/2] Add load, store variant ops

---
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 238 +-
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp| 156 +++-
 .../Dialect/Ptr/PtrToLLVMIRTranslation.cpp| 119 +
 mlir/test/Dialect/Ptr/ops.mlir|  70 ++
 mlir/test/Target/LLVMIR/ptr.mlir  | 114 +
 5 files changed, 682 insertions(+), 15 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 1c88efced950e..170513d57c7be 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -17,6 +17,46 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
 include "mlir/Interfaces/ViewLikeInterface.td"
 include "mlir/IR/OpAsmInterface.td"
 
+//===--===//
+// Common props
+//===--===//
+
+def AlignmentProp : OptionalProp;
+
+//===--===//
+// Common types
+//===--===//
+
+// A shaped value type with value semantics and rank.
+class Ptr_ShapedValueType allowedTypes, list preds = []> :
+  ShapedContainerType,
+/*descr=*/[{A shaped type with value semantics and rank.}],
+/*cppType=*/"::mlir::ShapedType">;
+
+// A shaped pointer type with value semantics and rank.
+class Ptr_ShapedPtrType : Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>;
+
+// A shaped value type of rank 1 of any element type.
+def Ptr_Any1DType :
+  Ptr_ShapedValueType<[AnyType], [HasAnyRankOfPred<[1]>]>;
+
+// A shaped value type of rank 1 of `i1` element type.
+def Ptr_Mask1DType :
+  Ptr_ShapedValueType<[I1], [HasAnyRankOfPred<[1]>]>;
+
+// A shaped value type of rank 1 of `i1` element type.
+def Ptr_Ptr1DType :
+  Ptr_ShapedValueType<[Ptr_PtrType], [HasAnyRankOfPred<[1]>]>;
+
+// Gets the type ID of a type.  
+class TypeIDType :
+StrFunc<"$" # name # ".getType().getTypeID()">;
+
+// Checks that all type IDs match.
+class AllTypeIDsMatch names> :
+AllMatchSameOperatorTrait.result, "type IDs">;
+
 
//===--===//
 // FromPtrOp
 
//===--===//
@@ -56,6 +96,58 @@ def Ptr_FromPtrOp : Pointer_Op<"from_ptr", [
   let hasVerifier = 1;
 }
 
+//===--===//
+// GatherOp
+//===--===//
+
+def Ptr_GatherOp : Pointer_Op<"gather", [
+DeclareOpInterfaceMethods,
+TypesMatchWith<"result and mask must be compatible", "result", "mask", [{
+  ::llvm::cast($_self).clone(
+IntegerType::get($_self.getContext(), 1))
+}]>,
+AllTypesMatch<["result", "passthrough"]>,
+// Check the shapes are compatible and both use the same shaped container
+// type.
+AllShapesMatch<["result", "ptrs"]>, AllTypeIDsMatch<["result", "ptrs"]>
+  ]> {
+  let summary = "Gather operation";
+  let description = [{
+The `gather` operation performs conditional loads from multiple memory
+locations specified by `ptrs` based on a mask `mask`. Elements of the
+result corresponding to masked-off lanes are taken from the passthrough
+operand.
+
+The mask operand is a shaped type of `i1` elements that must have the same
+shape as the result type.
+
+Examples:
+```mlir
+// Gather values from multiple memory locations
+%result = ptr.gather %ptrs, %mask, %passthrough :
+  vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
+
+// Gather with alignment
+%result = ptr.gather %ptrs, %mask, %passthrough alignment = 8 :
+  vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
+```
+  }];
+  let arguments = (ins Ptr_Ptr1DType:$ptrs,
+   Ptr_Mask1DType:$mask,
+   Ptr_Any1DType:$passthrough,
+   AlignmentProp:$alignment);
+  let results = (outs Ptr_Any1DType:$result);
+  let assemblyFormat = [{
+$ptrs `,` $mask `,` $passthrough (`alignment` `=` $alignment^)?
+attr-dict `:` qualified(type($ptrs)) `->` type($result)
+  }];
+  let builders = [
+  OpBuilder<(ins "Type":$resultType, "Value":$ptrs, "Value":$mask,
+  "Value":$passthrough, CArg<"unsigned", "0">:$alignment)>
+  ];
+  let hasVerifier = 1;
+}
+
 
//===--===//
 // GetMetadataOp
 
//===--

[llvm-branch-commits] [mlir] [mlir][ptr] Add `gather`, `masked_load`, `masked_store`, and `scatter` ops (PR #156368)

2025-09-02 Thread Fabian Mora via llvm-branch-commits


@@ -56,6 +96,58 @@ def Ptr_FromPtrOp : Pointer_Op<"from_ptr", [
   let hasVerifier = 1;
 }
 
+//===--===//
+// GatherOp
+//===--===//
+
+def Ptr_GatherOp : Pointer_Op<"gather", [
+DeclareOpInterfaceMethods,
+TypesMatchWith<"result and mask must be compatible", "result", "mask", [{
+  ::llvm::cast($_self).clone(
+IntegerType::get($_self.getContext(), 1))
+}]>,
+AllTypesMatch<["result", "passthrough"]>,
+// Check the shapes are compatible and both use the same shaped container
+// type.
+AllShapesMatch<["result", "ptrs"]>, AllTypeIDsMatch<["result", "ptrs"]>
+  ]> {
+  let summary = "Gather operation";
+  let description = [{
+The `gather` operation performs conditional loads from multiple memory
+locations specified by `ptrs` based on a mask `mask`. Elements of the
+result corresponding to masked-off lanes are taken from the passthrough
+operand.
+
+The mask operand is a shaped type of `i1` elements that must have the same
+shape as the result type.
+
+Examples:
+```mlir
+// Gather values from multiple memory locations
+%result = ptr.gather %ptrs, %mask, %passthrough :
+  vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
+
+// Gather with alignment
+%result = ptr.gather %ptrs, %mask, %passthrough alignment = 8 :
+  vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
+```
+  }];
+  let arguments = (ins Ptr_Ptr1DType:$ptrs,
+   Ptr_Mask1DType:$mask,
+   Ptr_Any1DType:$passthrough,
+   AlignmentProp:$alignment);
+  let results = (outs Ptr_Any1DType:$result);
+  let assemblyFormat = [{
+$ptrs `,` $mask `,` $passthrough (`alignment` `=` $alignment^)?
+attr-dict `:` qualified(type($ptrs)) `->` type($result)

fabianmcg wrote:

You're right, I'll remove.

https://github.com/llvm/llvm-project/pull/156368
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Add `gather`, `masked_load`, `masked_store`, and `scatter` ops (PR #156368)

2025-09-02 Thread Fabian Mora via llvm-branch-commits


@@ -56,6 +96,58 @@ def Ptr_FromPtrOp : Pointer_Op<"from_ptr", [
   let hasVerifier = 1;
 }
 
+//===--===//
+// GatherOp
+//===--===//
+
+def Ptr_GatherOp : Pointer_Op<"gather", [
+DeclareOpInterfaceMethods,
+TypesMatchWith<"result and mask must be compatible", "result", "mask", [{
+  ::llvm::cast($_self).clone(
+IntegerType::get($_self.getContext(), 1))
+}]>,
+AllTypesMatch<["result", "passthrough"]>,
+// Check the shapes are compatible and both use the same shaped container
+// type.
+AllShapesMatch<["result", "ptrs"]>, AllTypeIDsMatch<["result", "ptrs"]>
+  ]> {
+  let summary = "Gather operation";
+  let description = [{
+The `gather` operation performs conditional loads from multiple memory
+locations specified by `ptrs` based on a mask `mask`. Elements of the
+result corresponding to masked-off lanes are taken from the passthrough
+operand.
+
+The mask operand is a shaped type of `i1` elements that must have the same
+shape as the result type.
+
+Examples:
+```mlir
+// Gather values from multiple memory locations
+%result = ptr.gather %ptrs, %mask, %passthrough :
+  vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
+
+// Gather with alignment
+%result = ptr.gather %ptrs, %mask, %passthrough alignment = 8 :
+  vector<4x!ptr.ptr<#ptr.generic_space>> -> vector<4xf32>
+```
+  }];
+  let arguments = (ins Ptr_Ptr1DType:$ptrs,
+   Ptr_Mask1DType:$mask,
+   Ptr_Any1DType:$passthrough,
+   AlignmentProp:$alignment);
+  let results = (outs Ptr_Any1DType:$result);
+  let assemblyFormat = [{
+$ptrs `,` $mask `,` $passthrough (`alignment` `=` $alignment^)?
+attr-dict `:` qualified(type($ptrs)) `->` type($result)

fabianmcg wrote:

I generally prefer qualified type, but I'll remove.

https://github.com/llvm/llvm-project/pull/156368
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Extend `ptr_add` operation to support shaped operands (PR #156374)

2025-09-03 Thread Fabian Mora via llvm-branch-commits


@@ -23,6 +24,41 @@ class LLVM_Attrhttps://github.com/llvm/llvm-project/pull/156374
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [mlir][ptr] Extend `ptr_add` operation to support shaped operands (PR #156374)

2025-09-03 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg updated 
https://github.com/llvm/llvm-project/pull/156374

>From af522ed2b48cee2fe81901f2396025d58341997b Mon Sep 17 00:00:00 2001
From: Fabian Mora <[email protected]>
Date: Mon, 1 Sep 2025 21:05:55 +
Subject: [PATCH] extend ptr_add op

---
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h |   1 +
 mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td| 103 +++---
 mlir/lib/Dialect/Ptr/IR/CMakeLists.txt|   1 +
 mlir/lib/Dialect/Ptr/IR/PtrDialect.cpp|  40 +++
 .../Conversion/PtrToLLVM/ptr-to-llvm.mlir |  12 +-
 mlir/test/Dialect/Ptr/invalid.mlir|  16 +++
 mlir/test/Dialect/Ptr/ops.mlir|  65 +++
 mlir/test/Target/LLVMIR/ptr.mlir  |  30 +
 8 files changed, 225 insertions(+), 43 deletions(-)

diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.h
index 8686cc7d316d4..eaf1e6243a74d 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/InferTypeOpInterface.h"
 #include "mlir/Interfaces/SideEffectInterfaces.h"
 #include "mlir/Interfaces/ViewLikeInterface.h"
 
diff --git a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td 
b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
index 5939c3646884c..3ac12978b947c 100644
--- a/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
+++ b/mlir/include/mlir/Dialect/Ptr/IR/PtrOps.td
@@ -13,6 +13,7 @@ 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/InferTypeOpInterface.td"
 include "mlir/Interfaces/SideEffectInterfaces.td"
 include "mlir/Interfaces/ViewLikeInterface.td"
 include "mlir/IR/OpAsmInterface.td"
@@ -34,8 +35,15 @@ class Ptr_ShapedValueType allowedTypes, 
list preds = []> :
 /*descr=*/[{A shaped type with value semantics and rank.}],
 /*cppType=*/"::mlir::ShapedType">;
 
-// A shaped pointer type with value semantics and rank.
-class Ptr_ShapedPtrType : Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>;
+// A ptr-like type, either scalar or shaped type with value semantics.
+def Ptr_PtrLikeType : 
+  AnyTypeOf<[Ptr_ShapedValueType<[Ptr_PtrType], [HasRankPred]>, Ptr_PtrType]>;
+
+// An int-like type, either scalar or shaped type with value semantics.
+def Ptr_IntLikeType :AnyTypeOf<[
+  Ptr_ShapedValueType<[AnySignlessIntegerOrIndex], [HasRankPred]>,
+  AnySignlessIntegerOrIndex
+]>;
 
 // A shaped value type of rank 1 of any element type.
 def Ptr_Any1DType :
@@ -167,41 +175,6 @@ def Ptr_GetMetadataOp : Pointer_Op<"get_metadata", [
   }];
 }
 
-//===--===//
-// PtrAddOp
-//===--===//
-
-def Ptr_PtrAddOp : Pointer_Op<"ptr_add", [
-Pure, AllTypesMatch<["base", "result"]>, ViewLikeOpInterface
-  ]> {
-  let summary = "Pointer add operation";
-  let description = [{
-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.ptr_add %x, %off : !ptr.ptr<#ptr.generic_space>, i32
-%x_off0 = ptr.ptr_add nusw %x, %off : !ptr.ptr<#ptr.generic_space>, i32
-```
-  }];
-
-  let arguments = (ins
-Ptr_PtrType:$base,
-AnySignlessIntegerOrIndex:$offset,
-DefaultValuedProp, "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(); }
-  }];
-}
-
 
//===--===//
 // LoadOp
 
//===--===//
@@ -361,6 +334,62 @@ def Ptr_MaskedStoreOp : Pointer_Op<"masked_store", [
   let hasVerifier = 1;
 }
 
+//===--===//
+// PtrAddOp
+//===--===//
+
+def Ptr_PtrAddOp : Pointer_Op<"ptr_add", [
+Pure, ViewLikeOpInterface,
+DeclareOpInterfaceMethods
+  ]> {
+  let summary = "Pointer add operation";
+  let description = [{
+The `ptr_add` operation adds an int-like offset to one or more pointers to 
produce one or more new pointers.
+
+The operation supports both scalar and shaped types with value semantics:
+- When both base and offset are scalar: produces a single new pointer
+- When base is shaped and offset 

[llvm-branch-commits] [mlir] [Backport][MLIR] Properties.td fix from main commit 77f2560 (PR #165768)

2025-10-30 Thread Fabian Mora via llvm-branch-commits

fabianmcg wrote:

The only issue I can raise is,this is untested (I'm not familiar with back port 
requirements on tests, so it'd be great if someone can comment on that). In the 
other PR, the issue was indirectly tested by the ptr op.

https://github.com/llvm/llvm-project/pull/165768
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [mlir] [Backport][MLIR] Properties.td fix from main commit 77f2560 (PR #165768)

2025-10-30 Thread Fabian Mora via llvm-branch-commits

https://github.com/fabianmcg approved this pull request.

LGTM!

https://github.com/llvm/llvm-project/pull/165768
___
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits