writer/hlsl: Don't emit literal integer divide-by-zeros
FXC errors on these, and they are undefined behavior in WGSL.
Bug: tint:1083
Change-Id: I7643fdc6991f8729f274535b603b761398412398
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/60500
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Reviewed-by: David Neto <dneto@google.com>
diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc
index aa14cc1..db40ef3 100644
--- a/src/writer/hlsl/generator_impl.cc
+++ b/src/writer/hlsl/generator_impl.cc
@@ -364,6 +364,8 @@
}
out << "(";
+ TINT_DEFER(out << ")");
+
if (!EmitExpression(out, expr->lhs())) {
return false;
}
@@ -425,6 +427,19 @@
break;
case ast::BinaryOp::kDivide:
out << "/";
+
+ if (auto val = program_->Sem().Get(expr->rhs())->ConstantValue()) {
+ // Integer divide by zero is a DXC compile error, and undefined behavior
+ // in WGSL. Replace the 0 with 1.
+ if (val.Type()->Is<sem::I32>() && val.Elements()[0].i32 == 0) {
+ out << " 1";
+ return true;
+ }
+ if (val.Type()->Is<sem::U32>() && val.Elements()[0].u32 == 0u) {
+ out << " 1u";
+ return true;
+ }
+ }
break;
case ast::BinaryOp::kModulo:
out << "%";
@@ -440,7 +455,6 @@
return false;
}
- out << ")";
return true;
}
diff --git a/src/writer/hlsl/generator_impl_binary_test.cc b/src/writer/hlsl/generator_impl_binary_test.cc
index 435ce1d..78d4632 100644
--- a/src/writer/hlsl/generator_impl_binary_test.cc
+++ b/src/writer/hlsl/generator_impl_binary_test.cc
@@ -551,6 +551,32 @@
)");
}
+TEST_F(HlslGeneratorImplTest_Binary, DivideByLiteralZero_i32) {
+ Global("a", ty.i32(), ast::StorageClass::kPrivate);
+
+ auto* expr = Div("a", 0);
+ WrapInFunction(expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), R"((a / 1))");
+}
+
+TEST_F(HlslGeneratorImplTest_Binary, DivideByLiteralZero_u32) {
+ Global("a", ty.u32(), ast::StorageClass::kPrivate);
+
+ auto* expr = Div("a", 0u);
+ WrapInFunction(expr);
+
+ GeneratorImpl& gen = Build();
+
+ std::stringstream out;
+ ASSERT_TRUE(gen.EmitExpression(out, expr)) << gen.error();
+ EXPECT_EQ(out.str(), R"((a / 1u))");
+}
+
} // namespace
} // namespace hlsl
} // namespace writer
diff --git a/test/bug/tint/1083.wgsl.expected.hlsl b/test/bug/tint/1083.wgsl.expected.hlsl
index 30e2a72..182701b 100644
--- a/test/bug/tint/1083.wgsl.expected.hlsl
+++ b/test/bug/tint/1083.wgsl.expected.hlsl
@@ -5,5 +5,5 @@
const int c = (1 / 0);
return;
}
-C:\src\tint\test\Shader@0x000001BC7A7DD8D0(3,18-22): error X4010: Unsigned integer divide by zero
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x000002477B82F5C0(3,18-22): error X4010: Unsigned integer divide by zero
diff --git a/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.spvasm.expected.hlsl b/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.spvasm.expected.hlsl
index 72454e8..b82d8ee 100644
--- a/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.spvasm.expected.hlsl
+++ b/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.spvasm.expected.hlsl
@@ -53,6 +53,6 @@
const tint_symbol tint_symbol_3 = {tint_symbol_1.x_GLF_color_1};
return tint_symbol_3;
}
-C:\src\tint\test\Shader@0x0000021F05CF11C0(19,14-18): error X4010: Unsigned integer divide by zero
-C:\src\tint\test\Shader@0x0000021F05CF11C0(19,14-18): warning X3556: integer divides may be much slower, try using uints if possible.
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x000001481B9B0CA0(19,14-18): error X4010: Unsigned integer divide by zero
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x000001481B9B0CA0(19,14-18): warning X3556: integer divides may be much slower, try using uints if possible.
diff --git a/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.wgsl.expected.hlsl b/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.wgsl.expected.hlsl
index 6ed529d..c98ef25 100644
--- a/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.wgsl.expected.hlsl
+++ b/test/vk-gl-cts/graphicsfuzz/cov-loop-increment-or-divide-by-loop-index/0-opt.wgsl.expected.hlsl
@@ -53,6 +53,6 @@
const tint_symbol tint_symbol_3 = {tint_symbol_1.x_GLF_color_1};
return tint_symbol_3;
}
-C:\src\tint\test\Shader@0x00000199CF77C330(19,14-18): error X4010: Unsigned integer divide by zero
-C:\src\tint\test\Shader@0x00000199CF77C330(19,14-18): warning X3556: integer divides may be much slower, try using uints if possible.
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x0000029A80398B60(19,14-18): error X4010: Unsigned integer divide by zero
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x0000029A80398B60(19,14-18): warning X3556: integer divides may be much slower, try using uints if possible.
diff --git a/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.spvasm.expected.hlsl b/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.spvasm.expected.hlsl
index ada7447..0109ec6 100644
--- a/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.spvasm.expected.hlsl
+++ b/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.spvasm.expected.hlsl
@@ -63,5 +63,5 @@
const tint_symbol_2 tint_symbol_7 = {tint_symbol_3.x_GLF_color_1};
return tint_symbol_7;
}
-C:\src\tint\test\Shader@0x000002787AC0C3C0(25,16-23): error X4010: Unsigned integer divide by zero
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x0000028809903F10(25,16-23): error X4010: Unsigned integer divide by zero
diff --git a/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.wgsl.expected.hlsl b/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.wgsl.expected.hlsl
index bd2158c..3d86b59 100644
--- a/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.wgsl.expected.hlsl
+++ b/test/vk-gl-cts/graphicsfuzz/cov-modulo-zero-never-executed/0-opt.wgsl.expected.hlsl
@@ -63,5 +63,5 @@
const tint_symbol_2 tint_symbol_7 = {tint_symbol_3.x_GLF_color_1};
return tint_symbol_7;
}
-C:\src\tint\test\Shader@0x0000020234C8C230(25,16-23): error X4010: Unsigned integer divide by zero
+O:\src\chrome\src\third_party\dawn\third_party\tint\test\Shader@0x000001EB404C9FC0(25,16-23): error X4010: Unsigned integer divide by zero