Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding basic support for recognizing and handling SIMD intrinsics as HW intrinsics #35421

Merged
merged 40 commits into from
May 5, 2020
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
703ab93
Adding basic support for recognizing and handling SIMD intrinsics as …
tannergooding Apr 23, 2020
32209f3
Applying formatting patch
tannergooding Apr 24, 2020
a5ad01c
Fixing a preprocessor concatenation for non windows
tannergooding Apr 24, 2020
3b5f8f4
Add a default case to workaround a compiler warning on FreeBSD
tannergooding Apr 24, 2020
8744b7b
Fixing a noway_assert to include GT_HWINTRINSIC
tannergooding Apr 24, 2020
4beacab
Fixing some asserts that were being triggered
tannergooding Apr 24, 2020
3af99b2
Use getSIMDVectorRegisterByteLength
tannergooding Apr 25, 2020
e229ca0
Applying formatting patch
tannergooding Apr 25, 2020
92ec83c
Fixing ARM64 to use the actual type size
tannergooding Apr 25, 2020
e9e7b89
Removing the [Intrinsic] attribute from some Vector2/3/4 methods whic…
tannergooding Apr 25, 2020
f788049
Updating SSE/SSE2 CompareGreaterThan and related functions to be tabl…
tannergooding Apr 25, 2020
0cf2a0b
Fixing the SimdAsHWIntrinsic relational operations to match the GT_SI…
tannergooding Apr 25, 2020
10e7235
Ensure that GT_HWINTRINSIC fixes the type for certain TYP_SIMD8
tannergooding Apr 25, 2020
9022d94
Fixing the SimdAsHWIntrinsic Vector<int>.op_Multiply support to match…
tannergooding Apr 26, 2020
16048cd
Fixing the SimdAsHWIntrinsic Vector2/3 Division to match the GT_SIMD …
tannergooding Apr 26, 2020
82d646e
Porting Abs, Min, and Max to use the SimdAsHWIntrinsic support
tannergooding Apr 26, 2020
ed399c4
Minor fixups to the SSE2 codepath
tannergooding Apr 26, 2020
1e57f6e
Applying formatting patch
tannergooding Apr 26, 2020
aaa9962
Fixing a check in lowering
tannergooding Apr 26, 2020
d22ecab
Mark SimdAsHWIntrinsic nodes so we can lookup the correct handle
tannergooding Apr 27, 2020
5830101
Adding the 3 operand overload for gtNewSimdAsHWIntrinsicNode
tannergooding Apr 27, 2020
4f02f57
Fixing BuildHWIntrinsic to properly take RMW into account
tannergooding Apr 28, 2020
39f5086
Fixing the rationalize handling of GT_HWINTRINSIC to account for SIMD…
tannergooding Apr 28, 2020
fe969fd
Fixing the importer to not create SIMD nodes if featureSIMD is disabled
tannergooding Apr 28, 2020
bf291c5
Fixing the SSE4.2 implementation of CompareLessThan<long>
tannergooding Apr 28, 2020
ef4a77c
Preserve the base type for subtraction/addition operations
tannergooding Apr 29, 2020
e1b5acb
Applying formatting patch
tannergooding Apr 29, 2020
1b837a6
Responding to PR feedback
tannergooding Apr 29, 2020
ac867ec
Fixing a copy/paste error under reinterpret cast
tannergooding Apr 30, 2020
7482c49
Fixing abs to expect 1 argument
tannergooding May 1, 2020
c7ef80d
Adding method comment headers that were missing
tannergooding May 1, 2020
e569d25
Removing unused table entries from SimdAsHWIntrinsic for Vector2/3/4
tannergooding May 1, 2020
991a838
Ensure we catch intrinsics from the Vector static class
tannergooding May 1, 2020
017fe54
Fixing SSSE3_Abs and AVX2_Abs to get the base type from the first arg…
tannergooding May 1, 2020
06bec3e
Ensure we adjust the class handle used for intrinsics from the Vector…
tannergooding May 1, 2020
bd6e87a
Ensure we populate the handle cache for clsHnd even if it isn't used
tannergooding May 1, 2020
341aac8
Fix where we grab the base type from for the static Vector class
tannergooding May 2, 2020
b6494ee
Fixing ConditionalSelect and improving the messages used for impClone…
tannergooding May 2, 2020
470f627
Ensure we clone the constVectorDup before using it
tannergooding May 2, 2020
03840fa
Applying formatting patch
tannergooding May 3, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions src/coreclr/src/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ if (CLR_CMAKE_TARGET_WIN32)
regset.h
sideeffects.h
simd.h
simdashwintrinsic.h
simdintrinsiclist.h
sm.h
smallhash.h
Expand Down Expand Up @@ -204,14 +205,16 @@ if (CLR_CMAKE_TARGET_WIN32)
instrsarm.h
instrsarm64.h
registerarm.h
registerarm64.h)
registerarm64.h
simdashwintrinsiclistarm64.h)
elseif (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_I386)
list (APPEND JIT_HEADERS
emitfmtsxarch.h
emitxarch.h
hwintrinsiclistxarch.h
hwintrinsic.h
instrsxarch.h)
instrsxarch.h
simdashwintrinsiclistxarch.h)
endif ()
endif(CLR_CMAKE_TARGET_WIN32)

Expand All @@ -223,6 +226,7 @@ set( JIT_AMD64_SOURCES
lowerxarch.cpp
lsraxarch.cpp
simd.cpp
simdashwintrinsic.cpp
simdcodegenxarch.cpp
targetamd64.cpp
unwindamd64.cpp
Expand All @@ -249,6 +253,7 @@ set( JIT_I386_SOURCES
lowerxarch.cpp
lsraxarch.cpp
simd.cpp
simdashwintrinsic.cpp
simdcodegenxarch.cpp
targetx86.cpp
unwindx86.cpp
Expand All @@ -264,6 +269,7 @@ set( JIT_ARM64_SOURCES
lsraarmarch.cpp
lsraarm64.cpp
simd.cpp
simdashwintrinsic.cpp
targetarm64.cpp
unwindarm.cpp
unwindarm64.cpp
Expand Down
64 changes: 62 additions & 2 deletions src/coreclr/src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

#include "hwintrinsic.h"
#include "simd.h"
#include "simdashwintrinsic.h"

// This is only used locally in the JIT to indicate that
// a verification block should be inserted
Expand Down Expand Up @@ -2609,6 +2610,36 @@ class Compiler
NamedIntrinsic hwIntrinsicID,
var_types baseType,
unsigned size);

GenTreeHWIntrinsic* gtNewSimdAsHWIntrinsicNode(
var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size)
{
GenTreeHWIntrinsic* node = gtNewSimdHWIntrinsicNode(type, op1, hwIntrinsicID, baseType, size);
node->gtFlags |= GTF_SIMDASHW_OP;
return node;
}

GenTreeHWIntrinsic* gtNewSimdAsHWIntrinsicNode(
var_types type, GenTree* op1, GenTree* op2, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size)
{
GenTreeHWIntrinsic* node = gtNewSimdHWIntrinsicNode(type, op1, op2, hwIntrinsicID, baseType, size);
node->gtFlags |= GTF_SIMDASHW_OP;
return node;
}

GenTreeHWIntrinsic* gtNewSimdAsHWIntrinsicNode(var_types type,
GenTree* op1,
GenTree* op2,
GenTree* op3,
NamedIntrinsic hwIntrinsicID,
var_types baseType,
unsigned size)
{
GenTreeHWIntrinsic* node = gtNewSimdHWIntrinsicNode(type, op1, op2, op3, hwIntrinsicID, baseType, size);
node->gtFlags |= GTF_SIMDASHW_OP;
return node;
}

GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID);
GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(var_types type,
GenTree* op1,
Expand Down Expand Up @@ -3679,16 +3710,36 @@ class Compiler
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
bool mustExpand);
GenTree* impSimdAsHWIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig,
bool mustExpand);

protected:
bool compSupportsHWIntrinsic(CORINFO_InstructionSet isa);

GenTree* impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_SIG_INFO* sig,
var_types retType,
var_types baseType,
unsigned simdSize);

GenTree* impSimdAsHWIntrinsicCndSel(CORINFO_CLASS_HANDLE clsHnd,
var_types retType,
var_types baseType,
unsigned simdSize,
GenTree* op1,
GenTree* op2,
GenTree* op3);

GenTree* impSpecialIntrinsic(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
CORINFO_METHOD_HANDLE method,
CORINFO_SIG_INFO* sig);

GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass);
GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass, bool expectAddr = false);
GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType);
GenTree* addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* lastOp, bool mustExpand, int immUpperBound);

Expand All @@ -3702,6 +3753,13 @@ class Compiler
GenTree* impAvxOrAvx2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);
GenTree* impBMI1OrBMI2Intrinsic(NamedIntrinsic intrinsic, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO* sig);

GenTree* impSimdAsHWIntrinsicRelOp(NamedIntrinsic intrinsic,
CORINFO_CLASS_HANDLE clsHnd,
var_types retType,
var_types baseType,
unsigned simdSize,
GenTree* op1,
GenTree* op2);
#endif // TARGET_XARCH
#endif // FEATURE_HW_INTRINSICS
GenTree* impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
Expand Down Expand Up @@ -8154,8 +8212,9 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
return emitTypeSize(TYP_SIMD8);
}

public:
// Returns the codegen type for a given SIMD size.
var_types getSIMDTypeForSize(unsigned size)
static var_types getSIMDTypeForSize(unsigned size)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also change GenTreeHWIntrinsic to track the SimdType rather than the SimdSize, but it is a more involved change.

{
var_types simdType = TYP_UNDEF;
if (size == 8)
Expand All @@ -8181,6 +8240,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
return simdType;
}

private:
unsigned getSIMDInitTempVarNum()
{
if (lvaSIMDInitTempVarNum == BAD_VAR_NUM)
Expand Down
11 changes: 5 additions & 6 deletions src/coreclr/src/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22298,12 +22298,11 @@ void Compiler::fgNoteNonInlineCandidate(Statement* stmt, GenTreeCall* call)
*/
GenTree* Compiler::fgGetStructAsStructPtr(GenTree* tree)
{
noway_assert((tree->gtOper == GT_LCL_VAR) || (tree->gtOper == GT_FIELD) || (tree->gtOper == GT_IND) ||
(tree->gtOper == GT_BLK) || (tree->gtOper == GT_OBJ) || tree->OperIsSIMD() ||
// tree->gtOper == GT_CALL || cannot get address of call.
// tree->gtOper == GT_MKREFANY || inlining should've been aborted due to mkrefany opcode.
// tree->gtOper == GT_RET_EXPR || cannot happen after fgUpdateInlineReturnExpressionPlaceHolder
(tree->gtOper == GT_COMMA));
noway_assert(tree->OperIs(GT_LCL_VAR, GT_FIELD, GT_IND, GT_BLK, GT_OBJ, GT_COMMA) || tree->OperIsSIMD() ||
tree->OperIsHWIntrinsic());
// GT_CALL, cannot get address of call.
// GT_MKREFANY, inlining should've been aborted due to mkrefany opcode.
// GT_RET_EXPR, cannot happen after fgUpdateInlineReturnExpressionPlaceHolder

switch (tree->OperGet())
{
Expand Down
15 changes: 14 additions & 1 deletion src/coreclr/src/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17197,6 +17197,12 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree)
if (varTypeIsSIMD(tree))
{
structHnd = gtGetStructHandleForSIMD(tree->gtType, TYP_FLOAT);
#ifdef FEATURE_HW_INTRINSICS
if (structHnd == NO_CLASS_HANDLE)
{
structHnd = gtGetStructHandleForHWSIMD(tree->gtType, TYP_FLOAT);
}
#endif
}
#endif
break;
Expand Down Expand Up @@ -17263,7 +17269,14 @@ CORINFO_CLASS_HANDLE Compiler::gtGetStructHandleIfPresent(GenTree* tree)
#endif // FEATURE_SIMD
#ifdef FEATURE_HW_INTRINSICS
case GT_HWINTRINSIC:
structHnd = gtGetStructHandleForHWSIMD(tree->gtType, tree->AsHWIntrinsic()->gtSIMDBaseType);
if ((tree->gtFlags & GTF_SIMDASHW_OP) != 0)
{
structHnd = gtGetStructHandleForSIMD(tree->gtType, tree->AsHWIntrinsic()->gtSIMDBaseType);
}
else
{
structHnd = gtGetStructHandleForHWSIMD(tree->gtType, tree->AsHWIntrinsic()->gtSIMDBaseType);
}
break;
#endif
break;
Expand Down
5 changes: 4 additions & 1 deletion src/coreclr/src/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ struct GenTree

#define GTF_UNSIGNED 0x00008000 // With GT_CAST: the source operand is an unsigned type
// With operators: the specified node is an unsigned operator
//
//
#define GTF_LATE_ARG 0x00010000 // The specified node is evaluated to a temp in the arg list, and this temp is added to gtCallLateArgs.
#define GTF_SPILL 0x00020000 // Needs to be spilled here

Expand Down Expand Up @@ -913,6 +913,9 @@ struct GenTree
#define GTF_SIMD12_OP 0x80000000 // GT_SIMD -- Indicates that the operands need to be handled as SIMD12
// even if they have been retyped as SIMD16.

#define GTF_SIMDASHW_OP 0x80000000 // GT_HWINTRINSIC -- Indicates that the structHandle should be gotten from gtGetStructHandleForSIMD
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was looking at resolving the struct handle issue (called out #35421 (comment)) differently at first. As far as the JIT needs to be concerned, there isn't really a difference between two TYP_SIMD of the same size until it needs to pass/return the value, at which point Vector4 and Vector128<float> are handled differently.

However, recognizing this is non-trivial and so I went with the simpler approach of just flagging the operation as taking/returning System.Numerics vector types so we can call the right lookup method for the struct handle.

Unlike GT_SIMD, we don't need to track whether it is SIMD12 (even if retyped to SIMD16) because we don't require any special codegen handling (all the relevant fixups are handled in importation) so we can just reuse the same flag value here.

// rarther than from gtGetStructHandleForHWSIMD.

//---------------------------------------------------------------------
//
// GenTree flags stored in gtDebugFlags.
Expand Down
15 changes: 8 additions & 7 deletions src/coreclr/src/jit/hwintrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -494,26 +494,27 @@ bool HWIntrinsicInfo::isImmOp(NamedIntrinsic id, const GenTree* op)
}

//------------------------------------------------------------------------
// // getArgForHWIntrinsic: pop an argument from the stack and validate its type
// getArgForHWIntrinsic: pop an argument from the stack and validate its type
//
// Arguments:
// argType -- the required type of argument
// argClass -- the class handle of argType
// argType -- the required type of argument
// argClass -- the class handle of argType
// expectAddr -- if true indicates we are expecting type stack entry to be a TYP_BYREF.
//
// Return Value:
// the validated argument
//
GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass)
GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass, bool expectAddr)
{
GenTree* arg = nullptr;
if (argType == TYP_STRUCT)
{
unsigned int argSizeBytes;
var_types base = getBaseTypeAndSizeOfSIMDType(argClass, &argSizeBytes);
argType = getSIMDTypeForSize(argSizeBytes);
assert((argType == TYP_SIMD8) || (argType == TYP_SIMD16) || (argType == TYP_SIMD32));
arg = impSIMDPopStack(argType);
assert((arg->TypeGet() == TYP_SIMD8) || (arg->TypeGet() == TYP_SIMD16) || (arg->TypeGet() == TYP_SIMD32));
assert(varTypeIsSIMD(argType));
arg = impSIMDPopStack(argType, expectAddr);
assert(varTypeIsSIMD(arg->TypeGet()));
}
else
{
Expand Down
66 changes: 45 additions & 21 deletions src/coreclr/src/jit/hwintrinsic.h
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ struct HWIntrinsicInfo
}

#ifdef TARGET_XARCH
static int lookupIval(NamedIntrinsic id)
static int lookupIval(NamedIntrinsic id, bool opportunisticallyDependsOnAVX)
{
switch (id)
{
Expand All @@ -325,6 +325,17 @@ struct HWIntrinsicInfo
case NI_SSE_CompareScalarGreaterThan:
case NI_SSE2_CompareGreaterThan:
case NI_SSE2_CompareScalarGreaterThan:
case NI_AVX_CompareGreaterThan:
{
if (opportunisticallyDependsOnAVX)
{
return static_cast<int>(FloatComparisonMode::OrderedGreaterThanSignaling);
}

assert(id != NI_AVX_CompareGreaterThan);
return static_cast<int>(FloatComparisonMode::OrderedLessThanSignaling);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be confusing to someone who doesn't know that we expect later in the JIT to swap the intrinsic arguments.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, it would be clearer to leave these as special import intrinsics and move all the plumbing related to opportunisticallyDependsOnAVX to one place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add a comment, but the entire point of moving it to lowering is so the rest of the JIT doesn't need to care that AVX supports proper GreaterThan while Pre-AVX emulates it.

As we continue adding more JIT optimizations around HWIntrinsics, the distinction doesn't matter to anything except for codegen and so handling the fixup in lowering makes this trivial for everything else.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will submit a follow up PR that adds the comment.

}

case NI_SSE_CompareLessThan:
case NI_SSE_CompareScalarLessThan:
case NI_SSE2_CompareLessThan:
Expand All @@ -338,6 +349,17 @@ struct HWIntrinsicInfo
case NI_SSE_CompareScalarGreaterThanOrEqual:
case NI_SSE2_CompareGreaterThanOrEqual:
case NI_SSE2_CompareScalarGreaterThanOrEqual:
case NI_AVX_CompareGreaterThanOrEqual:
{
if (opportunisticallyDependsOnAVX)
{
return static_cast<int>(FloatComparisonMode::OrderedGreaterThanOrEqualSignaling);
}

assert(id != NI_AVX_CompareGreaterThanOrEqual);
return static_cast<int>(FloatComparisonMode::OrderedLessThanOrEqualSignaling);
}

case NI_SSE_CompareLessThanOrEqual:
case NI_SSE_CompareScalarLessThanOrEqual:
case NI_SSE2_CompareLessThanOrEqual:
Expand All @@ -360,6 +382,17 @@ struct HWIntrinsicInfo
case NI_SSE_CompareScalarNotGreaterThan:
case NI_SSE2_CompareNotGreaterThan:
case NI_SSE2_CompareScalarNotGreaterThan:
case NI_AVX_CompareNotGreaterThan:
{
if (opportunisticallyDependsOnAVX)
{
return static_cast<int>(FloatComparisonMode::UnorderedNotGreaterThanSignaling);
}

assert(id != NI_AVX_CompareNotGreaterThan);
return static_cast<int>(FloatComparisonMode::UnorderedNotLessThanSignaling);
}

case NI_SSE_CompareNotLessThan:
case NI_SSE_CompareScalarNotLessThan:
case NI_SSE2_CompareNotLessThan:
Expand All @@ -373,6 +406,17 @@ struct HWIntrinsicInfo
case NI_SSE_CompareScalarNotGreaterThanOrEqual:
case NI_SSE2_CompareNotGreaterThanOrEqual:
case NI_SSE2_CompareScalarNotGreaterThanOrEqual:
case NI_AVX_CompareNotGreaterThanOrEqual:
{
if (opportunisticallyDependsOnAVX)
{
return static_cast<int>(FloatComparisonMode::UnorderedNotGreaterThanOrEqualSignaling);
}

assert(id != NI_AVX_CompareNotGreaterThanOrEqual);
return static_cast<int>(FloatComparisonMode::UnorderedNotLessThanOrEqualSignaling);
}

case NI_SSE_CompareNotLessThanOrEqual:
case NI_SSE_CompareScalarNotLessThanOrEqual:
case NI_SSE2_CompareNotLessThanOrEqual:
Expand Down Expand Up @@ -441,26 +485,6 @@ struct HWIntrinsicInfo
return static_cast<int>(FloatRoundingMode::ToZero);
}

case NI_AVX_CompareGreaterThan:
{
return static_cast<int>(FloatComparisonMode::OrderedGreaterThanSignaling);
}

case NI_AVX_CompareGreaterThanOrEqual:
{
return static_cast<int>(FloatComparisonMode::OrderedGreaterThanOrEqualSignaling);
}

case NI_AVX_CompareNotGreaterThan:
{
return static_cast<int>(FloatComparisonMode::UnorderedNotGreaterThanSignaling);
}

case NI_AVX_CompareNotGreaterThanOrEqual:
{
return static_cast<int>(FloatComparisonMode::UnorderedNotGreaterThanOrEqualSignaling);
}

default:
{
return -1;
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
}
else
{
emitSize = EA_SIZE(node->gtSIMDSize);
emitSize = emitActualTypeSize(Compiler::getSIMDTypeForSize(node->gtSIMDSize));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? To support Vector3 on Arm64?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, its required to support Vector3 as it is size = 12 but actualSize = 16

opt = genGetSimdInsOpt(emitSize, intrin.baseType);

if ((opt == INS_OPTS_1D) && (intrin.category == HW_Category_SimpleSIMD))
Expand Down
Loading