diff --git a/naga/src/back/hlsl/writer.rs b/naga/src/back/hlsl/writer.rs index a0d25e1d0d..9895dee97d 100644 --- a/naga/src/back/hlsl/writer.rs +++ b/naga/src/back/hlsl/writer.rs @@ -2620,11 +2620,23 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> { crate::Literal::F32(value) => write!(self.out, "{value:?}")?, crate::Literal::F16(value) => write!(self.out, "{value:?}h")?, crate::Literal::U32(value) => write!(self.out, "{value}u")?, + // `-2147483648` is parsed by some compilers as unary negation of + // positive 2147483648, which is too large for an int, causing + // issues for some compilers. Neither DXC nor FXC appear to have + // this problem, but this is not specified and could change. We + // therefore use `-2147483647 - 1` as a precaution. + crate::Literal::I32(value) if value == i32::MIN => { + write!(self.out, "int({} - 1)", value + 1)? + } // HLSL has no suffix for explicit i32 literals, but not using any suffix // makes the type ambiguous which prevents overload resolution from // working. So we explicitly use the int() constructor syntax. crate::Literal::I32(value) => write!(self.out, "int({value})")?, crate::Literal::U64(value) => write!(self.out, "{value}uL")?, + // I64 version of the minimum I32 value issue described above. + crate::Literal::I64(value) if value == i64::MIN => { + write!(self.out, "({}L - 1L)", value + 1)?; + } crate::Literal::I64(value) => write!(self.out, "{value}L")?, crate::Literal::Bool(value) => write!(self.out, "{value}")?, crate::Literal::AbstractInt(_) | crate::Literal::AbstractFloat(_) => { diff --git a/naga/tests/out/hlsl/wgsl-conversion-float-to-int.hlsl b/naga/tests/out/hlsl/wgsl-conversion-float-to-int.hlsl index ca0a79ce69..aa599b8242 100644 --- a/naga/tests/out/hlsl/wgsl-conversion-float-to-int.hlsl +++ b/naga/tests/out/hlsl/wgsl-conversion-float-to-int.hlsl @@ -15,23 +15,23 @@ void test_const_eval() int64_t max_f16_to_i64_ = 65504L; uint64_t min_f16_to_u64_ = 0uL; uint64_t max_f16_to_u64_ = 65504uL; - int min_f32_to_i32_ = int(-2147483648); + int min_f32_to_i32_ = int(-2147483647 - 1); int max_f32_to_i32_ = int(2147483520); uint min_f32_to_u32_ = 0u; uint max_f32_to_u32_ = 4294967040u; - int64_t min_f32_to_i64_ = -9223372036854775808L; + int64_t min_f32_to_i64_ = (-9223372036854775807L - 1L); int64_t max_f32_to_i64_ = 9223371487098961920L; uint64_t min_f32_to_u64_ = 0uL; uint64_t max_f32_to_u64_ = 18446742974197923840uL; - int64_t min_f64_to_i64_ = -9223372036854775808L; + int64_t min_f64_to_i64_ = (-9223372036854775807L - 1L); int64_t max_f64_to_i64_ = 9223372036854774784L; uint64_t min_f64_to_u64_ = 0uL; uint64_t max_f64_to_u64_ = 18446744073709549568uL; - int min_abstract_float_to_i32_ = int(-2147483648); + int min_abstract_float_to_i32_ = int(-2147483647 - 1); int max_abstract_float_to_i32_ = int(2147483647); uint min_abstract_float_to_u32_ = 0u; uint max_abstract_float_to_u32_ = 4294967295u; - int64_t min_abstract_float_to_i64_ = -9223372036854775808L; + int64_t min_abstract_float_to_i64_ = (-9223372036854775807L - 1L); int64_t max_abstract_float_to_i64_ = 9223372036854774784L; uint64_t min_abstract_float_to_u64_ = 0uL; uint64_t max_abstract_float_to_u64_ = 18446744073709549568uL; diff --git a/naga/tests/out/hlsl/wgsl-int64.hlsl b/naga/tests/out/hlsl/wgsl-int64.hlsl index 6705e77e71..75fc5cb089 100644 --- a/naga/tests/out/hlsl/wgsl-int64.hlsl +++ b/naga/tests/out/hlsl/wgsl-int64.hlsl @@ -100,7 +100,7 @@ int64_t int64_function(int64_t x) int64_t _e74 = val; val = (_e74 + _e71.w); int64_t _e77 = val; - val = (_e77 + -9223372036854775808L); + val = (_e77 + (-9223372036854775807L - 1L)); int64_t _e83 = input_uniform.val_i64_; int64_t _e86 = input_storage.Load(128); output.Store(128, (_e83 + _e86)); diff --git a/naga/tests/out/hlsl/wgsl-operators.hlsl b/naga/tests/out/hlsl/wgsl-operators.hlsl index b19e526ff0..3dbec43451 100644 --- a/naga/tests/out/hlsl/wgsl-operators.hlsl +++ b/naga/tests/out/hlsl/wgsl-operators.hlsl @@ -197,7 +197,7 @@ void arithmetic() float4 mul_vector1_ = mul(ZeroValuefloat4x3(), (2.0).xxx); float3x3 mul_ = mul(ZeroValuefloat3x4(), ZeroValuefloat4x3()); int _e175 = prevent_const_eval; - wgpu_7437_ = asint(asuint(_e175) + asuint(int(-2147483648))); + wgpu_7437_ = asint(asuint(_e175) + asuint(int(-2147483647 - 1))); return; }