Uh oh!
There was an error while loading. Please reload this page.
Fix System.Decimal aligment on ARM32 with crossgen2 - #38390
Conversation
pavel-orekhov
commented
Jun 25, 2020
- Fix passing Decimal to funcs. Fixes tests/.../decimal.cs and half of tests/.../10w5d.cs
MichalStrehovsky
commented
Jun 25, 2020
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?
MichalStrehovsky
commented
Jun 25, 2020
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.IsDecimalPro: Checking type in
ReadyToRunCompilerContextremoves checking of platform viaReadyToRunCompilerContextconstructorContra: Checking type in
ReadyToRunCompilerContextrequires to write many code to implement other methods ofFieldLayoutAlgorithmPro: checking type in
MetadataFieldLayoutAlgorithm.csexists already and is almost one-linerContra: copy-paste of
isDecimalrequired or moving ofInteropTypestoILC.TypeSystem.R2RPro: 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.csFunc_* 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
pavel-orekhov
commented
Jun 26, 2020
cc @alpencolt |
* Fix passing Decimal to funcs. It fixes the JIT/Methodical/MDArray/DataTypes/decimal.cs
pavel-orekhov
commented
Jun 29, 2020
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. Fixesdotnet#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
jkotas
commented
Jun 30, 2020
@pavel-orekhov I have fixed decimal implementation to not require this quirk. Give it a try |
t-mustafin
commented
Jul 6, 2020
I hit on different input argument r1 usage generated by crossgen2 and Tier-1 compilation on lambda-expression containing decimal variable: varsoldOutProducts=products.Where(p =>p.UnitsInStock>0&&p.UnitPrice>60.00M);from Linq test. 00001A 6948 ldr r0,[r1+20]00001C 9004str r0,[sp+0x10]00001E 6988 ldr r0,[r1+24]0000209005str r0,[sp+0x14]000022 69C8 ldr r0,[r1+28]0000249006str r0,[sp+0x18]000026 6A08 ldr r0,[r1+32]0000289007str r0,[sp+0x1c]meanwhile tier-1 compiled code loads input decimal from r1+24: 00001A F101 0018add r0, r1,2400001E 6804 ldr r4,[r0]0000206845 ldr r5,[r0+4]0000223008 adds r0,80000246801 ldr r1,[r0]0000266840 ldr r0,[r0+4]0000289108str r1,[sp+0x20]00002A 9009str r0,[sp+0x24]That incompatibility leads to test fail after tier compilation of that lambda-expression. Test with turned off tier compilation finish successfully. |
jkotas
commented
Jul 6, 2020
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 |
t-mustafin
commented
Jul 6, 2020
Yes, it is reproduced with varsoldOutProducts=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,76800000C DC14 bgt SHORT G_M16079_IG06 ;; bbWeight=1 PerfScore 3.00G_M16079_IG03:00000E 6A88 ldr r0,[r1+40]000010 F5B0 2FA0 cmp r0,0x50000000014 DC10 bgt SHORT G_M16079_IG06000016 F101 002C add r0, r1,4400001A 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,76800000C DC14 bgt SHORT G_M16079_IG06 ;; bbWeight=1 PerfScore 3.00G_M16079_IG03:00000E 6AC8 ldr r0,[r1+44]000010 F5B0 2FA0 cmp r0,0x50000000014 DC10 bgt SHORT G_M16079_IG06000016 F101 0030add r0, r1,4800001A 6803 ldr r3,[r0]00001C 6840 ldr r0,[r0+4] |
mangod9
commented
Jul 6, 2020
@t-mustafin since this particular issues is closed, could you please create a new issue for this ? Thx. |