Fix GCStress failures from hardware intrinsic tests#17314
Fix GCStress failures from hardware intrinsic tests#17314CarolEidt merged 1 commit intodotnet:masterfrom
Conversation
|
|
||
| Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), this.simdSize); | ||
| Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), this.simdSize); | ||
| Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), inArray1.Length * sizeof(TOp1)); |
There was a problem hiding this comment.
It's not obvious to me why the old code was bad and the new code is correct, the array length is simdSize * 2 so it seems that copying simdSize bytes should have worked correctly. Besides, I doubt that sizeof(TOp1) will compile.
There was a problem hiding this comment.
The problem was the size of arguments (inArray1, inArray2, outArray, etc) could be different in AVX/AVX2 intrinsics.
the array length is simdSize * 2
simdSize * 2 is the length of buffers (the members) rather than input arrays (the arguments).
Besides, I doubt that sizeof(TOp1) will compile.
I tried, it works well.
There was a problem hiding this comment.
The code in this file is plain bogus...
There was a problem hiding this comment.
simdSize * 2 is the length of buffers (the members) rather than input arrays (the arguments).
Right. And that is odd since the buffers end up being smaller than the input arrays. I assume that simdSize is the size of a vector.
There was a problem hiding this comment.
Oops, sizeof(TOp1) does not work...
There was a problem hiding this comment.
Actually, it is the largest alignment boundary.
Isn't that the same thing as the vector size? SSE2 vector size is 16 bytes and the required alignment is 16 bytes. CopyBlockUnaligned copies bytes the old code copied 16 bytes. How could the input arrays be smaller than 16 bytes?
There was a problem hiding this comment.
For any given test, simdSize should be the size of the largest Vector used (so 16 or 32, currently).
We then allocate 2 * simdSize so that we can guarantee the buffer is aligned (since you need at most alignment - 1 additional bytes to guarantee alignment).
In the case where one argument is Vector128 and one argument is Vector256, simdSize will be larger than the input array for the Vector128 args, and will result in an AV.
There was a problem hiding this comment.
Except you don't usually get an AV. The code just keeps copying whatever random bytes there are past the end of the array. So the failure only shows up in GC stress when we break in just after the copy and find there is a byref and it happens to be pointing into free space.
There was a problem hiding this comment.
In the case where one argument is Vector128 and one argument is Vector256, simdSize will be larger than the input array for the Vector128 args, and will result in an AV.
I see. Well, this code is a mess.
- The
DataTablename is misleading, this whole class isn't some sort of data table, it's just some kind of wrapper for some aligned memory buffers (and it's not clear why instead of simply having aAlignedArray<T>class we have instead this set of classes where the logic is duplicated). - The
simdSizeparameter should have been called alignment, that's its main purpose here. - There are no asserts that would suggest that the input arrays are supposed to contain only one vector and thus be smaller than
simdSize. - In the absence of such asserts the length of the new arrays should have been calculated based on the parameter arrays, not based on
simdSize. - The out array parameter is not used
- The way alignment is done is sort of unusual. Pretty much every alignment function I've seen does
(x + (alignment - 1)) & ~(alignment - 1). - It probably would have been simpler to just allocate memory using
Marshal.AllocCoTaskMeminstead of dragging in GC handles as well
The actual test code isn't any better. Tons of repeated code, unsafe copies and whatnot. I take it that people were in a hurry to get things done and this is the result.
|
test Windows_NT x86 Checked gcstress0xc_jitstress1 |
|
@fiigii, we fixed this in the other templates by doing We should probably do the same here. Edit: Actually, we don't have the |
|
With these changes I can see that the copy won't read of the end of the parameter Seems like we are relying on the callers to pass reasonable values for parameters and I suspect as people try and add tests they will get this wrong sometimes. A few lines of validation checking can catch these issues without having to debug through a gc stress failure. So I suggest adding some here. |
|
Addressed feedback. @AndyAyersMS @mikedn @tannergooding PTAL |
|
We only create Please use explicit throws to ensure that validation is always done no matter how the test is built. |
|
@AndyAyersMS Thanks for the suggestion. Fixed. |
AndyAyersMS
left a comment
There was a problem hiding this comment.
LGTM save for the one typo.
| int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<TResult>(); | ||
| if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray) | ||
| { | ||
| throw new ArgumentException("Invalid vlue of alignment"); |
There was a problem hiding this comment.
Nit: "vlue" --> "value" (copied thoughout)
|
Hmm, think jenkins lost it there for a minute. Let me close/repoen. |
|
test Windows_NT x86 Checked gcstress0xc_jitstress1 |
|
The "hit priveleged instruction" failure in x86 gc stress 0xC jitstress 1 is a symptom of a gc stress race that I'm trying to fix over in #17330. The "SanityCheck()" failure in x86 gc stress 0xC jitstress 2 could be a number of things but it's unrelated to this change. |
|
Can we merge this PR? |
fix https://github.com/dotnet/coreclr/issues/17278