diff --git a/src/coreclr/jit/assertionprop.cpp b/src/coreclr/jit/assertionprop.cpp index 53307c1465c400..c84ccb96d76c7d 100644 --- a/src/coreclr/jit/assertionprop.cpp +++ b/src/coreclr/jit/assertionprop.cpp @@ -3007,7 +3007,7 @@ GenTree* Compiler::optVNBasedFoldConstExpr(BasicBlock* block, GenTree* parent, G } break; -#if FEATURE_SIMD +#if defined(FEATURE_SIMD) case TYP_SIMD8: { simd8_t value = vnStore->ConstantValue(vnCns); @@ -3066,6 +3066,7 @@ GenTree* Compiler::optVNBasedFoldConstExpr(BasicBlock* block, GenTree* parent, G break; #endif // TARGET_XARCH +#endif // FEATURE_SIMD #if defined(FEATURE_MASKED_HW_INTRINSICS) case TYP_MASK: @@ -3080,7 +3081,6 @@ GenTree* Compiler::optVNBasedFoldConstExpr(BasicBlock* block, GenTree* parent, G } break; #endif // FEATURE_MASKED_HW_INTRINSICS -#endif // FEATURE_SIMD case TYP_BYREF: // Do not support const byref optimization. diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 3b7f17752de67a..ab8d95125ff5c8 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -2405,6 +2405,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } break; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { GenTreeVecCon* vecCon = tree->AsVecCon(); @@ -2414,7 +2415,6 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre switch (tree->TypeGet()) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: case TYP_SIMD12: case TYP_SIMD16: @@ -2470,7 +2470,6 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } break; } -#endif // FEATURE_SIMD default: { @@ -2480,6 +2479,7 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre break; } +#endif // FEATURE_SIMD default: unreached(); diff --git a/src/coreclr/jit/codegenarmarch.cpp b/src/coreclr/jit/codegenarmarch.cpp index 8340663ad9b901..07b08c3692a4e5 100644 --- a/src/coreclr/jit/codegenarmarch.cpp +++ b/src/coreclr/jit/codegenarmarch.cpp @@ -186,8 +186,12 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) case GT_CNS_INT: case GT_CNS_DBL: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS genSetRegToConst(targetReg, targetType, treeNode); genProduceReg(treeNode); break; diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 0f1824f70b826d..aec95740e8b555 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -8320,7 +8320,14 @@ void CodeGen::genCodeForReuseVal(GenTree* treeNode) assert(treeNode->IsReuseRegVal()); // For now, this is only used for constant nodes. +#if defined(FEATURE_MASKED_HW_INTRINSICS) assert(treeNode->OperIs(GT_CNS_INT, GT_CNS_DBL, GT_CNS_VEC, GT_CNS_MSK)); +#elif defined(FEATURE_SIMD) + assert(treeNode->OperIs(GT_CNS_INT, GT_CNS_DBL, GT_CNS_VEC)); +#else + assert(treeNode->OperIs(GT_CNS_INT, GT_CNS_DBL)); +#endif + JITDUMP(" TreeNode is marked ReuseReg\n"); if (treeNode->IsIntegralConst(0) && GetEmitter()->emitCurIGnonEmpty()) diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 707bdea163d9b7..6c23977f83a096 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -724,27 +724,23 @@ void CodeGen::genSetRegToConst(regNumber targetReg, var_types targetType, GenTre } break; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { -#if defined(FEATURE_SIMD) GenTreeVecCon* vecCon = tree->AsVecCon(); genSetRegToConst(vecCon->GetRegNum(), targetType, &vecCon->gtSimdVal); -#else - unreached(); -#endif break; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { -#if defined(FEATURE_MASKED_HW_INTRINSICS) GenTreeMskCon* mskCon = tree->AsMskCon(); genSetRegToConst(mskCon->GetRegNum(), targetType, &mskCon->gtSimdMaskVal); -#else - unreached(); -#endif break; } +#endif // FEATURE_MASKED_HW_INTRINSICS default: unreached(); @@ -1906,8 +1902,12 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) FALLTHROUGH; case GT_CNS_DBL: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS genSetRegToConst(targetReg, targetType, treeNode); genProduceReg(treeNode); break; diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 56410dfd3035a9..f29849b39da4d0 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -3057,11 +3057,14 @@ class Compiler GenTree* gtNewSconNode(int CPX, CORINFO_MODULE_HANDLE scpHandle); +#if defined(FEATURE_SIMD) GenTreeVecCon* gtNewVconNode(var_types type); - GenTreeVecCon* gtNewVconNode(var_types type, void* data); +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) GenTreeMskCon* gtNewMskConNode(var_types type); +#endif // FEATURE_MASKED_HW_INTRINSICS GenTree* gtNewAllBitsSetConNode(var_types type); @@ -11800,8 +11803,12 @@ class GenTreeVisitor case GT_CNS_LNG: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_MEMORYBARRIER: case GT_JMP: case GT_JCC: diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp index 6e5e2c444be1e6..832fa9e9ac9277 100644 --- a/src/coreclr/jit/compiler.hpp +++ b/src/coreclr/jit/compiler.hpp @@ -4365,8 +4365,12 @@ void GenTree::VisitOperands(TVisitor visitor) case GT_CNS_LNG: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_MEMORYBARRIER: case GT_JMP: case GT_JCC: diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 62cbaedf55aaa0..df5cf261018847 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -240,9 +240,9 @@ void GenTree::InitNodeSize() // clang-format off GenTree::s_gtNodeSizes[GT_CALL] = TREE_NODE_SZ_LARGE; -#ifdef TARGET_XARCH +#if defined(FEATURE_SIMD) && defined(TARGET_XARCH) GenTree::s_gtNodeSizes[GT_CNS_VEC] = TREE_NODE_SZ_LARGE; -#endif // TARGET_XARCH +#endif // FEATURE_SIMD && TARGET_XARCH GenTree::s_gtNodeSizes[GT_CAST] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_FTN_ADDR] = TREE_NODE_SZ_LARGE; GenTree::s_gtNodeSizes[GT_BOX] = TREE_NODE_SZ_LARGE; @@ -285,11 +285,13 @@ void GenTree::InitNodeSize() static_assert_no_msg(sizeof(GenTreeLngCon) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeDblCon) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeStrCon) <= TREE_NODE_SZ_SMALL); +#if defined(FEATURE_SIMD) #ifdef TARGET_XARCH static_assert_no_msg(sizeof(GenTreeVecCon) <= TREE_NODE_SZ_LARGE); // *** large node #else static_assert_no_msg(sizeof(GenTreeVecCon) <= TREE_NODE_SZ_SMALL); -#endif +#endif // TARGET_XARCH +#endif // FEATURE_SIMD static_assert_no_msg(sizeof(GenTreeLclVarCommon) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeLclVar) <= TREE_NODE_SZ_SMALL); static_assert_no_msg(sizeof(GenTreeLclFld) <= TREE_NODE_SZ_SMALL); @@ -2726,6 +2728,7 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) } break; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { if (GenTreeVecCon::Equals(op1->AsVecCon(), op2->AsVecCon())) @@ -2734,7 +2737,9 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) } break; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { if (GenTreeMskCon::Equals(op1->AsMskCon(), op2->AsMskCon())) @@ -2743,6 +2748,7 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK) } break; } +#endif // FEATURE_MASKED_HW_INTRINSICS default: break; @@ -3269,6 +3275,7 @@ unsigned Compiler::gtHashValue(GenTree* tree) add = tree->AsStrCon()->gtSconCPX; break; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { GenTreeVecCon* vecCon = tree->AsVecCon(); @@ -3276,7 +3283,6 @@ unsigned Compiler::gtHashValue(GenTree* tree) switch (vecCon->TypeGet()) { -#if defined(FEATURE_SIMD) #if defined(TARGET_XARCH) case TYP_SIMD64: { @@ -3319,7 +3325,6 @@ unsigned Compiler::gtHashValue(GenTree* tree) add = genTreeHashAdd(ulo32(add), vecCon->gtSimdVal.u32[0]); break; } -#endif // FEATURE_SIMD default: { @@ -3328,20 +3333,19 @@ unsigned Compiler::gtHashValue(GenTree* tree) } break; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { GenTreeMskCon* mskCon = tree->AsMskCon(); add = 0; -#if defined(FEATURE_MASKED_HW_INTRINSICS) add = genTreeHashAdd(ulo32(add), mskCon->gtSimdMaskVal.u32[1]); add = genTreeHashAdd(ulo32(add), mskCon->gtSimdMaskVal.u32[0]); -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS break; } +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_JMP: add = tree->AsVal()->gtVal1; @@ -5266,6 +5270,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) } break; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { level = 0; @@ -5289,7 +5294,9 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) } break; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { level = 0; @@ -5306,6 +5313,7 @@ unsigned Compiler::gtSetEvalOrder(GenTree* tree) } break; } +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_LCL_VAR: level = 1; @@ -6649,8 +6657,12 @@ bool GenTree::TryGetUse(GenTree* operand, GenTree*** pUse) case GT_CNS_LNG: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_MEMORYBARRIER: case GT_JMP: case GT_JCC: @@ -7881,6 +7893,7 @@ GenTree* Compiler::gtNewSconNode(int CPX, CORINFO_MODULE_HANDLE scpHandle) return node; } +#if defined(FEATURE_SIMD) GenTreeVecCon* Compiler::gtNewVconNode(var_types type) { GenTreeVecCon* vecCon = new (this, GT_CNS_VEC) GenTreeVecCon(type); @@ -7893,12 +7906,15 @@ GenTreeVecCon* Compiler::gtNewVconNode(var_types type, void* data) memcpy(&vecCon->gtSimdVal, data, genTypeSize(type)); return vecCon; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) GenTreeMskCon* Compiler::gtNewMskConNode(var_types type) { GenTreeMskCon* mskCon = new (this, GT_CNS_MSK) GenTreeMskCon(type); return mskCon; } +#endif // FEATURE_MASKED_HW_INTRINSICS GenTree* Compiler::gtNewAllBitsSetConNode(var_types type) { @@ -8216,6 +8232,7 @@ GenTree* Compiler::gtNewConWithPattern(var_types type, uint8_t pattern) case TYP_BYREF: assert(pattern == 0); return gtNewZeroConNode(type); + #ifdef FEATURE_SIMD case TYP_SIMD8: case TYP_SIMD12: @@ -8224,12 +8241,13 @@ GenTree* Compiler::gtNewConWithPattern(var_types type, uint8_t pattern) case TYP_SIMD32: case TYP_SIMD64: #endif // TARGET_XARCH -#endif // FEATURE_SIMD { GenTreeVecCon* node = gtNewVconNode(type); memset(&node->gtSimdVal, pattern, sizeof(node->gtSimdVal)); return node; } +#endif // FEATURE_SIMD + default: unreached(); } @@ -8402,10 +8420,10 @@ GenTreeLclVar* Compiler::gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL LclVarDsc* varDsc = lvaGetDesc(lnum); bool simd12ToSimd16Widening = false; -#if FEATURE_SIMD +#if defined(FEATURE_SIMD) // We can additionally have a SIMD12 that was widened to a SIMD16, generally as part of lowering simd12ToSimd16Widening = (type == TYP_SIMD16) && (varDsc->lvType == TYP_SIMD12); -#endif +#endif // FEATURE_SIMD assert((type == varDsc->lvType) || simd12ToSimd16Widening || (lvaIsImplicitByRefLocal(lnum) && fgGlobalMorph && (varDsc->lvType == TYP_BYREF))); } @@ -8569,11 +8587,20 @@ void Compiler::gtInitializeStoreNode(GenTree* store, GenTree* value) SetOpLclRelatedToSIMDIntrinsic(value); } } -#else // TARGET_X86 +#else // TARGET_X86 // TODO-Cleanup: merge into the all-arch. - if (varTypeIsSIMD(value) && value->OperIs(GT_HWINTRINSIC, GT_CNS_VEC, GT_CNS_MSK)) + if (varTypeIsSIMD(value) || varTypeIsMask(value)) { - SetOpLclRelatedToSIMDIntrinsic(store); + bool isRelatedToSimdIntrinsic = value->OperIs(GT_HWINTRINSIC, GT_CNS_VEC); + +#if defined(FEATURE_MASKED_HW_INTRINSICS) + isRelatedToSimdIntrinsic |= value->OperIs(GT_CNS_MSK); +#endif // FEATURE_MASKED_HW_INTRINSICS + + if (isRelatedToSimdIntrinsic) + { + SetOpLclRelatedToSIMDIntrinsic(store); + } } #endif // TARGET_X86 #endif // FEATURE_SIMD @@ -9207,6 +9234,7 @@ GenTree* Compiler::gtClone(GenTree* tree, bool complexOK) break; } +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { GenTreeVecCon* vecCon = gtNewVconNode(tree->TypeGet()); @@ -9214,18 +9242,17 @@ GenTree* Compiler::gtClone(GenTree* tree, bool complexOK) copy = vecCon; break; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { -#if defined(FEATURE_MASKED_HW_INTRINSICS) GenTreeMskCon* mskCon = gtNewMskConNode(tree->TypeGet()); mskCon->gtSimdMaskVal = tree->AsMskCon()->gtSimdMaskVal; copy = mskCon; -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS break; } +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_FTN_ADDR: { @@ -9398,6 +9425,7 @@ GenTree* Compiler::gtCloneExpr(GenTree* tree) copy = gtNewSconNode(tree->AsStrCon()->gtSconCPX, tree->AsStrCon()->gtScpHnd); goto DONE; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { GenTreeVecCon* vecCon = gtNewVconNode(tree->TypeGet()); @@ -9405,18 +9433,17 @@ GenTree* Compiler::gtCloneExpr(GenTree* tree) copy = vecCon; goto DONE; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { -#if defined(FEATURE_MASKED_HW_INTRINSICS) GenTreeMskCon* mskCon = gtNewMskConNode(tree->TypeGet()); mskCon->gtSimdMaskVal = tree->AsMskCon()->gtSimdMaskVal; copy = mskCon; goto DONE; -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS } +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_LCL_VAR: @@ -10204,8 +10231,12 @@ GenTreeUseEdgeIterator::GenTreeUseEdgeIterator(GenTree* node) case GT_CNS_LNG: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_MEMORYBARRIER: case GT_JMP: case GT_JCC: @@ -12268,6 +12299,7 @@ void Compiler::gtDispConst(GenTree* tree) break; } +#endif // FEATURE_SIMD #if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: @@ -12277,7 +12309,6 @@ void Compiler::gtDispConst(GenTree* tree) break; } #endif // FEATURE_MASKED_HW_INTRINSICS -#endif // FEATURE_SIMD default: assert(!"unexpected constant node"); @@ -30798,6 +30829,7 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) } resultNode = cnsNode; } +#if defined(FEATURE_MASKED_HW_INTRINSICS) else if (tree->OperIsConvertMaskToVector()) { GenTreeMskCon* mskCon = cnsNode->AsMskCon(); @@ -30854,6 +30886,7 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) resultNode = mskCon; } +#endif // FEATURE_MASKED_HW_INTRINSICS else { switch (ni) diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 6b46eafcf84221..f72fa678135d22 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -898,8 +898,34 @@ struct GenTree bool isUsedFromMemory() const { - return ((isContained() && (isMemoryOp() || OperIs(GT_LCL_VAR, GT_CNS_DBL, GT_CNS_VEC, GT_CNS_MSK))) || - isUsedFromSpillTemp()); + if (isContained()) + { + if (isMemoryOp()) + { + return true; + } + + if (OperIs(GT_LCL_VAR, GT_CNS_DBL)) + { + return true; + } + +#if defined(FEATURE_SIMD) + if (OperIs(GT_CNS_VEC)) + { + return true; + } +#endif // FEATURE_SIMD + +#if defined(FEATURE_MASKED_HW_INTRINSICS) + if (OperIs(GT_CNS_MSK)) + { + return true; + } +#endif // FEATURE_MASKED_HW_INTRINSICS + } + + return isUsedFromSpillTemp(); } bool isUsedFromReg() const @@ -1092,8 +1118,16 @@ struct GenTree static bool OperIsConst(genTreeOps gtOper) { +#if defined(FEATURE_MASKED_HW_INTRINSICS) static_assert_no_msg(AreContiguous(GT_CNS_INT, GT_CNS_LNG, GT_CNS_DBL, GT_CNS_STR, GT_CNS_VEC, GT_CNS_MSK)); return (GT_CNS_INT <= gtOper) && (gtOper <= GT_CNS_MSK); +#elif defined(FEATURE_SIMD) + static_assert_no_msg(AreContiguous(GT_CNS_INT, GT_CNS_LNG, GT_CNS_DBL, GT_CNS_STR, GT_CNS_VEC)); + return (GT_CNS_INT <= gtOper) && (gtOper <= GT_CNS_VEC); +#else + static_assert_no_msg(AreContiguous(GT_CNS_INT, GT_CNS_LNG, GT_CNS_DBL, GT_CNS_STR)); + return (GT_CNS_INT <= gtOper) && (gtOper <= GT_CNS_STR); +#endif } bool OperIsConst() const @@ -6696,6 +6730,7 @@ struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic }; #endif // FEATURE_HW_INTRINSICS +#if defined(FEATURE_SIMD) // GenTreeVecCon -- vector constant (GT_CNS_VEC) // struct GenTreeVecCon : public GenTree @@ -6938,7 +6973,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { simd8_t result = {}; @@ -6980,7 +7014,6 @@ struct GenTreeVecCon : public GenTree break; } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -6996,7 +7029,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { simd8_t result = {}; @@ -7038,7 +7070,6 @@ struct GenTreeVecCon : public GenTree break; } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7051,7 +7082,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { simd8_t result = {}; @@ -7093,7 +7123,6 @@ struct GenTreeVecCon : public GenTree break; } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7106,7 +7135,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { return gtSimd8Val.IsAllBitsSet(); @@ -7134,7 +7162,6 @@ struct GenTreeVecCon : public GenTree } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7156,7 +7183,6 @@ struct GenTreeVecCon : public GenTree switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { return left->gtSimd8Val == right->gtSimd8Val; @@ -7184,7 +7210,6 @@ struct GenTreeVecCon : public GenTree } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7201,7 +7226,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { return gtSimd8Val.IsZero(); @@ -7229,7 +7253,6 @@ struct GenTreeVecCon : public GenTree } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7242,7 +7265,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { return EvaluateGetElementFloating(simdBaseType, gtSimd8Val, index); @@ -7269,7 +7291,6 @@ struct GenTreeVecCon : public GenTree return EvaluateGetElementFloating(simdBaseType, gtSimd64Val, index); } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7282,7 +7303,6 @@ struct GenTreeVecCon : public GenTree { switch (gtType) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { return EvaluateGetElementIntegral(simdBaseType, gtSimd8Val, index); @@ -7309,7 +7329,6 @@ struct GenTreeVecCon : public GenTree return EvaluateGetElementIntegral(simdBaseType, gtSimd64Val, index); } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -7400,13 +7419,12 @@ struct GenTreeVecCon : public GenTree #endif }; +#if defined(FEATURE_MASKED_HW_INTRINSICS) // GenTreeMskCon -- mask constant (GT_CNS_MSK) // struct GenTreeMskCon : public GenTree { -#if defined(FEATURE_MASKED_HW_INTRINSICS) simdmask_t gtSimdMaskVal; -#endif // FEATURE_MASKED_HW_INTRINSICS void EvaluateUnaryInPlace(genTreeOps oper, bool scalar, var_types baseType, unsigned simdSize); void EvaluateBinaryInPlace( @@ -7414,29 +7432,17 @@ struct GenTreeMskCon : public GenTree bool IsAllBitsSet() const { -#if defined(FEATURE_MASKED_HW_INTRINSICS) return gtSimdMaskVal.IsAllBitsSet(); -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS } static bool Equals(const GenTreeMskCon* left, const GenTreeMskCon* right) { -#if defined(FEATURE_MASKED_HW_INTRINSICS) return left->gtSimdMaskVal == right->gtSimdMaskVal; -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS } bool IsZero() const { -#if defined(FEATURE_MASKED_HW_INTRINSICS) return gtSimdMaskVal.IsZero(); -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS } GenTreeMskCon(var_types type) @@ -7444,13 +7450,9 @@ struct GenTreeMskCon : public GenTree { assert(varTypeIsMask(type)); -#if defined(FEATURE_MASKED_HW_INTRINSICS) // Some uses of GenTreeMskCon do not specify all bits in the mask they are using but failing to zero out the // buffer will cause determinism issues with the compiler. memset(>SimdMaskVal, 0, sizeof(gtSimdMaskVal)); -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS } #if DEBUGGABLE_GENTREE @@ -7460,6 +7462,8 @@ struct GenTreeMskCon : public GenTree } #endif }; +#endif // FEATURE_MASKED_HW_INTRINSICS +#endif // FEATURE_SIMD // GenTreeIndexAddr: Given an array object and an index, checks that the index is within the bounds of the array if // necessary and produces the address of the value at that index of the array. @@ -9652,7 +9656,11 @@ inline bool GenTree::IsFloatPositiveZero() const // inline bool GenTree::IsVectorZero() const { +#if defined(FEATURE_SIMD) return IsCnsVec() && AsVecCon()->IsZero(); +#else + return false; +#endif // FEATURE_SIMD } //------------------------------------------------------------------- @@ -9666,8 +9674,12 @@ inline bool GenTree::IsVectorZero() const // inline bool GenTree::IsVectorNegativeZero(var_types simdBaseType) const { +#if defined(FEATURE_SIMD) assert(varTypeIsFloating(simdBaseType)); return IsCnsVec() && AsVecCon()->IsNegativeZero(simdBaseType); +#else + return false; +#endif // FEATURE_SIMD } //------------------------------------------------------------------- @@ -9681,8 +9693,12 @@ inline bool GenTree::IsVectorNegativeZero(var_types simdBaseType) const // inline bool GenTree::IsVectorNaN(var_types simdBaseType) const { +#if defined(FEATURE_SIMD) assert(varTypeIsFloating(simdBaseType)); return IsCnsVec() && AsVecCon()->IsNaN(simdBaseType); +#else + return false; +#endif // FEATURE_SIMD } //------------------------------------------------------------------- @@ -10561,12 +10577,20 @@ inline bool GenTree::IsCnsNonZeroFltOrDbl() const inline bool GenTree::IsCnsVec() const { +#if defined(FEATURE_SIMD) return OperIs(GT_CNS_VEC); +#else + return false; +#endif // FEATURE_SIMD } inline bool GenTree::IsCnsMsk() const { +#if defined(FEATURE_MASKED_HW_INTRINSICS) return OperIs(GT_CNS_MSK); +#else + return false; +#endif // FEATURE_MASKED_HW_INTRINSICS } inline bool GenTree::IsHelperCall() @@ -10635,8 +10659,12 @@ const size_t TREE_NODE_SZ_SMALL = sizeof(GenTreeLclFld); // the largest by a small margin due to needing to carry a simd64_t // constant value. Otherwise, GenTreeCall is the largest. +#if defined(FEATURE_SIMD) const size_t TREE_NODE_SZ_LARGE = (sizeof(GenTreeVecCon) < sizeof(GenTreeCall)) ? sizeof(GenTreeCall) : sizeof(GenTreeVecCon); +#else +const size_t TREE_NODE_SZ_LARGE = sizeof(GenTreeCall); +#endif // FEATURE_SIMD enum varRefKinds { diff --git a/src/coreclr/jit/gtlist.h b/src/coreclr/jit/gtlist.h index e1e1f909896276..8c6c67fd6a3273 100644 --- a/src/coreclr/jit/gtlist.h +++ b/src/coreclr/jit/gtlist.h @@ -46,8 +46,12 @@ GTNODE(CNS_INT , GenTreeIntCon ,0,0,GTK_LEAF) GTNODE(CNS_LNG , GenTreeLngCon ,0,0,GTK_LEAF) GTNODE(CNS_DBL , GenTreeDblCon ,0,0,GTK_LEAF) GTNODE(CNS_STR , GenTreeStrCon ,0,0,GTK_LEAF) +#if defined(FEATURE_SIMD) GTNODE(CNS_VEC , GenTreeVecCon ,0,0,GTK_LEAF) +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) GTNODE(CNS_MSK , GenTreeMskCon ,0,0,GTK_LEAF) +#endif // FEATURE_MASKED_HW_INTRINSICS //----------------------------------------------------------------------------- // Unary operators (1 operand): diff --git a/src/coreclr/jit/gtstructs.h b/src/coreclr/jit/gtstructs.h index 7dbf6af39c5d01..26f88d17909974 100644 --- a/src/coreclr/jit/gtstructs.h +++ b/src/coreclr/jit/gtstructs.h @@ -60,8 +60,12 @@ GTSTRUCT_1(IntCon , GT_CNS_INT) GTSTRUCT_1(LngCon , GT_CNS_LNG) GTSTRUCT_1(DblCon , GT_CNS_DBL) GTSTRUCT_1(StrCon , GT_CNS_STR) +#if defined(FEATURE_SIMD) GTSTRUCT_1(VecCon , GT_CNS_VEC) +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) GTSTRUCT_1(MskCon , GT_CNS_MSK) +#endif // FEATURE_MASKED_HW_INTRINSICS GTSTRUCT_N(LclVarCommon, GT_LCL_VAR, GT_LCL_FLD, GT_PHI_ARG, GT_STORE_LCL_VAR, GT_STORE_LCL_FLD, GT_LCL_ADDR) GTSTRUCT_2(LclVar , GT_LCL_VAR, GT_STORE_LCL_VAR) GTSTRUCT_3(LclFld , GT_LCL_FLD, GT_STORE_LCL_FLD, GT_LCL_ADDR) @@ -76,7 +80,7 @@ GTSTRUCT_1(Intrinsic , GT_INTRINSIC) GTSTRUCT_1(IndexAddr , GT_INDEX_ADDR) #if defined(FEATURE_HW_INTRINSICS) GTSTRUCT_N(MultiOp , GT_HWINTRINSIC) -#endif +#endif // FEATURE_HW_INTRINSICS GTSTRUCT_1(BoundsChk , GT_BOUNDS_CHECK) GTSTRUCT_3_SPECIAL(ArrCommon , GT_ARR_LENGTH, GT_MDARR_LENGTH, GT_MDARR_LOWER_BOUND) GTSTRUCT_1(ArrLen , GT_ARR_LENGTH) diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index e96029011985a2..67bffe9636bb72 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -222,8 +222,12 @@ void Compiler::impSaveStackState(SavedStack* savePtr, bool copy) case GT_CNS_LNG: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_LCL_VAR: table->val = gtCloneExpr(tree); break; @@ -3881,7 +3885,7 @@ GenTree* Compiler::impImportStaticReadOnlyField(CORINFO_FIELD_HANDLE field, CORI hwAccelerated = compOpportunisticallyDependsOn(InstructionSet_AVX); } else -#endif +#endif // TARGET_XARCH { // SIMD8, SIMD12, SIMD16 are covered by IsBaselineSimdIsaSupported check assert((simdType == TYP_SIMD8) || (simdType == TYP_SIMD12) || (simdType == TYP_SIMD16)); @@ -3894,7 +3898,7 @@ GenTree* Compiler::impImportStaticReadOnlyField(CORINFO_FIELD_HANDLE field, CORI return vec; } } -#endif +#endif // FEATURE_SIMD for (unsigned i = 0; i < totalSize; i++) { diff --git a/src/coreclr/jit/instr.cpp b/src/coreclr/jit/instr.cpp index bc0300c83a846e..73749d6aa54413 100644 --- a/src/coreclr/jit/instr.cpp +++ b/src/coreclr/jit/instr.cpp @@ -956,11 +956,11 @@ CodeGen::OperandDesc CodeGen::genOperandDesc(GenTree* op) return OperandDesc(op->AsIntCon()->IconValue(), op->AsIntCon()->ImmedValNeedsReloc(compiler)); } +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { switch (op->TypeGet()) { -#if defined(FEATURE_SIMD) case TYP_SIMD8: { simd8_t constValue; @@ -997,7 +997,6 @@ CodeGen::OperandDesc CodeGen::genOperandDesc(GenTree* op) } #endif // TARGET_XARCH -#endif // FEATURE_SIMD default: { @@ -1005,17 +1004,16 @@ CodeGen::OperandDesc CodeGen::genOperandDesc(GenTree* op) } } } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { -#if defined(FEATURE_MASKED_HW_INTRINSICS) simdmask_t constValue; memcpy(&constValue, &op->AsMskCon()->gtSimdMaskVal, sizeof(simdmask_t)); return OperandDesc(emit->emitSimdMaskConst(constValue)); -#else - unreached(); -#endif // FEATURE_MASKED_HW_INTRINSICS } +#endif // FEATURE_MASKED_HW_INTRINSICS default: unreached(); diff --git a/src/coreclr/jit/liveness.cpp b/src/coreclr/jit/liveness.cpp index e07afacc31dc44..b66da476b05c72 100644 --- a/src/coreclr/jit/liveness.cpp +++ b/src/coreclr/jit/liveness.cpp @@ -1421,8 +1421,12 @@ void Compiler::fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALAR case GT_CNS_LNG: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_PHYSREG: // These are all side-effect-free leaf nodes. if (node->IsUnusedValue()) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index bd2571f8649099..438c6ebc7e9432 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -2759,6 +2759,7 @@ bool LinearScan::isMatchingConstant(RegRecord* physRegRecord, RefPosition* refPo break; } +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { return @@ -2767,11 +2768,14 @@ bool LinearScan::isMatchingConstant(RegRecord* physRegRecord, RefPosition* refPo #endif GenTreeVecCon::Equals(refPosition->treeNode->AsVecCon(), otherTreeNode->AsVecCon()); } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { return GenTreeMskCon::Equals(refPosition->treeNode->AsMskCon(), otherTreeNode->AsMskCon()); } +#endif // FEATURE_MASKED_HW_INTRINSICS) default: break; diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index ab86d18d706def..6825f190db01ab 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -719,6 +719,7 @@ int LinearScan::BuildNode(GenTree* tree) } break; +#if defined(FEATURE_SIMD) case GT_CNS_VEC: { GenTreeVecCon* vecCon = tree->AsVecCon(); @@ -741,7 +742,9 @@ int LinearScan::BuildNode(GenTree* tree) def->getInterval()->isConstant = true; break; } +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: { GenTreeMskCon* mskCon = tree->AsMskCon(); @@ -764,6 +767,7 @@ int LinearScan::BuildNode(GenTree* tree) def->getInterval()->isConstant = true; break; } +#endif // FEATURE_MASKED_HW_INTRINSICS case GT_BOX: case GT_COMMA: diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index cf3f3efacd9fac..1197b17ef15f8b 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -151,8 +151,12 @@ int LinearScan::BuildNode(GenTree* tree) case GT_CNS_INT: case GT_CNS_LNG: case GT_CNS_DBL: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS { srcCount = 0; diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index c7fb0fe6f4fb7c..25ed8dfdbce3ad 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -1913,8 +1913,12 @@ bool CSE_HeuristicCommon::CanConsiderTree(GenTree* tree, bool isReturn) case GT_CNS_INT: case GT_CNS_DBL: case GT_CNS_STR: +#if defined(FEATURE_SIMD) case GT_CNS_VEC: +#endif // FEATURE_SIMD +#if defined(FEATURE_MASKED_HW_INTRINSICS) case GT_CNS_MSK: +#endif // FEATURE_MASKED_HW_INTRINSICS break; case GT_ARR_ELEM: