[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