diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index 70a82004ffa1bd..d1e56fbe33766b 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -13308,6 +13308,20 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) bool foundVal = false; bool profileInconsistent = false; + if (block->hasProfileWeight()) + { + // Use unique successor edges, as duplicate jump table entries share an edge. + for (FlowEdge* const succEdge : block->SuccEdges()) + { + BasicBlock* const targetBlock = succEdge->getDestinationBlock(); + if (targetBlock->hasProfileWeight()) + { + targetBlock->decreaseBBProfileWeight(succEdge->getLikelyWeight()); + profileInconsistent |= (targetBlock->NumSucc() > 0); + } + } + } + for (unsigned val = 0; val < jumpCnt; val++, jumpTab++) { FlowEdge* curEdge = *jumpTab; @@ -13315,11 +13329,6 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) assert(curEdge->getDestinationBlock()->countOfInEdges() > 0); BasicBlock* const targetBlock = curEdge->getDestinationBlock(); - if (block->hasProfileWeight() && targetBlock->hasProfileWeight()) - { - targetBlock->decreaseBBProfileWeight(curEdge->getLikelyWeight()); - profileInconsistent |= (targetBlock->NumSucc() > 0); - } // If val matches switchVal or we are at the last entry and // we never found the switch value then set the new jump dest diff --git a/src/tests/JIT/Regression_ro_2/Runtime_134896.cs b/src/tests/JIT/Regression_ro_2/Runtime_134896.cs new file mode 100644 index 00000000000000..561cfd8661b13e --- /dev/null +++ b/src/tests/JIT/Regression_ro_2/Runtime_134896.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_134896 +{ + private static int Zero() => 0; + + [MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)] + private static int Test(int a) + { + switch (Zero()) + { + default: return a + 2; + case 0: case 1: return a; + case 2: return a + 1; + case 3: return a * 3; + } + } + + [Fact] + public static void TestEntryPoint() + { + Assert.Equal(5, Test(5)); + } +}