-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
Disable Int128 use in by value ABI scenarios, and fix field layout behavior #74123
Conversation
- On Unix platforms (64 bit) use 16 byte alignment - On Arm32 use 8 byte alignment matching the 128 byte vector type - On other Windows platforms the 128 bit integer type isn't defined by the C compiler, but match the behavior of other 128 bit types (16 byte alignment) Add tests to call down to native that should pass with these rules - Disable use of Int128 as p/invoke parameter passed by value
- This disables use of these types for parameter passing in R2R images
If you explicitly mark |
@@ -25,6 +32,47 @@ unsafe partial class Int128Native | |||
[DllImport(nameof(Int128Native))] | |||
public static extern Int128 AddInt128(Int128 lhs, Int128 rhs); | |||
|
|||
|
|||
[DllImport(nameof(Int128Native))] | |||
public static extern void AddStructWithInt128_ByRef(ref StructWithInt128 lhs, ref StructWithInt128 rhs); |
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.
Should pointers also be checked to make sure the marshaler doesn't change the by-ref marshalling?
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've done some mild testing of pointers. It should work acceptably well.
All failures caused by the unix arm queue getting completely overwhelmed |
// On Windows, no standard for Int128 has been established yet, | ||
// although applying 16 byte alignment is consistent with treatment of 128 bit SSE types | ||
// even on X86 |
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.
Worth noting that the MSVC STL does have a private __int128
that is 16-byte aligned. Clang also uses 16-byte alignment for its own Int128
when targeting the Windows ABI.
Nothing official/documented of course, but it does help justify using 16
on Windows here for managed.
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.
LGTM with a few nits
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
<DebugType>embedded</DebugType> |
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 this necessary?
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 separate test? Yes, as the other test fails, and I'd like to not get rid of it. The DebugType flag, no, but it was just a copy/paste from the other project.
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 question was around the DebugType in particular.
Co-authored-by: Jeremy Koritzinsky <[email protected]>
[Intrinsic] | ||
[StructLayout(LayoutKind.Sequential)] | ||
public readonly struct Int128 | ||
{ | ||
|
||
private readonly ulong _lower; | ||
private readonly ulong _upper; | ||
} | ||
|
||
[Intrinsic] | ||
[StructLayout(LayoutKind.Sequential)] | ||
public readonly struct UInt128 | ||
{ | ||
|
||
private readonly ulong _lower; | ||
private readonly ulong _upper; | ||
} |
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.
[Intrinsic] | |
[StructLayout(LayoutKind.Sequential)] | |
public readonly struct Int128 | |
{ | |
private readonly ulong _lower; | |
private readonly ulong _upper; | |
} | |
[Intrinsic] | |
[StructLayout(LayoutKind.Sequential)] | |
public readonly struct UInt128 | |
{ | |
private readonly ulong _lower; | |
private readonly ulong _upper; | |
} | |
[Intrinsic] | |
[StructLayout(LayoutKind.Sequential)] | |
public readonly struct Int128 | |
{ | |
private readonly ulong _lower; | |
private readonly ulong _upper; | |
} | |
[Intrinsic] | |
[StructLayout(LayoutKind.Sequential)] | |
public readonly struct UInt128 | |
{ | |
private readonly ulong _lower; | |
private readonly ulong _upper; | |
} |
The failures here are all arm64 issues hit by the arm helix queues falling over today. |
/backport to release/7.0-rc1 |
Started backporting to release/7.0-rc1: https://github.com/dotnet/runtime/actions/runs/2892554223 |
dotnet#74123 broke compiling TechEmpower benchmarks with NativeAOT. We now crash with: ``` > ILCompiler.TypeSystem.dll!Internal.TypeSystem.RuntimeDeterminedFieldLayoutAlgorithm.ComputeInstanceLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 19 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeInstanceLayout(Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 436 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.IsInt128OrHasInt128Fields.get() Line 150 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeAutoFieldLayout(Internal.TypeSystem.MetadataType type, int numInstanceFields) Line 483 C# ILCompiler.Compiler.dll!ILCompiler.CompilerMetadataFieldLayoutAlgorithm.ComputeInstanceFieldLayout(Internal.TypeSystem.MetadataType type, int numInstanceFields) Line 56 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeInstanceLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 164 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeInstanceLayout(Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 436 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.InstanceFieldSize.get() Line 165 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeFieldSizeAndAlignment(Internal.TypeSystem.TypeDesc fieldType, bool hasLayout, int packingSize, out bool layoutAbiStable, out bool fieldTypeHasAutoLayout, out bool fieldTypeHasInt128Field) Line 838 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeStaticFieldLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.StaticLayoutKind layoutKind) Line 215 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeStaticFieldLayout(Internal.TypeSystem.StaticLayoutKind layoutKind) Line 473 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.GCStaticFieldSize.get() Line 302 C# ILCompiler.Compiler.dll!ILCompiler.DependencyAnalysis.NativeLayoutTemplateTypeLayoutVertexNode.GetStaticDependencies(ILCompiler.DependencyAnalysis.NodeFactory context) Line 997 C# ``` https://github.com/dotnet/runtime/blob/4cf1383c8458945b7eb27ae5f57338c10ed25d54/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/RuntimeDeterminedFieldLayoutAlgorithm.cs#L17-L19 I was not able to come up with a standalone repro case, but this fixes compiling the benchmark. I'm not clear why native layout operates on runtime determined forms, but what I'm doing here should have equivalent behaviors, except avoiding the problem that we can no longer compute layouts of runtime determined things in some obscure scenarios due to the new code.
#74123 broke compiling TechEmpower benchmarks with NativeAOT. We now crash with: ``` > ILCompiler.TypeSystem.dll!Internal.TypeSystem.RuntimeDeterminedFieldLayoutAlgorithm.ComputeInstanceLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 19 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeInstanceLayout(Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 436 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.IsInt128OrHasInt128Fields.get() Line 150 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeAutoFieldLayout(Internal.TypeSystem.MetadataType type, int numInstanceFields) Line 483 C# ILCompiler.Compiler.dll!ILCompiler.CompilerMetadataFieldLayoutAlgorithm.ComputeInstanceFieldLayout(Internal.TypeSystem.MetadataType type, int numInstanceFields) Line 56 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeInstanceLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 164 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeInstanceLayout(Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 436 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.InstanceFieldSize.get() Line 165 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeFieldSizeAndAlignment(Internal.TypeSystem.TypeDesc fieldType, bool hasLayout, int packingSize, out bool layoutAbiStable, out bool fieldTypeHasAutoLayout, out bool fieldTypeHasInt128Field) Line 838 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeStaticFieldLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.StaticLayoutKind layoutKind) Line 215 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeStaticFieldLayout(Internal.TypeSystem.StaticLayoutKind layoutKind) Line 473 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.GCStaticFieldSize.get() Line 302 C# ILCompiler.Compiler.dll!ILCompiler.DependencyAnalysis.NativeLayoutTemplateTypeLayoutVertexNode.GetStaticDependencies(ILCompiler.DependencyAnalysis.NodeFactory context) Line 997 C# ``` https://github.com/dotnet/runtime/blob/4cf1383c8458945b7eb27ae5f57338c10ed25d54/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/RuntimeDeterminedFieldLayoutAlgorithm.cs#L17-L19 I was not able to come up with a standalone repro case, but this fixes compiling the benchmark. I'm not clear why native layout operates on runtime determined forms, but what I'm doing here should have equivalent behaviors, except avoiding the problem that we can no longer compute layouts of runtime determined things in some obscure scenarios due to the new code.
#74123 broke compiling TechEmpower benchmarks with NativeAOT. We now crash with: ``` > ILCompiler.TypeSystem.dll!Internal.TypeSystem.RuntimeDeterminedFieldLayoutAlgorithm.ComputeInstanceLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 19 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeInstanceLayout(Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 436 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.IsInt128OrHasInt128Fields.get() Line 150 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeAutoFieldLayout(Internal.TypeSystem.MetadataType type, int numInstanceFields) Line 483 C# ILCompiler.Compiler.dll!ILCompiler.CompilerMetadataFieldLayoutAlgorithm.ComputeInstanceFieldLayout(Internal.TypeSystem.MetadataType type, int numInstanceFields) Line 56 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeInstanceLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 164 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeInstanceLayout(Internal.TypeSystem.InstanceLayoutKind layoutKind) Line 436 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.InstanceFieldSize.get() Line 165 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeFieldSizeAndAlignment(Internal.TypeSystem.TypeDesc fieldType, bool hasLayout, int packingSize, out bool layoutAbiStable, out bool fieldTypeHasAutoLayout, out bool fieldTypeHasInt128Field) Line 838 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.MetadataFieldLayoutAlgorithm.ComputeStaticFieldLayout(Internal.TypeSystem.DefType defType, Internal.TypeSystem.StaticLayoutKind layoutKind) Line 215 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.ComputeStaticFieldLayout(Internal.TypeSystem.StaticLayoutKind layoutKind) Line 473 C# ILCompiler.TypeSystem.dll!Internal.TypeSystem.DefType.GCStaticFieldSize.get() Line 302 C# ILCompiler.Compiler.dll!ILCompiler.DependencyAnalysis.NativeLayoutTemplateTypeLayoutVertexNode.GetStaticDependencies(ILCompiler.DependencyAnalysis.NodeFactory context) Line 997 C# ``` https://github.com/dotnet/runtime/blob/4cf1383c8458945b7eb27ae5f57338c10ed25d54/src/coreclr/tools/Common/TypeSystem/RuntimeDetermined/RuntimeDeterminedFieldLayoutAlgorithm.cs#L17-L19 I was not able to come up with a standalone repro case, but this fixes compiling the benchmark. I'm not clear why native layout operates on runtime determined forms, but what I'm doing here should have equivalent behaviors, except avoiding the problem that we can no longer compute layouts of runtime determined things in some obscure scenarios due to the new code.
Unfortunately, attempting to actually fix all the ABI issues is probably too complex for this time in the release cycle.
Int128
as being ABI unstable in Crossgen2. This will prevent it from appearing in function signaturesInt128
in pinvokes as a by value parameter or return value. (Match behavior ofVector128<T>
) (Unlike Vector128 handle scenarios such as having fields ofInt128
types.)Fixes #72206