mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-13 07:06:11 +00:00
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>
This commit is contained in:
committed by
Tint LUCI CQ
parent
72dad76c21
commit
51750f15d2
@@ -364,6 +364,8 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, ast::BinaryExpression* expr) {
|
||||
}
|
||||
|
||||
out << "(";
|
||||
TINT_DEFER(out << ")");
|
||||
|
||||
if (!EmitExpression(out, expr->lhs())) {
|
||||
return false;
|
||||
}
|
||||
@@ -425,6 +427,19 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, ast::BinaryExpression* expr) {
|
||||
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 @@ bool GeneratorImpl::EmitBinary(std::ostream& out, ast::BinaryExpression* expr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
out << ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -551,6 +551,32 @@ foo((tint_tmp), (tint_tmp_1), (tint_tmp_2));
|
||||
)");
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user