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
"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 {
%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
+}
// 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
%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
}