Fix VZERoUPPER for HW intrinsic
authorFei Peng <fei.peng@intel.com>
Tue, 8 Jan 2019 23:22:52 +0000 (15:22 -0800)
committerFei Peng <fei.peng@intel.com>
Tue, 8 Jan 2019 23:22:52 +0000 (15:22 -0800)
src/jit/lsra.h
src/jit/lsraxarch.cpp

index e0e33ef..db80795 100644 (file)
@@ -1565,7 +1565,7 @@ private:
     // returns true if the tree can use the read-modify-write memory instruction form
     bool isRMWRegOper(GenTree* tree);
     int BuildMul(GenTree* tree);
-    void SetContainsAVXFlags(bool isFloatingPointType = true, unsigned sizeOfSIMDVector = 0);
+    void SetContainsAVXFlags(unsigned sizeOfSIMDVector = 0);
     // Move the last use bit, if any, from 'fromTree' to 'toTree'; 'fromTree' must be contained.
     void CheckAndMoveRMWLastUse(GenTree* fromTree, GenTree* toTree)
     {
index 6adb574..493463a 100644 (file)
@@ -71,7 +71,10 @@ int LinearScan::BuildNode(GenTree* tree)
     }
 
     // floating type generates AVX instruction (vmovss etc.), set the flag
-    SetContainsAVXFlags(varTypeIsFloating(tree->TypeGet()));
+    if (varTypeIsFloating(tree->TypeGet()))
+    {
+        SetContainsAVXFlags();
+    }
 
     switch (tree->OperGet())
     {
@@ -1881,7 +1884,7 @@ int LinearScan::BuildSIMD(GenTreeSIMD* simdTree)
         assert((simdTree->gtSIMDIntrinsicID == SIMDIntrinsicOpEquality) ||
                (simdTree->gtSIMDIntrinsicID == SIMDIntrinsicOpInEquality));
     }
-    SetContainsAVXFlags(true, simdTree->gtSIMDSize);
+    SetContainsAVXFlags(simdTree->gtSIMDSize);
     GenTree* op1      = simdTree->gtGetOp1();
     GenTree* op2      = simdTree->gtGetOp2();
     int      srcCount = 0;
@@ -2287,9 +2290,12 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
     HWIntrinsicCategory category    = HWIntrinsicInfo::lookupCategory(intrinsicId);
     int                 numArgs     = HWIntrinsicInfo::lookupNumArgs(intrinsicTree);
 
-    if ((isa == InstructionSet_AVX) || (isa == InstructionSet_AVX2))
+    // Set the AVX Flags if this instruction may use VEX encoding for SIMD operations.
+    // Note that this may be true even if the ISA is not AVX (e.g. for platform-agnostic intrinsics
+    // or non-AVX intrinsics that will use VEX encoding if it is available on the target).
+    if (intrinsicTree->isSIMD())
     {
-        SetContainsAVXFlags(true, 32);
+        SetContainsAVXFlags(intrinsicTree->gtSIMDSize);
     }
 
     GenTree* op1    = intrinsicTree->gtGetOp1();
@@ -2856,7 +2862,7 @@ int LinearScan::BuildIndir(GenTreeIndir* indirTree)
 #ifdef FEATURE_SIMD
     if (varTypeIsSIMD(indirTree))
     {
-        SetContainsAVXFlags(true, genTypeSize(indirTree->TypeGet()));
+        SetContainsAVXFlags(genTypeSize(indirTree->TypeGet()));
     }
     buildInternalRegisterUses();
 #endif // FEATURE_SIMD
@@ -2959,9 +2965,9 @@ int LinearScan::BuildMul(GenTree* tree)
 //    isFloatingPointType   - true if it is floating point type
 //    sizeOfSIMDVector      - SIMD Vector size
 //
-void LinearScan::SetContainsAVXFlags(bool isFloatingPointType /* = true */, unsigned sizeOfSIMDVector /* = 0*/)
+void LinearScan::SetContainsAVXFlags(unsigned sizeOfSIMDVector /* = 0*/)
 {
-    if (isFloatingPointType && compiler->canUseVexEncoding())
+    if (compiler->canUseVexEncoding())
     {
         compiler->getEmitter()->SetContainsAVX(true);
         if (sizeOfSIMDVector == 32)