-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Add basic support for TYP_MASK
constants
#99743
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3406,6 +3406,13 @@ unsigned Compiler::gtHashValue(GenTree* tree) | |
{ | ||
#if defined(FEATURE_SIMD) | ||
#if defined(TARGET_XARCH) | ||
case TYP_MASK: | ||
{ | ||
add = genTreeHashAdd(ulo32(add), vecCon->gtSimdVal.u32[1]); | ||
add = genTreeHashAdd(ulo32(add), vecCon->gtSimdVal.u32[0]); | ||
break; | ||
} | ||
|
||
case TYP_SIMD64: | ||
{ | ||
add = genTreeHashAdd(ulo32(add), vecCon->gtSimdVal.u32[15]); | ||
|
@@ -12235,6 +12242,12 @@ void Compiler::gtDispConst(GenTree* tree) | |
vecCon->gtSimdVal.u64[6], vecCon->gtSimdVal.u64[7]); | ||
break; | ||
} | ||
|
||
case TYP_MASK: | ||
{ | ||
printf("<0x%08x, 0x%08x>", vecCon->gtSimdVal.u32[0], vecCon->gtSimdVal.u32[1]); | ||
break; | ||
Comment on lines
+12248
to
+12249
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I think this one would be better to display as a single 64-bit value. If we have a trivial way to format it as binary, that's all the better, as it is effectively a bitmask representing which elements are included or not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense. I wasn't sure why simd8 displayed as 2x32 either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For simd8, it's mostly for convenience. The most common data size used with vectors is 4-byte elements (float, int, and uint) so it makes the display more relevant for typical inputs while still being overall short. |
||
} | ||
#endif // TARGET_XARCH | ||
|
||
default: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -277,6 +277,55 @@ struct simd64_t | |
}; | ||
static_assert_no_msg(sizeof(simd64_t) == 64); | ||
|
||
struct simdmask_t | ||
{ | ||
union { | ||
int8_t i8[8]; | ||
int16_t i16[4]; | ||
int32_t i32[2]; | ||
int64_t i64[1]; | ||
uint8_t u8[8]; | ||
uint16_t u16[4]; | ||
uint32_t u32[2]; | ||
uint64_t u64[1]; | ||
}; | ||
|
||
bool operator==(const simdmask_t& other) const | ||
{ | ||
return (u64[0] == other.u64[0]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is UB in C++ if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's UB per the spec. On the other hand, it's behavior that Clang, GCC, and MSVC all use themselves and which Windows, Linux, and MacOS all have various system level defines where similar is done. So it's something that's pretty heavily relied upon for all our targets We could always switch to defining many different structs and using std::bit_cast or reinterpet_cast, but it doesn't buy us much in practice and the current definitions roughly match the official definitions used for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would rather be safe about stuff like this. It won't be the first time we have had bugs caused by similar cases of UB (e.g. #67669), and tracking these down is very painful. Getters/setters that use |
||
} | ||
|
||
bool operator!=(const simdmask_t& other) const | ||
{ | ||
return !(*this == other); | ||
} | ||
|
||
static simdmask_t AllBitsSet() | ||
{ | ||
simdmask_t result; | ||
|
||
result.u64[0] = 0xFFFFFFFFFFFFFFFF; | ||
|
||
return result; | ||
} | ||
|
||
bool IsAllBitsSet() const | ||
{ | ||
return *this == AllBitsSet(); | ||
} | ||
|
||
bool IsZero() const | ||
{ | ||
return *this == Zero(); | ||
} | ||
|
||
static simdmask_t Zero() | ||
{ | ||
return {}; | ||
} | ||
}; | ||
static_assert_no_msg(sizeof(simdmask_t) == 8); | ||
|
||
typedef simd64_t simd_t; | ||
#else | ||
typedef simd16_t simd_t; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
VecCon
really the right type to use here? This isn't a vector constant and I worry about other places potentially getting this wrong as they expect the type to only beTYP_SIMD*
.I'd have expected that we instead represent this is a new type, since its a completely separate kind of constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems reasonable. I currently don't think we ever get here...