writer/msl: Implement atomics
Common logic between the HLSL, WGSL and MSL writers has been moved into
the TextGenerator base class.
Fixed: tint:892
Change-Id: I0f469516947fe64817ce6251e436da74e5e176e8
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/56068
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@chromium.org>
Reviewed-by: James Price <jrprice@google.com>
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 14a78f9..c808b43 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -669,6 +669,7 @@
utils/unique_vector_test.cc
writer/append_vector_test.cc
writer/float_to_string_test.cc
+ writer/text_generator_test.cc
)
if(${TINT_BUILD_SPV_READER})
diff --git a/src/resolver/atomics_validation_test.cc b/src/resolver/atomics_validation_test.cc
index 767a648..4788d45 100644
--- a/src/resolver/atomics_validation_test.cc
+++ b/src/resolver/atomics_validation_test.cc
@@ -61,7 +61,7 @@
EXPECT_FALSE(r()->Resolve());
EXPECT_EQ(r()->error(),
- "12:34 error: cannot declare an atomic var in a function scope");
+ "12:34 error: atomic var requires workgroup storage");
}
TEST_F(ResolverAtomicValidationTest, NoAtomicExpr) {
diff --git a/src/resolver/resolver.cc b/src/resolver/resolver.cc
index c6462df..f613790 100644
--- a/src/resolver/resolver.cc
+++ b/src/resolver/resolver.cc
@@ -909,21 +909,13 @@
// https://gpuweb.github.io/gpuweb/wgsl/#atomic-types
// Atomic types may only be instantiated by variables in the workgroup storage
// class or by storage buffer variables with a read_write access mode.
- if (info->type->UnwrapRef()->Is<sem::Atomic>()) {
- if (info->kind != VariableKind::kGlobal) {
- // Neither storage nor workgroup storage classes can be used in function
- // scopes.
- AddError("cannot declare an atomic var in a function scope",
- info->declaration->type()->source());
- return false;
- }
- if (info->storage_class != ast::StorageClass::kWorkgroup) {
- // Storage buffers require a structure, so just check for workgroup
- // storage here.
- AddError("atomic var requires workgroup storage",
- info->declaration->type()->source());
- return false;
- }
+ if (info->type->UnwrapRef()->Is<sem::Atomic>() &&
+ info->storage_class != ast::StorageClass::kWorkgroup) {
+ // Storage buffers require a structure, so just check for workgroup
+ // storage here.
+ AddError("atomic var requires workgroup storage",
+ info->declaration->type()->source());
+ return false;
}
return true;
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index 430f05f..9e81adb 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -104,8 +104,7 @@
} // namespace
-GeneratorImpl::GeneratorImpl(const Program* program)
- : builder_(ProgramBuilder::Wrap(program)) {}
+GeneratorImpl::GeneratorImpl(const Program* program) : TextGenerator(program) {}
GeneratorImpl::~GeneratorImpl() = default;
@@ -165,10 +164,6 @@
return true;
}
-std::string GeneratorImpl::generate_name(const std::string& prefix) {
- return builder_.Symbols().NameFor(builder_.Symbols().New(prefix));
-}
-
bool GeneratorImpl::EmitArrayAccessor(std::ostream& out,
ast::ArrayAccessorExpression* expr) {
if (!EmitExpression(out, expr->array())) {
@@ -222,7 +217,7 @@
bool GeneratorImpl::EmitBinary(std::ostream& out, ast::BinaryExpression* expr) {
if (expr->op() == ast::BinaryOp::kLogicalAnd ||
expr->op() == ast::BinaryOp::kLogicalOr) {
- auto name = generate_name(kTempNamePrefix);
+ auto name = UniqueIdentifier(kTempNamePrefix);
{
auto pre = line();
@@ -505,7 +500,7 @@
const transform::DecomposeMemoryAccess::Intrinsic* intrinsic) {
const auto& params = expr->params();
- std::string scalar_offset = generate_name("scalar_offset");
+ std::string scalar_offset = UniqueIdentifier("scalar_offset");
{
auto pre = line();
pre << "const int " << scalar_offset << " = (";
@@ -534,7 +529,7 @@
};
// Has a minimum alignment of 8 bytes, so is either .xy or .zw
auto load_vec2 = [&] {
- std::string ubo_load = generate_name("ubo_load");
+ std::string ubo_load = UniqueIdentifier("ubo_load");
{
auto pre = line();
@@ -744,7 +739,7 @@
transform::DecomposeMemoryAccess::Intrinsic::Op op) {
using Op = transform::DecomposeMemoryAccess::Intrinsic::Op;
- std::string result = generate_name("atomic_result");
+ std::string result = UniqueIdentifier("atomic_result");
auto* result_ty = TypeOf(expr);
if (!result_ty->Is<sem::Void>()) {
@@ -849,7 +844,7 @@
auto* compare_value = expr->params()[2];
auto* value = expr->params()[3];
- std::string compare = generate_name("atomic_compare_value");
+ std::string compare = UniqueIdentifier("atomic_compare_value");
{ // T atomic_compare_value = compare_value;
auto pre = line();
if (!EmitTypeAndName(pre, TypeOf(compare_value),
@@ -924,7 +919,7 @@
bool GeneratorImpl::EmitWorkgroupAtomicCall(std::ostream& out,
ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
- std::string result = generate_name("atomic_result");
+ std::string result = UniqueIdentifier("atomic_result");
if (!intrinsic->ReturnType()->Is<sem::Void>()) {
auto pre = line();
@@ -1018,7 +1013,7 @@
auto* compare_value = expr->params()[1];
auto* value = expr->params()[2];
- std::string compare = generate_name("atomic_compare_value");
+ std::string compare = UniqueIdentifier("atomic_compare_value");
{ // T compare_value = <compare_value>;
auto pre = line();
@@ -1130,8 +1125,8 @@
// Exponent is an integer, which HLSL does not have an overload for.
// We need to cast from a float.
- auto float_exp = generate_name(kTempNamePrefix);
- auto significand = generate_name(kTempNamePrefix);
+ auto float_exp = UniqueIdentifier(kTempNamePrefix);
+ auto significand = UniqueIdentifier(kTempNamePrefix);
line() << "float" << width << " " << float_exp << ";";
{
auto pre = line();
@@ -1173,8 +1168,8 @@
constexpr auto* kMinNormalExponent = "0x0080000";
constexpr auto* kMaxNormalExponent = "0x7f00000";
- auto exponent = generate_name("tint_isnormal_exponent");
- auto clamped = generate_name("tint_isnormal_clamped");
+ auto exponent = UniqueIdentifier("tint_isnormal_exponent");
+ auto clamped = UniqueIdentifier("tint_isnormal_clamped");
{
auto pre = line();
@@ -1196,7 +1191,7 @@
ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
auto* param = expr->params()[0];
- auto tmp_name = generate_name(kTempNamePrefix);
+ auto tmp_name = UniqueIdentifier(kTempNamePrefix);
std::ostringstream expr_out;
if (!EmitExpression(expr_out, param)) {
return false;
@@ -1261,7 +1256,7 @@
ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
auto* param = expr->params()[0];
- auto tmp_name = generate_name(kTempNamePrefix);
+ auto tmp_name = UniqueIdentifier(kTempNamePrefix);
std::ostringstream expr_out;
if (!EmitExpression(expr_out, param)) {
return false;
@@ -1282,7 +1277,7 @@
switch (intrinsic->Type()) {
case sem::IntrinsicType::kUnpack4x8snorm:
case sem::IntrinsicType::kUnpack2x16snorm: {
- auto tmp_name2 = generate_name(kTempNamePrefix);
+ auto tmp_name2 = UniqueIdentifier(kTempNamePrefix);
line() << "int " << tmp_name2 << " = int(" << expr_out.str() << ");";
{ // Perform sign extension on the converted values.
auto pre = line();
@@ -1302,7 +1297,7 @@
}
case sem::IntrinsicType::kUnpack4x8unorm:
case sem::IntrinsicType::kUnpack2x16unorm: {
- auto tmp_name2 = generate_name(kTempNamePrefix);
+ auto tmp_name2 = UniqueIdentifier(kTempNamePrefix);
line() << "uint " << tmp_name2 << " = " << expr_out.str() << ";";
{
auto pre = line();
@@ -1492,7 +1487,7 @@
}
// Declare a variable to hold the queried texture info
- auto dims = generate_name(kTempNamePrefix);
+ auto dims = UniqueIdentifier(kTempNamePrefix);
if (num_dimensions == 1) {
line() << "int " << dims << ";";
} else {
diff --git a/src/writer/hlsl/generator_impl.h b/src/writer/hlsl/generator_impl.h
index 77f2bcf..58b791d 100644
--- a/src/writer/hlsl/generator_impl.h
+++ b/src/writer/hlsl/generator_impl.h
@@ -361,11 +361,6 @@
ast::InterpolationType type,
ast::InterpolationSampling sampling) const;
- /// Generate a unique name
- /// @param prefix the name prefix
- /// @returns a unique name
- std::string generate_name(const std::string& prefix);
-
private:
enum class VarType { kIn, kOut };
@@ -376,25 +371,6 @@
std::string get_buffer_name(ast::Expression* expr);
- /// @returns the resolved type of the ast::Expression `expr`
- /// @param expr the expression
- sem::Type* TypeOf(ast::Expression* expr) const {
- return builder_.TypeOf(expr);
- }
-
- /// @returns the resolved type of the ast::Type `type`
- /// @param type the type
- const sem::Type* TypeOf(const ast::Type* type) const {
- return builder_.TypeOf(type);
- }
-
- /// @returns the resolved type of the ast::TypeDecl `type_decl`
- /// @param type_decl the type
- const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const {
- return builder_.TypeOf(type_decl);
- }
-
- ProgramBuilder builder_;
std::function<bool()> emit_continuing_;
std::unordered_map<const sem::Struct*, std::string> structure_builders_;
};
diff --git a/src/writer/hlsl/generator_impl_test.cc b/src/writer/hlsl/generator_impl_test.cc
index 30cf659..cd01730 100644
--- a/src/writer/hlsl/generator_impl_test.cc
+++ b/src/writer/hlsl/generator_impl_test.cc
@@ -43,24 +43,6 @@
)");
}
-TEST_F(HlslGeneratorImplTest, InputStructName) {
- GeneratorImpl& gen = Build();
-
- ASSERT_EQ(gen.generate_name("func_main_in"), "func_main_in");
-}
-
-TEST_F(HlslGeneratorImplTest, InputStructName_ConflictWithExisting) {
- Symbols().Register("func_main_out_1");
- Symbols().Register("func_main_out_2");
-
- GeneratorImpl& gen = Build();
-
- ASSERT_EQ(gen.generate_name("func_main_out"), "func_main_out");
- ASSERT_EQ(gen.generate_name("func_main_out"), "func_main_out_3");
- ASSERT_EQ(gen.generate_name("func_main_out"), "func_main_out_4");
- ASSERT_EQ(gen.generate_name("func_main_out"), "func_main_out_5");
-}
-
struct HlslBuiltinData {
ast::Builtin builtin;
const char* attribute_name;
diff --git a/src/writer/msl/generator.cc b/src/writer/msl/generator.cc
index 9f08f56..3c2190f 100644
--- a/src/writer/msl/generator.cc
+++ b/src/writer/msl/generator.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include "src/writer/msl/generator.h"
+#include "src/writer/msl/generator_impl.h"
namespace tint {
namespace writer {
diff --git a/src/writer/msl/generator.h b/src/writer/msl/generator.h
index 3844875..d63f755 100644
--- a/src/writer/msl/generator.h
+++ b/src/writer/msl/generator.h
@@ -18,13 +18,14 @@
#include <memory>
#include <string>
-#include "src/writer/msl/generator_impl.h"
#include "src/writer/text.h"
namespace tint {
namespace writer {
namespace msl {
+class GeneratorImpl;
+
/// Class to generate MSL source
class Generator : public Text {
public:
@@ -46,6 +47,9 @@
std::string error() const;
private:
+ Generator(const Generator&) = delete;
+ Generator& operator=(const Generator&) = delete;
+
std::unique_ptr<GeneratorImpl> impl_;
};
diff --git a/src/writer/msl/generator_impl.cc b/src/writer/msl/generator_impl.cc
index a12c44d..bf7ffab 100644
--- a/src/writer/msl/generator_impl.cc
+++ b/src/writer/msl/generator_impl.cc
@@ -33,6 +33,7 @@
#include "src/ast/variable_decl_statement.h"
#include "src/ast/void.h"
#include "src/sem/array.h"
+#include "src/sem/atomic_type.h"
#include "src/sem/bool_type.h"
#include "src/sem/call.h"
#include "src/sem/depth_texture_type.h"
@@ -71,8 +72,7 @@
} // namespace
-GeneratorImpl::GeneratorImpl(const Program* program)
- : TextGenerator(), program_(program) {}
+GeneratorImpl::GeneratorImpl(const Program* program) : TextGenerator(program) {}
GeneratorImpl::~GeneratorImpl() = default;
@@ -359,6 +359,9 @@
bool GeneratorImpl::EmitIntrinsicCall(std::ostream& out,
ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
+ if (intrinsic->IsAtomic()) {
+ return EmitAtomicCall(out, expr, intrinsic);
+ }
if (intrinsic->IsTexture()) {
return EmitTextureCall(out, expr, intrinsic);
}
@@ -422,6 +425,111 @@
return true;
}
+bool GeneratorImpl::EmitAtomicCall(std::ostream& out,
+ ast::CallExpression* expr,
+ const sem::Intrinsic* intrinsic) {
+ auto call = [&](const char* name) {
+ out << name;
+ {
+ ScopedParen sp(out);
+ for (size_t i = 0; i < expr->params().size(); i++) {
+ auto* arg = expr->params()[i];
+ if (i > 0) {
+ out << ", ";
+ }
+ if (!EmitExpression(out, arg)) {
+ return false;
+ }
+ }
+ out << ", memory_order_relaxed";
+ }
+ return true;
+ };
+
+ switch (intrinsic->Type()) {
+ case sem::IntrinsicType::kAtomicLoad:
+ return call("atomic_load_explicit");
+
+ case sem::IntrinsicType::kAtomicStore:
+ return call("atomic_store_explicit");
+
+ case sem::IntrinsicType::kAtomicAdd:
+ return call("atomic_fetch_add_explicit");
+
+ case sem::IntrinsicType::kAtomicMax:
+ return call("atomic_fetch_max_explicit");
+
+ case sem::IntrinsicType::kAtomicMin:
+ return call("atomic_fetch_min_explicit");
+
+ case sem::IntrinsicType::kAtomicAnd:
+ return call("atomic_fetch_and_explicit");
+
+ case sem::IntrinsicType::kAtomicOr:
+ return call("atomic_fetch_or_explicit");
+
+ case sem::IntrinsicType::kAtomicXor:
+ return call("atomic_fetch_xor_explicit");
+
+ case sem::IntrinsicType::kAtomicExchange:
+ return call("atomic_exchange_explicit");
+
+ case sem::IntrinsicType::kAtomicCompareExchangeWeak: {
+ auto* target = expr->params()[0];
+ auto* compare_value = expr->params()[1];
+ auto* value = expr->params()[2];
+
+ auto prev_value = UniqueIdentifier("prev_value");
+ auto matched = UniqueIdentifier("matched");
+
+ { // prev_value = <compare_value>;
+ auto pre = line();
+ if (!EmitType(pre, TypeOf(value), "")) {
+ return false;
+ }
+ pre << " " << prev_value << " = ";
+ if (!EmitExpression(pre, compare_value)) {
+ return false;
+ }
+ pre << ";";
+ }
+
+ { // bool matched = atomic_compare_exchange_weak_explicit(
+ // target, &got, <value>, memory_order_relaxed, memory_order_relaxed)
+ auto pre = line();
+ pre << "bool " << matched << " = atomic_compare_exchange_weak_explicit";
+ {
+ ScopedParen sp(pre);
+ if (!EmitExpression(pre, target)) {
+ return false;
+ }
+ pre << ", &" << prev_value << ", ";
+ if (!EmitExpression(pre, value)) {
+ return false;
+ }
+ pre << ", memory_order_relaxed, memory_order_relaxed";
+ }
+ pre << ";";
+ }
+
+ { // [u]int2(got, matched)
+ if (!EmitType(out, TypeOf(expr), "")) {
+ return false;
+ }
+ out << "(" << prev_value << ", " << matched << ")";
+ }
+ return true;
+ }
+
+ default:
+ break;
+ }
+
+ TINT_UNREACHABLE(Writer, diagnostics_)
+ << "unsupported atomic intrinsic: " << intrinsic->Type();
+ return false;
+}
+
bool GeneratorImpl::EmitTextureCall(std::ostream& out,
ast::CallExpression* expr,
const sem::Intrinsic* intrinsic) {
@@ -1550,6 +1658,20 @@
bool GeneratorImpl::EmitType(std::ostream& out,
const sem::Type* type,
const std::string& name) {
+ if (auto* atomic = type->As<sem::Atomic>()) {
+ if (atomic->Type()->Is<sem::I32>()) {
+ out << "atomic_int";
+ return true;
+ }
+ if (atomic->Type()->Is<sem::U32>()) {
+ out << "atomic_uint";
+ return true;
+ }
+ TINT_ICE(Writer, diagnostics_)
+ << "unhandled atomic type " << atomic->Type()->type_name();
+ return false;
+ }
+
if (auto* ary = type->As<sem::Array>()) {
const sem::Type* base_type = ary;
std::vector<uint32_t> sizes;
@@ -1570,18 +1692,33 @@
for (uint32_t size : sizes) {
out << "[" << size << "]";
}
- } else if (type->Is<sem::Bool>()) {
+ return true;
+ }
+
+ if (type->Is<sem::Bool>()) {
out << "bool";
- } else if (type->Is<sem::F32>()) {
+ return true;
+ }
+
+ if (type->Is<sem::F32>()) {
out << "float";
- } else if (type->Is<sem::I32>()) {
+ return true;
+ }
+
+ if (type->Is<sem::I32>()) {
out << "int";
- } else if (auto* mat = type->As<sem::Matrix>()) {
+ return true;
+ }
+
+ if (auto* mat = type->As<sem::Matrix>()) {
if (!EmitType(out, mat->type(), "")) {
return false;
}
out << mat->columns() << "x" << mat->rows();
- } else if (auto* ptr = type->As<sem::Pointer>()) {
+ return true;
+ }
+
+ if (auto* ptr = type->As<sem::Pointer>()) {
switch (ptr->StorageClass()) {
case ast::StorageClass::kFunction:
case ast::StorageClass::kPrivate:
@@ -1611,13 +1748,22 @@
}
out << "* " << name;
}
- } else if (type->Is<sem::Sampler>()) {
+ return true;
+ }
+
+ if (type->Is<sem::Sampler>()) {
out << "sampler";
- } else if (auto* str = type->As<sem::Struct>()) {
+ return true;
+ }
+
+ if (auto* str = type->As<sem::Struct>()) {
// The struct type emits as just the name. The declaration would be emitted
// as part of emitting the declared types.
out << program_->Symbols().NameFor(str->Declaration()->name());
- } else if (auto* tex = type->As<sem::Texture>()) {
+ return true;
+ }
+
+ if (auto* tex = type->As<sem::Texture>()) {
if (tex->Is<sem::DepthTexture>()) {
out << "depth";
} else {
@@ -1684,23 +1830,30 @@
return false;
}
out << ">";
+ return true;
+ }
- } else if (type->Is<sem::U32>()) {
+ if (type->Is<sem::U32>()) {
out << "uint";
- } else if (auto* vec = type->As<sem::Vector>()) {
+ return true;
+ }
+
+ if (auto* vec = type->As<sem::Vector>()) {
if (!EmitType(out, vec->type(), "")) {
return false;
}
out << vec->size();
- } else if (type->Is<sem::Void>()) {
- out << "void";
- } else {
- diagnostics_.add_error(diag::System::Writer,
- "unknown type in EmitType: " + type->type_name());
- return false;
+ return true;
}
- return true;
+ if (type->Is<sem::Void>()) {
+ out << "void";
+ return true;
+ }
+
+ diagnostics_.add_error(diag::System::Writer,
+ "unknown type in EmitType: " + type->type_name());
+ return false;
}
bool GeneratorImpl::EmitPackedType(std::ostream& out,
@@ -2039,6 +2192,10 @@
return SizeAndAlign{str->Size(), str->Align()};
}
+ if (auto* atomic = ty->As<sem::Atomic>()) {
+ return MslPackedTypeSizeAndAlign(atomic->Type());
+ }
+
TINT_UNREACHABLE(Writer, diagnostics_)
<< "Unhandled type " << ty->TypeInfo().name;
return {};
diff --git a/src/writer/msl/generator_impl.h b/src/writer/msl/generator_impl.h
index a527eb9..0f5bf1a 100644
--- a/src/writer/msl/generator_impl.h
+++ b/src/writer/msl/generator_impl.h
@@ -104,6 +104,15 @@
bool EmitIntrinsicCall(std::ostream& out,
ast::CallExpression* expr,
const sem::Intrinsic* intrinsic);
+ /// Handles generating a call to an atomic function (`atomicAdd`,
+ /// `atomicMax`, etc)
+ /// @param out the output of the expression stream
+ /// @param expr the call expression
+ /// @param intrinsic the semantic information for the atomic intrinsic
+ /// @returns true if the call expression is emitted
+ bool EmitAtomicCall(std::ostream& out,
+ ast::CallExpression* expr,
+ const sem::Intrinsic* intrinsic);
/// Handles generating a call to a texture function (`textureSample`,
/// `textureSampleGrad`, etc)
/// @param out the output of the expression stream
@@ -263,24 +272,6 @@
ast::InterpolationSampling sampling) const;
private:
- /// @returns the resolved type of the ast::Expression `expr`
- /// @param expr the expression
- sem::Type* TypeOf(ast::Expression* expr) const {
- return program_->TypeOf(expr);
- }
-
- /// @returns the resolved type of the ast::Type `type`
- /// @param type the type
- const sem::Type* TypeOf(const ast::Type* type) const {
- return program_->TypeOf(type);
- }
-
- /// @returns the resolved type of the ast::TypeDecl `type_decl`
- /// @param type_decl the type declaration
- const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const {
- return program_->TypeOf(type_decl);
- }
-
// A pair of byte size and alignment `uint32_t`s.
struct SizeAndAlign {
uint32_t size;
@@ -291,7 +282,6 @@
/// type.
SizeAndAlign MslPackedTypeSizeAndAlign(const sem::Type* ty);
- const Program* program_ = nullptr;
std::function<bool()> emit_continuing_;
};
diff --git a/src/writer/text_generator.cc b/src/writer/text_generator.cc
index a3ec05c..6a6c364 100644
--- a/src/writer/text_generator.cc
+++ b/src/writer/text_generator.cc
@@ -14,10 +14,13 @@
#include "src/writer/text_generator.h"
+#include <limits>
+
namespace tint {
namespace writer {
-TextGenerator::TextGenerator() = default;
+TextGenerator::TextGenerator(const Program* program)
+ : program_(program), builder_(ProgramBuilder::Wrap(program)) {}
TextGenerator::~TextGenerator() = default;
@@ -31,6 +34,10 @@
}
}
+std::string TextGenerator::UniqueIdentifier(const std::string& prefix) {
+ return builder_.Symbols().NameFor(builder_.Symbols().New(prefix));
+}
+
TextGenerator::LineWriter::LineWriter(TextGenerator* generator)
: gen(generator) {}
diff --git a/src/writer/text_generator.h b/src/writer/text_generator.h
index 8f68385..57011d9 100644
--- a/src/writer/text_generator.h
+++ b/src/writer/text_generator.h
@@ -20,6 +20,7 @@
#include <utility>
#include "src/diagnostic/diagnostic.h"
+#include "src/program_builder.h"
namespace tint {
namespace writer {
@@ -28,7 +29,8 @@
class TextGenerator {
public:
/// Constructor
- TextGenerator();
+ /// @param program the program used by the generator
+ explicit TextGenerator(const Program* program);
~TextGenerator();
/// Increment the emitter indent level
@@ -58,6 +60,11 @@
/// @returns the error
std::string error() const { return diagnostics_.str(); }
+ /// @return a new, unique identifier with the given prefix.
+ /// @param prefix optional prefix to apply to the generated identifier. If
+ /// empty "tint" will be used.
+ std::string UniqueIdentifier(const std::string& prefix = "");
+
protected:
/// LineWriter is a helper that acts as a string buffer, who's content is
/// emitted to the TextGenerator as a single line on destruction.
@@ -122,9 +129,31 @@
TextGenerator* gen;
};
+ /// @returns the resolved type of the ast::Expression `expr`
+ /// @param expr the expression
+ sem::Type* TypeOf(ast::Expression* expr) const {
+ return builder_.TypeOf(expr);
+ }
+
+ /// @returns the resolved type of the ast::Type `type`
+ /// @param type the type
+ const sem::Type* TypeOf(const ast::Type* type) const {
+ return builder_.TypeOf(type);
+ }
+
+ /// @returns the resolved type of the ast::TypeDecl `type_decl`
+ /// @param type_decl the type
+ const sem::Type* TypeOf(const ast::TypeDecl* type_decl) const {
+ return builder_.TypeOf(type_decl);
+ }
+
/// @returns a new LineWriter, used for buffering and writing a line to out_
LineWriter line() { return LineWriter(this); }
+ /// The program
+ Program const* const program_;
+ /// A ProgramBuilder that thinly wraps program_
+ ProgramBuilder builder_;
/// The text output stream
std::ostringstream out_;
/// Diagnostics generated by the generator
diff --git a/src/writer/text_generator_test.cc b/src/writer/text_generator_test.cc
new file mode 100644
index 0000000..10c7086
--- /dev/null
+++ b/src/writer/text_generator_test.cc
@@ -0,0 +1,48 @@
+// Copyright 2021 The Tint Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/writer/text_generator.h"
+
+#include "gtest/gtest.h"
+
+namespace tint {
+namespace writer {
+namespace {
+
+TEST(TextGeneratorTest, UniqueIdentifier) {
+ Program program(ProgramBuilder{});
+
+ TextGenerator gen(&program);
+
+ ASSERT_EQ(gen.UniqueIdentifier("ident"), "ident");
+ ASSERT_EQ(gen.UniqueIdentifier("ident"), "ident_1");
+}
+
+TEST(TextGeneratorTest, UniqueIdentifier_ConflictWithExisting) {
+ ProgramBuilder builder;
+ builder.Symbols().Register("ident_1");
+ builder.Symbols().Register("ident_2");
+ Program program(std::move(builder));
+
+ TextGenerator gen(&program);
+
+ ASSERT_EQ(gen.UniqueIdentifier("ident"), "ident");
+ ASSERT_EQ(gen.UniqueIdentifier("ident"), "ident_3");
+ ASSERT_EQ(gen.UniqueIdentifier("ident"), "ident_4");
+ ASSERT_EQ(gen.UniqueIdentifier("ident"), "ident_5");
+}
+
+} // namespace
+} // namespace writer
+} // namespace tint
diff --git a/src/writer/wgsl/generator.cc b/src/writer/wgsl/generator.cc
index f190463..36eeabc 100644
--- a/src/writer/wgsl/generator.cc
+++ b/src/writer/wgsl/generator.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include "src/writer/wgsl/generator.h"
+#include "src/writer/wgsl/generator_impl.h"
namespace tint {
namespace writer {
diff --git a/src/writer/wgsl/generator.h b/src/writer/wgsl/generator.h
index 6085ecf..6b0b358 100644
--- a/src/writer/wgsl/generator.h
+++ b/src/writer/wgsl/generator.h
@@ -19,12 +19,13 @@
#include <string>
#include "src/writer/text.h"
-#include "src/writer/wgsl/generator_impl.h"
namespace tint {
namespace writer {
namespace wgsl {
+class GeneratorImpl;
+
/// Class to generate WGSL source
class Generator : public Text {
public:
@@ -46,6 +47,9 @@
std::string error() const;
private:
+ Generator(const Generator&) = delete;
+ Generator& operator=(const Generator&) = delete;
+
std::unique_ptr<GeneratorImpl> impl_;
};
diff --git a/src/writer/wgsl/generator_impl.cc b/src/writer/wgsl/generator_impl.cc
index 42785a8..077e990 100644
--- a/src/writer/wgsl/generator_impl.cc
+++ b/src/writer/wgsl/generator_impl.cc
@@ -15,7 +15,6 @@
#include "src/writer/wgsl/generator_impl.h"
#include <algorithm>
-#include <limits>
#include "src/ast/access.h"
#include "src/ast/alias.h"
@@ -60,8 +59,7 @@
namespace writer {
namespace wgsl {
-GeneratorImpl::GeneratorImpl(const Program* program)
- : TextGenerator(), program_(program) {}
+GeneratorImpl::GeneratorImpl(const Program* program) : TextGenerator(program) {}
GeneratorImpl::~GeneratorImpl() = default;
@@ -1059,24 +1057,6 @@
return true;
}
-std::string GeneratorImpl::UniqueIdentifier(const std::string& suffix) {
- auto const limit =
- std::numeric_limits<decltype(next_unique_identifier_suffix)>::max();
- while (next_unique_identifier_suffix < limit) {
- auto ident = "tint_" + std::to_string(next_unique_identifier_suffix);
- if (!suffix.empty()) {
- ident += "_" + suffix;
- }
- next_unique_identifier_suffix++;
- if (!program_->Symbols().Get(ident).IsValid()) {
- return ident;
- }
- }
- diagnostics_.add_error(diag::System::Writer,
- "Unable to generate a unique WGSL identifier");
- return "<invalid-ident>";
-}
-
} // namespace wgsl
} // namespace writer
} // namespace tint
diff --git a/src/writer/wgsl/generator_impl.h b/src/writer/wgsl/generator_impl.h
index ad9f535..7d7c732 100644
--- a/src/writer/wgsl/generator_impl.h
+++ b/src/writer/wgsl/generator_impl.h
@@ -194,13 +194,6 @@
/// @param decos the decoration list
/// @returns true if the decorations were emitted
bool EmitDecorations(const ast::DecorationList& decos);
-
- private:
- /// @return a new, unique, valid WGSL identifier with the given suffix.
- std::string UniqueIdentifier(const std::string& suffix = "");
-
- Program const* const program_;
- uint32_t next_unique_identifier_suffix = 0;
};
} // namespace wgsl
diff --git a/src/writer/wgsl/generator_impl_type_test.cc b/src/writer/wgsl/generator_impl_type_test.cc
index 991dc69..3273e92 100644
--- a/src/writer/wgsl/generator_impl_type_test.cc
+++ b/src/writer/wgsl/generator_impl_type_test.cc
@@ -141,10 +141,10 @@
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S {
[[size(8)]]
- tint_0_padding : u32;
+ padding : u32;
a : i32;
[[size(4)]]
- tint_1_padding : u32;
+ padding_1 : u32;
b : f32;
};
)");
@@ -162,10 +162,10 @@
ASSERT_TRUE(gen.EmitStructType(s)) << gen.error();
EXPECT_EQ(gen.result(), R"(struct S {
[[size(8)]]
- tint_1_padding : u32;
+ padding : u32;
tint_0_padding : i32;
[[size(4)]]
- tint_3_padding : u32;
+ padding_1 : u32;
tint_2_padding : f32;
};
)");
diff --git a/test/BUILD.gn b/test/BUILD.gn
index e120d8b..fba8220 100644
--- a/test/BUILD.gn
+++ b/test/BUILD.gn
@@ -305,6 +305,7 @@
"../src/utils/unique_vector_test.cc",
"../src/writer/append_vector_test.cc",
"../src/writer/float_to_string_test.cc",
+ "../src/writer/text_generator_test.cc",
]
deps = [
diff --git a/test/intrinsics/gen/atomicAdd/794055.wgsl.expected.msl b/test/intrinsics/gen/atomicAdd/794055.wgsl.expected.msl
index 9cf781e..825608b 100644
--- a/test/intrinsics/gen/atomicAdd/794055.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAdd/794055.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicAdd_794055(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicAdd(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicAdd_794055(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_fetch_add_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicAdd_794055(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicAdd_794055(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicAdd/8a199a.wgsl.expected.msl b/test/intrinsics/gen/atomicAdd/8a199a.wgsl.expected.msl
index 86b5492..4d1bb52 100644
--- a/test/intrinsics/gen/atomicAdd/8a199a.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAdd/8a199a.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicAdd_8a199a() {
- var res : u32 = atomicAdd(&(sb_rw.arg_0), 1u);
+void atomicAdd_8a199a(device SB_RW& sb_rw) {
+ uint res = atomic_fetch_add_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicAdd_8a199a();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAdd_8a199a(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicAdd_8a199a();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAdd_8a199a(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicAdd/d32fe4.wgsl.expected.msl b/test/intrinsics/gen/atomicAdd/d32fe4.wgsl.expected.msl
index 85b0ee5..a1e838a 100644
--- a/test/intrinsics/gen/atomicAdd/d32fe4.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAdd/d32fe4.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicAdd_d32fe4() {
- var res : i32 = atomicAdd(&(sb_rw.arg_0), 1);
+void atomicAdd_d32fe4(device SB_RW& sb_rw) {
+ int res = atomic_fetch_add_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicAdd_d32fe4();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAdd_d32fe4(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicAdd_d32fe4();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAdd_d32fe4(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicAdd/d5db1d.wgsl.expected.msl b/test/intrinsics/gen/atomicAdd/d5db1d.wgsl.expected.msl
index 3e13cfd..ee51545 100644
--- a/test/intrinsics/gen/atomicAdd/d5db1d.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAdd/d5db1d.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicAdd_d5db1d(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicAdd(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicAdd_d5db1d(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_fetch_add_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicAdd_d5db1d(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicAdd_d5db1d(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicAnd/152966.wgsl.expected.msl b/test/intrinsics/gen/atomicAnd/152966.wgsl.expected.msl
index efcd326..d095ebb 100644
--- a/test/intrinsics/gen/atomicAnd/152966.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAnd/152966.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicAnd_152966() {
- var res : i32 = atomicAnd(&(sb_rw.arg_0), 1);
+void atomicAnd_152966(device SB_RW& sb_rw) {
+ int res = atomic_fetch_and_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicAnd_152966();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAnd_152966(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicAnd_152966();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAnd_152966(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicAnd/34edd3.wgsl.expected.msl b/test/intrinsics/gen/atomicAnd/34edd3.wgsl.expected.msl
index 6a5bb56..dd88dd3 100644
--- a/test/intrinsics/gen/atomicAnd/34edd3.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAnd/34edd3.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicAnd_34edd3(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicAnd(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicAnd_34edd3(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_fetch_and_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicAnd_34edd3(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicAnd_34edd3(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicAnd/45a819.wgsl.expected.msl b/test/intrinsics/gen/atomicAnd/45a819.wgsl.expected.msl
index 47755f6..7a700e9 100644
--- a/test/intrinsics/gen/atomicAnd/45a819.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAnd/45a819.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicAnd_45a819(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicAnd(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicAnd_45a819(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_fetch_and_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicAnd_45a819(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicAnd_45a819(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicAnd/85a8d9.wgsl.expected.msl b/test/intrinsics/gen/atomicAnd/85a8d9.wgsl.expected.msl
index 31f25e8..b9ca1b0 100644
--- a/test/intrinsics/gen/atomicAnd/85a8d9.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicAnd/85a8d9.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicAnd_85a8d9() {
- var res : u32 = atomicAnd(&(sb_rw.arg_0), 1u);
+void atomicAnd_85a8d9(device SB_RW& sb_rw) {
+ uint res = atomic_fetch_and_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicAnd_85a8d9();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAnd_85a8d9(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicAnd_85a8d9();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicAnd_85a8d9(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicCompareExchangeWeak/12871c.wgsl.expected.msl b/test/intrinsics/gen/atomicCompareExchangeWeak/12871c.wgsl.expected.msl
index 7135dea..56d8090 100644
--- a/test/intrinsics/gen/atomicCompareExchangeWeak/12871c.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicCompareExchangeWeak/12871c.wgsl.expected.msl
@@ -1,25 +1,23 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicCompareExchangeWeak_12871c() {
- var res : vec2<i32> = atomicCompareExchangeWeak(&(sb_rw.arg_0), 1, 1);
+void atomicCompareExchangeWeak_12871c(device SB_RW& sb_rw) {
+ int prev_value = 1;
+ bool matched = atomic_compare_exchange_weak_explicit(&(sb_rw.arg_0), &prev_value, 1, memory_order_relaxed, memory_order_relaxed);
+ int2 res = int2(prev_value, matched);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicCompareExchangeWeak_12871c();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicCompareExchangeWeak_12871c(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicCompareExchangeWeak_12871c();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicCompareExchangeWeak_12871c(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicCompareExchangeWeak/6673da.wgsl.expected.msl b/test/intrinsics/gen/atomicCompareExchangeWeak/6673da.wgsl.expected.msl
index a6c99ce..c4999ee 100644
--- a/test/intrinsics/gen/atomicCompareExchangeWeak/6673da.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicCompareExchangeWeak/6673da.wgsl.expected.msl
@@ -1,25 +1,23 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicCompareExchangeWeak_6673da() {
- var res : vec2<u32> = atomicCompareExchangeWeak(&(sb_rw.arg_0), 1u, 1u);
+void atomicCompareExchangeWeak_6673da(device SB_RW& sb_rw) {
+ uint prev_value = 1u;
+ bool matched = atomic_compare_exchange_weak_explicit(&(sb_rw.arg_0), &prev_value, 1u, memory_order_relaxed, memory_order_relaxed);
+ uint2 res = uint2(prev_value, matched);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicCompareExchangeWeak_6673da();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicCompareExchangeWeak_6673da(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicCompareExchangeWeak_6673da();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicCompareExchangeWeak_6673da(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicCompareExchangeWeak/89ea3b.wgsl.expected.msl b/test/intrinsics/gen/atomicCompareExchangeWeak/89ea3b.wgsl.expected.msl
index c6431fb..036e9bf 100644
--- a/test/intrinsics/gen/atomicCompareExchangeWeak/89ea3b.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicCompareExchangeWeak/89ea3b.wgsl.expected.msl
@@ -1,14 +1,19 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicCompareExchangeWeak_89ea3b(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : vec2<i32> = atomicCompareExchangeWeak(&(*(tint_symbol)), 1, 1);
+using namespace metal;
+void atomicCompareExchangeWeak_89ea3b(threadgroup atomic_int* const tint_symbol_1) {
+ int prev_value = 1;
+ bool matched = atomic_compare_exchange_weak_explicit(&(*(tint_symbol_1)), &prev_value, 1, memory_order_relaxed, memory_order_relaxed);
+ int2 res = int2(prev_value, matched);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicCompareExchangeWeak_89ea3b(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicCompareExchangeWeak_89ea3b(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicCompareExchangeWeak/b2ab2c.wgsl.expected.msl b/test/intrinsics/gen/atomicCompareExchangeWeak/b2ab2c.wgsl.expected.msl
index 1b632df..45d921c 100644
--- a/test/intrinsics/gen/atomicCompareExchangeWeak/b2ab2c.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicCompareExchangeWeak/b2ab2c.wgsl.expected.msl
@@ -1,14 +1,19 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicCompareExchangeWeak_b2ab2c(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : vec2<u32> = atomicCompareExchangeWeak(&(*(tint_symbol)), 1u, 1u);
+using namespace metal;
+void atomicCompareExchangeWeak_b2ab2c(threadgroup atomic_uint* const tint_symbol_1) {
+ uint prev_value = 1u;
+ bool matched = atomic_compare_exchange_weak_explicit(&(*(tint_symbol_1)), &prev_value, 1u, memory_order_relaxed, memory_order_relaxed);
+ uint2 res = uint2(prev_value, matched);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicCompareExchangeWeak_b2ab2c(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicCompareExchangeWeak_b2ab2c(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicExchange/0a5dca.wgsl.expected.msl b/test/intrinsics/gen/atomicExchange/0a5dca.wgsl.expected.msl
index 070beca..1dafa27 100644
--- a/test/intrinsics/gen/atomicExchange/0a5dca.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicExchange/0a5dca.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicExchange_0a5dca(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicExchange(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicExchange_0a5dca(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_exchange_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicExchange_0a5dca(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicExchange_0a5dca(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicExchange/d59712.wgsl.expected.msl b/test/intrinsics/gen/atomicExchange/d59712.wgsl.expected.msl
index d3d01f5..248b62a 100644
--- a/test/intrinsics/gen/atomicExchange/d59712.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicExchange/d59712.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicExchange_d59712() {
- var res : u32 = atomicExchange(&(sb_rw.arg_0), 1u);
+void atomicExchange_d59712(device SB_RW& sb_rw) {
+ uint res = atomic_exchange_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicExchange_d59712();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicExchange_d59712(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicExchange_d59712();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicExchange_d59712(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicExchange/e114ba.wgsl.expected.msl b/test/intrinsics/gen/atomicExchange/e114ba.wgsl.expected.msl
index 9e1b24d..5104612 100644
--- a/test/intrinsics/gen/atomicExchange/e114ba.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicExchange/e114ba.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicExchange_e114ba(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicExchange(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicExchange_e114ba(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_exchange_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicExchange_e114ba(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicExchange_e114ba(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicExchange/f2e22f.wgsl.expected.msl b/test/intrinsics/gen/atomicExchange/f2e22f.wgsl.expected.msl
index be0f897..9e0dd6b 100644
--- a/test/intrinsics/gen/atomicExchange/f2e22f.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicExchange/f2e22f.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicExchange_f2e22f() {
- var res : i32 = atomicExchange(&(sb_rw.arg_0), 1);
+void atomicExchange_f2e22f(device SB_RW& sb_rw) {
+ int res = atomic_exchange_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicExchange_f2e22f();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicExchange_f2e22f(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicExchange_f2e22f();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicExchange_f2e22f(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicLoad/0806ad.wgsl.expected.msl b/test/intrinsics/gen/atomicLoad/0806ad.wgsl.expected.msl
index 39eff93..8cc7837 100644
--- a/test/intrinsics/gen/atomicLoad/0806ad.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicLoad/0806ad.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicLoad_0806ad() {
- var res : i32 = atomicLoad(&(sb_rw.arg_0));
+void atomicLoad_0806ad(device SB_RW& sb_rw) {
+ int res = atomic_load_explicit(&(sb_rw.arg_0), memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicLoad_0806ad();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicLoad_0806ad(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicLoad_0806ad();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicLoad_0806ad(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicLoad/361bf1.wgsl.expected.msl b/test/intrinsics/gen/atomicLoad/361bf1.wgsl.expected.msl
index 7d5661a..b7c08b5 100644
--- a/test/intrinsics/gen/atomicLoad/361bf1.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicLoad/361bf1.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicLoad_361bf1(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicLoad(&(*(tint_symbol)));
+using namespace metal;
+void atomicLoad_361bf1(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_load_explicit(&(*(tint_symbol_1)), memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicLoad_361bf1(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicLoad_361bf1(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicLoad/afcc03.wgsl.expected.msl b/test/intrinsics/gen/atomicLoad/afcc03.wgsl.expected.msl
index 6304ed0..7b6310a 100644
--- a/test/intrinsics/gen/atomicLoad/afcc03.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicLoad/afcc03.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicLoad_afcc03(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicLoad(&(*(tint_symbol)));
+using namespace metal;
+void atomicLoad_afcc03(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_load_explicit(&(*(tint_symbol_1)), memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicLoad_afcc03(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicLoad_afcc03(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicLoad/fe6cc3.wgsl.expected.msl b/test/intrinsics/gen/atomicLoad/fe6cc3.wgsl.expected.msl
index 2c1eeff..aef98d3 100644
--- a/test/intrinsics/gen/atomicLoad/fe6cc3.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicLoad/fe6cc3.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicLoad_fe6cc3() {
- var res : u32 = atomicLoad(&(sb_rw.arg_0));
+void atomicLoad_fe6cc3(device SB_RW& sb_rw) {
+ uint res = atomic_load_explicit(&(sb_rw.arg_0), memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicLoad_fe6cc3();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicLoad_fe6cc3(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicLoad_fe6cc3();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicLoad_fe6cc3(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicMax/51b9be.wgsl.expected.msl b/test/intrinsics/gen/atomicMax/51b9be.wgsl.expected.msl
index 9a9fb1d..8d45595 100644
--- a/test/intrinsics/gen/atomicMax/51b9be.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMax/51b9be.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicMax_51b9be() {
- var res : u32 = atomicMax(&(sb_rw.arg_0), 1u);
+void atomicMax_51b9be(device SB_RW& sb_rw) {
+ uint res = atomic_fetch_max_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicMax_51b9be();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMax_51b9be(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicMax_51b9be();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMax_51b9be(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicMax/92aa72.wgsl.expected.msl b/test/intrinsics/gen/atomicMax/92aa72.wgsl.expected.msl
index a2997a1..12babbd 100644
--- a/test/intrinsics/gen/atomicMax/92aa72.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMax/92aa72.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicMax_92aa72() {
- var res : i32 = atomicMax(&(sb_rw.arg_0), 1);
+void atomicMax_92aa72(device SB_RW& sb_rw) {
+ int res = atomic_fetch_max_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicMax_92aa72();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMax_92aa72(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicMax_92aa72();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMax_92aa72(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicMax/a89cc3.wgsl.expected.msl b/test/intrinsics/gen/atomicMax/a89cc3.wgsl.expected.msl
index bdb46ff..26d0ee6 100644
--- a/test/intrinsics/gen/atomicMax/a89cc3.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMax/a89cc3.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicMax_a89cc3(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicMax(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicMax_a89cc3(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_fetch_max_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicMax_a89cc3(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicMax_a89cc3(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicMax/beccfc.wgsl.expected.msl b/test/intrinsics/gen/atomicMax/beccfc.wgsl.expected.msl
index 5dc602c..dd139ec 100644
--- a/test/intrinsics/gen/atomicMax/beccfc.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMax/beccfc.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicMax_beccfc(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicMax(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicMax_beccfc(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_fetch_max_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicMax_beccfc(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicMax_beccfc(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicMin/278235.wgsl.expected.msl b/test/intrinsics/gen/atomicMin/278235.wgsl.expected.msl
index 7eb65c5..282c957 100644
--- a/test/intrinsics/gen/atomicMin/278235.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMin/278235.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicMin_278235(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicMin(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicMin_278235(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_fetch_min_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicMin_278235(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicMin_278235(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicMin/69d383.wgsl.expected.msl b/test/intrinsics/gen/atomicMin/69d383.wgsl.expected.msl
index 5ed9a71..4e6ec92 100644
--- a/test/intrinsics/gen/atomicMin/69d383.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMin/69d383.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicMin_69d383(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicMin(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicMin_69d383(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_fetch_min_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicMin_69d383(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicMin_69d383(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicMin/8e38dc.wgsl.expected.msl b/test/intrinsics/gen/atomicMin/8e38dc.wgsl.expected.msl
index dc15ddd..5de8f10 100644
--- a/test/intrinsics/gen/atomicMin/8e38dc.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMin/8e38dc.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicMin_8e38dc() {
- var res : i32 = atomicMin(&(sb_rw.arg_0), 1);
+void atomicMin_8e38dc(device SB_RW& sb_rw) {
+ int res = atomic_fetch_min_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicMin_8e38dc();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMin_8e38dc(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicMin_8e38dc();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMin_8e38dc(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicMin/c67a74.wgsl.expected.msl b/test/intrinsics/gen/atomicMin/c67a74.wgsl.expected.msl
index 1b28fe8..04d9d54 100644
--- a/test/intrinsics/gen/atomicMin/c67a74.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicMin/c67a74.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicMin_c67a74() {
- var res : u32 = atomicMin(&(sb_rw.arg_0), 1u);
+void atomicMin_c67a74(device SB_RW& sb_rw) {
+ uint res = atomic_fetch_min_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicMin_c67a74();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMin_c67a74(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicMin_c67a74();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicMin_c67a74(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicOr/5e3d61.wgsl.expected.msl b/test/intrinsics/gen/atomicOr/5e3d61.wgsl.expected.msl
index e38ef78..3f85fc0 100644
--- a/test/intrinsics/gen/atomicOr/5e3d61.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicOr/5e3d61.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicOr_5e3d61(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicOr(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicOr_5e3d61(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_fetch_or_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicOr_5e3d61(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicOr_5e3d61(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicOr/5e95d4.wgsl.expected.msl b/test/intrinsics/gen/atomicOr/5e95d4.wgsl.expected.msl
index e8ae23b..a711f2d 100644
--- a/test/intrinsics/gen/atomicOr/5e95d4.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicOr/5e95d4.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicOr_5e95d4() {
- var res : u32 = atomicOr(&(sb_rw.arg_0), 1u);
+void atomicOr_5e95d4(device SB_RW& sb_rw) {
+ uint res = atomic_fetch_or_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicOr_5e95d4();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicOr_5e95d4(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicOr_5e95d4();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicOr_5e95d4(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicOr/8d96a0.wgsl.expected.msl b/test/intrinsics/gen/atomicOr/8d96a0.wgsl.expected.msl
index 22c839d..3602800 100644
--- a/test/intrinsics/gen/atomicOr/8d96a0.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicOr/8d96a0.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicOr_8d96a0() {
- var res : i32 = atomicOr(&(sb_rw.arg_0), 1);
+void atomicOr_8d96a0(device SB_RW& sb_rw) {
+ int res = atomic_fetch_or_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicOr_8d96a0();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicOr_8d96a0(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicOr_8d96a0();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicOr_8d96a0(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicOr/d09248.wgsl.expected.msl b/test/intrinsics/gen/atomicOr/d09248.wgsl.expected.msl
index e8c75dd..620f392 100644
--- a/test/intrinsics/gen/atomicOr/d09248.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicOr/d09248.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicOr_d09248(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicOr(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicOr_d09248(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_fetch_or_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicOr_d09248(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicOr_d09248(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicStore/726882.wgsl.expected.msl b/test/intrinsics/gen/atomicStore/726882.wgsl.expected.msl
index c2468d6..bebd8e5 100644
--- a/test/intrinsics/gen/atomicStore/726882.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicStore/726882.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicStore_726882(tint_symbol : ptr<workgroup, atomic<u32>>) {
- atomicStore(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicStore_726882(threadgroup atomic_uint* const tint_symbol_1) {
+ atomic_store_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicStore_726882(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicStore_726882(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicStore/8bea94.wgsl.expected.msl b/test/intrinsics/gen/atomicStore/8bea94.wgsl.expected.msl
index 651a1da..9f9249a 100644
--- a/test/intrinsics/gen/atomicStore/8bea94.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicStore/8bea94.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicStore_8bea94(tint_symbol : ptr<workgroup, atomic<i32>>) {
- atomicStore(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicStore_8bea94(threadgroup atomic_int* const tint_symbol_1) {
+ atomic_store_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicStore_8bea94(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicStore_8bea94(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicStore/cdc29e.wgsl.expected.msl b/test/intrinsics/gen/atomicStore/cdc29e.wgsl.expected.msl
index cefa61e..24231c1 100644
--- a/test/intrinsics/gen/atomicStore/cdc29e.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicStore/cdc29e.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicStore_cdc29e() {
- atomicStore(&(sb_rw.arg_0), 1u);
+void atomicStore_cdc29e(device SB_RW& sb_rw) {
+ atomic_store_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicStore_cdc29e();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicStore_cdc29e(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicStore_cdc29e();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicStore_cdc29e(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicStore/d1e9a6.wgsl.expected.msl b/test/intrinsics/gen/atomicStore/d1e9a6.wgsl.expected.msl
index 98cae7a..4d3c468 100644
--- a/test/intrinsics/gen/atomicStore/d1e9a6.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicStore/d1e9a6.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicStore_d1e9a6() {
- atomicStore(&(sb_rw.arg_0), 1);
+void atomicStore_d1e9a6(device SB_RW& sb_rw) {
+ atomic_store_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicStore_d1e9a6();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicStore_d1e9a6(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicStore_d1e9a6();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicStore_d1e9a6(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicXor/54510e.wgsl.expected.msl b/test/intrinsics/gen/atomicXor/54510e.wgsl.expected.msl
index 9bccb9b..c43fc6b 100644
--- a/test/intrinsics/gen/atomicXor/54510e.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicXor/54510e.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<u32>;
+ /* 0x0000 */ atomic_uint arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicXor_54510e() {
- var res : u32 = atomicXor(&(sb_rw.arg_0), 1u);
+void atomicXor_54510e(device SB_RW& sb_rw) {
+ uint res = atomic_fetch_xor_explicit(&(sb_rw.arg_0), 1u, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicXor_54510e();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicXor_54510e(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicXor_54510e();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicXor_54510e(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__u32
diff --git a/test/intrinsics/gen/atomicXor/75dc95.wgsl.expected.msl b/test/intrinsics/gen/atomicXor/75dc95.wgsl.expected.msl
index 32bbb93..e1b8265 100644
--- a/test/intrinsics/gen/atomicXor/75dc95.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicXor/75dc95.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicXor_75dc95(tint_symbol : ptr<workgroup, atomic<i32>>) {
- var res : i32 = atomicXor(&(*(tint_symbol)), 1);
+using namespace metal;
+void atomicXor_75dc95(threadgroup atomic_int* const tint_symbol_1) {
+ int res = atomic_fetch_xor_explicit(&(*(tint_symbol_1)), 1, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<i32>;
- atomicXor_75dc95(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_int tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), int(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicXor_75dc95(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope
diff --git a/test/intrinsics/gen/atomicXor/c1b78c.wgsl.expected.msl b/test/intrinsics/gen/atomicXor/c1b78c.wgsl.expected.msl
index bd565c8..d48ee31 100644
--- a/test/intrinsics/gen/atomicXor/c1b78c.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicXor/c1b78c.wgsl.expected.msl
@@ -1,25 +1,21 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-[[block]]
+using namespace metal;
struct SB_RW {
- arg_0 : atomic<i32>;
+ /* 0x0000 */ atomic_int arg_0;
};
-[[group(0), binding(0)]] var<storage, read_write> sb_rw : SB_RW;
-
-fn atomicXor_c1b78c() {
- var res : i32 = atomicXor(&(sb_rw.arg_0), 1);
+void atomicXor_c1b78c(device SB_RW& sb_rw) {
+ int res = atomic_fetch_xor_explicit(&(sb_rw.arg_0), 1, memory_order_relaxed);
}
-[[stage(fragment)]]
-fn fragment_main() {
- atomicXor_c1b78c();
+fragment void fragment_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicXor_c1b78c(sb_rw);
+ return;
}
-[[stage(compute)]]
-fn compute_main() {
- atomicXor_c1b78c();
+kernel void compute_main(device SB_RW& sb_rw [[buffer(0)]]) {
+ atomicXor_c1b78c(sb_rw);
+ return;
}
-Failed to generate: error: unknown type in EmitType: __atomic__i32
diff --git a/test/intrinsics/gen/atomicXor/c8e6be.wgsl.expected.msl b/test/intrinsics/gen/atomicXor/c8e6be.wgsl.expected.msl
index 4ee0172..3f0283d 100644
--- a/test/intrinsics/gen/atomicXor/c8e6be.wgsl.expected.msl
+++ b/test/intrinsics/gen/atomicXor/c8e6be.wgsl.expected.msl
@@ -1,14 +1,17 @@
-SKIP: FAILED
+#include <metal_stdlib>
-
-fn atomicXor_c8e6be(tint_symbol : ptr<workgroup, atomic<u32>>) {
- var res : u32 = atomicXor(&(*(tint_symbol)), 1u);
+using namespace metal;
+void atomicXor_c8e6be(threadgroup atomic_uint* const tint_symbol_1) {
+ uint res = atomic_fetch_xor_explicit(&(*(tint_symbol_1)), 1u, memory_order_relaxed);
}
-[[stage(compute)]]
-fn compute_main() {
- [[internal(disable_validation__function_var_storage_class)]] var<workgroup> tint_symbol_1 : atomic<u32>;
- atomicXor_c8e6be(&(tint_symbol_1));
+kernel void compute_main(uint local_invocation_index [[thread_index_in_threadgroup]]) {
+ threadgroup atomic_uint tint_symbol_2;
+ if ((local_invocation_index == 0u)) {
+ atomic_store_explicit(&(tint_symbol_2), uint(), memory_order_relaxed);
+ }
+ threadgroup_barrier(mem_flags::mem_threadgroup);
+ atomicXor_c8e6be(&(tint_symbol_2));
+ return;
}
-error: cannot declare an atomic var in a function scope