mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-12-01 18:12:44 +00:00
[mlir][spirv] Define spv.GLSL.Ldexp
co-authored-by: Alan Liu <alanliu.yf@gmail.com> Reviewed By: antiagainst Differential Revision: https://reviews.llvm.org/D97228
This commit is contained in:
parent
fe50be12c8
commit
ce2ad938ff
@ -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
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user