Import Tint changes from Dawn
Changes:
- 26dc5f6989a35758ee466e8b2df5cebc983058ab msl ast_writer: Prevent emitted loops from erasure during... by David Neto <dneto@google.com>
- 2be279ee795b144ba43171c943c09707eda4480e Fix the comparator used to sort output attributes by David Neto <dneto@google.com>
- ece88f74027f2554bc6c98d0194eca9f4de4eb46 spir-v ast writer: Fix order of dpdx and dpdy operands by David Neto <dneto@google.com>
GitOrigin-RevId: 26dc5f6989a35758ee466e8b2df5cebc983058ab
Change-Id: Iea9f5e89f2f48cf98db233add45846845aa6b03c
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/166980
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Copybara Prod <copybara-worker@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
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 8787d09..4f90706 100644
--- a/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
+++ b/src/tint/lang/msl/writer/ast_printer/ast_printer.cc
@@ -2123,6 +2123,7 @@
TINT_SCOPED_ASSIGNMENT(emit_continuing_, emit_continuing);
Line() << "while (true) {";
+ EmitLoopPreserver();
{
ScopedIndent si(this);
if (!EmitStatements(stmt->body->statements)) {
@@ -2193,6 +2194,7 @@
TINT_SCOPED_ASSIGNMENT(emit_continuing_, emit_continuing);
Line() << "while (true) {";
+ EmitLoopPreserver();
IncrementIndent();
TINT_DEFER({
DecrementIndent();
@@ -2233,6 +2235,7 @@
}
out << " {";
}
+ EmitLoopPreserver();
{
auto emit_continuing = [] { return true; };
TINT_SCOPED_ASSIGNMENT(emit_continuing_, emit_continuing);
@@ -2266,6 +2269,7 @@
bool emit_as_loop = cond_pre.lines.size() > 0;
if (emit_as_loop) {
Line() << "while (true) {";
+ EmitLoopPreserver();
IncrementIndent();
TINT_DEFER({
DecrementIndent();
@@ -2288,6 +2292,7 @@
}
out << " {";
}
+ EmitLoopPreserver();
if (!EmitStatementsWithIndent(stmt->body->statements)) {
return false;
}
@@ -3026,6 +3031,14 @@
return true;
}
+void ASTPrinter::EmitLoopPreserver() {
+ IncrementIndent();
+ // This statement prevents the MSL compiler from erasing a loop during
+ // optimimzations.
+ Line() << R"(__asm__("");)";
+ DecrementIndent();
+}
+
template <typename F>
bool ASTPrinter::CallBuiltinHelper(StringStream& out,
const ast::CallExpression* call,
diff --git a/src/tint/lang/msl/writer/ast_printer/ast_printer.h b/src/tint/lang/msl/writer/ast_printer/ast_printer.h
index 9c9ba7c..af251db 100644
--- a/src/tint/lang/msl/writer/ast_printer/ast_printer.h
+++ b/src/tint/lang/msl/writer/ast_printer/ast_printer.h
@@ -378,6 +378,10 @@
const ast::CallExpression* expr,
const sem::BuiltinFn* builtin);
+ /// Emits a code sequence that preserves a loop during
+ /// optimizations even if the loop is infinite.
+ void EmitLoopPreserver();
+
/// Handles generating a builtin name
/// @param builtin the semantic info for the builtin
/// @returns the name or "" if not valid
diff --git a/src/tint/lang/msl/writer/ast_printer/ast_printer_test.cc b/src/tint/lang/msl/writer/ast_printer/ast_printer_test.cc
index b62df62..f7b869e 100644
--- a/src/tint/lang/msl/writer/ast_printer/ast_printer_test.cc
+++ b/src/tint/lang/msl/writer/ast_printer/ast_printer_test.cc
@@ -232,6 +232,7 @@
void comp_main_inner(uint local_invocation_index, threadgroup tint_array<float2x2, 4>* const tint_symbol) {
for(uint idx = local_invocation_index; (idx < 4u); idx = (idx + 1u)) {
+ __asm__("");
uint const i = idx;
(*(tint_symbol))[i] = float2x2(float2(0.0f), float2(0.0f));
}
diff --git a/src/tint/lang/msl/writer/ast_printer/continue_test.cc b/src/tint/lang/msl/writer/ast_printer/continue_test.cc
index 508c69d..a79ddc3 100644
--- a/src/tint/lang/msl/writer/ast_printer/continue_test.cc
+++ b/src/tint/lang/msl/writer/ast_printer/continue_test.cc
@@ -43,6 +43,7 @@
ASSERT_TRUE(gen.EmitStatement(loop)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
if (false) {
break;
}
diff --git a/src/tint/lang/msl/writer/ast_printer/loop_test.cc b/src/tint/lang/msl/writer/ast_printer/loop_test.cc
index f4a6662..450592b 100644
--- a/src/tint/lang/msl/writer/ast_printer/loop_test.cc
+++ b/src/tint/lang/msl/writer/ast_printer/loop_test.cc
@@ -50,6 +50,7 @@
ASSERT_TRUE(gen.EmitStatement(l)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
break;
}
)");
@@ -70,6 +71,7 @@
ASSERT_TRUE(gen.EmitStatement(l)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
break;
{
a_statement();
@@ -93,6 +95,7 @@
ASSERT_TRUE(gen.EmitStatement(l)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
break;
{
a_statement();
@@ -126,7 +129,9 @@
ASSERT_TRUE(gen.EmitStatement(outer)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
while (true) {
+ __asm__("");
break;
{
a_statement();
@@ -166,6 +171,7 @@
ASSERT_TRUE(gen.EmitStatement(outer)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
float lhs = 2.5f;
float other = 0.0f;
break;
@@ -191,6 +197,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( for(; ; ) {
+ __asm__("");
return;
}
)");
@@ -211,6 +218,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( for(int i = 0; ; ) {
+ __asm__("");
return;
}
)");
@@ -244,6 +252,7 @@
f(2);
}
for(; ; ) {
+ __asm__("");
return;
}
}
@@ -265,6 +274,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( for(; true; ) {
+ __asm__("");
return;
}
)");
@@ -287,6 +297,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(),
R"( for(; ; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+ __asm__("");
return;
}
)");
@@ -315,6 +326,7 @@
ASSERT_TRUE(gen.EmitStatement(loop)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while (true) {
+ __asm__("");
return;
{
f(1);
@@ -342,6 +354,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(),
R"( for(int i = 0; true; i = as_type<int>((as_type<uint>(i) + as_type<uint>(1)))) {
+ __asm__("");
a_statement();
}
)");
@@ -376,6 +389,7 @@
f(2);
}
while (true) {
+ __asm__("");
if (!(true)) { break; }
return;
{
@@ -401,6 +415,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while(true) {
+ __asm__("");
return;
}
)");
@@ -420,6 +435,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while(true) {
+ __asm__("");
continue;
}
)");
@@ -442,6 +458,7 @@
ASSERT_TRUE(gen.EmitStatement(f)) << gen.Diagnostics();
EXPECT_EQ(gen.Result(), R"( while((t && false)) {
+ __asm__("");
return;
}
)");
diff --git a/src/tint/lang/spirv/writer/ast_printer/builder.cc b/src/tint/lang/spirv/writer/ast_printer/builder.cc
index 26c4d3a..19a5662 100644
--- a/src/tint/lang/spirv/writer/ast_printer/builder.cc
+++ b/src/tint/lang/spirv/writer/ast_printer/builder.cc
@@ -2997,8 +2997,10 @@
}
if (!image_operands.empty()) {
- std::sort(image_operands.begin(), image_operands.end(),
- [](auto& a, auto& b) { return a.mask < b.mask; });
+ // Use a stable sort to preserve the order of the Grad dpdx and dpdy
+ // operands.
+ std::stable_sort(image_operands.begin(), image_operands.end(),
+ [](auto& a, auto& b) { return a.mask < b.mask; });
uint32_t mask = 0;
for (auto& image_operand : image_operands) {
mask |= image_operand.mask;
diff --git a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
index e0ec04a..9bfa463 100644
--- a/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
+++ b/src/tint/lang/wgsl/ast/transform/canonicalize_entry_point_io.cc
@@ -102,6 +102,7 @@
default:
break;
}
+ TINT_UNREACHABLE();
return 0;
}
@@ -569,29 +570,26 @@
/// @param y another struct member
/// @returns true if a comes before b
bool StructMemberComparator(const MemberInfo& x, const MemberInfo& y) {
- if (x.color.has_value() && y.color.has_value()) {
+ if (x.color.has_value() && y.color.has_value() && x.color != y.color) {
// Both have color attributes: smallest goes first.
return x.color < y.color;
- }
- if (x.color.has_value() != y.color.has_value()) {
+ } else if (x.color.has_value() != y.color.has_value()) {
// The member with the color goes first
return x.color.has_value();
}
- if (x.location.has_value() && y.location.has_value()) {
+ if (x.location.has_value() && y.location.has_value() && x.location != y.location) {
// Both have location attributes: smallest goes first.
return x.location < y.location;
- }
- if (x.location.has_value() != y.location.has_value()) {
+ } else if (x.location.has_value() != y.location.has_value()) {
// The member with the location goes first
return x.location.has_value();
}
- if (x.index.has_value() && y.index.has_value()) {
+ if (x.index.has_value() && y.index.has_value() && x.index != y.index) {
// Both have index attributes: smallest goes first.
return x.index < y.index;
- }
- if (x.index.has_value() != y.index.has_value()) {
+ } else if (x.index.has_value() != y.index.has_value()) {
// The member with the index goes first
return x.index.has_value();
}
@@ -603,15 +601,19 @@
// Both are builtins: order matters for FXC.
auto builtin_a = BuiltinOf(x_blt);
auto builtin_b = BuiltinOf(y_blt);
- return BuiltinOrder(builtin_a) < BuiltinOrder(builtin_b);
- }
- if ((x_blt != nullptr) != (y_blt != nullptr)) {
+ auto order_a = BuiltinOrder(builtin_a);
+ auto order_b = BuiltinOrder(builtin_b);
+ if (order_a != order_b) {
+ return order_a < order_b;
+ }
+ } else if ((x_blt != nullptr) != (y_blt != nullptr)) {
// The member with the builtin goes first
return x_blt != nullptr;
}
}
- TINT_UNREACHABLE();
+ // Control flow reaches here if x is the same as y.
+ // Sort algorithms sometimes do that.
return false;
}