Skip to content

Mono: Min/MinNumber lowering does not preserve the sign of zero #131130

Description

@tannergooding

Description

Mono (observed on the LLVM AOT configuration) does not preserve the sign of zero when lowering Min / MinNumber for floating-point types. Per the BCL contract, double.Min(+0.0, -0.0) (and the float/MinNumber variants) must return -0.0, treating -0.0 as less than +0.0. Mono instead returns +0.0.

Reproduction

using System;
using System.Runtime.CompilerServices;

[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.AggressiveOptimization)]
static double MinNegZeroConst(double value) => double.Min(value, -0.0);

// Expected: -9223372036854775808 (bits of -0.0)
// Mono LLVM AOT actual: 0 (bits of +0.0)
Console.WriteLine(BitConverter.DoubleToInt64Bits(MinNegZeroConst(+0.0)));

The same divergence affects float.Min, double.MinNumber, and float.MinNumber.

Analysis

This surfaced in the CI for #130832: the regression test Runtime_130831 (added to validate a CoreCLR JIT constant-folding fix) fails on the AllSubsets_Mono_LLVMAot_RuntimeTests leg with:

Expected: -9223372036854775808
Actual:   0

The test has been marked [SkipOnMono] referencing this issue so it continues to validate the CoreCLR fix while the Mono divergence is tracked here.

Configuration

  • Mono, LLVM AOT (AllSubsets_Mono_LLVMAot_RuntimeTests), linux-x64 Release.

Note

This issue was authored with the assistance of GitHub Copilot.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions