Import Tint changes from Dawn
Changes:
- b32f9ca75b28abdbc0b8c25817de6641f2c71989 [tint][wgsl] Simplify IRToProgramTest by Ben Clayton <bclayton@google.com>
- d56afc4261e2d046a7d8e424be372487ec149c18 Remove materialize from core defs. by dan sinclair <dsinclair@chromium.org>
- a3430744b3c198bc3ad7e28dc94297f3b8e04ff9 [tint][ir] Validate user call arguments by Ben Clayton <bclayton@google.com>
- addf27edd4bd0f14ad3c459099f51195078929f6 [tint] Minor code refactor by Ben Clayton <bclayton@google.com>
- 47236f1ef5f29b90d32c7a591fadb38d321ba6ff [tint] Fix the datatype conversion in socket.cc by Sonakshi Saxena <nexa@google.com>
- becf2538e8896d1538d0e02e05c5e8022337b505 [tint] Improve unit test failure output. by Ben Clayton <bclayton@google.com>
- 9887c6ea389dfd01bec84e39aecbf07ead777d94 [tint][ir] Validate store target type by Ben Clayton <bclayton@google.com>
- fa41628b03f1c048b024e32581d4ec9404e88d1c [spirv-reader] Handle UBO variable decorations by James Price <jrprice@google.com>
- 2e2bf7b923ee30485fd134326345a6233e0884c2 [spirv-reader] Handle Op{AccessChain,Load,Store} by James Price <jrprice@google.com>
- bd9da033ea5b4242217b1343d16eaf9c2d098d44 [spirv-reader] Add Emit() and AddValue() helpers by James Price <jrprice@google.com>
- df41dad13f79f66e81d8693a10f44d67a2edbec7 Add new SPIRV AST fuzzer. by dan sinclair <dsinclair@chromium.org>
- 41cdde73fbc97afbe4de286d3180ad3420ca1fbc [tint][lang] Standardise lower / raise namespaces by Ben Clayton <bclayton@google.com>
- 31295c47ea224ae63b63bb78bd3f989074224f46 Add new GLSL fuzzer by dan sinclair <dsinclair@chromium.org>
- 91c5d6a2295dc2edd533de1935b92754690e23bb Add new HLSL fuzzer by dan sinclair <dsinclair@chromium.org>
- 2fe1f267e72e4e4e1b903b7c70f517c6d690c4e1 Add reflection for Access enum. by dan sinclair <dsinclair@chromium.org>
- 8a000ce7786b702fa12cee14160588dda6f6af5a [ir]: polyfill dot4I8Packed, dot4UPacked when needed by David Neto <dneto@google.com>
- 6140a5998637a8b64a83c4da189d02af11a503f2 Add Vector to byte decoder. by dan sinclair <dsinclair@chromium.org>
- d98c29e4403851696da11684c6f45ca840defd16 Additions to generator code. by dan sinclair <dsinclair@chromium.org>
- 514a18aed3fc6cbef08cfab57fc3b5155f6f84b9 [tint][ir] Use intrinsic table for binary ops. by Ben Clayton <bclayton@google.com>
- fa72454f21104406d53b6ca324c5fa65f03097a5 Add new MSL fuzzer by dan sinclair <dsinclair@chromium.org>
- 53edc77f378a6ff6837c75a8150fae179008e210 dp4a: fix Tint IR polyfills for unpack4x[IU]8 by David Neto <dneto@google.com>
- 1dc345789819bfa6509fe4fb3ecae600ddd6de2f [tint][ir] Add an IR binary roundtrip fuzzer by Ben Clayton <bclayton@google.com>
- b865a1e88666f21dc094e0218f12459e0743660c [tint][ir] Use intrinsic table for unary ops. by Ben Clayton <bclayton@google.com>
- 825f6265f4435d0aba4eaa60e5b6fa7938c513fc Add toggle to disable Tint polyfills on integer division ... by Jiawei Shao <jiawei.shao@intel.com>
GitOrigin-RevId: b32f9ca75b28abdbc0b8c25817de6641f2c71989
Change-Id: Ib87d37962a5220b36e44adc9989e61f001c7b599
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/168760
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/api/common/BUILD.bazel b/src/tint/api/common/BUILD.bazel
index 44c7d10..dca847a 100644
--- a/src/tint/api/common/BUILD.bazel
+++ b/src/tint/api/common/BUILD.bazel
@@ -49,7 +49,6 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/reflection",
- "//src/tint/utils/text",
"//src/tint/utils/traits",
],
copts = COPTS,
diff --git a/src/tint/api/common/BUILD.cmake b/src/tint/api/common/BUILD.cmake
index 019534d..96daf61 100644
--- a/src/tint/api/common/BUILD.cmake
+++ b/src/tint/api/common/BUILD.cmake
@@ -48,6 +48,5 @@
tint_utils_macros
tint_utils_math
tint_utils_reflection
- tint_utils_text
tint_utils_traits
)
diff --git a/src/tint/api/common/BUILD.gn b/src/tint/api/common/BUILD.gn
index 0d1ea88..7e710c8 100644
--- a/src/tint/api/common/BUILD.gn
+++ b/src/tint/api/common/BUILD.gn
@@ -48,7 +48,6 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/reflection",
- "${tint_src_dir}/utils/text",
"${tint_src_dir}/utils/traits",
]
}
diff --git a/src/tint/api/common/binding_point.h b/src/tint/api/common/binding_point.h
index f86d525..64d61f6 100644
--- a/src/tint/api/common/binding_point.h
+++ b/src/tint/api/common/binding_point.h
@@ -34,7 +34,6 @@
#include "src/tint/utils/math/hash.h"
#include "src/tint/utils/reflection/reflection.h"
-#include "src/tint/utils/text/string_stream.h"
#include "src/tint/utils/traits/traits.h"
namespace tint {
diff --git a/src/tint/api/options/BUILD.bazel b/src/tint/api/options/BUILD.bazel
index 3e1de60..b0e099b 100644
--- a/src/tint/api/options/BUILD.bazel
+++ b/src/tint/api/options/BUILD.bazel
@@ -53,7 +53,6 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/reflection",
- "//src/tint/utils/text",
"//src/tint/utils/traits",
],
copts = COPTS,
diff --git a/src/tint/api/options/BUILD.cmake b/src/tint/api/options/BUILD.cmake
index 9cf5e92..9de3f17 100644
--- a/src/tint/api/options/BUILD.cmake
+++ b/src/tint/api/options/BUILD.cmake
@@ -52,6 +52,5 @@
tint_utils_macros
tint_utils_math
tint_utils_reflection
- tint_utils_text
tint_utils_traits
)
diff --git a/src/tint/api/options/BUILD.gn b/src/tint/api/options/BUILD.gn
index 3b567ca..35d9806 100644
--- a/src/tint/api/options/BUILD.gn
+++ b/src/tint/api/options/BUILD.gn
@@ -52,7 +52,6 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/reflection",
- "${tint_src_dir}/utils/text",
"${tint_src_dir}/utils/traits",
]
}
diff --git a/src/tint/api/options/pixel_local.h b/src/tint/api/options/pixel_local.h
index 61e177b..1b4e200 100644
--- a/src/tint/api/options/pixel_local.h
+++ b/src/tint/api/options/pixel_local.h
@@ -28,6 +28,7 @@
#ifndef SRC_TINT_API_OPTIONS_PIXEL_LOCAL_H_
#define SRC_TINT_API_OPTIONS_PIXEL_LOCAL_H_
+#include <cstdint>
#include <unordered_map>
#include "src/tint/utils/reflection/reflection.h"
diff --git a/src/tint/cmd/bench/BUILD.bazel b/src/tint/cmd/bench/BUILD.bazel
index 48b45c3..a273bc9 100644
--- a/src/tint/cmd/bench/BUILD.bazel
+++ b/src/tint/cmd/bench/BUILD.bazel
@@ -113,6 +113,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/rtti:bench",
diff --git a/src/tint/cmd/bench/BUILD.cmake b/src/tint/cmd/bench/BUILD.cmake
index 9df1c7a..ee4b122 100644
--- a/src/tint/cmd/bench/BUILD.cmake
+++ b/src/tint/cmd/bench/BUILD.cmake
@@ -60,6 +60,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_rtti_bench
diff --git a/src/tint/cmd/bench/BUILD.gn b/src/tint/cmd/bench/BUILD.gn
index 8697f0c..7eb287d 100644
--- a/src/tint/cmd/bench/BUILD.gn
+++ b/src/tint/cmd/bench/BUILD.gn
@@ -114,6 +114,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/rtti:bench",
diff --git a/src/tint/cmd/fuzz/ir/fuzz.h b/src/tint/cmd/fuzz/ir/fuzz.h
index fa1ffd0..183ebe1 100644
--- a/src/tint/cmd/fuzz/ir/fuzz.h
+++ b/src/tint/cmd/fuzz/ir/fuzz.h
@@ -57,8 +57,8 @@
return;
}
bytes::BufferReader reader{data};
- if (auto data_args = bytes::Decode<std::tuple<std::decay_t<ARGS>...>>(reader);
- data_args == Success) {
+ auto data_args = bytes::Decode<std::tuple<std::decay_t<ARGS>...>>(reader);
+ if (data_args == Success) {
auto all_args =
std::tuple_cat(std::tuple<core::ir::Module&>{module}, data_args.Get());
std::apply(*fn, all_args);
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.bazel b/src/tint/cmd/fuzz/wgsl/BUILD.bazel
index c3cbe15..2b19c04 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.bazel
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.bazel
@@ -38,6 +38,26 @@
load("@bazel_skylib//lib:selects.bzl", "selects")
alias(
+ name = "tint_build_glsl_writer",
+ actual = "//src/tint:tint_build_glsl_writer_true",
+)
+
+alias(
+ name = "tint_build_hlsl_writer",
+ actual = "//src/tint:tint_build_hlsl_writer_true",
+)
+
+alias(
+ name = "tint_build_ir_binary",
+ actual = "//src/tint:tint_build_ir_binary_true",
+)
+
+alias(
+ name = "tint_build_msl_writer",
+ actual = "//src/tint:tint_build_msl_writer_true",
+)
+
+alias(
name = "tint_build_spv_writer",
actual = "//src/tint:tint_build_spv_writer_true",
)
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.cmake b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
index b0546c5..853fd5d 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.cmake
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.cmake
@@ -73,6 +73,30 @@
tint_utils_traits
)
+if(TINT_BUILD_GLSL_WRITER)
+ tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz_cmd fuzz_cmd
+ tint_lang_glsl_writer_fuzz
+ )
+endif(TINT_BUILD_GLSL_WRITER)
+
+if(TINT_BUILD_HLSL_WRITER)
+ tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz_cmd fuzz_cmd
+ tint_lang_hlsl_writer_fuzz
+ )
+endif(TINT_BUILD_HLSL_WRITER)
+
+if(TINT_BUILD_IR_BINARY)
+ tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz_cmd fuzz_cmd
+ tint_lang_core_ir_binary_fuzz
+ )
+endif(TINT_BUILD_IR_BINARY)
+
+if(TINT_BUILD_MSL_WRITER)
+ tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz_cmd fuzz_cmd
+ tint_lang_msl_writer_fuzz
+ )
+endif(TINT_BUILD_MSL_WRITER)
+
if(TINT_BUILD_SPV_WRITER)
tint_target_add_dependencies(tint_cmd_fuzz_wgsl_fuzz_cmd fuzz_cmd
tint_lang_spirv_writer_fuzz
diff --git a/src/tint/cmd/fuzz/wgsl/BUILD.gn b/src/tint/cmd/fuzz/wgsl/BUILD.gn
index 5dc14cb..97cec04 100644
--- a/src/tint/cmd/fuzz/wgsl/BUILD.gn
+++ b/src/tint/cmd/fuzz/wgsl/BUILD.gn
@@ -110,6 +110,22 @@
"${tint_src_dir}/utils/traits",
]
+ if (tint_build_glsl_writer) {
+ deps += [ "${tint_src_dir}/lang/glsl/writer:fuzz" ]
+ }
+
+ if (tint_build_hlsl_writer) {
+ deps += [ "${tint_src_dir}/lang/hlsl/writer:fuzz" ]
+ }
+
+ if (tint_build_ir_binary) {
+ deps += [ "${tint_src_dir}/lang/core/ir/binary:fuzz" ]
+ }
+
+ if (tint_build_msl_writer) {
+ deps += [ "${tint_src_dir}/lang/msl/writer:fuzz" ]
+ }
+
if (tint_build_spv_writer) {
deps += [ "${tint_src_dir}/lang/spirv/writer:fuzz" ]
}
diff --git a/src/tint/lang/core/BUILD.bazel b/src/tint/lang/core/BUILD.bazel
index a26c37f..ade8daa 100644
--- a/src/tint/lang/core/BUILD.bazel
+++ b/src/tint/lang/core/BUILD.bazel
@@ -78,6 +78,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/text",
@@ -143,6 +144,8 @@
],
deps = [
"//src/tint/lang/core",
+ "//src/tint/utils/macros",
+ "//src/tint/utils/reflection",
"//src/tint/utils/traits",
"@benchmark",
],
diff --git a/src/tint/lang/core/BUILD.cmake b/src/tint/lang/core/BUILD.cmake
index a5c1610..ea40bb5 100644
--- a/src/tint/lang/core/BUILD.cmake
+++ b/src/tint/lang/core/BUILD.cmake
@@ -82,6 +82,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_text
@@ -150,6 +151,8 @@
tint_target_add_dependencies(tint_lang_core_bench bench
tint_lang_core
+ tint_utils_macros
+ tint_utils_reflection
tint_utils_traits
)
diff --git a/src/tint/lang/core/BUILD.gn b/src/tint/lang/core/BUILD.gn
index 88de4fd..b1186f8 100644
--- a/src/tint/lang/core/BUILD.gn
+++ b/src/tint/lang/core/BUILD.gn
@@ -81,6 +81,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/text",
@@ -142,6 +143,8 @@
deps = [
"${tint_src_dir}:google_benchmark",
"${tint_src_dir}/lang/core",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/traits",
]
}
diff --git a/src/tint/lang/core/access.h b/src/tint/lang/core/access.h
index 9ace935..d03c07b 100644
--- a/src/tint/lang/core/access.h
+++ b/src/tint/lang/core/access.h
@@ -39,6 +39,7 @@
#include <cstdint>
+#include "src/tint/utils/reflection/reflection.h"
#include "src/tint/utils/traits/traits.h"
namespace tint::core {
@@ -76,4 +77,11 @@
} // namespace tint::core
+namespace tint {
+
+/// Access reflection information
+TINT_REFLECT_ENUM_RANGE(core::Access, kUndefined, kWrite);
+
+} // namespace tint
+
#endif // SRC_TINT_LANG_CORE_ACCESS_H_
diff --git a/src/tint/lang/core/access.h.tmpl b/src/tint/lang/core/access.h.tmpl
index 852f978..9e9112e 100644
--- a/src/tint/lang/core/access.h.tmpl
+++ b/src/tint/lang/core/access.h.tmpl
@@ -20,6 +20,7 @@
#include <cstdint>
+#include "src/tint/utils/reflection/reflection.h"
#include "src/tint/utils/traits/traits.h"
namespace tint::core {
@@ -29,4 +30,11 @@
} // namespace tint::core
+namespace tint {
+
+/// Access reflection information
+TINT_REFLECT_ENUM_RANGE(core::{{ Eval "EnumName" $enum }}, {{Eval "EnumFirst" $enum }}, {{Eval "EnumLast" $enum}});
+
+} // namespace tint
+
#endif // SRC_TINT_LANG_CORE_ACCESS_H_
diff --git a/src/tint/lang/core/builtin_fn.cc b/src/tint/lang/core/builtin_fn.cc
index 5344117..82e1e37 100644
--- a/src/tint/lang/core/builtin_fn.cc
+++ b/src/tint/lang/core/builtin_fn.cc
@@ -402,9 +402,6 @@
if (name == "subgroupBroadcast") {
return BuiltinFn::kSubgroupBroadcast;
}
- if (name == "_tint_materialize") {
- return BuiltinFn::kTintMaterialize;
- }
return BuiltinFn::kNone;
}
@@ -654,8 +651,6 @@
return "subgroupBallot";
case BuiltinFn::kSubgroupBroadcast:
return "subgroupBroadcast";
- case BuiltinFn::kTintMaterialize:
- return "_tint_materialize";
}
return "<unknown>";
}
diff --git a/src/tint/lang/core/builtin_fn.h b/src/tint/lang/core/builtin_fn.h
index 277b908..7a87054 100644
--- a/src/tint/lang/core/builtin_fn.h
+++ b/src/tint/lang/core/builtin_fn.h
@@ -168,7 +168,6 @@
kAtomicCompareExchangeWeak,
kSubgroupBallot,
kSubgroupBroadcast,
- kTintMaterialize,
kNone,
};
@@ -312,7 +311,6 @@
BuiltinFn::kAtomicCompareExchangeWeak,
BuiltinFn::kSubgroupBallot,
BuiltinFn::kSubgroupBroadcast,
- BuiltinFn::kTintMaterialize,
};
/// All builtin function names
@@ -438,7 +436,6 @@
"atomicCompareExchangeWeak",
"subgroupBallot",
"subgroupBroadcast",
- "_tint_materialize",
};
/// Determines if the given `f` is a coarse derivative.
diff --git a/src/tint/lang/core/constant/BUILD.bazel b/src/tint/lang/core/constant/BUILD.bazel
index b7967f5..b092c56 100644
--- a/src/tint/lang/core/constant/BUILD.bazel
+++ b/src/tint/lang/core/constant/BUILD.bazel
@@ -67,6 +67,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/core/constant/BUILD.cmake b/src/tint/lang/core/constant/BUILD.cmake
index 3e86cd2..b7dbca1 100644
--- a/src/tint/lang/core/constant/BUILD.cmake
+++ b/src/tint/lang/core/constant/BUILD.cmake
@@ -66,6 +66,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/core/constant/BUILD.gn b/src/tint/lang/core/constant/BUILD.gn
index 39c11d9..8549c0b 100644
--- a/src/tint/lang/core/constant/BUILD.gn
+++ b/src/tint/lang/core/constant/BUILD.gn
@@ -70,6 +70,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/core/core.def b/src/tint/lang/core/core.def
index 20eb59e..2606174 100644
--- a/src/tint/lang/core/core.def
+++ b/src/tint/lang/core/core.def
@@ -1115,8 +1115,3 @@
@must_use @const op >> <T: ia_iu32>(T, u32) -> T
@must_use @const op >> <T: ia_iu32, N: num> (vec<N, T>, vec<N, u32>) -> vec<N, T>
-
-////////////////////////////////////////////////////////////////////////////////
-// Tint internal builtins //
-////////////////////////////////////////////////////////////////////////////////
-@const("Identity") fn _tint_materialize<T>(T) -> T
diff --git a/src/tint/lang/core/intrinsic/BUILD.bazel b/src/tint/lang/core/intrinsic/BUILD.bazel
index ea936ea..141bff2 100644
--- a/src/tint/lang/core/intrinsic/BUILD.bazel
+++ b/src/tint/lang/core/intrinsic/BUILD.bazel
@@ -61,6 +61,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/core/intrinsic/BUILD.cmake b/src/tint/lang/core/intrinsic/BUILD.cmake
index 4a6f199..6af46bb 100644
--- a/src/tint/lang/core/intrinsic/BUILD.cmake
+++ b/src/tint/lang/core/intrinsic/BUILD.cmake
@@ -60,6 +60,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/core/intrinsic/BUILD.gn b/src/tint/lang/core/intrinsic/BUILD.gn
index 011a65a..fbfb8ce 100644
--- a/src/tint/lang/core/intrinsic/BUILD.gn
+++ b/src/tint/lang/core/intrinsic/BUILD.gn
@@ -64,6 +64,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/core/intrinsic/data.cc b/src/tint/lang/core/intrinsic/data.cc
index bf2983c..97482d5 100644
--- a/src/tint/lang/core/intrinsic/data.cc
+++ b/src/tint/lang/core/intrinsic/data.cc
@@ -4859,32 +4859,32 @@
/* [76] */ &core::constant::Eval::unpack4x8unorm,
/* [77] */ &core::constant::Eval::unpack4xI8,
/* [78] */ &core::constant::Eval::unpack4xU8,
- /* [79] */ &core::constant::Eval::Identity,
- /* [80] */ &core::constant::Eval::Not,
- /* [81] */ &core::constant::Eval::Complement,
- /* [82] */ &core::constant::Eval::UnaryMinus,
- /* [83] */ &core::constant::Eval::Plus,
- /* [84] */ &core::constant::Eval::Minus,
- /* [85] */ &core::constant::Eval::Multiply,
- /* [86] */ &core::constant::Eval::MultiplyMatVec,
- /* [87] */ &core::constant::Eval::MultiplyVecMat,
- /* [88] */ &core::constant::Eval::MultiplyMatMat,
- /* [89] */ &core::constant::Eval::Divide,
- /* [90] */ &core::constant::Eval::Modulo,
- /* [91] */ &core::constant::Eval::Xor,
- /* [92] */ &core::constant::Eval::And,
- /* [93] */ &core::constant::Eval::Or,
- /* [94] */ &core::constant::Eval::LogicalAnd,
- /* [95] */ &core::constant::Eval::LogicalOr,
- /* [96] */ &core::constant::Eval::Equal,
- /* [97] */ &core::constant::Eval::NotEqual,
- /* [98] */ &core::constant::Eval::LessThan,
- /* [99] */ &core::constant::Eval::GreaterThan,
- /* [100] */ &core::constant::Eval::LessThanEqual,
- /* [101] */ &core::constant::Eval::GreaterThanEqual,
- /* [102] */ &core::constant::Eval::ShiftLeft,
- /* [103] */ &core::constant::Eval::ShiftRight,
- /* [104] */ &core::constant::Eval::Zero,
+ /* [79] */ &core::constant::Eval::Not,
+ /* [80] */ &core::constant::Eval::Complement,
+ /* [81] */ &core::constant::Eval::UnaryMinus,
+ /* [82] */ &core::constant::Eval::Plus,
+ /* [83] */ &core::constant::Eval::Minus,
+ /* [84] */ &core::constant::Eval::Multiply,
+ /* [85] */ &core::constant::Eval::MultiplyMatVec,
+ /* [86] */ &core::constant::Eval::MultiplyVecMat,
+ /* [87] */ &core::constant::Eval::MultiplyMatMat,
+ /* [88] */ &core::constant::Eval::Divide,
+ /* [89] */ &core::constant::Eval::Modulo,
+ /* [90] */ &core::constant::Eval::Xor,
+ /* [91] */ &core::constant::Eval::And,
+ /* [92] */ &core::constant::Eval::Or,
+ /* [93] */ &core::constant::Eval::LogicalAnd,
+ /* [94] */ &core::constant::Eval::LogicalOr,
+ /* [95] */ &core::constant::Eval::Equal,
+ /* [96] */ &core::constant::Eval::NotEqual,
+ /* [97] */ &core::constant::Eval::LessThan,
+ /* [98] */ &core::constant::Eval::GreaterThan,
+ /* [99] */ &core::constant::Eval::LessThanEqual,
+ /* [100] */ &core::constant::Eval::GreaterThanEqual,
+ /* [101] */ &core::constant::Eval::ShiftLeft,
+ /* [102] */ &core::constant::Eval::ShiftRight,
+ /* [103] */ &core::constant::Eval::Zero,
+ /* [104] */ &core::constant::Eval::Identity,
/* [105] */ &core::constant::Eval::Conv,
/* [106] */ &core::constant::Eval::VecSplat,
/* [107] */ &core::constant::Eval::VecInitS,
@@ -5532,7 +5532,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(94),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [49] */
@@ -5545,7 +5545,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(52),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [50] */
@@ -5558,7 +5558,7 @@
/* parameters */ ParameterIndex(217),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(52),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [51] */
@@ -6429,7 +6429,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(88),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [118] */
@@ -6442,7 +6442,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(10),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [119] */
@@ -6455,7 +6455,7 @@
/* parameters */ ParameterIndex(213),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(10),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [120] */
@@ -6715,7 +6715,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(82),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [140] */
@@ -6728,7 +6728,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(72),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [141] */
@@ -6741,7 +6741,7 @@
/* parameters */ ParameterIndex(209),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(72),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [142] */
@@ -6845,7 +6845,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(85),
+ /* const_eval_fn */ ConstEvalFunctionIndex(84),
},
{
/* [150] */
@@ -6858,7 +6858,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(85),
+ /* const_eval_fn */ ConstEvalFunctionIndex(84),
},
{
/* [151] */
@@ -6871,7 +6871,7 @@
/* parameters */ ParameterIndex(223),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(85),
+ /* const_eval_fn */ ConstEvalFunctionIndex(84),
},
{
/* [152] */
@@ -6884,7 +6884,7 @@
/* parameters */ ParameterIndex(350),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(85),
+ /* const_eval_fn */ ConstEvalFunctionIndex(84),
},
{
/* [153] */
@@ -6897,7 +6897,7 @@
/* parameters */ ParameterIndex(355),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(12),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(2),
- /* const_eval_fn */ ConstEvalFunctionIndex(85),
+ /* const_eval_fn */ ConstEvalFunctionIndex(84),
},
{
/* [154] */
@@ -6910,7 +6910,7 @@
/* parameters */ ParameterIndex(354),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(12),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(2),
- /* const_eval_fn */ ConstEvalFunctionIndex(85),
+ /* const_eval_fn */ ConstEvalFunctionIndex(84),
},
{
/* [155] */
@@ -6923,7 +6923,7 @@
/* parameters */ ParameterIndex(356),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(3),
- /* const_eval_fn */ ConstEvalFunctionIndex(86),
+ /* const_eval_fn */ ConstEvalFunctionIndex(85),
},
{
/* [156] */
@@ -6936,7 +6936,7 @@
/* parameters */ ParameterIndex(358),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(87),
+ /* const_eval_fn */ ConstEvalFunctionIndex(86),
},
{
/* [157] */
@@ -6949,7 +6949,7 @@
/* parameters */ ParameterIndex(360),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(12),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(18),
- /* const_eval_fn */ ConstEvalFunctionIndex(88),
+ /* const_eval_fn */ ConstEvalFunctionIndex(87),
},
{
/* [158] */
@@ -7404,7 +7404,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(102),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [193] */
@@ -7417,7 +7417,7 @@
/* parameters */ ParameterIndex(385),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(102),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [194] */
@@ -7482,7 +7482,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(108),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [199] */
@@ -7495,7 +7495,7 @@
/* parameters */ ParameterIndex(388),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(108),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [200] */
@@ -7560,7 +7560,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(114),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [205] */
@@ -7573,7 +7573,7 @@
/* parameters */ ParameterIndex(391),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(114),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [206] */
@@ -7638,7 +7638,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(120),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [211] */
@@ -7651,7 +7651,7 @@
/* parameters */ ParameterIndex(394),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(120),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [212] */
@@ -7716,7 +7716,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(126),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [217] */
@@ -7729,7 +7729,7 @@
/* parameters */ ParameterIndex(397),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(126),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [218] */
@@ -7794,7 +7794,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(132),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [223] */
@@ -7807,7 +7807,7 @@
/* parameters */ ParameterIndex(400),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(132),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [224] */
@@ -7872,7 +7872,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(138),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [229] */
@@ -7885,7 +7885,7 @@
/* parameters */ ParameterIndex(403),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(138),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [230] */
@@ -7950,7 +7950,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(144),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [235] */
@@ -7963,7 +7963,7 @@
/* parameters */ ParameterIndex(406),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(144),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [236] */
@@ -8028,7 +8028,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(150),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [241] */
@@ -8041,7 +8041,7 @@
/* parameters */ ParameterIndex(409),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(150),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [242] */
@@ -8171,7 +8171,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(83),
+ /* const_eval_fn */ ConstEvalFunctionIndex(82),
},
{
/* [252] */
@@ -8184,7 +8184,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(83),
+ /* const_eval_fn */ ConstEvalFunctionIndex(82),
},
{
/* [253] */
@@ -8197,7 +8197,7 @@
/* parameters */ ParameterIndex(223),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(83),
+ /* const_eval_fn */ ConstEvalFunctionIndex(82),
},
{
/* [254] */
@@ -8210,7 +8210,7 @@
/* parameters */ ParameterIndex(350),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(83),
+ /* const_eval_fn */ ConstEvalFunctionIndex(82),
},
{
/* [255] */
@@ -8223,7 +8223,7 @@
/* parameters */ ParameterIndex(353),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(12),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(2),
- /* const_eval_fn */ ConstEvalFunctionIndex(83),
+ /* const_eval_fn */ ConstEvalFunctionIndex(82),
},
{
/* [256] */
@@ -8236,7 +8236,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(84),
+ /* const_eval_fn */ ConstEvalFunctionIndex(83),
},
{
/* [257] */
@@ -8249,7 +8249,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(84),
+ /* const_eval_fn */ ConstEvalFunctionIndex(83),
},
{
/* [258] */
@@ -8262,7 +8262,7 @@
/* parameters */ ParameterIndex(223),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(84),
+ /* const_eval_fn */ ConstEvalFunctionIndex(83),
},
{
/* [259] */
@@ -8275,7 +8275,7 @@
/* parameters */ ParameterIndex(350),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(84),
+ /* const_eval_fn */ ConstEvalFunctionIndex(83),
},
{
/* [260] */
@@ -8288,7 +8288,7 @@
/* parameters */ ParameterIndex(353),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(12),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(2),
- /* const_eval_fn */ ConstEvalFunctionIndex(84),
+ /* const_eval_fn */ ConstEvalFunctionIndex(83),
},
{
/* [261] */
@@ -8301,7 +8301,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(89),
+ /* const_eval_fn */ ConstEvalFunctionIndex(88),
},
{
/* [262] */
@@ -8314,7 +8314,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(89),
+ /* const_eval_fn */ ConstEvalFunctionIndex(88),
},
{
/* [263] */
@@ -8327,7 +8327,7 @@
/* parameters */ ParameterIndex(223),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(89),
+ /* const_eval_fn */ ConstEvalFunctionIndex(88),
},
{
/* [264] */
@@ -8340,7 +8340,7 @@
/* parameters */ ParameterIndex(350),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(89),
+ /* const_eval_fn */ ConstEvalFunctionIndex(88),
},
{
/* [265] */
@@ -8353,7 +8353,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(90),
+ /* const_eval_fn */ ConstEvalFunctionIndex(89),
},
{
/* [266] */
@@ -8366,7 +8366,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(90),
+ /* const_eval_fn */ ConstEvalFunctionIndex(89),
},
{
/* [267] */
@@ -8379,7 +8379,7 @@
/* parameters */ ParameterIndex(223),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(90),
+ /* const_eval_fn */ ConstEvalFunctionIndex(89),
},
{
/* [268] */
@@ -8392,7 +8392,7 @@
/* parameters */ ParameterIndex(350),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(90),
+ /* const_eval_fn */ ConstEvalFunctionIndex(89),
},
{
/* [269] */
@@ -8405,7 +8405,7 @@
/* parameters */ ParameterIndex(226),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(92),
+ /* const_eval_fn */ ConstEvalFunctionIndex(91),
},
{
/* [270] */
@@ -8418,7 +8418,7 @@
/* parameters */ ParameterIndex(233),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(92),
+ /* const_eval_fn */ ConstEvalFunctionIndex(91),
},
{
/* [271] */
@@ -8431,7 +8431,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(92),
+ /* const_eval_fn */ ConstEvalFunctionIndex(91),
},
{
/* [272] */
@@ -8444,7 +8444,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(92),
+ /* const_eval_fn */ ConstEvalFunctionIndex(91),
},
{
/* [273] */
@@ -8457,7 +8457,7 @@
/* parameters */ ParameterIndex(226),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(93),
+ /* const_eval_fn */ ConstEvalFunctionIndex(92),
},
{
/* [274] */
@@ -8470,7 +8470,7 @@
/* parameters */ ParameterIndex(233),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(93),
+ /* const_eval_fn */ ConstEvalFunctionIndex(92),
},
{
/* [275] */
@@ -8483,7 +8483,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(93),
+ /* const_eval_fn */ ConstEvalFunctionIndex(92),
},
{
/* [276] */
@@ -8496,7 +8496,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(93),
+ /* const_eval_fn */ ConstEvalFunctionIndex(92),
},
{
/* [277] */
@@ -8587,7 +8587,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(31),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [284] */
@@ -8600,7 +8600,7 @@
/* parameters */ ParameterIndex(380),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(31),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [285] */
@@ -8626,7 +8626,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(33),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [287] */
@@ -8639,7 +8639,7 @@
/* parameters */ ParameterIndex(17),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(33),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [288] */
@@ -8665,7 +8665,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(15),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [290] */
@@ -8678,7 +8678,7 @@
/* parameters */ ParameterIndex(370),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(15),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [291] */
@@ -8704,7 +8704,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(85),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [293] */
@@ -8717,7 +8717,7 @@
/* parameters */ ParameterIndex(381),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(85),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [294] */
@@ -8743,7 +8743,7 @@
/* parameters */ ParameterIndex(/* invalid */),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(104),
+ /* const_eval_fn */ ConstEvalFunctionIndex(103),
},
{
/* [296] */
@@ -8756,7 +8756,7 @@
/* parameters */ ParameterIndex(226),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(104),
},
{
/* [297] */
@@ -10212,7 +10212,7 @@
/* parameters */ ParameterIndex(226),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(80),
+ /* const_eval_fn */ ConstEvalFunctionIndex(79),
},
{
/* [409] */
@@ -10225,7 +10225,7 @@
/* parameters */ ParameterIndex(233),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(80),
+ /* const_eval_fn */ ConstEvalFunctionIndex(79),
},
{
/* [410] */
@@ -10238,7 +10238,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(81),
+ /* const_eval_fn */ ConstEvalFunctionIndex(80),
},
{
/* [411] */
@@ -10251,7 +10251,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(81),
+ /* const_eval_fn */ ConstEvalFunctionIndex(80),
},
{
/* [412] */
@@ -10264,7 +10264,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(82),
+ /* const_eval_fn */ ConstEvalFunctionIndex(81),
},
{
/* [413] */
@@ -10277,7 +10277,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(82),
+ /* const_eval_fn */ ConstEvalFunctionIndex(81),
},
{
/* [414] */
@@ -10290,7 +10290,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(91),
+ /* const_eval_fn */ ConstEvalFunctionIndex(90),
},
{
/* [415] */
@@ -10303,7 +10303,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(91),
+ /* const_eval_fn */ ConstEvalFunctionIndex(90),
},
{
/* [416] */
@@ -10316,7 +10316,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(96),
+ /* const_eval_fn */ ConstEvalFunctionIndex(95),
},
{
/* [417] */
@@ -10329,7 +10329,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(96),
+ /* const_eval_fn */ ConstEvalFunctionIndex(95),
},
{
/* [418] */
@@ -10342,7 +10342,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(97),
+ /* const_eval_fn */ ConstEvalFunctionIndex(96),
},
{
/* [419] */
@@ -10355,7 +10355,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(97),
+ /* const_eval_fn */ ConstEvalFunctionIndex(96),
},
{
/* [420] */
@@ -10368,7 +10368,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(98),
+ /* const_eval_fn */ ConstEvalFunctionIndex(97),
},
{
/* [421] */
@@ -10381,7 +10381,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(98),
+ /* const_eval_fn */ ConstEvalFunctionIndex(97),
},
{
/* [422] */
@@ -10394,7 +10394,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(99),
+ /* const_eval_fn */ ConstEvalFunctionIndex(98),
},
{
/* [423] */
@@ -10407,7 +10407,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(99),
+ /* const_eval_fn */ ConstEvalFunctionIndex(98),
},
{
/* [424] */
@@ -10420,7 +10420,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(100),
+ /* const_eval_fn */ ConstEvalFunctionIndex(99),
},
{
/* [425] */
@@ -10433,7 +10433,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(100),
+ /* const_eval_fn */ ConstEvalFunctionIndex(99),
},
{
/* [426] */
@@ -10446,7 +10446,7 @@
/* parameters */ ParameterIndex(1),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(101),
+ /* const_eval_fn */ ConstEvalFunctionIndex(100),
},
{
/* [427] */
@@ -10459,7 +10459,7 @@
/* parameters */ ParameterIndex(149),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(8),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(101),
+ /* const_eval_fn */ ConstEvalFunctionIndex(100),
},
{
/* [428] */
@@ -10472,7 +10472,7 @@
/* parameters */ ParameterIndex(16),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(102),
+ /* const_eval_fn */ ConstEvalFunctionIndex(101),
},
{
/* [429] */
@@ -10485,7 +10485,7 @@
/* parameters */ ParameterIndex(351),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(102),
+ /* const_eval_fn */ ConstEvalFunctionIndex(101),
},
{
/* [430] */
@@ -10498,7 +10498,7 @@
/* parameters */ ParameterIndex(16),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(103),
+ /* const_eval_fn */ ConstEvalFunctionIndex(102),
},
{
/* [431] */
@@ -10511,7 +10511,7 @@
/* parameters */ ParameterIndex(351),
/* return_type_matcher_indices */ TypeMatcherIndicesIndex(6),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(1),
- /* const_eval_fn */ ConstEvalFunctionIndex(103),
+ /* const_eval_fn */ ConstEvalFunctionIndex(102),
},
{
/* [432] */
@@ -10957,16 +10957,16 @@
},
{
/* [466] */
- /* flags */ OverloadFlags(OverloadFlag::kIsBuiltin, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline),
- /* num_parameters */ 1,
- /* num_template_types */ 1,
+ /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMustUse),
+ /* num_parameters */ 2,
+ /* num_template_types */ 0,
/* num_template_numbers */ 0,
- /* template_types */ TemplateTypeIndex(25),
+ /* template_types */ TemplateTypeIndex(/* invalid */),
/* template_numbers */ TemplateNumberIndex(/* invalid */),
- /* parameters */ ParameterIndex(1),
- /* return_type_matcher_indices */ TypeMatcherIndicesIndex(2),
+ /* parameters */ ParameterIndex(226),
+ /* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
/* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(79),
+ /* const_eval_fn */ ConstEvalFunctionIndex(93),
},
{
/* [467] */
@@ -10983,19 +10983,6 @@
},
{
/* [468] */
- /* flags */ OverloadFlags(OverloadFlag::kIsOperator, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMustUse),
- /* num_parameters */ 2,
- /* num_template_types */ 0,
- /* num_template_numbers */ 0,
- /* template_types */ TemplateTypeIndex(/* invalid */),
- /* template_numbers */ TemplateNumberIndex(/* invalid */),
- /* parameters */ ParameterIndex(226),
- /* return_type_matcher_indices */ TypeMatcherIndicesIndex(9),
- /* return_number_matcher_indices */ NumberMatcherIndicesIndex(/* invalid */),
- /* const_eval_fn */ ConstEvalFunctionIndex(95),
- },
- {
- /* [469] */
/* flags */ OverloadFlags(OverloadFlag::kIsConverter, OverloadFlag::kSupportsVertexPipeline, OverloadFlag::kSupportsFragmentPipeline, OverloadFlag::kSupportsComputePipeline, OverloadFlag::kMustUse),
/* num_parameters */ 1,
/* num_template_types */ 1,
@@ -11943,12 +11930,6 @@
/* num overloads */ 1,
/* overloads */ OverloadIndex(465),
},
- {
- /* [121] */
- /* fn _tint_materialize<T>(T) -> T */
- /* num overloads */ 1,
- /* overloads */ OverloadIndex(466),
- },
};
constexpr IntrinsicInfo kUnaryOperators[] = {
@@ -12060,13 +12041,13 @@
/* [8] */
/* op &&(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ OverloadIndex(467),
+ /* overloads */ OverloadIndex(466),
},
{
/* [9] */
/* op ||(bool, bool) -> bool */
/* num overloads */ 1,
- /* overloads */ OverloadIndex(468),
+ /* overloads */ OverloadIndex(467),
},
{
/* [10] */
@@ -12341,7 +12322,7 @@
/* [17] */
/* conv packedVec3<T : concrete_scalar>(vec3<T>) -> packedVec3<T> */
/* num overloads */ 1,
- /* overloads */ OverloadIndex(469),
+ /* overloads */ OverloadIndex(468),
},
};
diff --git a/src/tint/lang/core/ir/BUILD.bazel b/src/tint/lang/core/ir/BUILD.bazel
index 3c62fe9..a02930e 100644
--- a/src/tint/lang/core/ir/BUILD.bazel
+++ b/src/tint/lang/core/ir/BUILD.bazel
@@ -54,7 +54,9 @@
"continue.cc",
"control_instruction.cc",
"convert.cc",
+ "core_binary.cc",
"core_builtin_call.cc",
+ "core_unary.cc",
"disassembler.cc",
"discard.cc",
"exit.cc",
@@ -104,7 +106,9 @@
"continue.h",
"control_instruction.h",
"convert.h",
+ "core_binary.h",
"core_builtin_call.h",
+ "core_unary.h",
"disassembler.h",
"discard.h",
"exit.h",
@@ -169,7 +173,6 @@
alwayslink = True,
srcs = [
"access_test.cc",
- "binary_test.cc",
"bitcast_test.cc",
"block_param_test.cc",
"block_test.cc",
@@ -178,7 +181,9 @@
"construct_test.cc",
"continue_test.cc",
"convert_test.cc",
+ "core_binary_test.cc",
"core_builtin_call_test.cc",
+ "core_unary_test.cc",
"discard_test.cc",
"exit_if_test.cc",
"exit_loop_test.cc",
@@ -204,7 +209,6 @@
"swizzle_test.cc",
"terminate_invocation_test.cc",
"traverse_test.cc",
- "unary_test.cc",
"unreachable_test.cc",
"user_call_test.cc",
"validator_test.cc",
diff --git a/src/tint/lang/core/ir/BUILD.cmake b/src/tint/lang/core/ir/BUILD.cmake
index c901636..94365b4 100644
--- a/src/tint/lang/core/ir/BUILD.cmake
+++ b/src/tint/lang/core/ir/BUILD.cmake
@@ -72,8 +72,12 @@
lang/core/ir/control_instruction.h
lang/core/ir/convert.cc
lang/core/ir/convert.h
+ lang/core/ir/core_binary.cc
+ lang/core/ir/core_binary.h
lang/core/ir/core_builtin_call.cc
lang/core/ir/core_builtin_call.h
+ lang/core/ir/core_unary.cc
+ lang/core/ir/core_unary.h
lang/core/ir/disassembler.cc
lang/core/ir/disassembler.h
lang/core/ir/discard.cc
@@ -170,7 +174,6 @@
################################################################################
tint_add_target(tint_lang_core_ir_test test
lang/core/ir/access_test.cc
- lang/core/ir/binary_test.cc
lang/core/ir/bitcast_test.cc
lang/core/ir/block_param_test.cc
lang/core/ir/block_test.cc
@@ -179,7 +182,9 @@
lang/core/ir/construct_test.cc
lang/core/ir/continue_test.cc
lang/core/ir/convert_test.cc
+ lang/core/ir/core_binary_test.cc
lang/core/ir/core_builtin_call_test.cc
+ lang/core/ir/core_unary_test.cc
lang/core/ir/discard_test.cc
lang/core/ir/exit_if_test.cc
lang/core/ir/exit_loop_test.cc
@@ -205,7 +210,6 @@
lang/core/ir/swizzle_test.cc
lang/core/ir/terminate_invocation_test.cc
lang/core/ir/traverse_test.cc
- lang/core/ir/unary_test.cc
lang/core/ir/unreachable_test.cc
lang/core/ir/user_call_test.cc
lang/core/ir/validator_test.cc
diff --git a/src/tint/lang/core/ir/BUILD.gn b/src/tint/lang/core/ir/BUILD.gn
index 9bcb139..ac59268 100644
--- a/src/tint/lang/core/ir/BUILD.gn
+++ b/src/tint/lang/core/ir/BUILD.gn
@@ -74,8 +74,12 @@
"control_instruction.h",
"convert.cc",
"convert.h",
+ "core_binary.cc",
+ "core_binary.h",
"core_builtin_call.cc",
"core_builtin_call.h",
+ "core_unary.cc",
+ "core_unary.h",
"disassembler.cc",
"disassembler.h",
"discard.cc",
@@ -169,7 +173,6 @@
tint_unittests_source_set("unittests") {
sources = [
"access_test.cc",
- "binary_test.cc",
"bitcast_test.cc",
"block_param_test.cc",
"block_test.cc",
@@ -178,7 +181,9 @@
"construct_test.cc",
"continue_test.cc",
"convert_test.cc",
+ "core_binary_test.cc",
"core_builtin_call_test.cc",
+ "core_unary_test.cc",
"discard_test.cc",
"exit_if_test.cc",
"exit_loop_test.cc",
@@ -204,7 +209,6 @@
"swizzle_test.cc",
"terminate_invocation_test.cc",
"traverse_test.cc",
- "unary_test.cc",
"unreachable_test.cc",
"user_call_test.cc",
"validator_test.cc",
diff --git a/src/tint/lang/core/ir/binary.cc b/src/tint/lang/core/ir/binary.cc
index 732f029..2738b01 100644
--- a/src/tint/lang/core/ir/binary.cc
+++ b/src/tint/lang/core/ir/binary.cc
@@ -44,49 +44,4 @@
Binary::~Binary() = default;
-Binary* Binary::Clone(CloneContext& ctx) {
- auto* new_result = ctx.Clone(Result(0));
- auto* lhs = ctx.Remap(LHS());
- auto* rhs = ctx.Remap(RHS());
- return ctx.ir.instructions.Create<Binary>(new_result, op_, lhs, rhs);
-}
-
-std::string_view ToString(enum BinaryOp op) {
- switch (op) {
- case BinaryOp::kAdd:
- return "add";
- case BinaryOp::kSubtract:
- return "subtract";
- case BinaryOp::kMultiply:
- return "multiply";
- case BinaryOp::kDivide:
- return "divide";
- case BinaryOp::kModulo:
- return "modulo";
- case BinaryOp::kAnd:
- return "and";
- case BinaryOp::kOr:
- return "or";
- case BinaryOp::kXor:
- return "xor";
- case BinaryOp::kEqual:
- return "equal";
- case BinaryOp::kNotEqual:
- return "not equal";
- case BinaryOp::kLessThan:
- return "less than";
- case BinaryOp::kGreaterThan:
- return "greater than";
- case BinaryOp::kLessThanEqual:
- return "less than equal";
- case BinaryOp::kGreaterThanEqual:
- return "greater than equal";
- case BinaryOp::kShiftLeft:
- return "shift left";
- case BinaryOp::kShiftRight:
- return "shift right";
- }
- return "<unknown>";
-}
-
} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/binary.h b/src/tint/lang/core/ir/binary.h
index 5f8c26a..378dae4 100644
--- a/src/tint/lang/core/ir/binary.h
+++ b/src/tint/lang/core/ir/binary.h
@@ -30,36 +30,18 @@
#include <string>
+#include "src/tint/lang/core/binary_op.h"
#include "src/tint/lang/core/ir/operand_instruction.h"
-#include "src/tint/utils/rtti/castable.h"
+
+// Forward declarations
+namespace tint::core::intrinsic {
+struct TableData;
+}
namespace tint::core::ir {
-/// A binary operator.
-enum class BinaryOp {
- kAdd,
- kSubtract,
- kMultiply,
- kDivide,
- kModulo,
-
- kAnd,
- kOr,
- kXor,
-
- kEqual,
- kNotEqual,
- kLessThan,
- kGreaterThan,
- kLessThanEqual,
- kGreaterThanEqual,
-
- kShiftLeft,
- kShiftRight
-};
-
-/// A binary instruction in the IR.
-class Binary final : public Castable<Binary, OperandInstruction<2, 1>> {
+/// The abstract base class for dialect-specific binary-op instructions in the IR.
+class Binary : public Castable<Binary, OperandInstruction<2, 1>> {
public:
/// The offset in Operands() for the LHS
static constexpr size_t kLhsOperandOffset = 0;
@@ -78,9 +60,6 @@
Binary(InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs);
~Binary() override;
- /// @copydoc Instruction::Clone()
- Binary* Clone(CloneContext& ctx) override;
-
/// @returns the binary operator
BinaryOp Op() const { return op_; }
@@ -102,20 +81,13 @@
/// @returns the friendly name for the instruction
std::string FriendlyName() const override { return "binary"; }
+ /// @returns the table data to validate this builtin
+ virtual const core::intrinsic::TableData& TableData() const = 0;
+
private:
BinaryOp op_ = BinaryOp::kAdd;
};
-/// @param kind the enum value
-/// @returns the string for the given enum value
-std::string_view ToString(BinaryOp kind);
-
-/// Emits the name of the intrinsic type.
-template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>>
-auto& operator<<(STREAM& out, BinaryOp kind) {
- return out << ToString(kind);
-}
-
} // namespace tint::core::ir
#endif // SRC_TINT_LANG_CORE_IR_BINARY_H_
diff --git a/src/tint/lang/core/ir/binary/BUILD.cmake b/src/tint/lang/core/ir/binary/BUILD.cmake
index 61650da..c749148 100644
--- a/src/tint/lang/core/ir/binary/BUILD.cmake
+++ b/src/tint/lang/core/ir/binary/BUILD.cmake
@@ -130,4 +130,44 @@
)
endif(TINT_BUILD_IR_BINARY)
+endif(TINT_BUILD_IR_BINARY)
+if(TINT_BUILD_IR_BINARY)
+################################################################################
+# Target: tint_lang_core_ir_binary_fuzz
+# Kind: fuzz
+# Condition: TINT_BUILD_IR_BINARY
+################################################################################
+tint_add_target(tint_lang_core_ir_binary_fuzz fuzz
+ lang/core/ir/binary/roundtrip_fuzz.cc
+)
+
+tint_target_add_dependencies(tint_lang_core_ir_binary_fuzz fuzz
+ tint_api_common
+ tint_cmd_fuzz_ir_fuzz
+ tint_lang_core
+ tint_lang_core_constant
+ tint_lang_core_ir
+ tint_lang_core_type
+ tint_utils_bytes
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_IR_BINARY)
+ tint_target_add_dependencies(tint_lang_core_ir_binary_fuzz fuzz
+ tint_lang_core_ir_binary
+ )
+endif(TINT_BUILD_IR_BINARY)
+
endif(TINT_BUILD_IR_BINARY)
\ No newline at end of file
diff --git a/src/tint/lang/core/ir/binary/BUILD.gn b/src/tint/lang/core/ir/binary/BUILD.gn
index d0333c8..0e3dd8e 100644
--- a/src/tint/lang/core/ir/binary/BUILD.gn
+++ b/src/tint/lang/core/ir/binary/BUILD.gn
@@ -116,3 +116,34 @@
}
}
}
+if (tint_build_ir_binary) {
+ tint_fuzz_source_set("fuzz") {
+ sources = [ "roundtrip_fuzz.cc" ]
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/cmd/fuzz/ir:fuzz",
+ "${tint_src_dir}/lang/core",
+ "${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/ir",
+ "${tint_src_dir}/lang/core/type",
+ "${tint_src_dir}/utils/bytes",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_ir_binary) {
+ deps += [ "${tint_src_dir}/lang/core/ir/binary" ]
+ }
+ }
+}
diff --git a/src/tint/lang/core/ir/binary/decode.cc b/src/tint/lang/core/ir/binary/decode.cc
index fb77a96..8b3d75d 100644
--- a/src/tint/lang/core/ir/binary/decode.cc
+++ b/src/tint/lang/core/ir/binary/decode.cc
@@ -347,8 +347,8 @@
return mod_out_.instructions.Create<ir::Access>();
}
- ir::Binary* CreateInstructionBinary(const pb::InstructionBinary& binary_in) {
- auto* binary_out = mod_out_.instructions.Create<ir::Binary>();
+ ir::CoreBinary* CreateInstructionBinary(const pb::InstructionBinary& binary_in) {
+ auto* binary_out = mod_out_.instructions.Create<ir::CoreBinary>();
binary_out->SetOp(BinaryOp(binary_in.op()));
return binary_out;
}
@@ -494,8 +494,8 @@
return switch_out;
}
- ir::Unary* CreateInstructionUnary(const pb::InstructionUnary& unary_in) {
- auto* unary_out = mod_out_.instructions.Create<ir::Unary>();
+ ir::CoreUnary* CreateInstructionUnary(const pb::InstructionUnary& unary_in) {
+ auto* unary_out = mod_out_.instructions.Create<ir::CoreUnary>();
unary_out->SetOp(UnaryOp(unary_in.op()));
return unary_out;
}
@@ -894,57 +894,63 @@
}
}
- core::ir::UnaryOp UnaryOp(pb::UnaryOp in) {
+ core::UnaryOp UnaryOp(pb::UnaryOp in) {
switch (in) {
case pb::UnaryOp::complement:
- return core::ir::UnaryOp::kComplement;
+ return core::UnaryOp::kComplement;
case pb::UnaryOp::negation:
- return core::ir::UnaryOp::kNegation;
+ return core::UnaryOp::kNegation;
+ case pb::UnaryOp::address_of:
+ return core::UnaryOp::kAddressOf;
+ case pb::UnaryOp::indirection:
+ return core::UnaryOp::kIndirection;
+ case pb::UnaryOp::not_:
+ return core::UnaryOp::kNot;
default:
TINT_ICE() << "invalid UnaryOp: " << in;
- return core::ir::UnaryOp::kComplement;
+ return core::UnaryOp::kComplement;
}
}
- core::ir::BinaryOp BinaryOp(pb::BinaryOp in) {
+ core::BinaryOp BinaryOp(pb::BinaryOp in) {
switch (in) {
case pb::BinaryOp::add_:
- return core::ir::BinaryOp::kAdd;
+ return core::BinaryOp::kAdd;
case pb::BinaryOp::subtract:
- return core::ir::BinaryOp::kSubtract;
+ return core::BinaryOp::kSubtract;
case pb::BinaryOp::multiply:
- return core::ir::BinaryOp::kMultiply;
+ return core::BinaryOp::kMultiply;
case pb::BinaryOp::divide:
- return core::ir::BinaryOp::kDivide;
+ return core::BinaryOp::kDivide;
case pb::BinaryOp::modulo:
- return core::ir::BinaryOp::kModulo;
+ return core::BinaryOp::kModulo;
case pb::BinaryOp::and_:
- return core::ir::BinaryOp::kAnd;
+ return core::BinaryOp::kAnd;
case pb::BinaryOp::or_:
- return core::ir::BinaryOp::kOr;
+ return core::BinaryOp::kOr;
case pb::BinaryOp::xor_:
- return core::ir::BinaryOp::kXor;
+ return core::BinaryOp::kXor;
case pb::BinaryOp::equal:
- return core::ir::BinaryOp::kEqual;
+ return core::BinaryOp::kEqual;
case pb::BinaryOp::not_equal:
- return core::ir::BinaryOp::kNotEqual;
+ return core::BinaryOp::kNotEqual;
case pb::BinaryOp::less_than:
- return core::ir::BinaryOp::kLessThan;
+ return core::BinaryOp::kLessThan;
case pb::BinaryOp::greater_than:
- return core::ir::BinaryOp::kGreaterThan;
+ return core::BinaryOp::kGreaterThan;
case pb::BinaryOp::less_than_equal:
- return core::ir::BinaryOp::kLessThanEqual;
+ return core::BinaryOp::kLessThanEqual;
case pb::BinaryOp::greater_than_equal:
- return core::ir::BinaryOp::kGreaterThanEqual;
+ return core::BinaryOp::kGreaterThanEqual;
case pb::BinaryOp::shift_left:
- return core::ir::BinaryOp::kShiftLeft;
+ return core::BinaryOp::kShiftLeft;
case pb::BinaryOp::shift_right:
- return core::ir::BinaryOp::kShiftRight;
+ return core::BinaryOp::kShiftRight;
default:
TINT_ICE() << "invalid BinaryOp: " << in;
- return core::ir::BinaryOp::kAdd;
+ return core::BinaryOp::kAdd;
}
}
diff --git a/src/tint/lang/core/ir/binary/encode.cc b/src/tint/lang/core/ir/binary/encode.cc
index fa72a55..6f57223 100644
--- a/src/tint/lang/core/ir/binary/encode.cc
+++ b/src/tint/lang/core/ir/binary/encode.cc
@@ -35,13 +35,14 @@
#include "src/tint/lang/core/constant/scalar.h"
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/ir/access.h"
-#include "src/tint/lang/core/ir/binary.h"
#include "src/tint/lang/core/ir/bitcast.h"
#include "src/tint/lang/core/ir/break_if.h"
#include "src/tint/lang/core/ir/construct.h"
#include "src/tint/lang/core/ir/continue.h"
#include "src/tint/lang/core/ir/convert.h"
+#include "src/tint/lang/core/ir/core_binary.h"
#include "src/tint/lang/core/ir/core_builtin_call.h"
+#include "src/tint/lang/core/ir/core_unary.h"
#include "src/tint/lang/core/ir/discard.h"
#include "src/tint/lang/core/ir/exit_if.h"
#include "src/tint/lang/core/ir/exit_loop.h"
@@ -60,7 +61,6 @@
#include "src/tint/lang/core/ir/store_vector_element.h"
#include "src/tint/lang/core/ir/switch.h"
#include "src/tint/lang/core/ir/swizzle.h"
-#include "src/tint/lang/core/ir/unary.h"
#include "src/tint/lang/core/ir/unreachable.h"
#include "src/tint/lang/core/ir/user_call.h"
#include "src/tint/lang/core/ir/var.h"
@@ -198,12 +198,13 @@
tint::Switch(
inst_in, //
[&](const ir::Access* i) { InstructionAccess(*inst_out.mutable_access(), i); },
- [&](const ir::Binary* i) { InstructionBinary(*inst_out.mutable_binary(), i); },
[&](const ir::Bitcast* i) { InstructionBitcast(*inst_out.mutable_bitcast(), i); },
[&](const ir::BreakIf* i) { InstructionBreakIf(*inst_out.mutable_break_if(), i); },
+ [&](const ir::CoreBinary* i) { InstructionBinary(*inst_out.mutable_binary(), i); },
[&](const ir::CoreBuiltinCall* i) {
InstructionBuiltinCall(*inst_out.mutable_builtin_call(), i);
},
+ [&](const ir::CoreUnary* i) { InstructionUnary(*inst_out.mutable_unary(), i); },
[&](const ir::Construct* i) { InstructionConstruct(*inst_out.mutable_construct(), i); },
[&](const ir::Continue* i) { InstructionContinue(*inst_out.mutable_continue_(), i); },
[&](const ir::Convert* i) { InstructionConvert(*inst_out.mutable_convert(), i); },
@@ -230,7 +231,6 @@
},
[&](const ir::Switch* i) { InstructionSwitch(*inst_out.mutable_switch_(), i); },
[&](const ir::Swizzle* i) { InstructionSwizzle(*inst_out.mutable_swizzle(), i); },
- [&](const ir::Unary* i) { InstructionUnary(*inst_out.mutable_unary(), i); },
[&](const ir::UserCall* i) { InstructionUserCall(*inst_out.mutable_user_call(), i); },
[&](const ir::Var* i) { InstructionVar(*inst_out.mutable_var(), i); },
[&](const ir::Unreachable* i) {
@@ -247,7 +247,7 @@
void InstructionAccess(pb::InstructionAccess&, const ir::Access*) {}
- void InstructionBinary(pb::InstructionBinary& binary_out, const ir::Binary* binary_in) {
+ void InstructionBinary(pb::InstructionBinary& binary_out, const ir::CoreBinary* binary_in) {
binary_out.set_op(BinaryOp(binary_in->Op()));
}
@@ -329,7 +329,7 @@
}
}
- void InstructionUnary(pb::InstructionUnary& unary_out, const ir::Unary* unary_in) {
+ void InstructionUnary(pb::InstructionUnary& unary_out, const ir::CoreUnary* unary_in) {
unary_out.set_op(UnaryOp(unary_in->Op()));
}
@@ -675,51 +675,61 @@
}
}
- pb::UnaryOp UnaryOp(core::ir::UnaryOp in) {
+ pb::UnaryOp UnaryOp(core::UnaryOp in) {
switch (in) {
- case core::ir::UnaryOp::kComplement:
+ case core::UnaryOp::kComplement:
return pb::UnaryOp::complement;
- case core::ir::UnaryOp::kNegation:
+ case core::UnaryOp::kNegation:
return pb::UnaryOp::negation;
+ case core::UnaryOp::kAddressOf:
+ return pb::UnaryOp::address_of;
+ case core::UnaryOp::kIndirection:
+ return pb::UnaryOp::indirection;
+ case core::UnaryOp::kNot:
+ return pb::UnaryOp::not_;
}
TINT_ICE() << "invalid UnaryOp: " << in;
return pb::UnaryOp::complement;
}
- pb::BinaryOp BinaryOp(core::ir::BinaryOp in) {
+ pb::BinaryOp BinaryOp(core::BinaryOp in) {
switch (in) {
- case core::ir::BinaryOp::kAdd:
+ case core::BinaryOp::kAdd:
return pb::BinaryOp::add_;
- case core::ir::BinaryOp::kSubtract:
+ case core::BinaryOp::kSubtract:
return pb::BinaryOp::subtract;
- case core::ir::BinaryOp::kMultiply:
+ case core::BinaryOp::kMultiply:
return pb::BinaryOp::multiply;
- case core::ir::BinaryOp::kDivide:
+ case core::BinaryOp::kDivide:
return pb::BinaryOp::divide;
- case core::ir::BinaryOp::kModulo:
+ case core::BinaryOp::kModulo:
return pb::BinaryOp::modulo;
- case core::ir::BinaryOp::kAnd:
+ case core::BinaryOp::kAnd:
return pb::BinaryOp::and_;
- case core::ir::BinaryOp::kOr:
+ case core::BinaryOp::kOr:
return pb::BinaryOp::or_;
- case core::ir::BinaryOp::kXor:
+ case core::BinaryOp::kXor:
return pb::BinaryOp::xor_;
- case core::ir::BinaryOp::kEqual:
+ case core::BinaryOp::kEqual:
return pb::BinaryOp::equal;
- case core::ir::BinaryOp::kNotEqual:
+ case core::BinaryOp::kNotEqual:
return pb::BinaryOp::not_equal;
- case core::ir::BinaryOp::kLessThan:
+ case core::BinaryOp::kLessThan:
return pb::BinaryOp::less_than;
- case core::ir::BinaryOp::kGreaterThan:
+ case core::BinaryOp::kGreaterThan:
return pb::BinaryOp::greater_than;
- case core::ir::BinaryOp::kLessThanEqual:
+ case core::BinaryOp::kLessThanEqual:
return pb::BinaryOp::less_than_equal;
- case core::ir::BinaryOp::kGreaterThanEqual:
+ case core::BinaryOp::kGreaterThanEqual:
return pb::BinaryOp::greater_than_equal;
- case core::ir::BinaryOp::kShiftLeft:
+ case core::BinaryOp::kShiftLeft:
return pb::BinaryOp::shift_left;
- case core::ir::BinaryOp::kShiftRight:
+ case core::BinaryOp::kShiftRight:
return pb::BinaryOp::shift_right;
+ case core::BinaryOp::kLogicalAnd:
+ return pb::BinaryOp::logical_and;
+ case core::BinaryOp::kLogicalOr:
+ return pb::BinaryOp::logical_or;
}
TINT_ICE() << "invalid BinaryOp: " << in;
diff --git a/src/tint/lang/core/ir/binary/ir.proto b/src/tint/lang/core/ir/binary/ir.proto
index 8eb5c20..20933ce 100644
--- a/src/tint/lang/core/ir/binary/ir.proto
+++ b/src/tint/lang/core/ir/binary/ir.proto
@@ -413,6 +413,9 @@
enum UnaryOp {
complement = 0;
negation = 1;
+ address_of = 2;
+ indirection = 3;
+ not = 4;
}
enum BinaryOp {
@@ -432,6 +435,8 @@
greater_than_equal = 13;
shift_left = 14;
shift_right = 15;
+ logical_and = 16;
+ logical_or = 17;
}
enum TextureDimension {
diff --git a/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc b/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc
new file mode 100644
index 0000000..32886de
--- /dev/null
+++ b/src/tint/lang/core/ir/binary/roundtrip_fuzz.cc
@@ -0,0 +1,69 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/cmd/fuzz/ir/fuzz.h"
+#include "src/tint/lang/core/ir/binary/decode.h"
+#include "src/tint/lang/core/ir/binary/encode.h"
+#include "src/tint/lang/core/ir/disassembler.h"
+
+namespace tint::core::ir::binary {
+namespace {
+
+void IRBinaryRoundtripFuzzer(core::ir::Module& module) {
+ auto encoded = Encode(module);
+ if (encoded != Success) {
+ TINT_ICE() << "Encode() failed\n" << encoded.Failure();
+ return;
+ }
+
+ auto decoded = Decode(encoded->Slice());
+ if (decoded != Success) {
+ TINT_ICE() << "Decode() failed\n" << decoded.Failure();
+ return;
+ }
+
+ auto in = Disassemble(module);
+ auto out = Disassemble(decoded.Get());
+ if (in != out) {
+ TINT_ICE() << "Roundtrip produced different disassembly\n"
+ << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+ << "-= In =-\n"
+ << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+ << in << "\n"
+ << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+ << "-= Out =-\n"
+ << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"
+ << out << "\n"
+ << "-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n";
+ return;
+ }
+}
+
+} // namespace
+} // namespace tint::core::ir::binary
+
+TINT_IR_MODULE_FUZZER(tint::core::ir::binary::IRBinaryRoundtripFuzzer);
diff --git a/src/tint/lang/core/ir/builder.h b/src/tint/lang/core/ir/builder.h
index fc847c7..dd44c4f 100644
--- a/src/tint/lang/core/ir/builder.h
+++ b/src/tint/lang/core/ir/builder.h
@@ -34,7 +34,6 @@
#include "src/tint/lang/core/constant/scalar.h"
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/ir/access.h"
-#include "src/tint/lang/core/ir/binary.h"
#include "src/tint/lang/core/ir/bitcast.h"
#include "src/tint/lang/core/ir/block_param.h"
#include "src/tint/lang/core/ir/break_if.h"
@@ -42,7 +41,9 @@
#include "src/tint/lang/core/ir/construct.h"
#include "src/tint/lang/core/ir/continue.h"
#include "src/tint/lang/core/ir/convert.h"
+#include "src/tint/lang/core/ir/core_binary.h"
#include "src/tint/lang/core/ir/core_builtin_call.h"
+#include "src/tint/lang/core/ir/core_unary.h"
#include "src/tint/lang/core/ir/discard.h"
#include "src/tint/lang/core/ir/exit_if.h"
#include "src/tint/lang/core/ir/exit_loop.h"
@@ -64,7 +65,6 @@
#include "src/tint/lang/core/ir/switch.h"
#include "src/tint/lang/core/ir/swizzle.h"
#include "src/tint/lang/core/ir/terminate_invocation.h"
-#include "src/tint/lang/core/ir/unary.h"
#include "src/tint/lang/core/ir/unreachable.h"
#include "src/tint/lang/core/ir/user_call.h"
#include "src/tint/lang/core/ir/value.h"
@@ -472,12 +472,12 @@
/// @param rhs the right-hand-side of the operation
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Binary(BinaryOp op, const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Binary(BinaryOp op, const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
CheckForNonDeterministicEvaluation<LHS, RHS>();
auto* lhs_val = Value(std::forward<LHS>(lhs));
auto* rhs_val = Value(std::forward<RHS>(rhs));
return Append(
- ir.instructions.Create<ir::Binary>(InstructionResult(type), op, lhs_val, rhs_val));
+ ir.instructions.Create<ir::CoreBinary>(InstructionResult(type), op, lhs_val, rhs_val));
}
/// Creates an And operation
@@ -486,7 +486,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* And(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* And(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kAnd, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -496,7 +496,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* And(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* And(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return And(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -507,7 +507,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Or(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Or(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kOr, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -517,7 +517,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Or(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Or(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Or(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -528,7 +528,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Xor(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Xor(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kXor, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -538,7 +538,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Xor(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Xor(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Xor(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -549,7 +549,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Equal(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Equal(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kEqual, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -559,7 +559,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Equal(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Equal(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Equal(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -570,7 +570,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* NotEqual(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* NotEqual(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kNotEqual, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -580,7 +580,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* NotEqual(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* NotEqual(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return NotEqual(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -591,7 +591,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* LessThan(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* LessThan(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kLessThan, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -601,7 +601,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* LessThan(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* LessThan(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return LessThan(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -612,7 +612,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* GreaterThan(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* GreaterThan(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kGreaterThan, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -622,7 +622,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* GreaterThan(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* GreaterThan(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return GreaterThan(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -633,7 +633,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* LessThanEqual(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* LessThanEqual(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kLessThanEqual, type, std::forward<LHS>(lhs),
std::forward<RHS>(rhs));
}
@@ -644,7 +644,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* LessThanEqual(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* LessThanEqual(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return LessThanEqual(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -655,7 +655,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* GreaterThanEqual(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* GreaterThanEqual(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kGreaterThanEqual, type, std::forward<LHS>(lhs),
std::forward<RHS>(rhs));
}
@@ -666,7 +666,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* GreaterThanEqual(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* GreaterThanEqual(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return GreaterThanEqual(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -677,7 +677,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* ShiftLeft(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* ShiftLeft(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kShiftLeft, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -687,7 +687,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* ShiftLeft(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* ShiftLeft(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return ShiftLeft(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -698,7 +698,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* ShiftRight(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* ShiftRight(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kShiftRight, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -708,7 +708,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* ShiftRight(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* ShiftRight(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return ShiftRight(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -719,7 +719,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Add(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Add(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kAdd, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -729,7 +729,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Add(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Add(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Add(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -740,7 +740,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Subtract(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Subtract(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kSubtract, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -750,7 +750,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Subtract(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Subtract(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Subtract(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -761,7 +761,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Multiply(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Multiply(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kMultiply, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -771,7 +771,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Multiply(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Multiply(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Multiply(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -782,7 +782,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Divide(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Divide(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kDivide, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -792,7 +792,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Divide(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Divide(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Divide(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -803,7 +803,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename LHS, typename RHS>
- ir::Binary* Modulo(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Modulo(const core::type::Type* type, LHS&& lhs, RHS&& rhs) {
return Binary(BinaryOp::kModulo, type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -813,7 +813,7 @@
/// @param rhs the rhs of the add
/// @returns the operation
template <typename TYPE, typename LHS, typename RHS>
- ir::Binary* Modulo(LHS&& lhs, RHS&& rhs) {
+ ir::CoreBinary* Modulo(LHS&& lhs, RHS&& rhs) {
auto* type = ir.Types().Get<TYPE>();
return Modulo(type, std::forward<LHS>(lhs), std::forward<RHS>(rhs));
}
@@ -824,9 +824,9 @@
/// @param val the value of the operation
/// @returns the operation
template <typename VAL>
- ir::Unary* Unary(UnaryOp op, const core::type::Type* type, VAL&& val) {
+ ir::CoreUnary* Unary(UnaryOp op, const core::type::Type* type, VAL&& val) {
auto* value = Value(std::forward<VAL>(val));
- return Append(ir.instructions.Create<ir::Unary>(InstructionResult(type), op, value));
+ return Append(ir.instructions.Create<ir::CoreUnary>(InstructionResult(type), op, value));
}
/// Creates an op for `op val`
@@ -835,7 +835,7 @@
/// @param val the value of the operation
/// @returns the operation
template <typename TYPE, typename VAL>
- ir::Unary* Unary(UnaryOp op, VAL&& val) {
+ ir::CoreUnary* Unary(UnaryOp op, VAL&& val) {
auto* type = ir.Types().Get<TYPE>();
return Unary(op, type, std::forward<VAL>(val));
}
@@ -845,8 +845,8 @@
/// @param val the value
/// @returns the operation
template <typename VAL>
- ir::Unary* Complement(const core::type::Type* type, VAL&& val) {
- return Unary(ir::UnaryOp::kComplement, type, std::forward<VAL>(val));
+ ir::CoreUnary* Complement(const core::type::Type* type, VAL&& val) {
+ return Unary(UnaryOp::kComplement, type, std::forward<VAL>(val));
}
/// Creates a Complement operation
@@ -854,7 +854,7 @@
/// @param val the value
/// @returns the operation
template <typename TYPE, typename VAL>
- ir::Unary* Complement(VAL&& val) {
+ ir::CoreUnary* Complement(VAL&& val) {
auto* type = ir.Types().Get<TYPE>();
return Complement(type, std::forward<VAL>(val));
}
@@ -864,8 +864,8 @@
/// @param val the value
/// @returns the operation
template <typename VAL>
- ir::Unary* Negation(const core::type::Type* type, VAL&& val) {
- return Unary(ir::UnaryOp::kNegation, type, std::forward<VAL>(val));
+ ir::CoreUnary* Negation(const core::type::Type* type, VAL&& val) {
+ return Unary(UnaryOp::kNegation, type, std::forward<VAL>(val));
}
/// Creates a Negation operation
@@ -873,7 +873,7 @@
/// @param val the value
/// @returns the operation
template <typename TYPE, typename VAL>
- ir::Unary* Negation(VAL&& val) {
+ ir::CoreUnary* Negation(VAL&& val) {
auto* type = ir.Types().Get<TYPE>();
return Negation(type, std::forward<VAL>(val));
}
@@ -883,7 +883,7 @@
/// @param val the value
/// @returns the operation
template <typename VAL>
- ir::Binary* Not(const core::type::Type* type, VAL&& val) {
+ ir::CoreBinary* Not(const core::type::Type* type, VAL&& val) {
if (auto* vec = type->As<core::type::Vector>()) {
return Equal(type, std::forward<VAL>(val), Splat(vec, false, vec->Width()));
} else {
@@ -896,7 +896,7 @@
/// @param val the value
/// @returns the operation
template <typename TYPE, typename VAL>
- ir::Binary* Not(VAL&& val) {
+ ir::CoreBinary* Not(VAL&& val) {
auto* type = ir.Types().Get<TYPE>();
return Not(type, std::forward<VAL>(val));
}
@@ -1297,6 +1297,15 @@
return FunctionParam(name, type);
}
+ /// Creates a new `FunctionParam`
+ /// @tparam TYPE the parameter type
+ /// @returns the value
+ template <typename TYPE>
+ ir::FunctionParam* FunctionParam() {
+ auto* type = ir.Types().Get<TYPE>();
+ return FunctionParam(type);
+ }
+
/// Creates a new `Access`
/// @param type the return type
/// @param object the object being accessed
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/core/ir/core_binary.cc
similarity index 62%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/core/ir/core_binary.cc
index 421db7b..0bab152 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/core/ir/core_binary.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,32 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+#include "src/tint/lang/core/ir/core_binary.h"
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/lang/core/intrinsic/dialect.h"
+#include "src/tint/lang/core/ir/clone_context.h"
+#include "src/tint/lang/core/ir/module.h"
-namespace tint::spirv::writer {
-namespace {
+TINT_INSTANTIATE_TYPEINFO(tint::core::ir::CoreBinary);
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
- return;
- }
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
- }
+namespace tint::core::ir {
+
+CoreBinary::CoreBinary() = default;
+
+CoreBinary::CoreBinary(InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs)
+ : Base(result, op, lhs, rhs) {}
+
+CoreBinary::~CoreBinary() = default;
+
+CoreBinary* CoreBinary::Clone(CloneContext& ctx) {
+ auto* new_result = ctx.Clone(Result(0));
+ auto* lhs = ctx.Remap(LHS());
+ auto* rhs = ctx.Remap(RHS());
+ return ctx.ir.instructions.Create<CoreBinary>(new_result, Op(), lhs, rhs);
}
-} // namespace
-} // namespace tint::spirv::writer
+const core::intrinsic::TableData& CoreBinary::TableData() const {
+ return core::intrinsic::Dialect::kData;
+}
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/core_binary.h b/src/tint/lang/core/ir/core_binary.h
new file mode 100644
index 0000000..7329ce6
--- /dev/null
+++ b/src/tint/lang/core/ir/core_binary.h
@@ -0,0 +1,61 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_CORE_IR_CORE_BINARY_H_
+#define SRC_TINT_LANG_CORE_IR_CORE_BINARY_H_
+
+#include "src/tint/lang/core/ir/binary.h"
+
+namespace tint::core::ir {
+
+/// A core-dialect binary-op instruction in the IR.
+class CoreBinary final : public Castable<CoreBinary, Binary> {
+ public:
+ /// The offset in Operands() for the value
+ static constexpr size_t kValueOperandOffset = 0;
+
+ /// Constructor (no results, no operands)
+ CoreBinary();
+
+ /// Constructor
+ /// @param result the result value
+ /// @param op the Binary operator
+ /// @param lhs the lhs of the instruction
+ /// @param rhs the rhs of the instruction
+ CoreBinary(InstructionResult* result, BinaryOp op, Value* lhs, Value* rhs);
+ ~CoreBinary() override;
+
+ /// @copydoc Instruction::Clone()
+ CoreBinary* Clone(CloneContext& ctx) override;
+
+ /// @returns the table data to validate this builtin
+ const core::intrinsic::TableData& TableData() const override;
+};
+
+} // namespace tint::core::ir
+
+#endif // SRC_TINT_LANG_CORE_IR_CORE_BINARY_H_
diff --git a/src/tint/lang/core/ir/binary_test.cc b/src/tint/lang/core/ir/core_binary_test.cc
similarity index 100%
rename from src/tint/lang/core/ir/binary_test.cc
rename to src/tint/lang/core/ir/core_binary_test.cc
diff --git a/src/tint/lang/core/ir/core_builtin_call.cc b/src/tint/lang/core/ir/core_builtin_call.cc
index bb876cf..b8114ba 100644
--- a/src/tint/lang/core/ir/core_builtin_call.cc
+++ b/src/tint/lang/core/ir/core_builtin_call.cc
@@ -44,7 +44,6 @@
VectorRef<Value*> arguments)
: Base(result, arguments), func_(func) {
TINT_ASSERT(func != core::BuiltinFn::kNone);
- TINT_ASSERT(func != core::BuiltinFn::kTintMaterialize);
}
CoreBuiltinCall::~CoreBuiltinCall() = default;
diff --git a/src/tint/lang/core/ir/core_builtin_call_test.cc b/src/tint/lang/core/ir/core_builtin_call_test.cc
index 05965f8..29c5913 100644
--- a/src/tint/lang/core/ir/core_builtin_call_test.cc
+++ b/src/tint/lang/core/ir/core_builtin_call_test.cc
@@ -75,16 +75,6 @@
"");
}
-TEST_F(IR_CoreBuiltinCallTest, Fail_TintMaterializeFunction) {
- EXPECT_FATAL_FAILURE(
- {
- Module mod;
- Builder b{mod};
- b.Call(mod.Types().f32(), core::BuiltinFn::kTintMaterialize);
- },
- "");
-}
-
TEST_F(IR_CoreBuiltinCallTest, Clone) {
auto* builtin = b.Call(mod.Types().f32(), core::BuiltinFn::kAbs, 1_u, 2_u);
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/core/ir/core_unary.cc
similarity index 62%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/core/ir/core_unary.cc
index 421db7b..5ab130d 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/core/ir/core_unary.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,30 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+#include "src/tint/lang/core/ir/core_unary.h"
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/lang/core/intrinsic/dialect.h"
+#include "src/tint/lang/core/ir/clone_context.h"
+#include "src/tint/lang/core/ir/module.h"
-namespace tint::spirv::writer {
-namespace {
+TINT_INSTANTIATE_TYPEINFO(tint::core::ir::CoreUnary);
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
- return;
- }
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
- }
+namespace tint::core::ir {
+
+CoreUnary::CoreUnary() = default;
+
+CoreUnary::CoreUnary(InstructionResult* result, UnaryOp op, Value* val) : Base(result, op, val) {}
+
+CoreUnary::~CoreUnary() = default;
+
+CoreUnary* CoreUnary::Clone(CloneContext& ctx) {
+ auto* new_result = ctx.Clone(Result(0));
+ auto* val = ctx.Remap(Val());
+ return ctx.ir.instructions.Create<CoreUnary>(new_result, Op(), val);
}
-} // namespace
-} // namespace tint::spirv::writer
+const core::intrinsic::TableData& CoreUnary::TableData() const {
+ return core::intrinsic::Dialect::kData;
+}
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/core_unary.h b/src/tint/lang/core/ir/core_unary.h
new file mode 100644
index 0000000..04a02f4
--- /dev/null
+++ b/src/tint/lang/core/ir/core_unary.h
@@ -0,0 +1,60 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_CORE_IR_CORE_UNARY_H_
+#define SRC_TINT_LANG_CORE_IR_CORE_UNARY_H_
+
+#include "src/tint/lang/core/ir/unary.h"
+
+namespace tint::core::ir {
+
+/// A core-dialect unary instruction in the IR.
+class CoreUnary final : public Castable<CoreUnary, Unary> {
+ public:
+ /// The offset in Operands() for the value
+ static constexpr size_t kValueOperandOffset = 0;
+
+ /// Constructor (no results, no operands)
+ CoreUnary();
+
+ /// Constructor
+ /// @param result the result value
+ /// @param op the unary operator
+ /// @param val the input value for the instruction
+ CoreUnary(InstructionResult* result, UnaryOp op, Value* val);
+ ~CoreUnary() override;
+
+ /// @copydoc Instruction::Clone()
+ CoreUnary* Clone(CloneContext& ctx) override;
+
+ /// @returns the table data to validate this builtin
+ const core::intrinsic::TableData& TableData() const override;
+};
+
+} // namespace tint::core::ir
+
+#endif // SRC_TINT_LANG_CORE_IR_CORE_UNARY_H_
diff --git a/src/tint/lang/core/ir/unary_test.cc b/src/tint/lang/core/ir/core_unary_test.cc
similarity index 100%
rename from src/tint/lang/core/ir/unary_test.cc
rename to src/tint/lang/core/ir/core_unary_test.cc
diff --git a/src/tint/lang/core/ir/disassembler.cc b/src/tint/lang/core/ir/disassembler.cc
index 9292f50..cfa2e30 100644
--- a/src/tint/lang/core/ir/disassembler.cc
+++ b/src/tint/lang/core/ir/disassembler.cc
@@ -852,6 +852,12 @@
case BinaryOp::kShiftRight:
out_ << "shr";
break;
+ case BinaryOp::kLogicalAnd:
+ out_ << "logical-and";
+ break;
+ case BinaryOp::kLogicalOr:
+ out_ << "logical-or";
+ break;
}
out_ << " ";
EmitOperandList(b);
@@ -870,6 +876,15 @@
case UnaryOp::kNegation:
out_ << "negation";
break;
+ case UnaryOp::kAddressOf:
+ out_ << "ref-to-ptr";
+ break;
+ case UnaryOp::kIndirection:
+ out_ << "ptr-to-ref";
+ break;
+ case UnaryOp::kNot:
+ out_ << "not";
+ break;
}
out_ << " ";
EmitOperandList(u);
diff --git a/src/tint/lang/core/ir/transform/BUILD.bazel b/src/tint/lang/core/ir/transform/BUILD.bazel
index b75b761..467e451 100644
--- a/src/tint/lang/core/ir/transform/BUILD.bazel
+++ b/src/tint/lang/core/ir/transform/BUILD.bazel
@@ -151,6 +151,7 @@
"//src/tint/lang/wgsl/program",
"//src/tint/lang/wgsl/sem",
"//src/tint/lang/wgsl/writer/ir_to_program",
+ "//src/tint/lang/wgsl/writer/raise",
"//src/tint/utils/containers",
"//src/tint/utils/diagnostic",
"//src/tint/utils/ice",
diff --git a/src/tint/lang/core/ir/transform/BUILD.cmake b/src/tint/lang/core/ir/transform/BUILD.cmake
index 76a01e3..01120f4 100644
--- a/src/tint/lang/core/ir/transform/BUILD.cmake
+++ b/src/tint/lang/core/ir/transform/BUILD.cmake
@@ -141,6 +141,7 @@
tint_lang_wgsl_program
tint_lang_wgsl_sem
tint_lang_wgsl_writer_ir_to_program
+ tint_lang_wgsl_writer_raise
tint_utils_containers
tint_utils_diagnostic
tint_utils_ice
diff --git a/src/tint/lang/core/ir/transform/BUILD.gn b/src/tint/lang/core/ir/transform/BUILD.gn
index fbb325a..56910e6 100644
--- a/src/tint/lang/core/ir/transform/BUILD.gn
+++ b/src/tint/lang/core/ir/transform/BUILD.gn
@@ -143,6 +143,7 @@
"${tint_src_dir}/lang/wgsl/program",
"${tint_src_dir}/lang/wgsl/sem",
"${tint_src_dir}/lang/wgsl/writer/ir_to_program",
+ "${tint_src_dir}/lang/wgsl/writer/raise",
"${tint_src_dir}/utils/containers",
"${tint_src_dir}/utils/diagnostic",
"${tint_src_dir}/utils/ice",
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill.cc b/src/tint/lang/core/ir/transform/binary_polyfill.cc
index 14c6756..83fb233 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/binary_polyfill.cc
@@ -66,12 +66,12 @@
/// Process the module.
void Process() {
// Find the binary instructions that need to be polyfilled.
- Vector<ir::Binary*, 64> worklist;
+ Vector<ir::CoreBinary*, 64> worklist;
for (auto* inst : ir.instructions.Objects()) {
if (!inst->Alive()) {
continue;
}
- if (auto* binary = inst->As<ir::Binary>()) {
+ if (auto* binary = inst->As<ir::CoreBinary>()) {
switch (binary->Op()) {
case BinaryOp::kDivide:
case BinaryOp::kModulo:
@@ -149,7 +149,7 @@
/// divide-by-zero and signed integer overflow.
/// @param binary the binary instruction
/// @returns the replacement value
- ir::Value* IntDivMod(ir::Binary* binary) {
+ ir::Value* IntDivMod(ir::CoreBinary* binary) {
auto* result_ty = binary->Result(0)->Type();
bool is_div = binary->Op() == BinaryOp::kDivide;
bool is_signed = result_ty->is_signed_integer_scalar_or_vector();
@@ -232,13 +232,13 @@
/// Mask the RHS of a shift instruction to ensure it is modulo the bitwidth of the LHS.
/// @param binary the binary instruction
/// @returns the replacement value
- ir::Value* MaskShiftAmount(ir::Binary* binary) {
+ ir::Value* MaskShiftAmount(ir::CoreBinary* binary) {
auto* lhs = binary->LHS();
auto* rhs = binary->RHS();
auto* mask = b.Constant(u32(lhs->Type()->DeepestElement()->Size() * 8 - 1));
auto* masked = b.And(rhs->Type(), rhs, MatchWidth(mask, rhs->Type()));
masked->InsertBefore(binary);
- binary->SetOperand(ir::Binary::kRhsOperandOffset, masked->Result(0));
+ binary->SetOperand(ir::CoreBinary::kRhsOperandOffset, masked->Result(0));
return binary->Result(0);
}
};
diff --git a/src/tint/lang/core/ir/transform/binary_polyfill_test.cc b/src/tint/lang/core/ir/transform/binary_polyfill_test.cc
index b582411..314ac0c 100644
--- a/src/tint/lang/core/ir/transform/binary_polyfill_test.cc
+++ b/src/tint/lang/core/ir/transform/binary_polyfill_test.cc
@@ -671,9 +671,9 @@
}
TEST_F(IR_BinaryPolyfillTest, Divide_Scalar_Vector) {
- Build(BinaryOp::kDivide, ty.vec4<i32>(), ty.i32(), ty.vec2<i32>());
+ Build(BinaryOp::kDivide, ty.vec4<i32>(), ty.i32(), ty.vec4<i32>());
auto* src = R"(
-%foo = func(%lhs:i32, %rhs:vec2<i32>):vec4<i32> -> %b1 {
+%foo = func(%lhs:i32, %rhs:vec4<i32>):vec4<i32> -> %b1 {
%b1 = block {
%result:vec4<i32> = div %lhs, %rhs
ret %result
@@ -681,7 +681,7 @@
}
)";
auto* expect = R"(
-%foo = func(%lhs:i32, %rhs:vec2<i32>):vec4<i32> -> %b1 {
+%foo = func(%lhs:i32, %rhs:vec4<i32>):vec4<i32> -> %b1 {
%b1 = block {
%4:vec4<i32> = construct %lhs
%result:vec4<i32> = call %tint_div_v4i32, %4, %rhs
@@ -711,9 +711,9 @@
}
TEST_F(IR_BinaryPolyfillTest, Divide_Vector_Scalar) {
- Build(BinaryOp::kDivide, ty.vec4<i32>(), ty.vec2<i32>(), ty.i32());
+ Build(BinaryOp::kDivide, ty.vec4<i32>(), ty.vec4<i32>(), ty.i32());
auto* src = R"(
-%foo = func(%lhs:vec2<i32>, %rhs:i32):vec4<i32> -> %b1 {
+%foo = func(%lhs:vec4<i32>, %rhs:i32):vec4<i32> -> %b1 {
%b1 = block {
%result:vec4<i32> = div %lhs, %rhs
ret %result
@@ -721,7 +721,7 @@
}
)";
auto* expect = R"(
-%foo = func(%lhs:vec2<i32>, %rhs:i32):vec4<i32> -> %b1 {
+%foo = func(%lhs:vec4<i32>, %rhs:i32):vec4<i32> -> %b1 {
%b1 = block {
%4:vec4<i32> = construct %rhs
%result:vec4<i32> = call %tint_div_v4i32, %lhs, %4
@@ -751,9 +751,9 @@
}
TEST_F(IR_BinaryPolyfillTest, Modulo_Scalar_Vector) {
- Build(BinaryOp::kModulo, ty.vec4<i32>(), ty.i32(), ty.vec2<i32>());
+ Build(BinaryOp::kModulo, ty.vec4<i32>(), ty.i32(), ty.vec4<i32>());
auto* src = R"(
-%foo = func(%lhs:i32, %rhs:vec2<i32>):vec4<i32> -> %b1 {
+%foo = func(%lhs:i32, %rhs:vec4<i32>):vec4<i32> -> %b1 {
%b1 = block {
%result:vec4<i32> = mod %lhs, %rhs
ret %result
@@ -761,7 +761,7 @@
}
)";
auto* expect = R"(
-%foo = func(%lhs:i32, %rhs:vec2<i32>):vec4<i32> -> %b1 {
+%foo = func(%lhs:i32, %rhs:vec4<i32>):vec4<i32> -> %b1 {
%b1 = block {
%4:vec4<i32> = construct %lhs
%result:vec4<i32> = call %tint_mod_v4i32, %4, %rhs
@@ -793,9 +793,9 @@
}
TEST_F(IR_BinaryPolyfillTest, Modulo_Vector_Scalar) {
- Build(BinaryOp::kModulo, ty.vec4<i32>(), ty.vec2<i32>(), ty.i32());
+ Build(BinaryOp::kModulo, ty.vec4<i32>(), ty.vec4<i32>(), ty.i32());
auto* src = R"(
-%foo = func(%lhs:vec2<i32>, %rhs:i32):vec4<i32> -> %b1 {
+%foo = func(%lhs:vec4<i32>, %rhs:i32):vec4<i32> -> %b1 {
%b1 = block {
%result:vec4<i32> = mod %lhs, %rhs
ret %result
@@ -803,7 +803,7 @@
}
)";
auto* expect = R"(
-%foo = func(%lhs:vec2<i32>, %rhs:i32):vec4<i32> -> %b1 {
+%foo = func(%lhs:vec4<i32>, %rhs:i32):vec4<i32> -> %b1 {
%b1 = block {
%4:vec4<i32> = construct %rhs
%result:vec4<i32> = call %tint_mod_v4i32, %lhs, %4
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill.cc b/src/tint/lang/core/ir/transform/builtin_polyfill.cc
index f321fe1..4ff5cbf 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill.cc
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill.cc
@@ -119,6 +119,13 @@
}
}
break;
+ case core::BuiltinFn::kDot4U8Packed:
+ case core::BuiltinFn::kDot4I8Packed: {
+ if (config.dot_4x8_packed) {
+ worklist.Push(builtin);
+ }
+ break;
+ }
case core::BuiltinFn::kPack4XI8:
case core::BuiltinFn::kPack4XU8:
case core::BuiltinFn::kPack4XI8Clamp:
@@ -167,6 +174,12 @@
case core::BuiltinFn::kTextureSampleBaseClampToEdge:
replacement = TextureSampleBaseClampToEdge_2d_f32(builtin);
break;
+ case core::BuiltinFn::kDot4I8Packed:
+ replacement = Dot4I8Packed(builtin);
+ break;
+ case core::BuiltinFn::kDot4U8Packed:
+ replacement = Dot4U8Packed(builtin);
+ break;
case core::BuiltinFn::kPack4XI8:
replacement = Pack4xI8(builtin);
break;
@@ -601,6 +614,44 @@
return result;
}
+ /// Polyfill a `dot4I8Packed()` builtin call
+ /// @param call the builtin call instruction
+ /// @returns the replacement value
+ ir::Value* Dot4I8Packed(ir::CoreBuiltinCall* call) {
+ // Replace `dot4I8Packed(%x,%y)` with:
+ // %unpacked_x = unpack4xI8(%x);
+ // %unpacked_y = unpack4xI8(%y);
+ // %result = dot(%unpacked_x, %unpacked_y);
+ auto* x = call->Args()[0];
+ auto* y = call->Args()[1];
+ auto* unpacked_x = Unpack4xI8OnValue(call, x);
+ auto* unpacked_y = Unpack4xI8OnValue(call, y);
+ ir::Value* result = nullptr;
+ b.InsertBefore(call, [&] {
+ result = b.Call(ty.i32(), core::BuiltinFn::kDot, unpacked_x, unpacked_y)->Result(0);
+ });
+ return result;
+ }
+
+ /// Polyfill a `dot4U8Packed()` builtin call
+ /// @param call the builtin call instruction
+ /// @returns the replacement value
+ ir::Value* Dot4U8Packed(ir::CoreBuiltinCall* call) {
+ // Replace `dot4U8Packed(%x,%y)` with:
+ // %unpacked_x = unpack4xU8(%x);
+ // %unpacked_y = unpack4xU8(%y);
+ // %result = dot(%unpacked_x, %unpacked_y);
+ auto* x = call->Args()[0];
+ auto* y = call->Args()[1];
+ auto* unpacked_x = Unpack4xU8OnValue(call, x);
+ auto* unpacked_y = Unpack4xU8OnValue(call, y);
+ ir::Value* result = nullptr;
+ b.InsertBefore(call, [&] {
+ result = b.Call(ty.u32(), core::BuiltinFn::kDot, unpacked_x, unpacked_y)->Result(0);
+ });
+ return result;
+ }
+
/// Polyfill a `pack4xI8()` builtin call
/// @param call the builtin call instruction
/// @returns the replacement value
@@ -713,50 +764,64 @@
return result;
}
- /// Polyfill a `unpack4xI8()` builtin call
- /// @param call the builtin call instruction
- /// @returns the replacement value
- ir::Value* Unpack4xI8(ir::CoreBuiltinCall* call) {
+ /// Emit code for `unpack4xI8` on u32 value `x`, before the given call.
+ /// @param call the instruction that should follow the emitted code
+ /// @param x the u32 value to be unpacked
+ ir::Value* Unpack4xI8OnValue(ir::CoreBuiltinCall* call, ir::Value* x) {
// Replace `unpack4xI8(%x)` with:
// %n = vec4u(24, 16, 8, 0);
- // %x_vec4u = vec4u(x);
- // %x_vec4i = bitcast<vec4i>(%x_vec4u << n);
+ // %x_splat = vec4u(%x); // splat the scalar to a vector
+ // %x_vec4i = bitcast<vec4i>(%x_splat << n);
// %result = %x_vec4i >> vec4u(24);
ir::Value* result = nullptr;
- auto* x = call->Args()[0];
b.InsertBefore(call, [&] {
auto* vec4i = ty.vec4<i32>();
auto* vec4u = ty.vec4<u32>();
auto* n = b.Construct(vec4u, b.Constant(u32(24)), b.Constant(u32(16)),
b.Constant(u32(8)), b.Constant(u32(0)));
- auto* x_vec4u = b.Convert(vec4u, x);
- auto* x_vec4i = b.Bitcast(vec4i, b.ShiftLeft(vec4u, x_vec4u, n));
+ auto* x_splat = b.Construct(vec4u, x);
+ auto* x_vec4i = b.Bitcast(vec4i, b.ShiftLeft(vec4u, x_splat, n));
result =
b.ShiftRight(vec4i, x_vec4i, b.Construct(vec4u, b.Constant(u32(24))))->Result(0);
});
return result;
}
+ /// Polyfill a `unpack4xI8()` builtin call
+ /// @param call the builtin call instruction
+ /// @returns the replacement value
+ ir::Value* Unpack4xI8(ir::CoreBuiltinCall* call) {
+ return Unpack4xI8OnValue(call, call->Args()[0]);
+ }
+
+ /// Emit code for `unpack4xU8` on u32 value `x`, before the given call.
+ /// @param call the instruction that should follow the emitted code
+ /// @param x the u32 value to be unpacked
+ ir::Value* Unpack4xU8OnValue(ir::CoreBuiltinCall* call, ir::Value* x) {
+ // Replace `unpack4xU8(%x)` with:
+ // %n = vec4u(0, 8, 16, 24);
+ // %x_splat = vec4u(%x); // splat the scalar to a vector
+ // %x_vec4u = %x_splat >> n;
+ // %result = %x_vec4u & vec4u(0xff);
+ ir::Value* result = nullptr;
+ b.InsertBefore(call, [&] {
+ auto* vec4u = ty.vec4<u32>();
+
+ auto* n = b.Construct(vec4u, b.Constant(u32(0)), b.Constant(u32(8)),
+ b.Constant(u32(16)), b.Constant(u32(24)));
+ auto* x_splat = b.Construct(vec4u, x);
+ auto* x_vec4u = b.ShiftRight(vec4u, x_splat, n);
+ result = b.And(vec4u, x_vec4u, b.Construct(vec4u, b.Constant(u32(0xff))))->Result(0);
+ });
+ return result;
+ }
+
/// Polyfill a `unpack4xU8()` builtin call
/// @param call the builtin call instruction
/// @returns the replacement value
ir::Value* Unpack4xU8(ir::CoreBuiltinCall* call) {
- // Replace `unpack4xU8(%x)` with:
- // %n = vec4u(0, 8, 16, 24);
- // %x_vec4u = vec4u(x) >> n;
- // %result = %x_vec4u & vec4u(0xff);
- ir::Value* result = nullptr;
- auto* x = call->Args()[0];
- b.InsertBefore(call, [&] {
- auto* vec4u = ty.vec4<u32>();
-
- auto* n = b.Construct(vec4u, b.Constant(u32(0)), b.Constant(u32(8)),
- b.Constant(u32(16)), b.Constant(u32(24)));
- auto* x_vec4u = b.ShiftRight(vec4u, b.Convert(vec4u, x), n);
- result = b.And(vec4u, x_vec4u, b.Construct(vec4u, b.Constant(u32(0xff))))->Result(0);
- });
- return result;
+ return Unpack4xU8OnValue(call, call->Args()[0]);
}
};
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill.h b/src/tint/lang/core/ir/transform/builtin_polyfill.h
index 2f90486..cb3c054 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill.h
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill.h
@@ -69,6 +69,8 @@
bool saturate = false;
/// Should `textureSampleBaseClampToEdge()` be polyfilled for texture_2d<f32> textures?
bool texture_sample_base_clamp_to_edge_2d_f32 = false;
+ /// Should `dot4U8Packed()` and `dot4I8Packed()` be polyfilled?
+ bool dot_4x8_packed = false;
/// Should `pack4xI8()` and `pack4xU8()` be polyfilled?
bool pack_unpack_4x8 = false;
};
diff --git a/src/tint/lang/core/ir/transform/builtin_polyfill_test.cc b/src/tint/lang/core/ir/transform/builtin_polyfill_test.cc
index 37a3fdf..9dfaee0 100644
--- a/src/tint/lang/core/ir/transform/builtin_polyfill_test.cc
+++ b/src/tint/lang/core/ir/transform/builtin_polyfill_test.cc
@@ -1572,7 +1572,7 @@
%foo = func(%arg:u32):vec4<i32> -> %b1 {
%b1 = block {
%3:vec4<u32> = construct 24u, 16u, 8u, 0u
- %4:vec4<u32> = convert %arg
+ %4:vec4<u32> = construct %arg
%5:vec4<u32> = shl %4, %3
%6:vec4<i32> = bitcast %5
%7:vec4<u32> = construct 24u
@@ -1606,7 +1606,7 @@
%foo = func(%arg:u32):vec4<u32> -> %b1 {
%b1 = block {
%3:vec4<u32> = construct 0u, 8u, 16u, 24u
- %4:vec4<u32> = convert %arg
+ %4:vec4<u32> = construct %arg
%5:vec4<u32> = shr %4, %3
%6:vec4<u32> = construct 255u
%result:vec4<u32> = and %5, %6
@@ -1622,5 +1622,85 @@
EXPECT_EQ(expect, str());
}
+TEST_F(IR_BuiltinPolyfillTest, Dot4I8Packed) {
+ Build(core::BuiltinFn::kDot4I8Packed, ty.i32(), Vector{ty.u32(), ty.u32()});
+
+ auto* src = R"(
+%foo = func(%arg:u32, %arg_1:u32):i32 -> %b1 { # %arg_1: 'arg'
+ %b1 = block {
+ %result:i32 = dot4I8Packed %arg, %arg_1
+ ret %result
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = func(%arg:u32, %arg_1:u32):i32 -> %b1 { # %arg_1: 'arg'
+ %b1 = block {
+ %4:vec4<u32> = construct 24u, 16u, 8u, 0u
+ %5:vec4<u32> = construct %arg
+ %6:vec4<u32> = shl %5, %4
+ %7:vec4<i32> = bitcast %6
+ %8:vec4<u32> = construct 24u
+ %9:vec4<i32> = shr %7, %8
+ %10:vec4<u32> = construct 24u, 16u, 8u, 0u
+ %11:vec4<u32> = construct %arg_1
+ %12:vec4<u32> = shl %11, %10
+ %13:vec4<i32> = bitcast %12
+ %14:vec4<u32> = construct 24u
+ %15:vec4<i32> = shr %13, %14
+ %result:i32 = dot %9, %15
+ ret %result
+ }
+}
+)";
+
+ BuiltinPolyfillConfig config;
+ config.dot_4x8_packed = true;
+ Run(BuiltinPolyfill, config);
+
+ EXPECT_EQ(expect, str());
+}
+
+TEST_F(IR_BuiltinPolyfillTest, Dot4U8Packed) {
+ Build(core::BuiltinFn::kDot4U8Packed, ty.u32(), Vector{ty.u32(), ty.u32()});
+
+ auto* src = R"(
+%foo = func(%arg:u32, %arg_1:u32):u32 -> %b1 { # %arg_1: 'arg'
+ %b1 = block {
+ %result:u32 = dot4U8Packed %arg, %arg_1
+ ret %result
+ }
+}
+)";
+ EXPECT_EQ(src, str());
+
+ auto* expect = R"(
+%foo = func(%arg:u32, %arg_1:u32):u32 -> %b1 { # %arg_1: 'arg'
+ %b1 = block {
+ %4:vec4<u32> = construct 0u, 8u, 16u, 24u
+ %5:vec4<u32> = construct %arg
+ %6:vec4<u32> = shr %5, %4
+ %7:vec4<u32> = construct 255u
+ %8:vec4<u32> = and %6, %7
+ %9:vec4<u32> = construct 0u, 8u, 16u, 24u
+ %10:vec4<u32> = construct %arg_1
+ %11:vec4<u32> = shr %10, %9
+ %12:vec4<u32> = construct 255u
+ %13:vec4<u32> = and %11, %12
+ %result:u32 = dot %8, %13
+ ret %result
+ }
+}
+)";
+
+ BuiltinPolyfillConfig config;
+ config.dot_4x8_packed = true;
+ Run(BuiltinPolyfill, config);
+
+ EXPECT_EQ(expect, str());
+}
+
} // namespace
} // namespace tint::core::ir::transform
diff --git a/src/tint/lang/core/ir/transform/direct_variable_access_wgsl_test.cc b/src/tint/lang/core/ir/transform/direct_variable_access_wgsl_test.cc
index 9f39916..49780b7 100644
--- a/src/tint/lang/core/ir/transform/direct_variable_access_wgsl_test.cc
+++ b/src/tint/lang/core/ir/transform/direct_variable_access_wgsl_test.cc
@@ -36,6 +36,7 @@
#include "src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h"
#include "src/tint/lang/wgsl/reader/reader.h"
#include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.h"
+#include "src/tint/lang/wgsl/writer/raise/raise.h"
#include "src/tint/lang/wgsl/writer/writer.h"
namespace tint::core::ir::transform {
@@ -62,12 +63,12 @@
wgsl::reader::Options parser_options;
parser_options.allowed_features = wgsl::AllowedFeatures::Everything();
Source::File file{"test", in};
- auto program = wgsl::reader::Parse(&file, parser_options);
- if (!program.IsValid()) {
- return "wgsl::reader::Parse() failed: \n" + program.Diagnostics().str();
+ auto program_in = wgsl::reader::Parse(&file, parser_options);
+ if (!program_in.IsValid()) {
+ return "wgsl::reader::Parse() failed: \n" + program_in.Diagnostics().str();
}
- auto module = wgsl::reader::ProgramToIR(program);
+ auto module = wgsl::reader::ProgramToIR(program_in);
if (module != Success) {
return "ProgramToIR() failed:\n" + module.Failure().reason.str();
}
@@ -77,19 +78,27 @@
return "DirectVariableAccess failed:\n" + res.Failure().reason.str();
}
+ auto pre_raise = ir::Disassemble(module.Get());
+
+ if (auto raise = wgsl::writer::Raise(module.Get()); raise != Success) {
+ return "wgsl::writer::Raise failed:\n" + res.Failure().reason.str();
+ }
+
wgsl::writer::ProgramOptions program_options;
program_options.allowed_features.extensions.insert(
wgsl::Extension::kChromiumExperimentalFullPtrParameters);
- auto transformed = wgsl::writer::IRToProgram(module.Get(), program_options);
- if (!transformed.IsValid()) {
- return "wgsl::writer::IRToProgram() failed: \n" + transformed.Diagnostics().str() +
- "\n\nIR:\n" + ir::Disassemble(module.Get()) + //
- "\n\nAST:\n" + Program::printer(transformed);
+ auto program_out = wgsl::writer::IRToProgram(module.Get(), program_options);
+ if (!program_out.IsValid()) {
+ return "wgsl::writer::IRToProgram() failed: \n" + program_out.Diagnostics().str() +
+ "\n\nIR (pre):\n" + pre_raise + //
+ "\n\nIR (post):\n" + ir::Disassemble(module.Get()) + //
+ "\n\nAST:\n" + Program::printer(program_out);
}
- auto output = wgsl::writer::Generate(transformed, wgsl::writer::Options{});
+ auto output = wgsl::writer::Generate(program_out, wgsl::writer::Options{});
if (output != Success) {
- return "wgsl::writer::Generate() failed: \n" + output.Failure().reason.str();
+ return "wgsl::writer::IRToProgram() failed: \n" + output.Failure().reason.str() +
+ "\n\nIR:\n" + ir::Disassemble(module.Get());
}
return "\n" + output->wgsl;
diff --git a/src/tint/lang/core/ir/unary.cc b/src/tint/lang/core/ir/unary.cc
index d4de4e1..9fdfe0f 100644
--- a/src/tint/lang/core/ir/unary.cc
+++ b/src/tint/lang/core/ir/unary.cc
@@ -43,19 +43,4 @@
Unary::~Unary() = default;
-Unary* Unary::Clone(CloneContext& ctx) {
- auto* new_result = ctx.Clone(Result(0));
- auto* val = ctx.Remap(Val());
- return ctx.ir.instructions.Create<Unary>(new_result, op_, val);
-}
-
-std::string_view ToString(enum UnaryOp op) {
- switch (op) {
- case UnaryOp::kComplement:
- return "complement";
- case UnaryOp::kNegation:
- return "negation";
- }
- return "<unknown>";
-}
} // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/unary.h b/src/tint/lang/core/ir/unary.h
index 41a4875..8ade151 100644
--- a/src/tint/lang/core/ir/unary.h
+++ b/src/tint/lang/core/ir/unary.h
@@ -31,18 +31,17 @@
#include <string>
#include "src/tint/lang/core/ir/operand_instruction.h"
-#include "src/tint/utils/rtti/castable.h"
+#include "src/tint/lang/core/unary_op.h"
+
+// Forward declarations
+namespace tint::core::intrinsic {
+struct TableData;
+}
namespace tint::core::ir {
-/// A unary operator.
-enum class UnaryOp {
- kComplement,
- kNegation,
-};
-
-/// A unary instruction in the IR.
-class Unary final : public Castable<Unary, OperandInstruction<1, 1>> {
+/// The abstract base class for dialect-specific unary-op instructions in the IR.
+class Unary : public Castable<Unary, OperandInstruction<1, 1>> {
public:
/// The offset in Operands() for the value
static constexpr size_t kValueOperandOffset = 0;
@@ -57,9 +56,6 @@
Unary(InstructionResult* result, UnaryOp op, Value* val);
~Unary() override;
- /// @copydoc Instruction::Clone()
- Unary* Clone(CloneContext& ctx) override;
-
/// @returns the value for the instruction
Value* Val() { return operands_[kValueOperandOffset]; }
@@ -75,20 +71,13 @@
/// @returns the friendly name for the instruction
std::string FriendlyName() const override { return "unary"; }
+ /// @returns the table data to validate this builtin
+ virtual const core::intrinsic::TableData& TableData() const = 0;
+
private:
UnaryOp op_ = UnaryOp::kComplement;
};
-/// @param kind the enum value
-/// @returns the string for the given enum value
-std::string_view ToString(UnaryOp kind);
-
-/// Emits the name of the intrinsic type.
-template <typename STREAM, typename = traits::EnableIfIsOStream<STREAM>>
-auto& operator<<(STREAM& out, UnaryOp kind) {
- return out << ToString(kind);
-}
-
} // namespace tint::core::ir
#endif // SRC_TINT_LANG_CORE_IR_UNARY_H_
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index dd7925a..b6e96e5 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -594,6 +594,24 @@
AddError(call, UserCall::kFunctionOperandOffset,
InstError(call, "call target is not part of the module"));
}
+ auto args = call->Args();
+ auto params = call->Target()->Params();
+ if (args.Length() != params.Length()) {
+ StringStream err;
+ err << "function has " << params.Length() << " parameters, but call provides "
+ << args.Length() << " arguments";
+ AddError(call, UserCall::kFunctionOperandOffset, InstError(call, err.str()));
+ return;
+ }
+
+ for (size_t i = 0; i < args.Length(); i++) {
+ if (args[i]->Type() != params[i]->Type()) {
+ StringStream err;
+ err << "function parameter " << i << " is of type " << params[i]->Type()->FriendlyName()
+ << ", but argument is of type " << args[i]->Type()->FriendlyName();
+ AddError(call, UserCall::kArgsOperandOffset + i, InstError(call, err.str()));
+ }
+ }
}
void Validator::CheckAccess(const Access* a) {
@@ -667,14 +685,61 @@
void Validator::CheckBinary(const Binary* b) {
CheckOperandsNotNull(b, Binary::kLhsOperandOffset, Binary::kRhsOperandOffset);
+ if (b->LHS() && b->RHS()) {
+ auto symbols = SymbolTable::Wrap(mod_.symbols);
+ auto type_mgr = type::Manager::Wrap(mod_.Types());
+ intrinsic::Context context{
+ b->TableData(),
+ type_mgr,
+ symbols,
+ };
+
+ auto overload =
+ core::intrinsic::LookupBinary(context, b->Op(), b->LHS()->Type(), b->RHS()->Type(),
+ core::EvaluationStage::kRuntime, /* is_compound */ false);
+ if (overload != Success) {
+ AddError(b, InstError(b, overload.Failure()));
+ return;
+ }
+
+ if (auto* result = b->Result(0)) {
+ if (overload->return_type != result->Type()) {
+ StringStream err;
+ err << "binary instruction result type (" << result->Type()->FriendlyName()
+ << ") does not match overload result type ("
+ << overload->return_type->FriendlyName() << ")";
+ AddError(b, InstError(b, err.str()));
+ }
+ }
+ }
}
void Validator::CheckUnary(const Unary* u) {
CheckOperandNotNull(u, u->Val(), Unary::kValueOperandOffset);
+ if (u->Val()) {
+ auto symbols = SymbolTable::Wrap(mod_.symbols);
+ auto type_mgr = type::Manager::Wrap(mod_.Types());
+ intrinsic::Context context{
+ u->TableData(),
+ type_mgr,
+ symbols,
+ };
- if (u->Result(0) && u->Val()) {
- if (u->Result(0)->Type() != u->Val()->Type()) {
- AddError(u, InstError(u, "result type must match value type"));
+ auto overload = core::intrinsic::LookupUnary(context, u->Op(), u->Val()->Type(),
+ core::EvaluationStage::kRuntime);
+ if (overload != Success) {
+ AddError(u, InstError(u, overload.Failure()));
+ return;
+ }
+
+ if (auto* result = u->Result(0)) {
+ if (overload->return_type != result->Type()) {
+ StringStream err;
+ err << "unary instruction result type (" << result->Type()->FriendlyName()
+ << ") does not match overload result type ("
+ << overload->return_type->FriendlyName() << ")";
+ AddError(u, InstError(u, err.str()));
+ }
}
}
}
@@ -856,9 +921,13 @@
if (auto* from = s->From()) {
if (auto* to = s->To()) {
- if (from->Type() != to->Type()->UnwrapPtr()) {
- AddError(s, Store::kFromOperandOffset,
- "value type does not match pointer element type");
+ auto* mv = to->Type()->As<core::type::MemoryView>();
+ if (!mv) {
+ AddError(s, Store::kFromOperandOffset, "store target operand is not a memory view");
+ return;
+ }
+ if (from->Type() != mv->StoreType()) {
+ AddError(s, Store::kFromOperandOffset, "value type does not match store type");
}
}
}
diff --git a/src/tint/lang/core/ir/validator_test.cc b/src/tint/lang/core/ir/validator_test.cc
index 7dd1d69..9989e2a 100644
--- a/src/tint/lang/core/ir/validator_test.cc
+++ b/src/tint/lang/core/ir/validator_test.cc
@@ -179,6 +179,117 @@
)");
}
+TEST_F(IR_ValidatorTest, CallToFunctionTooFewArguments) {
+ auto* g = b.Function("g", ty.void_());
+ g->SetParams({b.FunctionParam<i32>(), b.FunctionParam<i32>()});
+ b.Append(g->Block(), [&] { b.Return(g); });
+
+ auto* f = b.Function("f", ty.void_());
+ b.Append(f->Block(), [&] {
+ b.Call(g, 42_i);
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.str(),
+ R"(:8:20 error: call: function has 2 parameters, but call provides 1 arguments
+ %5:void = call %g, 42i
+ ^^
+
+:7:3 note: In block
+ %b2 = block {
+ ^^^^^^^^^^^
+
+note: # Disassembly
+%g = func(%2:i32, %3:i32):void -> %b1 {
+ %b1 = block {
+ ret
+ }
+}
+%f = func():void -> %b2 {
+ %b2 = block {
+ %5:void = call %g, 42i
+ ret
+ }
+}
+)");
+}
+
+TEST_F(IR_ValidatorTest, CallToFunctionTooManyArguments) {
+ auto* g = b.Function("g", ty.void_());
+ g->SetParams({b.FunctionParam<i32>(), b.FunctionParam<i32>()});
+ b.Append(g->Block(), [&] { b.Return(g); });
+
+ auto* f = b.Function("f", ty.void_());
+ b.Append(f->Block(), [&] {
+ b.Call(g, 1_i, 2_i, 3_i);
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.str(),
+ R"(:8:20 error: call: function has 2 parameters, but call provides 3 arguments
+ %5:void = call %g, 1i, 2i, 3i
+ ^^
+
+:7:3 note: In block
+ %b2 = block {
+ ^^^^^^^^^^^
+
+note: # Disassembly
+%g = func(%2:i32, %3:i32):void -> %b1 {
+ %b1 = block {
+ ret
+ }
+}
+%f = func():void -> %b2 {
+ %b2 = block {
+ %5:void = call %g, 1i, 2i, 3i
+ ret
+ }
+}
+)");
+}
+
+TEST_F(IR_ValidatorTest, CallToFunctionWrongArgType) {
+ auto* g = b.Function("g", ty.void_());
+ g->SetParams({b.FunctionParam<i32>(), b.FunctionParam<i32>(), b.FunctionParam<i32>()});
+ b.Append(g->Block(), [&] { b.Return(g); });
+
+ auto* f = b.Function("f", ty.void_());
+ b.Append(f->Block(), [&] {
+ b.Call(g, 1_i, 2_f, 3_i);
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.str(),
+ R"(:8:28 error: call: function parameter 1 is of type i32, but argument is of type f32
+ %6:void = call %g, 1i, 2.0f, 3i
+ ^^^^
+
+:7:3 note: In block
+ %b2 = block {
+ ^^^^^^^^^^^
+
+note: # Disassembly
+%g = func(%2:i32, %3:i32, %4:i32):void -> %b1 {
+ %b1 = block {
+ ret
+ }
+}
+%f = func():void -> %b2 {
+ %b2 = block {
+ %6:void = call %g, 1i, 2.0f, 3i
+ ret
+ }
+}
+)");
+}
+
TEST_F(IR_ValidatorTest, Block_NoTerminator) {
b.Function("my_func", ty.void_());
@@ -1271,8 +1382,8 @@
}
TEST_F(IR_ValidatorTest, Binary_Result_Nullptr) {
- auto* bin = mod.instructions.Create<ir::Binary>(nullptr, BinaryOp::kAdd, b.Constant(3_i),
- b.Constant(2_i));
+ auto* bin = mod.instructions.Create<ir::CoreBinary>(nullptr, BinaryOp::kAdd, b.Constant(3_i),
+ b.Constant(2_i));
auto* f = b.Function("my_func", ty.void_());
@@ -1329,7 +1440,7 @@
TEST_F(IR_ValidatorTest, Unary_Result_Nullptr) {
auto* bin =
- mod.instructions.Create<ir::Unary>(nullptr, ir::UnaryOp::kNegation, b.Constant(2_i));
+ mod.instructions.Create<ir::CoreUnary>(nullptr, UnaryOp::kNegation, b.Constant(2_i));
auto* f = b.Function("my_func", ty.void_());
@@ -1368,7 +1479,9 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
- EXPECT_EQ(res.Failure().reason.str(), R"(:3:5 error: unary: result type must match value type
+ EXPECT_EQ(
+ res.Failure().reason.str(),
+ R"(:3:5 error: unary: unary instruction result type (f32) does not match overload result type (i32)
%2:f32 = complement 2i
^^^^^^^^^^^^^^^^^^^^^^
@@ -2931,6 +3044,37 @@
)");
}
+TEST_F(IR_ValidatorTest, Store_TargetNotMemoryView) {
+ auto* f = b.Function("my_func", ty.void_());
+
+ b.Append(f->Block(), [&] {
+ auto* let = b.Let("l", 1_i);
+ b.Append(mod.instructions.Create<ir::Store>(let->Result(0), b.Constant(42_u)));
+ b.Return(f);
+ });
+
+ auto res = ir::Validate(mod);
+ ASSERT_NE(res, Success);
+ EXPECT_EQ(res.Failure().reason.str(),
+ R"(:4:15 error: store target operand is not a memory view
+ store %l, 42u
+ ^^^
+
+:2:3 note: In block
+ %b1 = block {
+ ^^^^^^^^^^^
+
+note: # Disassembly
+%my_func = func():void -> %b1 {
+ %b1 = block {
+ %l:i32 = let 1i
+ store %l, 42u
+ ret
+ }
+}
+)");
+}
+
TEST_F(IR_ValidatorTest, Store_TypeMismatch) {
auto* f = b.Function("my_func", ty.void_());
@@ -2943,7 +3087,7 @@
auto res = ir::Validate(mod);
ASSERT_NE(res, Success);
EXPECT_EQ(res.Failure().reason.str(),
- R"(:4:15 error: value type does not match pointer element type
+ R"(:4:15 error: value type does not match store type
store %2, 42u
^^^
diff --git a/src/tint/lang/core/type/BUILD.bazel b/src/tint/lang/core/type/BUILD.bazel
index e3c6b72..485a4a8 100644
--- a/src/tint/lang/core/type/BUILD.bazel
+++ b/src/tint/lang/core/type/BUILD.bazel
@@ -122,6 +122,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/core/type/BUILD.cmake b/src/tint/lang/core/type/BUILD.cmake
index d212503..7c9b819 100644
--- a/src/tint/lang/core/type/BUILD.cmake
+++ b/src/tint/lang/core/type/BUILD.cmake
@@ -121,6 +121,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/core/type/BUILD.gn b/src/tint/lang/core/type/BUILD.gn
index 8942f2a..2f0568b 100644
--- a/src/tint/lang/core/type/BUILD.gn
+++ b/src/tint/lang/core/type/BUILD.gn
@@ -125,6 +125,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/glsl/writer/BUILD.bazel b/src/tint/lang/glsl/writer/BUILD.bazel
index 3dac23b..0d24e42 100644
--- a/src/tint/lang/glsl/writer/BUILD.bazel
+++ b/src/tint/lang/glsl/writer/BUILD.bazel
@@ -131,3 +131,8 @@
actual = "//src/tint:tint_build_glsl_writer_true",
)
+alias(
+ name = "tint_build_wgsl_reader",
+ actual = "//src/tint:tint_build_wgsl_reader_true",
+)
+
diff --git a/src/tint/lang/glsl/writer/BUILD.cmake b/src/tint/lang/glsl/writer/BUILD.cmake
index cb302d8..35e7e21 100644
--- a/src/tint/lang/glsl/writer/BUILD.cmake
+++ b/src/tint/lang/glsl/writer/BUILD.cmake
@@ -138,4 +138,58 @@
)
endif(TINT_BUILD_GLSL_WRITER)
+endif(TINT_BUILD_GLSL_WRITER)
+if(TINT_BUILD_GLSL_WRITER)
+################################################################################
+# Target: tint_lang_glsl_writer_fuzz
+# Kind: fuzz
+# Condition: TINT_BUILD_GLSL_WRITER
+################################################################################
+tint_add_target(tint_lang_glsl_writer_fuzz fuzz
+)
+
+tint_target_add_dependencies(tint_lang_glsl_writer_fuzz fuzz
+ tint_api_common
+ tint_api_options
+ tint_lang_core
+ tint_lang_core_constant
+ tint_lang_core_type
+ tint_lang_wgsl
+ tint_lang_wgsl_ast
+ tint_lang_wgsl_features
+ tint_lang_wgsl_inspector
+ tint_lang_wgsl_program
+ tint_lang_wgsl_sem
+ tint_utils_bytes
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_GLSL_WRITER)
+ tint_target_add_dependencies(tint_lang_glsl_writer_fuzz fuzz
+ tint_lang_glsl_writer
+ tint_lang_glsl_writer_common
+ )
+endif(TINT_BUILD_GLSL_WRITER)
+
+if(TINT_BUILD_WGSL_READER)
+ tint_target_add_sources(tint_lang_glsl_writer_fuzz fuzz
+ "lang/glsl/writer/writer_ast_fuzz.cc"
+ )
+ tint_target_add_dependencies(tint_lang_glsl_writer_fuzz fuzz
+ tint_cmd_fuzz_wgsl_fuzz
+ )
+endif(TINT_BUILD_WGSL_READER)
+
endif(TINT_BUILD_GLSL_WRITER)
\ No newline at end of file
diff --git a/src/tint/lang/glsl/writer/BUILD.gn b/src/tint/lang/glsl/writer/BUILD.gn
index 4d5bfda..2f908e4 100644
--- a/src/tint/lang/glsl/writer/BUILD.gn
+++ b/src/tint/lang/glsl/writer/BUILD.gn
@@ -127,3 +127,47 @@
}
}
}
+if (tint_build_glsl_writer) {
+ tint_fuzz_source_set("fuzz") {
+ sources = []
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/api/options",
+ "${tint_src_dir}/lang/core",
+ "${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/type",
+ "${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/lang/wgsl/ast",
+ "${tint_src_dir}/lang/wgsl/features",
+ "${tint_src_dir}/lang/wgsl/inspector",
+ "${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/utils/bytes",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_glsl_writer) {
+ deps += [
+ "${tint_src_dir}/lang/glsl/writer",
+ "${tint_src_dir}/lang/glsl/writer/common",
+ ]
+ }
+
+ if (tint_build_wgsl_reader) {
+ sources += [ "writer_ast_fuzz.cc" ]
+ deps += [ "${tint_src_dir}/cmd/fuzz/wgsl:fuzz" ]
+ }
+ }
+}
diff --git a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
index dde83cd..8d96bc7 100644
--- a/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/glsl/writer/ast_printer/ast_printer.cc
@@ -182,7 +182,7 @@
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
polyfills.insert_bits = ast::transform::BuiltinPolyfill::Level::kClampParameters;
- polyfills.int_div_mod = true;
+ polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
diff --git a/src/tint/lang/glsl/writer/common/options.h b/src/tint/lang/glsl/writer/common/options.h
index 8068595..b795d10 100644
--- a/src/tint/lang/glsl/writer/common/options.h
+++ b/src/tint/lang/glsl/writer/common/options.h
@@ -61,6 +61,9 @@
/// Set to `true` to disable workgroup memory zero initialization
bool disable_workgroup_init = false;
+ /// Set to `true` to disable the polyfills on integer division and modulo.
+ bool disable_polyfill_integer_div_mod = false;
+
/// The GLSL version to emit
Version version;
@@ -85,6 +88,7 @@
/// Reflect the fields of this class so that it can be used by tint::ForeachField()
TINT_REFLECT(disable_robustness,
disable_workgroup_init,
+ disable_polyfill_integer_div_mod,
version,
binding_map,
placeholder_binding_point,
diff --git a/src/tint/lang/glsl/writer/common/version.h b/src/tint/lang/glsl/writer/common/version.h
index 84a5a9c..9c3463a 100644
--- a/src/tint/lang/glsl/writer/common/version.h
+++ b/src/tint/lang/glsl/writer/common/version.h
@@ -73,4 +73,11 @@
} // namespace tint::glsl::writer
+namespace tint {
+
+/// Relect enum information for Version
+TINT_REFLECT_ENUM_RANGE(glsl::writer::Version::Standard, kDesktop, kES);
+
+} // namespace tint
+
#endif // SRC_TINT_LANG_GLSL_WRITER_COMMON_VERSION_H_
diff --git a/src/tint/lang/glsl/writer/printer/helper_test.h b/src/tint/lang/glsl/writer/printer/helper_test.h
index f6b31dd..a720241 100644
--- a/src/tint/lang/glsl/writer/printer/helper_test.h
+++ b/src/tint/lang/glsl/writer/printer/helper_test.h
@@ -62,7 +62,7 @@
/// Run the writer on the IR module and validate the result.
/// @returns true if generation and validation succeeded
bool Generate() {
- if (auto raised = raise::Raise(mod); raised != Success) {
+ if (auto raised = Raise(mod); raised != Success) {
err_ = raised.Failure().reason.str();
return false;
}
diff --git a/src/tint/lang/glsl/writer/raise/raise.cc b/src/tint/lang/glsl/writer/raise/raise.cc
index 33c17e9..1985ec7 100644
--- a/src/tint/lang/glsl/writer/raise/raise.cc
+++ b/src/tint/lang/glsl/writer/raise/raise.cc
@@ -27,7 +27,7 @@
#include "src/tint/lang/glsl/writer/raise/raise.h"
-namespace tint::glsl::raise {
+namespace tint::glsl::writer {
Result<SuccessType> Raise(core::ir::Module&) {
// #define RUN_TRANSFORM(name)
@@ -41,4 +41,4 @@
return Success;
}
-} // namespace tint::glsl::raise
+} // namespace tint::glsl::writer
diff --git a/src/tint/lang/glsl/writer/raise/raise.h b/src/tint/lang/glsl/writer/raise/raise.h
index 2ff1489..846790d 100644
--- a/src/tint/lang/glsl/writer/raise/raise.h
+++ b/src/tint/lang/glsl/writer/raise/raise.h
@@ -35,13 +35,13 @@
class Module;
} // namespace tint::core::ir
-namespace tint::glsl::raise {
+namespace tint::glsl::writer {
/// Raise a core IR module to the MSL dialect of the IR.
/// @param mod the core IR module to raise to MSL dialect
/// @returns success or failure
Result<SuccessType> Raise(core::ir::Module& mod);
-} // namespace tint::glsl::raise
+} // namespace tint::glsl::writer
#endif // SRC_TINT_LANG_GLSL_WRITER_RAISE_RAISE_H_
diff --git a/src/tint/lang/glsl/writer/writer.cc b/src/tint/lang/glsl/writer/writer.cc
index 1402afe..3f8437d 100644
--- a/src/tint/lang/glsl/writer/writer.cc
+++ b/src/tint/lang/glsl/writer/writer.cc
@@ -40,7 +40,7 @@
Output output;
// Raise from core-dialect to GLSL-dialect.
- if (auto res = raise::Raise(ir); res != Success) {
+ if (auto res = Raise(ir); res != Success) {
return res.Failure();
}
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/glsl/writer/writer_ast_fuzz.cc
similarity index 65%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/glsl/writer/writer_ast_fuzz.cc
index 421db7b..096c259 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/glsl/writer/writer_ast_fuzz.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,31 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+// GEN_BUILD:CONDITION(tint_build_wgsl_reader)
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/cmd/fuzz/wgsl/fuzz.h"
+#include "src/tint/lang/glsl/writer/writer.h"
+#include "src/tint/lang/wgsl/ast/module.h"
+#include "src/tint/lang/wgsl/inspector/inspector.h"
-namespace tint::spirv::writer {
+namespace tint::glsl::writer {
namespace {
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
+void ASTFuzzer(const tint::Program& program, Options options) {
+ if (program.AST().HasOverrides()) {
return;
}
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
+
+ auto inspector = tint::inspector::Inspector(program);
+ auto entrypoints = inspector.GetEntryPoints();
+
+ // Test all of the entry points as GLSL requires specifying which one to generate.
+ for (const auto& ep : entrypoints) {
+ [[maybe_unused]] auto res = tint::glsl::writer::Generate(program, options, ep.name);
}
}
} // namespace
-} // namespace tint::spirv::writer
+} // namespace tint::glsl::writer
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+TINT_WGSL_PROGRAM_FUZZER(tint::glsl::writer::ASTFuzzer);
diff --git a/src/tint/lang/hlsl/writer/BUILD.bazel b/src/tint/lang/hlsl/writer/BUILD.bazel
index 71c0cbd..affbe22 100644
--- a/src/tint/lang/hlsl/writer/BUILD.bazel
+++ b/src/tint/lang/hlsl/writer/BUILD.bazel
@@ -130,3 +130,8 @@
actual = "//src/tint:tint_build_hlsl_writer_true",
)
+alias(
+ name = "tint_build_wgsl_reader",
+ actual = "//src/tint:tint_build_wgsl_reader_true",
+)
+
diff --git a/src/tint/lang/hlsl/writer/BUILD.cmake b/src/tint/lang/hlsl/writer/BUILD.cmake
index b9d641d..5a19a3c 100644
--- a/src/tint/lang/hlsl/writer/BUILD.cmake
+++ b/src/tint/lang/hlsl/writer/BUILD.cmake
@@ -135,4 +135,57 @@
)
endif(TINT_BUILD_HLSL_WRITER)
+endif(TINT_BUILD_HLSL_WRITER)
+if(TINT_BUILD_HLSL_WRITER)
+################################################################################
+# Target: tint_lang_hlsl_writer_fuzz
+# Kind: fuzz
+# Condition: TINT_BUILD_HLSL_WRITER
+################################################################################
+tint_add_target(tint_lang_hlsl_writer_fuzz fuzz
+)
+
+tint_target_add_dependencies(tint_lang_hlsl_writer_fuzz fuzz
+ tint_api_common
+ tint_api_options
+ tint_lang_core
+ tint_lang_core_constant
+ tint_lang_core_type
+ tint_lang_hlsl_writer_common
+ tint_lang_wgsl
+ tint_lang_wgsl_ast
+ tint_lang_wgsl_features
+ tint_lang_wgsl_program
+ tint_lang_wgsl_sem
+ tint_utils_bytes
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_HLSL_WRITER)
+ tint_target_add_dependencies(tint_lang_hlsl_writer_fuzz fuzz
+ tint_lang_hlsl_writer
+ )
+endif(TINT_BUILD_HLSL_WRITER)
+
+if(TINT_BUILD_WGSL_READER)
+ tint_target_add_sources(tint_lang_hlsl_writer_fuzz fuzz
+ "lang/hlsl/writer/writer_ast_fuzz.cc"
+ )
+ tint_target_add_dependencies(tint_lang_hlsl_writer_fuzz fuzz
+ tint_cmd_fuzz_wgsl_fuzz
+ )
+endif(TINT_BUILD_WGSL_READER)
+
endif(TINT_BUILD_HLSL_WRITER)
\ No newline at end of file
diff --git a/src/tint/lang/hlsl/writer/BUILD.gn b/src/tint/lang/hlsl/writer/BUILD.gn
index 6b8a8fc..4c8f704 100644
--- a/src/tint/lang/hlsl/writer/BUILD.gn
+++ b/src/tint/lang/hlsl/writer/BUILD.gn
@@ -124,3 +124,44 @@
}
}
}
+if (tint_build_hlsl_writer) {
+ tint_fuzz_source_set("fuzz") {
+ sources = []
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/api/options",
+ "${tint_src_dir}/lang/core",
+ "${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/type",
+ "${tint_src_dir}/lang/hlsl/writer/common",
+ "${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/lang/wgsl/ast",
+ "${tint_src_dir}/lang/wgsl/features",
+ "${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/utils/bytes",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_hlsl_writer) {
+ deps += [ "${tint_src_dir}/lang/hlsl/writer" ]
+ }
+
+ if (tint_build_wgsl_reader) {
+ sources += [ "writer_ast_fuzz.cc" ]
+ deps += [ "${tint_src_dir}/cmd/fuzz/wgsl:fuzz" ]
+ }
+ }
+}
diff --git a/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc b/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
index 6932c07..452abc5 100644
--- a/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/hlsl/writer/ast_printer/ast_printer.cc
@@ -250,7 +250,7 @@
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
polyfills.insert_bits = ast::transform::BuiltinPolyfill::Level::kFull;
- polyfills.int_div_mod = true;
+ polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
polyfills.precise_float_mod = true;
polyfills.reflect_vec2_f32 = options.polyfill_reflect_vec2_f32;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
diff --git a/src/tint/lang/hlsl/writer/common/BUILD.bazel b/src/tint/lang/hlsl/writer/common/BUILD.bazel
index f9bbbad..93cb98f 100644
--- a/src/tint/lang/hlsl/writer/common/BUILD.bazel
+++ b/src/tint/lang/hlsl/writer/common/BUILD.bazel
@@ -51,7 +51,6 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/reflection",
- "//src/tint/utils/text",
"//src/tint/utils/traits",
],
copts = COPTS,
diff --git a/src/tint/lang/hlsl/writer/common/BUILD.cmake b/src/tint/lang/hlsl/writer/common/BUILD.cmake
index aa8415c..1a5415e 100644
--- a/src/tint/lang/hlsl/writer/common/BUILD.cmake
+++ b/src/tint/lang/hlsl/writer/common/BUILD.cmake
@@ -50,6 +50,5 @@
tint_utils_macros
tint_utils_math
tint_utils_reflection
- tint_utils_text
tint_utils_traits
)
diff --git a/src/tint/lang/hlsl/writer/common/BUILD.gn b/src/tint/lang/hlsl/writer/common/BUILD.gn
index eeb1335..39c9b06 100644
--- a/src/tint/lang/hlsl/writer/common/BUILD.gn
+++ b/src/tint/lang/hlsl/writer/common/BUILD.gn
@@ -50,7 +50,6 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/reflection",
- "${tint_src_dir}/utils/text",
"${tint_src_dir}/utils/traits",
]
}
diff --git a/src/tint/lang/hlsl/writer/common/options.h b/src/tint/lang/hlsl/writer/common/options.h
index 44cb403..b1d8535 100644
--- a/src/tint/lang/hlsl/writer/common/options.h
+++ b/src/tint/lang/hlsl/writer/common/options.h
@@ -74,6 +74,9 @@
/// Set to `true` to generate polyfill for `dot4I8Packed` and `dot4U8Packed` builtins
bool polyfill_dot_4x8_packed = false;
+ /// Set to `true` to disable the polyfills on integer division and modulo.
+ bool disable_polyfill_integer_div_mod = false;
+
/// Options used to specify a mapping of binding points to indices into a UBO
/// from which to load buffer sizes.
ArrayLengthFromUniformOptions array_length_from_uniform = {};
@@ -106,6 +109,7 @@
truncate_interstage_variables,
polyfill_reflect_vec2_f32,
polyfill_dot_4x8_packed,
+ disable_polyfill_integer_div_mod,
array_length_from_uniform,
interstage_locations,
root_constant_binding_point,
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/hlsl/writer/writer_ast_fuzz.cc
similarity index 64%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/hlsl/writer/writer_ast_fuzz.cc
index 421db7b..a2865f9 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/hlsl/writer/writer_ast_fuzz.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,24 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+// GEN_BUILD:CONDITION(tint_build_wgsl_reader)
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/cmd/fuzz/wgsl/fuzz.h"
+#include "src/tint/lang/hlsl/writer/writer.h"
+#include "src/tint/lang/wgsl/ast/module.h"
-namespace tint::spirv::writer {
+namespace tint::hlsl::writer {
namespace {
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
+void ASTFuzzer(const tint::Program& program, Options options) {
+ if (program.AST().HasOverrides()) {
return;
}
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
- }
+
+ [[maybe_unused]] auto res = tint::hlsl::writer::Generate(program, options);
}
} // namespace
-} // namespace tint::spirv::writer
+} // namespace tint::hlsl::writer
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+TINT_WGSL_PROGRAM_FUZZER(tint::hlsl::writer::ASTFuzzer);
diff --git a/src/tint/lang/msl/intrinsic/BUILD.bazel b/src/tint/lang/msl/intrinsic/BUILD.bazel
index de60b66..d4b9fab 100644
--- a/src/tint/lang/msl/intrinsic/BUILD.bazel
+++ b/src/tint/lang/msl/intrinsic/BUILD.bazel
@@ -57,6 +57,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/msl/intrinsic/BUILD.cmake b/src/tint/lang/msl/intrinsic/BUILD.cmake
index 60cca31..3ede760 100644
--- a/src/tint/lang/msl/intrinsic/BUILD.cmake
+++ b/src/tint/lang/msl/intrinsic/BUILD.cmake
@@ -56,6 +56,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/msl/intrinsic/BUILD.gn b/src/tint/lang/msl/intrinsic/BUILD.gn
index 61d0771..2351f59 100644
--- a/src/tint/lang/msl/intrinsic/BUILD.gn
+++ b/src/tint/lang/msl/intrinsic/BUILD.gn
@@ -56,6 +56,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/msl/validate/BUILD.bazel b/src/tint/lang/msl/validate/BUILD.bazel
index 0606047..7e5730a 100644
--- a/src/tint/lang/msl/validate/BUILD.bazel
+++ b/src/tint/lang/msl/validate/BUILD.bazel
@@ -67,6 +67,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/msl/validate/BUILD.cmake b/src/tint/lang/msl/validate/BUILD.cmake
index e51eab9..698e899 100644
--- a/src/tint/lang/msl/validate/BUILD.cmake
+++ b/src/tint/lang/msl/validate/BUILD.cmake
@@ -63,6 +63,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/msl/validate/BUILD.gn b/src/tint/lang/msl/validate/BUILD.gn
index 2d587b1..cbf7c61 100644
--- a/src/tint/lang/msl/validate/BUILD.gn
+++ b/src/tint/lang/msl/validate/BUILD.gn
@@ -61,6 +61,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/msl/writer/BUILD.cmake b/src/tint/lang/msl/writer/BUILD.cmake
index d1b3c1a..18bec4c 100644
--- a/src/tint/lang/msl/writer/BUILD.cmake
+++ b/src/tint/lang/msl/writer/BUILD.cmake
@@ -148,4 +148,58 @@
)
endif(TINT_BUILD_MSL_WRITER)
+endif(TINT_BUILD_MSL_WRITER)
+if(TINT_BUILD_MSL_WRITER)
+################################################################################
+# Target: tint_lang_msl_writer_fuzz
+# Kind: fuzz
+# Condition: TINT_BUILD_MSL_WRITER
+################################################################################
+tint_add_target(tint_lang_msl_writer_fuzz fuzz
+)
+
+tint_target_add_dependencies(tint_lang_msl_writer_fuzz fuzz
+ tint_api_common
+ tint_api_options
+ tint_lang_core
+ tint_lang_core_constant
+ tint_lang_core_type
+ tint_lang_wgsl
+ tint_lang_wgsl_ast
+ tint_lang_wgsl_features
+ tint_lang_wgsl_program
+ tint_lang_wgsl_sem
+ tint_utils_bytes
+ tint_utils_containers
+ tint_utils_diagnostic
+ tint_utils_ice
+ tint_utils_id
+ tint_utils_macros
+ tint_utils_math
+ tint_utils_memory
+ tint_utils_reflection
+ tint_utils_result
+ tint_utils_rtti
+ tint_utils_symbol
+ tint_utils_text
+ tint_utils_traits
+)
+
+if(TINT_BUILD_MSL_WRITER)
+ tint_target_add_dependencies(tint_lang_msl_writer_fuzz fuzz
+ tint_lang_msl_writer
+ tint_lang_msl_writer_common
+ tint_lang_msl_writer_helpers
+ )
+endif(TINT_BUILD_MSL_WRITER)
+
+if(TINT_BUILD_WGSL_READER)
+ tint_target_add_sources(tint_lang_msl_writer_fuzz fuzz
+ "lang/msl/writer/writer_ast_fuzz.cc"
+ )
+ tint_target_add_dependencies(tint_lang_msl_writer_fuzz fuzz
+ tint_cmd_fuzz_wgsl_fuzz
+ )
+endif(TINT_BUILD_WGSL_READER)
+
endif(TINT_BUILD_MSL_WRITER)
\ No newline at end of file
diff --git a/src/tint/lang/msl/writer/BUILD.gn b/src/tint/lang/msl/writer/BUILD.gn
index e3f3066..e26ed1f 100644
--- a/src/tint/lang/msl/writer/BUILD.gn
+++ b/src/tint/lang/msl/writer/BUILD.gn
@@ -134,3 +134,47 @@
}
}
}
+if (tint_build_msl_writer) {
+ tint_fuzz_source_set("fuzz") {
+ sources = []
+ deps = [
+ "${tint_src_dir}/api/common",
+ "${tint_src_dir}/api/options",
+ "${tint_src_dir}/lang/core",
+ "${tint_src_dir}/lang/core/constant",
+ "${tint_src_dir}/lang/core/type",
+ "${tint_src_dir}/lang/wgsl",
+ "${tint_src_dir}/lang/wgsl/ast",
+ "${tint_src_dir}/lang/wgsl/features",
+ "${tint_src_dir}/lang/wgsl/program",
+ "${tint_src_dir}/lang/wgsl/sem",
+ "${tint_src_dir}/utils/bytes",
+ "${tint_src_dir}/utils/containers",
+ "${tint_src_dir}/utils/diagnostic",
+ "${tint_src_dir}/utils/ice",
+ "${tint_src_dir}/utils/id",
+ "${tint_src_dir}/utils/macros",
+ "${tint_src_dir}/utils/math",
+ "${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
+ "${tint_src_dir}/utils/result",
+ "${tint_src_dir}/utils/rtti",
+ "${tint_src_dir}/utils/symbol",
+ "${tint_src_dir}/utils/text",
+ "${tint_src_dir}/utils/traits",
+ ]
+
+ if (tint_build_msl_writer) {
+ deps += [
+ "${tint_src_dir}/lang/msl/writer",
+ "${tint_src_dir}/lang/msl/writer/common",
+ "${tint_src_dir}/lang/msl/writer/helpers",
+ ]
+ }
+
+ if (tint_build_wgsl_reader) {
+ sources += [ "writer_ast_fuzz.cc" ]
+ deps += [ "${tint_src_dir}/cmd/fuzz/wgsl:fuzz" ]
+ }
+ }
+}
diff --git a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
index 517885a..b5991d0 100644
--- a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
@@ -184,7 +184,7 @@
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
polyfills.insert_bits = ast::transform::BuiltinPolyfill::Level::kClampParameters;
- polyfills.int_div_mod = true;
+ polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
polyfills.sign_int = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.workgroup_uniform_load = true;
diff --git a/src/tint/lang/msl/writer/common/options.h b/src/tint/lang/msl/writer/common/options.h
index 66623d9..1004293 100644
--- a/src/tint/lang/msl/writer/common/options.h
+++ b/src/tint/lang/msl/writer/common/options.h
@@ -130,6 +130,9 @@
/// for all vertex shaders in the module.
bool emit_vertex_point_size = false;
+ /// Set to `true` to disable the polyfills on integer division and modulo.
+ bool disable_polyfill_integer_div_mod = false;
+
/// The index to use when generating a UBO to receive storage buffer sizes.
/// Defaults to 30, which is the last valid buffer slot.
uint32_t buffer_size_ubo_index = 30;
@@ -152,6 +155,7 @@
TINT_REFLECT(disable_robustness,
disable_workgroup_init,
emit_vertex_point_size,
+ disable_polyfill_integer_div_mod,
buffer_size_ubo_index,
fixed_sample_mask,
pixel_local_options,
diff --git a/src/tint/lang/msl/writer/printer/binary_test.cc b/src/tint/lang/msl/writer/printer/binary_test.cc
index 74808bf..495b156 100644
--- a/src/tint/lang/msl/writer/printer/binary_test.cc
+++ b/src/tint/lang/msl/writer/printer/binary_test.cc
@@ -38,7 +38,7 @@
struct BinaryData {
const char* result;
- core::ir::BinaryOp op;
+ core::BinaryOp op;
};
inline std::ostream& operator<<(std::ostream& out, BinaryData data) {
StringStream str;
@@ -70,22 +70,21 @@
}
)");
}
-INSTANTIATE_TEST_SUITE_P(
- MslPrinterTest,
- MslPrinterBinaryTest,
- testing::Values(BinaryData{"(left + right)", core::ir::BinaryOp::kAdd},
- BinaryData{"(left - right)", core::ir::BinaryOp::kSubtract},
- BinaryData{"(left * right)", core::ir::BinaryOp::kMultiply},
- BinaryData{"(left & right)", core::ir::BinaryOp::kAnd},
- BinaryData{"(left | right)", core::ir::BinaryOp::kOr},
- BinaryData{"(left ^ right)", core::ir::BinaryOp::kXor}));
+INSTANTIATE_TEST_SUITE_P(MslPrinterTest,
+ MslPrinterBinaryTest,
+ testing::Values(BinaryData{"(left + right)", core::BinaryOp::kAdd},
+ BinaryData{"(left - right)", core::BinaryOp::kSubtract},
+ BinaryData{"(left * right)", core::BinaryOp::kMultiply},
+ BinaryData{"(left & right)", core::BinaryOp::kAnd},
+ BinaryData{"(left | right)", core::BinaryOp::kOr},
+ BinaryData{"(left ^ right)", core::BinaryOp::kXor}));
TEST_F(MslPrinterTest, BinaryDivU32) {
auto* func = b.Function("foo", ty.void_());
b.Append(func->Block(), [&] {
auto* l = b.Let("left", b.Constant(1_u));
auto* r = b.Let("right", b.Constant(2_u));
- auto* bin = b.Binary(core::ir::BinaryOp::kDivide, ty.u32(), l, r);
+ auto* bin = b.Binary(core::BinaryOp::kDivide, ty.u32(), l, r);
b.Let("val", bin);
b.Return(func);
});
@@ -108,7 +107,7 @@
b.Append(func->Block(), [&] {
auto* l = b.Let("left", b.Constant(1_u));
auto* r = b.Let("right", b.Constant(2_u));
- auto* bin = b.Binary(core::ir::BinaryOp::kModulo, ty.u32(), l, r);
+ auto* bin = b.Binary(core::BinaryOp::kModulo, ty.u32(), l, r);
b.Let("val", bin);
b.Return(func);
});
@@ -132,7 +131,7 @@
b.Append(func->Block(), [&] {
auto* l = b.Let("left", b.Constant(1_u));
auto* r = b.Let("right", b.Constant(2_u));
- auto* bin = b.Binary(core::ir::BinaryOp::kShiftLeft, ty.u32(), l, r);
+ auto* bin = b.Binary(core::BinaryOp::kShiftLeft, ty.u32(), l, r);
b.Let("val", bin);
b.Return(func);
});
@@ -152,7 +151,7 @@
b.Append(func->Block(), [&] {
auto* l = b.Let("left", b.Constant(1_u));
auto* r = b.Let("right", b.Constant(2_u));
- auto* bin = b.Binary(core::ir::BinaryOp::kShiftRight, ty.u32(), l, r);
+ auto* bin = b.Binary(core::BinaryOp::kShiftRight, ty.u32(), l, r);
b.Let("val", bin);
b.Return(func);
});
@@ -193,12 +192,12 @@
INSTANTIATE_TEST_SUITE_P(
MslPrinterTest,
MslPrinterBinaryBoolTest,
- testing::Values(BinaryData{"(left == right)", core::ir::BinaryOp::kEqual},
- BinaryData{"(left != right)", core::ir::BinaryOp::kNotEqual},
- BinaryData{"(left < right)", core::ir::BinaryOp::kLessThan},
- BinaryData{"(left > right)", core::ir::BinaryOp::kGreaterThan},
- BinaryData{"(left <= right)", core::ir::BinaryOp::kLessThanEqual},
- BinaryData{"(left >= right)", core::ir::BinaryOp::kGreaterThanEqual}));
+ testing::Values(BinaryData{"(left == right)", core::BinaryOp::kEqual},
+ BinaryData{"(left != right)", core::BinaryOp::kNotEqual},
+ BinaryData{"(left < right)", core::BinaryOp::kLessThan},
+ BinaryData{"(left > right)", core::BinaryOp::kGreaterThan},
+ BinaryData{"(left <= right)", core::BinaryOp::kLessThanEqual},
+ BinaryData{"(left >= right)", core::BinaryOp::kGreaterThanEqual}));
// TODO(dsinclair): Needs transform
// TODO(dsinclair): Requires `bitcast` support
@@ -228,9 +227,9 @@
}
constexpr BinaryData signed_overflow_defined_behaviour_cases[] = {
- {"as_type<int>((as_type<uint>(left) + as_type<uint>(right)))", core::ir::BinaryOp::kAdd},
- {"as_type<int>((as_type<uint>(left) - as_type<uint>(right)))", core::ir::BinaryOp::kSubtract},
- {"as_type<int>((as_type<uint>(left) * as_type<uint>(right)))", core::ir::BinaryOp::kMultiply}};
+ {"as_type<int>((as_type<uint>(left) + as_type<uint>(right)))", core::BinaryOp::kAdd},
+ {"as_type<int>((as_type<uint>(left) - as_type<uint>(right)))", core::BinaryOp::kSubtract},
+ {"as_type<int>((as_type<uint>(left) * as_type<uint>(right)))", core::BinaryOp::kMultiply}};
INSTANTIATE_TEST_SUITE_P(MslPrinterTest,
MslPrinterBinaryTest_SignedOverflowDefinedBehaviour,
testing::ValuesIn(signed_overflow_defined_behaviour_cases));
@@ -263,8 +262,8 @@
}
constexpr BinaryData shift_signed_overflow_defined_behaviour_cases[] = {
- {"as_type<int>((as_type<uint>(left) << right))", core::ir::BinaryOp::kShiftLeft},
- {"(left >> right)", core::ir::BinaryOp::kShiftRight}};
+ {"as_type<int>((as_type<uint>(left) << right))", core::BinaryOp::kShiftLeft},
+ {"(left >> right)", core::BinaryOp::kShiftRight}};
INSTANTIATE_TEST_SUITE_P(MslPrinterTest,
MslPrinterBinaryTest_ShiftSignedOverflowDefinedBehaviour,
testing::ValuesIn(shift_signed_overflow_defined_behaviour_cases));
@@ -299,13 +298,13 @@
constexpr BinaryData signed_overflow_defined_behaviour_chained_cases[] = {
{R"(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(left) + as_type<uint>(right)))) +
as_type<uint>(right))))",
- core::ir::BinaryOp::kAdd},
+ core::BinaryOp::kAdd},
{R"(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(left) - as_type<uint>(right)))) -
as_type<uint>(right))))",
- core::ir::BinaryOp::kSubtract},
+ core::BinaryOp::kSubtract},
{R"(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(left) * as_type<uint>(right)))) *
as_type<uint>(right))))",
- core::ir::BinaryOp::kMultiply}};
+ core::BinaryOp::kMultiply}};
INSTANTIATE_TEST_SUITE_P(MslPrinterTest,
MslPrinterBinaryTest_SignedOverflowDefinedBehaviour_Chained,
testing::ValuesIn(signed_overflow_defined_behaviour_chained_cases));
@@ -339,8 +338,8 @@
}
constexpr BinaryData shift_signed_overflow_defined_behaviour_chained_cases[] = {
{R"(as_type<int>((as_type<uint>(as_type<int>((as_type<uint>(left) << right))) << right)))",
- core::ir::BinaryOp::kShiftLeft},
- {R"(((left >> right) >> right))", core::ir::BinaryOp::kShiftRight},
+ core::BinaryOp::kShiftLeft},
+ {R"(((left >> right) >> right))", core::BinaryOp::kShiftRight},
};
INSTANTIATE_TEST_SUITE_P(MslPrinterTest,
MslPrinterBinaryTest_ShiftSignedOverflowDefinedBehaviour_Chained,
@@ -353,7 +352,7 @@
auto* left = b.Var("left", ty.ptr<core::AddressSpace::kFunction, f32>());
auto* right = b.Var("right", ty.ptr<core::AddressSpace::kFunction, f32>());
- auto* expr1 = b.Binary(core::ir::BinaryOp::kModulo, ty.f32(), left, right);
+ auto* expr1 = b.Binary(core::BinaryOp::kModulo, ty.f32(), left, right);
b.Let("val", expr1);
});
@@ -376,7 +375,7 @@
auto* left = b.Var("left", ty.ptr<core::AddressSpace::kFunction, f16>());
auto* right = b.Var("right", ty.ptr<core::AddressSpace::kFunction, f16>());
- auto* expr1 = b.Binary(core::ir::BinaryOp::kModulo, ty.f16(), left, right);
+ auto* expr1 = b.Binary(core::BinaryOp::kModulo, ty.f16(), left, right);
b.Let("val", expr1);
});
@@ -397,7 +396,7 @@
auto* left = b.Var("left", ty.ptr(core::AddressSpace::kFunction, ty.vec3<f32>()));
auto* right = b.Var("right", ty.ptr(core::AddressSpace::kFunction, ty.vec3<f32>()));
- auto* expr1 = b.Binary(core::ir::BinaryOp::kModulo, ty.vec3<f32>(), left, right);
+ auto* expr1 = b.Binary(core::BinaryOp::kModulo, ty.vec3<f32>(), left, right);
b.Let("val", expr1);
});
@@ -420,7 +419,7 @@
auto* left = b.Var("left", ty.ptr(core::AddressSpace::kFunction, ty.vec3<f16>()));
auto* right = b.Var("right", ty.ptr(core::AddressSpace::kFunction, ty.vec3<f16>()));
- auto* expr1 = b.Binary(core::ir::BinaryOp::kModulo, ty.vec3<f16>(), left, right);
+ auto* expr1 = b.Binary(core::BinaryOp::kModulo, ty.vec3<f16>(), left, right);
b.Let("val", expr1);
});
@@ -441,7 +440,7 @@
auto* left = b.Var("left", ty.ptr(core::AddressSpace::kFunction, ty.bool_()));
auto* right = b.Var("right", ty.ptr(core::AddressSpace::kFunction, ty.bool_()));
- auto* expr1 = b.Binary(core::ir::BinaryOp::kAdd, ty.bool_(), left, right);
+ auto* expr1 = b.Binary(core::BinaryOp::kAdd, ty.bool_(), left, right);
b.Let("val", expr1);
});
@@ -462,7 +461,7 @@
auto* left = b.Var("left", ty.ptr(core::AddressSpace::kFunction, ty.bool_()));
auto* right = b.Var("right", ty.ptr(core::AddressSpace::kFunction, ty.bool_()));
- auto* expr1 = b.Binary(core::ir::BinaryOp::kOr, ty.bool_(), left, right);
+ auto* expr1 = b.Binary(core::BinaryOp::kOr, ty.bool_(), left, right);
b.Let("val", expr1);
});
diff --git a/src/tint/lang/msl/writer/printer/helper_test.h b/src/tint/lang/msl/writer/printer/helper_test.h
index b52e60d..410153b 100644
--- a/src/tint/lang/msl/writer/printer/helper_test.h
+++ b/src/tint/lang/msl/writer/printer/helper_test.h
@@ -80,7 +80,7 @@
/// Run the writer on the IR module and validate the result.
/// @returns true if generation and validation succeeded
bool Generate() {
- if (auto raised = raise::Raise(mod, {}); raised != Success) {
+ if (auto raised = Raise(mod, {}); raised != Success) {
err_ = raised.Failure().reason.str();
return false;
}
diff --git a/src/tint/lang/msl/writer/printer/printer.cc b/src/tint/lang/msl/writer/printer/printer.cc
index 6cfa838..e2950c5 100644
--- a/src/tint/lang/msl/writer/printer/printer.cc
+++ b/src/tint/lang/msl/writer/printer/printer.cc
@@ -35,14 +35,15 @@
#include "src/tint/lang/core/constant/splat.h"
#include "src/tint/lang/core/fluent_types.h"
#include "src/tint/lang/core/ir/access.h"
-#include "src/tint/lang/core/ir/binary.h"
#include "src/tint/lang/core/ir/bitcast.h"
#include "src/tint/lang/core/ir/break_if.h"
#include "src/tint/lang/core/ir/constant.h"
#include "src/tint/lang/core/ir/construct.h"
#include "src/tint/lang/core/ir/continue.h"
#include "src/tint/lang/core/ir/convert.h"
+#include "src/tint/lang/core/ir/core_binary.h"
#include "src/tint/lang/core/ir/core_builtin_call.h"
+#include "src/tint/lang/core/ir/core_unary.h"
#include "src/tint/lang/core/ir/discard.h"
#include "src/tint/lang/core/ir/exit_if.h"
#include "src/tint/lang/core/ir/exit_loop.h"
@@ -349,8 +350,8 @@
[&](core::ir::LoadVectorElement*) { /* inlined */ }, //
[&](core::ir::Swizzle*) { /* inlined */ }, //
[&](core::ir::Bitcast*) { /* inlined */ }, //
- [&](core::ir::Unary*) { /* inlined */ }, //
- [&](core::ir::Binary*) { /* inlined */ }, //
+ [&](core::ir::CoreBinary*) { /* inlined */ }, //
+ [&](core::ir::CoreUnary*) { /* inlined */ }, //
[&](core::ir::Load*) { /* inlined */ }, //
[&](core::ir::Construct*) { /* inlined */ }, //
[&](core::ir::Access*) { /* inlined */ }, //
@@ -365,8 +366,8 @@
[&](const core::ir::InstructionResult* r) {
Switch(
r->Instruction(), //
- [&](const core::ir::Unary* u) { EmitUnary(out, u); }, //
- [&](const core::ir::Binary* b) { EmitBinary(out, b); }, //
+ [&](const core::ir::CoreBinary* b) { EmitBinary(out, b); }, //
+ [&](const core::ir::CoreUnary* u) { EmitUnary(out, u); }, //
[&](const core::ir::Convert* b) { EmitConvert(out, b); }, //
[&](const core::ir::Let* l) { out << NameOf(l->Result(0)); }, //
[&](const core::ir::Load* l) { EmitValue(out, l->From()); }, //
@@ -387,14 +388,17 @@
TINT_ICE_ON_NO_MATCH);
}
- void EmitUnary(StringStream& out, const core::ir::Unary* u) {
+ void EmitUnary(StringStream& out, const core::ir::CoreUnary* u) {
switch (u->Op()) {
- case core::ir::UnaryOp::kNegation:
+ case core::UnaryOp::kNegation:
out << "-";
break;
- case core::ir::UnaryOp::kComplement:
+ case core::UnaryOp::kComplement:
out << "~";
break;
+ default:
+ TINT_UNIMPLEMENTED() << u->Op();
+ break;
}
out << "(";
EmitValue(out, u->Val());
@@ -403,8 +407,8 @@
/// Emit a binary instruction
/// @param b the binary instruction
- void EmitBinary(StringStream& out, const core::ir::Binary* b) {
- if (b->Op() == core::ir::BinaryOp::kEqual) {
+ void EmitBinary(StringStream& out, const core::ir::CoreBinary* b) {
+ if (b->Op() == core::BinaryOp::kEqual) {
auto* rhs = b->RHS()->As<core::ir::Constant>();
if (rhs && rhs->Type()->Is<core::type::Bool>() &&
rhs->Value()->ValueAs<bool>() == false) {
@@ -418,38 +422,42 @@
auto kind = [&] {
switch (b->Op()) {
- case core::ir::BinaryOp::kAdd:
+ case core::BinaryOp::kAdd:
return "+";
- case core::ir::BinaryOp::kSubtract:
+ case core::BinaryOp::kSubtract:
return "-";
- case core::ir::BinaryOp::kMultiply:
+ case core::BinaryOp::kMultiply:
return "*";
- case core::ir::BinaryOp::kDivide:
+ case core::BinaryOp::kDivide:
return "/";
- case core::ir::BinaryOp::kModulo:
+ case core::BinaryOp::kModulo:
return "%";
- case core::ir::BinaryOp::kAnd:
+ case core::BinaryOp::kAnd:
return "&";
- case core::ir::BinaryOp::kOr:
+ case core::BinaryOp::kOr:
return "|";
- case core::ir::BinaryOp::kXor:
+ case core::BinaryOp::kXor:
return "^";
- case core::ir::BinaryOp::kEqual:
+ case core::BinaryOp::kEqual:
return "==";
- case core::ir::BinaryOp::kNotEqual:
+ case core::BinaryOp::kNotEqual:
return "!=";
- case core::ir::BinaryOp::kLessThan:
+ case core::BinaryOp::kLessThan:
return "<";
- case core::ir::BinaryOp::kGreaterThan:
+ case core::BinaryOp::kGreaterThan:
return ">";
- case core::ir::BinaryOp::kLessThanEqual:
+ case core::BinaryOp::kLessThanEqual:
return "<=";
- case core::ir::BinaryOp::kGreaterThanEqual:
+ case core::BinaryOp::kGreaterThanEqual:
return ">=";
- case core::ir::BinaryOp::kShiftLeft:
+ case core::BinaryOp::kShiftLeft:
return "<<";
- case core::ir::BinaryOp::kShiftRight:
+ case core::BinaryOp::kShiftRight:
return ">>";
+ case core::BinaryOp::kLogicalAnd:
+ return "&&";
+ case core::BinaryOp::kLogicalOr:
+ return "||";
}
return "<error>";
};
diff --git a/src/tint/lang/msl/writer/raise/raise.cc b/src/tint/lang/msl/writer/raise/raise.cc
index 2d970cc..63591e7 100644
--- a/src/tint/lang/msl/writer/raise/raise.cc
+++ b/src/tint/lang/msl/writer/raise/raise.cc
@@ -43,7 +43,7 @@
#include "src/tint/lang/msl/writer/common/option_helpers.h"
#include "src/tint/lang/msl/writer/raise/builtin_polyfill.h"
-namespace tint::msl::writer::raise {
+namespace tint::msl::writer {
Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
#define RUN_TRANSFORM(name, ...) \
@@ -61,7 +61,7 @@
{
core::ir::transform::BinaryPolyfillConfig binary_polyfills{};
- binary_polyfills.int_div_mod = true;
+ binary_polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
binary_polyfills.bitshift_modulo = true; // crbug.com/tint/1543
RUN_TRANSFORM(core::ir::transform::BinaryPolyfill, binary_polyfills);
}
@@ -103,9 +103,9 @@
RUN_TRANSFORM(core::ir::transform::DemoteToHelper);
RUN_TRANSFORM(core::ir::transform::ValueToLet);
- RUN_TRANSFORM(BuiltinPolyfill);
+ RUN_TRANSFORM(raise::BuiltinPolyfill);
return Success;
}
-} // namespace tint::msl::writer::raise
+} // namespace tint::msl::writer
diff --git a/src/tint/lang/msl/writer/raise/raise.h b/src/tint/lang/msl/writer/raise/raise.h
index 256925d..a4d5895 100644
--- a/src/tint/lang/msl/writer/raise/raise.h
+++ b/src/tint/lang/msl/writer/raise/raise.h
@@ -39,7 +39,7 @@
class Module;
} // namespace tint::core::ir
-namespace tint::msl::writer::raise {
+namespace tint::msl::writer {
/// Raise a core IR module to the MSL dialect of the IR.
/// @param module the core IR module to raise to MSL dialect
@@ -47,6 +47,6 @@
/// @returns success or failure
Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
-} // namespace tint::msl::writer::raise
+} // namespace tint::msl::writer
#endif // SRC_TINT_LANG_MSL_WRITER_RAISE_RAISE_H_
diff --git a/src/tint/lang/msl/writer/writer.cc b/src/tint/lang/msl/writer/writer.cc
index e997959..c0f9d41 100644
--- a/src/tint/lang/msl/writer/writer.cc
+++ b/src/tint/lang/msl/writer/writer.cc
@@ -53,7 +53,7 @@
Output output;
// Raise from core-dialect to MSL-dialect.
- if (auto res = raise::Raise(ir, options); res != Success) {
+ if (auto res = Raise(ir, options); res != Success) {
return res.Failure();
}
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/msl/writer/writer_ast_fuzz.cc
similarity index 64%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/msl/writer/writer_ast_fuzz.cc
index 421db7b..937a4a8 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/msl/writer/writer_ast_fuzz.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,27 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+// GEN_BUILD:CONDITION(tint_build_wgsl_reader)
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/cmd/fuzz/wgsl/fuzz.h"
+#include "src/tint/lang/msl/writer/helpers/generate_bindings.h"
+#include "src/tint/lang/msl/writer/writer.h"
+#include "src/tint/lang/wgsl/ast/module.h"
-namespace tint::spirv::writer {
+namespace tint::msl::writer {
namespace {
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
+void ASTFuzzer(const tint::Program& program, Options options) {
+ if (program.AST().HasOverrides()) {
return;
}
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
- }
+
+ options.bindings = GenerateBindings(program);
+
+ [[maybe_unused]] auto res = tint::msl::writer::Generate(program, options);
}
} // namespace
-} // namespace tint::spirv::writer
+} // namespace tint::msl::writer
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+TINT_WGSL_PROGRAM_FUZZER(tint::msl::writer::ASTFuzzer);
diff --git a/src/tint/lang/spirv/intrinsic/BUILD.bazel b/src/tint/lang/spirv/intrinsic/BUILD.bazel
index 6ebd70e..7b2f0e8 100644
--- a/src/tint/lang/spirv/intrinsic/BUILD.bazel
+++ b/src/tint/lang/spirv/intrinsic/BUILD.bazel
@@ -60,6 +60,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/spirv/intrinsic/BUILD.cmake b/src/tint/lang/spirv/intrinsic/BUILD.cmake
index 92e0bc5..541c0f5 100644
--- a/src/tint/lang/spirv/intrinsic/BUILD.cmake
+++ b/src/tint/lang/spirv/intrinsic/BUILD.cmake
@@ -59,6 +59,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/spirv/intrinsic/BUILD.gn b/src/tint/lang/spirv/intrinsic/BUILD.gn
index eb892d0..e99baee 100644
--- a/src/tint/lang/spirv/intrinsic/BUILD.gn
+++ b/src/tint/lang/spirv/intrinsic/BUILD.gn
@@ -59,6 +59,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/spirv/reader/parser/BUILD.bazel b/src/tint/lang/spirv/reader/parser/BUILD.bazel
index 6990fb1..d41f46f 100644
--- a/src/tint/lang/spirv/reader/parser/BUILD.bazel
+++ b/src/tint/lang/spirv/reader/parser/BUILD.bazel
@@ -82,6 +82,7 @@
"constant_test.cc",
"function_test.cc",
"helper_test.h",
+ "memory_test.cc",
"struct_test.cc",
"var_test.cc",
],
diff --git a/src/tint/lang/spirv/reader/parser/BUILD.cmake b/src/tint/lang/spirv/reader/parser/BUILD.cmake
index ac508eb..e82f651 100644
--- a/src/tint/lang/spirv/reader/parser/BUILD.cmake
+++ b/src/tint/lang/spirv/reader/parser/BUILD.cmake
@@ -88,6 +88,7 @@
lang/spirv/reader/parser/constant_test.cc
lang/spirv/reader/parser/function_test.cc
lang/spirv/reader/parser/helper_test.h
+ lang/spirv/reader/parser/memory_test.cc
lang/spirv/reader/parser/struct_test.cc
lang/spirv/reader/parser/var_test.cc
)
diff --git a/src/tint/lang/spirv/reader/parser/BUILD.gn b/src/tint/lang/spirv/reader/parser/BUILD.gn
index 8ffc520..430c576 100644
--- a/src/tint/lang/spirv/reader/parser/BUILD.gn
+++ b/src/tint/lang/spirv/reader/parser/BUILD.gn
@@ -89,6 +89,7 @@
"constant_test.cc",
"function_test.cc",
"helper_test.h",
+ "memory_test.cc",
"struct_test.cc",
"var_test.cc",
]
diff --git a/src/tint/lang/spirv/reader/parser/function_test.cc b/src/tint/lang/spirv/reader/parser/function_test.cc
index b9ec90a..a66b1e0 100644
--- a/src/tint/lang/spirv/reader/parser/function_test.cc
+++ b/src/tint/lang/spirv/reader/parser/function_test.cc
@@ -398,6 +398,56 @@
)");
}
+TEST_F(SpirvParserTest, FunctionCall_ReturnValueChain) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %bool = OpTypeBool
+ %true = OpConstantTrue %bool
+ %fn_type = OpTypeFunction %bool
+ %main_type = OpTypeFunction %void
+
+ %bar = OpFunction %bool None %fn_type
+ %bar_start = OpLabel
+ OpReturnValue %true
+ OpFunctionEnd
+
+ %foo = OpFunction %bool None %fn_type
+ %foo_start = OpLabel
+ %call = OpFunctionCall %bool %foo
+ OpReturnValue %call
+ OpFunctionEnd
+
+ %main = OpFunction %void None %main_type
+ %main_start = OpLabel
+ %1 = OpFunctionCall %bool %bar
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+%1 = func():bool -> %b1 {
+ %b1 = block {
+ ret true
+ }
+}
+%2 = func():bool -> %b2 {
+ %b2 = block {
+ %3:bool = call %2
+ ret %3
+ }
+}
+%main = @compute @workgroup_size(1, 1, 1) func():void -> %b3 {
+ %b3 = block {
+ %5:bool = call %1
+ ret
+ }
+}
+)");
+}
+
TEST_F(SpirvParserTest, FunctionCall_ParamAndReturnValue) {
EXPECT_IR(R"(
OpCapability Shader
diff --git a/src/tint/lang/spirv/reader/parser/memory_test.cc b/src/tint/lang/spirv/reader/parser/memory_test.cc
new file mode 100644
index 0000000..2031696
--- /dev/null
+++ b/src/tint/lang/spirv/reader/parser/memory_test.cc
@@ -0,0 +1,766 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/lang/spirv/reader/parser/helper_test.h"
+
+namespace tint::spirv::reader {
+namespace {
+
+TEST_F(SpirvParserTest, Load_Scalar) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_ptr = OpTypePointer Function %u32
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %u32_ptr Function
+ %load = OpLoad %u32 %var
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, u32, read_write> = var
+ %3:u32 = load %2
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_Vector) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %vec4u_ptr = OpTypePointer Function %vec4u
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %vec4u_ptr Function
+ %load = OpLoad %vec4u %var
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, vec4<u32>, read_write> = var
+ %3:vec4<u32> = load %2
+ ret
+ }
+)");
+}
+
+// TODO(jrprice): We need to handle pointer-to-vector component somewhere.
+TEST_F(SpirvParserTest, DISABLED_Load_VectorComponent) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %u32_ptr = OpTypePointer Function %u32
+ %vec4u_ptr = OpTypePointer Function %vec4u
+ %u32_2 = OpConstant %u32 2
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %vec4u_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_2
+ %load = OpLoad %u32 %access
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, vec4<u32>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 2u
+ %4:u32 = load %3
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_Matrix) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %f32 = OpTypeFloat 32
+ %vec4f = OpTypeVector %f32 4
+ %mat3x4f = OpTypeMatrix %vec4f 3
+%mat3x4f_ptr = OpTypePointer Function %mat3x4f
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %mat3x4f_ptr Function
+ %load = OpLoad %mat3x4f %var
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, mat3x4<f32>, read_write> = var
+ %3:mat3x4<f32> = load %2
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_MatrixColumn) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %f32 = OpTypeFloat 32
+ %vec4f = OpTypeVector %f32 4
+ %mat3x4f = OpTypeMatrix %vec4f 3
+ %vec4f_ptr = OpTypePointer Function %vec4f
+%mat3x4f_ptr = OpTypePointer Function %mat3x4f
+ %u32_2 = OpConstant %u32 2
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %mat3x4f_ptr Function
+ %access = OpAccessChain %vec4f_ptr %var %u32_2
+ %load = OpLoad %vec4f %access
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, mat3x4<f32>, read_write> = var
+ %3:ptr<function, vec4<f32>, read_write> = access %2, 2u
+ %4:vec4<f32> = load %3
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_Array) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_4 = OpConstant %u32 4
+ %arr = OpTypeArray %u32 %u32_4
+ %arr_ptr = OpTypePointer Function %arr
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_ptr Function
+ %load = OpLoad %arr %var
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<u32, 4>, read_write> = var
+ %3:array<u32, 4> = load %2
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_ArrayElement) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_2 = OpConstant %u32 2
+ %u32_4 = OpConstant %u32 4
+ %arr = OpTypeArray %u32 %u32_4
+ %u32_ptr = OpTypePointer Function %u32
+ %arr_ptr = OpTypePointer Function %arr
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_2
+ %load = OpLoad %u32 %access
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<u32, 4>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 2u
+ %4:u32 = load %3
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_Struct) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %str = OpTypeStruct %u32 %u32
+ %str_ptr = OpTypePointer Function %str
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %str_ptr Function
+ %load = OpLoad %str %var
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, tint_symbol_2, read_write> = var
+ %3:tint_symbol_2 = load %2
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Load_StructMember) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_1 = OpConstant %u32 1
+ %str = OpTypeStruct %u32 %u32
+ %u32_ptr = OpTypePointer Function %u32
+ %str_ptr = OpTypePointer Function %str
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %str_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_1
+ %load = OpLoad %u32 %access
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, tint_symbol_2, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 1u
+ %4:u32 = load %3
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_Scalar) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_42 = OpConstant %u32 42
+ %u32_ptr = OpTypePointer Function %u32
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %u32_ptr Function
+ OpStore %var %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, u32, read_write> = var
+ store %2, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_Vector) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %vec4u = OpTypeVector %u32 4
+ %null = OpConstantNull %vec4u
+ %vec4u_ptr = OpTypePointer Function %vec4u
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %vec4u_ptr Function
+ OpStore %var %null
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, vec4<u32>, read_write> = var
+ store %2, vec4<u32>(0u)
+ ret
+ }
+)");
+}
+
+// TODO(jrprice): We need to handle pointer-to-vector component somewhere.
+TEST_F(SpirvParserTest, DISABLED_Store_VectorComponent) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_42 = OpConstantInt %u32 42
+ %vec4u = OpTypeVector %u32 4
+ %u32_ptr = OpTypePointer Function %u32
+ %vec4u_ptr = OpTypePointer Function %vec4u
+ %u32_2 = OpConstant %u32 2
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %vec4u_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_2
+ OpStore %access %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, vec4<u32>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 2u
+ store %3, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_Matrix) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %f32 = OpTypeFloat 32
+ %vec4f = OpTypeVector %f32 4
+ %mat3x4f = OpTypeMatrix %vec4f 3
+ %null = OpConstantNull %mat3x4f
+%mat3x4f_ptr = OpTypePointer Function %mat3x4f
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %mat3x4f_ptr Function
+ OpStore %var %null
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, mat3x4<f32>, read_write> = var
+ store %2, mat3x4<f32>(vec4<f32>(0.0f))
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_MatrixColumn) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %f32 = OpTypeFloat 32
+ %vec4f = OpTypeVector %f32 4
+ %mat3x4f = OpTypeMatrix %vec4f 3
+ %null = OpConstantNull %vec4f
+ %vec4f_ptr = OpTypePointer Function %vec4f
+%mat3x4f_ptr = OpTypePointer Function %mat3x4f
+ %u32_2 = OpConstant %u32 2
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %mat3x4f_ptr Function
+ %access = OpAccessChain %vec4f_ptr %var %u32_2
+ OpStore %access %null
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, mat3x4<f32>, read_write> = var
+ %3:ptr<function, vec4<f32>, read_write> = access %2, 2u
+ store %3, vec4<f32>(0.0f)
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_Array) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_4 = OpConstant %u32 4
+ %arr = OpTypeArray %u32 %u32_4
+ %null = OpConstantNull %arr
+ %arr_ptr = OpTypePointer Function %arr
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_ptr Function
+ OpStore %var %null
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<u32, 4>, read_write> = var
+ store %2, array<u32, 4>(0u)
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_ArrayElement) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_2 = OpConstant %u32 2
+ %u32_4 = OpConstant %u32 4
+ %u32_42 = OpConstant %u32 42
+ %arr = OpTypeArray %u32 %u32_4
+ %u32_ptr = OpTypePointer Function %u32
+ %arr_ptr = OpTypePointer Function %arr
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_2
+ OpStore %access %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<u32, 4>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 2u
+ store %3, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_Struct) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %str = OpTypeStruct %u32 %u32
+ %null = OpConstantNull %str
+ %str_ptr = OpTypePointer Function %str
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %str_ptr Function
+ OpStore %var %null
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, tint_symbol_2, read_write> = var
+ store %2, tint_symbol_2(0u)
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Store_StructMember) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_1 = OpConstant %u32 1
+ %u32_42 = OpConstant %u32 42
+ %str = OpTypeStruct %u32 %u32
+ %u32_ptr = OpTypePointer Function %u32
+ %str_ptr = OpTypePointer Function %str
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %str_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_1
+ OpStore %access %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, tint_symbol_2, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 1u
+ store %3, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Access_Nested_SingleAccessInstruction) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %u32_42 = OpConstant %u32 42
+ %arr_inner = OpTypeArray %u32 %u32_4
+ %str = OpTypeStruct %arr_inner %arr_inner %arr_inner %arr_inner
+ %arr_outer = OpTypeArray %str %u32_4
+ %u32_ptr = OpTypePointer Function %u32
+%arr_outer_ptr = OpTypePointer Function %arr_outer
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_outer_ptr Function
+ %access = OpAccessChain %u32_ptr %var %u32_1 %u32_2 %u32_3
+ %load = OpLoad %u32 %access
+ OpStore %access %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<tint_symbol_4, 4>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 1u, 2u, 3u
+ %4:u32 = load %3
+ store %3, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Access_Nested_SeparateAccessInstructions) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %u32_42 = OpConstant %u32 42
+ %arr_inner = OpTypeArray %u32 %u32_4
+ %str = OpTypeStruct %arr_inner %arr_inner %arr_inner %arr_inner
+ %arr_outer = OpTypeArray %str %u32_4
+ %u32_ptr = OpTypePointer Function %u32
+%arr_inner_ptr = OpTypePointer Function %arr_inner
+ %str_ptr = OpTypePointer Function %str
+%arr_outer_ptr = OpTypePointer Function %arr_outer
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_outer_ptr Function
+ %access_1 = OpAccessChain %str_ptr %var %u32_1
+ %access_2 = OpAccessChain %arr_inner_ptr %access_1 %u32_2
+ %access_3 = OpAccessChain %u32_ptr %access_2 %u32_3
+ %load = OpLoad %u32 %access_3
+ OpStore %access_3 %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<tint_symbol_4, 4>, read_write> = var
+ %3:ptr<function, tint_symbol_4, read_write> = access %2, 1u
+ %4:ptr<function, array<u32, 4>, read_write> = access %3, 2u
+ %5:ptr<function, u32, read_write> = access %4, 3u
+ %6:u32 = load %5
+ store %5, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Access_NoIndices) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_ptr = OpTypePointer Function %u32
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %u32_ptr Function
+ %access_1 = OpAccessChain %u32_ptr %var
+ %access_2 = OpAccessChain %u32_ptr %access_1
+ %load = OpLoad %u32 %access_2
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, u32, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2
+ %4:ptr<function, u32, read_write> = access %3
+ %5:u32 = load %4
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, Access_SignedIndices) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %i32 = OpTypeInt 32 1
+ %i32_1 = OpConstant %i32 1
+ %u32_2 = OpConstant %u32 2
+ %i32_3 = OpConstant %i32 3
+ %u32_4 = OpConstant %u32 4
+ %u32_42 = OpConstant %u32 42
+ %arr_inner = OpTypeArray %u32 %u32_4
+ %str = OpTypeStruct %arr_inner %arr_inner %arr_inner %arr_inner
+ %arr_outer = OpTypeArray %str %u32_4
+ %u32_ptr = OpTypePointer Function %u32
+%arr_outer_ptr = OpTypePointer Function %arr_outer
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_outer_ptr Function
+ %access = OpAccessChain %u32_ptr %var %i32_1 %u32_2 %i32_3
+ %load = OpLoad %u32 %access
+ OpStore %access %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<tint_symbol_4, 4>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 1i, 2u, 3i
+ %4:u32 = load %3
+ store %3, 42u
+ ret
+ }
+)");
+}
+
+TEST_F(SpirvParserTest, InBoundsAccessChain) {
+ EXPECT_IR(R"(
+ OpCapability Shader
+ OpMemoryModel Logical GLSL450
+ OpEntryPoint GLCompute %main "main"
+ OpExecutionMode %main LocalSize 1 1 1
+ %void = OpTypeVoid
+ %u32 = OpTypeInt 32 0
+ %u32_1 = OpConstant %u32 1
+ %u32_2 = OpConstant %u32 2
+ %u32_3 = OpConstant %u32 3
+ %u32_4 = OpConstant %u32 4
+ %u32_42 = OpConstant %u32 42
+ %arr_inner = OpTypeArray %u32 %u32_4
+ %str = OpTypeStruct %arr_inner %arr_inner %arr_inner %arr_inner
+ %arr_outer = OpTypeArray %str %u32_4
+ %u32_ptr = OpTypePointer Function %u32
+%arr_outer_ptr = OpTypePointer Function %arr_outer
+ %ep_type = OpTypeFunction %void
+ %main = OpFunction %void None %ep_type
+ %main_start = OpLabel
+ %var = OpVariable %arr_outer_ptr Function
+ %access = OpInBoundsAccessChain %u32_ptr %var %u32_1 %u32_2 %u32_3
+ %load = OpLoad %u32 %access
+ OpStore %access %u32_42
+ OpReturn
+ OpFunctionEnd
+)",
+ R"(
+ %b1 = block {
+ %2:ptr<function, array<tint_symbol_4, 4>, read_write> = var
+ %3:ptr<function, u32, read_write> = access %2, 1u, 2u, 3u
+ %4:u32 = load %3
+ store %3, 42u
+ ret
+ }
+)");
+}
+
+} // namespace
+} // namespace tint::spirv::reader
diff --git a/src/tint/lang/spirv/reader/parser/parser.cc b/src/tint/lang/spirv/reader/parser/parser.cc
index f9057b3..56a3d47 100644
--- a/src/tint/lang/spirv/reader/parser/parser.cc
+++ b/src/tint/lang/spirv/reader/parser/parser.cc
@@ -76,7 +76,10 @@
return Failure("failed to build the internal representation of the module");
}
- EmitModuleScopeVariables();
+ {
+ TINT_SCOPED_ASSIGNMENT(current_block_, ir_.root_block);
+ EmitModuleScopeVariables();
+ }
EmitFunctions();
@@ -316,11 +319,27 @@
return nullptr;
}
+ /// Register an IR value for a SPIR-V result ID.
+ /// @param result_id the SPIR-V result ID
+ /// @param value the IR value
+ void AddValue(uint32_t result_id, core::ir::Value* value) { values_.Add(result_id, value); }
+
+ /// Emit an instruction to the current block.
+ /// @param inst the instruction to emit
+ /// @param result_id an optional SPIR-V result ID to register the instruction result for
+ void Emit(core::ir::Instruction* inst, uint32_t result_id = 0) {
+ current_block_->Append(inst);
+ if (result_id != 0) {
+ TINT_ASSERT_OR_RETURN(inst->Results().Length() == 1u);
+ AddValue(result_id, inst->Result(0));
+ }
+ }
+
/// Emit the module-scope variables.
void EmitModuleScopeVariables() {
for (auto& inst : spirv_context_->module()->types_values()) {
if (inst.opcode() == spv::Op::OpVariable) {
- ir_.root_block->Append(EmitVar(inst));
+ EmitVar(inst);
}
}
}
@@ -394,19 +413,31 @@
/// @param dst the Tint IR block to append to
/// @param src the SPIR-V block to emit
void EmitBlock(core::ir::Block* dst, const spvtools::opt::BasicBlock& src) {
+ TINT_SCOPED_ASSIGNMENT(current_block_, dst);
for (auto& inst : src) {
switch (inst.opcode()) {
+ case spv::Op::OpAccessChain:
+ case spv::Op::OpInBoundsAccessChain:
+ EmitAccess(inst);
+ break;
case spv::Op::OpFunctionCall:
- dst->Append(EmitFunctionCall(inst));
+ EmitFunctionCall(inst);
+ break;
+ case spv::Op::OpLoad:
+ Emit(b_.Load(Value(inst.GetSingleWordOperand(2))), inst.result_id());
break;
case spv::Op::OpReturn:
- dst->Append(b_.Return(current_function_));
+ Emit(b_.Return(current_function_));
break;
case spv::Op::OpReturnValue:
- dst->Append(b_.Return(current_function_, Value(inst.GetSingleWordOperand(0))));
+ Emit(b_.Return(current_function_, Value(inst.GetSingleWordOperand(0))));
+ break;
+ case spv::Op::OpStore:
+ Emit(b_.Store(Value(inst.GetSingleWordOperand(0)),
+ Value(inst.GetSingleWordOperand(1))));
break;
case spv::Op::OpVariable:
- dst->Append(EmitVar(inst));
+ EmitVar(inst);
break;
default:
TINT_UNIMPLEMENTED()
@@ -415,25 +446,60 @@
}
}
+ /// @param inst the SPIR-V instruction for OpAccessChain
+ void EmitAccess(const spvtools::opt::Instruction& inst) {
+ Vector<core::ir::Value*, 4> indices;
+ for (uint32_t i = 3; i < inst.NumOperandWords(); i++) {
+ indices.Push(Value(inst.GetSingleWordOperand(i)));
+ }
+ auto* base = Value(inst.GetSingleWordOperand(2));
+ auto* access = b_.Access(Type(inst.type_id()), base, std::move(indices));
+ Emit(access, inst.result_id());
+ }
+
/// @param inst the SPIR-V instruction for OpFunctionCall
- /// @returns the Tint IR instruction
- core::ir::UserCall* EmitFunctionCall(const spvtools::opt::Instruction& inst) {
+ void EmitFunctionCall(const spvtools::opt::Instruction& inst) {
// TODO(crbug.com/tint/1907): Capture result.
Vector<core::ir::Value*, 4> args;
for (uint32_t i = 3; i < inst.NumOperandWords(); i++) {
args.Push(Value(inst.GetSingleWordOperand(i)));
}
- return b_.Call(Function(inst.GetSingleWordInOperand(0)), std::move(args));
+ Emit(b_.Call(Function(inst.GetSingleWordInOperand(0)), std::move(args)), inst.result_id());
}
/// @param inst the SPIR-V instruction for OpVariable
- /// @returns the Tint IR instruction
- core::ir::Var* EmitVar(const spvtools::opt::Instruction& inst) {
+ void EmitVar(const spvtools::opt::Instruction& inst) {
auto* var = b_.Var(Type(inst.type_id())->As<core::type::Pointer>());
if (inst.NumOperands() > 3) {
var->SetInitializer(Value(inst.GetSingleWordOperand(3)));
}
- return var;
+
+ // Handle decorations.
+ std::optional<uint32_t> group;
+ std::optional<uint32_t> binding;
+ for (auto* deco :
+ spirv_context_->get_decoration_mgr()->GetDecorationsFor(inst.result_id(), false)) {
+ auto d = deco->GetSingleWordOperand(1);
+ switch (spv::Decoration(d)) {
+ case spv::Decoration::NonWritable:
+ break;
+ case spv::Decoration::DescriptorSet:
+ group = deco->GetSingleWordOperand(2);
+ break;
+ case spv::Decoration::Binding:
+ binding = deco->GetSingleWordOperand(2);
+ break;
+ default:
+ TINT_UNIMPLEMENTED() << "unhandled decoration " << d;
+ break;
+ }
+ }
+ if (group || binding) {
+ TINT_ASSERT(group && binding);
+ var->SetBindingPoint(group.value(), binding.value());
+ }
+
+ Emit(var, inst.result_id());
}
private:
@@ -446,6 +512,8 @@
/// The Tint IR function that is currently being emitted.
core::ir::Function* current_function_ = nullptr;
+ /// The Tint IR block that is currently being emitted.
+ core::ir::Block* current_block_ = nullptr;
/// A map from a SPIR-V type declaration result ID to the corresponding Tint type object.
Hashmap<const spvtools::opt::analysis::Type*, const core::type::Type*, 16> types_;
/// A map from a SPIR-V function definition result ID to the corresponding Tint function object.
diff --git a/src/tint/lang/spirv/reader/parser/var_test.cc b/src/tint/lang/spirv/reader/parser/var_test.cc
index 28d2a66..b2963dd 100644
--- a/src/tint/lang/spirv/reader/parser/var_test.cc
+++ b/src/tint/lang/spirv/reader/parser/var_test.cc
@@ -150,6 +150,9 @@
OpExecutionMode %1 LocalSize 1 1 1
OpDecorate %str Block
OpMemberDecorate %str 0 Offset 0
+ OpDecorate %6 NonWritable
+ OpDecorate %6 DescriptorSet 1
+ OpDecorate %6 Binding 2
%void = OpTypeVoid
%uint = OpTypeInt 32 0
%str = OpTypeStruct %uint
@@ -167,7 +170,7 @@
}
%b1 = block { # root
- %1:ptr<uniform, tint_symbol_1, read_write> = var
+ %1:ptr<uniform, tint_symbol_1, read_write> = var @binding_point(1, 2)
}
%main = @compute @workgroup_size(1, 1, 1) func():void -> %b2 {
diff --git a/src/tint/lang/spirv/type/BUILD.bazel b/src/tint/lang/spirv/type/BUILD.bazel
index 9bbee2d..53c59e9 100644
--- a/src/tint/lang/spirv/type/BUILD.bazel
+++ b/src/tint/lang/spirv/type/BUILD.bazel
@@ -56,6 +56,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/spirv/type/BUILD.cmake b/src/tint/lang/spirv/type/BUILD.cmake
index 92c1ede..7d21774 100644
--- a/src/tint/lang/spirv/type/BUILD.cmake
+++ b/src/tint/lang/spirv/type/BUILD.cmake
@@ -55,6 +55,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/spirv/type/BUILD.gn b/src/tint/lang/spirv/type/BUILD.gn
index 8c03245..2834593 100644
--- a/src/tint/lang/spirv/type/BUILD.gn
+++ b/src/tint/lang/spirv/type/BUILD.gn
@@ -55,6 +55,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/spirv/writer/BUILD.cmake b/src/tint/lang/spirv/writer/BUILD.cmake
index 3700f48..0afdfec 100644
--- a/src/tint/lang/spirv/writer/BUILD.cmake
+++ b/src/tint/lang/spirv/writer/BUILD.cmake
@@ -232,7 +232,7 @@
# Condition: TINT_BUILD_SPV_WRITER
################################################################################
tint_add_target(tint_lang_spirv_writer_fuzz fuzz
- lang/spirv/writer/writer_fuzz.cc
+ lang/spirv/writer/writer_ir_fuzz.cc
)
tint_target_add_dependencies(tint_lang_spirv_writer_fuzz fuzz
@@ -244,6 +244,7 @@
tint_lang_core_type
tint_lang_wgsl
tint_lang_wgsl_ast
+ tint_lang_wgsl_features
tint_lang_wgsl_helpers
tint_lang_wgsl_program
tint_lang_wgsl_sem
@@ -283,6 +284,7 @@
if(TINT_BUILD_WGSL_READER)
tint_target_add_sources(tint_lang_spirv_writer_fuzz fuzz
"lang/spirv/writer/ast_writer_fuzz.cc"
+ "lang/spirv/writer/writer_ast_fuzz.cc"
)
tint_target_add_dependencies(tint_lang_spirv_writer_fuzz fuzz
tint_cmd_fuzz_wgsl_fuzz
diff --git a/src/tint/lang/spirv/writer/BUILD.gn b/src/tint/lang/spirv/writer/BUILD.gn
index 120b4f4..02f722a 100644
--- a/src/tint/lang/spirv/writer/BUILD.gn
+++ b/src/tint/lang/spirv/writer/BUILD.gn
@@ -205,7 +205,7 @@
}
if (tint_build_spv_writer) {
tint_fuzz_source_set("fuzz") {
- sources = [ "writer_fuzz.cc" ]
+ sources = [ "writer_ir_fuzz.cc" ]
deps = [
"${tint_src_dir}/api/common",
"${tint_src_dir}/cmd/fuzz/ir:fuzz",
@@ -215,6 +215,7 @@
"${tint_src_dir}/lang/core/type",
"${tint_src_dir}/lang/wgsl",
"${tint_src_dir}/lang/wgsl/ast",
+ "${tint_src_dir}/lang/wgsl/features",
"${tint_src_dir}/lang/wgsl/helpers",
"${tint_src_dir}/lang/wgsl/program",
"${tint_src_dir}/lang/wgsl/sem",
@@ -251,7 +252,10 @@
}
if (tint_build_wgsl_reader) {
- sources += [ "ast_writer_fuzz.cc" ]
+ sources += [
+ "ast_writer_fuzz.cc",
+ "writer_ast_fuzz.cc",
+ ]
deps += [ "${tint_src_dir}/cmd/fuzz/wgsl:fuzz" ]
}
}
diff --git a/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc b/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc
index 31a300e..2b3c5fa 100644
--- a/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/ast_printer.cc
@@ -28,8 +28,6 @@
#include "src/tint/lang/spirv/writer/ast_printer/ast_printer.h"
#include <unordered_map>
-#include <utility>
-#include <vector>
#include "src/tint/lang/spirv/writer/ast_raise/clamp_frag_depth.h"
#include "src/tint/lang/spirv/writer/ast_raise/for_loop_to_loop.h"
@@ -140,7 +138,7 @@
polyfills.first_leading_bit = true;
polyfills.first_trailing_bit = true;
polyfills.insert_bits = ast::transform::BuiltinPolyfill::Level::kClampParameters;
- polyfills.int_div_mod = true;
+ polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
polyfills.saturate = true;
polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
polyfills.quantize_to_vec_f16 = true; // crbug.com/tint/1741
diff --git a/src/tint/lang/spirv/writer/binary_test.cc b/src/tint/lang/spirv/writer/binary_test.cc
index 607b04b..a14b39b 100644
--- a/src/tint/lang/spirv/writer/binary_test.cc
+++ b/src/tint/lang/spirv/writer/binary_test.cc
@@ -38,10 +38,38 @@
/// A parameterized test case.
struct BinaryTestCase {
- /// The element type to test.
- TestElementType type;
+ BinaryTestCase(TestElementType type_,
+ core::BinaryOp op_,
+ std::string spirv_inst_,
+ std::string spirv_type_name_)
+ : res_type(type_),
+ lhs_type(type_),
+ rhs_type(type_),
+ op(op_),
+ spirv_inst(spirv_inst_),
+ spirv_type_name(spirv_type_name_) {}
+
+ BinaryTestCase(TestElementType res_type_,
+ TestElementType lhs_type_,
+ TestElementType rhs_type_,
+ core::BinaryOp op_,
+ std::string spirv_inst_,
+ std::string spirv_type_name_)
+ : res_type(res_type_),
+ lhs_type(lhs_type_),
+ rhs_type(rhs_type_),
+ op(op_),
+ spirv_inst(spirv_inst_),
+ spirv_type_name(spirv_type_name_) {}
+
+ /// The result type of the binary op.
+ TestElementType res_type;
+ /// The LHS type of the binary op.
+ TestElementType lhs_type;
+ /// The RHS type of the binary op.
+ TestElementType rhs_type;
/// The binary operation.
- core::ir::BinaryOp op;
+ core::BinaryOp op;
/// The expected SPIR-V instruction.
std::string spirv_inst;
/// The expected SPIR-V result type name.
@@ -54,9 +82,9 @@
auto* func = b.Function("foo", ty.void_());
b.Append(func->Block(), [&] {
- auto* lhs = MakeScalarValue(params.type);
- auto* rhs = MakeScalarValue(params.type);
- auto* result = b.Binary(params.op, MakeScalarType(params.type), lhs, rhs);
+ auto* lhs = MakeScalarValue(params.lhs_type);
+ auto* rhs = MakeScalarValue(params.rhs_type);
+ auto* result = b.Binary(params.op, MakeScalarType(params.res_type), lhs, rhs);
b.Return(func);
mod.SetName(result, "result");
});
@@ -69,9 +97,9 @@
auto* func = b.Function("foo", ty.void_());
b.Append(func->Block(), [&] {
- auto* lhs = MakeVectorValue(params.type);
- auto* rhs = MakeVectorValue(params.type);
- auto* result = b.Binary(params.op, MakeVectorType(params.type), lhs, rhs);
+ auto* lhs = MakeVectorValue(params.lhs_type);
+ auto* rhs = MakeVectorValue(params.rhs_type);
+ auto* result = b.Binary(params.op, MakeVectorType(params.res_type), lhs, rhs);
b.Return(func);
mod.SetName(result, "result");
});
@@ -82,48 +110,49 @@
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_I32,
Arithmetic_Bitwise,
- testing::Values(
- BinaryTestCase{kI32, core::ir::BinaryOp::kAdd, "OpIAdd", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kSubtract, "OpISub", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kMultiply, "OpIMul", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kAnd, "OpBitwiseAnd", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kOr, "OpBitwiseOr", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kXor, "OpBitwiseXor", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kShiftLeft, "OpShiftLeftLogical", "int"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kShiftRight, "OpShiftRightArithmetic", "int"}));
+ testing::Values(BinaryTestCase{kI32, core::BinaryOp::kAdd, "OpIAdd", "int"},
+ BinaryTestCase{kI32, core::BinaryOp::kSubtract, "OpISub", "int"},
+ BinaryTestCase{kI32, core::BinaryOp::kMultiply, "OpIMul", "int"},
+ BinaryTestCase{kI32, core::BinaryOp::kAnd, "OpBitwiseAnd", "int"},
+ BinaryTestCase{kI32, core::BinaryOp::kOr, "OpBitwiseOr", "int"},
+ BinaryTestCase{kI32, core::BinaryOp::kXor, "OpBitwiseXor", "int"},
+ BinaryTestCase{kI32, kI32, kU32, core::BinaryOp::kShiftLeft,
+ "OpShiftLeftLogical", "int"},
+ BinaryTestCase{kI32, kI32, kU32, core::BinaryOp::kShiftRight,
+ "OpShiftRightArithmetic", "int"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_U32,
Arithmetic_Bitwise,
- testing::Values(
- BinaryTestCase{kU32, core::ir::BinaryOp::kAdd, "OpIAdd", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kSubtract, "OpISub", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kMultiply, "OpIMul", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kAnd, "OpBitwiseAnd", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kOr, "OpBitwiseOr", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kXor, "OpBitwiseXor", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kShiftLeft, "OpShiftLeftLogical", "uint"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kShiftRight, "OpShiftRightLogical", "uint"}));
+ testing::Values(BinaryTestCase{kU32, core::BinaryOp::kAdd, "OpIAdd", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kSubtract, "OpISub", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kMultiply, "OpIMul", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kAnd, "OpBitwiseAnd", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kOr, "OpBitwiseOr", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kXor, "OpBitwiseXor", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kShiftLeft, "OpShiftLeftLogical", "uint"},
+ BinaryTestCase{kU32, core::BinaryOp::kShiftRight, "OpShiftRightLogical",
+ "uint"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_F32,
Arithmetic_Bitwise,
- testing::Values(BinaryTestCase{kF32, core::ir::BinaryOp::kAdd, "OpFAdd", "float"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kSubtract, "OpFSub", "float"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kMultiply, "OpFMul", "float"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kDivide, "OpFDiv", "float"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kModulo, "OpFRem", "float"}));
+ testing::Values(BinaryTestCase{kF32, core::BinaryOp::kAdd, "OpFAdd", "float"},
+ BinaryTestCase{kF32, core::BinaryOp::kSubtract, "OpFSub", "float"},
+ BinaryTestCase{kF32, core::BinaryOp::kMultiply, "OpFMul", "float"},
+ BinaryTestCase{kF32, core::BinaryOp::kDivide, "OpFDiv", "float"},
+ BinaryTestCase{kF32, core::BinaryOp::kModulo, "OpFRem", "float"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_F16,
Arithmetic_Bitwise,
- testing::Values(BinaryTestCase{kF16, core::ir::BinaryOp::kAdd, "OpFAdd", "half"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kSubtract, "OpFSub", "half"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kMultiply, "OpFMul", "half"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kDivide, "OpFDiv", "half"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kModulo, "OpFRem", "half"}));
+ testing::Values(BinaryTestCase{kF16, core::BinaryOp::kAdd, "OpFAdd", "half"},
+ BinaryTestCase{kF16, core::BinaryOp::kSubtract, "OpFSub", "half"},
+ BinaryTestCase{kF16, core::BinaryOp::kMultiply, "OpFMul", "half"},
+ BinaryTestCase{kF16, core::BinaryOp::kDivide, "OpFDiv", "half"},
+ BinaryTestCase{kF16, core::BinaryOp::kModulo, "OpFRem", "half"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_Bool,
Arithmetic_Bitwise,
- testing::Values(BinaryTestCase{kBool, core::ir::BinaryOp::kAnd, "OpLogicalAnd", "bool"},
- BinaryTestCase{kBool, core::ir::BinaryOp::kOr, "OpLogicalOr", "bool"}));
+ testing::Values(BinaryTestCase{kBool, core::BinaryOp::kAnd, "OpLogicalAnd", "bool"},
+ BinaryTestCase{kBool, core::BinaryOp::kOr, "OpLogicalOr", "bool"}));
TEST_F(SpirvWriterTest, Binary_ScalarTimesVector_F32) {
auto* scalar = b.FunctionParam("scalar", ty.f32());
@@ -236,8 +265,8 @@
auto* func = b.Function("foo", ty.void_());
b.Append(func->Block(), [&] {
- auto* lhs = MakeScalarValue(params.type);
- auto* rhs = MakeScalarValue(params.type);
+ auto* lhs = MakeScalarValue(params.lhs_type);
+ auto* rhs = MakeScalarValue(params.rhs_type);
auto* result = b.Binary(params.op, ty.bool_(), lhs, rhs);
b.Return(func);
mod.SetName(result, "result");
@@ -252,8 +281,8 @@
auto* func = b.Function("foo", ty.void_());
b.Append(func->Block(), [&] {
- auto* lhs = MakeVectorValue(params.type);
- auto* rhs = MakeVectorValue(params.type);
+ auto* lhs = MakeVectorValue(params.lhs_type);
+ auto* rhs = MakeVectorValue(params.rhs_type);
auto* result = b.Binary(params.op, ty.vec2<bool>(), lhs, rhs);
b.Return(func);
mod.SetName(result, "result");
@@ -266,50 +295,47 @@
SpirvWriterTest_Binary_I32,
Comparison,
testing::Values(
- BinaryTestCase{kI32, core::ir::BinaryOp::kEqual, "OpIEqual", "bool"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kNotEqual, "OpINotEqual", "bool"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kGreaterThan, "OpSGreaterThan", "bool"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kGreaterThanEqual, "OpSGreaterThanEqual", "bool"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kLessThan, "OpSLessThan", "bool"},
- BinaryTestCase{kI32, core::ir::BinaryOp::kLessThanEqual, "OpSLessThanEqual", "bool"}));
+ BinaryTestCase{kI32, core::BinaryOp::kEqual, "OpIEqual", "bool"},
+ BinaryTestCase{kI32, core::BinaryOp::kNotEqual, "OpINotEqual", "bool"},
+ BinaryTestCase{kI32, core::BinaryOp::kGreaterThan, "OpSGreaterThan", "bool"},
+ BinaryTestCase{kI32, core::BinaryOp::kGreaterThanEqual, "OpSGreaterThanEqual", "bool"},
+ BinaryTestCase{kI32, core::BinaryOp::kLessThan, "OpSLessThan", "bool"},
+ BinaryTestCase{kI32, core::BinaryOp::kLessThanEqual, "OpSLessThanEqual", "bool"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_U32,
Comparison,
testing::Values(
- BinaryTestCase{kU32, core::ir::BinaryOp::kEqual, "OpIEqual", "bool"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kNotEqual, "OpINotEqual", "bool"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kGreaterThan, "OpUGreaterThan", "bool"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kGreaterThanEqual, "OpUGreaterThanEqual", "bool"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kLessThan, "OpULessThan", "bool"},
- BinaryTestCase{kU32, core::ir::BinaryOp::kLessThanEqual, "OpULessThanEqual", "bool"}));
+ BinaryTestCase{kU32, core::BinaryOp::kEqual, "OpIEqual", "bool"},
+ BinaryTestCase{kU32, core::BinaryOp::kNotEqual, "OpINotEqual", "bool"},
+ BinaryTestCase{kU32, core::BinaryOp::kGreaterThan, "OpUGreaterThan", "bool"},
+ BinaryTestCase{kU32, core::BinaryOp::kGreaterThanEqual, "OpUGreaterThanEqual", "bool"},
+ BinaryTestCase{kU32, core::BinaryOp::kLessThan, "OpULessThan", "bool"},
+ BinaryTestCase{kU32, core::BinaryOp::kLessThanEqual, "OpULessThanEqual", "bool"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_F32,
Comparison,
testing::Values(
- BinaryTestCase{kF32, core::ir::BinaryOp::kEqual, "OpFOrdEqual", "bool"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kNotEqual, "OpFOrdNotEqual", "bool"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kGreaterThan, "OpFOrdGreaterThan", "bool"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kGreaterThanEqual, "OpFOrdGreaterThanEqual",
- "bool"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kLessThan, "OpFOrdLessThan", "bool"},
- BinaryTestCase{kF32, core::ir::BinaryOp::kLessThanEqual, "OpFOrdLessThanEqual", "bool"}));
+ BinaryTestCase{kF32, core::BinaryOp::kEqual, "OpFOrdEqual", "bool"},
+ BinaryTestCase{kF32, core::BinaryOp::kNotEqual, "OpFOrdNotEqual", "bool"},
+ BinaryTestCase{kF32, core::BinaryOp::kGreaterThan, "OpFOrdGreaterThan", "bool"},
+ BinaryTestCase{kF32, core::BinaryOp::kGreaterThanEqual, "OpFOrdGreaterThanEqual", "bool"},
+ BinaryTestCase{kF32, core::BinaryOp::kLessThan, "OpFOrdLessThan", "bool"},
+ BinaryTestCase{kF32, core::BinaryOp::kLessThanEqual, "OpFOrdLessThanEqual", "bool"}));
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Binary_F16,
Comparison,
testing::Values(
- BinaryTestCase{kF16, core::ir::BinaryOp::kEqual, "OpFOrdEqual", "bool"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kNotEqual, "OpFOrdNotEqual", "bool"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kGreaterThan, "OpFOrdGreaterThan", "bool"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kGreaterThanEqual, "OpFOrdGreaterThanEqual",
- "bool"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kLessThan, "OpFOrdLessThan", "bool"},
- BinaryTestCase{kF16, core::ir::BinaryOp::kLessThanEqual, "OpFOrdLessThanEqual", "bool"}));
-INSTANTIATE_TEST_SUITE_P(SpirvWriterTest_Binary_Bool,
- Comparison,
- testing::Values(BinaryTestCase{kBool, core::ir::BinaryOp::kEqual,
- "OpLogicalEqual", "bool"},
- BinaryTestCase{kBool, core::ir::BinaryOp::kNotEqual,
- "OpLogicalNotEqual", "bool"}));
+ BinaryTestCase{kF16, core::BinaryOp::kEqual, "OpFOrdEqual", "bool"},
+ BinaryTestCase{kF16, core::BinaryOp::kNotEqual, "OpFOrdNotEqual", "bool"},
+ BinaryTestCase{kF16, core::BinaryOp::kGreaterThan, "OpFOrdGreaterThan", "bool"},
+ BinaryTestCase{kF16, core::BinaryOp::kGreaterThanEqual, "OpFOrdGreaterThanEqual", "bool"},
+ BinaryTestCase{kF16, core::BinaryOp::kLessThan, "OpFOrdLessThan", "bool"},
+ BinaryTestCase{kF16, core::BinaryOp::kLessThanEqual, "OpFOrdLessThanEqual", "bool"}));
+INSTANTIATE_TEST_SUITE_P(
+ SpirvWriterTest_Binary_Bool,
+ Comparison,
+ testing::Values(BinaryTestCase{kBool, core::BinaryOp::kEqual, "OpLogicalEqual", "bool"},
+ BinaryTestCase{kBool, core::BinaryOp::kNotEqual, "OpLogicalNotEqual", "bool"}));
TEST_F(SpirvWriterTest, Binary_Chain) {
auto* func = b.Function("foo", ty.void_());
@@ -334,7 +360,7 @@
auto* func = b.Function("foo", ty.u32());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kDivide, ty.u32(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kDivide, ty.u32(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -370,7 +396,7 @@
auto* func = b.Function("foo", ty.i32());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kDivide, ty.i32(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kDivide, ty.i32(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -410,7 +436,7 @@
auto* func = b.Function("foo", ty.vec4<i32>());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kDivide, ty.vec4<i32>(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kDivide, ty.vec4<i32>(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -452,7 +478,7 @@
auto* func = b.Function("foo", ty.vec4<i32>());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kDivide, ty.vec4<i32>(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kDivide, ty.vec4<i32>(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -494,7 +520,7 @@
auto* func = b.Function("foo", ty.u32());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kModulo, ty.u32(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kModulo, ty.u32(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -532,7 +558,7 @@
auto* func = b.Function("foo", ty.i32());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kModulo, ty.i32(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kModulo, ty.i32(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -574,7 +600,7 @@
auto* func = b.Function("foo", ty.vec4<i32>());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kModulo, ty.vec4<i32>(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kModulo, ty.vec4<i32>(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
@@ -618,7 +644,7 @@
auto* func = b.Function("foo", ty.vec4<i32>());
func->SetParams(args);
b.Append(func->Block(), [&] {
- auto* result = b.Binary(core::ir::BinaryOp::kModulo, ty.vec4<i32>(), args[0], args[1]);
+ auto* result = b.Binary(core::BinaryOp::kModulo, ty.vec4<i32>(), args[0], args[1]);
b.Return(func, result);
mod.SetName(result, "result");
});
diff --git a/src/tint/lang/spirv/writer/common/helper_test.h b/src/tint/lang/spirv/writer/common/helper_test.h
index df4936e..1c08ab9 100644
--- a/src/tint/lang/spirv/writer/common/helper_test.h
+++ b/src/tint/lang/spirv/writer/common/helper_test.h
@@ -115,7 +115,7 @@
/// storage class with OpConstantNull
/// @returns true if generation and validation succeeded
bool Generate(Options options = {}, bool zero_init_workgroup_memory = false) {
- auto raised = raise::Raise(mod, options);
+ auto raised = Raise(mod, options);
if (raised != Success) {
err_ = raised.Failure().reason.str();
return false;
diff --git a/src/tint/lang/spirv/writer/common/options.h b/src/tint/lang/spirv/writer/common/options.h
index 2c8a117..79ec0e7 100644
--- a/src/tint/lang/spirv/writer/common/options.h
+++ b/src/tint/lang/spirv/writer/common/options.h
@@ -146,6 +146,9 @@
/// Set to `true` to generate polyfill for `dot4I8Packed` and `dot4U8Packed` builtins
bool polyfill_dot_4x8_packed = false;
+ /// Set to `true` to disable the polyfills on integer division and modulo.
+ bool disable_polyfill_integer_div_mod = false;
+
/// The bindings
Bindings bindings;
@@ -159,6 +162,7 @@
clamp_frag_depth,
experimental_require_subgroup_uniform_control_flow,
polyfill_dot_4x8_packed,
+ disable_polyfill_integer_div_mod,
bindings);
};
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index e5e9945..8eec980 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -879,8 +879,8 @@
Switch(
inst, //
[&](core::ir::Access* a) { EmitAccess(a); }, //
- [&](core::ir::Binary* b) { EmitBinary(b); }, //
[&](core::ir::Bitcast* b) { EmitBitcast(b); }, //
+ [&](core::ir::CoreBinary* b) { EmitBinary(b); }, //
[&](core::ir::CoreBuiltinCall* b) { EmitCoreBuiltinCall(b); }, //
[&](spirv::ir::BuiltinCall* b) { EmitSpirvBuiltinCall(b); }, //
[&](core::ir::Construct* c) { EmitConstruct(c); }, //
@@ -893,7 +893,7 @@
[&](core::ir::Store* s) { EmitStore(s); }, //
[&](core::ir::StoreVectorElement* s) { EmitStoreVectorElement(s); }, //
[&](core::ir::UserCall* c) { EmitUserCall(c); }, //
- [&](core::ir::Unary* u) { EmitUnary(u); }, //
+ [&](core::ir::CoreUnary* u) { EmitUnary(u); }, //
[&](core::ir::Var* v) { EmitVar(v); }, //
[&](core::ir::Let* l) { EmitLet(l); }, //
[&](core::ir::If* i) { EmitIf(i); }, //
@@ -1060,7 +1060,7 @@
/// Emit a binary instruction.
/// @param binary the binary instruction to emit
- void EmitBinary(core::ir::Binary* binary) {
+ void EmitBinary(core::ir::CoreBinary* binary) {
auto id = Value(binary);
auto lhs = Value(binary->LHS());
auto rhs = Value(binary->RHS());
@@ -1070,11 +1070,11 @@
// Determine the opcode.
spv::Op op = spv::Op::Max;
switch (binary->Op()) {
- case core::ir::BinaryOp::kAdd: {
+ case core::BinaryOp::kAdd: {
op = ty->is_integer_scalar_or_vector() ? spv::Op::OpIAdd : spv::Op::OpFAdd;
break;
}
- case core::ir::BinaryOp::kDivide: {
+ case core::BinaryOp::kDivide: {
if (ty->is_signed_integer_scalar_or_vector()) {
op = spv::Op::OpSDiv;
} else if (ty->is_unsigned_integer_scalar_or_vector()) {
@@ -1084,7 +1084,7 @@
}
break;
}
- case core::ir::BinaryOp::kMultiply: {
+ case core::BinaryOp::kMultiply: {
if (ty->is_integer_scalar_or_vector()) {
op = spv::Op::OpIMul;
} else if (ty->is_float_scalar_or_vector()) {
@@ -1092,11 +1092,11 @@
}
break;
}
- case core::ir::BinaryOp::kSubtract: {
+ case core::BinaryOp::kSubtract: {
op = ty->is_integer_scalar_or_vector() ? spv::Op::OpISub : spv::Op::OpFSub;
break;
}
- case core::ir::BinaryOp::kModulo: {
+ case core::BinaryOp::kModulo: {
if (ty->is_signed_integer_scalar_or_vector()) {
op = spv::Op::OpSRem;
} else if (ty->is_unsigned_integer_scalar_or_vector()) {
@@ -1107,7 +1107,7 @@
break;
}
- case core::ir::BinaryOp::kAnd: {
+ case core::BinaryOp::kAnd: {
if (ty->is_integer_scalar_or_vector()) {
op = spv::Op::OpBitwiseAnd;
} else if (ty->is_bool_scalar_or_vector()) {
@@ -1115,7 +1115,7 @@
}
break;
}
- case core::ir::BinaryOp::kOr: {
+ case core::BinaryOp::kOr: {
if (ty->is_integer_scalar_or_vector()) {
op = spv::Op::OpBitwiseOr;
} else if (ty->is_bool_scalar_or_vector()) {
@@ -1123,16 +1123,16 @@
}
break;
}
- case core::ir::BinaryOp::kXor: {
+ case core::BinaryOp::kXor: {
op = spv::Op::OpBitwiseXor;
break;
}
- case core::ir::BinaryOp::kShiftLeft: {
+ case core::BinaryOp::kShiftLeft: {
op = spv::Op::OpShiftLeftLogical;
break;
}
- case core::ir::BinaryOp::kShiftRight: {
+ case core::BinaryOp::kShiftRight: {
if (ty->is_signed_integer_scalar_or_vector()) {
op = spv::Op::OpShiftRightArithmetic;
} else if (ty->is_unsigned_integer_scalar_or_vector()) {
@@ -1141,7 +1141,7 @@
break;
}
- case core::ir::BinaryOp::kEqual: {
+ case core::BinaryOp::kEqual: {
if (lhs_ty->is_bool_scalar_or_vector()) {
op = spv::Op::OpLogicalEqual;
} else if (lhs_ty->is_float_scalar_or_vector()) {
@@ -1151,7 +1151,7 @@
}
break;
}
- case core::ir::BinaryOp::kNotEqual: {
+ case core::BinaryOp::kNotEqual: {
if (lhs_ty->is_bool_scalar_or_vector()) {
op = spv::Op::OpLogicalNotEqual;
} else if (lhs_ty->is_float_scalar_or_vector()) {
@@ -1161,7 +1161,7 @@
}
break;
}
- case core::ir::BinaryOp::kGreaterThan: {
+ case core::BinaryOp::kGreaterThan: {
if (lhs_ty->is_float_scalar_or_vector()) {
op = spv::Op::OpFOrdGreaterThan;
} else if (lhs_ty->is_signed_integer_scalar_or_vector()) {
@@ -1171,7 +1171,7 @@
}
break;
}
- case core::ir::BinaryOp::kGreaterThanEqual: {
+ case core::BinaryOp::kGreaterThanEqual: {
if (lhs_ty->is_float_scalar_or_vector()) {
op = spv::Op::OpFOrdGreaterThanEqual;
} else if (lhs_ty->is_signed_integer_scalar_or_vector()) {
@@ -1181,7 +1181,7 @@
}
break;
}
- case core::ir::BinaryOp::kLessThan: {
+ case core::BinaryOp::kLessThan: {
if (lhs_ty->is_float_scalar_or_vector()) {
op = spv::Op::OpFOrdLessThan;
} else if (lhs_ty->is_signed_integer_scalar_or_vector()) {
@@ -1191,7 +1191,7 @@
}
break;
}
- case core::ir::BinaryOp::kLessThanEqual: {
+ case core::BinaryOp::kLessThanEqual: {
if (lhs_ty->is_float_scalar_or_vector()) {
op = spv::Op::OpFOrdLessThanEqual;
} else if (lhs_ty->is_signed_integer_scalar_or_vector()) {
@@ -1201,6 +1201,9 @@
}
break;
}
+ default:
+ TINT_UNIMPLEMENTED() << binary->Op();
+ break;
}
// Emit the instruction.
@@ -1961,21 +1964,24 @@
/// Emit a unary instruction.
/// @param unary the unary instruction to emit
- void EmitUnary(core::ir::Unary* unary) {
+ void EmitUnary(core::ir::CoreUnary* unary) {
auto id = Value(unary);
auto* ty = unary->Result(0)->Type();
spv::Op op = spv::Op::Max;
switch (unary->Op()) {
- case core::ir::UnaryOp::kComplement:
+ case core::UnaryOp::kComplement:
op = spv::Op::OpNot;
break;
- case core::ir::UnaryOp::kNegation:
+ case core::UnaryOp::kNegation:
if (ty->is_float_scalar_or_vector()) {
op = spv::Op::OpFNegate;
} else if (ty->is_signed_integer_scalar_or_vector()) {
op = spv::Op::OpSNegate;
}
break;
+ default:
+ TINT_UNIMPLEMENTED() << unary->Op();
+ break;
}
current_function_.push_inst(op, {Type(ty), id, Value(unary->Val())});
}
diff --git a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc
index 083a98b..3385ad0 100644
--- a/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc
+++ b/src/tint/lang/spirv/writer/raise/expand_implicit_splats.cc
@@ -46,7 +46,7 @@
// Find the instructions that use implicit splats and either modify them in place or record them
// to be replaced in a second pass.
- Vector<core::ir::Binary*, 4> binary_worklist;
+ Vector<core::ir::CoreBinary*, 4> binary_worklist;
Vector<core::ir::CoreBuiltinCall*, 4> builtin_worklist;
for (auto* inst : ir.instructions.Objects()) {
if (!inst->Alive()) {
@@ -63,7 +63,7 @@
construct->AppendArg(construct->Args()[0]);
}
}
- } else if (auto* binary = inst->As<core::ir::Binary>()) {
+ } else if (auto* binary = inst->As<core::ir::CoreBinary>()) {
// A binary instruction that mixes vector and scalar operands needs to have the scalar
// operand replaced with an explicit vector constructor.
if (binary->Result(0)->Type()->Is<core::type::Vector>()) {
@@ -101,7 +101,7 @@
// Replace scalar operands to binary instructions that produce vectors.
for (auto* binary : binary_worklist) {
auto* result_ty = binary->Result(0)->Type();
- if (result_ty->is_float_vector() && binary->Op() == core::ir::BinaryOp::kMultiply) {
+ if (result_ty->is_float_vector() && binary->Op() == core::BinaryOp::kMultiply) {
// Use OpVectorTimesScalar for floating point multiply.
auto* vts =
b.Call<spirv::ir::BuiltinCall>(result_ty, spirv::BuiltinFn::kVectorTimesScalar);
@@ -121,9 +121,9 @@
} else {
// Expand the scalar argument into an explicitly constructed vector.
if (binary->LHS()->Type()->Is<core::type::Scalar>()) {
- expand_operand(binary, core::ir::Binary::kLhsOperandOffset);
+ expand_operand(binary, core::ir::CoreBinary::kLhsOperandOffset);
} else if (binary->RHS()->Type()->Is<core::type::Scalar>()) {
- expand_operand(binary, core::ir::Binary::kRhsOperandOffset);
+ expand_operand(binary, core::ir::CoreBinary::kRhsOperandOffset);
}
}
}
diff --git a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc
index 6be5daf..3e77d21 100644
--- a/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc
+++ b/src/tint/lang/spirv/writer/raise/handle_matrix_arithmetic.cc
@@ -48,13 +48,13 @@
core::ir::Builder b{ir};
// Find the instructions that need to be modified.
- Vector<core::ir::Binary*, 4> binary_worklist;
+ Vector<core::ir::CoreBinary*, 4> binary_worklist;
Vector<core::ir::Convert*, 4> convert_worklist;
for (auto* inst : ir.instructions.Objects()) {
if (!inst->Alive()) {
continue;
}
- if (auto* binary = inst->As<core::ir::Binary>()) {
+ if (auto* binary = inst->As<core::ir::CoreBinary>()) {
TINT_ASSERT(binary->Operands().Length() == 2);
if (binary->LHS()->Type()->Is<core::type::Matrix>() ||
binary->RHS()->Type()->Is<core::type::Matrix>()) {
@@ -101,13 +101,13 @@
};
switch (binary->Op()) {
- case core::ir::BinaryOp::kAdd:
- column_wise(core::ir::BinaryOp::kAdd);
+ case core::BinaryOp::kAdd:
+ column_wise(core::BinaryOp::kAdd);
break;
- case core::ir::BinaryOp::kSubtract:
- column_wise(core::ir::BinaryOp::kSubtract);
+ case core::BinaryOp::kSubtract:
+ column_wise(core::BinaryOp::kSubtract);
break;
- case core::ir::BinaryOp::kMultiply:
+ case core::BinaryOp::kMultiply:
// Select the SPIR-V intrinsic that corresponds to the operation being performed.
if (lhs_ty->Is<core::type::Matrix>()) {
if (rhs_ty->Is<core::type::Scalar>()) {
diff --git a/src/tint/lang/spirv/writer/raise/raise.cc b/src/tint/lang/spirv/writer/raise/raise.cc
index 1c88637..6372390 100644
--- a/src/tint/lang/spirv/writer/raise/raise.cc
+++ b/src/tint/lang/spirv/writer/raise/raise.cc
@@ -54,7 +54,7 @@
#include "src/tint/lang/spirv/writer/raise/shader_io.h"
#include "src/tint/lang/spirv/writer/raise/var_for_dynamic_index.h"
-namespace tint::spirv::writer::raise {
+namespace tint::spirv::writer {
Result<SuccessType> Raise(core::ir::Module& module, const Options& options) {
#define RUN_TRANSFORM(name, ...) \
@@ -73,7 +73,7 @@
core::ir::transform::BinaryPolyfillConfig binary_polyfills;
binary_polyfills.bitshift_modulo = true;
- binary_polyfills.int_div_mod = true;
+ binary_polyfills.int_div_mod = !options.disable_polyfill_integer_div_mod;
RUN_TRANSFORM(core::ir::transform::BinaryPolyfill, module, binary_polyfills);
core::ir::transform::BuiltinPolyfillConfig core_polyfills;
@@ -86,6 +86,7 @@
core_polyfills.insert_bits = core::ir::transform::BuiltinPolyfillLevel::kClampOrRangeCheck;
core_polyfills.saturate = true;
core_polyfills.texture_sample_base_clamp_to_edge_2d_f32 = true;
+ core_polyfills.dot_4x8_packed = options.polyfill_dot_4x8_packed;
core_polyfills.pack_unpack_4x8 = true;
RUN_TRANSFORM(core::ir::transform::BuiltinPolyfill, module, core_polyfills);
@@ -121,7 +122,7 @@
if (options.pass_matrix_by_pointer) {
// PassMatrixByPointer must come after PreservePadding+DirectVariableAccess.
- RUN_TRANSFORM(PassMatrixByPointer, module);
+ RUN_TRANSFORM(raise::PassMatrixByPointer, module);
}
RUN_TRANSFORM(core::ir::transform::AddEmptyEntryPoint, module);
@@ -137,16 +138,16 @@
// DemoteToHelper must come before any transform that introduces non-core instructions.
RUN_TRANSFORM(core::ir::transform::DemoteToHelper, module);
- RUN_TRANSFORM(BuiltinPolyfill, module);
- RUN_TRANSFORM(ExpandImplicitSplats, module);
- RUN_TRANSFORM(HandleMatrixArithmetic, module);
- RUN_TRANSFORM(MergeReturn, module);
- RUN_TRANSFORM(ShaderIO, module,
- ShaderIOConfig{options.clamp_frag_depth, options.emit_vertex_point_size});
+ RUN_TRANSFORM(raise::BuiltinPolyfill, module);
+ RUN_TRANSFORM(raise::ExpandImplicitSplats, module);
+ RUN_TRANSFORM(raise::HandleMatrixArithmetic, module);
+ RUN_TRANSFORM(raise::MergeReturn, module);
+ RUN_TRANSFORM(raise::ShaderIO, module,
+ raise::ShaderIOConfig{options.clamp_frag_depth, options.emit_vertex_point_size});
RUN_TRANSFORM(core::ir::transform::Std140, module);
- RUN_TRANSFORM(VarForDynamicIndex, module);
+ RUN_TRANSFORM(raise::VarForDynamicIndex, module);
return Success;
}
-} // namespace tint::spirv::writer::raise
+} // namespace tint::spirv::writer
diff --git a/src/tint/lang/spirv/writer/raise/raise.h b/src/tint/lang/spirv/writer/raise/raise.h
index ba6270d..64854f3 100644
--- a/src/tint/lang/spirv/writer/raise/raise.h
+++ b/src/tint/lang/spirv/writer/raise/raise.h
@@ -39,7 +39,7 @@
class Module;
}
-namespace tint::spirv::writer::raise {
+namespace tint::spirv::writer {
/// Raise a core IR module to the SPIR-V dialect of the IR.
/// @param module the core IR module to raise to SPIR-V dialect
@@ -47,6 +47,6 @@
/// @returns success or failure
Result<SuccessType> Raise(core::ir::Module& module, const Options& options);
-} // namespace tint::spirv::writer::raise
+} // namespace tint::spirv::writer
#endif // SRC_TINT_LANG_SPIRV_WRITER_RAISE_RAISE_H_
diff --git a/src/tint/lang/spirv/writer/unary_test.cc b/src/tint/lang/spirv/writer/unary_test.cc
index 72fff71..43fb04e 100644
--- a/src/tint/lang/spirv/writer/unary_test.cc
+++ b/src/tint/lang/spirv/writer/unary_test.cc
@@ -39,7 +39,7 @@
/// The element type to test.
TestElementType type;
/// The unary operation.
- enum core::ir::UnaryOp op;
+ core::UnaryOp op;
/// The expected SPIR-V instruction.
std::string spirv_inst;
/// The expected SPIR-V result type name.
@@ -80,11 +80,11 @@
INSTANTIATE_TEST_SUITE_P(
SpirvWriterTest_Unary,
Arithmetic,
- testing::Values(UnaryTestCase{kI32, core::ir::UnaryOp::kComplement, "OpNot", "int"},
- UnaryTestCase{kU32, core::ir::UnaryOp::kComplement, "OpNot", "uint"},
- UnaryTestCase{kI32, core::ir::UnaryOp::kNegation, "OpSNegate", "int"},
- UnaryTestCase{kF32, core::ir::UnaryOp::kNegation, "OpFNegate", "float"},
- UnaryTestCase{kF16, core::ir::UnaryOp::kNegation, "OpFNegate", "half"}));
+ testing::Values(UnaryTestCase{kI32, core::UnaryOp::kComplement, "OpNot", "int"},
+ UnaryTestCase{kU32, core::UnaryOp::kComplement, "OpNot", "uint"},
+ UnaryTestCase{kI32, core::UnaryOp::kNegation, "OpSNegate", "int"},
+ UnaryTestCase{kF32, core::UnaryOp::kNegation, "OpFNegate", "float"},
+ UnaryTestCase{kF16, core::UnaryOp::kNegation, "OpFNegate", "half"}));
} // namespace
} // namespace tint::spirv::writer
diff --git a/src/tint/lang/spirv/writer/writer.cc b/src/tint/lang/spirv/writer/writer.cc
index a605c36..88f8233 100644
--- a/src/tint/lang/spirv/writer/writer.cc
+++ b/src/tint/lang/spirv/writer/writer.cc
@@ -54,7 +54,7 @@
Output output;
// Raise from core-dialect to SPIR-V-dialect.
- if (auto res = raise::Raise(ir, options); res != Success) {
+ if (auto res = Raise(ir, options); res != Success) {
return std::move(res.Failure());
}
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/spirv/writer/writer_ast_fuzz.cc
similarity index 69%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/spirv/writer/writer_ast_fuzz.cc
index 421db7b..8a7d6e9 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/spirv/writer/writer_ast_fuzz.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,27 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+// GEN_BUILD:CONDITION(tint_build_wgsl_reader)
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/cmd/fuzz/wgsl/fuzz.h"
+#include "src/tint/lang/spirv/writer/helpers/ast_generate_bindings.h"
+#include "src/tint/lang/spirv/writer/writer.h"
+#include "src/tint/lang/wgsl/ast/module.h"
namespace tint::spirv::writer {
namespace {
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
+void ASTFuzzer(const tint::Program& program, Options options) {
+ if (program.AST().HasOverrides()) {
return;
}
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
- }
+
+ options.bindings = GenerateBindings(program);
+
+ [[maybe_unused]] auto res = tint::spirv::writer::Generate(program, options);
}
} // namespace
} // namespace tint::spirv::writer
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+TINT_WGSL_PROGRAM_FUZZER(tint::spirv::writer::ASTFuzzer);
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/spirv/writer/writer_ir_fuzz.cc
similarity index 94%
rename from src/tint/lang/spirv/writer/writer_fuzz.cc
rename to src/tint/lang/spirv/writer/writer_ir_fuzz.cc
index 421db7b..dcc848c 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/spirv/writer/writer_ir_fuzz.cc
@@ -34,7 +34,7 @@
namespace tint::spirv::writer {
namespace {
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
+void IRFuzzer(core::ir::Module& module, Options options) {
options.bindings = GenerateBindings(module);
auto output = Generate(module, options);
if (output != Success) {
@@ -51,4 +51,4 @@
} // namespace
} // namespace tint::spirv::writer
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRFuzzer);
diff --git a/src/tint/lang/wgsl/BUILD.bazel b/src/tint/lang/wgsl/BUILD.bazel
index f30a202..b945e60 100644
--- a/src/tint/lang/wgsl/BUILD.bazel
+++ b/src/tint/lang/wgsl/BUILD.bazel
@@ -94,12 +94,10 @@
"//src/tint/lang/wgsl/ast",
"//src/tint/lang/wgsl/common",
"//src/tint/lang/wgsl/features",
- "//src/tint/lang/wgsl/helpers:test",
"//src/tint/lang/wgsl/program",
- "//src/tint/lang/wgsl/reader/lower",
- "//src/tint/lang/wgsl/resolver",
"//src/tint/lang/wgsl/sem",
"//src/tint/lang/wgsl/writer/ir_to_program",
+ "//src/tint/lang/wgsl/writer/raise",
"//src/tint/utils/containers",
"//src/tint/utils/diagnostic",
"//src/tint/utils/ice",
diff --git a/src/tint/lang/wgsl/BUILD.cmake b/src/tint/lang/wgsl/BUILD.cmake
index 17f4d73..63b67a8 100644
--- a/src/tint/lang/wgsl/BUILD.cmake
+++ b/src/tint/lang/wgsl/BUILD.cmake
@@ -97,12 +97,10 @@
tint_lang_wgsl_ast
tint_lang_wgsl_common
tint_lang_wgsl_features
- tint_lang_wgsl_helpers_test
tint_lang_wgsl_program
- tint_lang_wgsl_reader_lower
- tint_lang_wgsl_resolver
tint_lang_wgsl_sem
tint_lang_wgsl_writer_ir_to_program
+ tint_lang_wgsl_writer_raise
tint_utils_containers
tint_utils_diagnostic
tint_utils_ice
diff --git a/src/tint/lang/wgsl/BUILD.gn b/src/tint/lang/wgsl/BUILD.gn
index 1b7590c..c63b21c 100644
--- a/src/tint/lang/wgsl/BUILD.gn
+++ b/src/tint/lang/wgsl/BUILD.gn
@@ -86,12 +86,10 @@
"${tint_src_dir}/lang/wgsl/ast",
"${tint_src_dir}/lang/wgsl/common",
"${tint_src_dir}/lang/wgsl/features",
- "${tint_src_dir}/lang/wgsl/helpers:unittests",
"${tint_src_dir}/lang/wgsl/program",
- "${tint_src_dir}/lang/wgsl/reader/lower",
- "${tint_src_dir}/lang/wgsl/resolver",
"${tint_src_dir}/lang/wgsl/sem",
"${tint_src_dir}/lang/wgsl/writer/ir_to_program",
+ "${tint_src_dir}/lang/wgsl/writer/raise",
"${tint_src_dir}/utils/containers",
"${tint_src_dir}/utils/diagnostic",
"${tint_src_dir}/utils/ice",
diff --git a/src/tint/lang/wgsl/intrinsic/BUILD.bazel b/src/tint/lang/wgsl/intrinsic/BUILD.bazel
index be578ca..bfb10a6 100644
--- a/src/tint/lang/wgsl/intrinsic/BUILD.bazel
+++ b/src/tint/lang/wgsl/intrinsic/BUILD.bazel
@@ -59,6 +59,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/symbol",
diff --git a/src/tint/lang/wgsl/intrinsic/BUILD.cmake b/src/tint/lang/wgsl/intrinsic/BUILD.cmake
index f77068d..275c8b0 100644
--- a/src/tint/lang/wgsl/intrinsic/BUILD.cmake
+++ b/src/tint/lang/wgsl/intrinsic/BUILD.cmake
@@ -58,6 +58,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_symbol
diff --git a/src/tint/lang/wgsl/intrinsic/BUILD.gn b/src/tint/lang/wgsl/intrinsic/BUILD.gn
index 61a2bb1..bae4bd0 100644
--- a/src/tint/lang/wgsl/intrinsic/BUILD.gn
+++ b/src/tint/lang/wgsl/intrinsic/BUILD.gn
@@ -58,6 +58,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/symbol",
diff --git a/src/tint/lang/wgsl/ir/BUILD.bazel b/src/tint/lang/wgsl/ir/BUILD.bazel
index e764df7..259b851 100644
--- a/src/tint/lang/wgsl/ir/BUILD.bazel
+++ b/src/tint/lang/wgsl/ir/BUILD.bazel
@@ -40,9 +40,11 @@
name = "ir",
srcs = [
"builtin_call.cc",
+ "unary.cc",
],
hdrs = [
"builtin_call.h",
+ "unary.h",
],
deps = [
"//src/tint/api/common",
diff --git a/src/tint/lang/wgsl/ir/BUILD.cmake b/src/tint/lang/wgsl/ir/BUILD.cmake
index f41c7a4..d0192da 100644
--- a/src/tint/lang/wgsl/ir/BUILD.cmake
+++ b/src/tint/lang/wgsl/ir/BUILD.cmake
@@ -41,6 +41,8 @@
tint_add_target(tint_lang_wgsl_ir lib
lang/wgsl/ir/builtin_call.cc
lang/wgsl/ir/builtin_call.h
+ lang/wgsl/ir/unary.cc
+ lang/wgsl/ir/unary.h
)
tint_target_add_dependencies(tint_lang_wgsl_ir lib
diff --git a/src/tint/lang/wgsl/ir/BUILD.gn b/src/tint/lang/wgsl/ir/BUILD.gn
index 462ecfa..1194bb7 100644
--- a/src/tint/lang/wgsl/ir/BUILD.gn
+++ b/src/tint/lang/wgsl/ir/BUILD.gn
@@ -42,6 +42,8 @@
sources = [
"builtin_call.cc",
"builtin_call.h",
+ "unary.cc",
+ "unary.h",
]
deps = [
"${tint_src_dir}/api/common",
diff --git a/src/tint/lang/spirv/writer/writer_fuzz.cc b/src/tint/lang/wgsl/ir/unary.cc
similarity index 62%
copy from src/tint/lang/spirv/writer/writer_fuzz.cc
copy to src/tint/lang/wgsl/ir/unary.cc
index 421db7b..f8c90f3 100644
--- a/src/tint/lang/spirv/writer/writer_fuzz.cc
+++ b/src/tint/lang/wgsl/ir/unary.cc
@@ -1,4 +1,4 @@
-// Copyright 2023 The Dawn & Tint Authors
+// Copyright 2024 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
@@ -25,30 +25,31 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include "src/tint/lang/spirv/writer/writer.h"
+#include "src/tint/lang/wgsl/ir/unary.h"
-#include "src/tint/cmd/fuzz/ir/fuzz.h"
-#include "src/tint/lang/spirv/validate/validate.h"
-#include "src/tint/lang/spirv/writer/helpers/generate_bindings.h"
+#include "src/tint/lang/core/ir/clone_context.h"
+#include "src/tint/lang/core/ir/module.h"
+#include "src/tint/lang/wgsl/intrinsic/dialect.h"
-namespace tint::spirv::writer {
-namespace {
+TINT_INSTANTIATE_TYPEINFO(tint::wgsl::ir::Unary);
-void IRPrinterFuzzer(core::ir::Module& module, Options options) {
- options.bindings = GenerateBindings(module);
- auto output = Generate(module, options);
- if (output != Success) {
- return;
- }
- auto& spirv = output->spirv;
- if (auto res = validate::Validate(Slice(spirv.data(), spirv.size()), SPV_ENV_VULKAN_1_1);
- res != Success) {
- TINT_ICE() << "Output of SPIR-V writer failed to validate with SPIR-V Tools\n"
- << res.Failure();
- }
+namespace tint::wgsl::ir {
+
+Unary::Unary() = default;
+
+Unary::Unary(core::ir::InstructionResult* result, core::UnaryOp op, core::ir::Value* val)
+ : Base(result, op, val) {}
+
+Unary::~Unary() = default;
+
+Unary* Unary::Clone(core::ir::CloneContext& ctx) {
+ auto* new_result = ctx.Clone(Result(0));
+ auto* val = ctx.Remap(Val());
+ return ctx.ir.instructions.Create<Unary>(new_result, Op(), val);
}
-} // namespace
-} // namespace tint::spirv::writer
+const core::intrinsic::TableData& Unary::TableData() const {
+ return wgsl::intrinsic::Dialect::kData;
+}
-TINT_IR_MODULE_FUZZER(tint::spirv::writer::IRPrinterFuzzer);
+} // namespace tint::wgsl::ir
diff --git a/src/tint/lang/wgsl/ir/unary.h b/src/tint/lang/wgsl/ir/unary.h
new file mode 100644
index 0000000..9fbeeea
--- /dev/null
+++ b/src/tint/lang/wgsl/ir/unary.h
@@ -0,0 +1,60 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_LANG_WGSL_IR_UNARY_H_
+#define SRC_TINT_LANG_WGSL_IR_UNARY_H_
+
+#include "src/tint/lang/core/ir/unary.h"
+
+namespace tint::wgsl::ir {
+
+/// A WGSL-dialect unary instruction in the IR.
+class Unary final : public Castable<Unary, core::ir::Unary> {
+ public:
+ /// The offset in Operands() for the value
+ static constexpr size_t kValueOperandOffset = 0;
+
+ /// Constructor (no results, no operands)
+ Unary();
+
+ /// Constructor
+ /// @param result the result value
+ /// @param op the unary operator
+ /// @param val the input value for the instruction
+ Unary(core::ir::InstructionResult* result, core::UnaryOp op, core::ir::Value* val);
+ ~Unary() override;
+
+ /// @copydoc core::ir::Instruction::Clone()
+ Unary* Clone(core::ir::CloneContext& ctx) override;
+
+ /// @returns the table data to validate this builtin
+ const core::intrinsic::TableData& TableData() const override;
+};
+
+} // namespace tint::wgsl::ir
+
+#endif // SRC_TINT_LANG_WGSL_IR_UNARY_H_
diff --git a/src/tint/lang/wgsl/ir_roundtrip_test.cc b/src/tint/lang/wgsl/ir_roundtrip_test.cc
index ab1b3d6..d3497d0 100644
--- a/src/tint/lang/wgsl/ir_roundtrip_test.cc
+++ b/src/tint/lang/wgsl/ir_roundtrip_test.cc
@@ -27,10 +27,13 @@
// GEN_BUILD:CONDITION(tint_build_wgsl_reader && tint_build_wgsl_writer)
-#include "src/tint/lang/wgsl/helpers/ir_program_test.h"
+#include "gtest/gtest.h"
+
+#include "src/tint/lang/core/ir/disassembler.h"
#include "src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.h"
#include "src/tint/lang/wgsl/reader/reader.h"
#include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.h"
+#include "src/tint/lang/wgsl/writer/raise/raise.h"
#include "src/tint/lang/wgsl/writer/writer.h"
#include "src/tint/utils/text/string.h"
@@ -39,60 +42,146 @@
using namespace tint::core::number_suffixes; // NOLINT
-class IRToProgramRoundtripTest : public helpers::IRProgramTest {
+class IRToProgramRoundtripTest : public testing::Test {
public:
- void Test(std::string_view input_wgsl, std::string_view expected_wgsl) {
+ struct Result {
+ /// The resulting WGSL
+ std::string wgsl;
+ /// The resulting AST
+ std::string ast;
+ /// The resulting IR before raising
+ std::string ir_pre_raise;
+ /// The resulting IR after raising
+ std::string ir_post_raise;
+ /// The resulting error
+ std::string err;
+ /// The expected WGSL
+ std::string expected;
+ };
+
+ /// @return the round-tripped string and the expected string
+ Result Run(std::string input_wgsl, std::string expected_wgsl) {
+ std::string input{tint::TrimSpace(input_wgsl)};
+
+ Result result;
+
wgsl::reader::Options options;
options.allowed_features = wgsl::AllowedFeatures::Everything();
- auto input = tint::TrimSpace(input_wgsl);
Source::File file("test.wgsl", std::string(input));
auto ir_module = wgsl::reader::WgslToIR(&file, options);
- ASSERT_EQ(ir_module, Success);
+ if (ir_module != Success) {
+ return result;
+ }
- auto disassembly = tint::core::ir::Disassemble(ir_module.Get());
+ result.ir_pre_raise = core::ir::Disassemble(ir_module.Get());
+
+ if (auto res = tint::wgsl::writer::Raise(ir_module.Get()); res != Success) {
+ result.err = res.Failure().reason.str();
+ return result;
+ }
+
+ result.ir_post_raise = core::ir::Disassemble(ir_module.Get());
writer::ProgramOptions program_options;
program_options.allowed_features = AllowedFeatures::Everything();
- auto output = wgsl::writer::WgslFromIR(ir_module.Get(), program_options);
- if (output != Success) {
- FAIL() << output.Failure() << std::endl //
- << "IR:" << std::endl //
- << disassembly << std::endl;
+ auto output_program = wgsl::writer::IRToProgram(ir_module.Get(), program_options);
+ if (!output_program.IsValid()) {
+ result.err = output_program.Diagnostics().str();
+ result.ast = Program::printer(output_program);
+ return result;
}
- auto expected = expected_wgsl.empty() ? input : tint::TrimSpace(expected_wgsl);
- auto got = tint::TrimSpace(output->wgsl);
- EXPECT_EQ(expected, got) << "IR:" << std::endl << disassembly;
+ auto output = wgsl::writer::Generate(output_program, {});
+ if (output != Success) {
+ std::stringstream ss;
+ ss << "wgsl::Generate() errored: " << output.Failure();
+ result.err = ss.str();
+ result.ast = Program::printer(output_program);
+ return result;
+ }
+
+ result.expected = expected_wgsl.empty() ? input : tint::TrimSpace(expected_wgsl);
+ if (!result.expected.empty()) {
+ result.expected = "\n" + result.expected + "\n";
+ }
+
+ result.wgsl = std::string(tint::TrimSpace(output->wgsl));
+ if (!result.wgsl.empty()) {
+ result.wgsl = "\n" + result.wgsl + "\n";
+ }
+
+ return result;
}
- void Test(std::string_view wgsl) { Test(wgsl, wgsl); }
+ Result Run(std::string wgsl) { return Run(wgsl, wgsl); }
};
+std::ostream& operator<<(std::ostream& o, const IRToProgramRoundtripTest::Result& res) {
+ if (!res.err.empty()) {
+ o << "============================" << std::endl
+ << "== Error ==" << std::endl
+ << "============================" << std::endl
+ << res.err << std::endl
+ << std::endl;
+ }
+ if (!res.ir_pre_raise.empty()) {
+ o << "============================" << std::endl
+ << "== IR (pre-raise) ==" << std::endl
+ << "============================" << std::endl
+ << res.ir_pre_raise << std::endl
+ << std::endl;
+ }
+ if (!res.ir_post_raise.empty()) {
+ o << "============================" << std::endl
+ << "== IR (post-raise) ==" << std::endl
+ << "============================" << std::endl
+ << res.ir_post_raise << std::endl
+ << std::endl;
+ }
+ if (!res.ast.empty()) {
+ o << "============================" << std::endl
+ << "== AST ==" << std::endl
+ << "============================" << std::endl
+ << res.ast << std::endl
+ << std::endl;
+ }
+ return o;
+}
+
+#define RUN_TEST(...) \
+ do { \
+ if (auto res = Run(__VA_ARGS__); res.err.empty()) { \
+ EXPECT_EQ(res.expected, res.wgsl) << res; \
+ } else { \
+ FAIL() << res; \
+ } \
+ } while (false)
+
TEST_F(IRToProgramRoundtripTest, EmptyModule) {
- Test("");
+ RUN_TEST("");
}
TEST_F(IRToProgramRoundtripTest, SingleFunction_Empty) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
}
)");
}
TEST_F(IRToProgramRoundtripTest, SingleFunction_Return) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
return;
}
)",
- R"(
+ R"(
fn f() {
}
)");
}
TEST_F(IRToProgramRoundtripTest, SingleFunction_Return_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
return 42i;
}
@@ -100,7 +189,7 @@
}
TEST_F(IRToProgramRoundtripTest, SingleFunction_Parameters) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32, u : u32) -> i32 {
return i;
}
@@ -111,7 +200,7 @@
// Struct declaration
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, StructDecl_Scalars) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
b : u32,
@@ -123,7 +212,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberAlign) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@align(32u)
@@ -136,7 +225,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberSize) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@size(32u)
@@ -149,7 +238,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberLocation) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@location(1u)
@@ -162,7 +251,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberIndex) {
- Test(R"(
+ RUN_TEST(R"(
enable chromium_internal_dual_source_blending;
struct S {
@@ -177,7 +266,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberBuiltin) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@builtin(position)
@@ -190,7 +279,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberInterpolateType) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@location(1u) @interpolate(flat)
@@ -203,7 +292,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberInterpolateTypeSampling) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@location(1u) @interpolate(perspective, centroid)
@@ -216,7 +305,7 @@
}
TEST_F(IRToProgramRoundtripTest, StructDecl_MemberInvariant) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
@builtin(position) @invariant
@@ -232,7 +321,7 @@
// Function Call
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, FnCall_NoArgs_NoRet) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -243,7 +332,7 @@
}
TEST_F(IRToProgramRoundtripTest, FnCall_NoArgs_Ret_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> i32 {
return 1i;
}
@@ -255,7 +344,7 @@
}
TEST_F(IRToProgramRoundtripTest, FnCall_3Args_NoRet) {
- Test(R"(
+ RUN_TEST(R"(
fn a(x : i32, y : u32, z : f32) {
}
@@ -266,7 +355,7 @@
}
TEST_F(IRToProgramRoundtripTest, FnCall_3Args_Ret_f32) {
- Test(R"(
+ RUN_TEST(R"(
fn a(x : i32, y : u32, z : f32) -> f32 {
return z;
}
@@ -278,7 +367,7 @@
}
TEST_F(IRToProgramRoundtripTest, FnCall_PtrArgs) {
- Test(R"(
+ RUN_TEST(R"(
var<private> y : i32 = 2i;
fn a(px : ptr<function, i32>, py : ptr<private, i32>) -> i32 {
@@ -296,7 +385,7 @@
// Core Builtin Call
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, CoreBuiltinCall_Stmt) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
workgroupBarrier();
}
@@ -304,7 +393,7 @@
}
TEST_F(IRToProgramRoundtripTest, CoreBuiltinCall_Expr) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) {
var i : i32 = max(a, b);
}
@@ -312,7 +401,7 @@
}
TEST_F(IRToProgramRoundtripTest, CoreBuiltinCall_PhonyAssignment) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) {
_ = max(a, b);
}
@@ -320,7 +409,7 @@
}
TEST_F(IRToProgramRoundtripTest, CoreBuiltinCall_UnusedLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) {
let unused = max(a, b);
}
@@ -328,7 +417,7 @@
}
TEST_F(IRToProgramRoundtripTest, CoreBuiltinCall_PtrArg) {
- Test(R"(
+ RUN_TEST(R"(
@group(0) @binding(0) var<storage, read> v : array<u32>;
fn foo() -> u32 {
@@ -338,13 +427,13 @@
}
TEST_F(IRToProgramRoundtripTest, CoreBuiltinCall_DisableDerivativeUniformity) {
- Test(R"(
+ RUN_TEST(R"(
fn f(in : f32) {
let x = dpdx(in);
let y = dpdy(in);
}
)",
- R"(
+ R"(
diagnostic(off, derivative_uniformity);
fn f(in : f32) {
@@ -358,7 +447,7 @@
// Type Construct
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, TypeConstruct_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) {
var v : i32 = i32(i);
}
@@ -366,7 +455,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_u32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : u32) {
var v : u32 = u32(i);
}
@@ -374,7 +463,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_f32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : f32) {
var v : f32 = f32(i);
}
@@ -382,7 +471,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_bool) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : bool) {
var v : bool = bool(i);
}
@@ -390,7 +479,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_struct) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
b : u32,
@@ -404,7 +493,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_array) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) {
var v : array<i32, 3u> = array<i32, 3u>(i, i, i);
}
@@ -412,7 +501,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_vec3i_Splat) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) {
var v : vec3<i32> = vec3<i32>(i);
}
@@ -420,7 +509,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_vec3i_Scalars) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) {
var v : vec3<i32> = vec3<i32>(i, i, i);
}
@@ -428,7 +517,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_mat2x3f_Scalars) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : f32) {
var v : mat2x3<f32> = mat2x3<f32>(i, i, i, i, i, i);
}
@@ -436,7 +525,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConstruct_mat2x3f_Columns) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : f32) {
var v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(i, i, i), vec3<f32>(i, i, i));
}
@@ -447,7 +536,7 @@
// Type Convert
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, TypeConvert_i32_to_u32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) {
var v : u32 = u32(i);
}
@@ -455,7 +544,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConvert_u32_to_f32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : u32) {
var v : f32 = f32(i);
}
@@ -463,7 +552,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConvert_f32_to_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : f32) {
var v : i32 = i32(i);
}
@@ -471,7 +560,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConvert_bool_to_u32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : bool) {
var v : u32 = u32(i);
}
@@ -479,7 +568,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConvert_vec3i_to_vec3u) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : vec3<i32>) {
var v : vec3<u32> = vec3<u32>(i);
}
@@ -487,7 +576,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConvert_vec3u_to_vec3f) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : vec3<u32>) {
var v : vec3<f32> = vec3<f32>(i);
}
@@ -495,7 +584,7 @@
}
TEST_F(IRToProgramRoundtripTest, TypeConvert_mat2x3f_to_mat2x3h) {
- Test(R"(
+ RUN_TEST(R"(
enable f16;
fn f(i : mat2x3<f32>) {
@@ -508,7 +597,7 @@
// Bitcast
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Bitcast_i32_to_u32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) {
var v : u32 = bitcast<u32>(i);
}
@@ -516,7 +605,7 @@
}
TEST_F(IRToProgramRoundtripTest, Bitcast_u32_to_f32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : u32) {
var v : f32 = bitcast<f32>(i);
}
@@ -524,7 +613,7 @@
}
TEST_F(IRToProgramRoundtripTest, Bitcast_f32_to_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : f32) {
var v : i32 = bitcast<i32>(i);
}
@@ -535,7 +624,7 @@
// Discard
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Discard) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
discard;
}
@@ -546,12 +635,12 @@
// Access
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Access_Value_vec3f_1) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> f32 {
return v[1];
}
)",
- R"(
+ R"(
fn f(v : vec3<f32>) -> f32 {
return v.y;
}
@@ -559,14 +648,14 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_vec3f_1) {
- Test(R"(
+ RUN_TEST(R"(
var<private> v : vec3<f32>;
fn f() -> f32 {
return v[1];
}
)",
- R"(
+ R"(
var<private> v : vec3<f32>;
fn f() -> f32 {
@@ -576,7 +665,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_vec3f_z) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> f32 {
return v.z;
}
@@ -584,7 +673,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_vec3f_z) {
- Test(R"(
+ RUN_TEST(R"(
var<private> v : vec3<f32>;
fn f() -> f32 {
@@ -594,12 +683,12 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_vec3f_g) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> f32 {
return v.g;
}
)",
- R"(
+ R"(
fn f(v : vec3<f32>) -> f32 {
return v.y;
}
@@ -607,14 +696,14 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_vec3f_g) {
- Test(R"(
+ RUN_TEST(R"(
var<private> v : vec3<f32>;
fn f() -> f32 {
return v.g;
}
)",
- R"(
+ R"(
var<private> v : vec3<f32>;
fn f() -> f32 {
@@ -624,7 +713,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_vec3f_i) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>, i : i32) -> f32 {
return v[i];
}
@@ -632,7 +721,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_vec3f_i) {
- Test(R"(
+ RUN_TEST(R"(
var<private> v : vec3<f32>;
fn f(i : i32) -> f32 {
@@ -642,12 +731,12 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_mat3x2f_1_0) {
- Test(R"(
+ RUN_TEST(R"(
fn f(m : mat3x2<f32>) -> f32 {
return m[1][0];
}
)",
- R"(
+ R"(
fn f(m : mat3x2<f32>) -> f32 {
return m[1i].x;
}
@@ -655,14 +744,14 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_mat3x2f_1_0) {
- Test(R"(
+ RUN_TEST(R"(
var<private> m : mat3x2<f32>;
fn f() -> f32 {
return m[1][0];
}
)",
- R"(
+ R"(
var<private> m : mat3x2<f32>;
fn f() -> f32 {
@@ -672,12 +761,12 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_mat3x2f_u_0) {
- Test(R"(
+ RUN_TEST(R"(
fn f(m : mat3x2<f32>, u : u32) -> f32 {
return m[u][0];
}
)",
- R"(
+ R"(
fn f(m : mat3x2<f32>, u : u32) -> f32 {
return m[u].x;
}
@@ -685,14 +774,14 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_mat3x2f_u_0) {
- Test(R"(
+ RUN_TEST(R"(
var<private> m : mat3x2<f32>;
fn f(u : u32) -> f32 {
return m[u][0];
}
)",
- R"(
+ R"(
var<private> m : mat3x2<f32>;
fn f(u : u32) -> f32 {
@@ -702,7 +791,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_mat3x2f_u_i) {
- Test(R"(
+ RUN_TEST(R"(
fn f(m : mat3x2<f32>, u : u32, i : i32) -> f32 {
return m[u][i];
}
@@ -710,7 +799,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_mat3x2f_u_i) {
- Test(R"(
+ RUN_TEST(R"(
var<private> m : mat3x2<f32>;
fn f(u : u32, i : i32) -> f32 {
@@ -720,7 +809,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_array_0u) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : array<i32, 4u>) -> i32 {
return a[0u];
}
@@ -728,7 +817,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_array_0u) {
- Test(R"(
+ RUN_TEST(R"(
var<private> a : array<i32, 4u>;
fn f() -> i32 {
@@ -738,7 +827,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Value_array_i) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : array<i32, 4u>, i : i32) -> i32 {
return a[i];
}
@@ -746,7 +835,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Ref_array_i) {
- Test(R"(
+ RUN_TEST(R"(
var<private> a : array<i32, 4u>;
fn f(i : i32) -> i32 {
@@ -756,7 +845,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ValueStruct) {
- Test(R"(
+ RUN_TEST(R"(
struct Y {
a : i32,
b : i32,
@@ -776,7 +865,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ReferenceStruct) {
- Test(R"(
+ RUN_TEST(R"(
struct Y {
a : i32,
b : i32,
@@ -797,7 +886,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfArrayOfArray_123) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -810,7 +899,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfArrayOfArray_213) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -824,7 +913,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfArrayOfArray_312) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -838,7 +927,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfArrayOfArray_321) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -853,7 +942,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfMat3x4f_123) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -865,7 +954,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfMat3x4f_213) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -879,7 +968,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfMat3x4f_312) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -893,7 +982,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_ArrayOfMat3x4f_321) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> i32 {
return 1i;
}
@@ -908,7 +997,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_UsePartialChains) {
- Test(R"(
+ RUN_TEST(R"(
var<private> a : array<array<array<i32, 4u>, 5u>, 6u>;
fn f(i : i32) -> i32 {
@@ -927,7 +1016,7 @@
// Swizzle
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_xy) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> vec2<f32> {
return v.xy;
}
@@ -935,7 +1024,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_yz) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> vec2<f32> {
return v.yz;
}
@@ -943,7 +1032,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_yzx) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> vec3<f32> {
return v.yzx;
}
@@ -951,7 +1040,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Value_yzxy) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : vec3<f32>) -> vec4<f32> {
return v.yzxy;
}
@@ -959,7 +1048,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_xy) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : ptr<function, vec3<f32>>) -> vec2<f32> {
return (*(v)).xy;
}
@@ -967,7 +1056,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_yz) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : ptr<function, vec3<f32>>) -> vec2<f32> {
return (*(v)).yz;
}
@@ -975,7 +1064,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_yzx) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : ptr<function, vec3<f32>>) -> vec3<f32> {
return (*(v)).yzx;
}
@@ -983,7 +1072,7 @@
}
TEST_F(IRToProgramRoundtripTest, Access_Vec3_Pointer_yzxy) {
- Test(R"(
+ RUN_TEST(R"(
fn f(v : ptr<function, vec3<f32>>) -> vec4<f32> {
return (*(v)).yzxy;
}
@@ -994,7 +1083,7 @@
// Unary ops
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, UnaryOp_Negate) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) -> i32 {
return -(i);
}
@@ -1002,7 +1091,7 @@
}
TEST_F(IRToProgramRoundtripTest, UnaryOp_Complement) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : u32) -> u32 {
return ~(i);
}
@@ -1010,7 +1099,7 @@
}
TEST_F(IRToProgramRoundtripTest, UnaryOp_Not) {
- Test(R"(
+ RUN_TEST(R"(
fn f(b : bool) -> bool {
return !(b);
}
@@ -1021,7 +1110,7 @@
// Binary ops
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, BinaryOp_Add) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a + b);
}
@@ -1029,7 +1118,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Subtract) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a - b);
}
@@ -1037,7 +1126,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Multiply) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a * b);
}
@@ -1045,7 +1134,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Divide) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a / b);
}
@@ -1053,7 +1142,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Modulo) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a % b);
}
@@ -1061,7 +1150,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_And) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a & b);
}
@@ -1069,7 +1158,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Or) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a | b);
}
@@ -1077,7 +1166,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Xor) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> i32 {
return (a ^ b);
}
@@ -1085,7 +1174,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_Equal) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> bool {
return (a == b);
}
@@ -1093,7 +1182,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_NotEqual) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> bool {
return (a != b);
}
@@ -1101,7 +1190,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_LessThan) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> bool {
return (a < b);
}
@@ -1109,7 +1198,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_GreaterThan) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> bool {
return (a > b);
}
@@ -1117,7 +1206,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_LessThanEqual) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> bool {
return (a <= b);
}
@@ -1125,7 +1214,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_GreaterThanEqual) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : i32) -> bool {
return (a >= b);
}
@@ -1133,7 +1222,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_ShiftLeft) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : u32) -> i32 {
return (a << b);
}
@@ -1141,7 +1230,7 @@
}
TEST_F(IRToProgramRoundtripTest, BinaryOp_ShiftRight) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : i32, b : u32) -> i32 {
return (a >> b);
}
@@ -1152,7 +1241,7 @@
// Short-circuiting binary ops
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Param_2) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool) -> bool {
return (a && b);
}
@@ -1160,7 +1249,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Param_3_ab_c) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
return ((a && b) && c);
}
@@ -1168,7 +1257,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Param_3_a_bc) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
return ((a && b) && c);
}
@@ -1176,7 +1265,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Let_2) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool) -> bool {
let l = (a && b);
return l;
@@ -1185,7 +1274,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Let_3_ab_c) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
let l = ((a && b) && c);
return l;
@@ -1194,7 +1283,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Let_3_a_bc) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
let l = (a && (b && c));
return l;
@@ -1203,7 +1292,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Call_2) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> bool {
return true;
}
@@ -1219,7 +1308,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Call_3_ab_c) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> bool {
return true;
}
@@ -1239,7 +1328,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_And_Call_3_a_bc) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> bool {
return true;
}
@@ -1259,7 +1348,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Param_2) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool) -> bool {
return (a || b);
}
@@ -1267,7 +1356,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Param_3_ab_c) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
return ((a || b) || c);
}
@@ -1275,7 +1364,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Param_3_a_bc) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
return (a || (b || c));
}
@@ -1283,7 +1372,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Let_2) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool) -> bool {
let l = (a || b);
return l;
@@ -1292,7 +1381,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Let_3_ab_c) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
let l = ((a || b) || c);
return l;
@@ -1301,7 +1390,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Let_3_a_bc) {
- Test(R"(
+ RUN_TEST(R"(
fn f(a : bool, b : bool, c : bool) -> bool {
let l = (a || (b || c));
return l;
@@ -1310,7 +1399,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Call_2) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> bool {
return true;
}
@@ -1326,7 +1415,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Call_3_ab_c) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> bool {
return true;
}
@@ -1346,7 +1435,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Or_Call_3_a_bc) {
- Test(R"(
+ RUN_TEST(R"(
fn a() -> bool {
return true;
}
@@ -1366,7 +1455,7 @@
}
TEST_F(IRToProgramRoundtripTest, ShortCircuit_Mixed) {
- Test(R"(
+ RUN_TEST(R"(
fn b() -> bool {
return true;
}
@@ -1386,7 +1475,7 @@
// Assignment
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Assign_ArrayOfArrayOfArrayAccess_123456) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1399,7 +1488,7 @@
}
TEST_F(IRToProgramRoundtripTest, Assign_ArrayOfArrayOfArrayAccess_261345) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1414,7 +1503,7 @@
}
TEST_F(IRToProgramRoundtripTest, Assign_ArrayOfArrayOfArrayAccess_532614) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1431,7 +1520,7 @@
}
TEST_F(IRToProgramRoundtripTest, Assign_ArrayOfMatrixAccess_123456) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1444,7 +1533,7 @@
}
TEST_F(IRToProgramRoundtripTest, Assign_ArrayOfMatrixAccess_261345) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1459,7 +1548,7 @@
}
TEST_F(IRToProgramRoundtripTest, Assign_ArrayOfMatrixAccess_532614) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1479,13 +1568,13 @@
// Compound assignment
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Increment) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v++;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v + 1i);
@@ -1494,13 +1583,13 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Decrement) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v++;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v + 1i);
@@ -1509,13 +1598,13 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Add) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v += 8i;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v + 8i);
@@ -1524,13 +1613,13 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Subtract) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v -= 8i;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v - 8i);
@@ -1539,13 +1628,13 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Multiply) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v *= 8i;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v * 8i);
@@ -1554,13 +1643,13 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Divide) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v /= 8i;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v / 8i);
@@ -1569,13 +1658,13 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_Xor) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var v : i32;
v ^= 8i;
}
)",
- R"(
+ R"(
fn f() {
var v : i32;
v = (v ^ 8i);
@@ -1584,7 +1673,7 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_ArrayOfArrayOfArrayAccess_123456) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1594,7 +1683,8 @@
v[e(1i)][e(2i)][e(3i)] += v[e(4i)][e(5i)][e(6i)];
}
)",
- R"(fn e(i : i32) -> i32 {
+ R"(
+fn e(i : i32) -> i32 {
return i;
}
@@ -1607,7 +1697,7 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_ArrayOfArrayOfArrayAccess_261345) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1619,7 +1709,8 @@
v[e(1i)][v_2][e(3i)] += v[e(4i)][e(5i)][v_3];
}
)",
- R"(fn e(i : i32) -> i32 {
+ R"(
+fn e(i : i32) -> i32 {
return i;
}
@@ -1634,7 +1725,7 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_ArrayOfArrayOfArrayAccess_532614) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1648,7 +1739,8 @@
v[e(1i)][v_4][v_3] += v[e(4i)][v_2][v_5];
}
)",
- R"(fn e(i : i32) -> i32 {
+ R"(
+fn e(i : i32) -> i32 {
return i;
}
@@ -1665,7 +1757,7 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_ArrayOfMatrixAccess_123456) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1675,7 +1767,8 @@
v[e(1i)][e(2i)][e(3i)] += v[e(4i)][e(5i)][e(6i)];
}
)",
- R"(fn e(i : i32) -> i32 {
+ R"(
+fn e(i : i32) -> i32 {
return i;
}
@@ -1689,7 +1782,7 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_ArrayOfMatrixAccess_261345) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1701,7 +1794,8 @@
v[e(1i)][v_2][e(3i)] += v[e(4i)][e(5i)][v_3];
}
)",
- R"(fn e(i : i32) -> i32 {
+ R"(
+fn e(i : i32) -> i32 {
return i;
}
@@ -1717,7 +1811,7 @@
}
TEST_F(IRToProgramRoundtripTest, CompoundAssign_ArrayOfMatrixAccess_532614) {
- Test(R"(
+ RUN_TEST(R"(
fn e(i : i32) -> i32 {
return i;
}
@@ -1731,7 +1825,8 @@
v[e(1i)][v_4][v_3] += v[e(4i)][v_2][v_5];
}
)",
- R"(fn e(i : i32) -> i32 {
+ R"(
+fn e(i : i32) -> i32 {
return i;
}
@@ -1751,7 +1846,7 @@
// Phony Assignment
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, PhonyAssign_PrivateVar) {
- Test(R"(
+ RUN_TEST(R"(
var<private> p : i32;
fn f() {
@@ -1761,7 +1856,7 @@
}
TEST_F(IRToProgramRoundtripTest, PhonyAssign_FunctionVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var i : i32;
_ = i;
@@ -1770,13 +1865,13 @@
}
TEST_F(IRToProgramRoundtripTest, PhonyAssign_FunctionLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
let i : i32 = 42i;
_ = i;
}
)",
- R"(
+ R"(
fn f() {
let i = 42i;
}
@@ -1784,7 +1879,7 @@
}
TEST_F(IRToProgramRoundtripTest, PhonyAssign_HandleVar) {
- Test(R"(
+ RUN_TEST(R"(
@group(0) @binding(0) var t : texture_2d<f32>;
fn f() {
@@ -1794,19 +1889,19 @@
}
TEST_F(IRToProgramRoundtripTest, PhonyAssign_Constant) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
_ = 42i;
}
)",
- R"(
+ R"(
fn f() {
}
)");
}
TEST_F(IRToProgramRoundtripTest, PhonyAssign_Call) {
- Test(R"(
+ RUN_TEST(R"(
fn v() -> i32 {
return 42;
}
@@ -1815,7 +1910,7 @@
_ = v();
}
)",
- R"(
+ R"(
fn v() -> i32 {
return 42i;
}
@@ -1830,7 +1925,7 @@
// let
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, LetUsedOnce) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : u32) -> u32 {
let v = ~(i);
return v;
@@ -1839,7 +1934,7 @@
}
TEST_F(IRToProgramRoundtripTest, LetUsedTwice) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) -> i32 {
let v = (i * 2i);
return (v + v);
@@ -1851,19 +1946,25 @@
// Module-scope var
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_i32) {
- Test("var<private> v : i32 = 1i;");
+ RUN_TEST(R"(
+var<private> v : i32 = 1i;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_u32) {
- Test("var<private> v : u32 = 1u;");
+ RUN_TEST(R"(
+var<private> v : u32 = 1u;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_f32) {
- Test("var<private> v : f32 = 1.0f;");
+ RUN_TEST(R"(
+var<private> v : f32 = 1.0f;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_f16) {
- Test(R"(
+ RUN_TEST(R"(
enable f16;
var<private> v : f16 = 1.0h;
@@ -1871,28 +1972,38 @@
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_bool) {
- Test("var<private> v : bool = true;");
+ RUN_TEST(R"(
+var<private> v : bool = true;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_array_NoArgs) {
- Test("var<private> v : array<i32, 4u> = array<i32, 4u>();");
+ RUN_TEST(R"(
+var<private> v : array<i32, 4u> = array<i32, 4u>();
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_array_Zero) {
- Test("var<private> v : array<i32, 4u> = array<i32, 4u>(0i, 0i, 0i, 0i);",
- "var<private> v : array<i32, 4u> = array<i32, 4u>();");
+ RUN_TEST(R"(
+var<private> v : array<i32, 4u> = array<i32, 4u>(0i, 0i, 0i, 0i);
+var<private> v : array<i32, 4u> = array<i32, 4u>();
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_array_SameValue) {
- Test("var<private> v : array<i32, 4u> = array<i32, 4u>(4i, 4i, 4i, 4i);");
+ RUN_TEST(R"(
+var<private> v : array<i32, 4u> = array<i32, 4u>(4i, 4i, 4i, 4i);
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_array_DifferentValues) {
- Test("var<private> v : array<i32, 4u> = array<i32, 4u>(1i, 2i, 3i, 4i);");
+ RUN_TEST(R"(
+var<private> v : array<i32, 4u> = array<i32, 4u>(1i, 2i, 3i, 4i);
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_struct_NoArgs) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
i : i32,
u : u32,
@@ -1904,7 +2015,7 @@
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_struct_Zero) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
i : i32,
u : u32,
@@ -1913,7 +2024,7 @@
var<private> s : S = S(0i, 0u, 0f);
)",
- R"(
+ R"(
struct S {
i : i32,
u : u32,
@@ -1925,7 +2036,7 @@
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_struct_SameValue) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
b : i32,
@@ -1937,7 +2048,7 @@
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_struct_DifferentValues) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
a : i32,
b : i32,
@@ -1949,78 +2060,104 @@
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_vec3f_NoArgs) {
- Test("var<private> v : vec3<f32> = vec3<f32>();");
+ RUN_TEST(R"(
+var<private> v : vec3<f32> = vec3<f32>();
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_vec3f_Zero) {
- Test("var<private> v : vec3<f32> = vec3<f32>(0f);",
- "var<private> v : vec3<f32> = vec3<f32>();");
+ RUN_TEST(R"(
+var<private> v : vec3<f32> = vec3<f32>(0f);",
+ "var<private> v : vec3<f32> = vec3<f32>();
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_vec3f_Splat) {
- Test("var<private> v : vec3<f32> = vec3<f32>(1.0f);");
+ RUN_TEST(R"(
+var<private> v : vec3<f32> = vec3<f32>(1.0f);
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_vec3f_Scalars) {
- Test("var<private> v : vec3<f32> = vec3<f32>(1.0f, 2.0f, 3.0f);");
+ RUN_TEST(R"(
+var<private> v : vec3<f32> = vec3<f32>(1.0f, 2.0f, 3.0f);
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_mat2x3f_NoArgs) {
- Test("var<private> v : mat2x3<f32> = mat2x3<f32>();");
+ RUN_TEST(R"(
+var<private> v : mat2x3<f32> = mat2x3<f32>();
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_mat2x3f_Scalars_SameValue) {
- Test("var<private> v : mat2x3<f32> = mat2x3<f32>(4.0f, 4.0f, 4.0f, 4.0f, 4.0f, 4.0f);",
- "var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(4.0f), vec3<f32>(4.0f));");
+ RUN_TEST(R"(
+var<private> v : mat2x3<f32> = mat2x3<f32>(4.0f, 4.0f, 4.0f, 4.0f, 4.0f, 4.0f);
+var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(4.0f), vec3<f32>(4.0f));
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_mat2x3f_Scalars) {
- Test("var<private> v : mat2x3<f32> = mat2x3<f32>(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f);",
- "var<private> v : mat2x3<f32> = "
- "mat2x3<f32>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));");
+ RUN_TEST(R"(
+var<private> v : mat2x3<f32> = mat2x3<f32>(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f);
+var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_mat2x3f_Columns) {
- Test(
- "var<private> v : mat2x3<f32> = "
- "mat2x3<f32>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));");
+ RUN_TEST(
+ R"(
+var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(1.0f, 2.0f, 3.0f), vec3<f32>(4.0f, 5.0f, 6.0f));
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Private_mat2x3f_Columns_SameValue) {
- Test(
- "var<private> v : mat2x3<f32> = "
- "mat2x3<f32>(vec3<f32>(4.0f, 4.0f, 4.0f), vec3<f32>(4.0f, 4.0f, 4.0f));",
- "var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(4.0f), vec3<f32>(4.0f));");
+ RUN_TEST(R"(
+var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(4.0f, 4.0f, 4.0f), vec3<f32>(4.0f, 4.0f, 4.0f));
+var<private> v : mat2x3<f32> = mat2x3<f32>(vec3<f32>(4.0f), vec3<f32>(4.0f));
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Uniform_vec4i) {
- Test("@group(10) @binding(20) var<uniform> v : vec4<i32>;");
+ RUN_TEST(R"(
+@group(10) @binding(20) var<uniform> v : vec4<i32>;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_StorageRead_u32) {
- Test("@group(10) @binding(20) var<storage, read> v : u32;");
+ RUN_TEST(R"(
+@group(10) @binding(20) var<storage, read> v : u32;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_StorageReadWrite_i32) {
- Test("@group(10) @binding(20) var<storage, read_write> v : i32;");
+ RUN_TEST(R"(
+@group(10) @binding(20) var<storage, read_write> v : i32;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Handle_Texture2D) {
- Test("@group(0) @binding(0) var t : texture_2d<f32>;");
+ RUN_TEST(R"(
+@group(0) @binding(0) var t : texture_2d<f32>;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Handle_Sampler) {
- Test("@group(0) @binding(0) var s : sampler;");
+ RUN_TEST(R"(
+@group(0) @binding(0) var s : sampler;
+)");
}
TEST_F(IRToProgramRoundtripTest, ModuleScopeVar_Handle_SamplerCmp) {
- Test("@group(0) @binding(0) var s : sampler_comparison;");
+ RUN_TEST(R"(
+@group(0) @binding(0) var s : sampler_comparison;
+)");
}
////////////////////////////////////////////////////////////////////////////////
// Function-scope var
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, FunctionScopeVar_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var i : i32;
}
@@ -2028,7 +2165,7 @@
}
TEST_F(IRToProgramRoundtripTest, FunctionScopeVar_i32_InitLiteral) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var i : i32 = 42i;
}
@@ -2036,7 +2173,7 @@
}
TEST_F(IRToProgramRoundtripTest, FunctionScopeVar_Chained) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var a : i32 = 42i;
var b : i32 = a;
@@ -2049,7 +2186,7 @@
// Function-scope let
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, FunctionScopeLet_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f(i : i32) -> i32 {
let a = (42i + i);
let b = (24i + i);
@@ -2060,7 +2197,7 @@
}
TEST_F(IRToProgramRoundtripTest, FunctionScopeLet_ptr) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var a : array<i32, 3u>;
let b = &(a[1i]);
@@ -2075,7 +2212,7 @@
// If their constant values were inlined, then the initializer for 'c' would be treated as a
// constant expression instead of the authored runtime expression. Evaluating '1 / 0' as a
// constant expression is a WGSL validation error.
- Test(R"(
+ RUN_TEST(R"(
fn f() {
let a = 1i;
let b = 0i;
@@ -2088,7 +2225,7 @@
// If
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, If_CallFn) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2101,7 +2238,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_Return) {
- Test(R"(
+ RUN_TEST(R"(
fn f(cond : bool) {
if (cond) {
return;
@@ -2111,7 +2248,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_Return_i32) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var cond : bool = true;
if (cond) {
@@ -2123,7 +2260,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_CallFn_Else_CallFn) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2141,7 +2278,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_Return_f32_Else_Return_f32) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> f32 {
var cond : bool = true;
if (cond) {
@@ -2154,7 +2291,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_Return_u32_Else_CallFn) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2175,7 +2312,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_CallFn_ElseIf_CallFn) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2198,7 +2335,7 @@
}
TEST_F(IRToProgramRoundtripTest, If_Else_Chain) {
- Test(R"(
+ RUN_TEST(R"(
fn x(i : i32) -> bool {
return true;
}
@@ -2221,7 +2358,7 @@
// Switch
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Switch_Default) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2237,7 +2374,7 @@
}
TEST_F(IRToProgramRoundtripTest, Switch_3_Cases) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2265,7 +2402,7 @@
}
TEST_F(IRToProgramRoundtripTest, Switch_3_Cases_AllReturn) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2285,7 +2422,7 @@
a();
}
)",
- R"(
+ R"(
fn a() {
}
@@ -2307,7 +2444,7 @@
}
TEST_F(IRToProgramRoundtripTest, Switch_Nested) {
- Test(R"(
+ RUN_TEST(R"(
fn a() {
}
@@ -2345,7 +2482,7 @@
// For
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, For_Empty) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
for(var i : i32 = 0i; (i < 5i); i = (i + 1i)) {
}
@@ -2354,7 +2491,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_Empty_NoInit) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var i : i32 = 0i;
for(; (i < 5i); i = (i + 1i)) {
@@ -2364,14 +2501,14 @@
}
TEST_F(IRToProgramRoundtripTest, For_Empty_NoCond) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
for(var i : i32 = 0i; ; i = (i + 1i)) {
break;
}
}
)",
- R"(
+ R"(
fn f() {
{
var i : i32 = 0i;
@@ -2388,7 +2525,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_Empty_NoCont) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
for(var i : i32 = 0i; (i < 5i); ) {
}
@@ -2397,7 +2534,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_ComplexBody) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> bool {
return (v == 1i);
}
@@ -2416,7 +2553,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_ComplexBody_NoInit) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> bool {
return (v == 1i);
}
@@ -2436,7 +2573,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_ComplexBody_NoCond) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> bool {
return (v == 1i);
}
@@ -2451,7 +2588,7 @@
}
}
)",
- R"(
+ R"(
fn a(v : i32) -> bool {
return (v == 1i);
}
@@ -2476,7 +2613,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_ComplexBody_NoCont) {
- Test(R"(
+ RUN_TEST(R"(
fn a(v : i32) -> bool {
return (v == 1i);
}
@@ -2495,7 +2632,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_CallInInitCondCont) {
- Test(R"(
+ RUN_TEST(R"(
fn n(v : i32) -> i32 {
return (v + 1i);
}
@@ -2508,7 +2645,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_AssignAsInit) {
- Test(R"(
+ RUN_TEST(R"(
fn n() {
}
@@ -2521,7 +2658,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_CompoundAssignAsInit) {
- Test(R"(
+ RUN_TEST(R"(
fn n() {
}
@@ -2531,7 +2668,7 @@
}
}
)",
- R"(
+ R"(
fn n() {
}
@@ -2544,7 +2681,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_IncrementAsInit) {
- Test(R"(
+ RUN_TEST(R"(
fn n() {
}
@@ -2554,7 +2691,7 @@
}
}
)",
- R"(
+ R"(
fn n() {
}
@@ -2567,7 +2704,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_DecrementAsInit) {
- Test(R"(
+ RUN_TEST(R"(
fn n() {
}
@@ -2577,7 +2714,7 @@
}
}
)",
- R"(
+ R"(
fn n() {
}
@@ -2590,7 +2727,7 @@
}
TEST_F(IRToProgramRoundtripTest, For_CallAsInit) {
- Test(R"(
+ RUN_TEST(R"(
fn n() {
}
@@ -2606,7 +2743,7 @@
// While
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, While_Empty) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
while(true) {
}
@@ -2615,7 +2752,7 @@
}
TEST_F(IRToProgramRoundtripTest, While_Cond) {
- Test(R"(
+ RUN_TEST(R"(
fn f(cond : bool) {
while(cond) {
}
@@ -2624,7 +2761,7 @@
}
TEST_F(IRToProgramRoundtripTest, While_Break) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
while(true) {
break;
@@ -2634,7 +2771,7 @@
}
TEST_F(IRToProgramRoundtripTest, While_IfBreak) {
- Test(R"(
+ RUN_TEST(R"(
fn f(cond : bool) {
while(true) {
if (cond) {
@@ -2646,7 +2783,7 @@
}
TEST_F(IRToProgramRoundtripTest, While_IfReturn) {
- Test(R"(
+ RUN_TEST(R"(
fn f(cond : bool) {
while(true) {
if (cond) {
@@ -2661,7 +2798,7 @@
// Loop
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Loop_Break) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
loop {
break;
@@ -2671,7 +2808,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_IfBreak) {
- Test(R"(
+ RUN_TEST(R"(
fn f(cond : bool) {
loop {
if (cond) {
@@ -2683,7 +2820,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_IfReturn) {
- Test(R"(
+ RUN_TEST(R"(
fn f(cond : bool) {
loop {
if (cond) {
@@ -2695,7 +2832,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_IfContinuing) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var cond : bool = false;
loop {
@@ -2712,7 +2849,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_VarsDeclaredOutsideAndInside) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
var b : i32 = 1i;
loop {
@@ -2730,7 +2867,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_BreakIf_EmptyBody) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
loop {
@@ -2743,7 +2880,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_BreakIf_NotFalse) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
loop {
if (false) {
@@ -2757,7 +2894,7 @@
}
}
)",
- R"(
+ R"(
fn f() {
loop {
if (!(false)) {
@@ -2773,7 +2910,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_BreakIf_NotTrue) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
loop {
if (false) {
@@ -2787,7 +2924,7 @@
}
}
)",
- R"(
+ R"(
fn f() {
loop {
if (!(false)) {
@@ -2803,7 +2940,7 @@
}
TEST_F(IRToProgramRoundtripTest, Loop_WithReturn) {
- Test(R"(
+ RUN_TEST(R"(
fn f() {
loop {
let i = 42i;
@@ -2817,12 +2954,12 @@
// Shadowing tests
////////////////////////////////////////////////////////////////////////////////
TEST_F(IRToProgramRoundtripTest, Shadow_f32_With_Fn) {
- Test(R"(
+ RUN_TEST(R"(
fn f32() {
var v = mat4x4f();
}
)",
- R"(
+ R"(
fn f32_1() {
var v : mat4x4<f32> = mat4x4<f32>();
}
@@ -2830,7 +2967,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_f32_With_Struct) {
- Test(R"(
+ RUN_TEST(R"(
struct f32 {
v : i32,
}
@@ -2839,7 +2976,7 @@
let f = vec2f(1.0f);
}
)",
- R"(
+ R"(
struct f32_1 {
v : i32,
}
@@ -2851,21 +2988,21 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_f32_With_ModVar) {
- Test(R"(
+ RUN_TEST(R"(
var<private> f32 : vec2f = vec2f(0.0f, 1.0f);
)",
- R"(
+ R"(
var<private> f32_1 : vec2<f32> = vec2<f32>(0.0f, 1.0f);
)");
}
TEST_F(IRToProgramRoundtripTest, Shadow_f32_With_ModVar2) {
- Test(R"(
+ RUN_TEST(R"(
var<private> f32 : i32 = 1i;
var<private> v = vec2(1.0).x;
)",
- R"(
+ R"(
var<private> f32_1 : i32 = 1i;
var<private> v : f32 = 1.0f;
@@ -2873,14 +3010,14 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_f32_With_Alias) {
- Test(R"(
+ RUN_TEST(R"(
alias f32 = i32;
fn f() {
var v = vec3(1.0f, 2.0f, 3.0f);
}
)",
- R"(
+ R"(
fn f() {
var v : vec3<f32> = vec3<f32>(1.0f, 2.0f, 3.0f);
}
@@ -2888,7 +3025,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_Struct_With_FnVar) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
i : i32,
}
@@ -2901,7 +3038,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_Struct_With_Param) {
- Test(R"(
+ RUN_TEST(R"(
struct S {
i : i32,
}
@@ -2913,7 +3050,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_ModVar_With_FnVar) {
- Test(R"(
+ RUN_TEST(R"(
var<private> i : i32 = 1i;
fn f() -> i32 {
@@ -2925,7 +3062,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_ModVar_With_FnLet) {
- Test(R"(
+ RUN_TEST(R"(
var<private> i : i32 = 1i;
fn f() -> i32 {
@@ -2937,7 +3074,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_IfVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
if (true) {
@@ -2951,7 +3088,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_IfLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
if (true) {
@@ -2965,7 +3102,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_WhileVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
while((i < 4i)) {
@@ -2978,7 +3115,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_WhileLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
while((i < 4i)) {
@@ -2991,7 +3128,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_ForInitVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
for(var i : f32 = 0.0f; (i < 4.0f); ) {
@@ -3003,7 +3140,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_ForInitLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
for(let i = 0.0f; (i < 4.0f); ) {
@@ -3015,7 +3152,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_ForBodyVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
for(var x : i32 = 0i; (i < 4i); ) {
@@ -3028,7 +3165,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_ForBodyLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
for(var x : i32 = 0i; (i < 4i); ) {
@@ -3041,7 +3178,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_LoopBodyVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
loop {
@@ -3059,7 +3196,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_LoopBodyLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
loop {
@@ -3077,7 +3214,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_LoopContinuingVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
loop {
@@ -3096,7 +3233,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_LoopContinuingLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
loop {
@@ -3115,7 +3252,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_SwitchCaseVar) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
switch(i) {
@@ -3135,7 +3272,7 @@
}
TEST_F(IRToProgramRoundtripTest, Shadow_FnVar_With_SwitchCaseLet) {
- Test(R"(
+ RUN_TEST(R"(
fn f() -> i32 {
var i : i32;
switch(i) {
diff --git a/src/tint/lang/wgsl/reader/lower/lower_test.cc b/src/tint/lang/wgsl/reader/lower/lower_test.cc
index dd05a5d..d8ec462 100644
--- a/src/tint/lang/wgsl/reader/lower/lower_test.cc
+++ b/src/tint/lang/wgsl/reader/lower/lower_test.cc
@@ -33,7 +33,7 @@
#include "src/tint/lang/wgsl/ir/builtin_call.h"
#include "src/tint/lang/wgsl/reader/lower/lower.h"
-namespace tint::wgsl::reader::lower {
+namespace tint::wgsl::reader {
namespace {
using namespace tint::core::fluent_types; // NOLINT
@@ -124,4 +124,4 @@
}
} // namespace
-} // namespace tint::wgsl::reader::lower
+} // namespace tint::wgsl::reader
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index 0ae2eea..740c918 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -950,7 +950,7 @@
if (!rhs) {
return;
}
- core::ir::Binary* inst = impl.BinaryOp(ty, lhs, rhs, b->op);
+ auto* inst = impl.BinaryOp(ty, lhs, rhs, b->op);
if (!inst) {
return;
}
@@ -1288,10 +1288,10 @@
TINT_ICE_ON_NO_MATCH);
}
- core::ir::Binary* BinaryOp(const core::type::Type* ty,
- core::ir::Value* lhs,
- core::ir::Value* rhs,
- core::BinaryOp op) {
+ core::ir::CoreBinary* BinaryOp(const core::type::Type* ty,
+ core::ir::Value* lhs,
+ core::ir::Value* rhs,
+ core::BinaryOp op) {
switch (op) {
case core::BinaryOp::kAnd:
return builder_.And(ty, lhs, rhs);
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel b/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel
index f4308d6..f580105 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.bazel
@@ -61,6 +61,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/strconv",
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake b/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
index 1f2d210..7ce8c41 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.cmake
@@ -62,6 +62,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_strconv
diff --git a/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn b/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn
index 796fc83..3d484a5 100644
--- a/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn
+++ b/src/tint/lang/wgsl/writer/ast_printer/BUILD.gn
@@ -64,6 +64,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/strconv",
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
index f7b6321..47b6468 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.cc
@@ -749,12 +749,15 @@
void Unary(const core::ir::Unary* u) {
const ast::Expression* expr = nullptr;
switch (u->Op()) {
- case core::ir::UnaryOp::kComplement:
+ case core::UnaryOp::kComplement:
expr = b.Complement(Expr(u->Val()));
break;
- case core::ir::UnaryOp::kNegation:
+ case core::UnaryOp::kNegation:
expr = b.Negation(Expr(u->Val()));
break;
+ default:
+ TINT_UNIMPLEMENTED() << u->Op();
+ break;
}
Bind(u->Result(0), expr);
}
@@ -809,7 +812,7 @@
}
void Binary(const core::ir::Binary* e) {
- if (e->Op() == core::ir::BinaryOp::kEqual) {
+ if (e->Op() == core::BinaryOp::kEqual) {
auto* rhs = e->RHS()->As<core::ir::Constant>();
if (rhs && rhs->Type()->Is<core::type::Bool>() &&
rhs->Value()->ValueAs<bool>() == false) {
@@ -822,54 +825,60 @@
auto* rhs = Expr(e->RHS());
const ast::Expression* expr = nullptr;
switch (e->Op()) {
- case core::ir::BinaryOp::kAdd:
+ case core::BinaryOp::kAdd:
expr = b.Add(lhs, rhs);
break;
- case core::ir::BinaryOp::kSubtract:
+ case core::BinaryOp::kSubtract:
expr = b.Sub(lhs, rhs);
break;
- case core::ir::BinaryOp::kMultiply:
+ case core::BinaryOp::kMultiply:
expr = b.Mul(lhs, rhs);
break;
- case core::ir::BinaryOp::kDivide:
+ case core::BinaryOp::kDivide:
expr = b.Div(lhs, rhs);
break;
- case core::ir::BinaryOp::kModulo:
+ case core::BinaryOp::kModulo:
expr = b.Mod(lhs, rhs);
break;
- case core::ir::BinaryOp::kAnd:
+ case core::BinaryOp::kAnd:
expr = b.And(lhs, rhs);
break;
- case core::ir::BinaryOp::kOr:
+ case core::BinaryOp::kOr:
expr = b.Or(lhs, rhs);
break;
- case core::ir::BinaryOp::kXor:
+ case core::BinaryOp::kXor:
expr = b.Xor(lhs, rhs);
break;
- case core::ir::BinaryOp::kEqual:
+ case core::BinaryOp::kEqual:
expr = b.Equal(lhs, rhs);
break;
- case core::ir::BinaryOp::kNotEqual:
+ case core::BinaryOp::kNotEqual:
expr = b.NotEqual(lhs, rhs);
break;
- case core::ir::BinaryOp::kLessThan:
+ case core::BinaryOp::kLessThan:
expr = b.LessThan(lhs, rhs);
break;
- case core::ir::BinaryOp::kGreaterThan:
+ case core::BinaryOp::kGreaterThan:
expr = b.GreaterThan(lhs, rhs);
break;
- case core::ir::BinaryOp::kLessThanEqual:
+ case core::BinaryOp::kLessThanEqual:
expr = b.LessThanEqual(lhs, rhs);
break;
- case core::ir::BinaryOp::kGreaterThanEqual:
+ case core::BinaryOp::kGreaterThanEqual:
expr = b.GreaterThanEqual(lhs, rhs);
break;
- case core::ir::BinaryOp::kShiftLeft:
+ case core::BinaryOp::kShiftLeft:
expr = b.Shl(lhs, rhs);
break;
- case core::ir::BinaryOp::kShiftRight:
+ case core::BinaryOp::kShiftRight:
expr = b.Shr(lhs, rhs);
break;
+ case core::BinaryOp::kLogicalAnd:
+ expr = b.LogicalAnd(lhs, rhs);
+ break;
+ case core::BinaryOp::kLogicalOr:
+ expr = b.LogicalOr(lhs, rhs);
+ break;
}
Bind(e->Result(0), expr);
}
diff --git a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
index f379020..cd77dba 100644
--- a/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
+++ b/src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.cc
@@ -33,6 +33,7 @@
#include "src/tint/lang/core/ir/disassembler.h"
#include "src/tint/lang/core/type/storage_texture.h"
#include "src/tint/lang/wgsl/ir/builtin_call.h"
+#include "src/tint/lang/wgsl/ir/unary.h"
#include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program.h"
#include "src/tint/lang/wgsl/writer/ir_to_program/ir_to_program_test.h"
#include "src/tint/lang/wgsl/writer/writer.h"
@@ -926,7 +927,7 @@
////////////////////////////////////////////////////////////////////////////////
// Short-circuiting binary ops
////////////////////////////////////////////////////////////////////////////////
-TEST_F(IRToProgramTest, ShortCircuit_And_Param_2) {
+TEST_F(IRToProgramTest, ShortCircuit_And_2) {
auto* fn = b.Function("f", ty.bool_());
auto* pa = b.FunctionParam("a", ty.bool_());
auto* pb = b.FunctionParam("b", ty.bool_());
@@ -938,7 +939,7 @@
b.Append(if_->True(), [&] { b.ExitIf(if_, pb); });
b.Append(if_->False(), [&] { b.ExitIf(if_, false); });
- b.Return(fn, if_->Result(0));
+ b.Return(fn, if_);
});
EXPECT_WGSL(R"(
@@ -948,7 +949,7 @@
)");
}
-TEST_F(IRToProgramTest, ShortCircuit_And_Param_3_ab_c) {
+TEST_F(IRToProgramTest, ShortCircuit_And_3_ab_c) {
auto* fn = b.Function("f", ty.bool_());
auto* pa = b.FunctionParam("a", ty.bool_());
auto* pb = b.FunctionParam("b", ty.bool_());
@@ -961,12 +962,12 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, pb); });
b.Append(if1->False(), [&] { b.ExitIf(if1, false); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, pc); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -976,7 +977,7 @@
)");
}
-TEST_F(IRToProgramTest, ShortCircuit_And_Param_3_a_bc) {
+TEST_F(IRToProgramTest, ShortCircuit_And_3_a_bc) {
auto* fn = b.Function("f", ty.bool_());
auto* pa = b.FunctionParam("a", ty.bool_());
auto* pb = b.FunctionParam("b", ty.bool_());
@@ -992,10 +993,10 @@
b.Append(if2->True(), [&] { b.ExitIf(if2, pc); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.ExitIf(if1, if2->Result(0));
+ b.ExitIf(if1, if2);
});
b.Append(if1->False(), [&] { b.ExitIf(if1, false); });
- b.Return(fn, if1->Result(0));
+ b.Return(fn, if1);
});
EXPECT_WGSL(R"(
@@ -1017,8 +1018,8 @@
b.Append(if_->True(), [&] { b.ExitIf(if_, pb); });
b.Append(if_->False(), [&] { b.ExitIf(if_, false); });
- mod.SetName(if_->Result(0), "l");
- b.Return(fn, if_->Result(0));
+ mod.SetName(if_, "l");
+ b.Return(fn, if_);
});
EXPECT_WGSL(R"(
@@ -1042,13 +1043,13 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, pb); });
b.Append(if1->False(), [&] { b.ExitIf(if1, false); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, pc); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- mod.SetName(if2->Result(0), "l");
- b.Return(fn, if2->Result(0));
+ mod.SetName(if2, "l");
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1075,12 +1076,12 @@
b.Append(if2->True(), [&] { b.ExitIf(if2, pc); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.ExitIf(if1, if2->Result(0));
+ b.ExitIf(if1, if2);
});
b.Append(if1->False(), [&] { b.ExitIf(if1, false); });
- mod.SetName(if1->Result(0), "l");
- b.Return(fn, if1->Result(0));
+ mod.SetName(if1, "l");
+ b.Return(fn, if1);
});
EXPECT_WGSL(R"(
@@ -1106,7 +1107,7 @@
b.Append(if_->True(), [&] { b.ExitIf(if_, b.Call(ty.bool_(), fn_b)); });
b.Append(if_->False(), [&] { b.ExitIf(if_, false); });
- b.Return(fn, if_->Result(0));
+ b.Return(fn, if_);
});
EXPECT_WGSL(R"(
@@ -1142,12 +1143,12 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, b.Call(ty.bool_(), fn_b)); });
b.Append(if1->False(), [&] { b.ExitIf(if1, false); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, b.Call(ty.bool_(), fn_c)); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1190,11 +1191,11 @@
b.Append(if2->True(), [&] { b.ExitIf(if2, b.Call(ty.bool_(), fn_c)); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.ExitIf(if1, if2->Result(0));
+ b.ExitIf(if1, if2);
});
b.Append(if1->False(), [&] { b.ExitIf(if1, false); });
- b.Return(fn, if1->Result(0));
+ b.Return(fn, if1);
});
EXPECT_WGSL(R"(
@@ -1228,7 +1229,7 @@
b.Append(if_->True(), [&] { b.ExitIf(if_, true); });
b.Append(if_->False(), [&] { b.ExitIf(if_, pb); });
- b.Return(fn, if_->Result(0));
+ b.Return(fn, if_);
});
EXPECT_WGSL(R"(
@@ -1251,12 +1252,12 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, true); });
b.Append(if1->False(), [&] { b.ExitIf(if1, pb); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
b.Append(if2->False(), [&] { b.ExitIf(if2, pc); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1283,10 +1284,10 @@
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
b.Append(if2->False(), [&] { b.ExitIf(if2, pc); });
- b.ExitIf(if1, if2->Result(0));
+ b.ExitIf(if1, if2);
});
- b.Return(fn, if1->Result(0));
+ b.Return(fn, if1);
});
EXPECT_WGSL(R"(
@@ -1308,8 +1309,8 @@
b.Append(if_->True(), [&] { b.ExitIf(if_, true); });
b.Append(if_->False(), [&] { b.ExitIf(if_, pb); });
- mod.SetName(if_->Result(0), "l");
- b.Return(fn, if_->Result(0));
+ mod.SetName(if_, "l");
+ b.Return(fn, if_);
});
EXPECT_WGSL(R"(
@@ -1333,13 +1334,13 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, true); });
b.Append(if1->False(), [&] { b.ExitIf(if1, pb); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
b.Append(if2->False(), [&] { b.ExitIf(if2, pc); });
- mod.SetName(if2->Result(0), "l");
- b.Return(fn, if2->Result(0));
+ mod.SetName(if2, "l");
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1367,11 +1368,11 @@
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
b.Append(if2->False(), [&] { b.ExitIf(if2, pc); });
- b.ExitIf(if1, if2->Result(0));
+ b.ExitIf(if1, if2);
});
- mod.SetName(if1->Result(0), "l");
- b.Return(fn, if1->Result(0));
+ mod.SetName(if1, "l");
+ b.Return(fn, if1);
});
EXPECT_WGSL(R"(
@@ -1397,7 +1398,7 @@
b.Append(if_->True(), [&] { b.ExitIf(if_, true); });
b.Append(if_->False(), [&] { b.ExitIf(if_, b.Call(ty.bool_(), fn_b)); });
- b.Return(fn, if_->Result(0));
+ b.Return(fn, if_);
});
EXPECT_WGSL(R"(
@@ -1433,12 +1434,12 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, true); });
b.Append(if1->False(), [&] { b.ExitIf(if1, b.Call(ty.bool_(), fn_b)); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
b.Append(if2->False(), [&] { b.ExitIf(if2, b.Call(ty.bool_(), fn_c)); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1482,10 +1483,10 @@
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
b.Append(if2->False(), [&] { b.ExitIf(if2, b.Call(ty.bool_(), fn_c)); });
- b.ExitIf(if1, if2->Result(0));
+ b.ExitIf(if1, if2);
});
- b.Return(fn, if1->Result(0));
+ b.Return(fn, if1);
});
EXPECT_WGSL(R"(
@@ -1525,7 +1526,7 @@
b.Append(if1->True(), [&] { b.ExitIf(if1, true); });
b.Append(if1->False(), [&] { b.ExitIf(if1, b.Call(ty.bool_(), fn_b)); });
- auto* if2 = b.If(if1->Result(0));
+ auto* if2 = b.If(if1);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] {
auto* if3 = b.If(pc);
@@ -1533,12 +1534,12 @@
b.Append(if3->True(), [&] { b.ExitIf(if3, true); });
b.Append(if3->False(), [&] { b.ExitIf(if3, b.Call(ty.bool_(), fn_d)); });
- b.ExitIf(if2, if3->Result(0));
+ b.ExitIf(if2, if3);
});
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- mod.SetName(if2->Result(0), "l");
- b.Return(fn, if2->Result(0));
+ mod.SetName(if2, "l");
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1582,9 +1583,9 @@
auto* if2 = b.If(pa);
if2->SetResults(b.InstructionResult(ty.bool_()));
- b.Append(if2->True(), [&] { b.ExitIf(if2, if1->Result(0)); });
+ b.Append(if2->True(), [&] { b.ExitIf(if2, if1); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1623,10 +1624,10 @@
auto* if2 = b.If(b.Call(ty.bool_(), fn_a));
if2->SetResults(b.InstructionResult(ty.bool_()));
- b.Append(if2->True(), [&] { b.ExitIf(if2, if1->Result(0)); });
+ b.Append(if2->True(), [&] { b.ExitIf(if2, if1); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1669,10 +1670,10 @@
auto* if2 = b.If(pa);
if2->SetResults(b.InstructionResult(ty.bool_()));
- b.Append(if2->True(), [&] { b.ExitIf(if2, if1->Result(0)); });
+ b.Append(if2->True(), [&] { b.ExitIf(if2, if1); });
b.Append(if2->False(), [&] { b.ExitIf(if2, false); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1704,10 +1705,10 @@
auto* if2 = b.If(pa);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
- b.Append(if2->False(), [&] { b.ExitIf(if2, if1->Result(0)); });
+ b.Append(if2->False(), [&] { b.ExitIf(if2, if1); });
- mod.SetName(if2->Result(0), "l");
- b.Return(fn, if2->Result(0));
+ mod.SetName(if2, "l");
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1747,9 +1748,9 @@
auto* if2 = b.If(b.Call(ty.bool_(), fn_a));
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
- b.Append(if2->False(), [&] { b.ExitIf(if2, if1->Result(0)); });
+ b.Append(if2->False(), [&] { b.ExitIf(if2, if1); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1793,9 +1794,9 @@
auto* if2 = b.If(pa);
if2->SetResults(b.InstructionResult(ty.bool_()));
b.Append(if2->True(), [&] { b.ExitIf(if2, true); });
- b.Append(if2->False(), [&] { b.ExitIf(if2, if1->Result(0)); });
+ b.Append(if2->False(), [&] { b.ExitIf(if2, if1); });
- b.Return(fn, if2->Result(0));
+ b.Return(fn, if2);
});
EXPECT_WGSL(R"(
@@ -1813,7 +1814,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Add(ty.i32(), b.Load(v), 1_i));
b.Return(fn);
@@ -1831,7 +1832,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Subtract(ty.i32(), b.Load(v), 1_i));
b.Return(fn);
@@ -1849,7 +1850,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Add(ty.i32(), b.Load(v), 8_i));
b.Return(fn);
@@ -1867,7 +1868,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Subtract(ty.i32(), b.Load(v), 8_i));
b.Return(fn);
@@ -1885,7 +1886,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Multiply(ty.i32(), b.Load(v), 8_i));
b.Return(fn);
@@ -1903,7 +1904,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Divide(ty.i32(), b.Load(v), 8_i));
b.Return(fn);
@@ -1921,7 +1922,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
+ auto* v = b.Var<function, i32>("v");
b.Store(v, b.Xor(ty.i32(), b.Load(v), 8_i));
b.Return(fn);
@@ -1944,9 +1945,8 @@
fn->SetParams({i});
b.Append(fn->Block(), [&] {
- auto* v = b.Complement(ty.u32(), i);
+ auto* v = b.Let("v", b.Complement(ty.u32(), i));
b.Return(fn, v);
- mod.SetName(v, "v");
});
EXPECT_WGSL(R"(
@@ -1963,9 +1963,8 @@
fn->SetParams({i});
b.Append(fn->Block(), [&] {
- auto* v = b.Multiply(ty.i32(), i, 2_i);
+ auto* v = b.Let("v", b.Multiply(ty.i32(), i, 2_i));
b.Return(fn, b.Add(ty.i32(), v, v));
- mod.SetName(v, "v");
});
EXPECT_WGSL(R"(
@@ -1983,7 +1982,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] { //
- b.Var("i", ty.ptr<function, i32>());
+ b.Var<function, i32>("i");
b.Return(fn);
});
@@ -1999,8 +1998,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(42_i));
+ b.Var("i", 42_i);
b.Return(fn);
});
@@ -2016,16 +2014,11 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* va = b.Var("a", ty.ptr<function, i32>());
- va->SetInitializer(b.Constant(42_i));
+ auto* va = b.Var("a", 42_i);
- auto* la = b.Load(va)->Result(0);
- auto* vb = b.Var("b", ty.ptr<function, i32>());
- vb->SetInitializer(la);
+ auto* vb = b.Var("b", b.Load(va));
- auto* lb = b.Load(vb)->Result(0);
- auto* vc = b.Var("c", ty.ptr<function, i32>());
- vc->SetInitializer(lb);
+ b.Var("c", b.Load(vb));
b.Return(fn);
});
@@ -2097,8 +2090,7 @@
auto* fn = b.Function("f", ty.i32());
b.Append(fn->Block(), [&] {
- auto* cond = b.Var("cond", ty.ptr<function, bool>());
- cond->SetInitializer(b.Constant(true));
+ auto* cond = b.Var("cond", true);
auto if_ = b.If(b.Load(cond));
b.Append(if_->True(), [&] { b.Return(fn, 42_i); });
@@ -2162,8 +2154,7 @@
auto* fn = b.Function("f", ty.f32());
b.Append(fn->Block(), [&] {
- auto* cond = b.Var("cond", ty.ptr<function, bool>());
- cond->SetInitializer(b.Constant(true));
+ auto* cond = b.Var("cond", true);
auto if_ = b.If(b.Load(cond));
b.Append(if_->True(), [&] { b.Return(fn, 1.0_f); });
b.Append(if_->False(), [&] { b.Return(fn, 2.0_f); });
@@ -2193,8 +2184,7 @@
auto* fn = b.Function("f", ty.u32());
b.Append(fn->Block(), [&] {
- auto* cond = b.Var("cond", ty.ptr<function, bool>());
- cond->SetInitializer(b.Constant(true));
+ auto* cond = b.Var("cond", true);
auto if_ = b.If(b.Load(cond));
b.Append(if_->True(), [&] { b.Return(fn, 1_u); });
b.Append(if_->False(), [&] {
@@ -2238,8 +2228,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* cond = b.Var("cond", ty.ptr<function, bool>());
- cond->SetInitializer(b.Constant(true));
+ auto* cond = b.Var("cond", true);
auto if1 = b.If(b.Load(cond));
b.Append(if1->True(), [&] {
b.Call(ty.void_(), fn_a);
@@ -2351,8 +2340,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
- v->SetInitializer(b.Constant(42_i));
+ auto* v = b.Var("v", 42_i);
auto s = b.Switch(b.Load(v));
b.Append(b.DefaultCase(s), [&] {
@@ -2391,8 +2379,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
- v->SetInitializer(b.Constant(42_i));
+ auto* v = b.Var("v", 42_i);
auto s = b.Switch(b.Load(v));
b.Append(b.Case(s, {b.Constant(0_i)}), [&] {
@@ -2445,8 +2432,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v = b.Var("v", ty.ptr<function, i32>());
- v->SetInitializer(b.Constant(42_i));
+ auto* v = b.Var("v", 42_i);
auto s = b.Switch(b.Load(v));
b.Append(b.Case(s, {b.Constant(0_i)}), [&] { b.Return(fn); });
@@ -2491,11 +2477,9 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* v1 = b.Var("v1", ty.ptr<function, i32>());
- v1->SetInitializer(b.Constant(42_i));
+ auto* v1 = b.Var("v1", 42_i);
- auto* v2 = b.Var("v2", ty.ptr<function, i32>());
- v2->SetInitializer(b.Constant(24_i));
+ auto* v2 = b.Var("v2", 24_i);
auto s1 = b.Switch(b.Load(v1));
b.Append(b.Case(s1, {b.Constant(0_i)}), [&] {
@@ -2560,8 +2544,7 @@
auto* loop = b.Loop();
b.Append(loop->Initializer(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(0_i));
+ auto* i = b.Var("i", 0_i);
b.NextIteration(loop);
b.Append(loop->Body(), [&] {
@@ -2592,8 +2575,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(0_i));
+ auto* i = b.Var("i", 0_i);
auto* loop = b.Loop();
@@ -2628,8 +2610,7 @@
auto* loop = b.Loop();
b.Append(loop->Initializer(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(0_i));
+ auto* i = b.Var("i", 0_i);
b.NextIteration(loop);
b.Append(loop->Body(), [&] {
@@ -2663,8 +2644,7 @@
auto* loop = b.Loop();
b.Append(loop->Initializer(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(0_i));
+ auto* i = b.Var("i", 0_i);
b.NextIteration(loop);
b.Append(loop->Body(), [&] {
@@ -2714,8 +2694,7 @@
auto* fn = b.Function("f", ty.i32());
b.Append(fn->Block(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(0_i));
+ auto* i = b.Var("i", 0_i);
auto* loop = b.Loop();
@@ -2770,8 +2749,7 @@
auto* loop = b.Loop();
b.Append(loop->Initializer(), [&] {
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(b.Constant(0_i));
+ auto* i = b.Var("i", 0_i);
b.NextIteration(loop);
b.Append(loop->Body(), [&] {
@@ -2820,9 +2798,7 @@
auto* loop = b.Loop();
b.Append(loop->Initializer(), [&] {
- auto* n_0 = b.Call(ty.i32(), fn_n, 0_i)->Result(0);
- auto* i = b.Var("i", ty.ptr<function, i32>());
- i->SetInitializer(n_0);
+ auto* i = b.Var("i", b.Call(ty.i32(), fn_n, 0_i));
b.NextIteration(loop);
b.Append(loop->Body(), [&] {
@@ -2889,7 +2865,7 @@
// }
b.Append(mod.root_block, [&] {
- auto* i = b.Var(ty.ptr<storage, u32, read_write>());
+ auto* i = b.Var<storage, u32, read_write>();
i->SetBindingPoint(0, 0);
auto* fn_f = b.Function("f", ty.void_());
@@ -3156,8 +3132,7 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* cond = b.Var("cond", ty.ptr<function, bool>());
- cond->SetInitializer(b.Constant(false));
+ auto* cond = b.Var("cond", false);
auto* loop = b.Loop();
@@ -3194,14 +3169,12 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- auto* var_b = b.Var("b", ty.ptr<function, i32>());
- var_b->SetInitializer(b.Constant(1_i));
+ auto* var_b = b.Var("b", 1_i);
auto* loop = b.Loop();
b.Append(loop->Body(), [&] {
- auto* var_a = b.Var("a", ty.ptr<function, i32>());
- var_a->SetInitializer(b.Constant(2_i));
+ auto* var_a = b.Var("a", 2_i);
auto* body_load_a = b.Load(var_a);
auto* body_load_b = b.Load(var_b);
@@ -3343,8 +3316,9 @@
TEST_F(IRToProgramTest, Enable_ChromiumExperimentalSubgroups_SubgroupBallot) {
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
- b.Append(mod.instructions.Create<wgsl::ir::BuiltinCall>(
+ auto* call = b.Append(mod.instructions.Create<wgsl::ir::BuiltinCall>(
b.InstructionResult(ty.vec4<u32>()), wgsl::BuiltinFn::kSubgroupBallot, Empty));
+ b.Let("v", call);
b.Return(fn);
});
@@ -3352,7 +3326,7 @@
enable chromium_experimental_subgroups;
fn f() {
- _ = subgroupBallot();
+ let v = subgroupBallot();
}
)");
}
@@ -3361,8 +3335,9 @@
auto* fn = b.Function("f", ty.void_());
b.Append(fn->Block(), [&] {
auto* one = b.Value(1_u);
- b.Append(mod.instructions.Create<wgsl::ir::BuiltinCall>(
+ auto* call = b.Append(mod.instructions.Create<wgsl::ir::BuiltinCall>(
b.InstructionResult(ty.u32()), wgsl::BuiltinFn::kSubgroupBroadcast, Vector{one, one}));
+ b.Let("v", call);
b.Return(fn);
});
@@ -3370,7 +3345,7 @@
enable chromium_experimental_subgroups;
fn f() {
- _ = subgroupBroadcast(1u, 1u);
+ let v = subgroupBroadcast(1u, 1u);
}
)");
}
diff --git a/src/tint/lang/wgsl/writer/raise/raise.cc b/src/tint/lang/wgsl/writer/raise/raise.cc
index 9d69c41..9a64c26 100644
--- a/src/tint/lang/wgsl/writer/raise/raise.cc
+++ b/src/tint/lang/wgsl/writer/raise/raise.cc
@@ -229,7 +229,8 @@
}
}
}
- if (auto result = RenameConflicts(&mod); result != Success) {
+
+ if (auto result = raise::RenameConflicts(mod); result != Success) {
return result.Failure();
}
diff --git a/src/tint/lang/wgsl/writer/raise/rename_conflicts.cc b/src/tint/lang/wgsl/writer/raise/rename_conflicts.cc
index 8ab6b7e..f54efd1 100644
--- a/src/tint/lang/wgsl/writer/raise/rename_conflicts.cc
+++ b/src/tint/lang/wgsl/writer/raise/rename_conflicts.cc
@@ -50,7 +50,7 @@
#include "src/tint/utils/rtti/switch.h"
#include "src/tint/utils/text/string.h"
-namespace tint::wgsl::writer {
+namespace tint::wgsl::writer::raise {
namespace {
@@ -58,7 +58,7 @@
struct State {
/// Constructor
/// @param i the IR module
- explicit State(core::ir::Module* i) : ir(i) {}
+ explicit State(core::ir::Module& i) : ir(i) {}
/// Processes the module, renaming all declarations that would prevent an identifier resolving
/// to the correct declaration.
@@ -69,17 +69,17 @@
RegisterModuleScopeDecls();
// Process the module-scope variable declarations
- for (auto* inst : *ir->root_block) {
+ for (auto* inst : *ir.root_block) {
Process(inst);
}
// Process the functions
- for (core::ir::Function* fn : ir->functions) {
+ for (core::ir::Function* fn : ir.functions) {
scopes.Push(Scope{});
TINT_DEFER(scopes.Pop());
for (auto* param : fn->Params()) {
EnsureResolvable(param->Type());
- if (auto symbol = ir->NameOf(param); symbol.IsValid()) {
+ if (auto symbol = ir.NameOf(param); symbol.IsValid()) {
Declare(scopes.Back(), param, symbol.NameView());
}
}
@@ -93,7 +93,7 @@
using Scope = Hashmap<std::string_view, CastableBase*, 8>;
/// The IR module.
- core::ir::Module* ir = nullptr;
+ core::ir::Module& ir;
/// Stack of scopes
Vector<Scope, 8> scopes{};
@@ -102,7 +102,7 @@
/// Duplicate declarations with the same name will renamed.
void RegisterModuleScopeDecls() {
// Declare all the user types
- for (auto* ty : ir->Types()) {
+ for (auto* ty : ir.Types()) {
if (auto* str = ty->As<core::type::Struct>()) {
auto name = str->Name().NameView();
if (!IsBuiltinStruct(str)) {
@@ -112,17 +112,17 @@
}
// Declare all the module-scope vars
- for (auto* inst : *ir->root_block) {
+ for (auto* inst : *ir.root_block) {
for (auto* result : inst->Results()) {
- if (auto symbol = ir->NameOf(result)) {
+ if (auto symbol = ir.NameOf(result)) {
Declare(scopes.Front(), result, symbol.NameView());
}
}
}
// Declare all the functions
- for (core::ir::Function* fn : ir->functions) {
- if (auto symbol = ir->NameOf(fn); symbol.IsValid()) {
+ for (core::ir::Function* fn : ir.functions) {
+ if (auto symbol = ir.NameOf(fn); symbol.IsValid()) {
Declare(scopes.Back(), fn, symbol.NameView());
}
}
@@ -142,7 +142,7 @@
for (auto* operand : inst->Operands()) {
if (operand) {
// Ensure that named operands can be resolved.
- if (auto symbol = ir->NameOf(operand)) {
+ if (auto symbol = ir.NameOf(operand)) {
EnsureResolvesTo(symbol.NameView(), operand);
}
// If the operand is a constant, then ensure that type name can be resolved.
@@ -195,7 +195,7 @@
// Register new operands and check their types can resolve
for (auto* result : inst->Results()) {
- if (auto symbol = ir->NameOf(result); symbol.IsValid()) {
+ if (auto symbol = ir.NameOf(result); symbol.IsValid()) {
Declare(scopes.Back(), result, symbol.NameView());
}
}
@@ -266,10 +266,10 @@
/// Rename changes the name of @p thing with the old name of @p old_name
void Rename(CastableBase* thing, std::string_view old_name) {
- Symbol new_name = ir->symbols.New(old_name);
+ Symbol new_name = ir.symbols.New(old_name);
Switch(
thing, //
- [&](core::ir::Value* value) { ir->SetName(value, new_name); },
+ [&](core::ir::Value* value) { ir.SetName(value, new_name); },
[&](core::type::Struct* str) { str->SetName(new_name); }, //
TINT_ICE_ON_NO_MATCH);
}
@@ -283,8 +283,8 @@
} // namespace
-Result<SuccessType> RenameConflicts(core::ir::Module* ir) {
- auto result = ValidateAndDumpIfNeeded(*ir, "RenameConflicts transform");
+Result<SuccessType> RenameConflicts(core::ir::Module& ir) {
+ auto result = ValidateAndDumpIfNeeded(ir, "RenameConflicts transform");
if (result != Success) {
return result;
}
@@ -294,4 +294,4 @@
return Success;
}
-} // namespace tint::wgsl::writer
+} // namespace tint::wgsl::writer::raise
diff --git a/src/tint/lang/wgsl/writer/raise/rename_conflicts.h b/src/tint/lang/wgsl/writer/raise/rename_conflicts.h
index 9f5d989..e9c6816 100644
--- a/src/tint/lang/wgsl/writer/raise/rename_conflicts.h
+++ b/src/tint/lang/wgsl/writer/raise/rename_conflicts.h
@@ -38,15 +38,15 @@
class Module;
}
-namespace tint::wgsl::writer {
+namespace tint::wgsl::writer::raise {
/// RenameConflicts is a transform that renames declarations which prevent identifiers from
/// resolving to the correct declaration, and those with identical identifiers declared in the same
/// scope.
/// @param module the module to transform
/// @returns success or failure
-Result<SuccessType> RenameConflicts(core::ir::Module* module);
+Result<SuccessType> RenameConflicts(core::ir::Module& module);
-} // namespace tint::wgsl::writer
+} // namespace tint::wgsl::writer::raise
#endif // SRC_TINT_LANG_WGSL_WRITER_RAISE_RENAME_CONFLICTS_H_
diff --git a/src/tint/lang/wgsl/writer/raise/rename_conflicts_test.cc b/src/tint/lang/wgsl/writer/raise/rename_conflicts_test.cc
index 6facee7..8b28870 100644
--- a/src/tint/lang/wgsl/writer/raise/rename_conflicts_test.cc
+++ b/src/tint/lang/wgsl/writer/raise/rename_conflicts_test.cc
@@ -36,7 +36,7 @@
#include "src/tint/lang/core/ir/validator.h"
#include "src/tint/lang/core/type/matrix.h"
-namespace tint::wgsl::writer {
+namespace tint::wgsl::writer::raise {
namespace {
using namespace tint::core::fluent_types; // NOLINT
@@ -56,7 +56,7 @@
}
// Run the transforms.
- auto result = RenameConflicts(&mod);
+ auto result = RenameConflicts(mod);
EXPECT_EQ(result, Success);
// Validate the output IR.
@@ -1102,4 +1102,4 @@
}
} // namespace
-} // namespace tint::wgsl::writer
+} // namespace tint::wgsl::writer::raise
diff --git a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.bazel b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.bazel
index 96fdf82..6742227 100644
--- a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.bazel
+++ b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.bazel
@@ -61,6 +61,7 @@
"//src/tint/utils/macros",
"//src/tint/utils/math",
"//src/tint/utils/memory",
+ "//src/tint/utils/reflection",
"//src/tint/utils/result",
"//src/tint/utils/rtti",
"//src/tint/utils/strconv",
diff --git a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake
index 859fa03..889fd35 100644
--- a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake
+++ b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.cmake
@@ -60,6 +60,7 @@
tint_utils_macros
tint_utils_math
tint_utils_memory
+ tint_utils_reflection
tint_utils_result
tint_utils_rtti
tint_utils_strconv
diff --git a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.gn b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.gn
index 71df0af..8a70111 100644
--- a/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.gn
+++ b/src/tint/lang/wgsl/writer/syntax_tree_printer/BUILD.gn
@@ -60,6 +60,7 @@
"${tint_src_dir}/utils/macros",
"${tint_src_dir}/utils/math",
"${tint_src_dir}/utils/memory",
+ "${tint_src_dir}/utils/reflection",
"${tint_src_dir}/utils/result",
"${tint_src_dir}/utils/rtti",
"${tint_src_dir}/utils/strconv",
diff --git a/src/tint/utils/bytes/decoder.h b/src/tint/utils/bytes/decoder.h
index 95e9f8f..6901f7c 100644
--- a/src/tint/utils/bytes/decoder.h
+++ b/src/tint/utils/bytes/decoder.h
@@ -35,6 +35,7 @@
#include <tuple>
#include <unordered_map>
#include <utility>
+#include <vector>
#include "src/tint/utils/bytes/reader.h"
#include "src/tint/utils/reflection/reflection.h"
@@ -154,6 +155,34 @@
}
};
+/// Decoder specialization for std::vector
+template <typename V>
+struct Decoder<std::vector<V>, void> {
+ /// Decode decodes the vector from @p reader.
+ /// @param reader the reader to decode from
+ /// @returns the decoded vector, or an error if the stream is too short.
+ static Result<std::vector<V>> Decode(Reader& reader) {
+ std::vector<V> out;
+
+ while (true) {
+ auto stop = bytes::Decode<bool>(reader);
+ if (stop != Success) {
+ return stop.Failure();
+ }
+ if (stop.Get()) {
+ break;
+ }
+ auto val = bytes::Decode<V>(reader);
+ if (val != Success) {
+ return val.Failure();
+ }
+ out.emplace_back(std::move(val.Get()));
+ }
+
+ return out;
+ }
+};
+
/// Decoder specialization for std::optional
template <typename T>
struct Decoder<std::optional<T>, void> {
diff --git a/src/tint/utils/bytes/decoder_test.cc b/src/tint/utils/bytes/decoder_test.cc
index 9bae945..3535298 100644
--- a/src/tint/utils/bytes/decoder_test.cc
+++ b/src/tint/utils/bytes/decoder_test.cc
@@ -154,6 +154,24 @@
EXPECT_NE(Decode<M>(reader), Success);
}
+TEST(BytesDecoderTest, Vector) {
+ using M = std::vector<uint8_t>;
+ auto data = Data(0x00, 0x10, //
+ 0x00, 0x30, //
+ 0x00, 0x50, //
+ 0x00, 0x70, //
+ 0x01);
+ auto reader = BufferReader{Slice{data}};
+ auto got = Decode<M>(reader);
+ EXPECT_THAT(got.Get(), testing::ContainerEq(M{
+ 0x10u,
+ 0x30u,
+ 0x50u,
+ 0x70u,
+ }));
+ EXPECT_NE(Decode<M>(reader), Success);
+}
+
TEST(BytesDecoderTest, Optional) {
auto data = Data(0x00, //
0x01, 0x42);
diff --git a/src/tint/utils/socket/socket.cc b/src/tint/utils/socket/socket.cc
index bab68f2..064823c 100644
--- a/src/tint/utils/socket/socket.cc
+++ b/src/tint/utils/socket/socket.cc
@@ -320,7 +320,8 @@
timeval tv;
tv.tv_sec = timeout_us / 1000000;
- tv.tv_usec = static_cast<int>(timeout_us - (tv.tv_sec * 1000000));
+ using USEC = decltype(tv.tv_usec);
+ tv.tv_usec = static_cast<USEC>(timeout_us) - (static_cast<USEC>(tv.tv_sec) * 1000000);
res = select(static_cast<int>(socket + 1), nullptr, &fdset, nullptr, &tv);
if (res > 0 && !Errored(socket) && SetBlocking(socket, true)) {
out = impl;
diff --git a/src/tint/utils/templates/enums.tmpl.inc b/src/tint/utils/templates/enums.tmpl.inc
index 23dc6d3..45f3945 100644
--- a/src/tint/utils/templates/enums.tmpl.inc
+++ b/src/tint/utils/templates/enums.tmpl.inc
@@ -36,6 +36,24 @@
{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "EnumFirst" -}}
+{{- /* Prints the name of the first enum entry */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+ kUndefined
+{{- end -}}
+
+
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- define "EnumLast" -}}
+{{- /* Prints the name of the last enum entry */ -}}
+{{- /* ------------------------------------------------------------------ */ -}}
+{{- $enum := $ -}}
+{{- $item := index $enum.Entries (Sum -1 (len $enum.Entries)) -}}
+ k{{PascalCase $item.Name}}
+{{- end -}}
+
+
+{{- /* ------------------------------------------------------------------ */ -}}
{{- define "DeclareEnum" -}}
{{- /* Declares the 'enum class' for the provided sem.Enum argument. */ -}}
{{- /* The argument can also be a key-value pair with the following keys: */ -}}