Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Skip the balanced switch dispatch optimization for patterns on floating-point inputs #62322

Merged
merged 1 commit into from
Jul 6, 2022

Conversation

jcouv
Copy link
Member

@jcouv jcouv commented Jul 1, 2022

Fixes #62241

The DAG for the scenario < -40.0 => "Too low", >= -40.0 and < 0 => "Low", ..., double.NaN => "NaN" has a test for t0 < -40 at the top-level. When that test is false, the next test is t0 >= -40. When that test is false, we're in the NaN case (NaN is the only possible remaining value so we don't need an explicit test). That DAG is correct.

Original DAG:
image

But the lowering of DAGs can take multiple relational tests on a given input and convert it into a balanced switch dispatch.
That optimization results in a top-level < 0 test. The < -40.0 and >= -40.0 tests are therefore moved under the true case of that top-level test, and the <= 10 test is under the false case. That is more balanced, but it is incorrect because a NaN input value yields false for any comparison. In that configuration, the path to the NaN case (marked with dotted line) is impossible.

Balanced switch dispatch generated by optimization:
image

I haven't found a way to keep the benefits of the optimization while maintaining proper NaN semantics, so this PR disables the optimization for inputs of floating-point types.

Filed #62390 to explore re-enabling some partial-but-safe optimization.

@jcouv jcouv self-assigned this Jul 1, 2022
@@ -10177,162 +10171,156 @@ static int M(float d)
expectedOutput: expectedOutput);
compVerifier.VerifyIL("C.M", @"
{
// Code size 388 (0x184)
// Code size 374 (0x176)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find it very interesting that the IL is smaller in both of the modified tests. Do we understand that?


if (t1.Input.Type.SpecialType is SpecialType.System_Double or SpecialType.System_Single)
{
// The optimization (using balanced switch dispatch) breaks the semantics of NaN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: consider linking to the issue. up to you.

@CyrusNajmabadi
Copy link
Member

CyrusNajmabadi commented Jul 5, 2022

I haven't found a way to keep the benefits of the optimization while maintaining proper NaN semantics, so this PR disables the optimization for inputs of floating-point types.

From offline discussion: consider doing an upfront nan check against the input to jump to the 'catch-all' case. If the value is not nan, then run the value through the balanced switch case.

@RikkiGibson RikkiGibson self-assigned this Jul 6, 2022
@jcouv jcouv changed the title Skip the balanced switch dispatch optimization for patterns on floating point inputs Skip the balanced switch dispatch optimization for patterns on floating-point inputs Jul 6, 2022
@jcouv jcouv enabled auto-merge (squash) July 6, 2022 19:59
@jcouv jcouv merged commit 04a4764 into dotnet:main Jul 6, 2022
@ghost ghost added this to the Next milestone Jul 6, 2022
333fred added a commit to 333fred/roslyn that referenced this pull request Jul 7, 2022
* upstream/main: (62 commits)
  Prevent assert from being hit (dotnet#62366)
  Don't offer '??=' for pointer types (dotnet#62476)
  Integrate generator times into /reportAnalyzer (dotnet#61661)
  Switch to a callback for cleaning up resources instead of passing in an explicit IDisposable. (dotnet#62373)
  Filter trees to only those containing global-usings or attributes prior to analyzing them. (dotnet#62444)
  Update PublishData.json
  Complete 'file' support for `SyntaxGenerator` (dotnet#62413)
  Apply changes directly to text buffer (dotnet#62337)
  Remove LangVer check from extended nameof binding (dotnet#62339)
  Fixed shared project file error (dotnet#62466)
  Handle new error codes
  Use MSBuid generated property for package path
  Exclude BCL libraries from Roslyn vsix
  Bump the integration test timeouts a bit
  Skip the balanced switch dispatch optimization for patterns on floating-point inputs (dotnet#62322)
  Test helpers shouldn't escape quotes by default (dotnet#62321)
  Reuse prior TableEntry values in the increment NodeTable builder if possible. (dotnet#62320)
  Install 3.1 runtime for SBOM tool
  Generate VS SBOM during official build.
  Minor refactoring in 'required' handling for override completion (dotnet#62422)
  ...
@allisonchou allisonchou modified the milestones: Next, 17.4 P1 Jul 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switch expression using pattern matching on floating point values reports wrong result for double.Nan
5 participants