diff --git a/src/jit/emitfmtsxarch.h b/src/jit/emitfmtsxarch.h index b7ab38f0c034..4d97c4d8c535 100644 --- a/src/jit/emitfmtsxarch.h +++ b/src/jit/emitfmtsxarch.h @@ -139,6 +139,8 @@ IF_DEF(MRD_CNS, IS_GM_RD, DSP_CNS) // read [mem], const IF_DEF(MWR_CNS, IS_GM_WR, DSP_CNS) // write [mem], const IF_DEF(MRW_CNS, IS_GM_RW, DSP_CNS) // r/w [mem], const +IF_DEF(MWR_RRD_CNS, IS_GM_WR|IS_R1_RD, DSP_CNS) // write [mem], read reg, const + IF_DEF(MRW_SHF, IS_GM_RW, DSP_CNS) // shift [mem], const //---------------------------------------------------------------------------- @@ -194,6 +196,8 @@ IF_DEF(ARD_CNS, IS_AM_RD, AMD_CNS) // read [adr], const IF_DEF(AWR_CNS, IS_AM_WR, AMD_CNS) // write [adr], const IF_DEF(ARW_CNS, IS_AM_RW, AMD_CNS) // r/w [adr], const +IF_DEF(AWR_RRD_CNS, IS_AM_WR|IS_R1_RD, AMD_CNS) // write [adr], read reg, const + IF_DEF(ARW_SHF, IS_AM_RW, AMD_CNS) // shift [adr], const diff --git a/src/jit/emitxarch.cpp b/src/jit/emitxarch.cpp index 117bc21c2e56..094776b17d0b 100644 --- a/src/jit/emitxarch.cpp +++ b/src/jit/emitxarch.cpp @@ -2730,6 +2730,9 @@ emitter::insFormat emitter::emitMapFmtAtoM(insFormat fmt) case IF_ARW_CNS: return IF_MRW_CNS; + case IF_AWR_RRD_CNS: + return IF_MWR_RRD_CNS; + case IF_ARW_SHF: return IF_MRW_SHF; @@ -5067,6 +5070,32 @@ void emitter::emitIns_AR_R(instruction ins, emitAttr attr, regNumber ireg, regNu emitAdjustStackDepthPushPop(ins); } +#ifndef LEGACY_BACKEND +void emitter::emitIns_AR_R_I(instruction ins, emitAttr attr, regNumber base, int disp, regNumber ireg, int ival) +{ + assert(ins == INS_vextracti128 || ins == INS_vextractf128); + assert(base != REG_NA); + assert(ireg != REG_NA); + UNATIVE_OFFSET sz; + instrDesc* id = emitNewInstrAmdCns(attr, disp, ival); + + id->idIns(ins); + id->idInsFmt(IF_AWR_RRD_CNS); + id->idAddr()->iiaAddrMode.amBaseReg = base; + id->idAddr()->iiaAddrMode.amIndxReg = REG_NA; + id->idReg1(ireg); + + assert(emitGetInsAmdAny(id) == disp); // make sure "disp" is stored properly + + // the code size of "vextracti/f128 [mem], ymm, imm8" is 6 byte + sz = 6; + id->idCodeSize(sz); + + dispIns(id); + emitCurIGsize += sz; +} +#endif + void emitter::emitIns_AI_R(instruction ins, emitAttr attr, regNumber ireg, ssize_t disp) { UNATIVE_OFFSET sz; @@ -7790,6 +7819,32 @@ void emitter::emitDispIns( break; } + case IF_AWR_RRD_CNS: + { + assert(ins == INS_vextracti128 || ins == INS_vextractf128); + // vextracti/f128 extracts 128-bit data, so we fix sstr as "xmm ptr" + sstr = codeGen->genSizeStr(EA_ATTR(16)); + printf(sstr); + emitDispAddrMode(id); + printf(", %s", emitRegName(id->idReg1(), attr)); + + emitGetInsAmdCns(id, &cnsVal); + + val = cnsVal.cnsVal; + printf(", "); + + if (cnsVal.cnsReloc) + { + emitDispReloc(val); + } + else + { + goto PRINT_CONSTANT; + } + + break; + } + case IF_RWR_RRD_ARD: printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); emitDispAddrMode(id); @@ -8166,6 +8221,32 @@ void emitter::emitDispIns( break; } + case IF_MWR_RRD_CNS: + { + assert(ins == INS_vextracti128 || ins == INS_vextractf128); + // vextracti/f128 extracts 128-bit data, so we fix sstr as "xmm ptr" + sstr = codeGen->genSizeStr(EA_ATTR(16)); + printf(sstr); + offs = emitGetInsDsp(id); + emitDispClsVar(id->idAddr()->iiaFieldHnd, offs, ID_INFO_DSP_RELOC); + printf(", %s", emitRegName(id->idReg1(), attr)); + emitGetInsDcmCns(id, &cnsVal); + + val = cnsVal.cnsVal; + printf(", "); + + if (cnsVal.cnsReloc) + { + emitDispReloc(val); + } + else + { + goto PRINT_CONSTANT; + } + + break; + } + case IF_RWR_RRD_MRD: printf("%s, %s, %s", emitRegName(id->idReg1(), attr), emitRegName(id->idReg2(), attr), sstr); offs = emitGetInsDsp(id); @@ -12218,6 +12299,15 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) sz = emitSizeOfInsDsc(id); break; + case IF_AWR_RRD_CNS: + assert(ins == INS_vextracti128 || ins == INS_vextractf128); + assert(UseVEXEncoding()); + emitGetInsAmdCns(id, &cnsVal); + code = insCodeMR(ins); + dst = emitOutputAM(dst, id, code, &cnsVal); + sz = emitSizeOfInsDsc(id); + break; + case IF_RRD_ARD: case IF_RWR_ARD: case IF_RRW_ARD: @@ -12530,6 +12620,17 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) sz = emitSizeOfInsDsc(id); break; + case IF_MWR_RRD_CNS: + assert(ins == INS_vextracti128 || ins == INS_vextractf128); + assert(UseVEXEncoding()); + emitGetInsDcmCns(id, &cnsVal); + code = insCodeMR(ins); + // only AVX2 vextracti128 and AVX vextractf128 can reach this path, + // they do not need VEX.vvvv to encode the register operand + dst = emitOutputCV(dst, id, code, &cnsVal); + sz = emitSizeOfInsDsc(id); + break; + case IF_RRD_MRD: case IF_RWR_MRD: case IF_RRW_MRD: diff --git a/src/jit/emitxarch.h b/src/jit/emitxarch.h index a5bc3037196b..4cfa24fcdeea 100644 --- a/src/jit/emitxarch.h +++ b/src/jit/emitxarch.h @@ -416,6 +416,7 @@ void emitIns_R_R_A_I( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, GenTreeIndir* indir, int ival, insFormat fmt); void emitIns_R_R_AR_I( instruction ins, emitAttr attr, regNumber reg1, regNumber reg2, regNumber base, int offs, int ival); +void emitIns_AR_R_I(instruction ins, emitAttr attr, regNumber base, int disp, regNumber ireg, int ival); #endif // !LEGACY_BACKEND void emitIns_R_R_C_I( diff --git a/src/jit/hwintrinsiccodegenxarch.cpp b/src/jit/hwintrinsiccodegenxarch.cpp index 1d6380ebe02b..acf013e20794 100644 --- a/src/jit/hwintrinsiccodegenxarch.cpp +++ b/src/jit/hwintrinsiccodegenxarch.cpp @@ -1318,6 +1318,67 @@ void CodeGen::genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node) break; } + case NI_AVX_SetAllVector256: + { + assert(op1 != nullptr); + assert(op2 == nullptr); + op1Reg = op1->gtRegNum; + if (varTypeIsIntegral(baseType)) + { + // If the argument is a integer, it needs to be moved into a XMM register + regNumber tmpXMM = node->ExtractTempReg(); + emit->emitIns_R_R(INS_mov_i2xmm, emitActualTypeSize(baseType), tmpXMM, op1Reg); + op1Reg = tmpXMM; + } + + if (compiler->compSupports(InstructionSet_AVX2)) + { + // generate broadcast instructions if AVX2 is available + emit->emitIns_R_R(ins, emitTypeSize(TYP_SIMD32), targetReg, op1Reg); + } + else + { + // duplicate the scalar argument to XMM register + switch (baseType) + { + case TYP_FLOAT: + emit->emitIns_SIMD_R_R_I(INS_vpermilps, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg, 0); + break; + case TYP_DOUBLE: + emit->emitIns_R_R(INS_movddup, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg); + break; + case TYP_BYTE: + case TYP_UBYTE: + { + regNumber tmpZeroReg = node->GetSingleTempReg(); + emit->emitIns_R_R(INS_pxor, emitTypeSize(TYP_SIMD16), tmpZeroReg, tmpZeroReg); + emit->emitIns_SIMD_R_R_R(INS_pshufb, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg, tmpZeroReg); + break; + } + case TYP_SHORT: + case TYP_USHORT: + emit->emitIns_SIMD_R_R_I(INS_pshuflw, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg, 0); + emit->emitIns_SIMD_R_R_I(INS_pshufd, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg, 80); + break; + case TYP_INT: + case TYP_UINT: + emit->emitIns_SIMD_R_R_I(INS_pshufd, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg, 0); + break; + case TYP_LONG: + case TYP_ULONG: + emit->emitIns_SIMD_R_R_I(INS_pshufd, emitTypeSize(TYP_SIMD16), op1Reg, op1Reg, 68); + break; + + default: + unreached(); + break; + } + // duplicate the XMM register to YMM register + emit->emitIns_SIMD_R_R_R_I(INS_vinsertf128, emitTypeSize(TYP_SIMD32), targetReg, op1Reg, op1Reg, 1); + } + break; + } + case NI_AVX_ExtendToVector256: { // ExtendToVector256 has zero-extend semantics in order to ensure it is deterministic @@ -1412,7 +1473,7 @@ void CodeGen::genAvxOrAvx2Intrinsic(GenTreeHWIntrinsic* node) { if (intrinsicID == NI_AVX_ExtractVector128 || intrinsicID == NI_AVX2_ExtractVector128) { - emit->emitIns_R_AR_I(ins, attr, op2Reg, op1Reg, 0, (int)i); + emit->emitIns_AR_R_I(ins, attr, op1Reg, 0, op2Reg, (int)i); } else if (op2->TypeGet() == TYP_I_IMPL) { diff --git a/src/jit/hwintrinsiclistxarch.h b/src/jit/hwintrinsiclistxarch.h index 216284f93590..b7a769a4dba8 100644 --- a/src/jit/hwintrinsiclistxarch.h +++ b/src/jit/hwintrinsiclistxarch.h @@ -348,12 +348,14 @@ HARDWARE_INTRINSIC(AVX_Divide, "Divide", HARDWARE_INTRINSIC(AVX_DotProduct, "DotProduct", AVX, -1, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_dpps, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX_DuplicateEvenIndexed, "DuplicateEvenIndexed", AVX, -1, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movsldup, INS_movddup}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_DuplicateOddIndexed, "DuplicateOddIndexed", AVX, -1, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movshdup, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX_Extract, "Extract", AVX, -1, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_BaseTypeFromFirstArg|HW_Flag_FullRangeIMM|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(AVX_ExtendToVector256, "ExtendToVector256", AVX, -1, 32, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movaps, INS_movapd}, HW_Category_Helper, HW_Flag_OneTypeGeneric|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_ExtractVector128, "ExtractVector128", AVX, -1, 32, -1, {INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128,INS_vextractf128, INS_vextractf128},HW_Category_IMM, HW_Flag_OneTypeGeneric|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX_Floor, "Floor", AVX, 9, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_GetLowerHalf, "GetLowerHalf", AVX, -1, 32, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movaps, INS_movapd}, HW_Category_Helper, HW_Flag_OneTypeGeneric|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_HorizontalAdd, "HorizontalAdd", AVX, -1, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_haddps, INS_haddpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) HARDWARE_INTRINSIC(AVX_HorizontalSubtract, "HorizontalSubtract", AVX, -1, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_hsubps, INS_hsubpd}, HW_Category_SimpleSIMD, HW_Flag_NoFlag) +HARDWARE_INTRINSIC(AVX_Insert, "Insert", AVX, -1, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_NoCodeGen|HW_Flag_SecondArgMaybe64Bit) HARDWARE_INTRINSIC(AVX_InsertVector128, "InsertVector128", AVX, -1, 32, 3, {INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128,INS_vinsertf128, INS_vinsertf128},HW_Category_IMM, HW_Flag_FullRangeIMM|HW_Flag_OneTypeGeneric|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(AVX_LoadAlignedVector256, "LoadAlignedVector256", AVX, -1, 32, 1, {INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movdqa, INS_movaps, INS_movapd}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_LoadDquVector256, "LoadDquVector256", AVX, -1, 32, 1, {INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_lddqu, INS_invalid, INS_invalid}, HW_Category_MemoryLoad, HW_Flag_NoRMWSemantics) @@ -374,6 +376,8 @@ HARDWARE_INTRINSIC(AVX_RoundToNearestInteger, "RoundToNea HARDWARE_INTRINSIC(AVX_RoundToNegativeInfinity, "RoundToNegativeInfinity", AVX, 9, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_RoundToPositiveInfinity, "RoundToPositiveInfinity", AVX, 10, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_RoundToZero, "RoundToZero", AVX, 11, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_roundps, INS_roundpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) +HARDWARE_INTRINSIC(AVX_SetVector256, "SetVector256", AVX, -1, 32, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SecondArgMaybe64Bit) +HARDWARE_INTRINSIC(AVX_SetAllVector256, "SetAllVector256", AVX, -1, 32, 1, {INS_vpbroadcastb,INS_vpbroadcastb,INS_vpbroadcastw,INS_vpbroadcastw,INS_vpbroadcastd,INS_vpbroadcastd,INS_vpbroadcastq,INS_vpbroadcastq,INS_vbroadcastss,INS_vbroadcastsd},HW_Category_Helper, HW_Flag_MultiIns|HW_Flag_SpecialImport|HW_Flag_OneTypeGeneric) HARDWARE_INTRINSIC(AVX_SetZeroVector256, "SetZeroVector256", AVX, -1, 32, 0, {INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_pxor, INS_xorps, INS_xorpd}, HW_Category_Helper, HW_Flag_OneTypeGeneric|HW_Flag_NoRMWSemantics) HARDWARE_INTRINSIC(AVX_Shuffle, "Shuffle", AVX, -1, 32, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_shufps, INS_shufpd}, HW_Category_IMM, HW_Flag_NoRMWSemantics|HW_Flag_FullRangeIMM) HARDWARE_INTRINSIC(AVX_Sqrt, "Sqrt", AVX, -1, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqrtps, INS_sqrtpd}, HW_Category_SimpleSIMD, HW_Flag_NoRMWSemantics) diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp index c52958a170f9..1c80714918e0 100644 --- a/src/jit/hwintrinsicxarch.cpp +++ b/src/jit/hwintrinsicxarch.cpp @@ -1058,6 +1058,26 @@ GenTree* Compiler::impSSE42Intrinsic(NamedIntrinsic intrinsic, return retNode; } +//------------------------------------------------------------------------ +// normalizeAndGetHalfIndex: compute the half index of a Vector256 +// and normalize the index to the specific range +// +// Arguments: +// indexPtr -- OUT paramter, the pointer to the original index value +// baseType -- the base type of the Vector256 +// +// Return Value: +// retuen the middle index of a Vector256 +// return the normalized index via indexPtr +// +static int normalizeAndGetHalfIndex(int* indexPtr, var_types baseType) +{ + assert(varTypeIsArithmetic(baseType)); + // clear the unused bits to normalize the index into the range of [0, length of Vector256) + *indexPtr = (*indexPtr) & (32 / genTypeSize(baseType) - 1); + return (16 / genTypeSize(baseType)); +} + GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig, @@ -1071,6 +1091,145 @@ GenTree* Compiler::impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, switch (intrinsic) { + case NI_AVX_Extract: + { + // Avx.Extract executes software implementation when the imm8 argument is not compile-time constant + assert(!mustExpand); + + GenTree* lastOp = impPopStack().val; + GenTree* vectorOp = impSIMDPopStack(TYP_SIMD32); + assert(lastOp->IsCnsIntOrI()); + int ival = (int)lastOp->AsIntCon()->IconValue(); + baseType = getBaseTypeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args)); + var_types retType = JITtype2varType(sig->retType); + assert(varTypeIsArithmetic(baseType)); + + int midIndex = normalizeAndGetHalfIndex(&ival, baseType); + NamedIntrinsic extractIntrinsic = varTypeIsShort(baseType) ? NI_SSE2_Extract : NI_SSE41_Extract; + GenTree* half = nullptr; + + if (ival >= midIndex) + { + half = gtNewSimdHWIntrinsicNode(TYP_SIMD16, vectorOp, gtNewIconNode(1), NI_AVX_ExtractVector128, + baseType, 32); + ival -= midIndex; + } + else + { + half = gtNewSimdHWIntrinsicNode(TYP_SIMD16, vectorOp, NI_AVX_GetLowerHalf, baseType, 32); + } + + retNode = gtNewSimdHWIntrinsicNode(retType, half, gtNewIconNode(ival), extractIntrinsic, baseType, 16); + break; + } + + case NI_AVX_Insert: + { + // Avx.Extract executes software implementation when the imm8 argument is not compile-time constant + assert(!mustExpand); + + GenTree* lastOp = impPopStack().val; + GenTree* dataOp = impPopStack().val; + GenTree* vectorOp = impSIMDPopStack(TYP_SIMD32); + assert(lastOp->IsCnsIntOrI()); + int ival = (int)lastOp->AsIntCon()->IconValue(); + baseType = getBaseTypeOfSIMDType(sig->retTypeSigClass); + assert(varTypeIsArithmetic(baseType)); + + int midIndex = normalizeAndGetHalfIndex(&ival, baseType); + NamedIntrinsic insertIntrinsic = varTypeIsShort(baseType) ? NI_SSE2_Insert : NI_SSE41_Insert; + + GenTree* clonedVectorOp; + vectorOp = + impCloneExpr(vectorOp, &clonedVectorOp, info.compCompHnd->getArgClass(sig, sig->args), + (unsigned)CHECK_SPILL_ALL, nullptr DEBUGARG("AVX Insert clones the vector operand")); + + if (ival >= midIndex) + { + GenTree* halfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, vectorOp, gtNewIconNode(1), + NI_AVX_ExtractVector128, baseType, 32); + GenTree* ModifiedHalfVector = + gtNewSimdHWIntrinsicNode(TYP_SIMD16, halfVector, dataOp, gtNewIconNode(ival - midIndex), + insertIntrinsic, baseType, 16); + retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD32, clonedVectorOp, ModifiedHalfVector, gtNewIconNode(1), + NI_AVX_InsertVector128, baseType, 32); + } + else + { + GenTree* halfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, vectorOp, NI_AVX_GetLowerHalf, baseType, 32); + GenTree* ModifiedHalfVector = + gtNewSimdHWIntrinsicNode(TYP_SIMD32, halfVector, dataOp, gtNewIconNode(ival), insertIntrinsic, + baseType, 16); + retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD32, clonedVectorOp, ModifiedHalfVector, gtNewIconNode(15), + NI_AVX_Blend, TYP_FLOAT, 32); + } + break; + } + + case NI_AVX_SetVector256: + { + // TODO-XARCH: support long/ulong on 32-bit platfroms (remove HW_Flag_SecondArgMaybe64Bit) + int numArgs = sig->numArgs; + assert(numArgs >= 4); + assert(numArgs <= 32); + baseType = getBaseTypeOfSIMDType(sig->retTypeSigClass); + GenTree* higherHalfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, NI_SSE_SetZeroVector128, TYP_FLOAT, 16); + GenTree* lowerHalfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, NI_SSE_SetZeroVector128, TYP_FLOAT, 16); + NamedIntrinsic insertIntrinsic = varTypeIsShort(baseType) ? NI_SSE2_Insert : NI_SSE41_Insert; + int ival = 0; + + if (baseType != TYP_DOUBLE) + { + assert(varTypeIsIntegral(baseType) || baseType == TYP_FLOAT); + + for (int i = 0; i < numArgs / 2; i++) + { + GenTree* arg = impPopStack().val; + // SSE4.1 insertps has different semantics from integral insert + ival = baseType == TYP_FLOAT ? i * 16 : i; + lowerHalfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, lowerHalfVector, arg, gtNewIconNode(ival), + insertIntrinsic, baseType, 16); + } + + for (int i = 0; i < numArgs / 2; i++) + { + GenTree* arg = impPopStack().val; + // SSE4.1 insertps has different semantics from integral insert + ival = baseType == TYP_FLOAT ? i * 16 : i; + higherHalfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, higherHalfVector, arg, gtNewIconNode(ival), + insertIntrinsic, baseType, 16); + } + } + else + { + GenTree* op4 = impPopStack().val; + GenTree* op3 = impPopStack().val; + GenTree* op2 = impPopStack().val; + GenTree* op1 = impPopStack().val; + lowerHalfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op4, op3, NI_SSE2_UnpackLow, TYP_DOUBLE, 16); + higherHalfVector = gtNewSimdHWIntrinsicNode(TYP_SIMD16, op2, op1, NI_SSE2_UnpackLow, TYP_DOUBLE, 16); + } + + retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD32, lowerHalfVector, higherHalfVector, gtNewIconNode(1), + NI_AVX_InsertVector128, baseType, 32); + break; + } + + case NI_AVX_SetAllVector256: + { + baseType = getBaseTypeOfSIMDType(sig->retTypeSigClass); +#ifdef _TARGET_X86_ + // TODO-XARCH: support long/ulong on 32-bit platfroms + if (varTypeIsLong(baseType)) + { + return impUnsupportedHWIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand); + } +#endif + GenTree* arg = impPopStack().val; + retNode = gtNewSimdHWIntrinsicNode(TYP_SIMD32, arg, NI_AVX_SetAllVector256, baseType, 32); + break; + } + case NI_AVX_ExtractVector128: case NI_AVX2_ExtractVector128: { diff --git a/src/jit/instrsxarch.h b/src/jit/instrsxarch.h index 23af97a282df..8d210d9f2ede 100644 --- a/src/jit/instrsxarch.h +++ b/src/jit/instrsxarch.h @@ -474,8 +474,8 @@ INST3( vpbroadcastb, "pbroadcastb" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SS INST3( vpbroadcastw, "pbroadcastw" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x79)) // Broadcast int16 value from reg/memory to entire ymm register INST3( vpbroadcastd, "pbroadcastd" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x58)) // Broadcast int32 value from reg/memory to entire ymm register INST3( vpbroadcastq, "pbroadcastq" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE38(0x59)) // Broadcast int64 value from reg/memory to entire ymm register -INST3( vextractf128, "extractf128" , 0, IUM_WR, 0, 0, SSE3A(0x19), BAD_CODE, SSE3A(0x19)) // Extract 128-bit packed floating point values -INST3( vextracti128, "extracti128" , 0, IUM_WR, 0, 0, SSE3A(0x39), BAD_CODE, SSE3A(0x39)) // Extract 128-bit packed integer values +INST3( vextractf128, "extractf128" , 0, IUM_WR, 0, 0, SSE3A(0x19), BAD_CODE, BAD_CODE) // Extract 128-bit packed floating point values +INST3( vextracti128, "extracti128" , 0, IUM_WR, 0, 0, SSE3A(0x39), BAD_CODE, BAD_CODE) // Extract 128-bit packed integer values INST3( vinsertf128, "insertf128" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE3A(0x18)) // Insert 128-bit packed floating point values INST3( vinserti128, "inserti128" , 0, IUM_WR, 0, 0, BAD_CODE, BAD_CODE, SSE3A(0x38)) // Insert 128-bit packed integer values INST3( vzeroupper, "zeroupper" , 0, IUM_WR, 0, 0, 0xC577F8, BAD_CODE, BAD_CODE) // Zero upper 128-bits of all YMM regs (includes 2-byte fixed VEX prefix) diff --git a/src/jit/lsraxarch.cpp b/src/jit/lsraxarch.cpp index 2d7e6564e355..09cc9ca96ed3 100644 --- a/src/jit/lsraxarch.cpp +++ b/src/jit/lsraxarch.cpp @@ -2368,6 +2368,20 @@ void LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree) break; } + case NI_AVX_SetAllVector256: + { + if (varTypeIsIntegral(baseType)) + { + info->internalFloatCount = 1; + if (!compiler->compSupports(InstructionSet_AVX2) && varTypeIsByte(baseType)) + { + info->internalFloatCount += 1; + } + info->setInternalCandidates(this, allSIMDRegs()); + } + break; + } + case NI_SSE2_MaskMove: { // SSE2 MaskMove hardcodes the destination (op3) in DI/EDI/RDI diff --git a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs index 23f41276911f..f9e48f8373b5 100644 --- a/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs +++ b/src/mscorlib/src/System/Runtime/Intrinsics/X86/Avx.cs @@ -239,17 +239,14 @@ public static class Avx /// __int8 _mm256_extract_epi8 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static sbyte Extract(Vector256 value, byte index) { - index &= 0x1F; // the instructions only need the lowest 5 bits. - if (index > 15) + unsafe { - return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 16)); - } - else - { - return Sse41.Extract(GetLowerHalf(value), index); + index &= 0x1F; + sbyte* buffer = stackalloc sbyte[32]; + Store(buffer, value); + return buffer[index]; } } @@ -257,17 +254,14 @@ public static sbyte Extract(Vector256 value, byte index) /// __int8 _mm256_extract_epi8 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static byte Extract(Vector256 value, byte index) { - index &= 0x1F; // the instructions only need the lowest 5 bits. - if (index > 15) - { - return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 16)); - } - else + unsafe { - return Sse41.Extract(GetLowerHalf(value), index); + index &= 0x1F; + byte* buffer = stackalloc byte[32]; + Store(buffer, value); + return buffer[index]; } } @@ -275,35 +269,29 @@ public static byte Extract(Vector256 value, byte index) /// __int16 _mm256_extract_epi16 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static short Extract(Vector256 value, byte index) { - index &= 0xF; // the instructions only need the lowest 4 bits. - if (index > 7) + unsafe { - return Sse2.Extract(ExtractVector128(value, 1), (byte)(index - 8)); - } - else - { - return Sse2.Extract(GetLowerHalf(value), index); - } + index &= 0xF; + short* buffer = stackalloc short[16]; + Store(buffer, value); + return buffer[index]; + } } /// /// __int16 _mm256_extract_epi16 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ushort Extract(Vector256 value, byte index) { - index &= 0xF; // the instructions only need the lowest 4 bits. - if (index > 7) + unsafe { - return Sse2.Extract(ExtractVector128(value, 1), (byte)(index - 8)); - } - else - { - return Sse2.Extract(GetLowerHalf(value), index); + index &= 0xF; + ushort* buffer = stackalloc ushort[16]; + Store(buffer, value); + return buffer[index]; } } @@ -311,17 +299,14 @@ public static ushort Extract(Vector256 value, byte index) /// __int32 _mm256_extract_epi32 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int Extract(Vector256 value, byte index) { - index &= 0x7; // the instructions only need the lowest 3 bits. - if (index > 3) - { - return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 4)); - } - else + unsafe { - return Sse41.Extract(GetLowerHalf(value), index); + index &= 0x7; + int* buffer = stackalloc int[8]; + Store(buffer, value); + return buffer[index]; } } @@ -329,17 +314,14 @@ public static int Extract(Vector256 value, byte index) /// __int32 _mm256_extract_epi32 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static uint Extract(Vector256 value, byte index) { - index &= 0x7; // the instructions only need the lowest 3 bits. - if (index > 3) + unsafe { - return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 4)); - } - else - { - return Sse41.Extract(GetLowerHalf(value), index); + index &= 0x7; + uint* buffer = stackalloc uint[8]; + Store(buffer, value); + return buffer[index]; } } @@ -347,17 +329,18 @@ public static uint Extract(Vector256 value, byte index) /// __int64 _mm256_extract_epi64 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static long Extract(Vector256 value, byte index) { - index &= 0x3; // the instructions only need the lowest 2 bits. - if (index > 1) + if (IntPtr.Size != 8) { - return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 2)); + throw new PlatformNotSupportedException(); } - else + unsafe { - return Sse41.Extract(GetLowerHalf(value), index); + index &= 0x3; + long* buffer = stackalloc long[4]; + Store(buffer, value); + return buffer[index]; } } @@ -365,17 +348,18 @@ public static long Extract(Vector256 value, byte index) /// __int64 _mm256_extract_epi64 (__m256i a, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static ulong Extract(Vector256 value, byte index) { - index &= 0x3; // the instructions only need the lowest 2 bits. - if (index > 1) + if (IntPtr.Size != 8) { - return Sse41.Extract(ExtractVector128(value, 1), (byte)(index - 2)); + throw new PlatformNotSupportedException(); } - else + unsafe { - return Sse41.Extract(GetLowerHalf(value), index); + index &= 0x3; + ulong* buffer = stackalloc ulong[4]; + Store(buffer, value); + return buffer[index]; } } @@ -506,20 +490,15 @@ public static Vector128 GetLowerHalf(Vector256 value) where T : struct /// __m256i _mm256_insert_epi8 (__m256i a, __int8 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, sbyte data, byte index) { - index &= 0x1F; // the instructions only need the lowest 5 bits. - if (index > 15) - { - Vector128 half = ExtractVector128(value, 1); - half = Sse41.Insert(half, data, (byte)(index - 16)); - return InsertVector128(value, half, 1); - } - else + unsafe { - Vector128 half = Sse41.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0x1F; + sbyte* buffer = stackalloc sbyte[32]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -527,20 +506,15 @@ public static Vector256 Insert(Vector256 value, sbyte data, byte i /// __m256i _mm256_insert_epi8 (__m256i a, __int8 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, byte data, byte index) { - index &= 0x1F; // the instructions only need the lowest 5 bits. - if (index > 15) + unsafe { - Vector128 half = ExtractVector128(value, 1); - half = Sse41.Insert(half, data, (byte)(index - 16)); - return InsertVector128(value, half, 1); - } - else - { - Vector128 half = Sse41.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0x1F; + byte* buffer = stackalloc byte[32]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -548,20 +522,15 @@ public static Vector256 Insert(Vector256 value, byte data, byte inde /// __m256i _mm256_insert_epi16 (__m256i a, __int16 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, short data, byte index) { - index &= 0xF; // the instructions only need the lowest 4 bits. - if (index > 7) - { - Vector128 half = ExtractVector128(value, 1); - half = Sse2.Insert(half, data, (byte)(index - 8)); - return InsertVector128(value, half, 1); - } - else + unsafe { - Vector128 half = Sse2.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0xF; + short* buffer = stackalloc short[16]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -569,20 +538,15 @@ public static Vector256 Insert(Vector256 value, short data, byte i /// __m256i _mm256_insert_epi16 (__m256i a, __int16 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, ushort data, byte index) { - index &= 0xF; // the instructions only need the lowest 4 bits. - if (index > 7) + unsafe { - Vector128 half = ExtractVector128(value, 1); - half = Sse2.Insert(half, data, (byte)(index - 8)); - return InsertVector128(value, half, 1); - } - else - { - Vector128 half = Sse2.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0xF; + ushort* buffer = stackalloc ushort[16]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -590,20 +554,15 @@ public static Vector256 Insert(Vector256 value, ushort data, byt /// __m256i _mm256_insert_epi32 (__m256i a, __int32 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, int data, byte index) { - index &= 0x7; // the instructions only need the lowest 3 bits. - if (index > 3) - { - Vector128 half = ExtractVector128(value, 1); - half = Sse41.Insert(half, data, (byte)(index - 4)); - return InsertVector128(value, half, 1); - } - else + unsafe { - Vector128 half = Sse41.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0x7; + int* buffer = stackalloc int[8]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -611,20 +570,15 @@ public static Vector256 Insert(Vector256 value, int data, byte index) /// __m256i _mm256_insert_epi32 (__m256i a, __int32 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, uint data, byte index) { - index &= 0x7; // the instructions only need the lowest 3 bits. - if (index > 3) - { - Vector128 half = ExtractVector128(value, 1); - half = Sse41.Insert(half, data, (byte)(index - 4)); - return InsertVector128(value, half, 1); - } - else + unsafe { - Vector128 half = Sse41.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0x7; + uint* buffer = stackalloc uint[8]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -632,20 +586,15 @@ public static Vector256 Insert(Vector256 value, uint data, byte inde /// __m256i _mm256_insert_epi64 (__m256i a, __int64 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, long data, byte index) { - index &= 0x3; // the instructions only need the lowest 2 bits. - if (index > 1) + unsafe { - Vector128 half = ExtractVector128(value, 1); - half = Sse41.Insert(half, data, (byte)(index - 2)); - return InsertVector128(value, half, 1); - } - else - { - Vector128 half = Sse41.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0x3; + long* buffer = stackalloc long[4]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } @@ -653,20 +602,15 @@ public static Vector256 Insert(Vector256 value, long data, byte inde /// __m256i _mm256_insert_epi64 (__m256i a, __int64 i, const int index) /// HELPER /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector256 Insert(Vector256 value, ulong data, byte index) { - index &= 0x3; // the instructions only need the lowest 2 bits. - if (index > 1) - { - Vector128 half = ExtractVector128(value, 1); - half = Sse41.Insert(half, data, (byte)(index - 2)); - return InsertVector128(value, half, 1); - } - else + unsafe { - Vector128 half = Sse41.Insert(GetLowerHalf(value), data, index); - return StaticCast(Blend(StaticCast(value), StaticCast(ExtendToVector256(half)), 15)); + index &= 0x3; + ulong* buffer = stackalloc ulong[4]; + Store(buffer, value); + buffer[index] = data; + return LoadVector256(buffer); } } diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj index 15fd28eb487b..7f89b8944017 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj @@ -60,6 +60,14 @@ + + + + + + + + @@ -96,6 +104,14 @@ + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj index 6551b0ac84ba..66eb86a7e156 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj @@ -60,6 +60,14 @@ + + + + + + + + @@ -96,6 +104,14 @@ + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.52.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.52.cs new file mode 100644 index 000000000000..4f39a52795a0 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Byte.52.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractByte52() + { + var test = new SimpleUnaryOpTest__ExtractByte52(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractByte52 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractByte52() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractByte52() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)(random.Next(0, byte.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Byte)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractByte52(); + var result = Avx.Extract(test._fld, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[20])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.27.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.27.cs new file mode 100644 index 000000000000..83d73dacf628 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int16.27.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractInt1627() + { + var test = new SimpleUnaryOpTest__ExtractInt1627(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractInt1627 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractInt1627() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractInt1627() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)(random.Next(0, short.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int16)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractInt1627(); + var result = Avx.Extract(test._fld, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[11])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.22.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.22.cs new file mode 100644 index 000000000000..bd79d925cf05 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int32.22.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractInt3222() + { + var test = new SimpleUnaryOpTest__ExtractInt3222(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractInt3222 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractInt3222() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractInt3222() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int32)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractInt3222(); + var result = Avx.Extract(test._fld, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[6])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.19.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.19.cs new file mode 100644 index 000000000000..24e72078037f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.Int64.19.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractInt6419() + { + var test = new SimpleUnaryOpTest__ExtractInt6419(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractInt6419 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractInt6419() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractInt6419() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Int64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractInt6419(); + var result = Avx.Extract(test._fld, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[3])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.52.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.52.cs new file mode 100644 index 000000000000..391703f2d9aa --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.SByte.52.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractSByte52() + { + var test = new SimpleUnaryOpTest__ExtractSByte52(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractSByte52 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractSByte52() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractSByte52() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)(random.Next(0, sbyte.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (SByte)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractSByte52(); + var result = Avx.Extract(test._fld, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[20])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.27.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.27.cs new file mode 100644 index 000000000000..9ece246b5488 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt16.27.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractUInt1627() + { + var test = new SimpleUnaryOpTest__ExtractUInt1627(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractUInt1627 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractUInt1627() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractUInt1627() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)(random.Next(0, ushort.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt16)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractUInt1627(); + var result = Avx.Extract(test._fld, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[11])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.22.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.22.cs new file mode 100644 index 000000000000..7251ef78035c --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt32.22.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractUInt3222() + { + var test = new SimpleUnaryOpTest__ExtractUInt3222(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractUInt3222 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractUInt3222() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractUInt3222() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt32)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractUInt3222(); + var result = Avx.Extract(test._fld, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[6])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.19.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.19.cs new file mode 100644 index 000000000000..d3d90d8bd66f --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Extract.UInt64.19.cs @@ -0,0 +1,309 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void ExtractUInt6419() + { + var test = new SimpleUnaryOpTest__ExtractUInt6419(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__ExtractUInt6419 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__ExtractUInt6419() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__ExtractUInt6419() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)(random.Next(0, int.MaxValue)); } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Extract( + Unsafe.Read>(_dataTable.inArrayPtr), + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Extract( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Extract( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Extract), new Type[] { typeof(Vector256), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (UInt64)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Extract( + _clsVar, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Extract(firstOp, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx.Extract(firstOp, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__ExtractUInt6419(); + var result = Avx.Extract(test._fld, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Extract(_fld, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + if ((result[0] != firstOp[3])) + { + Succeeded = false; + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Extract)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.52.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.52.cs new file mode 100644 index 000000000000..218f984165cf --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Byte.52.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertByte52() + { + var test = new SimpleUnaryOpTest__InsertByte52(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertByte52 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Byte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Byte); + + private static Byte[] _data = new Byte[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertByte52() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertByte52() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (byte)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Byte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Byte), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (byte)2, + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Byte), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)2, + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Byte), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)), + (byte)2, + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (byte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (byte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (byte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (byte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertByte52(); + var result = Avx.Insert(test._fld, (byte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (byte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Byte[] inArray = new Byte[Op1ElementCount]; + Byte[] outArray = new Byte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 20 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.27.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.27.cs new file mode 100644 index 000000000000..373db0f0238b --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int16.27.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertInt1627() + { + var test = new SimpleUnaryOpTest__InsertInt1627(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertInt1627 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int16); + + private static Int16[] _data = new Int16[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertInt1627() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertInt1627() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (short)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (short)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (short)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (short)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int16), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (short)2, + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int16), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)), + (short)2, + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int16), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)), + (short)2, + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (short)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (short)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (short)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (short)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertInt1627(); + var result = Avx.Insert(test._fld, (short)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (short)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int16[] inArray = new Int16[Op1ElementCount]; + Int16[] outArray = new Int16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 11 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.22.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.22.cs new file mode 100644 index 000000000000..9740754b8007 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int32.22.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertInt3222() + { + var test = new SimpleUnaryOpTest__InsertInt3222(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertInt3222 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int32); + + private static Int32[] _data = new Int32[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertInt3222() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertInt3222() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (int)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (int)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (int)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (int)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int32), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (int)2, + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int32), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)), + (int)2, + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int32), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)), + (int)2, + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (int)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (int)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (int)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (int)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertInt3222(); + var result = Avx.Insert(test._fld, (int)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (int)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int32[] inArray = new Int32[Op1ElementCount]; + Int32[] outArray = new Int32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 6 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.19.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.19.cs new file mode 100644 index 000000000000..012f96493d1c --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.Int64.19.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertInt6419() + { + var test = new SimpleUnaryOpTest__InsertInt6419(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertInt6419 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(Int64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(Int64); + + private static Int64[] _data = new Int64[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertInt6419() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertInt6419() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (long)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new Int64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (long)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (long)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (long)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (long)2, + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int64), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)), + (long)2, + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(Int64), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)), + (long)2, + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (long)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (long)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (long)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (long)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertInt6419(); + var result = Avx.Insert(test._fld, (long)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (long)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + Int64[] inArray = new Int64[Op1ElementCount]; + Int64[] outArray = new Int64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 3 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.52.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.52.cs new file mode 100644 index 000000000000..cbbaa73d1c20 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.SByte.52.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertSByte52() + { + var test = new SimpleUnaryOpTest__InsertSByte52(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertSByte52 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(SByte); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(SByte); + + private static SByte[] _data = new SByte[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertSByte52() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertSByte52() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (sbyte)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new SByte[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (sbyte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + (sbyte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + (sbyte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(SByte), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (sbyte)2, + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(SByte), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)), + (sbyte)2, + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(SByte), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)), + (sbyte)2, + (byte)52 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (sbyte)2, + 52 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (sbyte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (sbyte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (sbyte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertSByte52(); + var result = Avx.Insert(test._fld, (sbyte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (sbyte)2, 52); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + SByte[] inArray = new SByte[Op1ElementCount]; + SByte[] outArray = new SByte[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 20 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.27.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.27.cs new file mode 100644 index 000000000000..cff1f45bc4b9 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt16.27.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertUInt1627() + { + var test = new SimpleUnaryOpTest__InsertUInt1627(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertUInt1627 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt16); + + private static UInt16[] _data = new UInt16[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertUInt1627() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertUInt1627() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ushort)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new UInt16[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (ushort)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (ushort)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (ushort)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt16), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (ushort)2, + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt16), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)), + (ushort)2, + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt16), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)), + (ushort)2, + (byte)27 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (ushort)2, + 27 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (ushort)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (ushort)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (ushort)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertUInt1627(); + var result = Avx.Insert(test._fld, (ushort)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (ushort)2, 27); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt16[] inArray = new UInt16[Op1ElementCount]; + UInt16[] outArray = new UInt16[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 11 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.22.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.22.cs new file mode 100644 index 000000000000..e3609e8962fa --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt32.22.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertUInt3222() + { + var test = new SimpleUnaryOpTest__InsertUInt3222(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertUInt3222 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt32); + + private static UInt32[] _data = new UInt32[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertUInt3222() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertUInt3222() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (uint)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new UInt32[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (uint)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (uint)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (uint)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt32), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (uint)2, + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt32), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)), + (uint)2, + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt32), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)), + (uint)2, + (byte)22 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (uint)2, + 22 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (uint)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (uint)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (uint)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertUInt3222(); + var result = Avx.Insert(test._fld, (uint)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (uint)2, 22); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt32[] inArray = new UInt32[Op1ElementCount]; + UInt32[] outArray = new UInt32[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 6 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.19.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.19.cs new file mode 100644 index 000000000000..f60e347cadbe --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Insert.UInt64.19.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/****************************************************************************** + * This file is auto-generated from a template file by the GenerateTests.csx * + * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make * + * changes, please update the corresponding template and run according to the * + * directions listed in the file. * + ******************************************************************************/ + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; + +namespace JIT.HardwareIntrinsics.X86 +{ + public static partial class Program + { + private static void InsertUInt6419() + { + var test = new SimpleUnaryOpTest__InsertUInt6419(); + + try + { + if (test.IsSupported) + { + // Validates basic functionality works, using Unsafe.Read + test.RunBasicScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates basic functionality works, using Load + test.RunBasicScenario_Load(); + + // Validates basic functionality works, using LoadAligned + test.RunBasicScenario_LoadAligned(); + } + + // Validates calling via reflection works, using Unsafe.Read + test.RunReflectionScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates calling via reflection works, using Load + test.RunReflectionScenario_Load(); + + // Validates calling via reflection works, using LoadAligned + test.RunReflectionScenario_LoadAligned(); + } + + // Validates passing a static member works + test.RunClsVarScenario(); + + // Validates passing a local works, using Unsafe.Read + test.RunLclVarScenario_UnsafeRead(); + + if (Avx.IsSupported) + { + // Validates passing a local works, using Load + test.RunLclVarScenario_Load(); + + // Validates passing a local works, using LoadAligned + test.RunLclVarScenario_LoadAligned(); + } + + // Validates passing the field of a local works + test.RunLclFldScenario(); + + // Validates passing an instance member works + test.RunFldScenario(); + } + else + { + // Validates we throw on unsupported hardware + test.RunUnsupportedScenario(); + } + } + catch (PlatformNotSupportedException) + { + test.Succeeded = true; + } + + if (!test.Succeeded) + { + throw new Exception("One or more scenarios did not complete as expected."); + } + } + } + + public sealed unsafe class SimpleUnaryOpTest__InsertUInt6419 + { + private static readonly int LargestVectorSize = 32; + + private static readonly int Op1ElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + private static readonly int RetElementCount = Unsafe.SizeOf>() / sizeof(UInt64); + + private static UInt64[] _data = new UInt64[Op1ElementCount]; + + private static Vector256 _clsVar; + + private Vector256 _fld; + + private SimpleUnaryOpTest__DataTable _dataTable; + + static SimpleUnaryOpTest__InsertUInt6419() + { + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _clsVar), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + } + + public SimpleUnaryOpTest__InsertUInt6419() + { + Succeeded = true; + + var random = new Random(); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As, byte>(ref _fld), ref Unsafe.As(ref _data[0]), (uint)Unsafe.SizeOf>()); + + for (var i = 0; i < Op1ElementCount; i++) { _data[i] = (ulong)0; } + _dataTable = new SimpleUnaryOpTest__DataTable(_data, new UInt64[RetElementCount], LargestVectorSize); + } + + public bool IsSupported => Avx.IsSupported; + + public bool Succeeded { get; set; } + + public void RunBasicScenario_UnsafeRead() + { + var result = Avx.Insert( + Unsafe.Read>(_dataTable.inArrayPtr), + (ulong)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_Load() + { + var result = Avx.Insert( + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (ulong)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunBasicScenario_LoadAligned() + { + var result = Avx.Insert( + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (ulong)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_UnsafeRead() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt64), typeof(byte) }) + .Invoke(null, new object[] { + Unsafe.Read>(_dataTable.inArrayPtr), + (ulong)2, + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_Load() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt64), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)), + (ulong)2, + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunReflectionScenario_LoadAligned() + { + var result = typeof(Avx).GetMethod(nameof(Avx.Insert), new Type[] { typeof(Vector256), typeof(UInt64), typeof(byte) }) + .Invoke(null, new object[] { + Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)), + (ulong)2, + (byte)19 + }); + + Unsafe.Write(_dataTable.outArrayPtr, (Vector256)(result)); + ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr); + } + + public void RunClsVarScenario() + { + var result = Avx.Insert( + _clsVar, + (ulong)2, + 19 + ); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_clsVar, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_UnsafeRead() + { + var firstOp = Unsafe.Read>(_dataTable.inArrayPtr); + var result = Avx.Insert(firstOp, (ulong)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_Load() + { + var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (ulong)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclVarScenario_LoadAligned() + { + var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArrayPtr)); + var result = Avx.Insert(firstOp, (ulong)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(firstOp, _dataTable.outArrayPtr); + } + + public void RunLclFldScenario() + { + var test = new SimpleUnaryOpTest__InsertUInt6419(); + var result = Avx.Insert(test._fld, (ulong)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(test._fld, _dataTable.outArrayPtr); + } + + public void RunFldScenario() + { + var result = Avx.Insert(_fld, (ulong)2, 19); + + Unsafe.Write(_dataTable.outArrayPtr, result); + ValidateResult(_fld, _dataTable.outArrayPtr); + } + + public void RunUnsupportedScenario() + { + Succeeded = false; + + try + { + RunBasicScenario_UnsafeRead(); + } + catch (PlatformNotSupportedException) + { + Succeeded = true; + } + } + + private void ValidateResult(Vector256 firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.WriteUnaligned(ref Unsafe.As(ref inArray[0]), firstOp); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "") + { + UInt64[] inArray = new UInt64[Op1ElementCount]; + UInt64[] outArray = new UInt64[RetElementCount]; + + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref inArray[0]), ref Unsafe.AsRef(firstOp), (uint)Unsafe.SizeOf>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf>()); + + ValidateResult(inArray, outArray, method); + } + + private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "") + { + + for (var i = 0; i < RetElementCount; i++) + { + if ((i == 3 ? result[i] != 2 : result[i] != 0)) + { + Succeeded = false; + break; + } + } + + if (!Succeeded) + { + Console.WriteLine($"{nameof(Avx)}.{nameof(Avx.Insert)}(Vector256<9>): {method} failed:"); + Console.WriteLine($" firstOp: ({string.Join(", ", firstOp)})"); + Console.WriteLine($" result: ({string.Join(", ", result)})"); + Console.WriteLine(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs index dbaa1a4912db..9c52458bfab2 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Program.Avx.cs @@ -33,18 +33,26 @@ static Program() ["Extract.SByte.1"] = ExtractSByte1, ["Extract.Byte.20"] = ExtractByte20, ["Extract.SByte.20"] = ExtractSByte20, + ["Extract.Byte.52"] = ExtractByte52, + ["Extract.SByte.52"] = ExtractSByte52, ["Extract.Int16.1"] = ExtractInt161, ["Extract.UInt16.1"] = ExtractUInt161, ["Extract.Int16.11"] = ExtractInt1611, ["Extract.UInt16.11"] = ExtractUInt1611, + ["Extract.Int16.27"] = ExtractInt1627, + ["Extract.UInt16.27"] = ExtractUInt1627, ["Extract.Int32.1"] = ExtractInt321, ["Extract.UInt32.1"] = ExtractUInt321, ["Extract.Int32.6"] = ExtractInt326, ["Extract.UInt32.6"] = ExtractUInt326, + ["Extract.Int32.22"] = ExtractInt3222, + ["Extract.UInt32.22"] = ExtractUInt3222, ["Extract.Int64.1"] = ExtractInt641, ["Extract.UInt64.1"] = ExtractUInt641, ["Extract.Int64.3"] = ExtractInt643, ["Extract.UInt64.3"] = ExtractUInt643, + ["Extract.Int64.19"] = ExtractInt6419, + ["Extract.UInt64.19"] = ExtractUInt6419, ["ExtendToVector256.Byte"] = ExtendToVector256Byte, ["ExtendToVector256.Double"] = ExtendToVector256Double, ["ExtendToVector256.Int16"] = ExtendToVector256Int16, @@ -69,18 +77,26 @@ static Program() ["Insert.Byte.20"] = InsertByte20, ["Insert.SByte.1"] = InsertSByte1, ["Insert.SByte.20"] = InsertSByte20, + ["Insert.Byte.52"] = InsertByte52, + ["Insert.SByte.52"] = InsertSByte52, ["Insert.Int16.1"] = InsertInt161, ["Insert.Int16.11"] = InsertInt1611, ["Insert.UInt16.1"] = InsertUInt161, ["Insert.UInt16.11"] = InsertUInt1611, + ["Insert.Int16.27"] = InsertInt1627, + ["Insert.UInt16.27"] = InsertUInt1627, ["Insert.Int32.1"] = InsertInt321, ["Insert.Int32.6"] = InsertInt326, ["Insert.UInt32.1"] = InsertUInt321, ["Insert.UInt32.6"] = InsertUInt326, + ["Insert.Int32.22"] = InsertInt3222, + ["Insert.UInt32.22"] = InsertUInt3222, ["Insert.Int64.1"] = InsertInt641, ["Insert.Int64.3"] = InsertInt643, ["Insert.UInt64.1"] = InsertUInt641, ["Insert.UInt64.3"] = InsertUInt643, + ["Insert.Int64.19"] = InsertInt6419, + ["Insert.UInt64.19"] = InsertUInt6419, ["InsertVector128.Byte.1.Load"] = InsertVector128Byte1Load, ["InsertVector128.SByte.1.Load"] = InsertVector128SByte1Load, ["InsertVector128.Int16.1.Load"] = InsertVector128Int161Load, diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256.cs new file mode 100644 index 000000000000..cfe3b841d543 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256.cs @@ -0,0 +1,241 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; + +namespace IntelHardwareIntrinsicTest +{ + class Program + { + const int Pass = 100; + const int Fail = 0; + + static unsafe int Main(string[] args) + { + int testResult = Pass; + + if (Avx.IsSupported) + { + using (TestTable floatTable = new TestTable(new float[8] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN })) + { + var vf1 = Avx.SetAllVector256(-5); + Unsafe.Write(floatTable.outArrayPtr, vf1); + + if (!floatTable.CheckResult((x) => (x == -5))) + { + Console.WriteLine("AVX SetAllVector256 failed on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable doubleTable = new TestTable(new double[4] { double.NaN, double.NaN, double.NaN, double.NaN })) + { + var vf1 = Avx.SetAllVector256(3); + Unsafe.Write(doubleTable.outArrayPtr, vf1); + + if (!doubleTable.CheckResult((x) => (x == 3))) + { + Console.WriteLine("AVX SetAllVector256 failed on double:"); + foreach (var item in doubleTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable sbyteTable = new TestTable(new sbyte[32] { sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, + sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, + sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, + sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue })) + { + var vf1 = Avx.SetAllVector256(100); + Unsafe.Write(sbyteTable.outArrayPtr, vf1); + + if (!sbyteTable.CheckResult((x) => (x == 100))) + { + Console.WriteLine("AVX SetAllVector256 failed on sbyte:"); + foreach (var item in sbyteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable byteTable = new TestTable(new byte[32] { byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, + byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, + byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, + byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue })) + { + Vector256 vf1 = Avx.SetAllVector256(4); + Unsafe.Write(byteTable.outArrayPtr, vf1); + + if (!byteTable.CheckResult((x) => (x == 4))) + { + Console.WriteLine("AVX SetAllVector256 failed on byte:"); + foreach (var item in byteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable shortTable = new TestTable(new short[16] { short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, + short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue })) + { + var vf1 = Avx.SetAllVector256(-5); + Unsafe.Write(shortTable.outArrayPtr, vf1); + + if (!shortTable.CheckResult((x) => (x == -5))) + { + Console.WriteLine("AVX SetAllVector256 failed on short:"); + foreach (var item in shortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable ushortTable = new TestTable(new ushort[16] { ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, + ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue })) + { + Vector256 vf1 = Avx.SetAllVector256(2); + Unsafe.Write(ushortTable.outArrayPtr, vf1); + + if (!ushortTable.CheckResult((x) => (x == 2))) + { + Console.WriteLine("AVX SetAllVector256 failed on ushort:"); + foreach (var item in ushortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable intTable = new TestTable(new int[8] { int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue })) + { + var vf1 = Avx.SetAllVector256(-5); + Unsafe.Write(intTable.outArrayPtr, vf1); + + if (!intTable.CheckResult((x) => (x == -5))) + { + Console.WriteLine("AVX SetAllVector256 failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable uintTable = new TestTable(new uint[8] { uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue })) + { + Vector256 vf1 = Avx.SetAllVector256(3); + Unsafe.Write(uintTable.outArrayPtr, vf1); + + if (!uintTable.CheckResult((x) => (x == 3))) + { + Console.WriteLine("AVX SetAllVector256 failed on uint:"); + foreach (var item in uintTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + if (Environment.Is64BitProcess) + { + using (TestTable longTable = new TestTable(new long[4] { long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue })) + { + var vf1 = Avx.SetAllVector256(-199); + Unsafe.Write(longTable.outArrayPtr, vf1); + + if (!longTable.CheckResult((x) => (x == -199))) + { + Console.WriteLine("AVX SetAllVector256 failed on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable ulongTable = new TestTable(new ulong[4] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue })) + { + Vector256 vf1 = Avx.SetAllVector256(34); + Unsafe.Write(ulongTable.outArrayPtr, vf1); + + if (!ulongTable.CheckResult((x) => (x == 34))) + { + Console.WriteLine("AVX SetAllVector256 failed on ulong:"); + foreach (var item in ulongTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + } + } + + return testResult; + } + + public unsafe struct TestTable : IDisposable where T : struct + { + public T[] outArray; + + public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); + + GCHandle outHandle; + public TestTable(T[] a) + { + this.outArray = a; + + outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); + } + public bool CheckResult(Func check) + { + foreach (var item in outArray) + { + if (!check(item)) + { + return false; + } + } + return true; + } + + public void Dispose() + { + outHandle.Free(); + } + } + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256_r.csproj new file mode 100644 index 000000000000..7864a8f75900 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256_r.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256_ro.csproj new file mode 100644 index 000000000000..da79454a83b9 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetAllVector256_ro.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + True + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256.cs new file mode 100644 index 000000000000..90e89c6f67e4 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256.cs @@ -0,0 +1,258 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Runtime.Intrinsics.X86; +using System.Runtime.Intrinsics; + +namespace IntelHardwareIntrinsicTest +{ + class Program + { + const int Pass = 100; + const int Fail = 0; + + static unsafe int Main(string[] args) + { + int testResult = Pass; + + if (Avx.IsSupported) + { + using (TestTable floatTable = new TestTable(new float[8] { float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN, float.NaN })) + { + var vf1 = Avx.SetVector256((float)1, -5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(floatTable.outArrayPtr, vf1); + + if (!floatTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == -5) && (x[7] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on float:"); + foreach (var item in floatTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable doubleTable = new TestTable(new double[4] { double.NaN, double.NaN, double.NaN, double.NaN })) + { + var vf1 = Avx.SetVector256((double)1, 2, 3, 4); + Unsafe.Write(doubleTable.outArrayPtr, vf1); + + if (!doubleTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on double:"); + foreach (var item in doubleTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable sbyteTable = new TestTable(new sbyte[32] { sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, + sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, + sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, + sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue, sbyte.MaxValue })) + { + var vf1 = Avx.SetVector256(1, -5, 100, 0, 1, 2, 3, 4, 1, -5, 100, 0, 1, 2, 3, 4, 1, -5, 100, 0, 1, 2, 3, 4, 1, -5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(sbyteTable.outArrayPtr, vf1); + + if (!sbyteTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == -5) && (x[7] == 1) && + (x[8] == 4) && (x[9] == 3) && (x[10] == 2) && (x[11] == 1) && + (x[12] == 0) && (x[13] == 100) && (x[14] == -5) && (x[15] == 1) && + (x[16] == 4) && (x[17] == 3) && (x[18] == 2) && (x[19] == 1) && + (x[20] == 0) && (x[21] == 100) && (x[22] == -5) && (x[23] == 1) && + (x[24] == 4) && (x[25] == 3) && (x[26] == 2) && (x[27] == 1) && + (x[28] == 0) && (x[29] == 100) && (x[30] == -5) && (x[31] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on sbyte:"); + foreach (var item in sbyteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable byteTable = new TestTable(new byte[32] { byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, + byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, + byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, + byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue, byte.MaxValue })) + { + Vector256 vf1 = Avx.SetVector256((byte)1, 5, 100, 0, 1, 2, 3, 4, 1, 5, 100, 0, 1, 2, 3, 4, 1, 5, 100, 0, 1, 2, 3, 4, 1, 5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(byteTable.outArrayPtr, vf1); + + if (!byteTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == 5) && (x[7] == 1) && + (x[8] == 4) && (x[9] == 3) && (x[10] == 2) && (x[11] == 1) && + (x[12] == 0) && (x[13] == 100) && (x[14] == 5) && (x[15] == 1) && + (x[16] == 4) && (x[17] == 3) && (x[18] == 2) && (x[19] == 1) && + (x[20] == 0) && (x[21] == 100) && (x[22] == 5) && (x[23] == 1) && + (x[24] == 4) && (x[25] == 3) && (x[26] == 2) && (x[27] == 1) && + (x[28] == 0) && (x[29] == 100) && (x[30] == 5) && (x[31] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on byte:"); + foreach (var item in byteTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable shortTable = new TestTable(new short[16] { short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, + short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue, short.MaxValue })) + { + var vf1 = Avx.SetVector256(1, -5, 100, 0, 1, 2, 3, 4, 1, -5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(shortTable.outArrayPtr, vf1); + + if (!shortTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == -5) && (x[7] == 1) && + (x[8] == 4) && (x[9] == 3) && (x[10] == 2) && (x[11] == 1) && + (x[12] == 0) && (x[13] == 100) && (x[14] == -5) && (x[15] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on short:"); + foreach (var item in shortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable ushortTable = new TestTable(new ushort[16] { ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, + ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue })) + { + Vector256 vf1 = Avx.SetVector256((ushort)1, 5, 100, 0, 1, 2, 3, 4, 1, 5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(ushortTable.outArrayPtr, vf1); + + if (!ushortTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == 5) && (x[7] == 1) && + (x[8] == 4) && (x[9] == 3) && (x[10] == 2) && (x[11] == 1) && + (x[12] == 0) && (x[13] == 100) && (x[14] == 5) && (x[15] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on ushort:"); + foreach (var item in ushortTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable intTable = new TestTable(new int[8] { int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue })) + { + var vf1 = Avx.SetVector256(1, -5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(intTable.outArrayPtr, vf1); + + if (!intTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == -5) && (x[7] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on int:"); + foreach (var item in intTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable uintTable = new TestTable(new uint[8] { uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue, uint.MaxValue })) + { + Vector256 vf1 = Avx.SetVector256((uint)1, 5, 100, 0, 1, 2, 3, 4); + Unsafe.Write(uintTable.outArrayPtr, vf1); + + if (!uintTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1) && + (x[4] == 0) && (x[5] == 100) && (x[6] == 5) && (x[7] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on uint:"); + foreach (var item in uintTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + if (Environment.Is64BitProcess) + { + using (TestTable longTable = new TestTable(new long[4] { long.MaxValue, long.MaxValue, long.MaxValue, long.MaxValue })) + { + var vf1 = Avx.SetVector256(1, 2, 3, 4); + Unsafe.Write(longTable.outArrayPtr, vf1); + + if (!longTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on long:"); + foreach (var item in longTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + + using (TestTable ulongTable = new TestTable(new ulong[4] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue })) + { + Vector256 vf1 = Avx.SetVector256((ulong)1, 2, 3, 4); + Unsafe.Write(ulongTable.outArrayPtr, vf1); + + if (!ulongTable.CheckResult((x) => (x[0] == 4) && (x[1] == 3) && (x[2] == 2) && (x[3] == 1))) + { + Console.WriteLine("AVX SetVector256 failed on ulong:"); + foreach (var item in ulongTable.outArray) + { + Console.Write(item + ", "); + } + Console.WriteLine(); + testResult = Fail; + } + } + } + } + + return testResult; + } + + public unsafe struct TestTable : IDisposable where T : struct + { + public T[] outArray; + + public void* outArrayPtr => outHandle.AddrOfPinnedObject().ToPointer(); + + GCHandle outHandle; + public TestTable(T[] a) + { + this.outArray = a; + + outHandle = GCHandle.Alloc(outArray, GCHandleType.Pinned); + } + public bool CheckResult(Func check) + { + return check(outArray); + } + + public void Dispose() + { + outHandle.Free(); + } + } + + } +} diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256_r.csproj new file mode 100644 index 000000000000..5bcc47e3f3d4 --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256_r.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256_ro.csproj new file mode 100644 index 000000000000..be90a4846ded --- /dev/null +++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/SetVector256_ro.csproj @@ -0,0 +1,34 @@ + + + + + Debug + AnyCPU + 2.0 + {95DFC527-4DC1-495E-97D7-E94EE1F7140D} + Exe + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + ..\..\ + true + + + + + + + False + + + + None + True + + + + + + + + + + diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx index 6a5c8abf64e0..101300b81b9e 100644 --- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx +++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx @@ -423,18 +423,26 @@ private static readonly (string templateFileName, Dictionary tem ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "20", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[20])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "20", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[20])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Imm"] = "52", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[20])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Imm"] = "52", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[20])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[11])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[11])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Imm"] = "27", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[11])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Imm"] = "27", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ushort)(random.Next(0, ushort.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[11])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[6])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[6])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Imm"] = "22", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[6])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Imm"] = "22", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[6])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[1])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[3])"}), ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[3])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Imm"] = "19", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(long)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[3])"}), + ("ExtractScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Extract", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Imm"] = "19", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ulong)(random.Next(0, int.MaxValue))", ["ValidateFirstResult"] = "(result[0] != firstOp[3])"}), ("GenericUnOpTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}), ("GenericUnOpTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Double", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(double)(random.NextDouble())", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}), ("GenericUnOpTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Sse2",["Method"] = "ExtendToVector256", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Int16", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(short.MinValue, short.MaxValue))", ["ValidateFirstResult"] = "firstOp[0] != result[0]", ["ValidateRemainingResults"] = "result[i] != ((i < (RetElementCount / 2)) ? firstOp[i] : 0)"}), @@ -459,18 +467,26 @@ private static readonly (string templateFileName, Dictionary tem ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "20", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(byte)0", ["ValidateFirstResult"] = "(i == 20 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "20", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 20 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Byte", ["Data"] = "(byte)2", ["Imm"] = "52", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(byte)0", ["ValidateFirstResult"] = "(i == 20 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "SByte", ["Data"] = "(sbyte)2", ["Imm"] = "52", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)0", ["ValidateFirstResult"] = "(i == 20 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 11 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2",["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2",["Imm"] = "11", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 11 ? result[i] != 2 : result[i] != 0)"}), - ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), - ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}), - ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), - ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int16", ["Data"] = "(short)2", ["Imm"] = "27", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)0", ["ValidateFirstResult"] = "(i == 11 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt16", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt16", ["Data"] = "(ushort)2",["Imm"] = "27", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ushort)0", ["ValidateFirstResult"] = "(i == 11 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "6", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int32", ["Data"] = "(int)2", ["Imm"] = "22", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(int)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt32", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt32", ["Data"] = "(uint)2", ["Imm"] = "22", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(uint)0", ["ValidateFirstResult"] = "(i == 6 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 3 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 1 ? result[i] != 2 : result[i] != 0)"}), ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "3", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 3 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "Int64", ["Data"] = "(long)2", ["Imm"] = "19", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(long)0", ["ValidateFirstResult"] = "(i == 3 ? result[i] != 2 : result[i] != 0)"}), + ("InsertScalarTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "Insert", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "UInt64", ["Op1VectorType"] ="Vector256", ["Op1BaseType"] = "UInt64", ["Data"] = "(ulong)2", ["Imm"] = "19", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(ulong)0", ["ValidateFirstResult"] = "(i == 3 ? result[i] != 2 : result[i] != 0)"}), ("InsertLoadTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(byte)(random.Next(0, byte.MaxValue))", ["NextValueOp2"] = "(byte)(random.Next(0, byte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}), ("InsertLoadTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(sbyte)(random.Next(0, sbyte.MaxValue))", ["NextValueOp2"] = "(sbyte)(random.Next(0,sbyte.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 15 ? result[i] != right[i - 16] : result[i] != left[i])"}), ("InsertLoadTest.template", new Dictionary { ["Isa"] = "Avx", ["LoadIsa"] = "Avx", ["Method"] = "InsertVector128", ["RetVectorType"] = "Vector256", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector256", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Int16", ["Imm"] = "1", ["LargestVectorSize"] = "32", ["NextValueOp1"] = "(short)(random.Next(0, short.MaxValue))", ["NextValueOp2"] = "(short)(random.Next(0,short.MaxValue))", ["ValidateFirstResult"] = "result[0] != left[0]", ["ValidateRemainingResults"] = "(i > 7 ? result[i] != right[i - 8] : result[i] != left[i])"}),