}
// For additions, one of the operands is a byref or a ref (and the other is not). Follow this down to its
// source.
- while (tgtAddr->OperGet() == GT_ADD || tgtAddr->OperGet() == GT_LEA)
+ while (tgtAddr->OperIs(GT_ADD, GT_LEA))
{
if (tgtAddr->OperGet() == GT_ADD)
{
- if (tgtAddr->AsOp()->gtOp1->TypeGet() == TYP_BYREF || tgtAddr->AsOp()->gtOp1->TypeGet() == TYP_REF)
+ GenTree* addOp1 = tgtAddr->AsOp()->gtGetOp1();
+ GenTree* addOp2 = tgtAddr->AsOp()->gtGetOp2();
+ var_types addOp1Type = addOp1->TypeGet();
+ var_types addOp2Type = addOp2->TypeGet();
+ if (addOp1Type == TYP_BYREF || addOp1Type == TYP_REF)
{
- assert(!(tgtAddr->AsOp()->gtOp2->TypeGet() == TYP_BYREF ||
- tgtAddr->AsOp()->gtOp2->TypeGet() == TYP_REF));
- tgtAddr = tgtAddr->AsOp()->gtOp1;
+ assert(addOp2Type != TYP_BYREF && addOp2Type != TYP_REF);
+ tgtAddr = addOp1;
simplifiedExpr = true;
}
- else if (tgtAddr->AsOp()->gtOp2->TypeGet() == TYP_BYREF || tgtAddr->AsOp()->gtOp2->TypeGet() == TYP_REF)
+ else if (addOp2Type == TYP_BYREF || addOp2Type == TYP_REF)
{
- tgtAddr = tgtAddr->AsOp()->gtOp2;
+ tgtAddr = addOp2;
simplifiedExpr = true;
}
else
}
else
{
- assert(op2);
- assert(op2->gtOper == GT_LSH || op2->gtOper == GT_MUL);
+ assert(op2 != nullptr);
+ assert(op2->OperIs(GT_LSH, GT_MUL));
op2->gtFlags |= GTF_ADDRMODE_NO_CSE;
// We may have eliminated multiple shifts and multiplies in the addressing mode,
// so navigate down through them to get to "idx".
{
if ((op1->gtOper == GT_MUL) || (op1->gtOper == GT_LSH))
{
- if ((op1->AsOp()->gtOp1->gtOper == GT_NOP) ||
- (op1->AsOp()->gtOp1->gtOper == GT_MUL &&
- op1->AsOp()->gtOp1->AsOp()->gtOp1->gtOper == GT_NOP))
+ GenTree* op1op1 = op1->AsOp()->gtOp1;
+ if ((op1op1->gtOper == GT_NOP) ||
+ (op1op1->gtOper == GT_MUL && op1op1->AsOp()->gtOp1->gtOper == GT_NOP))
{
op1->gtFlags |= GTF_ADDRMODE_NO_CSE;
- if (op1->AsOp()->gtOp1->gtOper == GT_MUL)
+ if (op1op1->gtOper == GT_MUL)
{
- op1->AsOp()->gtOp1->gtFlags |= GTF_ADDRMODE_NO_CSE;
+ op1op1->gtFlags |= GTF_ADDRMODE_NO_CSE;
}
}
}
{
if (idx != nullptr)
{
- assert(op2);
- if ((op2->gtOper == GT_MUL) || (op2->gtOper == GT_LSH))
+ assert(op2 != nullptr);
+ if (op2->OperIs(GT_MUL, GT_LSH))
{
- if ((op2->AsOp()->gtOp1->gtOper == GT_NOP) ||
- (op2->AsOp()->gtOp1->gtOper == GT_MUL &&
- op2->AsOp()->gtOp1->AsOp()->gtOp1->gtOper == GT_NOP))
+ GenTree* op2op1 = op2->AsOp()->gtOp1;
+ if ((op2op1->gtOper == GT_NOP) ||
+ (op2op1->gtOper == GT_MUL && op2op1->AsOp()->gtOp1->gtOper == GT_NOP))
{
op2->gtFlags |= GTF_ADDRMODE_NO_CSE;
- if (op2->AsOp()->gtOp1->gtOper == GT_MUL)
+ if (op2op1->gtOper == GT_MUL)
{
- op2->AsOp()->gtOp1->gtFlags |= GTF_ADDRMODE_NO_CSE;
+ op2op1->gtFlags |= GTF_ADDRMODE_NO_CSE;
}
}
}
assert(!AsOp()->gtOp2->gtIntCon.ImmedValNeedsReloc(comp));
// TODO-CrossBitness: we wouldn't need the cast below if GenTreeIntCon::gtIconVal had target_ssize_t
// type.
- target_ssize_t subMul = target_ssize_t{1}
- << (target_ssize_t)AsOp()->gtOp2->AsIntConCommon()->IconValue();
+ target_ssize_t shiftVal = AsOp()->gtOp2->AsIntConCommon()->IconValue();
+ target_ssize_t subMul = target_ssize_t{1} << shiftVal;
AsOp()->gtOp1->ParseArrayAddressWork(comp, inputMul * subMul, pArr, pInxVN, pOffset, pFldSeq);
return;
}
// Check for assignment to same array, ie. arrLcl[i] = arrLcl[j]
// This does not need CORINFO_HELP_ARRADDR_ST
- if (arrayNodeFrom->OperGet() == GT_INDEX && arrayNodeFrom->AsOp()->gtOp1->gtOper == GT_LCL_VAR &&
- arrayNodeTo->gtOper == GT_LCL_VAR &&
- arrayNodeTo->gtLclVarCommon.GetLclNum() ==
- arrayNodeFrom->AsOp()->gtOp1->gtLclVarCommon.GetLclNum() &&
- !lvaTable[arrayNodeTo->gtLclVarCommon.GetLclNum()].lvAddrExposed)
+ if (arrayNodeFrom->OperGet() == GT_INDEX && arrayNodeTo->gtOper == GT_LCL_VAR)
{
- JITDUMP("\nstelem of ref from same array: skipping covariant store check\n");
- lclTyp = TYP_REF;
- goto ARR_ST_POST_VERIFY;
+ GenTree* indexFromOp1 = arrayNodeFrom->AsIndex()->Arr();
+ if (indexFromOp1->OperGet() == GT_LCL_VAR)
+ {
+ unsigned indexFrom = indexFromOp1->AsLclVar()->GetLclNum();
+ unsigned indexTo = arrayNodeTo->AsLclVar()->GetLclNum();
+ if (indexFrom == indexTo && !lvaGetDesc(indexTo)->lvAddrExposed)
+ {
+ JITDUMP("\nstelem of ref from same array: skipping covariant store check\n");
+ lclTyp = TYP_REF;
+ goto ARR_ST_POST_VERIFY;
+ }
+ }
}
// Check for assignment of NULL. This does not need CORINFO_HELP_ARRADDR_ST