Skip to content
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

[mono] [llvm-aot] Fixed storing Vector3 into memory #111000

Merged
merged 2 commits into from
Jan 3, 2025

Conversation

jkurdek
Copy link
Member

@jkurdek jkurdek commented Dec 30, 2024

Fixes #110820

Vector3 is sometimes handled as Vector4 (Vector3 + 0) for perf purposes. On mono llvm aot it was incorrectly stored into memory with the trailing 0. This change fixes that behaviour.

@jkurdek
Copy link
Member Author

jkurdek commented Dec 30, 2024

/azp run runtime-llvm

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkurdek
Copy link
Member Author

jkurdek commented Dec 30, 2024

/azp run runtime-extra-platforms

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkurdek
Copy link
Member Author

jkurdek commented Dec 30, 2024

/azp run runtime-llvm, runtime-extra-platforms

Copy link

Azure Pipelines successfully started running 2 pipeline(s).

Copy link
Member

@matouskozak matouskozak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! I put down a few comments out of curiosity so feel free to merge.

btw. nice PR number 111000

Comment on lines +8437 to +8445
const int mask_values [] = { 0, 1, 2 };

LLVMValueRef truncatedVec3 = LLVMBuildShuffleVector (
builder,
lhs,
LLVMGetUndef (t),
create_const_vector_i32 (mask_values, 3),
"truncated_vec3"
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't this be replaced by something like?

LLVMValueRef truncatedVec3 = LLVMBuildTrunc (builder, lhs, LLVMVectorType (LLVMFloatType (), 3), "truncated_vec3);

However, I haven't tried it locally so I'm unsure whether it would make the same and be more efficient or not.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the trunc instruction does something different. Looking at the LLVM reference it seems to be casting each element of a vector to a different type - not casting a vector and dropping its last element.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, I thought it works the same as on primitives. Thank you for the explanation.

src/mono/mono/mini/mini-llvm.c Show resolved Hide resolved
@jkurdek
Copy link
Member Author

jkurdek commented Jan 3, 2025

/azp run runtime-extra-platforms

Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@jkurdek
Copy link
Member Author

jkurdek commented Jan 3, 2025

/ba-g failures unrelated

@jkurdek jkurdek merged commit 33351e6 into dotnet:main Jan 3, 2025
148 of 162 checks passed
@jkurdek jkurdek deleted the fix/vector3-aot-memory-store branch January 3, 2025 16:46
@jkurdek
Copy link
Member Author

jkurdek commented Jan 3, 2025

/backport to release/9.0-staging

Copy link
Contributor

github-actions bot commented Jan 3, 2025

Started backporting to release/9.0-staging: https://github.com/dotnet/runtime/actions/runs/12600960089

"truncated_vec3"
);

mono_llvm_build_aligned_store (builder, truncatedVec3, dest, FALSE, 1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the alignment being set to 1? A Vector3 is composed of 3x float fields and so is presumed to be 4 byte aligned unless the code is explicitly using something like Unsafe.ReadUnaligned or Unsafe.WriteUnaligned (which use the IL unaligned. prefix).

if (mono_class_value_size (ins->klass, NULL) == 12) {
const int mask_values [] = { 0, 1, 2 };

LLVMValueRef truncatedVec3 = LLVMBuildShuffleVector (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we using ShuffleVector here?

In other places, we instead do this via doing LLVMBuildExtractElement + LLVMBuildInsertValue (or Store) 3x. This alternative correctly represents the primitive steps and allows LLVM to optimize it as best fit for the underlying architecture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Class Vector3 field assignation overwrites the next field's contents when using LLVM AOT
4 participants