{"record":{"id":"5ce4ba1d0064dd68","repo":"openjdk/jdk","slug":"warning-cannot-find-memory-opnd-in-instr","errorCode":null,"errorMessage":"Warning: cannot find memory opnd in instr.\n","messagePattern":"Warning: cannot find memory opnd in instr\\.\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/hotspot/share/adlc/formssel.cpp","lineNumber":746,"sourceCode":"      assert(false, \"bad case analysis\");\n    }\n    // process the unique DEF or USE, if there is one\n    if( unique == nullptr ) {\n      return MANY_MEMORY_OPERANDS;\n    } else {\n      int pos = components.operand_position(unique->_name);\n      if( unique->isa(Component::DEF) ) {\n        pos += 1;                // get corresponding USE from DEF\n      }\n      assert(pos >= 1, \"I was just looking at it!\");\n      return pos;\n    }\n  }\n\n  // missed the memory op??\n  if( true ) {  // %%% should not be necessary\n    if( is_ideal_store() != Form::none ) {\n      fprintf(stderr, \"Warning: cannot find memory opnd in instr.\\n\");\n      ((InstructForm*)this)->dump();\n      // pretend it has multiple defs and uses\n      return MANY_MEMORY_OPERANDS;\n    }\n    if( is_ideal_load()  != Form::none ) {\n      fprintf(stderr, \"Warning: cannot find memory opnd in instr.\\n\");\n      ((InstructForm*)this)->dump();\n      // pretend it has multiple uses and no defs\n      return MANY_MEMORY_OPERANDS;\n    }\n  }\n\n  return NO_MEMORY_OPERAND;\n}\n\n// Access instr_cost attribute or return null.\nconst char* InstructForm::cost() {\n  for (Attribute* cur = _attribs; cur != nullptr; cur = (Attribute*)cur->_next) {","sourceCodeStart":728,"sourceCodeEnd":764,"githubUrl":"https://github.com/openjdk/jdk/blob/88dfb74bbeefcf2b0aa11835183bcd949998fc8f/src/hotspot/share/adlc/formssel.cpp#L728-L764","documentation":"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.","triggerScenarios":"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().","commonSituations":"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).","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"],"exampleFix":"// before (aarch64.ad-style, memory operand missing from match)\n// enc_class enc_store(...);\n// match(Set mem (StoreI mem src)) // but 'mem' not declared as operand\n\n// after\noperand indOffI(...) ...\n// ...\ninstruct storeI(iRegI src, memory4 mem) %{\n  match(Set mem (StoreI mem src));\n  // 'mem' now appears as a declared operand, so the DEF component is found\n%}","handlingStrategy":"validation","validationCode":"# Before building, sanity-check every load/store instruction in the .ad file\n# has its memory operand named in the match rule:\ngrep -nE 'match\\\\(Set [^ ]+ \\\\(Store|Load)' src/hotspot/cpu/$ARCH/$ARCH.ad | less\n# then confirm each listed instruction declares the memory operand used in the rule","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["hotspot","adlc","codegen","ad-file","matcher"],"backgroundTag":null,"analyzedSha":"88dfb74bbeefcf2b0aa11835183bcd949998fc8f","analyzedAt":"2026-08-14T11:45:09.665Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}