Skip to content

Commit

Permalink
JIT: Don't fold NEG(NEG(X)) to X when NEG(x) is a CSE candidate (#57478)
Browse files Browse the repository at this point in the history
  • Loading branch information
EgorBo authored Aug 17, 2021
1 parent d6b35bb commit 492a520
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
12 changes: 8 additions & 4 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13114,13 +13114,17 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac)
case GT_NEG:
// Remove double negation/not.
// Note: this is not a safe tranformation if "tree" is a CSE candidate.
// Consider for example the following expression: NEG(NEG(OP)), where the top-level
// Consider for example the following expression: NEG(NEG(OP)), where any
// NEG is a CSE candidate. Were we to morph this to just OP, CSE would fail to find
// the original NEG in the statement.
if (op1->OperIs(oper) && opts.OptimizationEnabled() && !gtIsActiveCSE_Candidate(tree))
if (op1->OperIs(oper) && opts.OptimizationEnabled() && !gtIsActiveCSE_Candidate(tree) &&
!gtIsActiveCSE_Candidate(op1))
{
GenTree* child = op1->AsOp()->gtGetOp1();
return child;
JITDUMP("Remove double negation/not\n")
GenTree* op1op1 = op1->gtGetOp1();
DEBUG_DESTROY_NODE(tree);
DEBUG_DESTROY_NODE(op1);
return op1op1;
}

// Distribute negation over simple multiplication/division expressions
Expand Down
50 changes: 50 additions & 0 deletions src/tests/JIT/opt/perf/doublenegate/GitHub_57470.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// This file is auto-generated.
// Seed: -1
//
using System;
using System.Runtime.CompilerServices;
public class TestClass8505
{
static int s_int32_6 = -5;
static sbyte s_sbyte_8 = 2;
static int s_loopInvariant = 3;
public sbyte LeafMethod8()
{
unchecked
{
return s_sbyte_8 <<= s_int32_6 >>= s_int32_6 ^ (-2 - (s_int32_6 &= -5)) / (-1 * s_int32_6 * (2 ^ -2)) + 77;
}
}
public void Method0()
{
unchecked
{
try
{
}
finally
{
{
int __loopvar1 = s_loopInvariant, __loopSecondaryVar1_0 = 15 - 4;
do
{
}
while (15 % 4 > LeafMethod8() / 15 + 4);
}
{
}
}
return;
}
}
public static int Main(string[] args)
{
TestClass8505 objTestClass8505 = new TestClass8505();
objTestClass8505.Method0();
return 100;
}
}
9 changes: 9 additions & 0 deletions src/tests/JIT/opt/perf/doublenegate/GitHub_57470.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<DebugType>None</DebugType>
</PropertyGroup>
<ItemGroup>
<Compile Include="GitHub_57470.cs" />
</ItemGroup>
</Project>

0 comments on commit 492a520

Please sign in to comment.