Skip to content

JIT: remove assert from postorder return value optimizations#31699

Merged
AndyAyersMS merged 1 commit intodotnet:masterfrom
AndyAyersMS:Fix31665
Feb 4, 2020
Merged

JIT: remove assert from postorder return value optimizations#31699
AndyAyersMS merged 1 commit intodotnet:masterfrom
AndyAyersMS:Fix31665

Conversation

@AndyAyersMS
Copy link
Member

We were trying to assert that we weren't losing side effects when folding
return value trees. But this seems to be more trouble than it is worth as
the set of side effects can also change.

Also re-enable the disabled tests, and make one of them Pri0.

Fixes #31665.

We were trying to assert that we weren't losing side effects when folding
return value trees. But this seems to be more trouble than it is worth as
the set of side effects can also change.

Also re-enable the disabled tests, and make one of them Pri0.

Fixes dotnet#31665.
@AndyAyersMS
Copy link
Member Author

cc @trylek @dotnet/jit-contrib

@BruceForstall
Copy link
Contributor

Reverts #31674

@AndyAyersMS AndyAyersMS merged commit b1d93c8 into dotnet:master Feb 4, 2020
@AndyAyersMS AndyAyersMS deleted the Fix31665 branch February 4, 2020 07:45
@erozenfeld
Copy link
Member

@AndyAyersMS Can you please provide more details? What side effect flag was set on tree and why is it ok to bash to nop with that flag set? Was the flag set incorrectly?

@AndyAyersMS
Copy link
Member Author

Can you please provide more details?

Odd, I thought I had added provided notes on this in the PR or in the issue, but don't see them.

Prior to this change, we would form:

[000008] --CX--------   *  JTRUE     void  
[000007] --CX--------   \--*  EQ        int   
[000005] --CX--------      +--*  CAST_ovfl int <- long
[000033] ---X--------      |  \--*  CAST_ovfl long <- int
[000032] ------------      |     \--*  CNS_INT   int    0x7FFFFFFF
[000006] ------------      \--*  CNS_INT   int    0x7FFFFFFF

With this change, we fold and so get rid of the possibility of overflow exceptions:

Folding long operator with constant nodes into a constant:
               [000033] ---X--------              *  CAST_ovfl long <- int
               [000032] ------------              \--*  CNS_INT   int    0x7FFFFFFF
Bashed to long constant:
               [000033] ------------              *  CNS_INT   long   0x7FFFFFFF

Replacing the return expression placeholder [000004] with [000033]
               [000004] --C---------              *  RET_EXPR  long  (inl return from call [000033])

Inserting the inline return expression
               [000033] ------------              *  CNS_INT   long   0x7FFFFFFF


Folding operator with constant nodes into a constant:
               [000005] --CX--------              *  CAST_ovfl int <- long
               [000033] ------------              \--*  CNS_INT   long   0x7FFFFFFF
Bashed to int constant:
               [000005] ------------              *  CNS_INT   int    0x7FFFFFFF

Folding operator with constant nodes into a constant:
               [000007] --CX--------              *  EQ        int   
               [000005] ------------              +--*  CNS_INT   int    0x7FFFFFFF
               [000006] ------------              \--*  CNS_INT   int    0x7FFFFFFF
Bashed to int constant:
               [000007] ------------              *  CNS_INT   int    1

So as we walk up the tree the parent nodes still have the X flag, even though we've cleared it out in the children, and that was what triggered the assert.

@erozenfeld
Copy link
Member

Perhaps a better fix is to call gtUpdateNodeSideEffects(tree) somewhere near the beginning of fgLateDevirtualization and keep the assert. gtUpdateNodeSideEffects will remove the GTF_CALL flag so we may need to set it back if it's still needed.

@AndyAyersMS
Copy link
Member Author

Do we know if gtUpdateNodeSideEffects works on early IR? I suppose I can find out.

@AndyAyersMS
Copy link
Member Author

I can just update flags in the JTRUE case; we already know we have a constant, so no need to worry about GTF_CALL.

I don't need to do this update for other trees.

diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp
index 9528f473615..23bc843a1d8 100644
--- a/src/coreclr/src/jit/flowgraph.cpp
+++ b/src/coreclr/src/jit/flowgraph.cpp
@@ -22617,8 +22617,10 @@ Compiler::fgWalkResult Compiler::fgLateDevirtualization(GenTree** pTree, fgWalkD
             JITDUMP(" ... found foldable jtrue at [%06u] in BB%02u\n", dspTreeID(tree), block->bbNum);
             noway_assert((block->bbNext->countOfInEdges() > 0) && (block->bbJumpDest->countOfInEdges() > 0));

-            // Had hoped to assert here that we are not losing any
-            // side effects, but can't find a way to express it properly.
+            // We have a constant operand, and should have the all clear to optimize.
+            // Update side effects on the tree, assert there aren't any, and bash to nop.
+            comp->gtUpdateNodeSideEffects(tree);
+            assert((tree->gtFlags & GTF_SIDE_EFFECT) == 0);
             tree->gtBashToNOP();

             BasicBlock* bTaken    = nullptr;

@erozenfeld
Copy link
Member

Sounds good to me.

AndyAyersMS added a commit to AndyAyersMS/runtime that referenced this pull request Feb 6, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Assertion failed '(tree->gtFlags & (GTF_SIDE_EFFECT & ~GTF_CALL)) == 0'

3 participants