oracle/graal · error · IllegalArgumentException

register %s is not allocatable

Error message

register %s is not allocatable

What it means

RegisterAllocationConfig.findRegister resolves a register name (from the RegisterPressure option's comma-separated restriction list) against the set of allocatable registers for the target architecture. If the name matches no register and the spec is not marked optional with a trailing '?', it throws IllegalArgumentException('register <name> is not allocatable').

Source

Thrown at compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/alloc/RegisterAllocationConfig.java:97

     * after the register name in the {@code spec}. In this case, {@code null} is returned instead
     * of throwing an exception.
     */
    private static Register findRegister(String spec, List<Register> all) {
        boolean optional = false;
        String name = spec;
        if (spec.endsWith("?")) {
            optional = true;
            name = spec.substring(0, spec.length() - 1);
        }
        for (Register reg : all) {
            if (reg.name.equals(name)) {
                return reg;
            }
        }
        if (optional) {
            return null;
        }
        throw new IllegalArgumentException("register " + name + " is not allocatable");
    }

    protected List<Register> initAllocatable(List<Register> registers) {
        if (allocationRestrictedTo != null) {
            Register[] regs = new Register[allocationRestrictedTo.length];
            int i = 0;
            for (String spec : allocationRestrictedTo) {
                Register register = findRegister(spec, registers);
                if (register == null) {
                    regs = Arrays.copyOf(regs, regs.length - 1);
                } else {
                    regs[i++] = register;
                }
            }
            return List.of(regs);
        }

        return registers;

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Correct the register list to names valid for the target architecture — inspect the arch's Register class (e.g. AMD64.cpuRegisters / AArch64.cpuRegisters) for the canonical names.
  2. Remove -Dgraal.RegisterPressure entirely if you did not intend to restrict allocation.
  3. Append '?' to a spec (e.g. 'k?' on AArch64) when a register may or may not be allocatable on the current configuration, so absence is tolerated.

Example fix

# before (run on aarch64)
-Dgraal.RegisterPressure=rax,rbx,rcx

# after
-Dgraal.RegisterPressure=x0,x1,x2
Defensive patterns

Strategy: validation

Validate before calling

// verify every spec resolves against the target arch's allocatable set
Set<String> allocatable = Arrays.stream(registerConfig.getAllocatableRegisters())
                .map(r -> r.name).collect(Collectors.toSet());
for (String spec : registerPressure.split(",")) {
    String name = spec.endsWith("?") ? spec.substring(0, spec.length() - 1) : spec;
    if (!allocatable.contains(name)) {
        throw new IllegalArgumentException("Unknown register for this arch: " + name);
    }
}

Prevention

When it happens

Trigger: Setting -Dgraal.RegisterPressure=rax,rbx,whatever on x86-64 where 'whatever' is not a register name, or copying a register list between architectures (e.g. x0-x28 AArch64 names used on AMD64, or vice versa). The optional form 'name?' returns null instead of throwing.

Common situations: Benchmark scripts or CI matrices that pin RegisterPressure for register-allocation experiments and are then run on a different architecture/container image; typos in register names; using platform register aliases (e.g. 'r13' vs 'sp' naming differences across Graal versions).

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/230a2344057ffec0. Report an issue: GitHub.