-
Notifications
You must be signed in to change notification settings - Fork 11.9k
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
[LoongArch] Pass 'half' in the lower 16 bits of an f32 value with F/D ABI #109368
Closed
Closed
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
You shouldn't need to custom lower the casts to change the ABI. Are you trying to special case the ABI for this one call in this one instance? That seems bad
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're not trying to special case the ABI, but rather ensuring compliance with the ABI rules for floating-point operations. Specifically, the argument for
f32 __gnu_h2f_ieee(f16)
needs to be passed via the FPR, as per the floating-point ABI, rather than the GPR. Custom lowering ensures that the argument is correctly passed through the FPR in cases where the default behavior doesn't align with this requirement. Thanks.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.
This change does not accomplish this. The cast opcodes have nothing to do with the ABI, other than ABI code may result in inserting them
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 default behavior of
softPromoteHalf
does not align with the expectations of the architecture, the custom lowering as referenced by the approach used in RISC-V.Ref: https://reviews.llvm.org/D151284
In Rust's implementation, the argument of
__gnu_h2f_ieee
isf16
, noti16
.https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.126/src/float/extend.rs#L95-L97
Is there a better approach to achieve this?
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.
In other words, you are special casing the ABI for this one libcall that happens to be used for legalization of the conversions. If you are fixing the ABI, as the title suggests, you need to make changes to the calling convention lowering code and possibly use addRegisterClass for f16.
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.
By default the half is going to be be pre-promoted to a legal f32 type and you need to intervene before that. I would start by overriding getRegisterTypeForCallingConv, and then see how that goes. You may need to just custom hack on the argument lists in each of the Lower* functions.
Yes SelectionDAG makes this more difficult than it should be. It would be much easier if calling convention code operated on the raw IR signature instead of going through type legalization first
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.
Thanks for your guidance. I haven't quite managed to get it done yet. To pass fp16 in FPR (excluding libcall),
splitValueIntoRegisterParts
andjoinRegisterPartsIntoValue
insert all ones in the upper bits and extract the lower bits by casting to an integer type. I guess this is the key point where the fp16 value is promoted to an integer when it reaches theFP16_TO_FP
operation, but I'm not sure how to bypass the integer type to achieve this.Additionally, it seems that custom-lowering
FP16_TO_FP
andFP_TO_FP16
to generate a libcall while keeping it passed in FPR works quite well and is fairly easy to implement, RISC-V is already using this approach. Can we go ahead with this? Thanks.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.
It's not really correct. It only happens to work out, and MOVFR2GR_S_LA64 is a hack
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.
Just to address this (quite late) - aiui
__gnu_h2f_ieee
is only called on platforms wheref16
is passed as an integer so that doesn't matter here. If there is a float ABI then__extendhfsf2
/__truncsfhf2
is used instead.There is something weird with the return value though, Rust's compiler-builtins and LLVM's compiler-rt both use
f32
but GCC usesint
. (I think maybe GCC just never emits that libcall except on ARM, LLVM seems to use it a lot more).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.
In my view,
__gnu_h2f_ieee
is primarily designed for convertingf16
values tof32
, particularly in scenarios where hardware lacks nativef16
support, requiring software emulation instead. This function does not inherently define any specific argument-passing conventions; rather, those are determined by the architecture's ABI. For instance, on RISC-V, the lower 16 bits of a floating point argument register are used (given that hardware support forf16
is not enabled), while some other architectures use integer registers. In terms of implementation,__extendhfsf2
serves as an alias for__gnu_h2f_ieee
and are used by arm.https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.126/src/float/extend.rs#L87-L89
https://github.com/rust-lang/compiler-builtins/blob/compiler_builtins-v0.1.126/src/float/extend.rs#L95-L97
https://github.com/llvm/llvm-project/blob/llvmorg-19.1.2/compiler-rt/lib/builtins/extendhfsf2.c#L13-L19