[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. |
| assert(argNum == 0); | ||
|
|
||
| unsigned fieldNum = 0; | ||
| for (GenTreeFieldList *list = arg->AsFieldList(); list != nullptr; list = list->Rest(), fieldNum++) |
There was a problem hiding this comment.
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.
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.
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.
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.
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.
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.
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.
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.
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?
| // 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.
I believe it is the case that we are moving away from GenTreePtr to GenTree*.
There was a problem hiding this comment.
I have not heard about it, do we?
There was a problem hiding this comment.
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.
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.
Will change it before the merge, do not want to rerun tests now.
| GenTreePtr intNode = LowerFloatArg(node, info, fieldNum); | ||
| if (intNode != nullptr) | ||
| { | ||
| ReplaceArgWithPutArgOrBitcast(list->pCurrent(), intNode); |
There was a problem hiding this comment.
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.
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 |
|
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.