From 796d63392a47ece82d31210bc916beb2bfef67db Mon Sep 17 00:00:00 2001 From: jimmyk Date: Wed, 15 May 2024 11:20:34 -0400 Subject: [PATCH] Removes incorrect check in fast path indexOf code For the recognized method JITHelpers.intrinsicIndexOfLatin1, the ch parameter is meant to be interpreted as an unsigned byte with a value of 0x00-0xFF. However, it gets passes into the method as a signed byte. This means for values 0x80-0xFF the data is sign extended inside of the register. The fast path code generated by inlineIntrinsicIndexOf_P10 has a check the checks if the bits other than the lowest 8 bits are 0 and returns -1 early if this is the case. But, this check is wrong. It is possible to have a valid parameter where there upper bits are not 0 due to the sign extension. This fix removes the check and instead zeros out the bits other than the lowest 8 bits. This is safe to do since it is known in advance that the byte data is meant to be interpreted as an unsigned byte and it is not possible to pass in an invalid value to this parameter. Also, this is needed since the byte parameter is eventually compared against a loaded byte that was zero extended. Signed-off-by: jimmyk --- runtime/compiler/p/codegen/J9TreeEvaluator.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/runtime/compiler/p/codegen/J9TreeEvaluator.cpp b/runtime/compiler/p/codegen/J9TreeEvaluator.cpp index c1f48ea0bae..24040e3d351 100644 --- a/runtime/compiler/p/codegen/J9TreeEvaluator.cpp +++ b/runtime/compiler/p/codegen/J9TreeEvaluator.cpp @@ -10862,12 +10862,13 @@ static TR::Register *inlineIntrinsicIndexOf_P10(TR::Node *node, TR::CodeGenerato generateTrg1Src1Instruction(cg, TR::InstOpCode::extsw, node, position, offset); generateTrg1Src1Instruction(cg, TR::InstOpCode::extsw, node, endPos, length); - // sanity check : if str isLatin1, then ch should be isLatin1 too. + /* + * Zero out upper bits. ch is later compared against values loaded by lbzx. + * Comparison expect bits other than the lowest 8 bits are zero. + */ if (isLatin1) { - generateTrg1Src1Imm2Instruction(cg, TR::InstOpCode::rlwinm, node, temp, ch, 24, 0xFF); - generateTrg1Src1ImmInstruction(cg, TR::InstOpCode::cmpi4, node, cr6, temp, 0); - generateConditionalBranchInstruction(cg, TR::InstOpCode::bne, node, endLabel, cr6); + generateTrg1Src1Imm2Instruction(cg, TR::InstOpCode::rlwinm, node, ch, ch, 0, 0xFF); }