-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Fix System.Decimal aligment on ARM32 with crossgen2 #38390
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
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:
runtime/src/coreclr/src/tools/aot/ILCompiler.ReadyToRun/Compiler/ReadyToRunCompilerContext.cs Lines 49 to 67 in 3705185
|
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the problem with Nullable types? Nullable types should not have any layout quirks.
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.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#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: var soldOutProducts = products.Where(p => p.UnitsInStock > 0 && p.UnitPrice > 60.00M);from Linq test. 00001A 6948 ldr r0, [r1+20]
00001C 9004 str r0, [sp+0x10]
00001E 6988 ldr r0, [r1+24]
000020 9005 str r0, [sp+0x14]
000022 69C8 ldr r0, [r1+28]
000024 9006 str r0, [sp+0x18]
000026 6A08 ldr r0, [r1+32]
000028 9007 str r0, [sp+0x1c]meanwhile tier-1 compiled code loads input decimal from r1+24: 00001A F101 0018 add r0, r1, 24
00001E 6804 ldr r4, [r0]
000020 6845 ldr r5, [r0+4]
000022 3008 adds r0, 8
000024 6801 ldr r1, [r0]
000026 6840 ldr r0, [r0+4]
000028 9108 str r1, [sp+0x20]
00002A 9009 str r0, [sp+0x24]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 var soldOutProducts = products.Where(p => p.MyStruct.a > 0x300 || p.MyStruct.b > 0x50000 || p.MyStruct.c > 0x6000000);Offsets generated by crossgen2: 000006 6A48 ldr r0, [r1+36]
000008 F5B0 7F40 cmp r0, 768
00000C DC14 bgt SHORT G_M16079_IG06
;; bbWeight=1 PerfScore 3.00
G_M16079_IG03:
00000E 6A88 ldr r0, [r1+40]
000010 F5B0 2FA0 cmp r0, 0x50000
000014 DC10 bgt SHORT G_M16079_IG06
000016 F101 002C add r0, r1, 44
00001A 6803 ldr r3, [r0]
00001C 6840 ldr r0, [r0+4]Offsets generated by Tier-1: G_M16079_IG02:
000006 6A88 ldr r0, [r1+40]
000008 F5B0 7F40 cmp r0, 768
00000C DC14 bgt SHORT G_M16079_IG06
;; bbWeight=1 PerfScore 3.00
G_M16079_IG03:
00000E 6AC8 ldr r0, [r1+44]
000010 F5B0 2FA0 cmp r0, 0x50000
000014 DC10 bgt SHORT G_M16079_IG06
000016 F101 0030 add r0, r1, 48
00001A 6803 ldr r3, [r0]
00001C 6840 ldr r0, [r0+4] |
|
@t-mustafin since this particular issues is closed, could you please create a new issue for this ? Thx. |