Enable `TYP_STRUCT` `LCL_VAR/LCL_FLD` call args on ARM64 (#71328)
authorSingleAccretion <62474226+SingleAccretion@users.noreply.github.com>
Wed, 29 Jun 2022 22:16:04 +0000 (01:16 +0300)
committerGitHub <noreply@github.com>
Wed, 29 Jun 2022 22:16:04 +0000 (00:16 +0200)
* Arm64: local morph

* Arm64: morph

* Fix MultiregStructArgs up

src/coreclr/jit/lclmorph.cpp
src/coreclr/jit/lower.cpp
src/coreclr/jit/morph.cpp

index aa02efa..108efa1 100644 (file)
@@ -1068,7 +1068,7 @@ private:
         // | Partial    | LCL_FLD | LCL_FLD | LCL_FLD |
         // |------------|---------|---------|---------|
         //
-        // * - On XArch only.
+        // * - On XArch/Arm64 only.
         //
         // |------------|------|------|--------|----------|
         // | SIMD       | CALL | ASG  | RETURN | HWI/SIMD |
@@ -1086,9 +1086,9 @@ private:
 
         if (user->IsCall())
         {
-#if !defined(TARGET_XARCH)
+#if !defined(TARGET_XARCH) && !defined(TARGET_ARM64)
             return IndirTransform::None;
-#endif // !defined(TARGET_XARCH)
+#endif // !defined(TARGET_XARCH) && !defined(TARGET_ARM64)
         }
 
         if (match == StructMatch::Compatible)
index 904abd0..b8baead 100644 (file)
@@ -1071,7 +1071,7 @@ GenTree* Lowering::NewPutArg(GenTreeCall* call, GenTree* arg, CallArg* callArg,
     // Struct can be split into register(s) and stack on ARM
     if (compFeatureArgSplit() && callArg->AbiInfo.IsSplit())
     {
-        assert(arg->OperGet() == GT_OBJ || arg->OperGet() == GT_FIELD_LIST);
+        assert(arg->OperIs(GT_OBJ, GT_FIELD_LIST) || arg->OperIsLocalRead());
         // TODO: Need to check correctness for FastTailCall
         if (call->IsFastTailCall())
         {
index 0dd864c..df1b2b4 100644 (file)
@@ -3265,7 +3265,7 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* call)
                     }
 #endif // UNIX_AMD64_ABI
 #elif defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64)
-                    if ((passingSize != structSize) && (lclVar == nullptr))
+                    if ((passingSize != structSize) && !argIsLocal)
                     {
                         makeOutArgCopy = true;
                     }
@@ -3632,21 +3632,9 @@ void Compiler::fgMorphMultiregStructArgs(GenTreeCall* call)
                 if (arg.AbiInfo.IsHfaRegArg())
                 {
                     var_types hfaType = arg.AbiInfo.GetHfaType();
-                    unsigned  structSize;
-                    if (argx->OperIs(GT_OBJ))
-                    {
-                        structSize = argx->AsObj()->GetLayout()->GetSize();
-                    }
-                    else if (varTypeIsSIMD(argx))
-                    {
-                        structSize = genTypeSize(argx);
-                    }
-                    else
-                    {
-                        assert(argx->OperIs(GT_LCL_VAR));
-                        structSize = lvaGetDesc(argx->AsLclVar())->lvExactSize;
-                    }
-                    assert(structSize > 0);
+                    unsigned  structSize =
+                        argx->TypeIs(TYP_STRUCT) ? argx->GetLayout(this)->GetSize() : genTypeSize(argx);
+
                     if (structSize == genTypeSize(hfaType))
                     {
                         if (argx->OperIs(GT_OBJ))
@@ -3731,10 +3719,10 @@ GenTree* Compiler::fgMorphMultiregStructArg(CallArg* arg)
             {
                 argNode = fgMorphLclArgToFieldlist(lcl);
             }
-#ifndef TARGET_XARCH
+#ifdef TARGET_LOONGARCH64
             else if (argNode->TypeGet() == TYP_STRUCT)
             {
-                // ARM/ARM64/LoongArch64 backends do not support local nodes as sources of some stack args.
+                // LoongArch64 backend does not support local nodes as sources of some stack args.
                 if (!actualArg->OperIs(GT_OBJ))
                 {
                     // Create an Obj of the temp to use it as a call argument.
@@ -3744,7 +3732,7 @@ GenTree* Compiler::fgMorphMultiregStructArg(CallArg* arg)
                 // Its fields will need to be accessed by address.
                 lvaSetVarDoNotEnregister(lcl->GetLclNum() DEBUGARG(DoNotEnregisterReason::IsStructArg));
             }
-#endif // !TARGET_XARCH
+#endif // TARGET_LOONGARCH64
         }
 
         return argNode;