{"record":{"id":"593683d738dd1eed","repo":"oracle/graal","slug":"there-are-no-allocatable-registers-for-kind-s-co","errorCode":null,"errorMessage":"There are no allocatable registers for kind %s, consider assigning fixed registers.","messagePattern":"There are no allocatable registers for kind (.+?), consider assigning fixed registers\\.","errorType":"exception","errorClass":"OutOfRegistersException","httpStatus":null,"severity":"critical","filePath":"compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanWalker.java","lineNumber":1146,"sourceCode":"                if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) {\n                    DebugContext debug = allocator.getDebug();\n                    if (debug.isLogEnabled()) {\n                        debug.log(\"free register cannot be available because all registers blocked by following call\");\n                    }\n\n                    // safety check that there is really no register available\n                    assert !allocFreeRegister(interval) : \"found a register for this interval\";\n                    return true;\n                }\n            }\n        }\n        return false;\n    }\n\n    void initVarsForAlloc(Interval interval) {\n        AllocatableRegisters allocatableRegisters = allocator.getRegisterAllocationConfig().getAllocatableRegisters(interval.kind().getPlatformKind());\n        if (allocatableRegisters == null) {\n            throw new OutOfRegistersException(\"There are no allocatable registers for kind \" + interval.kind().getPlatformKind() + \", consider assigning fixed registers.\");\n        }\n        availableRegs = allocatableRegisters.allocatableRegisters.toArray(Register[]::new);\n        minReg = allocatableRegisters.minRegisterNumber;\n        maxReg = allocatableRegisters.maxRegisterNumber;\n    }\n\n    static boolean isMove(LIRInstruction op, Interval from, Interval to) {\n        if (StandardOp.ValueMoveOp.isValueMoveOp(op)) {\n            StandardOp.ValueMoveOp move = StandardOp.ValueMoveOp.asValueMoveOp(op);\n            if (LIRValueUtil.isVariable(move.getInput()) && LIRValueUtil.isVariable(move.getResult())) {\n                return move.getInput() != null && move.getInput().equals(from.operand) && move.getResult() != null && move.getResult().equals(to.operand);\n            }\n        }\n        return false;\n    }\n\n    // optimization (especially for phi functions of nested loops):\n    // assign same spill slot to non-intersecting intervals","sourceCodeStart":1128,"sourceCodeEnd":1164,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/lir/alloc/lsra/LinearScanWalker.java#L1128-L1164","documentation":"initVarsForAlloc asks the RegisterAllocationConfig for the allocatable registers of the interval's platform kind; if the backend never registered any allocatable register for that kind, allocatableRegisters is null and an OutOfRegistersException is thrown with the suggestion 'consider assigning fixed registers'. It means the target configuration is fundamentally unable to hold values of that kind, not merely that pressure is high.","triggerScenarios":"An interval whose LIRKind carries a PlatformKind (often a vector kind like AVX512 mask registers, or a custom kind added to a new backend) for which RegisterConfig.getAllocatableRegisters returns null. Happens with custom/new architectures, misconfigured RegisterAllocationConfig, or when a generic phase emits a kind the current backend does not allocate registers for.","commonSituations":"Developing or backporting a Graal backend for a new architecture; using an experimental vector kind not yet wired into the register configuration; porting a patch where RegisterConfig.registerAllocationConfig was built without an entry for the new kind.","solutions":["In the backend's RegisterConfig/CompilationSetup, define allocatable (or at minimum fixed) registers for the failing platform kind named in the message","Verify the kind reaches LIR correctly: if the value should have been lowered to a supported kind before allocation, fix the lowering so unallocatable kinds never survive to LSRA","If the kind is only used behind a feature flag/arch check, ensure the frontend does not emit it on architectures where it is unsupported","Search the repo for existing backends handling the same kind (grep getAllocatableRegisters in compiler/src/jdk.graal.compiler/src/com.oracle.graal.lir) and mirror their configuration"],"exampleFix":"// before: new vector kind has no register class -> null allocatable registers\n// in MyArchRegisterConfig:\n//   (no entry for V512_MASK)\n\n// after: assign registers for the kind\n//   map Kind.V512_MASK -> allocatable set {k0..k7} in the RegisterAllocationConfig builder","handlingStrategy":"validation","validationCode":"// Backend author: assert during setup that every kind you emit has registers\nfor (PlatformKind kind : arch.getPlatformKinds()) {\n    AllocatableRegisters regs = registerConfig.getAllocatableRegisters(kind);\n    if (regs == null && frontendEmits(kind)) {\n        throw new IllegalStateException(\"No allocatable registers configured for \" + kind);\n    }\n}","typeGuard":null,"tryCatchPattern":"try { compile(m); } catch (OutOfRegistersException e) { /* config-level bug: fail fast in tests */ throw e; }","preventionTips":["When adding a PlatformKind to a backend, add its register set in the same change","Run backend smoke tests that emit every supported kind through LSRA","Gate experimental kinds behind arch checks so they never reach allocation unconfigured"],"tags":["graalvm","register-allocation","backend","configuration"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}