diff --git a/src/writer/hlsl/generator_impl.cc b/src/writer/hlsl/generator_impl.cc index fc9e5057e2..de9ea80210 100644 --- a/src/writer/hlsl/generator_impl.cc +++ b/src/writer/hlsl/generator_impl.cc @@ -2502,13 +2502,20 @@ bool GeneratorImpl::EmitLiteral(std::ostream& out, ast::Literal* lit) { if (auto* l = lit->As()) { out << (l->IsTrue() ? "true" : "false"); } else if (auto* fl = lit->As()) { - if (std::isinf(fl->value())) { - out << (fl->value() >= 0 ? "asfloat(0x7f800000u)" - : "asfloat(0xff800000u)"); - } else if (std::isnan(fl->value())) { - out << "asfloat(0x7fc00000u)"; - } else { - out << FloatToString(fl->value()) << "f"; + bool positive = !std::signbit(fl->value()); + switch (std::fpclassify(fl->value())) { + case FP_INFINITE: + out << (positive ? "asfloat(0x7f800000u)" : "asfloat(0xff800000u)"); + break; + case FP_NAN: + out << "asfloat(0x7fc00000u)"; + break; + case FP_ZERO: + out << (positive ? "0.0f" : "asfloat(0x80000000u)"); + break; + default: + out << FloatToString(fl->value()) << "f"; + break; } } else if (auto* sl = lit->As()) { out << sl->value(); diff --git a/test/expressions/literals/-inf.spvasm b/test/expressions/literals/neg_inf.spvasm similarity index 100% rename from test/expressions/literals/-inf.spvasm rename to test/expressions/literals/neg_inf.spvasm diff --git a/test/expressions/literals/-inf.spvasm.expected.hlsl b/test/expressions/literals/neg_inf.spvasm.expected.hlsl similarity index 100% rename from test/expressions/literals/-inf.spvasm.expected.hlsl rename to test/expressions/literals/neg_inf.spvasm.expected.hlsl diff --git a/test/expressions/literals/-inf.spvasm.expected.msl b/test/expressions/literals/neg_inf.spvasm.expected.msl similarity index 100% rename from test/expressions/literals/-inf.spvasm.expected.msl rename to test/expressions/literals/neg_inf.spvasm.expected.msl diff --git a/test/expressions/literals/-inf.spvasm.expected.spvasm b/test/expressions/literals/neg_inf.spvasm.expected.spvasm similarity index 100% rename from test/expressions/literals/-inf.spvasm.expected.spvasm rename to test/expressions/literals/neg_inf.spvasm.expected.spvasm diff --git a/test/expressions/literals/-inf.spvasm.expected.wgsl b/test/expressions/literals/neg_inf.spvasm.expected.wgsl similarity index 100% rename from test/expressions/literals/-inf.spvasm.expected.wgsl rename to test/expressions/literals/neg_inf.spvasm.expected.wgsl diff --git a/test/expressions/literals/neg_zero.spvasm b/test/expressions/literals/neg_zero.spvasm new file mode 100644 index 0000000000..610537bb1d --- /dev/null +++ b/test/expressions/literals/neg_zero.spvasm @@ -0,0 +1,21 @@ + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %out_var_SV_TARGET + OpExecutionMode %main OriginUpperLeft + OpSource HLSL 600 + OpName %out_var_SV_TARGET "out.var.SV_TARGET" + OpName %main "main" + OpDecorate %out_var_SV_TARGET Location 0 + %float = OpTypeFloat 32 + %float_0x1p_128 = OpConstant %float -0 + %v4float = OpTypeVector %float 4 +%_ptr_Output_v4float = OpTypePointer Output %v4float + %void = OpTypeVoid + %9 = OpTypeFunction %void + %out_var_SV_TARGET = OpVariable %_ptr_Output_v4float Output + %main = OpFunction %void None %9 + %10 = OpLabel + %12 = OpCompositeConstruct %v4float %float_0x1p_128 %float_0x1p_128 %float_0x1p_128 %float_0x1p_128 + OpStore %out_var_SV_TARGET %12 + OpReturn + OpFunctionEnd diff --git a/test/expressions/literals/neg_zero.spvasm.expected.hlsl b/test/expressions/literals/neg_zero.spvasm.expected.hlsl new file mode 100644 index 0000000000..f1ac2f2759 --- /dev/null +++ b/test/expressions/literals/neg_zero.spvasm.expected.hlsl @@ -0,0 +1,20 @@ +static float4 out_var_SV_TARGET = float4(0.0f, 0.0f, 0.0f, 0.0f); + +void main_1() { + out_var_SV_TARGET = float4(asfloat(0x80000000u), asfloat(0x80000000u), asfloat(0x80000000u), asfloat(0x80000000u)); + return; +} + +struct main_out { + float4 out_var_SV_TARGET_1; +}; +struct tint_symbol { + float4 out_var_SV_TARGET_1 : SV_Target0; +}; + +tint_symbol main() { + main_1(); + const main_out tint_symbol_1 = {out_var_SV_TARGET}; + const tint_symbol tint_symbol_2 = {tint_symbol_1.out_var_SV_TARGET_1}; + return tint_symbol_2; +} diff --git a/test/expressions/literals/neg_zero.spvasm.expected.msl b/test/expressions/literals/neg_zero.spvasm.expected.msl new file mode 100644 index 0000000000..a5862ed6a7 --- /dev/null +++ b/test/expressions/literals/neg_zero.spvasm.expected.msl @@ -0,0 +1,23 @@ +#include + +using namespace metal; +struct main_out { + float4 out_var_SV_TARGET_1; +}; +struct tint_symbol_1 { + float4 out_var_SV_TARGET_1 [[color(0)]]; +}; + +void main_1(thread float4* const tint_symbol_4) { + *(tint_symbol_4) = float4(-0.0f, -0.0f, -0.0f, -0.0f); + return; +} + +fragment tint_symbol_1 tint_symbol() { + thread float4 tint_symbol_5 = 0.0f; + main_1(&(tint_symbol_5)); + main_out const tint_symbol_2 = {.out_var_SV_TARGET_1=tint_symbol_5}; + tint_symbol_1 const tint_symbol_3 = {.out_var_SV_TARGET_1=tint_symbol_2.out_var_SV_TARGET_1}; + return tint_symbol_3; +} + diff --git a/test/expressions/literals/neg_zero.spvasm.expected.spvasm b/test/expressions/literals/neg_zero.spvasm.expected.spvasm new file mode 100644 index 0000000000..ea3e75c930 --- /dev/null +++ b/test/expressions/literals/neg_zero.spvasm.expected.spvasm @@ -0,0 +1,52 @@ +; SPIR-V +; Version: 1.3 +; Generator: Google Tint Compiler; 0 +; Bound: 26 +; Schema: 0 + OpCapability Shader + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %tint_symbol_1 + OpExecutionMode %main OriginUpperLeft + OpName %out_var_SV_TARGET "out_var_SV_TARGET" + OpName %tint_symbol_1 "tint_symbol_1" + OpName %main_1 "main_1" + OpName %main_out "main_out" + OpMemberName %main_out 0 "out_var_SV_TARGET_1" + OpName %tint_symbol_2 "tint_symbol_2" + OpName %tint_symbol "tint_symbol" + OpName %main "main" + OpDecorate %tint_symbol_1 Location 0 + OpMemberDecorate %main_out 0 Offset 0 + %float = OpTypeFloat 32 + %v4float = OpTypeVector %float 4 +%_ptr_Private_v4float = OpTypePointer Private %v4float + %5 = OpConstantNull %v4float +%out_var_SV_TARGET = OpVariable %_ptr_Private_v4float Private %5 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%tint_symbol_1 = OpVariable %_ptr_Output_v4float Output %5 + %void = OpTypeVoid + %8 = OpTypeFunction %void + %float_n0 = OpConstant %float -0 + %13 = OpConstantComposite %v4float %float_n0 %float_n0 %float_n0 %float_n0 + %main_out = OpTypeStruct %v4float + %14 = OpTypeFunction %void %main_out + %main_1 = OpFunction %void None %8 + %11 = OpLabel + OpStore %out_var_SV_TARGET %13 + OpReturn + OpFunctionEnd +%tint_symbol_2 = OpFunction %void None %14 +%tint_symbol = OpFunctionParameter %main_out + %18 = OpLabel + %19 = OpCompositeExtract %v4float %tint_symbol 0 + OpStore %tint_symbol_1 %19 + OpReturn + OpFunctionEnd + %main = OpFunction %void None %8 + %21 = OpLabel + %22 = OpFunctionCall %void %main_1 + %24 = OpLoad %v4float %out_var_SV_TARGET + %25 = OpCompositeConstruct %main_out %24 + %23 = OpFunctionCall %void %tint_symbol_2 %25 + OpReturn + OpFunctionEnd diff --git a/test/expressions/literals/neg_zero.spvasm.expected.wgsl b/test/expressions/literals/neg_zero.spvasm.expected.wgsl new file mode 100644 index 0000000000..d9a2025e85 --- /dev/null +++ b/test/expressions/literals/neg_zero.spvasm.expected.wgsl @@ -0,0 +1,17 @@ +var out_var_SV_TARGET : vec4; + +fn main_1() { + out_var_SV_TARGET = vec4(-0.0, -0.0, -0.0, -0.0); + return; +} + +struct main_out { + [[location(0)]] + out_var_SV_TARGET_1 : vec4; +}; + +[[stage(fragment)]] +fn main() -> main_out { + main_1(); + return main_out(out_var_SV_TARGET); +}