-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[RyuJit/ARMARCH] lower arg with list of float fields. #14753
Conversation
Signed-off-by: Sergey Andreenko <seandree@microsoft.com>
Copy was raplced with bitcast many commits ago.
Fix #14549 and #14377 |
114fe31
to
d073595
Compare
@dotnet-bot |
Ok, Windows_NT x86_arm_altjit Checked tailcallstress shows that SIMD tests passed (Test Result (38 failures / -11)), |
@dotnet/arm32-contrib PTAL. |
src/jit/lower.cpp
Outdated
assert(argNum == 0); | ||
|
||
unsigned fieldNum = 0; | ||
for (GenTreeFieldList *list = arg->AsFieldList(); list != nullptr; list = list->Rest(), fieldNum++) |
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 don't think this is correct for non-HFA struct types. I think that the caller of this method should always iterate through a FIELD_LIST, and then call LowerFloatArg
on its list items that require it. I think that will also be cleaner.
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 do not understand,
the caller of this method should always iterate through a FIELD_LIST
we do not always have a FIELD_LIST . Do you want to move this if-condition to the LowerArg
? Could you please give an example when this code is incorrect?
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 I meant was that if the arg is a FIELD_LIST
, then you need to iterate through all of its members. Some may be floating point, and some may not.
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.
Got it, thank you. If it is possible than we have a FIELD_LIST
with different types in it, which type is set on the FIELD_LIST
? And how is register information encoded in info->regnum
?
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.
Each FIELD_LIST
should only have the type of the field. The presence of a FIELD_LIST
node is an indication that the argument is an aggregate (either a struct or a decomposed long). When it is passed in register(s) the PUTARG
node will be a multireg node that has the register list.
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.
struct fgArgTabEntry:: regNumber regNum; // The (first) register to use when passing this argument, set to REG_STK for arguments passed on the stack.
Because regnum is just an int, we can't encode that the first field list member is passed through int register, the second float is passed through float register etc. There is no enough information to construct PUTARG
.
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.
Hmm - then perhaps I misremember. It must be the case that on arm only HFAs are passed in registers (not other struct types). I still think that it would be better and cleaner to iterate through the FIELD_LIST
in the caller to this method, and not have it call itself on the child of the FIELD_LIST
node.
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.
On ARM, only HFA are passed in floating-point registers. All structs can be passed, or partially passed, in integer registers.
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.
All structs can be passed, or partially passed, in integer registers.
So does that mean that if we have a TYP_DOUBLE
field, if that struct is promoted, we could expect to encounter the TYP_DOUBLE
in a FIELD_LIST
under a PUTARG_REG
or PUTARG_SPLIT
?
src/jit/lower.cpp
Outdated
// return arg if there was in place transformation; | ||
// return a new tree if the root was changed. | ||
// | ||
GenTreePtr Lowering::LowerFloatArg(GenTreePtr arg, fgArgTabEntryPtr info, unsigned argNum) |
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 believe it is the case that we are moving away from GenTreePtr
to GenTree*
.
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 not heard about it, do we?
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 has come up a few times. Here's a relatively recent reference: #14020 (comment)
We should probably put it in the coding conventions. @BruceForstall what do you think?
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 agree that it's weird that GenTreePtr is an oddball. Maybe if we want to stop using it, we should agree and then do a copy/replace everywhere. Generally, though, I'm ambivalent about it.
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.
Will change it before the merge, do not want to rerun tests now.
src/jit/lower.cpp
Outdated
GenTreePtr intNode = LowerFloatArg(node, info, fieldNum); | ||
if (intNode != nullptr) | ||
{ | ||
ReplaceArgWithPutArgOrBitcast(list->pCurrent(), intNode); |
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.
A FIELD_LIST doesn't always pass its fields in registers. This should check, because we shouldn't generate a BITCAST for a stack-passed field.
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.
Yes, you are right, this check is right below, line 1416. If it is stack location, then the function returns nullptr.
@dotnet-bot |
PR was updated, I have tried to make the new functions clearer. |
@dotnet-bot |
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 - thanks!
Merged, thanks for the review. |
Support transformation of Hfa that is represented as field list of floats to field list of integers.
It is a temporary solution before we get rid of gtRegNum assignments in the lowering.