[Windows|Arm64|VarArgs] Correctly pass HFA arguments#18364
Conversation
b481792 to
110fa8e
Compare
| #if !defined(_TARGET_UNIX_) && defined(_TARGET_ARM64_) | ||
| && !isVarArg // Arm64 Windows VarArg methods arguments will not | ||
| // classify HFA types, they will need to be treated | ||
| // as if they are not HFA types. |
There was a problem hiding this comment.
It would be nice to fix up this comment, if you can get the formatter to go along with a fix. Maybe put the comment above the && line.
| // Structs that are pointer sized or smaller should have been handled by getPrimitiveTypeForStruct | ||
| assert(structSize > TARGET_POINTER_SIZE); | ||
| #if !defined(_TARGET_UNIX_) | ||
| if (!isVarArg) |
There was a problem hiding this comment.
I don't see why this is needed. It should still be the case that getPrimitiveTypeForStruct should return a primitive type for anything <= TARGET_POINTER_SIZE, right?
There was a problem hiding this comment.
You are correct, thank you for catching this I do not know what I was thinking at the time.
| // | ||
| // Arguments: | ||
| // tmpVarNum - the var num which we clone into the newly created temp var. | ||
| // bool isVarArg - is a VarArg method. Will effect HFA decision for arm64 windows |
|
|
||
| void SortArgs(); | ||
|
|
||
| void EvalArgsToTemps(); |
There was a problem hiding this comment.
EvalArgs [](start = 9, length = 8)
Could you change this to be in the positive sense? Perhaps allowHfa?
|
This looks good except for some minor things and one more substantive question. |
8cd6d87 to
359b0fd
Compare
CarolEidt
left a comment
There was a problem hiding this comment.
LGTM - thanks! (and sorry for the delay in reviewing)
359b0fd to
1116404
Compare
Previously, the type would be reported as HFA and enregistered; however, this is not correct, as arm64 varargs abi requires passing using int registers.
1116404 to
6439ed1
Compare
|
@CarolEidt @briansull can you take another look, I have updated and rebased against master. This pulls in #18358. I have also followed Carol's approach to using fgArgEntry to store isVararg. This removes some of the isVararg parameters passed around. |
| // | ||
| // Arguments: | ||
| // tmpVarNum - the var num which we clone into the newly created temp var. | ||
| // curArgTabEntry |
| gcInfo.gcMarkRegPtrVal(argReg, loadType); | ||
|
|
||
| if (compiler->lvaIsMultiregStruct(varDsc)) | ||
| if (compiler->lvaIsMultiregStruct(varDsc, compiler->info.compIsVarArgs)) |
There was a problem hiding this comment.
What is the effect of passing a true for compIsVarArgs as the second parameter?
If it simply makes this function always return false when varargs is true,
then it does not need to be a parameter.
Instead write:
if (!compiler->info.compIsVarArgs && compiler->lvaIsMultiregStruct(varDsc))
There was a problem hiding this comment.
It will the decision for whether it is a multiregstruct for hfa cases. I believe it is necessary.
| if (IsHfa(clsHnd)) | ||
| #else // !ARM_SOFTFP | ||
| if (IsHfa(clsHnd) | ||
| #if !defined(_TARGET_UNIX_) && defined(_TARGET_ARM64_) |
There was a problem hiding this comment.
It might be better to define
#if defined(_TARGET_ARM64_) && !defined(_TARGET_UNIX_)
#define IGNORE_HFA_FOR_VARARG
Don't we have a TARGET_WINDOWS or WIN64?
There was a problem hiding this comment.
I believe there is only a WINOWS_AMD64_ABI define.
|
@dotnet-bot test OSX10.12 x64 Checked Innerloop Build and Test |
|
osx timed out. Arm64 has passed. OSX has passed in last change, only difference are ifdef names. Which the build passes so I do not think it is required to wait. |
…18364) * Fix passing HFA of two floats to vararg methods Previously, the type would be reported as HFA and enregistered; however, this is not correct, as arm64 varargs abi requires passing using int registers. * Address linux build issue * Apply final format patch * Add _TARGET_WINDOWS_ Commit migrated from dotnet/coreclr@c485d3f
Windows arm64 VarArgs ABI requires passing using the general purpose registers. For HFA types, this would lead to bad codegen for vararg methods. Both the fixed arguments and the variable arguments are affected.
For arguments only, HFA structs need to be treated as if they are not HFAs.