ARM64: Fix Liveness update for Division By Zero
authorKyungwoo Lee <kyulee@microsoft.com>
Wed, 25 May 2016 15:38:59 +0000 (08:38 -0700)
committerKyungwoo Lee <kyulee@microsoft.com>
Fri, 27 May 2016 04:18:48 +0000 (21:18 -0700)
We've missed updating liveness when converting division by zero to a
throw. This fixes an assertion failure in `assert(!varDsc->lvIsRegCandidate());` in
codegenarm64.cpp/L1903.
genConsumeOperands() is factored out of genCodeForBinary(). The call sites
appropriately invoke genConsumeOperands() to update liveness.

src/jit/codegenarm64.cpp
src/jit/codegenxarch.cpp
tests/arm64/Tests.lst

index 067e788..dcbdcfd 100644 (file)
@@ -2328,6 +2328,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* treeNode)
 }
 
 // Generate code for ADD, SUB, MUL, DIV, UDIV, AND, OR and XOR
+// This method is expected to have called genConsumeOperands() before calling it.
 void CodeGen::genCodeForBinary(GenTree* treeNode)
 {
     const genTreeOps oper = treeNode->OperGet();
@@ -2343,7 +2344,7 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
             oper == GT_AND  ||
             oper == GT_OR   || 
             oper == GT_XOR);
-        
+
     GenTreePtr op1 = treeNode->gtGetOp1();
     GenTreePtr op2 = treeNode->gtGetOp2();
     instruction ins = genGetInsForOper(treeNode->OperGet(), targetType);
@@ -2351,8 +2352,6 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
     // The arithmetic node must be sitting in a register (since it's not contained)
     noway_assert(targetReg != REG_NA);
 
-    genConsumeOperands(treeNode->AsOp());
-
     regNumber r = emit->emitInsTernary(ins, emitTypeSize(treeNode), treeNode, op1, op2);
     noway_assert(r == targetReg);
 
@@ -2453,10 +2452,12 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
 
     case GT_DIV:
     case GT_UDIV:
+        genConsumeOperands(treeNode->AsOp());
+
         if (varTypeIsFloating(targetType))
         {
             // Floating point divide never raises an exception
-            genCodeForBinary(treeNode);     
+            genCodeForBinary(treeNode);
         }
         else  // an integer divide operation
         {
@@ -2464,7 +2465,7 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
             emitAttr   size      = EA_ATTR(genTypeSize(genActualType(treeNode->TypeGet())));
 
             // TODO-ARM64-CQ: Optimize a divide by power of 2 as we do for AMD64
-            
+
             if (divisorOp->IsZero())
             {
                 // We unconditionally throw a divide by zero exception
@@ -2546,7 +2547,7 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
                         emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
                         genJumpToThrowHlpBlk(jmpEqual, SCK_DIV_BY_ZERO);
                     }
-                    genCodeForBinary(treeNode); 
+                    genCodeForBinary(treeNode);
                 }
             }
         }
@@ -2560,6 +2561,7 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
     case GT_ADD:
     case GT_SUB:
     case GT_MUL:
+        genConsumeOperands(treeNode->AsOp());
         genCodeForBinary(treeNode);
         break;
 
index 936ec2f..0940d27 100755 (executable)
@@ -1328,6 +1328,7 @@ void CodeGen::genCodeForDivMod(GenTreeOp* treeNode)
 
 //------------------------------------------------------------------------
 // genCodeForBinary: Generate code for many binary arithmetic operators
+// This method is expected to have called genConsumeOperands() before calling it.
 //
 // Arguments:
 //    treeNode - The binary operation for which we are generating code.
@@ -1389,8 +1390,6 @@ void CodeGen::genCodeForBinary(GenTree* treeNode)
     GenTreePtr dst;
     GenTreePtr src;
 
-    genConsumeOperands(treeNode->AsOp());
-
     // This is the case of reg1 = reg1 op reg2
     // We're ready to emit the instruction without any moves
     if (op1reg == targetReg)
@@ -1958,6 +1957,7 @@ CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
 #endif // !defined(_TARGET_64BIT_)
     case GT_ADD:
     case GT_SUB:
+        genConsumeOperands(treeNode->AsOp());
         genCodeForBinary(treeNode);
         break;
 
index 4b2b853..c5dcb59 100644 (file)
@@ -9503,7 +9503,7 @@ RelativePath=CoreMangLib\cti\system\dividebyzeroexception\DivideByZeroExceptionC
 WorkingDir=CoreMangLib\cti\system\dividebyzeroexception\DivideByZeroExceptionCtor
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=Pri1;RT;EXPECTED_FAIL;REGRESS
+Categories=Pri1;RT;EXPECTED_PASS
 HostStyle=0
 [DivideByZeroExceptionCtor2.cmd_1358]
 RelativePath=CoreMangLib\cti\system\dividebyzeroexception\DivideByZeroExceptionCtor2\DivideByZeroExceptionCtor2.cmd
@@ -18890,7 +18890,7 @@ RelativePath=CoreMangLib\cti\system\type\TypeGetType1\TypeGetType1.cmd
 WorkingDir=CoreMangLib\cti\system\type\TypeGetType1
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=Pri1;RT;EXPECTED_FAIL;REGRESS
+Categories=Pri1;RT;EXPECTED_PASS
 HostStyle=0
 [TypeGetType2.cmd_2699]
 RelativePath=CoreMangLib\cti\system\type\TypeGetType2\TypeGetType2.cmd