From 40a355a42d4a9444dc753c04c6608dade2f06a23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:27 +0200 Subject: Adding upstream version 125.0.1. Signed-off-by: Daniel Baumann --- .../rust/naga/src/proc/constant_evaluator.rs | 242 +++++++++++++-------- 1 file changed, 148 insertions(+), 94 deletions(-) (limited to 'third_party/rust/naga/src/proc/constant_evaluator.rs') diff --git a/third_party/rust/naga/src/proc/constant_evaluator.rs b/third_party/rust/naga/src/proc/constant_evaluator.rs index b3884b04b1..983af3718c 100644 --- a/third_party/rust/naga/src/proc/constant_evaluator.rs +++ b/third_party/rust/naga/src/proc/constant_evaluator.rs @@ -31,7 +31,7 @@ macro_rules! gen_component_wise_extractor { $( #[doc = concat!( "Maps to [`Literal::", - stringify!($mapping), + stringify!($literal), "`]", )] $mapping([$ty; N]), @@ -200,6 +200,8 @@ gen_component_wise_extractor! { AbstractInt => AbstractInt: i64, U32 => U32: u32, I32 => I32: i32, + U64 => U64: u64, + I64 => I64: i64, ], scalar_kinds: [ Float, @@ -847,6 +849,8 @@ impl<'a> ConstantEvaluator<'a> { Scalar::AbstractInt([e]) => Ok(Scalar::AbstractInt([e.abs()])), Scalar::I32([e]) => Ok(Scalar::I32([e.wrapping_abs()])), Scalar::U32([e]) => Ok(Scalar::U32([e])), // TODO: just re-use the expression, ezpz + Scalar::I64([e]) => Ok(Scalar::I64([e.wrapping_abs()])), + Scalar::U64([e]) => Ok(Scalar::U64([e])), }) } crate::MathFunction::Min => { @@ -1280,7 +1284,7 @@ impl<'a> ConstantEvaluator<'a> { Literal::U32(v) => v as i32, Literal::F32(v) => v as i32, Literal::Bool(v) => v as i32, - Literal::F64(_) | Literal::I64(_) => { + Literal::F64(_) | Literal::I64(_) | Literal::U64(_) => { return make_error(); } Literal::AbstractInt(v) => i32::try_from_abstract(v)?, @@ -1291,18 +1295,40 @@ impl<'a> ConstantEvaluator<'a> { Literal::U32(v) => v, Literal::F32(v) => v as u32, Literal::Bool(v) => v as u32, - Literal::F64(_) | Literal::I64(_) => { + Literal::F64(_) | Literal::I64(_) | Literal::U64(_) => { return make_error(); } Literal::AbstractInt(v) => u32::try_from_abstract(v)?, Literal::AbstractFloat(v) => u32::try_from_abstract(v)?, }), + Sc::I64 => Literal::I64(match literal { + Literal::I32(v) => v as i64, + Literal::U32(v) => v as i64, + Literal::F32(v) => v as i64, + Literal::Bool(v) => v as i64, + Literal::F64(v) => v as i64, + Literal::I64(v) => v, + Literal::U64(v) => v as i64, + Literal::AbstractInt(v) => i64::try_from_abstract(v)?, + Literal::AbstractFloat(v) => i64::try_from_abstract(v)?, + }), + Sc::U64 => Literal::U64(match literal { + Literal::I32(v) => v as u64, + Literal::U32(v) => v as u64, + Literal::F32(v) => v as u64, + Literal::Bool(v) => v as u64, + Literal::F64(v) => v as u64, + Literal::I64(v) => v as u64, + Literal::U64(v) => v, + Literal::AbstractInt(v) => u64::try_from_abstract(v)?, + Literal::AbstractFloat(v) => u64::try_from_abstract(v)?, + }), Sc::F32 => Literal::F32(match literal { Literal::I32(v) => v as f32, Literal::U32(v) => v as f32, Literal::F32(v) => v, Literal::Bool(v) => v as u32 as f32, - Literal::F64(_) | Literal::I64(_) => { + Literal::F64(_) | Literal::I64(_) | Literal::U64(_) => { return make_error(); } Literal::AbstractInt(v) => f32::try_from_abstract(v)?, @@ -1314,7 +1340,7 @@ impl<'a> ConstantEvaluator<'a> { Literal::F32(v) => v as f64, Literal::F64(v) => v, Literal::Bool(v) => v as u32 as f64, - Literal::I64(_) => return make_error(), + Literal::I64(_) | Literal::U64(_) => return make_error(), Literal::AbstractInt(v) => f64::try_from_abstract(v)?, Literal::AbstractFloat(v) => f64::try_from_abstract(v)?, }), @@ -1325,6 +1351,7 @@ impl<'a> ConstantEvaluator<'a> { Literal::Bool(v) => v, Literal::F64(_) | Literal::I64(_) + | Literal::U64(_) | Literal::AbstractInt(_) | Literal::AbstractFloat(_) => { return make_error(); @@ -1877,6 +1904,122 @@ impl<'a> ConstantEvaluator<'a> { } } +/// Trait for conversions of abstract values to concrete types. +trait TryFromAbstract: Sized { + /// Convert an abstract literal `value` to `Self`. + /// + /// Since Naga's `AbstractInt` and `AbstractFloat` exist to support + /// WGSL, we follow WGSL's conversion rules here: + /// + /// - WGSL §6.1.2. Conversion Rank says that automatic conversions + /// to integers are either lossless or an error. + /// + /// - WGSL §14.6.4 Floating Point Conversion says that conversions + /// to floating point in constant expressions and override + /// expressions are errors if the value is out of range for the + /// destination type, but rounding is okay. + /// + /// [`AbstractInt`]: crate::Literal::AbstractInt + /// [`Float`]: crate::Literal::Float + fn try_from_abstract(value: T) -> Result; +} + +impl TryFromAbstract for i32 { + fn try_from_abstract(value: i64) -> Result { + i32::try_from(value).map_err(|_| ConstantEvaluatorError::AutomaticConversionLossy { + value: format!("{value:?}"), + to_type: "i32", + }) + } +} + +impl TryFromAbstract for u32 { + fn try_from_abstract(value: i64) -> Result { + u32::try_from(value).map_err(|_| ConstantEvaluatorError::AutomaticConversionLossy { + value: format!("{value:?}"), + to_type: "u32", + }) + } +} + +impl TryFromAbstract for u64 { + fn try_from_abstract(value: i64) -> Result { + u64::try_from(value).map_err(|_| ConstantEvaluatorError::AutomaticConversionLossy { + value: format!("{value:?}"), + to_type: "u64", + }) + } +} + +impl TryFromAbstract for i64 { + fn try_from_abstract(value: i64) -> Result { + Ok(value) + } +} + +impl TryFromAbstract for f32 { + fn try_from_abstract(value: i64) -> Result { + let f = value as f32; + // The range of `i64` is roughly ±18 × 10¹⁸, whereas the range of + // `f32` is roughly ±3.4 × 10³⁸, so there's no opportunity for + // overflow here. + Ok(f) + } +} + +impl TryFromAbstract for f32 { + fn try_from_abstract(value: f64) -> Result { + let f = value as f32; + if f.is_infinite() { + return Err(ConstantEvaluatorError::AutomaticConversionLossy { + value: format!("{value:?}"), + to_type: "f32", + }); + } + Ok(f) + } +} + +impl TryFromAbstract for f64 { + fn try_from_abstract(value: i64) -> Result { + let f = value as f64; + // The range of `i64` is roughly ±18 × 10¹⁸, whereas the range of + // `f64` is roughly ±1.8 × 10³⁰⁸, so there's no opportunity for + // overflow here. + Ok(f) + } +} + +impl TryFromAbstract for f64 { + fn try_from_abstract(value: f64) -> Result { + Ok(value) + } +} + +impl TryFromAbstract for i32 { + fn try_from_abstract(_: f64) -> Result { + Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "i32" }) + } +} + +impl TryFromAbstract for u32 { + fn try_from_abstract(_: f64) -> Result { + Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "u32" }) + } +} + +impl TryFromAbstract for i64 { + fn try_from_abstract(_: f64) -> Result { + Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "i64" }) + } +} + +impl TryFromAbstract for u64 { + fn try_from_abstract(_: f64) -> Result { + Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "u64" }) + } +} + #[cfg(test)] mod tests { use std::vec; @@ -2384,92 +2527,3 @@ mod tests { } } } - -/// Trait for conversions of abstract values to concrete types. -trait TryFromAbstract: Sized { - /// Convert an abstract literal `value` to `Self`. - /// - /// Since Naga's `AbstractInt` and `AbstractFloat` exist to support - /// WGSL, we follow WGSL's conversion rules here: - /// - /// - WGSL §6.1.2. Conversion Rank says that automatic conversions - /// to integers are either lossless or an error. - /// - /// - WGSL §14.6.4 Floating Point Conversion says that conversions - /// to floating point in constant expressions and override - /// expressions are errors if the value is out of range for the - /// destination type, but rounding is okay. - /// - /// [`AbstractInt`]: crate::Literal::AbstractInt - /// [`Float`]: crate::Literal::Float - fn try_from_abstract(value: T) -> Result; -} - -impl TryFromAbstract for i32 { - fn try_from_abstract(value: i64) -> Result { - i32::try_from(value).map_err(|_| ConstantEvaluatorError::AutomaticConversionLossy { - value: format!("{value:?}"), - to_type: "i32", - }) - } -} - -impl TryFromAbstract for u32 { - fn try_from_abstract(value: i64) -> Result { - u32::try_from(value).map_err(|_| ConstantEvaluatorError::AutomaticConversionLossy { - value: format!("{value:?}"), - to_type: "u32", - }) - } -} - -impl TryFromAbstract for f32 { - fn try_from_abstract(value: i64) -> Result { - let f = value as f32; - // The range of `i64` is roughly ±18 × 10¹⁸, whereas the range of - // `f32` is roughly ±3.4 × 10³⁸, so there's no opportunity for - // overflow here. - Ok(f) - } -} - -impl TryFromAbstract for f32 { - fn try_from_abstract(value: f64) -> Result { - let f = value as f32; - if f.is_infinite() { - return Err(ConstantEvaluatorError::AutomaticConversionLossy { - value: format!("{value:?}"), - to_type: "f32", - }); - } - Ok(f) - } -} - -impl TryFromAbstract for f64 { - fn try_from_abstract(value: i64) -> Result { - let f = value as f64; - // The range of `i64` is roughly ±18 × 10¹⁸, whereas the range of - // `f64` is roughly ±1.8 × 10³⁰⁸, so there's no opportunity for - // overflow here. - Ok(f) - } -} - -impl TryFromAbstract for f64 { - fn try_from_abstract(value: f64) -> Result { - Ok(value) - } -} - -impl TryFromAbstract for i32 { - fn try_from_abstract(_: f64) -> Result { - Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "i32" }) - } -} - -impl TryFromAbstract for u32 { - fn try_from_abstract(_: f64) -> Result { - Err(ConstantEvaluatorError::AutomaticConversionFloatToInt { to_type: "u32" }) - } -} -- cgit v1.2.3