Repository navigation
Conversation
With SPV_KHR_float_controls2, the LLVM back-end replaces the
ContractionOff execution mode it gives kernels by FPFastMathDefault (with
no flags) for every floating-point type in the module. It only declares
the FloatControls2 capability and the extension that mode needs when it
decorates an instruction with fast-math flags, though, so a kernel with
floating-point types but without `contract` operations fails
validation:
Operand 2 of ExecutionModeId requires one of these capabilities:
FloatControls2
Add the missing declarations to the binary the back-end generates.
Declaring the defaults through `spirv.ExecutionMode` metadata instead
makes the back-end account for them, but then crashes it in
`handleMIFlagDecoration` on some `OpExtInst`s.
Assisted-by: Claude Code (Opus 5.5)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1007 +/- ##
==========================================
+ Coverage 89.49% 89.54% +0.05%
==========================================
Files 31 31
Lines 6902 6937 +35
==========================================
+ Hits 6177 6212 +35
Misses 725 725 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Shouldn't we fix this on LLVM instead and backport the fix to our SPIR-V back-end? |
With
extensions = "+SPV_KHR_float_controls2", the LLVM SPIR-V back-end emits per-instructionFPFastMathMode AllowContractforcontractoperations, which is howmuladdcan reach drivers as an FMA (JuliaGPU/KernelAbstractions.jl#865). KA and OpenCL.jl are about to enable the extension when the device reports it. With the extension enabled, though, most float kernels currently fail validation:Cause (LLVM bug, still on
main).SPIRVAsmPrinterreplaces theContractionOffit gives kernels with an implicitFPFastMathDefault(no flags) for every FP type in the module.SPIRVModuleAnalysisonly registers theFloatControls2capability and the extension for explicitspirv.ExecutionModemetadata, or when it decorates an instruction. So any kernel with float types but nocontractoperation is invalid. That includes a float type that appears only in the signature or inside a vector.Fix. After the LLVM back-end runs, if the binary uses
FPFastMathDefaultbut lacksOpCapability FloatControls2orOpExtension "SPV_KHR_float_controls2", insert them. Otherwise the module is exactly what the back-end meant to emit; the patch is a no-op without the extension.Declaring the defaults through
spirv.ExecutionModemetadata looks cleaner, but it hits a second back-end bug. Once a function has explicitFPFastMathDefaultinfo,handleMIFlagDecorationlooks up the type of every instruction that can take fast-math flags, and for someOpExtInsts it gets operand 1 (the result type). The back-end segfaulted that way inaddDecorationson GPUArrays'accumulatekernels. Only the:llvmback-end is affected; the Khronos translator declares what it needs.Tests. A new "float controls" testset covers both back-ends, with the extension enabled:
muladdkernel, which must getAllowContract;All are validated by
spirv-val. With the patch disabled, the strict, signature and vector cases fail on:llvm.test/runtests.jl spirv: 733/733 pass.End to end, with a PoCL build that accepts the extension (pocl/pocl#2393, LLVM 23.1.1) and the KA/OpenCL.jl PRs:
mainon the same PoCL, plus the new testset. One testset is excluded on both: "CPU back-end", where PoCL 8.0-pre with LLVM 23 aborts withCould not find a dominating alternative variableregardless of this change.main. The extra 6 are the new tests. The same twointrinsicscrashes occur on both: illegal instructions from that PoCL build.spirv-valon most float kernels.Both LLVM bugs should also be fixed upstream; this works around the first and avoids the second.
🤖 Generated with Claude Code