Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panama MemoryAccessAPI: Add jit intrinsic support for vectorizedMismatch #15204

Closed
tajila opened this issue Jun 2, 2022 · 32 comments · Fixed by #16662
Closed

Panama MemoryAccessAPI: Add jit intrinsic support for vectorizedMismatch #15204

tajila opened this issue Jun 2, 2022 · 32 comments · Fixed by #16662
Labels
comp:jit project:panama Used to track Project Panama related work

Comments

@tajila
Copy link
Contributor

tajila commented Jun 2, 2022

The following is used for mismatch operations in MemoryAccessAPIs. The JDK supplies a java implementation which is very slow. We are seeing test failures due to timeouts as a result of this, #13211.

This API takes two arrays (of the same type) and compares each elements until there is a mismatch. This operation is can be applied to all primitive array types, the log2ArrayIndexScale denotes which type it is.

class jdk.internal.util.ArraySupport {
     @IntrinsicCandidate
     public static int vectorizedMismatch(Object a, long aOffset, Object b, long bOffset, int length, int log2ArrayIndexScale) 
}
@tajila tajila added comp:jit project:panama Used to track Project Panama related work labels Jun 2, 2022
@tajila tajila added this to the Release 0.34 (Java 19) milestone Jun 2, 2022
@tajila
Copy link
Contributor Author

tajila commented Jun 2, 2022

@gita-omr Please take a look at this

@zl-wang
Copy link
Contributor

zl-wang commented Jun 8, 2022

It is fairly similar to arrayCopy, except not moving memory content but comparing them. Did it require:

  1. ArrayBoundCheck(s) similar to arrayCopy?
  2. Return true (matching)/false (mismatching), or the exact index of the first mismatching element?

If only true/false return is required, we can short-circuit it by comparing their length(s), cannot we?

From JIT perspective, i think it can come through like arrayCopy.

@zl-wang
Copy link
Contributor

zl-wang commented Jun 8, 2022

hmm ... there is even existing arrayCmp implementations already. This API has almost identical semantic as arrayCmp, from looking at the source code @r30shah posted in the slack channel. This can be mapped to arrayCmp somehow before coming to codegen. Pretty good performance.

@r30shah
Copy link
Contributor

r30shah commented Jun 9, 2022

On Z, I can see that we do generate a version of arrayCmp which returns the index of first unequal element [1]. For that it seems to checking for a node flag [2] which looking at the code base is set from IdiomTransformation [3]. Only difference for this API and such arrayCmp is that the API requires us to return number of remaining pairs of elements needed to compare in the tails of two arrays.

[1]. https://github.com/eclipse/omr/blob/cf8ddbd1adcd87e388cad6be1fd0e0c085285a29/compiler/z/codegen/OMRTreeEvaluator.cpp#L11567-L11609
[2]. https://github.com/eclipse/omr/blob/cf8ddbd1adcd87e388cad6be1fd0e0c085285a29/compiler/il/OMRNode.cpp#L6451-L6456
[3].

arraycmplen->setArrayCmpLen(true);

@EricYangIBM
Copy link
Contributor

Perf comparisons for vectorizedMismatch (for the test in #13211):

With hotspot the SegmentMismatchAccessor takes at most ~700 ms whereas on openj9 can take a few seconds when passing and >20 seconds when failing (timeout).

Hotspot:

Started first thread: "Accessor #" + id ; elapsed (ms): 1
Starting handshaker with delay set to 351 millis
Accessor #7 suspending - elapsed (ms): 376
Accessor #0 suspending - elapsed (ms): 376
Accessor #2 suspending - elapsed (ms): 376
Accessor #6 suspending - elapsed (ms): 377
Accessor #4 suspending - elapsed (ms): 377
Accessor #3 suspending - elapsed (ms): 377
Accessor #1 suspending - elapsed (ms): 377
Accessor #5 suspending - elapsed (ms): 377
Segment closed - elapsed (ms): 378
Accessor #0 resuming - elapsed (ms): 405
Accessor #0 terminated - elapsed (ms): 405
Accessor #2 resuming - elapsed (ms): 418
Accessor #2 terminated - elapsed (ms): 418
Accessor #7 resuming - elapsed (ms): 426
Accessor #7 terminated - elapsed (ms): 427
Accessor #5 resuming - elapsed (ms): 447
Accessor #5 terminated - elapsed (ms): 447
Accessor #6 resuming - elapsed (ms): 508
Accessor #6 terminated - elapsed (ms): 508
Accessor #1 resuming - elapsed (ms): 514
Accessor #1 terminated - elapsed (ms): 514
Accessor #4 resuming - elapsed (ms): 554
Accessor #4 terminated - elapsed (ms): 554
Accessor #3 resuming - elapsed (ms): 568
Accessor #3 terminated - elapsed (ms): 569
test TestHandshake.testHandshake("SegmentMismatchAccessor", TestHandshake$$Lambda$87/0x0000000801030a28@5d244645): success

OpenJ9:

Started first thread: "Accessor #" + id ; elapsed (ms): 1
Starting handshaker with delay set to 91 millis
Accessor #1 suspending - elapsed (ms): 175
Accessor #1 resuming - elapsed (ms): 182
Accessor #1 suspending - elapsed (ms): 183
Accessor #0 suspending - elapsed (ms): 193
...
Accessor #4 resuming - elapsed (ms): 1955
Accessor #3 suspending - elapsed (ms): 1960
Segment closed - elapsed (ms): 1965
Accessor #4 suspending - elapsed (ms): 1962
Accessor #2 terminated - elapsed (ms): 1965
Accessor #5 resuming - elapsed (ms): 1978
Accessor #5 terminated - elapsed (ms): 1978
Accessor #0 resuming - elapsed (ms): 1992
Accessor #0 terminated - elapsed (ms): 1992
Accessor #7 resuming - elapsed (ms): 1998
Accessor #7 terminated - elapsed (ms): 1998
Accessor #6 resuming - elapsed (ms): 2007
Accessor #6 terminated - elapsed (ms): 2007
Accessor #3 resuming - elapsed (ms): 2009
Accessor #3 terminated - elapsed (ms): 2009
Accessor #1 resuming - elapsed (ms): 2045
Accessor #1 terminated - elapsed (ms): 2045
Accessor #4 resuming - elapsed (ms): 2092
Accessor #4 terminated - elapsed (ms): 2092
test TestHandshake.testHandshake("SegmentMismatchAccessor", TestHandshake$$Lambda$84/0x0000000098137f88@4ce9e86a): success

Here the closing thread had to wait much longer for the accessors, which indicates that the mismatch accessors are slower.

@tajila
Copy link
Contributor Author

tajila commented Oct 18, 2022

@gita-omr any update on this?

@gita-omr
Copy link
Contributor

gita-omr commented Oct 18, 2022

@gita-omr any update on this?

Sorry, was busy with another project. I think this is a multi-platform issue.

@r30shah @0xdaryl @knn-k @zl-wang , do you think you can help with z, intel, arm, and p respectively?

@zl-wang
Copy link
Contributor

zl-wang commented Oct 18, 2022

for p, i assigned the implementation to @bhavanisn

technically, if your platform supports vector byte comparison and counting equal-byte in the right endian (p10 does and pre-p10 need a longer instr sequence), you will have fairly efficient implementations. the complicated return value for no-mismatching case in implementation can be simplified as follows:

        ~((lengthInByte & ((log2ArrayIndexScale<2)?3:7)) >> log2ArrayIndexScale);

               seems correct for all cases as below:
                       log2ArrayIndexScale is 3:  lengthInByte must be divisible by 8, the no-mismatch result destines to be -1;
                       log2ArrayIndexScale is 2:  lengthInByte must be divisible by 4, the only results are possibly -1 or -2;
                       log2ArrayIndexScale is 1:  lengthInByte must be multiple of 2, the only results are also possibly -1 or -2;
                       log2ArrayIndexScale is 0: possible results are -1, -2, -3, and -4.

@r30shah
Copy link
Contributor

r30shah commented Oct 18, 2022

For Z implementation, generated code for arrayCmp [1] and code needed to accelerate arrayMismatch would be fairly same except the output value that arrayMismatch API returns , which I think can be handled easily. @zl-wang / @bhavanisn Are you planning to do something that Julian mentioned in #15204 (comment) ?

@tajila This one is tagged 0.34/Java19 which might not be the correct target, are we expecting this to be resolved in 0.36?

[1]. https://github.com/eclipse/omr/blob/cf8ddbd1adcd87e388cad6be1fd0e0c085285a29/compiler/z/codegen/OMRTreeEvaluator.cpp#L11567-L11609

@zl-wang
Copy link
Contributor

zl-wang commented Oct 18, 2022

@r30shah it is tantalizing to take advantages of the existing arrayCmp implementation for mis-match cases and adding new instructions to calculate the no-mismatch cases. there are two issues to be followed up though:

  1. transforming this call into arrayCmp node in IL (and tagging it as the 3rd scenario of arrayCmp);
  2. not sure how arrayCmp for compressed strings complicates the situation. maybe reduce the code readability to such an extent that it is not worth of it.

@knn-k
Copy link
Contributor

knn-k commented Oct 19, 2022

Is it about generating inlined code for vectorizedMismatch(), or calling a JIT helper function for the method?
AArch64 does not have the support for arrayCmp now.

@zl-wang
Copy link
Contributor

zl-wang commented Oct 19, 2022

@knn-k it is about better implementation/code for vectorizedMismatch() than JIT-compiled code. there is no dependency on existence of arrayCmp inlined ... that is just a coincidental finding of possible reuse/hint for this implementation.

@tajila
Copy link
Contributor Author

tajila commented Oct 19, 2022

@tajila This one is tagged 0.34/Java19 which might not be the correct target, are we expecting this to be resolved in 0.36?

Memery Access APIs is a preview for JDK19 so we need to be functionally complete. That being said this is technically a perf issue not a functional problem, but we had to disable tests to not hit the timeouts due to poor performance.

We can move it out, if its unfeasible to deliver this in the next month.

@zl-wang
Copy link
Contributor

zl-wang commented Oct 19, 2022

while we are at this, it might be worthwhile to take a closer look why the usual JIT-compiled code is too slow. there might be a common issue slowing it down. for example, the Unsafe accesses to long are not/could not be optimized ... going through a long way to cover all possible cases.

@Spencer-Comin
Copy link
Contributor

Spencer-Comin commented Jan 6, 2023

I've done some testing and determined that the following pseudocode is equivalent to vectorizedMismatch:

int vectorizedMismatch(byte *a, long aOffset, byte *b, long bOffset, int length, int log2ArrayIndexScale) {
    int lengthInBytes = length << log2ArrayIndexScale;
    int mask = (log2ArrayIndexScale<<1) | 3;
    int n = lengthInBytes & ~(mask);
    int res = arrayCmpLen(a+aOffset, b+bOffset, n);
    if (res == n) // no mismatch found
        return ~((lengthInBytes & mask) >> log2ArrayIndexScale);
    else          // mismatch found
        return res >> log2ArrayIndexScale;
}

Swapping out the body of vectorizedMismatch with the following IL (derived from the pseudocode) is giving me correct results:

n1n       BBStart <block_2>
n12n      istore  <temp slot 20>[#400  Auto] [flags 0x3 0x0 ]
n11n        ishl
n9n           iload  length<parm 6 I>[#398  Parm] [flags 0x40000103 0x0 ]
n10n          iload  log2ArrayIndexScale<parm 7 I>[#399  Parm] [flags 0x40000103 0x0 ]
n18n      istore  <temp slot 21>[#401  Auto] [flags 0x3 0x0 ]
n17n        ior
n15n          ishl
n13n            iload  log2ArrayIndexScale<parm 7 I>[#399  Parm] [flags 0x40000103 0x0 ]
n14n            iconst 1
n16n          iconst 3
n24n      istore  <temp slot 22>[#402  Auto] [flags 0x3 0x0 ]
n23n        iand
n19n          iload  <temp slot 20>[#400  Auto] [flags 0x3 0x0 ]
n22n          ixor
n20n            iload  <temp slot 21>[#401  Auto] [flags 0x3 0x0 ]
n21n            iconst -1
n34n      istore  <temp slot 23>[#403  Auto] [flags 0x3 0x0 ]
n33n        arraycmp  <arraycmp>[#246  helper Method] [flags 0x400 0x0 ] (arrayCmpLen )
n27n          aladd
n25n            aload  a<parm 0 Ljava/lang/Object;>[#394  Parm] [flags 0x40000107 0x0 ]
n26n            lload  aOffset<parm 1 J>[#395  Parm] [flags 0x40000104 0x0 ]
n30n          aladd
n28n            aload  b<parm 3 Ljava/lang/Object;>[#396  Parm] [flags 0x40000107 0x0 ]
n29n            lload  bOffset<parm 4 J>[#397  Parm] [flags 0x40000104 0x0 ]
n32n          i2l
n31n            iload  <temp slot 22>[#402  Auto] [flags 0x3 0x0 ]
n37n      ificmpne --> block_4 BBStart at n5n ()
n35n        iload  <temp slot 22>[#402  Auto] [flags 0x3 0x0 ]
n36n        iload  <temp slot 23>[#403  Auto] [flags 0x3 0x0 ]
n2n       BBEnd </block_2> =====

n3n       BBStart <block_3>
n45n      istore  <temp slot 24>[#404  Auto] [flags 0x3 0x0 ]
n44n        ixor
n42n          ishr
n40n            iand
n38n              iload  <temp slot 20>[#400  Auto] [flags 0x3 0x0 ]
n39n              iload  <temp slot 21>[#401  Auto] [flags 0x3 0x0 ]
n41n            iload  log2ArrayIndexScale<parm 7 I>[#399  Parm] [flags 0x40000103 0x0 ]
n43n          iconst -1
n46n      goto --> block_5 BBStart at n7n
n4n       BBEnd </block_3> =====

n5n       BBStart <block_4>
n50n      istore  <temp slot 24>[#404  Auto] [flags 0x3 0x0 ]
n49n        ishr
n47n          iload  <temp slot 23>[#403  Auto] [flags 0x3 0x0 ]
n48n          iload  log2ArrayIndexScale<parm 7 I>[#399  Parm] [flags 0x40000103 0x0 ]
n6n       BBEnd </block_4> =====

n7n       BBStart <block_5>
n52n      ireturn
n51n        iload  <temp slot 24>[#404  Auto] [flags 0x3 0x0 ]
n8n       BBEnd </block_5> =====

Caveat: I've only done functionality testing locally on Z with byte, char, short, int, long, float, and double arrays. I have not yet tested the null case (see [1] for explanation, [2] for example).

My dev branch is working at this commit: Spencer-Comin@dfea139 with this test: TestVectorizedArrayMismatch.java.txt

[1] https://github.com/ibmruntimes/openj9-openjdk-jdk19/blob/332135c6a1fedc19e2e607b273125eb242b5d213/src/java.base/share/classes/jdk/internal/util/ArraysSupport.java#L92-L102
[2] https://github.com/ibmruntimes/openj9-openjdk-jdk19/blob/332135c6a1fedc19e2e607b273125eb242b5d213/src/java.base/share/classes/sun/nio/ch/NativeSocketAddress.java#L153-L158

@r30shah
Copy link
Contributor

r30shah commented Jan 16, 2023

Thanks a lot @Spencer-Comin for detailed summary of the experiments. I like the idea of doing this in IL. Would like @zl-wang's opinion on this approach.
Julian, Out of two issues you speculated with doing this in IL (#15204 (comment)), Spencer's pseudocode could be a way to fix first one (Without tagging the arraycmp, inserting IL around the code would make it easier).

I am bit confused about second issue though about arraycmp working with compressed strings. Can you elaborate bit more on it?

FYI @dchopra001

@zl-wang
Copy link
Contributor

zl-wang commented Jan 16, 2023

@r30shah A good try indeed. It is also understood that the existing IL is not in complete form yet. Exactly you need to take care of the different situations. the IL transformation needs to test if a/b is null and take the object header size (or off-heap addressing) into account. I saw the calling offsets are compensating for this purpose in the tests.

compressed strings have two further implications: 1) need to take care of the difference between intended element-size and representational in-memory element-size; 2) little-endian and big-endian difference in result calculation (might not applicable to z/x supporting single mode only).

@bhavanisn FYI ...

@zl-wang
Copy link
Contributor

zl-wang commented Jan 16, 2023

it is also nice that, if a/b is not null, it can be assumed to be an array object. otherwise, it is much more complicated.

@dchopra001
Copy link
Contributor

Summarizing a couple of offline discussions regarding the following

compressed strings have two further implications: 1) need to take care of the difference between intended element-size and representational in-memory element-size;

We may have a scenario where two arrays are passed in that represent strings. One array is representing a compressed string and the other is not. In addition, the log2ArrayIndexScale argument may indicate we are comparing char characters. This could theoretically be a problem. The implementation in jit code to handle this could be tricky.

However the internals of how a string is represented is private to the String class. In addition it doesn't look like the java implementation of VectorizedMismatch handles this scenario either. I believe @Spencer-Comin is performing some experiments to better understand how the Java implementation handles these scenarios. If it's not able to handle these correctly then we should be okay with not worrying about it as well.

@Spencer-Comin
Copy link
Contributor

A rather convoluted test case to see what happens when I pass the internal String representation to vectorizedMismatch:

import java.lang.reflect.Field;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.ArraysSupport;

public class TestCompressedString {
    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
        String a = "This is a string that I am using for testing that should be long enough to give a good answer";
        String b = "This is a string that I am using for test\u0101ng that should be long enough to give a good answer";
        // The char at index 41 is different
        // \u0101 should force b to not use a compressed representation
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        int vv = ArraysSupport.vectorizedMismatch(
            ((byte[])value.get(a)), Unsafe.ARRAY_BYTE_BASE_OFFSET,
            ((byte[])value.get(b)), Unsafe.ARRAY_BYTE_BASE_OFFSET,
            ((byte[])value.get(a)).length,
            ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE
        );
        System.out.println(vv);
    }
}

Running it on Z/Linux with OpenJ9:

$ java -version
openjdk version "19.0.1-internal" 2022-10-18
OpenJDK Runtime Environment (build 19.0.1-internal-adhoc.spencer.test)
Eclipse OpenJ9 VM (build master-892071c6a, JRE 19 Linux s390x-64-Bit Compressed References 20230109_000000 (JIT enabled, AOT enabled)
OpenJ9   - 277af292f
OMR      - 9c865e119
JCL      - d78ba9640fe based on jdk-19.0.1+10)
$ # without compressed strings
$ java  -XX:-CompactStrings --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED TestCompressedString
82
$ # with compressed strings
$ java  -XX:+CompactStrings --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED TestCompressedString
0

On Z/Linux with OpenJDK:

$ java -version
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment Temurin-19.0.1+10 (build 19.0.1+10)
OpenJDK 64-Bit Server VM Temurin-19.0.1+10 (build 19.0.1+10, mixed mode, sharing)
$ # without compressed strings
$ java  -XX:-CompactStrings --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED TestCompressedString
82
$ # with compressed strings
$ java  -XX:+CompactStrings --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED TestCompressedString
0

On Intel MacOS with OpenJDK:

$ java -version
openjdk version "19.0.1" 2022-10-18
OpenJDK Runtime Environment Homebrew (build 19.0.1)
OpenJDK 64-Bit Server VM Homebrew (build 19.0.1, mixed mode, sharing)
$ # without compressed strings
$ java  -XX:-CompactStrings --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED TestCompressedString
82
$ # with compressed strings
$ java  -XX:+CompactStrings --add-exports java.base/jdk.internal.misc=ALL-UNNAMED --add-exports java.base/jdk.internal.util=ALL-UNNAMED --add-opens java.base/java.lang=ALL-UNNAMED TestCompressedString
1

@Spencer-Comin
Copy link
Contributor

Spencer-Comin commented Jan 18, 2023

Additionally, a quick test to see what happens when I pass in a String and treat it as a char[]

import jdk.internal.misc.Unsafe;
import jdk.internal.util.ArraysSupport;

public class TestCompressedString {
    public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
        String a = "This is a string that I am using for testing that should be long enough to give a good answer";
        String b = "This is a string that I am using for test\u0101ng that should be long enough to give a good answer";
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        int vv = ArraysSupport.vectorizedMismatch(
            a, Unsafe.ARRAY_CHAR_BASE_OFFSET,
            b, Unsafe.ARRAY_CHAR_BASE_OFFSET,
            a.length(),
            ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE
        );
        System.out.println(vv);
    }
}
JVM With compressed strings Without compressed strings
Z/Linux OpenJ9 7 11
Z/Linux OpenJDK 0 3
Intel macOS OpenJDK 0 2

@knn-k
Copy link
Contributor

knn-k commented Mar 7, 2023

eclipse/omr#6904 implemented arraycmp on AArch64.

@tajila tajila modified the milestones: Java 20.0.1 0.39?, Java 20.0.2 Apr 11, 2023
@r30shah
Copy link
Contributor

r30shah commented Jun 15, 2023

Most of the development work for this is done and there are two PRs [1][2] which should go in couple of weeks. Given the code-split for 0.40 is already happened, I do not think we would be get the PRs in. @tajila should we move this to next milestone?

[1]. eclipse/omr#6983
[2]. #16662

@Spencer-Comin
Copy link
Contributor

... there are two PRs [1][2] which should go in couple of weeks.

There's actually also a third PR (#17382, changing OpenJ9 to use arraycmplen) that needs to go through between those two

Spencer-Comin added a commit to Spencer-Comin/openj9 that referenced this issue Jun 19, 2023
This patch adds ArraysSupport.vectorizedMismatch as a recognized method, and
adds a SupportsInlineVectorizedMismatch flag to the code generator. This flag
is set in Z, Power, aarch64 and x86 code generator initialization if the
arraycmp opcode is supported and the TR_disableInlineVectorizedMismatch
environment variable is not set. If the flag is set, vectorizedMismatch call
nodes are transformed to a functionally equivalent tree that uses arraycmp.

Fixes: eclipse-openj9#15204
Signed-off-by: Spencer Comin <spencer.comin@ibm.com>
@hzongaro
Copy link
Member

As the pull requests are still in progress, I'll move this out to the 0.43 release

Spencer-Comin added a commit to Spencer-Comin/openj9 that referenced this issue Aug 29, 2023
This patch adds ArraysSupport.vectorizedMismatch as a recognized method, and
adds a SupportsInlineVectorizedMismatch flag to the code generator. This flag
is set in Z, Power, aarch64 and x86 code generator initialization if the
arraycmp opcode is supported and the TR_disableInlineVectorizedMismatch
environment variable is not set. If the flag is set, vectorizedMismatch call
nodes are transformed to a functionally equivalent tree that uses arraycmp.

Fixes: eclipse-openj9#15204
Signed-off-by: Spencer Comin <spencer.comin@ibm.com>
Spencer-Comin added a commit to Spencer-Comin/openj9 that referenced this issue Oct 25, 2023
This patch adds ArraysSupport.vectorizedMismatch as a recognized method, and
adds a SupportsInlineVectorizedMismatch flag to the code generator. This flag
is set in Z, Power, aarch64 and x86 code generator initialization if the
arraycmp opcode is supported and the TR_disableInlineVectorizedMismatch
environment variable is not set. If the flag is set, vectorizedMismatch call
nodes are transformed to a functionally equivalent tree that uses arraycmp.

Fixes: eclipse-openj9#15204
Signed-off-by: Spencer Comin <spencer.comin@ibm.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comp:jit project:panama Used to track Project Panama related work
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants