Skip to content

Commit 85b3f7c

Browse files
authored
Merge pull request #19444 from hzongaro/indexOf-latin1-encoded-0.44
(0.44) Use signed comparisons for Latin-1 encoded indexOf in VP
2 parents 8d018d6 + 98d2c0a commit 85b3f7c

File tree

1 file changed

+79
-2
lines changed

1 file changed

+79
-2
lines changed

runtime/compiler/optimizer/J9ValuePropagation.cpp

Lines changed: 79 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,15 @@ bool J9::ValuePropagation::transformIndexOfKnownString(
376376
}
377377
else if (targetIsConstChar)
378378
{
379+
if (!is16Bit)
380+
{
381+
// The implementations of the 8-bit indexOf operations cast the character for
382+
// which they are searching to a signed byte value, and the characters in the
383+
// String themselves are stored in a signed byte array. Make sure that folding
384+
// at compile-time takes into account that operations are on signed bytes.
385+
targetChar = (int32_t)(int8_t) targetChar;
386+
}
387+
379388
for (int32_t i = start; i < length; ++i)
380389
{
381390
int32_t ch;
@@ -397,6 +406,15 @@ bool J9::ValuePropagation::transformIndexOfKnownString(
397406
// getStringCharacter should handle both 8 bit and 16 bit strings
398407
ch = TR::Compiler->cls.getStringCharacter(comp(), string, i);
399408
}
409+
if (!is16Bit)
410+
{
411+
// The implementations of the 8-bit indexOf operations cast the character for
412+
// which they are searching to a signed byte value, and the characters in the
413+
// String themselves are stored in a signed byte array. Make sure that folding
414+
// at compile-time takes into account that operations are on signed bytes.
415+
ch = (int32_t)(int8_t) ch;
416+
}
417+
400418
if (ch == targetChar)
401419
{
402420
if (performTransformation(comp(), "%sReplacing indexOf call node [" POINTER_PRINTF_FORMAT "] on known string receiver with constant value of %d\n", OPT_DETAILS, indexOfNode, i))
@@ -433,8 +451,37 @@ bool J9::ValuePropagation::transformIndexOfKnownString(
433451
// getStringCharacter should handle both 8 bit and 16 bit strings
434452
ch = TR::Compiler->cls.getStringCharacter(comp(), string, start);
435453
}
454+
455+
if (!is16Bit)
456+
{
457+
// The implementations of the 8-bit indexOf operations cast the character for
458+
// which they are searching to a signed byte value, and the characters in the
459+
// String themselves are stored in a signed byte array. Make sure that the
460+
// inlined version similarly operates on signed bytes.
461+
ch = (int32_t)(int8_t) ch;
462+
}
463+
436464
if (!performTransformation(comp(), "%sReplacing indexOf call node [" POINTER_PRINTF_FORMAT "] on known string receiver with equivalent icmpeq tree\n", OPT_DETAILS, indexOfNode))
437465
return false;
466+
467+
// The implementations of the 8-bit indexOf operations cast the character for
468+
// which they are searching to a signed byte value. In some cases that happens
469+
// at the call to the known method that's being processed here, and in some
470+
// cases that happens within the known method itself. If targetCharNode is not
471+
// known to be the result of a b2i operation and is not already known to be in
472+
// the required range for a signed byte value, force that. Otherwise, this
473+
// could end up looking for the degree symbol, U+00B0, say, as an unsigned
474+
// value 176 rather than the signed value -80.
475+
if (!is16Bit
476+
&& (targetCharNode->getOpCodeValue() != TR::b2i)
477+
&& ((targetConstraint == NULL)
478+
|| (targetConstraint->getLowInt() < -128)
479+
|| (targetConstraint->getHighInt() > 127)))
480+
{
481+
targetCharNode = TR::Node::create(indexOfNode, TR::b2i, 1,
482+
TR::Node::create(indexOfNode, TR::i2b, 1, targetCharNode));
483+
}
484+
438485
transformCallToNodeDelayedTransformations(
439486
_curTree,
440487
TR::Node::create(indexOfNode, TR::isub, 2,
@@ -448,7 +495,29 @@ bool J9::ValuePropagation::transformIndexOfKnownString(
448495
}
449496
else if (length < 4)
450497
{
498+
if (!performTransformation(comp(), "%sReplacing indexOf call node [" POINTER_PRINTF_FORMAT "] on known string receiver with equivalent iselect tree\n", OPT_DETAILS, indexOfNode))
499+
return false;
500+
451501
TR::Node *root = TR::Node::iconst(indexOfNode, -1);
502+
503+
// The implementations of the 8-bit indexOf operations cast the character for
504+
// which they are searching to a signed byte value. In some cases that happens
505+
// at the call to the known method that's being processed here, and in some
506+
// cases that happens within the known method itself. If targetCharNode is not
507+
// known to be the result of a b2i operation and is not already known to be in
508+
// the required range for a signed byte value, force that. Otherwise, this
509+
// could end up looking for the degree symbol, U+00B0, say, as an unsigned
510+
// value 176 rather than the signed value -80.
511+
if (!is16Bit
512+
&& (targetCharNode->getOpCodeValue() != TR::b2i)
513+
&& ((targetConstraint == NULL)
514+
|| (targetConstraint->getLowInt() < -128)
515+
|| (targetConstraint->getHighInt() > 127)))
516+
{
517+
targetCharNode = TR::Node::create(indexOfNode, TR::b2i, 1,
518+
TR::Node::create(indexOfNode, TR::i2b, 1, targetCharNode));
519+
}
520+
452521
for (int32_t i = length - 1; i >= start; --i)
453522
{
454523
int32_t ch;
@@ -470,8 +539,16 @@ bool J9::ValuePropagation::transformIndexOfKnownString(
470539
// getStringCharacter should handle both 8 bit and 16 bit strings
471540
ch = TR::Compiler->cls.getStringCharacter(comp(), string, i);
472541
}
473-
if (!performTransformation(comp(), "%sReplacing indexOf call node [" POINTER_PRINTF_FORMAT "] on known string receiver with equivalent iselect tree\n", OPT_DETAILS, indexOfNode))
474-
return false;
542+
543+
if (!is16Bit)
544+
{
545+
// The implementations of the 8-bit indexOf operations cast the character for
546+
// which they are searching to a signed byte value, and the characters in the
547+
// String themselves are stored in a signed byte array. Make sure that the
548+
// inlined version similarly operates on signed bytes.
549+
ch = (int32_t)(int8_t) ch;
550+
}
551+
475552
root = TR::Node::create(TR::iselect, 3,
476553
TR::Node::create(indexOfNode, TR::icmpeq, 2,
477554
targetCharNode,

0 commit comments

Comments
 (0)