spirv-reader: ldexp second argument must be signed
Fixed: tint:1079 Change-Id: I628b81d95201474c6d1c584eafacd125448de30b Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60240 Commit-Queue: Ben Clayton <bclayton@google.com> Kokoro: Kokoro <noreply+kokoro@google.com> Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
ada4864ffe
commit
9d4c24fa5e
|
@ -3986,6 +3986,20 @@ TypedExpression FunctionEmitter::EmitGlslStd450ExtInst(
|
||||||
const spvtools::opt::Instruction& inst) {
|
const spvtools::opt::Instruction& inst) {
|
||||||
const auto ext_opcode = inst.GetSingleWordInOperand(1);
|
const auto ext_opcode = inst.GetSingleWordInOperand(1);
|
||||||
|
|
||||||
|
if (ext_opcode == GLSLstd450Ldexp) {
|
||||||
|
// WGSL requires the second argument to be signed.
|
||||||
|
// Use a type constructor to convert it, which is the same as a bitcast.
|
||||||
|
// If the value would go from very large positive to negative, then the
|
||||||
|
// original result would have been infinity. And since WGSL
|
||||||
|
// implementations may assume that infinities are not present, then we
|
||||||
|
// don't have to worry about that case.
|
||||||
|
auto e1 = MakeOperand(inst, 2);
|
||||||
|
auto e2 = ToSignedIfUnsigned(MakeOperand(inst, 3));
|
||||||
|
|
||||||
|
return {e1.type, builder_.Call(Source{}, "ldexp",
|
||||||
|
ast::ExpressionList{e1.expr, e2.expr})};
|
||||||
|
}
|
||||||
|
|
||||||
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
auto* result_type = parser_impl_.ConvertType(inst.type_id());
|
||||||
|
|
||||||
if (result_type->IsScalar()) {
|
if (result_type->IsScalar()) {
|
||||||
|
|
|
@ -158,8 +158,6 @@ using SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating =
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
using SpvParserTest_GlslStd450_Floating_FloatingInting =
|
using SpvParserTest_GlslStd450_Floating_FloatingInting =
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
using SpvParserTest_GlslStd450_Floating_FloatingUinting =
|
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
|
||||||
using SpvParserTest_GlslStd450_Float3_Float3Float3 =
|
using SpvParserTest_GlslStd450_Float3_Float3Float3 =
|
||||||
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
SpvParserTestBase<::testing::TestWithParam<GlslStd450Case>>;
|
||||||
|
|
||||||
|
@ -503,73 +501,6 @@ TEST_P(SpvParserTest_GlslStd450_Floating_FloatingFloatingFloating, Vector) {
|
||||||
<< body;
|
<< body;
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingUinting, Scalar) {
|
|
||||||
const auto assembly = Preamble() + R"(
|
|
||||||
%1 = OpExtInst %float %glsl )" +
|
|
||||||
GetParam().opcode + R"( %f1 %u1
|
|
||||||
OpReturn
|
|
||||||
OpFunctionEnd
|
|
||||||
)";
|
|
||||||
auto p = parser(test::Assemble(assembly));
|
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
|
||||||
auto fe = p->function_emitter(100);
|
|
||||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
|
||||||
const auto body = ToString(p->builder(), fe.ast_body());
|
|
||||||
EXPECT_THAT(body, HasSubstr(R"(
|
|
||||||
VariableConst{
|
|
||||||
x_1
|
|
||||||
none
|
|
||||||
undefined
|
|
||||||
__f32
|
|
||||||
{
|
|
||||||
Call[not set]{
|
|
||||||
Identifier[not set]{)" +
|
|
||||||
GetParam().wgsl_func +
|
|
||||||
R"(}
|
|
||||||
(
|
|
||||||
Identifier[not set]{f1}
|
|
||||||
Identifier[not set]{u1}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})"))
|
|
||||||
<< body;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingUinting, Vector) {
|
|
||||||
const auto assembly = Preamble() + R"(
|
|
||||||
%1 = OpExtInst %v2float %glsl )" +
|
|
||||||
GetParam().opcode +
|
|
||||||
R"( %v2f1 %v2u1
|
|
||||||
OpReturn
|
|
||||||
OpFunctionEnd
|
|
||||||
)";
|
|
||||||
auto p = parser(test::Assemble(assembly));
|
|
||||||
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
|
||||||
auto fe = p->function_emitter(100);
|
|
||||||
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
|
||||||
const auto body = ToString(p->builder(), fe.ast_body());
|
|
||||||
EXPECT_THAT(body, HasSubstr(R"(
|
|
||||||
VariableConst{
|
|
||||||
x_1
|
|
||||||
none
|
|
||||||
undefined
|
|
||||||
__vec_2__f32
|
|
||||||
{
|
|
||||||
Call[not set]{
|
|
||||||
Identifier[not set]{)" +
|
|
||||||
GetParam().wgsl_func +
|
|
||||||
R"(}
|
|
||||||
(
|
|
||||||
Identifier[not set]{v2f1}
|
|
||||||
Identifier[not set]{v2u1}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})"))
|
|
||||||
<< body;
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Scalar) {
|
TEST_P(SpvParserTest_GlslStd450_Floating_FloatingInting, Scalar) {
|
||||||
const auto assembly = Preamble() + R"(
|
const auto assembly = Preamble() + R"(
|
||||||
%1 = OpExtInst %float %glsl )" +
|
%1 = OpExtInst %float %glsl )" +
|
||||||
|
@ -720,13 +651,10 @@ INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
{"Step", "step"},
|
{"Step", "step"},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Samples,
|
|
||||||
SpvParserTest_GlslStd450_Floating_FloatingUinting,
|
|
||||||
::testing::Values(GlslStd450Case{"Ldexp", "ldexp"}));
|
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Samples,
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
SpvParserTest_GlslStd450_Floating_FloatingInting,
|
SpvParserTest_GlslStd450_Floating_FloatingInting,
|
||||||
::testing::Values(GlslStd450Case{"Ldexp", "ldexp"}));
|
::testing::Values(GlslStd450Case{"Ldexp", "ldexp"}));
|
||||||
|
// For ldexp with unsigned second argument, see below.
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(Samples,
|
INSTANTIATE_TEST_SUITE_P(Samples,
|
||||||
SpvParserTest_GlslStd450_Float3_Float3Float3,
|
SpvParserTest_GlslStd450_Float3_Float3Float3,
|
||||||
|
@ -2187,6 +2115,77 @@ TEST_F(SpvParserTest, GlslStd450_Radians_Vector) {
|
||||||
EXPECT_THAT(body, HasSubstr(expected)) << body;
|
EXPECT_THAT(body, HasSubstr(expected)) << body;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For ldexp with signed second argument, see above.
|
||||||
|
TEST_F(SpvParserTest, GlslStd450_Ldexp_Scalar_Float_Uint) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %float %glsl Ldexp %f1 %u1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
const auto body = ToString(p->builder(), fe.ast_body());
|
||||||
|
const auto* expected = R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
undefined
|
||||||
|
__f32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{ldexp}
|
||||||
|
(
|
||||||
|
Identifier[not set]{f1}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__i32
|
||||||
|
Identifier[not set]{u1}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})";
|
||||||
|
|
||||||
|
EXPECT_THAT(body, HasSubstr(expected)) << body;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SpvParserTest, GlslStd450_Ldexp_Vector_Floatvec_Uintvec) {
|
||||||
|
const auto assembly = Preamble() + R"(
|
||||||
|
%1 = OpExtInst %v2float %glsl Ldexp %v2f1 %v2u1
|
||||||
|
OpReturn
|
||||||
|
OpFunctionEnd
|
||||||
|
)";
|
||||||
|
auto p = parser(test::Assemble(assembly));
|
||||||
|
ASSERT_TRUE(p->BuildAndParseInternalModuleExceptFunctions());
|
||||||
|
auto fe = p->function_emitter(100);
|
||||||
|
EXPECT_TRUE(fe.EmitBody()) << p->error();
|
||||||
|
const auto body = ToString(p->builder(), fe.ast_body());
|
||||||
|
const auto* expected = R"(VariableDeclStatement{
|
||||||
|
VariableConst{
|
||||||
|
x_1
|
||||||
|
none
|
||||||
|
undefined
|
||||||
|
__vec_2__f32
|
||||||
|
{
|
||||||
|
Call[not set]{
|
||||||
|
Identifier[not set]{ldexp}
|
||||||
|
(
|
||||||
|
Identifier[not set]{v2f1}
|
||||||
|
TypeConstructor[not set]{
|
||||||
|
__vec_2__i32
|
||||||
|
Identifier[not set]{v2u1}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})";
|
||||||
|
|
||||||
|
EXPECT_THAT(body, HasSubstr(expected)) << body;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
} // namespace spirv
|
} // namespace spirv
|
||||||
} // namespace reader
|
} // namespace reader
|
||||||
|
|
Loading…
Reference in New Issue