[release/6.0] Fix incorrect SIMD temp allocation for Vector256 with AVX2 disabled...
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Thu, 9 Sep 2021 18:18:26 +0000 (11:18 -0700)
committerGitHub <noreply@github.com>
Thu, 9 Sep 2021 18:18:26 +0000 (11:18 -0700)
* Fix incorrect SIMD temp allocation for Vector256 with AVX2 disabled

The NI_Vector256_GetElement intrinsic, in some situations, requires
a stack temporary. With AVX2 disabled, this temporary was getting
allocated as a TYP_SIMD16 instead of a TYP_SIMD32, leading to overwriting
the local variable.

Add a type argument to the temp variable allocation, and allocate the
temp as the largest sized type required by any use.

Fixes #58295

* Code review change: improve arm64 SIMD temp creation type

Co-authored-by: Bruce Forstall <brucefo@microsoft.com>
src/coreclr/jit/compiler.h
src/coreclr/jit/lsraarm64.cpp
src/coreclr/jit/lsraxarch.cpp
src/coreclr/jit/simd.cpp

index 3f87194..cabde31 100644 (file)
@@ -8915,15 +8915,7 @@ public:
     }
 
 private:
-    unsigned getSIMDInitTempVarNum()
-    {
-        if (lvaSIMDInitTempVarNum == BAD_VAR_NUM)
-        {
-            lvaSIMDInitTempVarNum                  = lvaGrabTempWithImplicitUse(false DEBUGARG("SIMDInitTempVar"));
-            lvaTable[lvaSIMDInitTempVarNum].lvType = getSIMDVectorType();
-        }
-        return lvaSIMDInitTempVarNum;
-    }
+    unsigned getSIMDInitTempVarNum(var_types simdType);
 
 #else  // !FEATURE_SIMD
     bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
index a7a14fd..88644ea 100644 (file)
@@ -1132,7 +1132,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
                 {
                     // If the index is not a constant or op1 is in register,
                     // we will use the SIMD temp location to store the vector.
-                    compiler->getSIMDInitTempVarNum();
+                    var_types requiredSimdTempType = (intrin.id == NI_Vector64_GetElement) ? TYP_SIMD8 : TYP_SIMD16;
+                    compiler->getSIMDInitTempVarNum(requiredSimdTempType);
                 }
             }
 
index f440182..5ccb43d 100644 (file)
@@ -2201,7 +2201,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
                 {
                     // If the index is not a constant or op1 is in register,
                     // we will use the SIMD temp location to store the vector.
-                    compiler->getSIMDInitTempVarNum();
+                    var_types requiredSimdTempType = (intrinsicId == NI_Vector128_GetElement) ? TYP_SIMD16 : TYP_SIMD32;
+                    compiler->getSIMDInitTempVarNum(requiredSimdTempType);
                 }
                 break;
             }
index 2eb0fca..ef5e482 100644 (file)
@@ -107,6 +107,34 @@ int Compiler::getSIMDTypeAlignment(var_types simdType)
 #endif
 }
 
+//------------------------------------------------------------------------
+// Get, and allocate if necessary, the SIMD temp used for various operations.
+// The temp is allocated as the maximum sized type of all operations required.
+//
+// Arguments:
+//    simdType - Required SIMD type
+//
+// Returns:
+//    The temp number
+//
+unsigned Compiler::getSIMDInitTempVarNum(var_types simdType)
+{
+    if (lvaSIMDInitTempVarNum == BAD_VAR_NUM)
+    {
+        JITDUMP("Allocating SIMDInitTempVar as %s\n", varTypeName(simdType));
+        lvaSIMDInitTempVarNum                  = lvaGrabTempWithImplicitUse(false DEBUGARG("SIMDInitTempVar"));
+        lvaTable[lvaSIMDInitTempVarNum].lvType = simdType;
+    }
+    else if (genTypeSize(lvaTable[lvaSIMDInitTempVarNum].lvType) < genTypeSize(simdType))
+    {
+        // We want the largest required type size for the temp.
+        JITDUMP("Increasing SIMDInitTempVar type size from %s to %s\n",
+                varTypeName(lvaTable[lvaSIMDInitTempVarNum].lvType), varTypeName(simdType));
+        lvaTable[lvaSIMDInitTempVarNum].lvType = simdType;
+    }
+    return lvaSIMDInitTempVarNum;
+}
+
 //----------------------------------------------------------------------------------
 // Return the base type and size of SIMD vector type given its type handle.
 //