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:
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
|
||||
|
|
|
@ -5,5 +5,5 @@ void f() {
|
|||
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
|
||||
|
||||
|
|
|
@ -53,6 +53,6 @@ tint_symbol main() {
|
|||
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.
|
||||
|
||||
|
|
|
@ -53,6 +53,6 @@ tint_symbol main() {
|
|||
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.
|
||||
|
||||
|
|
|
@ -63,5 +63,5 @@ tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
|||
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
|
||||
|
||||
|
|
|
@ -63,5 +63,5 @@ tint_symbol_2 main(tint_symbol_1 tint_symbol) {
|
|||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue