From 6be5805471837a4609cf8cf63042509220c44d02 Mon Sep 17 00:00:00 2001 From: Swapnil Gaikwad Date: Wed, 28 Aug 2024 15:18:33 +0100 Subject: [PATCH 1/3] Avoid combining conditional select for reduction instrinsics Fixes #106868, #106871, #106872 --- src/coreclr/jit/hwintrinsic.h | 9 ++ src/coreclr/jit/hwintrinsiclistarm64sve.h | 18 +-- src/coreclr/jit/lowerarmarch.cpp | 5 +- .../GenerateHWIntrinsicTests_Arm.cs | 63 ++++++++- .../_SveMinimalUnaryOpTestTemplate.template | 129 ++++++++++++++++++ .../JitBlue/Runtime_106868/Runtime_106868.cs | 54 ++++++++ .../Runtime_106868/Runtime_106868.csproj | 9 ++ .../JitBlue/Runtime_106871/Runtime_106871.cs | 38 ++++++ .../Runtime_106871/Runtime_106871.csproj | 9 ++ .../JitBlue/Runtime_106872/Runtime_106872.cs | 43 ++++++ .../Runtime_106872/Runtime_106872.csproj | 9 ++ 11 files changed, 374 insertions(+), 12 deletions(-) create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs create mode 100644 src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj diff --git a/src/coreclr/jit/hwintrinsic.h b/src/coreclr/jit/hwintrinsic.h index cbc88369cb03a6..139f2fbddeabd3 100644 --- a/src/coreclr/jit/hwintrinsic.h +++ b/src/coreclr/jit/hwintrinsic.h @@ -229,6 +229,9 @@ enum HWIntrinsicFlag : unsigned int // (HW_Flag_BaseTypeFrom{First, Second}Arg must also be set to denote the position of the ValueTuple) HW_Flag_BaseTypeFromValueTupleArg = 0x1000000, + // The intrinsic is a reduce operation. + HW_Flag_ReduceOperation = 0x2000000, + #else #error Unsupported platform #endif @@ -998,6 +1001,12 @@ struct HWIntrinsicInfo return (flags & HW_Flag_BaseTypeFromValueTupleArg) != 0; } + static bool IsReduceOperation(NamedIntrinsic id) + { + const HWIntrinsicFlag flags = lookupFlags(id); + return (flags & HW_Flag_ReduceOperation) != 0; + } + static NamedIntrinsic GetScalarInputVariant(NamedIntrinsic id) { assert(HasScalarInputVariant(id)); diff --git a/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/coreclr/jit/hwintrinsiclistarm64sve.h index ed238ba0fca56c..922b116fa25a23 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -23,12 +23,12 @@ HARDWARE_INTRINSIC(Sve, AbsoluteCompareLessThan, HARDWARE_INTRINSIC(Sve, AbsoluteCompareLessThanOrEqual, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_facle, INS_sve_facle}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReturnsPerElementMask|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, AbsoluteDifference, -1, -1, {INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_sabd, INS_sve_uabd, INS_sve_fabd, INS_sve_fabd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Add, -1, -1, {INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_add, INS_sve_fadd, INS_sve_fadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AddAcross, -1, 1, {INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_saddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_uaddv, INS_sve_faddv, INS_sve_faddv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, AddRotateComplex, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcadd, INS_sve_fcadd}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve, AddSaturate, -1, 2, {INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, AddSequentialAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fadda, INS_sve_fadda}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve, AddSequentialAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fadda, INS_sve_fadda}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, And, -1, -1, {INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_sve_and, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, AndAcross, -1, -1, {INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, AndAcross, -1, -1, {INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_sve_andv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, BitwiseClear, -1, -1, {INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_sve_bic, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, BooleanNot, -1, -1, {INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_sve_cnot, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Compact, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact, INS_sve_compact}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation) @@ -208,13 +208,13 @@ HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendFirstFaulting, HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, LoadVectorUInt32ZeroExtendToUInt64, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_ld1w, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_Scalable|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ZeroingMaskedOperation) HARDWARE_INTRINSIC(Sve, Max, -1, -1, {INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_smax, INS_sve_umax, INS_sve_fmax, INS_sve_fmax}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MaxAcross, -1, -1, {INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_fmaxv, INS_sve_fmaxv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MaxAcross, -1, -1, {INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_smaxv, INS_sve_umaxv, INS_sve_fmaxv, INS_sve_fmaxv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, MaxNumber, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnm, INS_sve_fmaxnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MaxNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnmv, INS_sve_fmaxnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MaxNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fmaxnmv, INS_sve_fmaxnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, Min, -1, -1, {INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_smin, INS_sve_umin, INS_sve_fmin, INS_sve_fmin}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MinAcross, -1, -1, {INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_fminv, INS_sve_fminv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MinAcross, -1, -1, {INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_sminv, INS_sve_uminv, INS_sve_fminv, INS_sve_fminv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, MinNumber, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnm, INS_sve_fminnm}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, MinNumberAcross, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fminnmv, INS_sve_fminnmv}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, Multiply, -1, 2, {INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_fmul, INS_sve_fmul}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, MultiplyAdd, -1, -1, {INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_FmaIntrinsic|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, MultiplyAddRotateComplex, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_fcmla, INS_sve_fcmla}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand) @@ -225,7 +225,7 @@ HARDWARE_INTRINSIC(Sve, MultiplySubtract, HARDWARE_INTRINSIC(Sve, Negate, -1, -1, {INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_neg, INS_invalid, INS_sve_fneg, INS_sve_fneg}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, Not, -1, -1, {INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_sve_not, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation) HARDWARE_INTRINSIC(Sve, Or, -1, -1, {INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_sve_orr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, OrAcross, -1, -1, {INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_sve_orv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, PopCount, -1, -1, {INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt, INS_sve_cnt}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_BaseTypeFromFirstArg|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, PrefetchBytes, -1, 3, {INS_invalid, INS_sve_prfb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Special, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_SpecialSideEffect_Other) HARDWARE_INTRINSIC(Sve, PrefetchInt16, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_sve_prfh, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Special, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_ExplicitMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_SpecialSideEffect_Other) @@ -293,7 +293,7 @@ HARDWARE_INTRINSIC(Sve, UnzipEven, HARDWARE_INTRINSIC(Sve, UnzipOdd, -1, 2, {INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2, INS_sve_uzp2}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve, VectorTableLookup, -1, 2, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve, Xor, -1, -1, {INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_sve_eor, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) -HARDWARE_INTRINSIC(Sve, XorAcross, -1, -1, {INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve, XorAcross, -1, -1, {INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_sve_eorv, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve, ZeroExtend16, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxth, INS_invalid, INS_sve_uxth, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ZeroExtend32, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtw, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve, ZeroExtend8, -1, -1, {INS_invalid, INS_invalid, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_sve_uxtb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_LowMaskedOperation) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 978c066be998a5..85a31b7c75aae3 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -4055,9 +4055,10 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* cndSelNode) NamedIntrinsic nestedOp2Id = nestedOp2->AsHWIntrinsic()->GetHWIntrinsicId(); // If the nested op uses Pg/Z, then inactive lanes will result in zeros, so can only transform if - // op3 is all zeros. + // op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this optimisation + // when the nestedOp is a reduce operation. - if (nestedOp1->IsMaskAllBitsSet() && + if (nestedOp1->IsMaskAllBitsSet() && (!HWIntrinsicInfo::IsReduceOperation(nestedOp2Id)) && (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero())) { GenTree* nestedOp2 = nestedCndSel->Op(2); diff --git a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 457808946c3dde..c8bf71ecc4be42 100644 --- a/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -220,6 +220,67 @@ } }"; +const string VecReduceUnOpTest_VectorValidationLogicForCndSel = @" + { + var hasFailed = (mask[0] != 0 ? {ValidateReduceOpResult}: (falseVal[0] != result[0])); + + if (hasFailed) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + var iterResult = (mask[i] != 0) ? 0 : falseVal[i]; + if (mask[i] != 0) + { + // Pick the trueValue + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + } + } + }"; + +const string VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue = @" + { + var hasFailed = (mask[0] != 0) ? (trueVal[0] != result[0]): {ValidateReduceOpResult}; + if (hasFailed) + { + succeeded = false; + } + else + { + for (var i = 1; i < RetElementCount; i++) + { + var iterResult = (mask[i] != 0) ? trueVal[i] : 0; + if (mask[i] != 0) + { + // Pick the trueValue + if (iterResult != result[i]) + { + succeeded = false; + break; + } + } + else + { + // For false, the values are merged with destination, and we do not know + // those contents would be, so skip verification for them. + } + } + } + }"; + const string VecReduceOpTest_ValidationLogic = @"if ({ValidateReduceOpResult}) { succeeded = false; @@ -293,7 +354,7 @@ ("_SveImmTernOpFirstArgTestTemplate.template", "SveVecImmTernOpFirstArgTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = SimpleTernVecOpTest_ValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = SimpleTernVecOpTest_ValidationLogicForCndSel_FalseValue }), ("_SveScalarTernOpTestTemplate.template", "SveScalarTernOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleScalarOpTest_ValidationLogic }), ("_SveImm2UnaryOpTestTemplate.template", "SveVecImm2UnOpTest.template", new Dictionary { ["TemplateName"] = "Imm", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), - ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic }), + ("_SveMinimalUnaryOpTestTemplate.template", "SveVecReduceUnOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = VecReduceOpTest_ValidationLogic, ["TemplateValidationLogicForCndSel"] = VecReduceUnOpTest_VectorValidationLogicForCndSel, ["TemplateValidationLogicForCndSel_FalseValue"] = VecReduceUnOpTest_VectorValidationLogicForCndSel_FalseValue }), ("_SveMasklessUnaryOpTestTemplate.template", "SveMasklessSimpleVecOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), ("_SveVecAndScalarOpTest.template", "SveVecAndScalarOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_VectorValidationLogic }), ("_SveMasklessBinaryOpTestTemplate.template", "SveMasklessVecBinOpTest.template", new Dictionary { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleVecOpTest_ValidationLogic }), diff --git a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template index 782f77de3520ea..5de4a13faa6ad0 100644 --- a/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template +++ b/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveMinimalUnaryOpTestTemplate.template @@ -50,6 +50,12 @@ namespace JIT.HardwareIntrinsics.Arm // Validates passing an instance member of a struct works test.RunStructFldScenario(); + + // Validates executing the test inside conditional, with op3 as falseValue + test.ConditionalSelect_FalseOp(); + + // Validates executing the test inside conditional, with op3 as zero + test.ConditionalSelect_ZeroOp(); } else { @@ -139,9 +145,12 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; + private {RetVectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; + private {RetVectorType}<{RetBaseType}> _falseFld; private DataTable _dataTable; @@ -149,8 +158,12 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})(TestLibrary.Generator.Get{RetBaseType}() % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetVectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize); @@ -239,6 +252,66 @@ namespace JIT.HardwareIntrinsics.Arm test.RunStructFldScenario(this); } + public void ConditionalSelect_FalseOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in trueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in falseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, _falseFld); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, _falseFld); + } + + public void ConditionalSelect_ZeroOp() + { + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in trueValue"); + ConditionalSelectScenario_TrueValue(_mask, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in trueValue"); + ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in falseValue"); + ConditionalSelectScenario_FalseValue(_mask, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.Zero, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + + TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in falseValue"); + ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}>.AllBitsSet, _fld1, {RetVectorType}<{RetBaseType}>.Zero); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario_TrueValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {RetVectorType}<{RetBaseType}> falseOp) + { + var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1), falseOp); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult_TrueValue(mask, op1, falseOp, _dataTable.outArrayPtr); + } + + [method: MethodImpl(MethodImplOptions.AggressiveInlining)] + private void ConditionalSelectScenario_FalseValue({RetVectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {RetVectorType}<{RetBaseType}> trueOp) + { + var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1)); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateConditionalSelectResult_FalseValue(mask, op1, trueOp, _dataTable.outArrayPtr); + } + public void RunUnsupportedScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario)); @@ -260,6 +333,62 @@ namespace JIT.HardwareIntrinsics.Arm } } + private void ValidateConditionalSelectResult_TrueValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {RetVectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") + { + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; + {Op1BaseType}[] firstOp = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref firstOp[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + bool succeeded = true; + {TemplateValidationLogicForCndSel} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Sve)}.{nameof({Isa}.{Method})}<{RetBaseType}>({RetVectorType}<{RetBaseType}>, {RetVectorType}<{RetBaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" falseOp: ({string.Join(", ", falseVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + + private void ValidateConditionalSelectResult_FalseValue({RetVectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> leftOp, {RetVectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") + { + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; + {Op1BaseType}[] firstOp = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; + {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref firstOp[0]), leftOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueVal[0]), trueOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); + + bool succeeded = true; + {TemplateValidationLogicForCndSel_FalseValue} + + if (!succeeded) + { + TestLibrary.TestFramework.LogInformation($"{nameof(Sve)}.{nameof({Isa}.{Method})}<{RetBaseType}>({RetVectorType}<{RetBaseType}>, {RetVectorType}<{RetBaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); + TestLibrary.TestFramework.LogInformation($"firstOp: ({string.Join(", ", firstOp)})"); + TestLibrary.TestFramework.LogInformation($" trueOp: ({string.Join(", ", trueVal)})"); + TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})"); + TestLibrary.TestFramework.LogInformation(string.Empty); + + Succeeded = false; + } + } + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs new file mode 100644 index 00000000000000..40a271dc856084 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; +using Xunit; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:17:54 +// Run on Arm64 Windows +// Seed: 14752078066107523191-vectort,vector64,vector128,armsve +// Reduced from 52.7 KiB to 0.7 KiB in 00:00:54 +// Hits JIT assert in Release: +// Assertion failed '!"Got unexpected instruction format after MOVPRFX"' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Emit code' (IL size 54; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\emitarm64sve.cpp Line: 18623 +// + +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public struct S2 +{ + public Vector F2; +} + +public class Runtime_106868 +{ + public static S2 s_1; + + public static int M4() + { + Vector vr17 = default(Vector); + var vr11 = Vector.Create(0); + var vr8 = Sve.SubtractSaturate(vr17, vr11); + return 1; + } + + [Fact] + public static void TestEntryPoint() + { + var vr12 = Vector.Create(0); + var vr13 = Vector.Create(0); + var vr14 = M4(); + var vr15 = Vector128.CreateScalar(vr14).AsVector(); + var vr16 = Sve.AndAcross(vr13); + s_1.F2 = Sve.ConditionalSelect(vr12, vr16, vr15); + Consume(s_1.F2); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(Vector v) + { + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj new file mode 100644 index 00000000000000..4c871121d918a1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs new file mode 100644 index 00000000000000..b471a6cc9631cf --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; +using Xunit; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:47:43 +// Run on Arm64 Windows +// Seed: 6363239363759785984-vectort,vector64,vector128,armsve +// Reduced from 29.6 KiB to 0.8 KiB in 00:00:27 +// Debug: Prints 0 line(s) +// Release: Prints 1 line(s) +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public class Runtime_106871 +{ + [Fact] + public static void TestEntryPoint() + { + var vr11 = (byte)1; + var vr12 = Vector128.CreateScalar(vr11).AsVector(); + var vr13 = Vector.Create(1); + var vr14 = Vector.Create(1); + var vr15 = (byte)Sve.ConditionalExtractAfterLastActiveElement(vr13, 0, vr14); + var vr16 = Vector128.CreateScalar(vr15).AsVector(); + var vr17 = Vector.Create(0); + var vr18 = (byte)1; + var vr19 = Vector128.CreateScalar(vr18).AsVector(); + var vr20 = Sve.MinAcross(vr19); + var vr21 = Sve.ConditionalSelect(vr16, vr20, vr17); + if (Sve.TestFirstTrue(vr12, vr21)) + { + System.Console.WriteLine(0); + } + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj new file mode 100644 index 00000000000000..4c871121d918a1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs new file mode 100644 index 00000000000000..557cb67f92cd16 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +using System.Runtime.CompilerServices; +using Xunit; + +// Generated by Fuzzlyn v2.3 on 2024-08-23 10:51:00 +// Run on Arm64 Windows +// Seed: 11139641262794602128-vectort,vector64,vector128,armsve +// Reduced from 38.6 KiB to 0.6 KiB in 00:00:32 +// Hits JIT assert in Release: +// Assertion failed 'intrin.op3->IsVectorZero()' in 'Program:Main(Fuzzlyn.ExecutionServer.IRuntime)' during 'Generate code' (IL size 100; hash 0xade6b36b; FullOpts) +// +// File: C:\dev\dotnet\runtime2\src\coreclr\jit\hwintrinsiccodegenarm64.cpp Line: 755 +// +using System; +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.Arm; + +public class C2 +{ + public Vector F3; +} + +public class Runtime_106872 +{ + public static C2[] s_1 = { new C2() }; + + [Fact] + public static void TestEntryPoint() + { + var vr4 = Vector128.CreateScalar(728.8837854670671d).AsVector(); + var vr5 = Vector128.CreateScalar(1103.750484880559d).AsVector(); + var vr6 = Vector128.CreateScalar(-1881.6772519539704d).AsVector(); + var vr7 = s_1[0].F3; + s_1[0].F3 = Sve.ConditionalSelect(vr4, Sve.AddSequentialAcross(vr6, vr7), vr5); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + private static void Consume(Vector v) + { + } +} \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj new file mode 100644 index 00000000000000..4c871121d918a1 --- /dev/null +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj @@ -0,0 +1,9 @@ + + + True + $(NoWarn),SYSLIB5003 + + + + + \ No newline at end of file From b3aed124a0467986376425a701b7471cc1790e10 Mon Sep 17 00:00:00 2001 From: Swapnil Gaikwad Date: Sat, 31 Aug 2024 10:36:26 +0100 Subject: [PATCH 2/3] Make tests SVE only --- src/coreclr/jit/lowerarmarch.cpp | 2 +- .../JitBlue/Runtime_106868/Runtime_106868.cs | 17 ++++++----- .../JitBlue/Runtime_106871/Runtime_106871.cs | 29 ++++++++++--------- .../JitBlue/Runtime_106872/Runtime_106872.cs | 13 +++++---- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/src/coreclr/jit/lowerarmarch.cpp b/src/coreclr/jit/lowerarmarch.cpp index 85a31b7c75aae3..a74bb3651c88f9 100644 --- a/src/coreclr/jit/lowerarmarch.cpp +++ b/src/coreclr/jit/lowerarmarch.cpp @@ -4058,7 +4058,7 @@ GenTree* Lowering::LowerHWIntrinsicCndSel(GenTreeHWIntrinsic* cndSelNode) // op3 is all zeros. Such a Csel operation is absorbed into the instruction when emitted. Skip this optimisation // when the nestedOp is a reduce operation. - if (nestedOp1->IsMaskAllBitsSet() && (!HWIntrinsicInfo::IsReduceOperation(nestedOp2Id)) && + if (nestedOp1->IsMaskAllBitsSet() && !HWIntrinsicInfo::IsReduceOperation(nestedOp2Id) && (!HWIntrinsicInfo::IsZeroingMaskedOperation(nestedOp2Id) || op3->IsVectorZero())) { GenTree* nestedOp2 = nestedCndSel->Op(2); diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs index 40a271dc856084..9b8c18ff935dd8 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs @@ -38,13 +38,16 @@ public static int M4() [Fact] public static void TestEntryPoint() { - var vr12 = Vector.Create(0); - var vr13 = Vector.Create(0); - var vr14 = M4(); - var vr15 = Vector128.CreateScalar(vr14).AsVector(); - var vr16 = Sve.AndAcross(vr13); - s_1.F2 = Sve.ConditionalSelect(vr12, vr16, vr15); - Consume(s_1.F2); + if (Sve.IsSupported) + { + var vr12 = Vector.Create(0); + var vr13 = Vector.Create(0); + var vr14 = M4(); + var vr15 = Vector128.CreateScalar(vr14).AsVector(); + var vr16 = Sve.AndAcross(vr13); + s_1.F2 = Sve.ConditionalSelect(vr12, vr16, vr15); + Consume(s_1.F2); + } } [MethodImpl(MethodImplOptions.NoInlining)] diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs index b471a6cc9631cf..917da32a9d8f9e 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs @@ -19,20 +19,23 @@ public class Runtime_106871 [Fact] public static void TestEntryPoint() { - var vr11 = (byte)1; - var vr12 = Vector128.CreateScalar(vr11).AsVector(); - var vr13 = Vector.Create(1); - var vr14 = Vector.Create(1); - var vr15 = (byte)Sve.ConditionalExtractAfterLastActiveElement(vr13, 0, vr14); - var vr16 = Vector128.CreateScalar(vr15).AsVector(); - var vr17 = Vector.Create(0); - var vr18 = (byte)1; - var vr19 = Vector128.CreateScalar(vr18).AsVector(); - var vr20 = Sve.MinAcross(vr19); - var vr21 = Sve.ConditionalSelect(vr16, vr20, vr17); - if (Sve.TestFirstTrue(vr12, vr21)) + if (Sve.IsSupported) { - System.Console.WriteLine(0); + var vr11 = (byte)1; + var vr12 = Vector128.CreateScalar(vr11).AsVector(); + var vr13 = Vector.Create(1); + var vr14 = Vector.Create(1); + var vr15 = (byte)Sve.ConditionalExtractAfterLastActiveElement(vr13, 0, vr14); + var vr16 = Vector128.CreateScalar(vr15).AsVector(); + var vr17 = Vector.Create(0); + var vr18 = (byte)1; + var vr19 = Vector128.CreateScalar(vr18).AsVector(); + var vr20 = Sve.MinAcross(vr19); + var vr21 = Sve.ConditionalSelect(vr16, vr20, vr17); + if (Sve.TestFirstTrue(vr12, vr21)) + { + System.Console.WriteLine(0); + } } } } \ No newline at end of file diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs index 557cb67f92cd16..d52326b8506ddc 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs @@ -29,11 +29,14 @@ public class Runtime_106872 [Fact] public static void TestEntryPoint() { - var vr4 = Vector128.CreateScalar(728.8837854670671d).AsVector(); - var vr5 = Vector128.CreateScalar(1103.750484880559d).AsVector(); - var vr6 = Vector128.CreateScalar(-1881.6772519539704d).AsVector(); - var vr7 = s_1[0].F3; - s_1[0].F3 = Sve.ConditionalSelect(vr4, Sve.AddSequentialAcross(vr6, vr7), vr5); + if (Sve.IsSupported) + { + var vr4 = Vector128.CreateScalar(728.8837854670671d).AsVector(); + var vr5 = Vector128.CreateScalar(1103.750484880559d).AsVector(); + var vr6 = Vector128.CreateScalar(-1881.6772519539704d).AsVector(); + var vr7 = s_1[0].F3; + s_1[0].F3 = Sve.ConditionalSelect(vr4, Sve.AddSequentialAcross(vr6, vr7), vr5); + } } [MethodImpl(MethodImplOptions.NoInlining)] From 5754bc6fb82650adbc9f7f11dd99df3844c28138 Mon Sep 17 00:00:00 2001 From: Swapnil Gaikwad Date: Mon, 2 Sep 2024 12:22:58 +0100 Subject: [PATCH 3/3] Add missing new lines at the end of new files --- .../JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs | 2 +- .../JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj | 2 +- .../JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs | 2 +- .../JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj | 2 +- .../JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs | 2 +- .../JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs index 9b8c18ff935dd8..0134bab599463c 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.cs @@ -54,4 +54,4 @@ public static void TestEntryPoint() private static void Consume(Vector v) { } -} \ No newline at end of file +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj index 4c871121d918a1..1352ebe3277bc7 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106868/Runtime_106868.csproj @@ -6,4 +6,4 @@ - \ No newline at end of file + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs index 917da32a9d8f9e..c69558571a31de 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.cs @@ -38,4 +38,4 @@ public static void TestEntryPoint() } } } -} \ No newline at end of file +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj index 4c871121d918a1..1352ebe3277bc7 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106871/Runtime_106871.csproj @@ -6,4 +6,4 @@ - \ No newline at end of file + diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs index d52326b8506ddc..16de557d30335c 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.cs @@ -43,4 +43,4 @@ public static void TestEntryPoint() private static void Consume(Vector v) { } -} \ No newline at end of file +} diff --git a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj index 4c871121d918a1..1352ebe3277bc7 100644 --- a/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj +++ b/src/tests/JIT/Regression/JitBlue/Runtime_106872/Runtime_106872.csproj @@ -6,4 +6,4 @@ - \ No newline at end of file +