@@ -8453,24 +8453,38 @@ bool Compiler::optIdentifyLoopOptInfo(unsigned loopNum, LoopCloneContext* contex
84538453//
84548454// TODO-CQ: CLONE: After morph make sure this method extracts values before morph.
84558455//
8456- // STMT void(IL 0x007...0x00C)
8457- // [000023] -A-XG+------ * ASG int
8458- // [000022] D----+-N---- +--* LCL_VAR int V06 tmp1
8459- // [000048] ---XG+------ \--* COMMA int
8460- // [000041] ---X-+------ +--* ARR_BOUNDS_CHECK_Rng void
8461- // [000020] -----+------ | +--* LCL_VAR int V04 loc0
8462- // [000040] ---X-+------ | \--* ARR_LENGTH int
8463- // [000019] -----+------ | \--* LCL_VAR ref V00 arg0
8464- // [000021] a--XG+------ \--* IND int
8465- // [000047] -----+------ \--* ADD byref
8466- // [000038] -----+------ +--* LCL_VAR ref V00 arg0
8467- // [000046] -----+------ \--* ADD long
8468- // [000044] -----+------ +--* LSH long
8469- // [000042] -----+------ | +--* CAST long < -int
8470- // [000039] i----+------ | | \--* LCL_VAR int V04 loc0
8471- // [000043] -----+-N---- | \--* CNS_INT long 2
8472- // [000045] -----+------ \--* CNS_INT long 16 Fseq[#FirstElem]
8473-
8456+ // Example tree to pattern match:
8457+ //
8458+ // * COMMA int
8459+ // +--* ARR_BOUNDS_CHECK_Rng void
8460+ // | +--* LCL_VAR int V02 loc1
8461+ // | \--* ARR_LENGTH int
8462+ // | \--* LCL_VAR ref V00 arg0
8463+ // \--* IND int
8464+ // \--* ADD byref
8465+ // +--* LCL_VAR ref V00 arg0
8466+ // \--* ADD long
8467+ // +--* LSH long
8468+ // | +--* CAST long <- int
8469+ // | | \--* LCL_VAR int V02 loc1
8470+ // | \--* CNS_INT long 2
8471+ // \--* CNS_INT long 16 Fseq[#FirstElem]
8472+ //
8473+ // Note that byte arrays don't require the LSH to scale the index, so look like this:
8474+ //
8475+ // * COMMA ubyte
8476+ // +--* ARR_BOUNDS_CHECK_Rng void
8477+ // | +--* LCL_VAR int V03 loc2
8478+ // | \--* ARR_LENGTH int
8479+ // | \--* LCL_VAR ref V00 arg0
8480+ // \--* IND ubyte
8481+ // \--* ADD byref
8482+ // +--* LCL_VAR ref V00 arg0
8483+ // \--* ADD long
8484+ // +--* CAST long <- int
8485+ // | \--* LCL_VAR int V03 loc2
8486+ // \--* CNS_INT long 16 Fseq[#FirstElem]
8487+ //
84748488bool Compiler::optExtractArrIndex (GenTree* tree, ArrIndex* result,unsigned lhsNum)
84758489{
84768490if (tree->gtOper != GT_COMMA)
@@ -8544,15 +8558,20 @@ bool Compiler::optExtractArrIndex(GenTree* tree, ArrIndex* result, unsigned lhsN
85448558 {
85458559return false ;
85468560 }
8547- if (si->gtOper != GT_LSH)
8561+ GenTree* index;
8562+ if (si->gtOper == GT_LSH)
85488563 {
8549- return false ;
8564+ GenTree* scale = si->gtGetOp2 ();
8565+ index = si->gtGetOp1 ();
8566+ if (scale->gtOper != GT_CNS_INT)
8567+ {
8568+ return false ;
8569+ }
85508570 }
8551- GenTree* scale = si->gtGetOp2 ();
8552- GenTree* index = si->gtGetOp1 ();
8553- if (scale->gtOper != GT_CNS_INT)
8571+ else
85548572 {
8555- return false ;
8573+ // No scale (e.g., byte array).
8574+ index = si;
85568575 }
85578576#ifdef TARGET_64BIT
85588577if (index->gtOper != GT_CAST)