{"record":{"id":"eb05a572ca7d3da5","repo":"gfx-rs/wgpu","slug":"unexpected-firstleadingbit","errorCode":null,"errorMessage":"Unexpected firstLeadingBit({:?})","messagePattern":"Unexpected firstLeadingBit\\((.+?)\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"naga/src/back/spv/block.rs","lineNumber":1944,"sourceCode":"                        ));\n\n                        MathOp::Custom(Instruction::quaternary(\n                            spirv::Op::BitFieldInsert,\n                            result_type_id,\n                            id,\n                            arg0_id,\n                            arg1_id,\n                            offset_id,\n                            count_id,\n                        ))\n                    }\n                    Mf::FirstTrailingBit => MathOp::Ext(spirv::GlslStd450Op::FindILsb),\n                    Mf::FirstLeadingBit => {\n                        if arg_ty.scalar_width() == Some(4) {\n                            let thing = match arg_scalar_kind {\n                                Some(crate::ScalarKind::Uint) => spirv::GlslStd450Op::FindUMsb,\n                                Some(crate::ScalarKind::Sint) => spirv::GlslStd450Op::FindSMsb,\n                                other => unimplemented!(\"Unexpected firstLeadingBit({:?})\", other),\n                            };\n                            MathOp::Ext(thing)\n                        } else {\n                            unreachable!(\"This is validated out until a polyfill is implemented. https://github.com/gfx-rs/wgpu/issues/5276\");\n                        }\n                    }\n                    Mf::Pack4x8unorm => MathOp::Ext(spirv::GlslStd450Op::PackUnorm4x8),\n                    Mf::Pack4x8snorm => MathOp::Ext(spirv::GlslStd450Op::PackSnorm4x8),\n                    Mf::Pack2x16float => MathOp::Ext(spirv::GlslStd450Op::PackHalf2x16),\n                    Mf::Pack2x16unorm => MathOp::Ext(spirv::GlslStd450Op::PackUnorm2x16),\n                    Mf::Pack2x16snorm => MathOp::Ext(spirv::GlslStd450Op::PackSnorm2x16),\n                    fun @ (Mf::Pack4xI8 | Mf::Pack4xU8 | Mf::Pack4xI8Clamp | Mf::Pack4xU8Clamp) => {\n                        let is_signed = matches!(fun, Mf::Pack4xI8 | Mf::Pack4xI8Clamp);\n                        let should_clamp = matches!(fun, Mf::Pack4xI8Clamp | Mf::Pack4xU8Clamp);\n\n                        let last_instruction =\n                            if self.writer.require_all(&[spirv::Capability::Int8]).is_ok() {\n                                self.write_pack4x8_optimized(","sourceCodeStart":1926,"sourceCodeEnd":1962,"githubUrl":"https://github.com/gfx-rs/wgpu/blob/3e11ff59bf3f9795d285ecc045014089640d7248/naga/src/back/spv/block.rs#L1926-L1962","documentation":"Panic from the `MathFunction::FirstLeadingBit` lowering in the SPIR-V backend. For 32-bit operands it maps to GLSL.std.450 FindUMsb/FindSMsb by scalar kind; any other kind (Float, Bool, None) hits `unimplemented!()`. Widths other than 32 bits are validated out entirely (`unreachable!`).","triggerScenarios":"`firstLeadingBit(x)` where x's scalar kind is neither Uint nor Sint (e.g. float operand), or where the kind info is missing, during SPIR-V emission.","commonSituations":"Bit-manipulation-heavy shaders transpiled from other languages where the intrinsic accepts floats or where types were inferred incorrectly; extremely rare in valid WGSL.","solutions":["Bitcast to an integer first: `firstLeadingBit(bitcast<u32>(x))`","Confirm the operand is i32/u32 and not f32 after constant folding","Run the shader through naga's validator/CLI to isolate the failing expression","Update naga/wgpu; report a reproducer if the shader is valid WGSL"],"exampleFix":"// before\nlet fb = firstLeadingBit(x); // x: f32\n// after\nlet fb = firstLeadingBit(bitcast<i32>(x));","handlingStrategy":"validation","validationCode":"fn check_first_leading_bit(module: &naga::Module) -> bool {\n    // firstLeadingBit requires 32-bit Sint/Uint operands\n    module.global_expressions.iter().all(|(_, e)| match e {\n        naga::Expression::Math { fun: naga::MathFunction::FirstLeadingBit, args, .. } => args.first().map_or(true, |a| {\n            matches!(ty_of(module, *a).inner,\n                naga::TypeInner::Scalar(s) | naga::TypeInner::Vector { scalar: s, .. }\n                if s.width == 4 && matches!(s.kind, naga::ScalarKind::Sint | naga::ScalarKind::Uint))\n        }),\n        _ => true,\n    })\n}","typeGuard":"fn first_leading_bit_supported(s: naga::Scalar) -> bool {\n    s.width == 4 && matches!(s.kind, naga::ScalarKind::Sint | naga::ScalarKind::Uint)\n}","tryCatchPattern":null,"preventionTips":["Bitcast float operands to i32/u32 before firstLeadingBit","Remember only 32-bit widths are supported in SPIR-V output (issue #5276)","Validate with the naga CLI before runtime compilation","Catch panics when compiling third-party shaders"],"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"}