[Mlir-commits] [mlir] ce2ad93 - [mlir][spirv] Define spv.GLSL.Ldexp

Lei Zhang llvmlistbot at llvm.org
Wed Feb 24 10:09:39 PST 2021


Author: Weiwei Li
Date: 2021-02-24T13:07:46-05:00
New Revision: ce2ad938ff1fd4bad6ee91809f970984b1614e35

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

LOG: [mlir][spirv] Define spv.GLSL.Ldexp

co-authored-by: Alan Liu <alanliu.yf at gmail.com>

Reviewed By: antiagainst

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

Added: 
    

Modified: 
    mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
    mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
    mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
    mlir/test/Target/SPIRV/glsl-ops.mlir

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
index 51ed82dba6b2..209749845a24 100644
--- a/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
+++ b/mlir/include/mlir/Dialect/SPIRV/IR/SPIRVGLSLOps.td
@@ -1069,4 +1069,59 @@ def SPV_GLSLFrexpStructOp : SPV_GLSLOp<"FrexpStruct", 52, [NoSideEffect]> {
   let verifier = [{ return ::verifyGLSLFrexpStructOp(*this); }];
 }
 
+def SPV_GLSLLdexpOp :
+  SPV_GLSLOp<"Ldexp", 53, [
+      NoSideEffect, AllTypesMatch<["x", "y"]>]> {
+  let summary = "Builds y such that y = significand * 2^exponent";
+
+  let description = [{
+    Builds a floating-point number from x and the corresponding
+    integral exponent of two in exp:
+
+    significand * 2^exponent
+
+    If this product is too large to be represented in the floating-point
+    type, the resulting value is undefined. If exp is greater than +128
+    (single precision) or +1024 (double precision), the resulting value is
+    undefined. If exp is less than -126 (single precision) or -1022 (double precision),
+    the result may be flushed to zero. Additionally, splitting the value
+    into a significand and exponent using frexp and then reconstructing a
+    floating-point value using ldexp should yield the original input for
+    zero and all finite non-denormalized values.
+
+    The operand x must be a scalar or vector whose component type is floating-point.
+
+    The exp operand must be a scalar or vector with integer component type.
+    The number of components in x and exp must be the same.
+
+    Result Type must be the same type as the type of x. Results are computed per
+    component.
+
+    <!-- End of AutoGen section -->
+
+    #### Example:
+
+    ```mlir
+    %y = spv.GLSL.Ldexp %x : f32, %exp : i32 -> f32
+    %y = spv.GLSL.Ldexp %x : vector<3xf32>, %exp : vector<3xi32> -> vector<3xf32>
+    ```
+  }];
+
+  let arguments = (ins
+    SPV_ScalarOrVectorOf<SPV_Float>:$x,
+    SPV_ScalarOrVectorOf<SPV_Integer>:$exp
+  );
+
+  let results = (outs
+    SPV_ScalarOrVectorOf<SPV_Float>:$y
+  );
+
+  let assemblyFormat = [{
+    attr-dict $x `:` type($x) `,` $exp `:` type($exp) `->` type($y)
+  }];
+
+  let verifier = [{ return ::verify(*this); }];
+}
+
+
 #endif // MLIR_DIALECT_SPIRV_IR_GLSL_OPS

diff  --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
index 05ca48d486cb..242c86ba7ea3 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVOps.cpp
@@ -3585,6 +3585,30 @@ verifyGLSLFrexpStructOp(spirv::GLSLFrexpStructOp frexpStructOp) {
       "must have the same number of components as the operand type");
 }
 
+//===----------------------------------------------------------------------===//
+// spv.GLSL.Ldexp
+//===----------------------------------------------------------------------===//
+
+static LogicalResult verify(spirv::GLSLLdexpOp ldexpOp) {
+  Type significandType = ldexpOp.x().getType();
+  Type exponentType = ldexpOp.exp().getType();
+
+  if (significandType.isa<FloatType>() != exponentType.isa<IntegerType>())
+    return ldexpOp.emitOpError("operands must both be scalars or vectors");
+
+  auto getNumElements = [](Type type) -> unsigned {
+    if (auto vectorType = type.dyn_cast<VectorType>())
+      return vectorType.getNumElements();
+    return 1;
+  };
+
+  if (getNumElements(significandType) != getNumElements(exponentType))
+    return ldexpOp.emitOpError(
+        "operands must have the same number of elements");
+
+  return success();
+}
+
 namespace mlir {
 namespace spirv {
 

diff  --git a/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir b/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
index 49fa6c382f24..5b6d382548c2 100644
--- a/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
+++ b/mlir/test/Dialect/SPIRV/IR/glsl-ops.mlir
@@ -420,3 +420,46 @@ func @frexp_struct_not_i32(%arg0 : f32) -> () {
   %2 = spv.GLSL.FrexpStruct %arg0 : f32 -> !spv.struct<(f32, i64)>
   return
 }
+
+// -----
+
+//===----------------------------------------------------------------------===//
+// spv.GLSL.Ldexp
+//===----------------------------------------------------------------------===//
+
+func @ldexp(%arg0 : f32, %arg1 : i32) -> () {
+  // CHECK: {{%.*}} = spv.GLSL.Ldexp {{%.*}} : f32, {{%.*}} : i32 -> f32
+  %0 = spv.GLSL.Ldexp %arg0 : f32, %arg1 : i32 -> f32
+  return
+}
+
+// -----
+func @ldexp_vec(%arg0 : vector<3xf32>, %arg1 : vector<3xi32>) -> () {
+  // CHECK: {{%.*}} = spv.GLSL.Ldexp {{%.*}} : vector<3xf32>, {{%.*}} : vector<3xi32> -> vector<3xf32>
+  %0 = spv.GLSL.Ldexp %arg0 : vector<3xf32>, %arg1 : vector<3xi32> -> vector<3xf32>
+  return
+}
+
+// -----
+
+func @ldexp_wrong_type_scalar(%arg0 : f32, %arg1 : vector<2xi32>) -> () {
+  // expected-error @+1 {{operands must both be scalars or vectors}}
+  %0 = spv.GLSL.Ldexp %arg0 : f32, %arg1 : vector<2xi32> -> f32
+  return
+}
+
+// -----
+
+func @ldexp_wrong_type_vec_1(%arg0 : vector<3xf32>, %arg1 : i32) -> () {
+  // expected-error @+1 {{operands must both be scalars or vectors}}
+  %0 = spv.GLSL.Ldexp %arg0 : vector<3xf32>, %arg1 : i32 -> vector<3xf32>
+  return
+}
+
+// -----
+
+func @ldexp_wrong_type_vec_2(%arg0 : vector<3xf32>, %arg1 : vector<2xi32>) -> () {
+  // expected-error @+1 {{operands must have the same number of elements}}
+  %0 = spv.GLSL.Ldexp %arg0 : vector<3xf32>, %arg1 : vector<2xi32> -> vector<3xf32>
+  return
+}

diff  --git a/mlir/test/Target/SPIRV/glsl-ops.mlir b/mlir/test/Target/SPIRV/glsl-ops.mlir
index 00422c226437..8fb583208428 100644
--- a/mlir/test/Target/SPIRV/glsl-ops.mlir
+++ b/mlir/test/Target/SPIRV/glsl-ops.mlir
@@ -1,7 +1,7 @@
 // RUN: mlir-translate -test-spirv-roundtrip %s | FileCheck %s
 
 spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
-  spv.func @fmul(%arg0 : f32, %arg1 : f32) "None" {
+  spv.func @fmul(%arg0 : f32, %arg1 : f32, %arg2 : i32) "None" {
     // CHECK: {{%.*}} = spv.GLSL.Exp {{%.*}} : f32
     %0 = spv.GLSL.Exp %arg0 : f32
     // CHECK: {{%.*}} = spv.GLSL.FMax {{%.*}}, {{%.*}} : f32
@@ -30,6 +30,8 @@ spv.module Logical GLSL450 requires #spv.vce<v1.0, [Shader], []> {
     %12 = spv.GLSL.Round %arg0 : f32
     // CHECK: {{%.*}} = spv.GLSL.FrexpStruct {{%.*}} : f32 -> !spv.struct<(f32, i32)>
     %13 = spv.GLSL.FrexpStruct %arg0 : f32 -> !spv.struct<(f32, i32)>
+    // CHECK: {{%.*}} = spv.GLSL.Ldexp {{%.*}} : f32, {{%.*}} : i32 -> f32
+    %14 = spv.GLSL.Ldexp %arg0 : f32, %arg2 : i32 -> f32
     spv.Return
   }
 


        


More information about the Mlir-commits mailing list