From a52b6de58deaef0730427142264956fb40564afb Mon Sep 17 00:00:00 2001 From: Henry Zongaro Date: Thu, 4 Jan 2024 09:19:41 -0800 Subject: [PATCH] Prevent commoning of l2a operations in localCSE An l2a operation might be used to convert the result of a compressed reference sequence to an address, but it is also used in other circumstances - for instance, if an Int64 value holds the address of a j9class or a j9method. The l2aEvaluators assume that l2a is used for compressed references or accessing arraylets. If the node is not accessing an arraylet and compressed references are enabled, the evaluator will mark the source register as containing a collected reference under the assumption that it's working with a compressed reference. However, if the l2a is being used for a j9class, j9method, etc., the register that holds it should not be marked as a collected reference. As an interim fix, this change will prevent commoning of l2a operations. The various OMR::::MemoryReference::populateMemoryReference code generation methods will skip evaluation of an l2a that has a reference count of one, so that prevents the register containing the operand of the l2a from being marked as a collected reference. In the longer term, OMR issue 6508 proposes introducing a new opcode - l2gcref - that would be used to mark explicitly the result of a conversion from long to an address as holding a collected reference. Once implemented, the change implemented by this commit can be reverted. --- compiler/optimizer/OMRLocalCSE.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/optimizer/OMRLocalCSE.cpp b/compiler/optimizer/OMRLocalCSE.cpp index 72619d317c..0ad59ece33 100644 --- a/compiler/optimizer/OMRLocalCSE.cpp +++ b/compiler/optimizer/OMRLocalCSE.cpp @@ -1186,6 +1186,9 @@ bool OMR::LocalCSE::canBeAvailable(TR::Node *parent, TR::Node *node, TR_BitVecto if (node->getOpCodeValue() == TR::allocationFence) return false; + if (node->getOpCodeValue() == TR::l2a) + return false; + if (node->getOpCode().isLoadReg() || node->getOpCode().isStoreReg() || (node->getOpCodeValue() == TR::PassThrough && parent->getOpCodeValue() != TR::GlRegDeps) || (node->getOpCodeValue() == TR::GlRegDeps)) return false;