[spirv-reader][ir] Correctly handle GLSL 450 FindSMsb
The SPIR-V `FindSMsb` method allows differing argument and return type.
The argument must also be interpreted as a signed value. So, inject
bitcasts as needed for the argument and return.
Bug: 391487629
Change-Id: If98081c52ddeebb2c176cc286771ce06bbeaf5e6
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/223055
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/tint/lang/spirv/builtin_fn.cc b/src/tint/lang/spirv/builtin_fn.cc
index e43c360..47afb9a 100644
--- a/src/tint/lang/spirv/builtin_fn.cc
+++ b/src/tint/lang/spirv/builtin_fn.cc
@@ -130,6 +130,8 @@
return "uclamp";
case BuiltinFn::kFindILsb:
return "findILsb";
+ case BuiltinFn::kFindSMsb:
+ return "findSMsb";
case BuiltinFn::kSdot:
return "sdot";
case BuiltinFn::kUdot:
@@ -194,6 +196,7 @@
case BuiltinFn::kUmin:
case BuiltinFn::kUclamp:
case BuiltinFn::kFindILsb:
+ case BuiltinFn::kFindSMsb:
break;
}
return core::ir::Instruction::Accesses{};
diff --git a/src/tint/lang/spirv/builtin_fn.cc.tmpl b/src/tint/lang/spirv/builtin_fn.cc.tmpl
index 30d7591..b8c68f1 100644
--- a/src/tint/lang/spirv/builtin_fn.cc.tmpl
+++ b/src/tint/lang/spirv/builtin_fn.cc.tmpl
@@ -83,6 +83,7 @@
case BuiltinFn::kUmin:
case BuiltinFn::kUclamp:
case BuiltinFn::kFindILsb:
+ case BuiltinFn::kFindSMsb:
break;
}
return core::ir::Instruction::Accesses{};
diff --git a/src/tint/lang/spirv/builtin_fn.h b/src/tint/lang/spirv/builtin_fn.h
index 1f62a6c..a5c85ef 100644
--- a/src/tint/lang/spirv/builtin_fn.h
+++ b/src/tint/lang/spirv/builtin_fn.h
@@ -92,6 +92,7 @@
kUmin,
kUclamp,
kFindILsb,
+ kFindSMsb,
kSdot,
kUdot,
kNone,
diff --git a/src/tint/lang/spirv/intrinsic/data.cc b/src/tint/lang/spirv/intrinsic/data.cc
index 3e1a0bd..e5b7421 100644
--- a/src/tint/lang/spirv/intrinsic/data.cc
+++ b/src/tint/lang/spirv/intrinsic/data.cc
@@ -5703,12 +5703,19 @@
},
{
/* [44] */
+ /* fn findSMsb<R : iu32>[T : iu32](T) -> R */
+ /* fn findSMsb<R : iu32>[T : iu32, N : num](vec<N, T>) -> vec<N, R> */
+ /* num overloads */ 2,
+ /* overloads */ OverloadIndex(154),
+ },
+ {
+ /* [45] */
/* fn sdot(u32, u32, u32) -> i32 */
/* num overloads */ 1,
/* overloads */ OverloadIndex(171),
},
{
- /* [45] */
+ /* [46] */
/* fn udot(u32, u32, u32) -> u32 */
/* num overloads */ 1,
/* overloads */ OverloadIndex(172),
diff --git a/src/tint/lang/spirv/reader/import_glsl_std450_test.cc b/src/tint/lang/spirv/reader/import_glsl_std450_test.cc
index cdea0a3..146868d 100644
--- a/src/tint/lang/spirv/reader/import_glsl_std450_test.cc
+++ b/src/tint/lang/spirv/reader/import_glsl_std450_test.cc
@@ -649,54 +649,6 @@
)");
}
-TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_FindSMsb) {
- // Check signedness conversion of arguments and results.
- // SPIR-V signed arg -> keep it
- // signed result -> keep it
- // unsigned result -> cast result to unsigned
- //
- // SPIR-V unsigned arg -> cast it to signed
- // signed result -> keept it
- // unsigned result -> cast result to unsigned
- EXPECT_IR(Preamble() + R"(
- ; signed arg
- ; signed result
- %1 = OpExtInst %int %glsl FindSMsb %int_30
- %2 = OpExtInst %v2int %glsl FindSMsb %v2int_30_40
-
- ; signed arg
- ; unsigned result
- %3 = OpExtInst %uint %glsl FindSMsb %int_30
- %4 = OpExtInst %v2uint %glsl FindSMsb %v2int_30_40
-
- ; unsigned arg
- ; signed result
- %5 = OpExtInst %int %glsl FindSMsb %uint_10
- %6 = OpExtInst %v2int %glsl FindSMsb %v2uint_10_20
-
- ; unsigned arg
- ; unsigned result
- %7 = OpExtInst %uint %glsl FindSMsb %uint_10
- %8 = OpExtInst %v2uint %glsl FindSMsb %v2uint_10_20
- OpReturn
- OpFunctionEnd
- )",
- R"(
-%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
- $B1: {
- let x_1 = firstLeadingBit(i1);
- let x_2 = firstLeadingBit(v2i1);
- let x_3 = bitcast<u32>(firstLeadingBit(i1));
- let x_4 = bitcast<vec2u>(firstLeadingBit(v2i1));
- let x_5 = firstLeadingBit(bitcast<i32>(u1));
- let x_6 = firstLeadingBit(bitcast<vec2i>(v2u1));
- let x_7 = bitcast<u32>(firstLeadingBit(bitcast<i32>(u1)));
- let x_8 = bitcast<vec2u>(firstLeadingBit(bitcast<vec2i>(v2u1)));
- }
-}
-)");
-}
-
TEST_F(SpirvReaderTest, DISABLED_RectifyOperandsAndResult_FindUMsb) {
// Check signedness conversion of arguments and results.
// SPIR-V signed arg -> cast arg to unsigned
diff --git a/src/tint/lang/spirv/reader/lower/builtins.cc b/src/tint/lang/spirv/reader/lower/builtins.cc
index 85acacb..b4ed7b1 100644
--- a/src/tint/lang/spirv/reader/lower/builtins.cc
+++ b/src/tint/lang/spirv/reader/lower/builtins.cc
@@ -94,6 +94,9 @@
case spirv::BuiltinFn::kFindILsb:
FindILsb(builtin);
break;
+ case spirv::BuiltinFn::kFindSMsb:
+ FindSMsb(builtin);
+ break;
default:
TINT_UNREACHABLE() << "unknown spirv builtin: " << builtin->Func();
}
@@ -137,6 +140,9 @@
WrapSignedSpirvMethods(call, core::BuiltinFn::kSign);
}
void Abs(spirv::ir::BuiltinCall* call) { WrapSignedSpirvMethods(call, core::BuiltinFn::kAbs); }
+ void FindSMsb(spirv::ir::BuiltinCall* call) {
+ WrapSignedSpirvMethods(call, core::BuiltinFn::kFirstLeadingBit);
+ }
void SMax(spirv::ir::BuiltinCall* call) { WrapSignedSpirvMethods(call, core::BuiltinFn::kMax); }
void SMin(spirv::ir::BuiltinCall* call) { WrapSignedSpirvMethods(call, core::BuiltinFn::kMin); }
void SClamp(spirv::ir::BuiltinCall* call) {
diff --git a/src/tint/lang/spirv/reader/lower/builtins_test.cc b/src/tint/lang/spirv/reader/lower/builtins_test.cc
index cda9c6e..e589218 100644
--- a/src/tint/lang/spirv/reader/lower/builtins_test.cc
+++ b/src/tint/lang/spirv/reader/lower/builtins_test.cc
@@ -1005,23 +1005,40 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvParser_BuiltinsTest, SAbs_UnsignedToUnsigned) {
+struct SpirvReaderParams {
+ spirv::BuiltinFn fn;
+ std::string spv_name;
+ std::string wgsl_name;
+};
+[[maybe_unused]] inline std::ostream& operator<<(std::ostream& out, SpirvReaderParams c) {
+ out << c.spv_name;
+ return out;
+}
+
+using SpirvParser_BuiltinsTest_OneParamSigned =
+ core::ir::transform::TransformTestWithParam<SpirvReaderParams>;
+
+TEST_P(SpirvParser_BuiltinsTest_OneParamSigned, UnsignedToUnsigned) {
+ auto params = GetParam();
+
auto* ep = b.ComputeFunction("foo");
b.Append(ep->Block(), [&] { //
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.u32(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.u32(), params.fn,
Vector<const core::type::Type*, 1>{ty.u32()}, 10_u);
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<u32>(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<u32>(), params.fn,
Vector<const core::type::Type*, 1>{ty.u32()},
b.Splat(ty.vec2<u32>(), 10_u));
b.Return(ep);
});
- auto* src = R"(
+ auto src = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:u32 = spirv.abs<u32> 10u
- %3:vec2<u32> = spirv.abs<u32> vec2<u32>(10u)
+ %2:u32 = spirv.)" +
+ params.spv_name + R"(<u32> 10u
+ %3:vec2<u32> = spirv.)" +
+ params.spv_name + R"(<u32> vec2<u32>(10u)
ret
}
}
@@ -1030,14 +1047,16 @@
EXPECT_EQ(src, str());
Run(Builtins);
- auto* expect = R"(
+ auto expect = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = bitcast 10u
- %3:i32 = abs %2
+ %3:i32 = )" + params.wgsl_name +
+ R"( %2
%4:u32 = bitcast %3
%5:vec2<i32> = bitcast vec2<u32>(10u)
- %6:vec2<i32> = abs %5
+ %6:vec2<i32> = )" +
+ params.wgsl_name + R"( %5
%7:vec2<u32> = bitcast %6
ret
}
@@ -1046,23 +1065,27 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvParser_BuiltinsTest, SAbs_UnsignedToSigned) {
+TEST_P(SpirvParser_BuiltinsTest_OneParamSigned, UnsignedToSigned) {
+ auto params = GetParam();
+
auto* ep = b.ComputeFunction("foo");
b.Append(ep->Block(), [&] { //
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.i32(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.i32(), params.fn,
Vector<const core::type::Type*, 1>{ty.i32()}, 10_u);
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<i32>(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<i32>(), params.fn,
Vector<const core::type::Type*, 1>{ty.i32()},
b.Splat(ty.vec2<u32>(), 10_u));
b.Return(ep);
});
- auto* src = R"(
+ auto src = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:i32 = spirv.abs<i32> 10u
- %3:vec2<i32> = spirv.abs<i32> vec2<u32>(10u)
+ %2:i32 = spirv.)" +
+ params.spv_name + R"(<i32> 10u
+ %3:vec2<i32> = spirv.)" +
+ params.spv_name + R"(<i32> vec2<u32>(10u)
ret
}
}
@@ -1071,13 +1094,15 @@
EXPECT_EQ(src, str());
Run(Builtins);
- auto* expect = R"(
+ auto expect = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = bitcast 10u
- %3:i32 = abs %2
+ %3:i32 = )" + params.wgsl_name +
+ R"( %2
%4:vec2<i32> = bitcast vec2<u32>(10u)
- %5:vec2<i32> = abs %4
+ %5:vec2<i32> = )" +
+ params.wgsl_name + R"( %4
ret
}
}
@@ -1085,23 +1110,27 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvParser_BuiltinsTest, SAbs_SignedToSigned) {
+TEST_P(SpirvParser_BuiltinsTest_OneParamSigned, SignedToSigned) {
+ auto params = GetParam();
+
auto* ep = b.ComputeFunction("foo");
b.Append(ep->Block(), [&] { //
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.i32(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.i32(), params.fn,
Vector<const core::type::Type*, 1>{ty.i32()}, 10_i);
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<i32>(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<i32>(), params.fn,
Vector<const core::type::Type*, 1>{ty.i32()},
b.Splat(ty.vec2<i32>(), 10_i));
b.Return(ep);
});
- auto* src = R"(
+ auto src = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:i32 = spirv.abs<i32> 10i
- %3:vec2<i32> = spirv.abs<i32> vec2<i32>(10i)
+ %2:i32 = spirv.)" +
+ params.spv_name + R"(<i32> 10i
+ %3:vec2<i32> = spirv.)" +
+ params.spv_name + R"(<i32> vec2<i32>(10i)
ret
}
}
@@ -1110,11 +1139,13 @@
EXPECT_EQ(src, str());
Run(Builtins);
- auto* expect = R"(
+ auto expect = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:i32 = abs 10i
- %3:vec2<i32> = abs vec2<i32>(10i)
+ %2:i32 = )" + params.wgsl_name +
+ R"( 10i
+ %3:vec2<i32> = )" +
+ params.wgsl_name + R"( vec2<i32>(10i)
ret
}
}
@@ -1122,23 +1153,27 @@
EXPECT_EQ(expect, str());
}
-TEST_F(SpirvParser_BuiltinsTest, SAbs_SignedToUnsigned) {
+TEST_P(SpirvParser_BuiltinsTest_OneParamSigned, SignedToUnsigned) {
+ auto params = GetParam();
+
auto* ep = b.ComputeFunction("foo");
b.Append(ep->Block(), [&] { //
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.u32(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.u32(), params.fn,
Vector<const core::type::Type*, 1>{ty.u32()}, 10_i);
- b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<u32>(), spirv::BuiltinFn::kAbs,
+ b.CallExplicit<spirv::ir::BuiltinCall>(ty.vec2<u32>(), params.fn,
Vector<const core::type::Type*, 1>{ty.u32()},
b.Splat(ty.vec2<i32>(), 10_i));
b.Return(ep);
});
- auto* src = R"(
+ auto src = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:u32 = spirv.abs<u32> 10i
- %3:vec2<u32> = spirv.abs<u32> vec2<i32>(10i)
+ %2:u32 = spirv.)" +
+ params.spv_name + R"(<u32> 10i
+ %3:vec2<u32> = spirv.)" +
+ params.spv_name + R"(<u32> vec2<i32>(10i)
ret
}
}
@@ -1147,12 +1182,14 @@
EXPECT_EQ(src, str());
Run(Builtins);
- auto* expect = R"(
+ auto expect = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:i32 = abs 10i
+ %2:i32 = )" + params.wgsl_name +
+ R"( 10i
%3:u32 = bitcast %2
- %4:vec2<i32> = abs vec2<i32>(10i)
+ %4:vec2<i32> = )" +
+ params.wgsl_name + R"( vec2<i32>(10i)
%5:vec2<u32> = bitcast %4
ret
}
@@ -1161,14 +1198,11 @@
EXPECT_EQ(expect, str());
}
-struct SpirvReaderParams {
- spirv::BuiltinFn fn;
- std::string name;
-};
-[[maybe_unused]] inline std::ostream& operator<<(std::ostream& out, SpirvReaderParams c) {
- out << c.name;
- return out;
-}
+INSTANTIATE_TEST_SUITE_P(SpirvReader,
+ SpirvParser_BuiltinsTest_OneParamSigned,
+ ::testing::Values(SpirvReaderParams{spirv::BuiltinFn::kAbs, "abs", "abs"},
+ SpirvReaderParams{spirv::BuiltinFn::kFindSMsb,
+ "findSMsb", "firstLeadingBit"}));
using SpirvParser_BuiltinsTest_TwoParamSigned =
core::ir::transform::TransformTestWithParam<SpirvReaderParams>;
@@ -1191,9 +1225,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = spirv.s)" +
- params.name + R"(<u32> 10u, 15u
+ params.spv_name + R"(<u32> 10u, 15u
%3:vec2<u32> = spirv.s)" +
- params.name + R"(<u32> vec2<u32>(10u), vec2<u32>(15u)
+ params.spv_name + R"(<u32> vec2<u32>(10u), vec2<u32>(15u)
ret
}
}
@@ -1207,13 +1241,13 @@
$B1: {
%2:i32 = bitcast 10u
%3:i32 = bitcast 15u
- %4:i32 = )" + params.name +
+ %4:i32 = )" + params.wgsl_name +
R"( %2, %3
%5:u32 = bitcast %4
%6:vec2<i32> = bitcast vec2<u32>(10u)
%7:vec2<i32> = bitcast vec2<u32>(15u)
%8:vec2<i32> = )" +
- params.name + R"( %6, %7
+ params.wgsl_name + R"( %6, %7
%9:vec2<u32> = bitcast %8
ret
}
@@ -1240,9 +1274,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = spirv.s)" +
- params.name + R"(<i32> 10i, 15i
+ params.spv_name + R"(<i32> 10i, 15i
%3:vec2<i32> = spirv.s)" +
- params.name + R"(<i32> vec2<i32>(10i), vec2<i32>(15i)
+ params.spv_name + R"(<i32> vec2<i32>(10i), vec2<i32>(15i)
ret
}
}
@@ -1254,10 +1288,10 @@
auto expect = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:i32 = )" + params.name +
+ %2:i32 = )" + params.wgsl_name +
R"( 10i, 15i
%3:vec2<i32> = )" +
- params.name + R"( vec2<i32>(10i), vec2<i32>(15i)
+ params.wgsl_name + R"( vec2<i32>(10i), vec2<i32>(15i)
ret
}
}
@@ -1283,9 +1317,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = spirv.s)" +
- params.name + R"(<u32> 10i, 10u
+ params.spv_name + R"(<u32> 10i, 10u
%3:vec2<u32> = spirv.s)" +
- params.name + R"(<u32> vec2<i32>(10i), vec2<u32>(10u)
+ params.spv_name + R"(<u32> vec2<i32>(10i), vec2<u32>(10u)
ret
}
}
@@ -1298,12 +1332,12 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = bitcast 10u
- %3:i32 = )" + params.name +
+ %3:i32 = )" + params.wgsl_name +
R"( 10i, %2
%4:u32 = bitcast %3
%5:vec2<i32> = bitcast vec2<u32>(10u)
%6:vec2<i32> = )" +
- params.name + R"( vec2<i32>(10i), %5
+ params.wgsl_name + R"( vec2<i32>(10i), %5
%7:vec2<u32> = bitcast %6
ret
}
@@ -1330,9 +1364,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = spirv.s)" +
- params.name + R"(<i32> 10u, 10i
+ params.spv_name + R"(<i32> 10u, 10i
%3:vec2<i32> = spirv.s)" +
- params.name + R"(<i32> vec2<u32>(10u), vec2<i32>(10i)
+ params.spv_name + R"(<i32> vec2<u32>(10u), vec2<i32>(10i)
ret
}
}
@@ -1345,11 +1379,11 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = bitcast 10u
- %3:i32 = )" + params.name +
+ %3:i32 = )" + params.wgsl_name +
R"( %2, 10i
%4:vec2<i32> = bitcast vec2<u32>(10u)
%5:vec2<i32> = )" +
- params.name + R"( %4, vec2<i32>(10i)
+ params.wgsl_name + R"( %4, vec2<i32>(10i)
ret
}
}
@@ -1359,8 +1393,9 @@
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvParser_BuiltinsTest_TwoParamSigned,
- ::testing::Values(SpirvReaderParams{spirv::BuiltinFn::kSmax, "max"},
- SpirvReaderParams{spirv::BuiltinFn::kSmin, "min"}));
+ ::testing::Values(SpirvReaderParams{spirv::BuiltinFn::kSmax, "max", "max"},
+ SpirvReaderParams{spirv::BuiltinFn::kSmin, "min",
+ "min"}));
using SpirvParser_BuiltinsTest_TwoParamUnsigned =
core::ir::transform::TransformTestWithParam<SpirvReaderParams>;
@@ -1383,9 +1418,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = spirv.u)" +
- params.name + R"(<u32> 10u, 15u
+ params.spv_name + R"(<u32> 10u, 15u
%3:vec2<u32> = spirv.u)" +
- params.name + R"(<u32> vec2<u32>(10u), vec2<u32>(15u)
+ params.spv_name + R"(<u32> vec2<u32>(10u), vec2<u32>(15u)
ret
}
}
@@ -1397,10 +1432,10 @@
auto expect = R"(
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
- %2:u32 = )" + params.name +
+ %2:u32 = )" + params.wgsl_name +
R"( 10u, 15u
%3:vec2<u32> = )" +
- params.name + R"( vec2<u32>(10u), vec2<u32>(15u)
+ params.wgsl_name + R"( vec2<u32>(10u), vec2<u32>(15u)
ret
}
}
@@ -1426,9 +1461,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = spirv.u)" +
- params.name + R"(<i32> 10i, 15i
+ params.spv_name + R"(<i32> 10i, 15i
%3:vec2<i32> = spirv.u)" +
- params.name + R"(<i32> vec2<i32>(10i), vec2<i32>(15i)
+ params.spv_name + R"(<i32> vec2<i32>(10i), vec2<i32>(15i)
ret
}
}
@@ -1442,13 +1477,13 @@
$B1: {
%2:u32 = bitcast 10i
%3:u32 = bitcast 15i
- %4:u32 = )" + params.name +
+ %4:u32 = )" + params.wgsl_name +
R"( %2, %3
%5:i32 = bitcast %4
%6:vec2<u32> = bitcast vec2<i32>(10i)
%7:vec2<u32> = bitcast vec2<i32>(15i)
%8:vec2<u32> = )" +
- params.name + R"( %6, %7
+ params.wgsl_name + R"( %6, %7
%9:vec2<i32> = bitcast %8
ret
}
@@ -1475,9 +1510,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = spirv.u)" +
- params.name + R"(<u32> 10i, 10u
+ params.spv_name + R"(<u32> 10i, 10u
%3:vec2<u32> = spirv.u)" +
- params.name + R"(<u32> vec2<i32>(10i), vec2<u32>(10u)
+ params.spv_name + R"(<u32> vec2<i32>(10i), vec2<u32>(10u)
ret
}
}
@@ -1490,11 +1525,11 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = bitcast 10i
- %3:u32 = )" + params.name +
+ %3:u32 = )" + params.wgsl_name +
R"( %2, 10u
%4:vec2<u32> = bitcast vec2<i32>(10i)
%5:vec2<u32> = )" +
- params.name + R"( %4, vec2<u32>(10u)
+ params.wgsl_name + R"( %4, vec2<u32>(10u)
ret
}
}
@@ -1520,9 +1555,9 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:i32 = spirv.u)" +
- params.name + R"(<i32> 10u, 10i
+ params.spv_name + R"(<i32> 10u, 10i
%3:vec2<i32> = spirv.u)" +
- params.name + R"(<i32> vec2<u32>(10u), vec2<i32>(10i)
+ params.spv_name + R"(<i32> vec2<u32>(10u), vec2<i32>(10i)
ret
}
}
@@ -1535,12 +1570,12 @@
%foo = @compute @workgroup_size(1u, 1u, 1u) func():void {
$B1: {
%2:u32 = bitcast 10i
- %3:u32 = )" + params.name +
+ %3:u32 = )" + params.wgsl_name +
R"( 10u, %2
%4:i32 = bitcast %3
%5:vec2<u32> = bitcast vec2<i32>(10i)
%6:vec2<u32> = )" +
- params.name + R"( vec2<u32>(10u), %5
+ params.wgsl_name + R"( vec2<u32>(10u), %5
%7:vec2<i32> = bitcast %6
ret
}
@@ -1551,8 +1586,9 @@
INSTANTIATE_TEST_SUITE_P(SpirvReader,
SpirvParser_BuiltinsTest_TwoParamUnsigned,
- ::testing::Values(SpirvReaderParams{spirv::BuiltinFn::kUmax, "max"},
- SpirvReaderParams{spirv::BuiltinFn::kUmin, "min"}));
+ ::testing::Values(SpirvReaderParams{spirv::BuiltinFn::kUmax, "max", "max"},
+ SpirvReaderParams{spirv::BuiltinFn::kUmin, "min",
+ "min"}));
TEST_F(SpirvParser_BuiltinsTest, SClamp_UnsignedToUnsigned) {
auto* ep = b.ComputeFunction("foo");
diff --git a/src/tint/lang/spirv/reader/parser/import_glsl_std450_test.cc b/src/tint/lang/spirv/reader/parser/import_glsl_std450_test.cc
index f87d7af..54020d8 100644
--- a/src/tint/lang/spirv/reader/parser/import_glsl_std450_test.cc
+++ b/src/tint/lang/spirv/reader/parser/import_glsl_std450_test.cc
@@ -159,104 +159,131 @@
)");
}
-TEST_F(SpirvParserTest, GlslStd450_SAbs_UnsignedToUnsigned) {
- EXPECT_IR(Preamble() + R"(
- %1 = OpExtInst %uint %glsl SAbs %uint_10
- %2 = OpExtInst %v2uint %glsl SAbs %v2uint_10_20
- %3 = OpCopyObject %uint %1
- %4 = OpCopyObject %v2uint %2
- OpReturn
- OpFunctionEnd
- )",
- R"(
-%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
- $B1: {
- %2:u32 = spirv.abs<u32> 10u
- %3:vec2<u32> = spirv.abs<u32> vec2<u32>(10u, 20u)
- %4:u32 = let %2
- %5:vec2<u32> = let %3
- ret
- }
-}
-)");
-}
-
-TEST_F(SpirvParserTest, GlslStd450_SAbs_UnsignedToSigned) {
- EXPECT_IR(Preamble() + R"(
- %1 = OpExtInst %int %glsl SAbs %uint_10
- %2 = OpExtInst %v2int %glsl SAbs %v2uint_10_20
- %3 = OpCopyObject %int %1
- %4 = OpCopyObject %v2int %2
- OpReturn
- OpFunctionEnd
- )",
- R"(
-%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
- $B1: {
- %2:i32 = spirv.abs<i32> 10u
- %3:vec2<i32> = spirv.abs<i32> vec2<u32>(10u, 20u)
- %4:i32 = let %2
- %5:vec2<i32> = let %3
- ret
- }
-}
-)");
-}
-
-TEST_F(SpirvParserTest, GlslStd450_SAbs_SignedToUnsigned) {
- EXPECT_IR(Preamble() + R"(
- %1 = OpExtInst %uint %glsl SAbs %int_10
- %2 = OpExtInst %v2uint %glsl SAbs %v2int_10_20
- %3 = OpCopyObject %uint %1
- %4 = OpCopyObject %v2uint %2
- OpReturn
- OpFunctionEnd
- )",
- R"(
-%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
- $B1: {
- %2:u32 = spirv.abs<u32> 10i
- %3:vec2<u32> = spirv.abs<u32> vec2<i32>(10i, 20i)
- %4:u32 = let %2
- %5:vec2<u32> = let %3
- ret
- }
-}
-)");
-}
-
-TEST_F(SpirvParserTest, GlslStd450_SAbs_SignedToSigned) {
- EXPECT_IR(Preamble() + R"(
- %1 = OpExtInst %int %glsl SAbs %int_10
- %2 = OpExtInst %v2int %glsl SAbs %v2int_10_20
- %3 = OpCopyObject %int %1
- %4 = OpCopyObject %v2int %2
- OpReturn
- OpFunctionEnd
- )",
- R"(
-%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
- $B1: {
- %2:i32 = spirv.abs<i32> 10i
- %3:vec2<i32> = spirv.abs<i32> vec2<i32>(10i, 20i)
- %4:i32 = let %2
- %5:vec2<i32> = let %3
- ret
- }
-}
-)");
-}
-
-struct GlslStd450TwoParams {
+struct GlslStd450Params {
std::string spv_name;
std::string ir_name;
};
-[[maybe_unused]] inline std::ostream& operator<<(std::ostream& out, GlslStd450TwoParams c) {
+[[maybe_unused]] inline std::ostream& operator<<(std::ostream& out, GlslStd450Params c) {
out << c.spv_name;
return out;
}
-using GlslStd450TwoParamTest = SpirvParserTestWithParam<GlslStd450TwoParams>;
+using GlslStd450OneParamTest = SpirvParserTestWithParam<GlslStd450Params>;
+
+TEST_P(GlslStd450OneParamTest, UnsignedToUnsigned) {
+ auto params = GetParam();
+ EXPECT_IR(Preamble() + R"(
+ %1 = OpExtInst %uint %glsl )" +
+ params.spv_name + R"( %uint_10
+ %2 = OpExtInst %v2uint %glsl )" +
+ params.spv_name + R"( %v2uint_10_20
+ %3 = OpCopyObject %uint %1
+ %4 = OpCopyObject %v2uint %2
+ OpReturn
+ OpFunctionEnd
+ )",
+ R"(
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ %2:u32 = spirv.)" +
+ params.ir_name + R"(<u32> 10u
+ %3:vec2<u32> = spirv.)" +
+ params.ir_name + R"(<u32> vec2<u32>(10u, 20u)
+ %4:u32 = let %2
+ %5:vec2<u32> = let %3
+ ret
+ }
+}
+)");
+}
+
+TEST_P(GlslStd450OneParamTest, UnsignedToSigned) {
+ auto params = GetParam();
+ EXPECT_IR(Preamble() + R"(
+ %1 = OpExtInst %int %glsl )" +
+ params.spv_name + R"( %uint_10
+ %2 = OpExtInst %v2int %glsl )" +
+ params.spv_name + R"( %v2uint_10_20
+ %3 = OpCopyObject %int %1
+ %4 = OpCopyObject %v2int %2
+ OpReturn
+ OpFunctionEnd
+ )",
+ R"(
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ %2:i32 = spirv.)" +
+ params.ir_name + R"(<i32> 10u
+ %3:vec2<i32> = spirv.)" +
+ params.ir_name + R"(<i32> vec2<u32>(10u, 20u)
+ %4:i32 = let %2
+ %5:vec2<i32> = let %3
+ ret
+ }
+}
+)");
+}
+
+TEST_P(GlslStd450OneParamTest, SignedToUnsigned) {
+ auto params = GetParam();
+ EXPECT_IR(Preamble() + R"(
+ %1 = OpExtInst %uint %glsl )" +
+ params.spv_name + R"( %int_10
+ %2 = OpExtInst %v2uint %glsl )" +
+ params.spv_name + R"( %v2int_10_20
+ %3 = OpCopyObject %uint %1
+ %4 = OpCopyObject %v2uint %2
+ OpReturn
+ OpFunctionEnd
+ )",
+ R"(
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ %2:u32 = spirv.)" +
+ params.ir_name + R"(<u32> 10i
+ %3:vec2<u32> = spirv.)" +
+ params.ir_name + R"(<u32> vec2<i32>(10i, 20i)
+ %4:u32 = let %2
+ %5:vec2<u32> = let %3
+ ret
+ }
+}
+)");
+}
+
+TEST_P(GlslStd450OneParamTest, SignedToSigned) {
+ auto params = GetParam();
+ EXPECT_IR(Preamble() + R"(
+ %1 = OpExtInst %int %glsl )" +
+ params.spv_name + R"( %int_10
+ %2 = OpExtInst %v2int %glsl )" +
+ params.spv_name + R"( %v2int_10_20
+ %3 = OpCopyObject %int %1
+ %4 = OpCopyObject %v2int %2
+ OpReturn
+ OpFunctionEnd
+ )",
+ R"(
+%main = @compute @workgroup_size(1u, 1u, 1u) func():void {
+ $B1: {
+ %2:i32 = spirv.)" +
+ params.ir_name + R"(<i32> 10i
+ %3:vec2<i32> = spirv.)" +
+ params.ir_name + R"(<i32> vec2<i32>(10i, 20i)
+ %4:i32 = let %2
+ %5:vec2<i32> = let %3
+ ret
+ }
+}
+)");
+}
+
+INSTANTIATE_TEST_SUITE_P(SpirvParser,
+ GlslStd450OneParamTest,
+ ::testing::Values(GlslStd450Params{"SAbs", "abs"},
+ GlslStd450Params{"FindSMsb", "findSMsb"}));
+
+using GlslStd450TwoParamTest = SpirvParserTestWithParam<GlslStd450Params>;
TEST_P(GlslStd450TwoParamTest, UnsignedToUnsigned) {
auto params = GetParam();
@@ -372,12 +399,12 @@
INSTANTIATE_TEST_SUITE_P(SpirvParser,
GlslStd450TwoParamTest,
- ::testing::Values(GlslStd450TwoParams{"SMax", "smax"},
- GlslStd450TwoParams{"SMin", "smin"},
- GlslStd450TwoParams{"UMax", "umax"},
- GlslStd450TwoParams{"UMin", "umin"}));
+ ::testing::Values(GlslStd450Params{"SMax", "smax"},
+ GlslStd450Params{"SMin", "smin"},
+ GlslStd450Params{"UMax", "umax"},
+ GlslStd450Params{"UMin", "umin"}));
-using GlslStd450ThreeParamTest = SpirvParserTestWithParam<GlslStd450TwoParams>;
+using GlslStd450ThreeParamTest = SpirvParserTestWithParam<GlslStd450Params>;
TEST_P(GlslStd450ThreeParamTest, UnsignedToUnsigned) {
auto params = GetParam();
@@ -493,8 +520,8 @@
INSTANTIATE_TEST_SUITE_P(SpirvParser,
GlslStd450ThreeParamTest,
- ::testing::Values(GlslStd450TwoParams{"SClamp", "sclamp"},
- GlslStd450TwoParams{"UClamp", "uclamp"}));
+ ::testing::Values(GlslStd450Params{"SClamp", "sclamp"},
+ GlslStd450Params{"UClamp", "uclamp"}));
TEST_F(SpirvParserTest, FindILsb) {
EXPECT_IR(Preamble() + R"(
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index 4ada393..5db0870 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -675,8 +675,6 @@
return core::BuiltinFn::kAbs;
case GLSLstd450FSign:
return core::BuiltinFn::kSign;
- case GLSLstd450FindSMsb:
- return core::BuiltinFn::kFirstLeadingBit;
case GLSLstd450FindUMsb:
return core::BuiltinFn::kFirstLeadingBit;
case GLSLstd450Floor:
@@ -779,6 +777,8 @@
return spirv::BuiltinFn::kUclamp;
case GLSLstd450FindILsb:
return spirv::BuiltinFn::kFindILsb;
+ case GLSLstd450FindSMsb:
+ return spirv::BuiltinFn::kFindSMsb;
default:
break;
}
@@ -791,7 +791,7 @@
ext_opcode == GLSLstd450SMax || ext_opcode == GLSLstd450SMin ||
ext_opcode == GLSLstd450SClamp || ext_opcode == GLSLstd450UMax ||
ext_opcode == GLSLstd450UMin || ext_opcode == GLSLstd450UClamp ||
- ext_opcode == GLSLstd450FindILsb) {
+ ext_opcode == GLSLstd450FindILsb || ext_opcode == GLSLstd450FindSMsb) {
return {result_ty->DeepestElement()};
}
return {};
diff --git a/src/tint/lang/spirv/spirv.def b/src/tint/lang/spirv/spirv.def
index 3e687c3..3724f02 100644
--- a/src/tint/lang/spirv/spirv.def
+++ b/src/tint/lang/spirv/spirv.def
@@ -347,6 +347,8 @@
implicit(T: iu32) fn findILsb<R: iu32>(T) -> R
implicit(T: iu32, N: num) fn findILsb<R: iu32>(vec<N, T>) -> vec<N, R>
+implicit(T: iu32) fn findSMsb<R: iu32>(T) -> R
+implicit(T: iu32, N: num) fn findSMsb<R: iu32>(vec<N, T>) -> vec<N, R>
////////////////////////////////////////////////////////////////////////////////
// SPV_KHR_integer_dot_product instructions
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index 566055f..4814b7f 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -1420,6 +1420,9 @@
case spirv::BuiltinFn::kFindILsb:
ext_inst(GLSLstd450FindILsb);
break;
+ case spirv::BuiltinFn::kFindSMsb:
+ ext_inst(GLSLstd450FindSMsb);
+ break;
case spirv::BuiltinFn::kUdot:
module_.PushExtension("SPV_KHR_integer_dot_product");
module_.PushCapability(SpvCapabilityDotProductKHR);