{"record":{"id":"9d17da5174837d7c","repo":"gfx-rs/wgpu","slug":"unexpected-sign","errorCode":null,"errorMessage":"Unexpected sign({:?})","messagePattern":"Unexpected sign\\((.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"naga/src/back/spv/block.rs","lineNumber":1662,"sourceCode":"                    )),\n                    Mf::Cross => MathOp::Ext(spirv::GlslStd450Op::Cross),\n                    Mf::Distance => MathOp::Ext(spirv::GlslStd450Op::Distance),\n                    Mf::Length => MathOp::Ext(spirv::GlslStd450Op::Length),\n                    Mf::Normalize => MathOp::Ext(spirv::GlslStd450Op::Normalize),\n                    Mf::FaceForward => MathOp::Ext(spirv::GlslStd450Op::FaceForward),\n                    Mf::Reflect => MathOp::Ext(spirv::GlslStd450Op::Reflect),\n                    Mf::Refract => MathOp::Ext(spirv::GlslStd450Op::Refract),\n                    // exponent\n                    Mf::Exp => MathOp::Ext(spirv::GlslStd450Op::Exp),\n                    Mf::Exp2 => MathOp::Ext(spirv::GlslStd450Op::Exp2),\n                    Mf::Log => MathOp::Ext(spirv::GlslStd450Op::Log),\n                    Mf::Log2 => MathOp::Ext(spirv::GlslStd450Op::Log2),\n                    Mf::Pow => MathOp::Ext(spirv::GlslStd450Op::Pow),\n                    // computational\n                    Mf::Sign => MathOp::Ext(match arg_scalar_kind {\n                        Some(crate::ScalarKind::Float) => spirv::GlslStd450Op::FSign,\n                        Some(crate::ScalarKind::Sint) => spirv::GlslStd450Op::SSign,\n                        other => unimplemented!(\"Unexpected sign({:?})\", other),\n                    }),\n                    Mf::Fma => MathOp::Ext(spirv::GlslStd450Op::Fma),\n                    Mf::Mix => {\n                        let selector = arg2.unwrap();\n                        let selector_ty =\n                            self.fun_info[selector].ty.inner_with(&self.ir_module.types);\n                        match (arg_ty, selector_ty) {\n                            // if the selector is a scalar, we need to splat it\n                            (\n                                &crate::TypeInner::Vector { size, .. },\n                                &crate::TypeInner::Scalar(scalar),\n                            ) => {\n                                let selector_type_id =\n                                    self.get_numeric_type_id(NumericType::Vector { size, scalar });\n                                self.temp_list.clear();\n                                self.temp_list.resize(size as usize, arg2_id);\n\n                                let selector_id = self.gen_id();","sourceCodeStart":1644,"sourceCodeEnd":1680,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/naga/src/back/spv/block.rs#L1644-L1680","documentation":"Panic in the SPIR-V backend's `MathFunction::Sign` lowering. The GLSL.std.450 extended instruction differs per scalar kind (FSign for floats, SSign for signed ints); if `arg_scalar_kind` is None or an unsupported kind (e.g. Uint, Bool), the `unimplemented!()` arm fires. Note unsigned `sign` is not provided by GLSL.std.450.","triggerScenarios":"A `sign(x)` call in a shader where x's scalar kind is not Float or Sint, most commonly `sign(uint_value)` or a bool-typed expression, during SPIR-V emission in `cache_expression_value`.","commonSituations":"Ported code from languages where sign works on unsigned ints (e.g. HLSL or generated code); WGSL authors normally get a frontend error first, so this appears with other frontends or IR constructed programmatically.","solutions":["Avoid `sign` on unsigned values: for uint, replace with `select(0u, 1u, x != 0u)` or compare directly","Cast to i32/f32 before calling sign: `sign(i32(x))`","Update naga to a version that either supports the case or reports a validation error","File a wgpu issue with a minimal shader if the case should be supported"],"exampleFix":"// before\nlet s = sign(u);\n// after\nlet s = sign(i32(u));","handlingStrategy":"validation","validationCode":"fn check_sign_operand(module: &naga::Module) -> bool {\n    // sign supports only Float (FSign) and Sint (SSign)\n    module.global_expressions.iter().all(|(_, e)| match e {\n        naga::Expression::Math { fun: naga::MathFunction::Sign, args, .. } => args.iter().all(|a| {\n            matches!(ty_of(module, *a).inner,\n                naga::TypeInner::Scalar(s) | naga::TypeInner::Vector { scalar: s, .. }\n                if matches!(s.kind, naga::ScalarKind::Float | naga::ScalarKind::Sint))\n        }),\n        _ => true,\n    })\n}","typeGuard":"fn sign_supported(s: naga::Scalar) -> bool {\n    matches!(s.kind, naga::ScalarKind::Float | naga::ScalarKind::Sint)\n}","tryCatchPattern":null,"preventionTips":["Never call sign() on unsigned values; express uint sign via select/comparison","Cast to i32/f32 before sign","Validate modules before backend emission","Isolate shader compilation panics with catch_unwind"],"tags":["spirv","shader-compilation","naga","unimplemented"],"backgroundTag":"unimplemented-shader-feature","analyzedSha":"3e11ff59bf3f9795d285ecc045014089640d7248","analyzedAt":"2026-09-03T01:43:21.459Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T07:17:11.731Z"}