openjdk/jdk · warning
Warning: cannot find memory opnd in instr.
Error message
Warning: cannot find memory opnd in instr.
What it means
Emitted by the ADL compiler (adlc) while generating the matcher for a CPU description file (.ad). InstructForm::operands_for_memory_op walks the instruction's components and match rule looking for the operand that plays the memory (DEF) role of a store; if the instruction is recognized as an ideal store (is_ideal_store()) but no memory operand was found, this warning is printed and MANY_MEMORY_OPERANDS is returned as a safe fallback so code generation still treats the instruction's memory effects conservatively.
Source
Thrown at src/hotspot/share/adlc/formssel.cpp:746
assert(false, "bad case analysis");
}
// process the unique DEF or USE, if there is one
if( unique == nullptr ) {
return MANY_MEMORY_OPERANDS;
} else {
int pos = components.operand_position(unique->_name);
if( unique->isa(Component::DEF) ) {
pos += 1; // get corresponding USE from DEF
}
assert(pos >= 1, "I was just looking at it!");
return pos;
}
}
// missed the memory op??
if( true ) { // %%% should not be necessary
if( is_ideal_store() != Form::none ) {
fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");
((InstructForm*)this)->dump();
// pretend it has multiple defs and uses
return MANY_MEMORY_OPERANDS;
}
if( is_ideal_load() != Form::none ) {
fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");
((InstructForm*)this)->dump();
// pretend it has multiple uses and no defs
return MANY_MEMORY_OPERANDS;
}
}
return NO_MEMORY_OPERAND;
}
// Access instr_cost attribute or return null.
const char* InstructForm::cost() {
for (Attribute* cur = _attribs; cur != nullptr; cur = (Attribute*)cur->_next) {View on GitHub (pinned to 88dfb74bbe)
Solutions
- Inspect the instruction dump printed right after the warning (InstructForm::dump()) to see which operands adlc actually collected
- Check the match rule of the flagged instruction in the .ad file and make sure the memory input of the ideal store node is bound to a named operand (e.g. storeI (mem) (src) -> ... match(Set mem (StoreI mem src)) ...)
- Verify that the operand used for the memory input is declared in the encodings/ins pipe spec and that its Component role is DEF; fix the operand name typo if components.operand_position(name) fails
- Re-run the build; adlc warnings on stderr during compilation of the .ad files are the signal — treat any 'cannot find memory opnd' as a bug in the description even though code generation continues
Example fix
// before (aarch64.ad-style, memory operand missing from match)
// enc_class enc_store(...);
// match(Set mem (StoreI mem src)) // but 'mem' not declared as operand
// after
operand indOffI(...) ...
// ...
instruct storeI(iRegI src, memory4 mem) %{
match(Set mem (StoreI mem src));
// 'mem' now appears as a declared operand, so the DEF component is found
%} Defensive patterns
Strategy: validation
Validate before calling
# Before building, sanity-check every load/store instruction in the .ad file # has its memory operand named in the match rule: grep -nE 'match\\(Set [^ ]+ \\(Store|Load)' src/hotspot/cpu/$ARCH/$ARCH.ad | less # then confirm each listed instruction declares the memory operand used in the rule
Prevention
- Treat any adlc stderr warning as a build failure in CI: pipe adlc output and grep for 'cannot find memory opnd'
- When adding instructions, copy the closest existing load/store pattern and keep the memory operand name consistent between the operand list and the match rule
- Run a debug-asserts build of adlc so shape mistakes abort loudly instead of generating conservative matcher code
When it happens
Trigger: Adding or editing an instruction in a hotspot .ad file (e.g. src/hotspot/cpu/<arch>/<arch>.ad) whose match rule matches an ideal store node (storeB/storeI/storeP/StoreCM...) but whose operand list / match rule does not expose a memory (DEF) operand that operands_for_memory_op can resolve via components.operand_position().
Common situations: Porting HotSpot to a new architecture, adding a new store intrinsic or vector store instruction, renaming an operand so the DEF component no longer matches the name used in the match rule, or copying an existing pattern but forgetting the memory input (%s memory operand).
Related errors
- No format defined for %s
- *** used_mask is 0 ***
- pipeline_res_mask_initializer: semantic error: pipeline stag
- Error: Out of memory in ADLC\n
- %s: Found %d syntax error
AI-assisted analysis of openjdk/jdk@88dfb74bbe (2026-08-14).
Data as JSON: /api/errors/5ce4ba1d0064dd68.
Report an issue: GitHub.