{"record":{"id":"86d2060c404e4ca4","repo":"stride3d/stride","slug":"unsupported-element-type-for-abs-context-reversetypes-x","errorCode":null,"errorMessage":"Unsupported element type for abs: {context.ReverseTypes[x.TypeId].GetElementType()}","messagePattern":"Unsupported element type for abs: (.+?)","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs","lineNumber":99,"sourceCode":"    }\n\n    // Derivatives\n    public override SpirvValue CompileDdx(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdx, x);\n    public override SpirvValue CompileDdx_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdxCoarse, x);\n    public override SpirvValue CompileDdx_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdxFine, x);\n    public override SpirvValue CompileDdy(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdy, x);\n    public override SpirvValue CompileDdy_coarse(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdyCoarse, x);\n    public override SpirvValue CompileDdy_fine(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpDPdyFine, x);\n    public override SpirvValue CompileFwidth(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.Op.OpFwidth, x);\n\n    // Per component math\n    public override SpirvValue CompileAbs(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default)\n    {\n        var instruction = context.ReverseTypes[x.TypeId].GetElementType() switch\n        {\n            ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)),\n            ScalarType { Type: Scalar.UInt or Scalar.Int } => builder.InsertData(new GLSLSAbs(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), x.Id)),\n            _ => throw new NotSupportedException($\"Unsupported element type for abs: {context.ReverseTypes[x.TypeId].GetElementType()}\"),\n        };\n        return new(instruction);\n    }\n    public override SpirvValue CompileFloor(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLFloor, x);\n    public override SpirvValue CompileCeil(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLCeil, x);\n    public override SpirvValue CompileTrunc(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue x, TextLocation location = default) => CompileGLSLFloatUnaryCall(table, context, builder, functionType.ReturnType, Specification.GLSLOp.GLSLTrunc, x);\n    public override SpirvValue CompileMin(SymbolTable table, SpirvContext context, SpirvBuilder builder, FunctionType functionType, SpirvValue a, SpirvValue b, TextLocation location = default)\n    {\n        var instruction = context.ReverseTypes[a.TypeId].GetElementType() switch\n        {\n            ScalarType { Type: Scalar.Float or Scalar.Double } => builder.InsertData(new GLSLFMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            ScalarType { Type: Scalar.UInt } => builder.InsertData(new GLSLUMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            ScalarType { Type: Scalar.Int } => builder.InsertData(new GLSLSMin(context.GetOrRegister(functionType.ReturnType), context.Bound++, context.GetGLSL(), a.Id, b.Id)),\n            _ => throw new NotSupportedException($\"Unsupported element type for min: {context.ReverseTypes[a.TypeId].GetElementType()}\"),\n        };\n        return new(instruction);\n    }\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/AST/IntrinsicImplementations.cs#L81-L117","documentation":"CompileAbs compiles the abs() intrinsic to GLSL.FAbs for float/double elements and GLSL.SAbs for signed/unsigned integers. If the element type of the operand is anything else (e.g. bool, half if unsupported, or a non-scalar element), the switch default throws NotSupportedException at IntrinsicImplementations.cs:99.","triggerScenarios":"Calling abs() on a value whose SPIR-V element scalar type is neither Float, Double, Int, nor UInt — for example a bool vector or an exotic scalar type.","commonSituations":"Applying abs() to boolean or non-numeric values, or after adding a new scalar type (e.g. float16/int16) without extending the intrinsic implementation.","solutions":["Apply abs() only to int/uint/float/double scalars or vectors of those types.","For bools, use the value directly (booleans have no sign); for other numeric types cast first.","If a new scalar kind must work, add an arm choosing the appropriate GLSL extended instruction in CompileAbs."],"exampleFix":"// before\nbool2 b; abs(b);            // unsupported\n// after\nint2 v = int2(-1, 2); int2 a = abs(v);","handlingStrategy":"type-guard","validationCode":"// abs supports int/uint/float/double element types only\nif (valueType.GetElementType() is not ScalarType { Type: Scalar.Float or Scalar.Double or Scalar.Int or Scalar.UInt })\n    throw new ShaderCompileHint(\"abs requires numeric scalar element type\");","typeGuard":"static bool IsAbsSupported(BaseType t) => t.GetElementType() is ScalarType s && s.Type is Scalar.Float or Scalar.Double or Scalar.Int or Scalar.UInt;","tryCatchPattern":"try { result = intrinsic.CompileAbs(table, context, builder, functionType, x); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"element type for abs\"))\n{ diagnostics.Report(location, ex.Message); }","preventionTips":["Apply abs() only to signed/unsigned ints and float/double values.","Avoid abs() on bools; cast new scalar types (half, int16) before use.","Extend CompileAbs whenever a new scalar type is added to the type system."],"tags":["shader","intrinsics","spirv","glm"],"backgroundTag":"unsupported-dtype","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}