From a93168832c7699373d574f7ac3bc3bd69b143bfc Mon Sep 17 00:00:00 2001 From: Rahil Shah Date: Wed, 28 Feb 2024 15:32:07 -0500 Subject: [PATCH] (0.44) Evaluate constant byteLenNode of arrayCopyChild In case of constant length array copy code, a length of bytes to be copied would be loaded into register in case we need to perform a test to check for destructive region copies and perform destructive array copy. We need to make sure that byteLength node is evaluated before the internal control flow starts. We found an issue where downstream consumer of primitive arraycopy sequnece generator needed byteLenReg and as the constant value was loaded only in case we fail absolute test for forward copy check, we ended up in scenario where it reads a value from array using length which consists of garbage. This commit fixes the issue and in case, we do not know the direction for array copy, it evaluates bytelength node before internal control flow starts. Signed-off-by: Rahil Shah --- compiler/z/codegen/OMRTreeEvaluator.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/compiler/z/codegen/OMRTreeEvaluator.cpp b/compiler/z/codegen/OMRTreeEvaluator.cpp index a27e680c18..1e10511fe6 100644 --- a/compiler/z/codegen/OMRTreeEvaluator.cpp +++ b/compiler/z/codegen/OMRTreeEvaluator.cpp @@ -13497,6 +13497,7 @@ OMR::Z::TreeEvaluator::primitiveArraycopyEvaluator(TR::Node* node, TR::CodeGener // We need to decide direction of array copy at runtime. if (isConstantByteLen) { + byteLenReg = cg->gprClobberEvaluate(byteLenNode); generateS390LabelInstruction(cg, TR::InstOpCode::label, node, cFlowRegionStart); cFlowRegionStart->setStartInternalControlFlow(); } @@ -13506,12 +13507,6 @@ OMR::Z::TreeEvaluator::primitiveArraycopyEvaluator(TR::Node* node, TR::CodeGener TR::Register *checkBoundReg = srm->findOrCreateScratchRegister(); - if (byteLenReg == NULL) - { - TR_ASSERT_FATAL(isConstantByteLen, "byteLenNode can be not evaluated only when we have constant length"); - byteLenReg = cg->allocateRegister(); - genLoadLongConstant(cg, node, byteLenNode->getConst(), byteLenReg); - } cursor = generateRXInstruction(cg, TR::InstOpCode::LA, node, checkBoundReg, generateS390MemoryReference(byteSrcReg, byteLenReg, 0, cg)); iComment("nextPointerToLastElement=byteSrcPointer+lengthInBytes");