[Mlir-commits] [mlir] [MLIR][Doc] Remove LLVM dialect typed pointer documentation (PR #71246)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Fri Nov 3 15:40:15 PDT 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-mlir

@llvm/pr-subscribers-openacc

Author: Christian Ulmann (Dinistro)

<details>
<summary>Changes</summary>

This commit removes all references to typed pointers. Typed pointers have been deprecated for a while now and they will be removed in a followup.

Related PSA: https://discourse.llvm.org/t/psa-removal-of-typed-pointers-from-the-llvm-dialect/74502

---

Patch is 38.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/71246.diff


12 Files Affected:

- (modified) mlir/docs/Dialects/LLVM.md (+17-39) 
- (modified) mlir/docs/SPIRVToLLVMDialectConversion.md (+9-9) 
- (modified) mlir/docs/TargetLLVMIR.md (+58-75) 
- (modified) mlir/include/mlir/Conversion/LLVMCommon/Pattern.h (+3-3) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMAttrDefs.td (+5-5) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td (+15-15) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/LLVMTypes.td (+2-4) 
- (modified) mlir/include/mlir/Dialect/LLVMIR/NVVMOps.td (+4-4) 
- (modified) mlir/include/mlir/Dialect/MemRef/IR/MemRefOps.td (+2-2) 
- (modified) mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td (+15-15) 
- (modified) mlir/include/mlir/Dialect/SparseTensor/Transforms/Passes.td (+2-2) 
- (modified) mlir/unittests/Dialect/LLVMIR/LLVMTypeTest.cpp (+2-2) 


``````````diff
diff --git a/mlir/docs/Dialects/LLVM.md b/mlir/docs/Dialects/LLVM.md
index 796c3a7b768443b..5bbccda7cf6bd22 100644
--- a/mlir/docs/Dialects/LLVM.md
+++ b/mlir/docs/Dialects/LLVM.md
@@ -210,9 +210,9 @@ style for types with nested angle brackets and keyword specifiers rather than
 using different bracket styles to differentiate types. Types inside the angle
 brackets may omit the `!llvm.` prefix for brevity: the parser first attempts to
 find a type (starting with `!` or a built-in type) and falls back to accepting a
-keyword. For example, `!llvm.ptr<!llvm.ptr<i32>>` and `!llvm.ptr<ptr<i32>>` are
-equivalent, with the latter being the canonical form, and denote a pointer to a
-pointer to a 32-bit integer.
+keyword. For example, `!llvm.struct<(!llvm.ptr, f32)>` and
+`!llvm.struct<(ptr, f32)>` are equivalent, with the latter being the canonical
+form, and denote a struct containing a pointer and a float.
 
 ### Built-in Type Compatibility
 
@@ -232,8 +232,8 @@ compatibility check.
 
 Each LLVM IR type corresponds to *exactly one* MLIR type, either built-in or
 LLVM dialect type. For example, because `i32` is LLVM-compatible, there is no
-`!llvm.i32` type. However, `!llvm.ptr<T>` is defined in the LLVM dialect as
-there is no corresponding built-in type.
+`!llvm.i32` type. However, `!llvm.struct<(T, ...)>` is defined in the LLVM
+dialect as there is no corresponding built-in type.
 
 ### Additional Simple Types
 
@@ -263,24 +263,19 @@ the element type, which can be either compatible built-in or LLVM dialect types.
 
 Pointer types specify an address in memory.
 
-Both opaque and type-parameterized pointer types are supported.
-[Opaque pointers](https://llvm.org/docs/OpaquePointers.html) do not indicate the
-type of the data pointed to, and are intended to simplify LLVM IR by encoding
-behavior relevant to the pointee type into operations rather than into types.
-Non-opaque pointer types carry the pointee type as a type parameter. Both kinds
-of pointers may be additionally parameterized by an address space. The address
-space is an integer, but this choice may be reconsidered if MLIR implements
-named address spaces. The syntax of pointer types is as follows:
+Pointers are [opaque](https://llvm.org/docs/OpaquePointers.html), i.e., do not
+indicate the type of the data pointed to, and are intended to simplify LLVM IR
+by encoding behavior relevant to the pointee type into operations rather than
+into types. Pointers can optionally be parametrized with an address space. The
+address space is an integer, but this choice may be reconsidered if MLIR
+implements named address spaces. The syntax of pointer types is as follows:
 
 ```
   llvm-ptr-type ::= `!llvm.ptr` (`<` integer-literal `>`)?
-                  | `!llvm.ptr<` type (`,` integer-literal)? `>`
 ```
 
-where the former case is the opaque pointer type and the latter case is the
-non-opaque pointer type; the optional group containing the integer literal
-corresponds to the memory space. All cases are represented by `LLVMPointerType`
-internally.
+where the optional group containing the integer literal corresponds to the
+address space. All cases are represented by `LLVMPointerType` internally.
 
 #### Array Types
 
@@ -346,7 +341,7 @@ syntax:
 
 Note that the sets of element types supported by built-in and LLVM dialect
 vector types are mutually exclusive, e.g., the built-in vector type does not
-accept `!llvm.ptr<i32>` and the LLVM dialect fixed-width vector type does not
+accept `!llvm.ptr` and the LLVM dialect fixed-width vector type does not
 accept `i32`.
 
 The following functions are provided to operate on any kind of the vector types
@@ -367,12 +362,11 @@ compatible with the LLVM dialect:
 
 ```mlir
 vector<42 x i32>                   // Vector of 42 32-bit integers.
-!llvm.vec<42 x ptr<i32>>           // Vector of 42 pointers to 32-bit integers.
+!llvm.vec<42 x ptr>                // Vector of 42 pointers.
 !llvm.vec<? x 4 x i32>             // Scalable vector of 32-bit integers with
                                    // size divisible by 4.
 !llvm.array<2 x vector<2 x i32>>   // Array of 2 vectors of 2 32-bit integers.
-!llvm.array<2 x vec<2 x ptr<i32>>> // Array of 2 vectors of 2 pointers to 32-bit
-                                   // integers.
+!llvm.array<2 x vec<2 x ptr>> // Array of 2 vectors of 2 pointers.
 ```
 
 ### Structure Types
@@ -421,21 +415,6 @@ type-or-ref ::= <any compatible type with optional !llvm.>
               | `!llvm.`? `struct<` string-literal `>`
 ```
 
-The body of the identified struct is printed in full unless the it is
-transitively contained in the same struct. In the latter case, only the
-identifier is printed. For example, the structure containing the pointer to
-itself is represented as `!llvm.struct<"A", (ptr<"A">)>`, and the structure `A`
-containing two pointers to the structure `B` containing a pointer to the
-structure `A` is represented as `!llvm.struct<"A", (ptr<"B", (ptr<"A">)>,
-ptr<"B", (ptr<"A">))>`. Note that the structure `B` is "unrolled" for both
-elements. _A structure with the same name but different body is a syntax error._
-**The user must ensure structure name uniqueness across all modules processed in
-a given MLIR context.** Structure names are arbitrary string literals and may
-include, e.g., spaces and keywords.
-
-Identified structs may be _opaque_. In this case, the body is unknown but the
-structure type is considered _initialized_ and is valid in the IR.
-
 #### Literal Structure Types
 
 Literal structures are uniqued according to the list of elements they contain,
@@ -460,11 +439,10 @@ elements provided.
 !llvm.struct<packed (i8, i32)>  // packed struct
 !llvm.struct<"a">               // recursive reference, only allowed within
                                 // another struct, NOT allowed at top level
-!llvm.struct<"a", ptr<struct<"a">>>  // supported example of recursive reference
 !llvm.struct<"a", ()>           // empty, named (necessary to differentiate from
                                 // recursive reference)
 !llvm.struct<"a", opaque>       // opaque, named
-!llvm.struct<"a", (i32)>        // named
+!llvm.struct<"a", (i32, ptr)>        // named
 !llvm.struct<"a", packed (i8, i32)>  // named, packed
 ```
 
diff --git a/mlir/docs/SPIRVToLLVMDialectConversion.md b/mlir/docs/SPIRVToLLVMDialectConversion.md
index 7a3bc7c62bd9a2c..0aae02cff26be1b 100644
--- a/mlir/docs/SPIRVToLLVMDialectConversion.md
+++ b/mlir/docs/SPIRVToLLVMDialectConversion.md
@@ -45,7 +45,7 @@ A SPIR-V pointer also takes a Storage Class. At the moment, conversion does
 
 SPIR-V Dialect                                | LLVM Dialect
 :-------------------------------------------: | :-------------------------:
-`!spirv.ptr< <element-type>, <storage-class> >` | `!llvm.ptr<<element-type>>`
+`!spirv.ptr< <element-type>, <storage-class> >` | `!llvm.ptr`
 
 ### Array types
 
@@ -443,7 +443,7 @@ order to go through the pointer.
 %i   = ...
 %var = ...
 %0   = llvm.mlir.constant(0 : i32) : i32
-%el  = llvm.getelementptr %var[%0, %i, %i] : (!llvm.ptr<struct<packed (f32, array<4 x f32>)>>, i32, i32, i32)
+%el  = llvm.getelementptr %var[%0, %i, %i] : (!llvm.ptr, i32, i32, i32), !llvm.struct<packed (f32, array<4 x f32>)>
 ```
 
 #### `spirv.Load` and `spirv.Store`
@@ -453,16 +453,16 @@ These ops are converted to their LLVM counterparts: `llvm.load` and
 following cases, based on the value of the attribute:
 
 *   **Aligned**: alignment is passed on to LLVM op builder, for example: `mlir
-    // llvm.store %ptr, %val {alignment = 4 : i64} : !llvm.ptr<f32> spirv.Store
+    // llvm.store %ptr, %val {alignment = 4 : i64} : !llvm.ptr spirv.Store
     "Function" %ptr, %val ["Aligned", 4] : f32`
 *   **None**: same case as if there is no memory access attribute.
 
 *   **Nontemporal**: set `nontemporal` flag, for example: `mlir // %res =
-    llvm.load %ptr {nontemporal} : !llvm.ptr<f32> %res = spirv.Load "Function"
+    llvm.load %ptr {nontemporal} : !llvm.ptr %res = spirv.Load "Function"
     %ptr ["Nontemporal"] : f32`
 
 *   **Volatile**: mark the op as `volatile`, for example: `mlir // %res =
-    llvm.load volatile %ptr : !llvm.ptr<f32> %res = spirv.Load "Function" %ptr
+    llvm.load volatile %ptr : !llvm.ptr f32> %res = spirv.Load "Function" %ptr
     ["Volatile"] : f32` Otherwise the conversion fails as other cases
     (`MakePointerAvailable`, `MakePointerVisible`, `NonPrivatePointer`) are not
     supported yet.
@@ -491,7 +491,7 @@ spirv.module Logical GLSL450 {
 module {
   llvm.mlir.global private @struct() : !llvm.struct<packed (f32, [10 x f32])>
   llvm.func @func() {
-    %0 = llvm.mlir.addressof @struct : !llvm.ptr<struct<packed (f32, [10 x f32])>>
+    %0 = llvm.mlir.addressof @struct : !llvm.ptr
     llvm.return
   }
 }
@@ -535,13 +535,13 @@ Also, at the moment initialization is only possible via `spirv.Constant`.
 ```mlir
 // Conversion of VariableOp without initialization
                                                                %size = llvm.mlir.constant(1 : i32) : i32
-%res = spirv.Variable : !spirv.ptr<vector<3xf32>, Function>   =>   %res  = llvm.alloca  %size x vector<3xf32> : (i32) -> !llvm.ptr<vec<3 x f32>>
+%res = spirv.Variable : !spirv.ptr<vector<3xf32>, Function>   =>   %res  = llvm.alloca  %size x vector<3xf32> : (i32) -> !llvm.ptr
 
 // Conversion of VariableOp with initialization
                                                                %c    = llvm.mlir.constant(0 : i64) : i64
 %c   = spirv.Constant 0 : i64                                    %size = llvm.mlir.constant(1 : i32) : i32
-%res = spirv.Variable init(%c) : !spirv.ptr<i64, Function>    =>   %res  = llvm.alloca %[[SIZE]] x i64 : (i32) -> !llvm.ptr<i64>
-                                                               llvm.store %c, %res : !llvm.ptr<i64>
+%res = spirv.Variable init(%c) : !spirv.ptr<i64, Function>    =>   %res  = llvm.alloca %[[SIZE]] x i64 : (i32) -> !llvm.ptr
+                                                               llvm.store %c, %res : i64, !llvm.ptr
 ```
 
 Note that simple conversion to `alloca` may not be sufficient if the code has
diff --git a/mlir/docs/TargetLLVMIR.md b/mlir/docs/TargetLLVMIR.md
index 4553accc5b9ae2b..73a74c394f2af79 100644
--- a/mlir/docs/TargetLLVMIR.md
+++ b/mlir/docs/TargetLLVMIR.md
@@ -135,20 +135,19 @@ Examples:
 ```mlir
 // Assuming index is converted to i64.
 
-memref<f32> -> !llvm.struct<(ptr<f32> , ptr<f32>, i64)>
-memref<1 x f32> -> !llvm.struct<(ptr<f32>, ptr<f32>, i64,
+memref<f32> -> !llvm.struct<(ptr , ptr, i64)>
+memref<1 x f32> -> !llvm.struct<(ptr, ptr, i64,
                                  array<1 x i64>, array<1 x i64>)>
-memref<? x f32> -> !llvm.struct<(ptr<f32>, ptr<f32>, i64
+memref<? x f32> -> !llvm.struct<(ptr, ptr, i64
                                  array<1 x i64>, array<1 x i64>)>
-memref<10x42x42x43x123 x f32> -> !llvm.struct<(ptr<f32>, ptr<f32>, i64
+memref<10x42x42x43x123 x f32> -> !llvm.struct<(ptr, ptr, i64
                                                array<5 x i64>, array<5 x i64>)>
-memref<10x?x42x?x123 x f32> -> !llvm.struct<(ptr<f32>, ptr<f32>, i64
+memref<10x?x42x?x123 x f32> -> !llvm.struct<(ptr, ptr, i64
                                              array<5 x i64>, array<5 x i64>)>
 
 // Memref types can have vectors as element types
-memref<1x? x vector<4xf32>> -> !llvm.struct<(ptr<vector<4 x f32>>,
-                                             ptr<vector<4 x f32>>, i64,
-                                             array<2 x i64>, array<2 x i64>)>
+memref<1x? x vector<4xf32>> -> !llvm.struct<(ptr, ptr, i64, array<2 x i64>,
+                                             array<2 x i64>)>
 ```
 
 #### Unranked MemRef Types
@@ -159,7 +158,7 @@ as *unranked descriptor*. It contains:
 
 1.  a converted `index`-typed integer representing the dynamic rank of the
     memref;
-2.  a type-erased pointer (`!llvm.ptr<i8>`) to a ranked memref descriptor with
+2.  a type-erased pointer (`!llvm.ptr`) to a ranked memref descriptor with
     the contents listed above.
 
 This descriptor is primarily intended for interfacing with rank-polymorphic
@@ -219,49 +218,42 @@ Examples:
 
 // Function-typed arguments or results in higher-order functions:
 (() -> ()) -> (() -> ())
-// are converted into pointers to functions.
-!llvm.func<ptr<func<void ()>> (ptr<func<void ()>>)>
-
-// These rules apply recursively: a function type taking a function that takes
-// another function
-( ( (i32) -> (i64) ) -> () ) -> ()
-// is converted into a function type taking a pointer-to-function that takes
-// another point-to-function.
-!llvm.func<void (ptr<func<void (ptr<func<i64 (i32)>>)>>)>
+// are converted into opaque pointers.
+!llvm.func<ptr (ptr)>
 
 // A memref descriptor appearing as function argument:
 (memref<f32>) -> ()
 // gets converted into a list of individual scalar components of a descriptor.
-!llvm.func<void (ptr<f32>, ptr<f32>, i64)>
+!llvm.func<void (ptr, ptr, i64)>
 
 // The list of arguments is linearized and one can freely mix memref and other
 // types in this list:
 (memref<f32>, f32) -> ()
 // which gets converted into a flat list.
-!llvm.func<void (ptr<f32>, ptr<f32>, i64, f32)>
+!llvm.func<void (ptr, ptr, i64, f32)>
 
 // For nD ranked memref descriptors:
 (memref<?x?xf32>) -> ()
 // the converted signature will contain 2n+1 `index`-typed integer arguments,
 // offset, n sizes and n strides, per memref argument type.
-!llvm.func<void (ptr<f32>, ptr<f32>, i64, i64, i64, i64, i64)>
+!llvm.func<void (ptr, ptr, i64, i64, i64, i64, i64)>
 
 // Same rules apply to unranked descriptors:
 (memref<*xf32>) -> ()
 // which get converted into their components.
-!llvm.func<void (i64, ptr<i8>)>
+!llvm.func<void (i64, ptr)>
 
 // However, returning a memref from a function is not affected:
 () -> (memref<?xf32>)
 // gets converted to a function returning a descriptor structure.
-!llvm.func<struct<(ptr<f32>, ptr<f32>, i64, array<1xi64>, array<1xi64>)> ()>
+!llvm.func<struct<(ptr, ptr, i64, array<1xi64>, array<1xi64>)> ()>
 
 // If multiple memref-typed results are returned:
 () -> (memref<f32>, memref<f64>)
 // their descriptor structures are additionally packed into another structure,
 // potentially with other non-memref typed results.
-!llvm.func<struct<(struct<(ptr<f32>, ptr<f32>, i64)>,
-                   struct<(ptr<double>, ptr<double>, i64)>)> ()>
+!llvm.func<struct<(struct<(ptr, ptr, i64)>,
+                   struct<(ptr, ptr, i64)>)> ()>
 
 // If "func.varargs" attribute is set:
 (i32) -> () attributes { "func.varargs" = true }
@@ -290,8 +282,7 @@ vector<4x8 x f32>
 
 memref<2 x vector<4x8 x f32>
 // ->
-!llvm.struct<(ptr<array<4 x vector<8xf32>>>, ptr<array<4 x vector<8xf32>>>
-              i64, array<1 x i64>, array<1 x i64>)>
+!llvm.struct<(ptr, ptr, i64, array<1 x i64>, array<1 x i64>)>
 ```
 
 #### Tensor Types
@@ -382,10 +373,10 @@ func.func @foo(%arg0: memref<?xf32>) -> () {
 
 // Gets converted to the following
 // (using type alias for brevity):
-!llvm.memref_1d = !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1xi64>, array<1xi64>)>
+!llvm.memref_1d = !llvm.struct<(ptr, ptr, i64, array<1xi64>, array<1xi64>)>
 
-llvm.func @foo(%arg0: !llvm.ptr<f32>,  // Allocated pointer.
-               %arg1: !llvm.ptr<f32>,  // Aligned pointer.
+llvm.func @foo(%arg0: !llvm.ptr,       // Allocated pointer.
+               %arg1: !llvm.ptr,       // Aligned pointer.
                %arg2: i64,             // Offset.
                %arg3: i64,             // Size in dim 0.
                %arg4: i64) {           // Stride in dim 0.
@@ -412,7 +403,7 @@ func.func @bar() {
 
 // Gets converted to the following
 // (using type alias for brevity):
-!llvm.memref_1d = !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<1xi64>, array<1xi64>)>
+!llvm.memref_1d = !llvm.struct<(ptr, ptr, i64, array<1xi64>, array<1xi64>)>
 
 llvm.func @bar() {
   %0 = "get"() : () -> !llvm.memref_1d
@@ -434,7 +425,7 @@ llvm.func @bar() {
 
 For unranked memrefs, the list of function arguments always contains two
 elements, same as the unranked memref descriptor: an integer rank, and a
-type-erased (`!llvm<"i8*">`) pointer to the ranked memref descriptor. Note that
+type-erased (`!llvm.ptr`) pointer to the ranked memref descriptor. Note that
 while the *calling convention* does not require allocation, *casting* to
 unranked memref does since one cannot take an address of an SSA value containing
 the ranked memref, which must be stored in some memory instead. The caller is in
@@ -452,13 +443,13 @@ llvm.func @foo(%arg0: memref<*xf32>) -> () {
 // Gets converted to the following.
 
 llvm.func @foo(%arg0: i64              // Rank.
-               %arg1: !llvm.ptr<i8>) { // Type-erased pointer to descriptor.
+               %arg1: !llvm.ptr) { // Type-erased pointer to descriptor.
   // Pack the unranked memref descriptor.
-  %0 = llvm.mlir.undef : !llvm.struct<(i64, ptr<i8>)>
-  %1 = llvm.insertvalue %arg0, %0[0] : !llvm.struct<(i64, ptr<i8>)>
-  %2 = llvm.insertvalue %arg1, %1[1] : !llvm.struct<(i64, ptr<i8>)>
+  %0 = llvm.mlir.undef : !llvm.struct<(i64, ptr)>
+  %1 = llvm.insertvalue %arg0, %0[0] : !llvm.struct<(i64, ptr)>
+  %2 = llvm.insertvalue %arg1, %1[1] : !llvm.struct<(i64, ptr)>
 
-  "use"(%2) : (!llvm.struct<(i64, ptr<i8>)>) -> ()
+  "use"(%2) : (!llvm.struct<(i64, ptr)>) -> ()
   llvm.return
 }
 ```
@@ -473,14 +464,14 @@ llvm.func @bar() {
 // Gets converted to the following.
 
 llvm.func @bar() {
-  %0 = "get"() : () -> (!llvm.struct<(i64, ptr<i8>)>)
+  %0 = "get"() : () -> (!llvm.struct<(i64, ptr)>)
 
   // Unpack the memref descriptor.
-  %1 = llvm.extractvalue %0[0] : !llvm.struct<(i64, ptr<i8>)>
-  %2 = llvm.extractvalue %0[1] : !llvm.struct<(i64, ptr<i8>)>
+  %1 = llvm.extractvalue %0[0] : !llvm.struct<(i64, ptr)>
+  %2 = llvm.extractvalue %0[1] : !llvm.struct<(i64, ptr)>
 
   // Pass individual values to the callee.
-  llvm.call @foo(%1, %2) : (i64, !llvm.ptr<i8>)
+  llvm.call @foo(%1, %2) : (i64, !llvm.ptr)
   llvm.return
 }
 ```
@@ -524,12 +515,12 @@ func.func @caller(%0 : memref<2x4xf32>) {
 
 // ->
 
-!descriptor = !llvm.struct<(ptr<f32>, ptr<f32>, i64,
+!descriptor = !llvm.struct<(ptr, ptr, i64,
                             array<2xi64>, array<2xi64>)>
 
-llvm.func @callee(!llvm.ptr<f32>)
+llvm.func @callee(!llvm.ptr)
 
-llvm.func @caller(%arg0: !llvm.ptr<f32>) {
+llvm.func @caller(%arg0: !llvm.ptr) {
   // A descriptor value is defined at the function entry point.
   %0 = llvm.mlir.undef : !descriptor
 
@@ -552,7 +543,7 @@ llvm.func @caller(%arg0: !llvm.ptr<f32>) {
 
   // The function call corresponds to extracting the aligned data pointer.
   %12 = llvm.extractelement %11[1] : !descriptor
-  llvm.call @callee(%12) : (!llvm.ptr<f32>) -> ()
+  llvm.call @callee(%12) : (!llvm.ptr) -> ()
 }
 ```
 
@@ -644,10 +635,10 @@ func.func @qux(%arg0: memref<?x?xf32>)
 
 // Gets converted into the following
 // (using type alias for brevity):
-!llvm.memref_2d = !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2xi64>, array<2xi64>)>
+!llvm.memref_2d = !llvm.struct<(ptr, ptr, i64, array<2xi64>, array<2xi64>)>
 
 // Function with unpacked arguments.
-llvm.func @qux(%arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>,
+llvm.func @qux(%arg0: !llvm.ptr, %arg1: !llvm.ptr,
                %arg2: i64, %arg3: i64, %arg4: i64,
                %arg5: i64, %arg6: i64) {
   // Populate memref descriptor (as per calling convention).
@@ -663,23 +654,18 @@ llvm.func @qux(%arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>,
   // Store the descriptor in a stack-allocated space.
   %8 = llvm.mlir.constant(1 : index) : i64
   %9 = llvm.alloca %8 x !llvm.memref_2d
-     : (i64) -> !llvm.ptr<struct<(ptr<f32>, ptr<f32>, i64,
-                                        array<2xi64>, array<2xi64>)>>
-  llvm.store %7, %9 : !llvm.ptr<struct<(ptr<f32>, ptr<f32>, i64,
-                                        array<2xi64>, array<2xi64>)>>
+     : (i64) -> !llvm.ptr
+  llvm.store %7, %9 : !llvm.memref_2d, !llvm.ptr
 
   // Call the interface function.
-  llvm.call @_mlir_ciface_qux(%9)
-     : (!llvm.ptr<struct<(ptr<f32>, ptr<f32>, i64,
-                          array<2xi64>, array<2xi64>)>>) -> ()
+  llvm.call @_mlir_ciface_qux(%9) : (!llvm.ptr) -> ()
 
   // The stored descriptor will be freed on return.
   llvm.return
 }
 
 // Interface function.
-llvm.func @_mlir_ciface_qux(!llvm.ptr<struct<(ptr<f32>, ptr<f32>, i64,
-                                              array<2xi64>, array<2xi64>)>>)
+llvm.func @_...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/71246


More information about the Mlir-commits mailing list