openjdk/jdk · critical
ERROR: More than one register has been assigned register-num
Error message
ERROR: More than one register has been assigned register-number 0. Probably because a register has not been entered into an allocation class.
What it means
RegisterForm verification error in ADLC: after processing all register classes, more than one RegDef still reports register_num() == 0. Registers not entered into any allocation class keep the default number 0, and multiple such registers collide, which would produce corrupt register masks in the generated matcher code. ADLC prints this 'ERROR:' and the RegisterForm::verify() result marks the file invalid.
Source
Thrown at src/hotspot/share/adlc/formsopt.cpp:157
// Verify Register Classes
// check that each register class contains registers from one chunk
const char *rc_name = nullptr;
_rclasses.reset();
while ( (rc_name = _rclasses.iter()) != nullptr ) {
// Check the chunk value for all registers in this class
RegClass *reg_class = getRegClass(rc_name);
assert( reg_class != nullptr, "InternalError() no matching register class");
} // end of RegClasses
// Verify that every register has been placed into an allocation class
RegDef *reg_def = nullptr;
reset_RegDefs();
uint num_register_zero = 0;
while ( (reg_def = iter_RegDefs()) != nullptr ) {
if( reg_def->register_num() == 0 ) ++num_register_zero;
}
if( num_register_zero > 1 ) {
fprintf(stderr,
"ERROR: More than one register has been assigned register-number 0.\n"
"Probably because a register has not been entered into an allocation class.\n");
}
return valid;
}
// Compute the least number of words required for registers in register masks.
int RegisterForm::words_for_regs() {
return (_reg_ctr + 31) >> 5;
}
// Compute RegMask size
int RegisterForm::RegMask_Size() {
// The array of Register Mask bits should be large enough to cover all the
// machine registers, as well as a certain number of parameters that need to
// be passed on the stack (stack registers). The number of parameters that can
// fit in the mask should be dimensioned to cover most common cases.View on GitHub (pinned to 88dfb74bbe)
Solutions
- Add each unassigned register to at least one reg_class in the register block of the .ad file
- Cross-check every 'reg_def' name appears inside some 'reg_class ... %name ...' declaration
- Rerun adlc and confirm the ERROR no longer prints before trusting generated adfiles
Example fix
// before reg_def R8 reg_def R9 // never added to a class reg_class ptr_r reg_read_r; // after reg_class ptr_r reg_read_r R8 R9;
Defensive patterns
Strategy: validation
Validate before calling
# every reg_def name must appear inside some reg_class body
for r in $(grep -oP '(?<=^reg_def )\S+' x86_64.ad); do grep -q "reg_class.*[({].*\b$r\b" x86_64.ad || echo "register $r not in any allocation class"; done Prevention
- Add every new reg_def to at least one reg_class in the same change
- Grep each register name against reg_class blocks before building
- Treat this ERROR as blocking: generated masks would be corrupt
When it happens
Trigger: Declaring a register in 'reg_def' but omitting it from every 'reg_class' / allocation-class definition in the .ad file; two or more such omissions trigger the >1 count. Register numbering is assigned only as classes are iterated (see the preceding RegClasses loop).
Common situations: Adding a new physical register (e.g. a new vector register) and forgetting the reg_class membership; reordering or renaming reg_class blocks so a def no longer matches; porting .ad files between architectures.
Related errors
- Error: Out of memory in ADLC\n
- %s: Found %d syntax error
- %s: Found %d semantic error
- %s: Found %d warning
- Error Context: %s>>>%c<<<%s
AI-assisted analysis of openjdk/jdk@88dfb74bbe (2026-08-14).
Data as JSON: /api/errors/e720d890e52f0a62.
Report an issue: GitHub.