Fix System.Decimal aligment on ARM32 with crossgen2#38390
Fix System.Decimal aligment on ARM32 with crossgen2#38390pavel-orekhov wants to merge 1 commit intodotnet:masterfrom pavel-orekhov:master
Conversation
pavel-orekhov
commented
Jun 25, 2020
- Fix passing Decimal to funcs. Fixes tests/.../decimal.cs and half of tests/.../10w5d.cs
|
This should be done similar to how other special types handled:
|
There was a problem hiding this comment.
The helpers in InteropTypes.cs are specifically for interop marshallers. We don't have a central location with a "is this type X?" functionality. We place the functionality locally where it's needed.
There was a problem hiding this comment.
Many thanks to you!
Ok. Moving modules to another assembly is not very good. So, is it right you suggests to copy-paste InteropTypes::IsSystemDecimal and IsCoreNamedType to R2RCompilerContext.FieldLayoutAlgorithm() / _r2rFieldLayoutAlgorithm and compare strings like
diff --git a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs
index bbe1274cae3..d3210f2c5c7 100644
--- a/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs
+++ b/src/coreclr/src/tools/crossgen2/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs
@@ -60,6 +60,10 @@ public override FieldLayoutAlgorithm GetLayoutAlgorithmForType(DefType type)
{
return _vectorFieldLayoutAlgorithm;
}
+ else if (type.IsValueType && type.Context.Target.Architecture == TargetArchitecture.ARM && IsSystemDecimal(type.Context, type))
+ {
+ return _decimalOnARM32FieldLayoutAlgorithm;
+ }
else
{
Debug.Assert(_r2rFieldLayoutAlgorithm != null);
return _r2rFieldLayoutAlgorithm;
}
?
Or i can use InteropTypes.IsSystemDecimal() directly here?
May be you suggests to create the flag DefType.isSystemDecimal in order to compare bits, not strings? But I don't know where to set this flag, where the Decimal class loads. :( Do you know it? Can you tell me that?
|
cc @dotnet/crossgen-contrib |
There was a problem hiding this comment.
I think it would be easiest to check for CoreLib types by name in a method called from here, and apply the layout quirks that way.
Similar to how MethodTableBuilder::CheckForSystemTypes is done. I expect we will need most quirks from this method eventually.
There was a problem hiding this comment.
Looking at MethodTableBuilder::CheckForSystemTypes - will we need anything else besides the Decimal addition? We already treat Vector<T> and the other vectors the way I propose for Decimal as well. I don't particularly care about the mechanism, but I do care about consistency.
There was a problem hiding this comment.
-
Pro: Checking type in
ReadyToRunCompilerContextallows to don't moveInteropTypestoILC.TypeSystem.R2Rand allows to use existingInteropTypes.IsDecimal -
Pro: Checking type in
ReadyToRunCompilerContextremoves checking of platform viaReadyToRunCompilerContextconstructor -
Contra: Checking type in
ReadyToRunCompilerContextrequires to write many code to implement other methods ofFieldLayoutAlgorithm -
Pro: checking type in
MetadataFieldLayoutAlgorithm.csexists already and is almost one-liner -
Contra: copy-paste of
isDecimalrequired or moving ofInteropTypestoILC.TypeSystem.R2R -
Pro: Moving is already done
-
Contra: More changes in a branch for
static structwill be to mitigate second half of the 10w5d.cs test. -
Contra: Colleagues say, more types with broken alignment on ARM32 may arise.
So, Where? Please tell me the consensus!
There was a problem hiding this comment.
We also faced with similar issues in Nullable types. If there are already exceptions for vectors and other types in ReadyToRunCompilerContext I think it would be preferred place.
There was a problem hiding this comment.
What is the problem with Nullable types? Nullable types should not have any layout quirks.
There was a problem hiding this comment.
If a nullable long enum isn't handled correctly, that is a bug in the general purpose type layout logic, not something that should be special cased.
There was a problem hiding this comment.
LongE & so seem are fixed by #32663 / #32664.
But I afraid it is only masking of bug:
When (before) jit/methodical/fp/exgen/10w5d.cs Func_* don't compiled by cg2 but delayed to jit while ctors is done by cg2. So some difference in placement of static structs was (IMHO) between cg2 & jit compilers was and leaded to missfunction.
Right now placement of statics and using of it is by cg2 and you can't see difference with jit's ideas.
So bug (10w5d, LongE and so) may resurrect when cg2 and jit will be used. For example in eval case.
There was a problem hiding this comment.
For Decimal, I am wondering whether we should fix the Decimal implementation to make this special casing unncessary. I will take a look at what it would take today.
I have reverted this workaround a few days ago. Could you please check whether it is still a problem on current master?
There was a problem hiding this comment.
I have reverted this workaround a few days ago. Could you please check whether it is still a problem on current master?
With 4e5c8c0 (today's (20200629) master) the jit/methodical/fp/exgen/10w5d.cs is ok.
How to force 'delayed compilation' back I don't know (eval does not exists, imho). Sorry.
If you mean mass testing clr tests with cg2 please look to our night test results:
results.tar.gz
There was a problem hiding this comment.
#38603 should be a cleaner fix for the Decimal issue.
|
cc @alpencolt |
* Fix passing Decimal to funcs. It fixes the JIT/Methodical/MDArray/DataTypes/decimal.cs
System.Decimal fields did not match Win32 DECIMAL type for historic reasons. It required type loader to have a quirk to artifically inflate System.Decimal alignment to match the alignment of Win32 DECIMAL type to make interop work well. This change is fixing the System.Decimal fields to match Win32 DECIMAL type and removing the quirk from the type loader since it does not belong there. The downsides are: - Slightly lower code quality on 32-bit platforms. 32-bit platforms are not our high performance targets anymore. - Explicit implementation of ISerializable is required on System.Decimal for binary serialization compatibility. Fixes dotnet#38390
System.Decimal fields did not match Win32 DECIMAL type for historic reasons. It required type loader to have a quirk to artificially inflate System.Decimal alignment to match the alignment of Win32 DECIMAL type to make interop work well. This change is fixing the System.Decimal fields to match Win32 DECIMAL type and removing the quirk from the type loader since it does not belong there. The downsides are: - Slightly lower code quality on 32-bit platforms. 32-bit platforms are not our high performance targets anymore. - Explicit implementation of ISerializable is required on System.Decimal for binary serialization compatibility. Fixes #38390
|
@pavel-orekhov I have fixed decimal implementation to not require this quirk. Give it a try |
|
I hit on different input argument r1 usage generated by crossgen2 and Tier-1 compilation on lambda-expression containing decimal variable: from Linq test. meanwhile tier-1 compiled code loads input decimal from r1+24: That incompatibility leads to test fail after tier compilation of that lambda-expression. Test with turned off tier compilation finish successfully. |
|
This bug should not be specific to Decimal. Are you able to reproduce it with a custom type with long field? E.g. Looks like |
|
Yes, it is reproduced with Offsets generated by crossgen2: Offsets generated by Tier-1: |
|
@t-mustafin since this particular issues is closed, could you please create a new issue for this ? Thx. |