diff --git a/src/coreclr/jit/gentree.h b/src/coreclr/jit/gentree.h index 52e18a84d8513..c127149782171 100644 --- a/src/coreclr/jit/gentree.h +++ b/src/coreclr/jit/gentree.h @@ -1774,6 +1774,7 @@ struct GenTree inline bool IsFloatPositiveZero() const; inline bool IsFloatNegativeZero() const; inline bool IsVectorZero() const; + inline bool IsVectorCreate() const; inline bool IsVectorAllBitsSet() const; inline bool IsVectorConst(); @@ -8396,6 +8397,52 @@ inline bool GenTree::IsVectorZero() const return IsCnsVec() && AsVecCon()->IsZero(); } +//------------------------------------------------------------------- +// IsVectorCreate: returns true if this node is the creation of a vector. +// Does not include "Unsafe" method calls. +// +// Returns: +// True if this node is the creation of a vector +// +inline bool GenTree::IsVectorCreate() const +{ +#ifdef FEATURE_HW_INTRINSICS + if (OperIs(GT_HWINTRINSIC)) + { + switch (AsHWIntrinsic()->GetHWIntrinsicId()) + { + case NI_Vector128_Create: +#if defined(TARGET_XARCH) + case NI_Vector256_Create: +#elif defined(TARGET_ARMARCH) + case NI_Vector64_Create: +#endif + return true; + + default: + return false; + } + } +#endif // FEATURE_HW_INTRINSICS + +#ifdef FEATURE_SIMD + if (OperIs(GT_SIMD)) + { + switch (AsSIMD()->GetSIMDIntrinsicId()) + { + case SIMDIntrinsicInit: + case SIMDIntrinsicInitN: + return true; + + default: + return false; + } + } +#endif // FEATURE_SIMD + + return false; +} + //------------------------------------------------------------------- // IsVectorAllBitsSet: returns true if this node is a vector constant with all bits set. // diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index c71e2c80424e9..513730836b733 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -13925,41 +13925,35 @@ GenTree* Compiler::fgMorphMultiOp(GenTreeMultiOp* multiOp) } #endif - case NI_Vector128_Create: -#if defined(TARGET_XARCH) - case NI_Vector256_Create: -#elif defined(TARGET_ARMARCH) - case NI_Vector64_Create: -#endif - { - bool hwAllArgsAreConst = true; - for (GenTree** use : multiOp->UseEdges()) - { - if (!(*use)->OperIsConst()) - { - hwAllArgsAreConst = false; - break; - } - } - - // Avoid unexpected CSE for constant arguments for Vector_.Create - // but only if all arguments are constants. - if (hwAllArgsAreConst) - { - for (GenTree** use : multiOp->UseEdges()) - { - (*use)->SetDoNotCSE(); - } - } - } - break; - default: break; } } #endif // defined(FEATURE_HW_INTRINSICS) && defined(TARGET_XARCH) + if (opts.OptimizationEnabled() && multiOp->IsVectorCreate()) + { + bool allArgsAreConst = true; + for (GenTree* arg : multiOp->Operands()) + { + if (!arg->OperIsConst()) + { + allArgsAreConst = false; + break; + } + } + + // Avoid unexpected CSE for constant arguments for Vector_.Create + // but only if all arguments are constants. + if (allArgsAreConst) + { + for (GenTree* arg : multiOp->Operands()) + { + arg->SetDoNotCSE(); + } + } + } + #ifdef FEATURE_HW_INTRINSICS if (multiOp->OperIsHWIntrinsic() && !optValnumCSE_phase) {