[Mlir-commits] [mlir] edfd360 - [mlir][spirv] Add OpConvertPtrToU and OpConvertUToPtr ops

Lei Zhang llvmlistbot at llvm.org
Wed May 24 21:40:10 PDT 2023


Author: Md Abdullah Shahneous Bari
Date: 2023-05-24T21:35:30-07:00
New Revision: edfd360d78bc610953053cb2ddf491f4f2b8e8c2

URL: https://github.com/llvm/llvm-project/commit/edfd360d78bc610953053cb2ddf491f4f2b8e8c2
DIFF: https://github.com/llvm/llvm-project/commit/edfd360d78bc610953053cb2ddf491f4f2b8e8c2.diff

LOG: [mlir][spirv] Add OpConvertPtrToU and OpConvertUToPtr ops

Add the definitions and necessary verifications of these Ops.

Reviewed By: antiagainst

Differential Revision: https://reviews.llvm.org/D151074

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
    mlir/include/mlir/Dialect/SPIRV/IR/SPIRVCastOps.td
    mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
    mlir/test/Dialect/SPIRV/IR/cast-ops.mlir
    mlir/test/Target/SPIRV/cast-ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
index 26e47f49af055..87d1040773948 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVBase.td
@@ -4267,6 +4267,8 @@ def SPIRV_OC_OpConvertUToF                : I32EnumAttrCase<"OpConvertUToF", 112
 def SPIRV_OC_OpUConvert                   : I32EnumAttrCase<"OpUConvert", 113>;
 def SPIRV_OC_OpSConvert                   : I32EnumAttrCase<"OpSConvert", 114>;
 def SPIRV_OC_OpFConvert                   : I32EnumAttrCase<"OpFConvert", 115>;
+def SPIRV_OC_OpConvertPtrToU              : I32EnumAttrCase<"OpConvertPtrToU", 117>;
+def SPIRV_OC_OpConvertUToPtr              : I32EnumAttrCase<"OpConvertUToPtr", 120>;
 def SPIRV_OC_OpPtrCastToGeneric           : I32EnumAttrCase<"OpPtrCastToGeneric", 121>;
 def SPIRV_OC_OpGenericCastToPtr           : I32EnumAttrCase<"OpGenericCastToPtr", 122>;
 def SPIRV_OC_OpGenericCastToPtrExplicit   : I32EnumAttrCase<"OpGenericCastToPtrExplicit", 123>;
@@ -4447,6 +4449,7 @@ def SPIRV_OpcodeAttr :
       SPIRV_OC_OpImage, SPIRV_OC_OpImageQuerySize, SPIRV_OC_OpConvertFToU,
       SPIRV_OC_OpConvertFToS, SPIRV_OC_OpConvertSToF, SPIRV_OC_OpConvertUToF,
       SPIRV_OC_OpUConvert, SPIRV_OC_OpSConvert, SPIRV_OC_OpFConvert,
+      SPIRV_OC_OpConvertPtrToU, SPIRV_OC_OpConvertUToPtr,
       SPIRV_OC_OpPtrCastToGeneric, SPIRV_OC_OpGenericCastToPtr,
       SPIRV_OC_OpGenericCastToPtrExplicit, SPIRV_OC_OpBitcast, SPIRV_OC_OpSNegate,
       SPIRV_OC_OpFNegate, SPIRV_OC_OpIAdd, SPIRV_OC_OpFAdd, SPIRV_OC_OpISub,

diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVCastOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVCastOps.td
index 1c9eeab689e4b..9109d41303d83 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVCastOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVCastOps.td
@@ -332,6 +332,118 @@ def SPIRV_UConvertOp : SPIRV_CastOp<"UConvert",
 }
 
 // -----
+
+def SPIRV_ConvertPtrToUOp : SPIRV_Op<"ConvertPtrToU", []> {
+  let summary = [{
+    Bit pattern-preserving conversion of a pointer to 
+    an unsigned scalar integer of possibly 
diff erent bit width.
+  }];
+
+  let description = [{
+    Result Type must be a scalar of integer type, whose Signedness operand is 0.
+
+    Pointer must be a physical pointer type. If the bit width of Pointer is 
+    smaller than that of Result Type, the conversion zero extends Pointer. 
+    If the bit width of Pointer is larger than that of Result Type, 
+    the conversion truncates Pointer. 
+
+    For same bit width Pointer and Result Type, this is the same as OpBitcast.
+
+    <!-- End of AutoGen section -->
+
+    ```
+    ptr-to-u-convert-op ::= ssa-id `=` `spirv.ConvertPtrToUOp` ssa-use
+                 `:` operand-type `to` result-type
+    ```
+
+    #### Example:
+
+    ```mlir
+    %1 = spirv.ConvertPtrToU %0 : !spirv.ptr<i32, Generic> to i32         
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_0>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_Addresses, SPIRV_C_PhysicalStorageBufferAddresses]>
+  ];
+
+  let arguments = (ins
+    SPIRV_AnyPtr:$pointer
+  );
+
+  let results = (outs
+    SPIRV_Integer:$result
+  );
+
+  let assemblyFormat = [{
+    $pointer attr-dict `:` type($pointer) `to` type($result)
+  }];
+
+  let hasVerifier = 1;
+}
+
+
+// -----
+
+def SPIRV_ConvertUToPtrOp : SPIRV_Op<"ConvertUToPtr", [UnsignedOp]> {
+  let summary = [{
+    Bit pattern-preserving conversion of an unsigned scalar integer 
+    to a pointer.
+  }];
+
+  let description = [{
+    Result Type must be a physical pointer type.
+
+    Integer Value must be a scalar of integer type, whose Signedness 
+    operand is 0. If the bit width of Integer Value is smaller 
+    than that of Result Type, the conversion zero extends Integer Value.
+    If the bit width of Integer Value is larger than that of Result Type, 
+    the conversion truncates Integer Value. 
+
+    For same-width Integer Value and Result Type, this is the same as OpBitcast.
+
+    <!-- End of AutoGen section -->
+
+    ```
+    u-to-ptr-convert-op ::= ssa-id `=` `spirv.ConvertUToPtr` ssa-use
+                 `:` operand-type `to` result-type
+    ```
+
+    #### Example:
+
+    ```mlir
+    %1 = spirv.ConvertUToPtr %0 :  i32 to !spirv.ptr<i32, Generic>         
+    ```
+  }];
+
+  let availability = [
+    MinVersion<SPIRV_V_1_0>,
+    MaxVersion<SPIRV_V_1_6>,
+    Extension<[]>,
+    Capability<[SPIRV_C_Addresses, SPIRV_C_PhysicalStorageBufferAddresses]>
+  ];
+
+  let arguments = (ins
+    SPIRV_Integer:$operand
+  );
+
+  let results = (outs
+    SPIRV_AnyPtr:$result
+  );
+
+  let assemblyFormat = [{
+    $operand attr-dict `:` type($operand) `to` type($result)
+  }];
+
+  let hasVerifier = 1;
+}
+
+// -----
+
+
 def SPIRV_PtrCastToGenericOp : SPIRV_Op<"PtrCastToGeneric", [Pure]> {
   let summary = "Convert a pointer’s Storage Class to Generic.";
 

diff  --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
index 2828108072352..16737560362d1 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
@@ -1557,6 +1557,48 @@ LogicalResult spirv::BitcastOp::verify() {
   return success();
 }
 
+//===----------------------------------------------------------------------===//
+// spirv.ConvertPtrToUOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult spirv::ConvertPtrToUOp::verify() {
+  auto operandType = getPointer().getType().cast<spirv::PointerType>();
+  auto resultType = getResult().getType().cast<spirv::ScalarType>();
+  if (!resultType || !resultType.isSignlessInteger())
+    return emitError("result must be a scalar type of unsigned integer");
+  auto spirvModule = (*this)->getParentOfType<spirv::ModuleOp>();
+  if (!spirvModule)
+    return success();
+  auto addressingModel = spirvModule.getAddressingModel();
+  if ((addressingModel == spirv::AddressingModel::Logical) ||
+      (addressingModel == spirv::AddressingModel::PhysicalStorageBuffer64 &&
+       operandType.getStorageClass() !=
+           spirv::StorageClass::PhysicalStorageBuffer))
+    return emitError("operand must be a physical pointer");
+  return success();
+}
+
+//===----------------------------------------------------------------------===//
+// spirv.ConvertUToPtrOp
+//===----------------------------------------------------------------------===//
+
+LogicalResult spirv::ConvertUToPtrOp::verify() {
+  auto operandType = getOperand().getType().cast<spirv::ScalarType>();
+  auto resultType = getResult().getType().cast<spirv::PointerType>();
+  if (!operandType || !operandType.isSignlessInteger())
+    return emitError("result must be a scalar type of unsigned integer");
+  auto spirvModule = (*this)->getParentOfType<spirv::ModuleOp>();
+  if (!spirvModule)
+    return success();
+  auto addressingModel = spirvModule.getAddressingModel();
+  if ((addressingModel == spirv::AddressingModel::Logical) ||
+      (addressingModel == spirv::AddressingModel::PhysicalStorageBuffer64 &&
+       resultType.getStorageClass() !=
+           spirv::StorageClass::PhysicalStorageBuffer))
+    return emitError("result must be a physical pointer");
+  return success();
+}
+
 //===----------------------------------------------------------------------===//
 // spirv.PtrCastToGenericOp
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/test/Dialect/SPIRV/IR/cast-ops.mlir b/mlir/test/Dialect/SPIRV/IR/cast-ops.mlir
index 4a7bd603b14dd..cfbbf9494a00e 100644
--- a/mlir/test/Dialect/SPIRV/IR/cast-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/cast-ops.mlir
@@ -363,3 +363,109 @@ func.func @genericcasttoptrexplicit4(%arg0 : !spirv.ptr<f32, Generic>) {
   %0 = spirv.GenericCastToPtrExplicit %arg0 : !spirv.ptr<f32, Generic> to !spirv.ptr<vector<2xi32>, Workgroup>
   return
 }
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.ConvertPtrToU
+//===----------------------------------------------------------------------===//
+spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses], []> {
+  spirv.func @covert_ptr_to_u(%arg0 : !spirv.ptr<i32, Generic>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, Generic> to i32
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
+    spirv.Return
+  }
+  spirv.func @covert_ptr_to_u_truncate(%arg0 : !spirv.ptr<i64, Generic>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i64, Generic> to i32
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i64, Generic> to i32
+    spirv.Return
+  }
+  spirv.func @covert_ptr_to_u_extend(%arg0 : !spirv.ptr<i32, Generic>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, Generic> to i64
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i64
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
+  spirv.func @covert_ptr_to_u_PhysicalStorageBuffer(%arg0 : !spirv.ptr<i32, PhysicalStorageBuffer>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, PhysicalStorageBuffer> to i32
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, PhysicalStorageBuffer> to i32
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
+  spirv.func @covert_ptr_to_u_fail(%arg0 : !spirv.ptr<i32, Generic>) "None" {
+    // expected-error @+1 {{operand must be a physical pointer}}
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
+  spirv.func @covert_ptr_to_u_fail_2(%arg0 : !spirv.ptr<i32, Generic>) "None" {
+    // expected-error @+1 {{operand must be a physical pointer}}
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
+    spirv.Return
+  }
+}
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spirv.ConvertUToPtr
+//===----------------------------------------------------------------------===//
+spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses], []> {
+  spirv.func @covert_u_to_ptr(%arg0 : i32) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i32, Generic> 
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
+    spirv.Return
+  }
+  spirv.func @covert_u_to_ptr_truncate(%arg0 : i64) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i64 to !spirv.ptr<i32, Generic> 
+    %0 = spirv.ConvertUToPtr %arg0 : i64 to !spirv.ptr<i32, Generic>
+    spirv.Return
+  }
+  spirv.func @covert_u_to_ptr_extend(%arg0 : i32) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i64, Generic> 
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i64, Generic>
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
+  spirv.func @covert_u_to_ptr_PhysicalStorageBuffer(%arg0 : i32) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i32, PhysicalStorageBuffer>
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, PhysicalStorageBuffer>
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
+  spirv.func @covert_u_to_ptr_fail(%arg0 : i32) "None" {
+    // expected-error @+1 {{result must be a physical pointer}}
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Shader], []> {
+  spirv.func @covert_u_to_ptr_fail_2(%arg0 : i32) "None" {
+    // expected-error @+1 {{result must be a physical pointer}}
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
+    spirv.Return
+  }
+}

diff  --git a/mlir/test/Target/SPIRV/cast-ops.mlir b/mlir/test/Target/SPIRV/cast-ops.mlir
index bad7c679950cb..7fe0969497c3e 100644
--- a/mlir/test/Target/SPIRV/cast-ops.mlir
+++ b/mlir/test/Target/SPIRV/cast-ops.mlir
@@ -91,3 +91,63 @@ spirv.module Logical GLSL450 requires #spirv.vce<v1.0, [Kernel], []> {
     spirv.Return
   }
 }
+
+// -----
+
+spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses], []> {
+  spirv.func @covert_ptr_to_u(%arg0 : !spirv.ptr<i32, Generic>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, Generic> to i32
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i32
+    spirv.Return
+  }
+  spirv.func @covert_ptr_to_u_truncate(%arg0 : !spirv.ptr<i64, Generic>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i64, Generic> to i32
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i64, Generic> to i32
+    spirv.Return
+  }
+  spirv.func @covert_ptr_to_u_extend(%arg0 : !spirv.ptr<i32, Generic>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, Generic> to i64
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, Generic> to i64
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {  
+  spirv.func @covert_ptr_to_u_PhysicalStorageBuffer(%arg0 : !spirv.ptr<i32, PhysicalStorageBuffer>) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertPtrToU {{%.*}} : !spirv.ptr<i32, PhysicalStorageBuffer> to i32
+    %0 = spirv.ConvertPtrToU %arg0 : !spirv.ptr<i32, PhysicalStorageBuffer> to i32
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module Physical64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses], []> {
+  spirv.func @covert_u_to_ptr(%arg0 : i32) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i32, Generic> 
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, Generic>
+    spirv.Return
+  }
+  spirv.func @covert_u_to_ptr_truncate(%arg0 : i64) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i64 to !spirv.ptr<i32, Generic> 
+    %0 = spirv.ConvertUToPtr %arg0 : i64 to !spirv.ptr<i32, Generic>
+    spirv.Return
+  }
+  spirv.func @covert_u_to_ptr_extend(%arg0 : i32) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i64, Generic> 
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i64, Generic>
+    spirv.Return
+  }
+}
+
+// -----
+
+spirv.module PhysicalStorageBuffer64 OpenCL requires #spirv.vce<v1.0, [Kernel, Addresses, PhysicalStorageBufferAddresses], []> {
+  spirv.func @covert_u_to_ptr_PhysicalStorageBuffer(%arg0 : i32) "None" {
+    // CHECK: {{%.*}} = spirv.ConvertUToPtr {{%.*}} : i32 to !spirv.ptr<i32, PhysicalStorageBuffer>
+    %0 = spirv.ConvertUToPtr %arg0 : i32 to !spirv.ptr<i32, PhysicalStorageBuffer>
+    spirv.Return
+  }
+}


        


More information about the Mlir-commits mailing list