Fix dotnet/coreclr#7093
authorBruce Forstall <brucefo@microsoft.com>
Fri, 9 Sep 2016 01:09:34 +0000 (18:09 -0700)
committerBruce Forstall <brucefo@microsoft.com>
Fri, 9 Sep 2016 01:09:34 +0000 (18:09 -0700)
This is an assert due to how STRESS_64RSLT_MUL is implemented. This
stress mode converts:
```
/--*  lclVar    int    V01 loc0
*  *         int
\--*  lclVar    int    V01 loc0
```
to:
```
*  cast      int <- long
|  /--*  cast      long <- int
|  |  \--*  lclVar    int    V01 loc0
\--*  *         long
   \--*  cast      long <- long
      \--*  nop       long
         \--*  lclVar    int    V01 loc0
```
Thus, the long 'nop' node is above an 'int' operand node. This led to an assert
in genCodeForTreeLng() that the lclVar was type long, which is isn't.

I added yet another cast under the 'nop' to fix this typing problem:
```
*  cast      int <- long
|  /--*  cast      long <- int
|  |  \--*  lclVar    int    V01 loc0
\--*  *         long
   \--*  cast      long <- long
      \--*  nop       long
         \--*  cast      long <- int
            \--*  lclVar    int    V01 loc0
```

Commit migrated from https://github.com/dotnet/coreclr/commit/c16b6bc96c1aa1edd9a3085a12f12a9df4169da5

src/coreclr/src/jit/flowgraph.cpp

index 1c68bfd..3389d4c 100644 (file)
@@ -19810,15 +19810,32 @@ Compiler::fgWalkResult      Compiler::fgStress64RsltMulCB(GenTreePtr* pTree, fgW
     
     if (tree->gtOper != GT_MUL || tree->gtType != TYP_INT || (tree->gtOverflow())) {
         return WALK_CONTINUE;
-}
+    }
+
+#ifdef DEBUG
+    if (pComp->verbose)
+    {
+        printf("STRESS_64RSLT_MUL before:\n");              
+        pComp->gtDispTree(tree);
+    }
+#endif // DEBUG
 
     // To ensure optNarrowTree() doesn't fold back to the original tree.
+    tree->gtOp.gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp1, TYP_LONG);
     tree->gtOp.gtOp1 = pComp->gtNewOperNode(GT_NOP, TYP_LONG, tree->gtOp.gtOp1); 
     tree->gtOp.gtOp1 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp1, TYP_LONG);
-    tree->gtOp.gtOp2 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp2,  TYP_LONG);
+    tree->gtOp.gtOp2 = pComp->gtNewCastNode(TYP_LONG, tree->gtOp.gtOp2, TYP_LONG);
     tree->gtType = TYP_LONG;
     *pTree = pComp->gtNewCastNode(TYP_INT, tree, TYP_INT);
 
+#ifdef DEBUG
+    if (pComp->verbose)
+    {
+        printf("STRESS_64RSLT_MUL after:\n");              
+        pComp->gtDispTree(*pTree);
+    }
+#endif // DEBUG
+
     return WALK_SKIP_SUBTREES;
 }
 
@@ -19826,7 +19843,7 @@ void                Compiler::fgStress64RsltMul()
 {
     if (!compStressCompile(STRESS_64RSLT_MUL, 20)) {
         return;
-}
+    }
 
     fgWalkAllTreesPre(fgStress64RsltMulCB, (void*)this);
 }