From 13952f7817a6e76b3538d42a45b02a84f9ecdb4c Mon Sep 17 00:00:00 2001 From: EgorBo Date: Sun, 3 May 2020 00:51:13 +0300 Subject: [PATCH] Don't convert GT/LE to EQ/NE for Array.Length op1 --- src/coreclr/src/jit/morph.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 69b3eaf80b0df1..8e546cef94cef8 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -12899,13 +12899,15 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac) } else if (tree->IsUnsigned() && op2->IsIntegralConst(0)) { - if ((oper == GT_GT) || (oper == GT_LE)) + if (!op1->OperIs(GT_ARR_LENGTH) && ((oper == GT_GT) || (oper == GT_LE))) { // IL doesn't have a cne instruction so compilers use cgt.un instead. The JIT // recognizes certain patterns that involve GT_NE (e.g (x & 4) != 0) and fails // if GT_GT is used instead. Transform (x GT_GT.unsigned 0) into (x GT_NE 0) // and (x GT_LE.unsigned 0) into (x GT_EQ 0). The later case is rare, it sometimes // occurs as a result of branch inversion. + // NOTE: keep it as it is for Array.Length op1 since GT_NE/GT_EQ operators are + // not bounds check elimination friendly yet. oper = (oper == GT_LE) ? GT_EQ : GT_NE; tree->SetOper(oper, GenTree::PRESERVE_VN); tree->gtFlags &= ~GTF_UNSIGNED;