Merge pull request #16422 from CarolEidt/Fix15037
authorCarol Eidt <carol.eidt@microsoft.com>
Sun, 18 Feb 2018 17:28:16 +0000 (09:28 -0800)
committerGitHub <noreply@github.com>
Sun, 18 Feb 2018 17:28:16 +0000 (09:28 -0800)
Don't set delayRegFree if no target

src/jit/lsra.cpp
src/jit/lsraarm64.cpp
src/jit/lsraxarch.cpp

index 276f3a4..4898968 100644 (file)
@@ -5248,16 +5248,23 @@ void LinearScan::allocateRegisters()
 
         if ((regsToFree | delayRegsToFree) != RBM_NONE)
         {
-            bool doFreeRegs = false;
             // Free at a new location, or at a basic block boundary
-            if (currentLocation > prevLocation || refType == RefTypeBB)
+            if (refType == RefTypeBB)
             {
-                doFreeRegs = true;
+                assert(currentLocation > prevLocation);
             }
-
-            if (doFreeRegs)
+            if (currentLocation > prevLocation)
             {
                 freeRegisters(regsToFree);
+                if ((currentLocation > (prevLocation + 1)) && (delayRegsToFree != RBM_NONE))
+                {
+                    // We should never see a delayReg that is delayed until a Location that has no RefPosition
+                    // (that would be the RefPosition that it was supposed to interfere with).
+                    assert(!"Found a delayRegFree associated with Location with no reference");
+                    // However, to be cautious for the Release build case, we will free them.
+                    freeRegisters(delayRegsToFree);
+                    delayRegsToFree = RBM_NONE;
+                }
                 regsToFree      = delayRegsToFree;
                 delayRegsToFree = RBM_NONE;
             }
index d74c080..5346945 100644 (file)
@@ -403,18 +403,24 @@ void LinearScan::BuildNode(GenTree* tree)
             // it may be used used multiple during retries
             assert(!tree->gtOp.gtOp1->isContained());
             LocationInfoListNode* op1Info = getLocationInfo(tree->gtOp.gtOp1);
-            op1Info->info.isDelayFree     = true;
             useList.Append(op1Info);
+            LocationInfoListNode* op2Info = nullptr;
             if (!tree->gtOp.gtOp2->isContained())
             {
-                LocationInfoListNode* op2Info = getLocationInfo(tree->gtOp.gtOp2);
-                op2Info->info.isDelayFree     = true;
+                op2Info = getLocationInfo(tree->gtOp.gtOp2);
                 useList.Append(op2Info);
             }
-            info->hasDelayFreeSrc = true;
-
-            // Internals may not collide with target
-            info->isInternalRegDelayFree = true;
+            if (info->dstCount != 0)
+            {
+                op1Info->info.isDelayFree = true;
+                if (op2Info != nullptr)
+                {
+                    op2Info->info.isDelayFree = true;
+                }
+                // Internals may not collide with target
+                info->isInternalRegDelayFree = true;
+                info->hasDelayFreeSrc        = true;
+            }
         }
         break;
 
index 63db1b0..2164cfa 100644 (file)
@@ -607,7 +607,7 @@ void LinearScan::BuildNode(GenTree* tree)
 
             // Is this a non-commutative operator, or is op2 a contained memory op?
             // In either case, we need to make op2 remain live until the op is complete, by marking
-            // the source(s) associated with op2 as "delayFree".
+            // the source(s) associated with op2 as "delayFree" if this node defines a register.
             // Note that if op2 of a binary RMW operator is a memory op, even if the operator
             // is commutative, codegen cannot reverse them.
             // TODO-XArch-CQ: This is not actually the case for all RMW binary operators, but there's
@@ -650,7 +650,8 @@ void LinearScan::BuildNode(GenTree* tree)
 
                 delayUseSrc = op1;
             }
-            else if ((op2 != nullptr) && (!tree->OperIsCommutative() || (op2->isContained() && !op2->IsCnsIntOrI())))
+            else if ((info->dstCount != 0) && (op2 != nullptr) &&
+                     (!tree->OperIsCommutative() || (op2->isContained() && !op2->IsCnsIntOrI())))
             {
                 delayUseSrc = op2;
             }