Skip to content

Commit

Permalink
Mark SIMD assignments as related to SIMD intrinsics (#51731)
Browse files Browse the repository at this point in the history
* Ensure that GenTreeJitIntrinsic explicitly zeroes out certain nodes

* Mark SIMD assignments as related to SIMD intrinsics

* Refactor SetOpLclRelatedToSIMDIntrinsic so it is easier to debug/understand

* Applying formatting patch

* Mark SIMD assignments as related to SIMD intrinsics on x86
  • Loading branch information
tannergooding authored Apr 27, 2021
1 parent ab84a8c commit 9a31832
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1980,7 +1980,7 @@ void CodeGen::genMultiRegStoreToSIMDLocal(GenTreeLclVar* lclNode)
}
genProduceReg(lclNode);
#else // !UNIX_AMD64_ABI
assert(!"Multireg store to SIMD reg not supported on X64 Windows");
assert(!"Multireg store to SIMD reg not supported on Windows");
#endif // !UNIX_AMD64_ABI
}
#endif // FEATURE_SIMD
Expand Down
41 changes: 33 additions & 8 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6759,6 +6759,20 @@ GenTreeOp* Compiler::gtNewAssignNode(GenTree* dst, GenTree* src)
}
dst->gtFlags |= GTF_DONT_CSE;

#if defined(FEATURE_SIMD) && !defined(TARGET_X86)
// TODO-CQ: x86 Windows supports multi-reg returns but not SIMD multi-reg returns

if (varTypeIsSIMD(dst->gtType))
{
// We want to track SIMD assignments as being intrinsics since they
// are functionally SIMD `mov` instructions and are more efficient
// when we don't promote, particularly when it occurs due to inlining

SetOpLclRelatedToSIMDIntrinsic(dst);
SetOpLclRelatedToSIMDIntrinsic(src);
}
#endif // FEATURE_SIMD

/* Create the assignment node */

GenTreeOp* asg = gtNewOperNode(GT_ASG, dst->TypeGet(), dst, src)->AsOp();
Expand Down Expand Up @@ -18937,16 +18951,27 @@ GenTreeSIMD* Compiler::gtNewSIMDNode(var_types type,
//
void Compiler::SetOpLclRelatedToSIMDIntrinsic(GenTree* op)
{
if (op != nullptr)
if (op == nullptr)
{
if (op->OperIsLocal())
{
setLclRelatedToSIMDIntrinsic(op);
}
else if ((op->OperGet() == GT_OBJ) && (op->AsOp()->gtOp1->OperGet() == GT_ADDR) &&
op->AsOp()->gtOp1->AsOp()->gtOp1->OperIsLocal())
return;
}

if (op->OperIsLocal())
{
setLclRelatedToSIMDIntrinsic(op);
}
else if (op->OperIs(GT_OBJ))
{
GenTree* addr = op->AsIndir()->Addr();

if (addr->OperIs(GT_ADDR))
{
setLclRelatedToSIMDIntrinsic(op->AsOp()->gtOp1->AsOp()->gtOp1);
GenTree* addrOp1 = addr->AsOp()->gtGetOp1();

if (addrOp1->OperIsLocal())
{
setLclRelatedToSIMDIntrinsic(addrOp1);
}
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4847,7 +4847,7 @@ struct GenTreeIntrinsic : public GenTreeOp
struct GenTreeJitIntrinsic : public GenTreeOp
{
private:
ClassLayout* m_layout;
ClassLayout* gtLayout;

unsigned char gtAuxiliaryJitType; // For intrinsics than need another type (e.g. Avx2.Gather* or SIMD (by element))
regNumberSmall gtOtherReg; // For intrinsics that return 2 registers
Expand All @@ -4867,13 +4867,13 @@ struct GenTreeJitIntrinsic : public GenTreeOp

ClassLayout* GetLayout() const
{
return m_layout;
return gtLayout;
}

void SetLayout(ClassLayout* layout)
{
assert(layout != nullptr);
m_layout = layout;
gtLayout = layout;
}

regNumber GetOtherReg() const
Expand Down Expand Up @@ -4927,6 +4927,9 @@ struct GenTreeJitIntrinsic : public GenTreeOp
GenTreeJitIntrinsic(
genTreeOps oper, var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize)
: GenTreeOp(oper, type, op1, op2)
, gtLayout(nullptr)
, gtAuxiliaryJitType(CORINFO_TYPE_UNDEF)
, gtOtherReg(REG_NA)
, gtSimdBaseJitType((unsigned char)simdBaseJitType)
, gtSimdSize((unsigned char)simdSize)
, gtHWIntrinsicId(NI_Illegal)
Expand Down

0 comments on commit 9a31832

Please sign in to comment.