Skip to content

Inconsistent results for -Float32x4.zero().clamp  #40426

Closed

Description

@bkonyi

The fuzzer caught a bug where clamping -Float32x4.zero() would result in different results depending on whether or not the Float32x4.clamp() operation had been optimized.

In addition, the C implementation of the clamp operation will produce different results from intrinsics for both:

  • x86/x64
  • ARM

DartFuzz reproduction information:

Dart Revision: 00e481a

Isolate (/b/s/w/ituNmYtd/dart_fuzzLUECTE) FP NO-FFI FLAT : KBC-INT-SRC-O3-DebugSIMARM64 - AOT-ReleaseX64: !DIVERGENCE! 1.86:3199948411 (output)

-- BEGIN REPRODUCE  --

dartfuzz.dart --fp --no-ffi --flat --seed 3199948411 /b/s/w/ituNmYtd/dart_fuzzLUECTE/fuzz.dart

-- RUN 1 --

/b/s/w/ir/out/DebugSIMARM64/dart --enable-interpreter --compilation-counter-threshold=-1 --optimization_level=3 --old_gen_heap_size=128 /b/s/w/ituNmYtd/dart_fuzzLUECTE/fuzz.dart

-- RUN 2 --

DART_CONFIGURATION='ReleaseX64' DART_VM_FLAGS='--enable-asserts' /b/s/w/ir/pkg/vm/tool/precompiler2 /b/s/w/ituNmYtd/dart_fuzzLUECTE/fuzz.dart /b/s/w/ituNmYtd/dart_fuzzLUECTE/snapshot
/b/s/w/ir/pkg/vm/tool/dart_precompiled_runtime2 /b/s/w/ituNmYtd/dart_fuzzLUECTE/snapshot

-- END REPRODUCE  --

Activity

  1. added
    area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.
    dartfuzzFound with Dart fuzzing (DartFuzz, libFuzzer, etc.)
    on Jan 31, 2020
  2. aam commented on May 10, 2022

    @aam
    Contributor

    Underlying issue with dart vm producing inconsistent clamp results around zero and negative zero is still relevant, still have to be fixed.

  3. reopened this on May 10, 2022
  4. modulovalue commented on Sep 11, 2026

    @modulovalue
    Contributor

    @lrhn @mkustermann We've solved min/max in #63962 but we haven't solved clamp.

    There are 3 different min/max versions specified for SIMD value types in wasm:

    The clamp intrinsic doesn't seem to carry its weight.

    Someone could want min -> max, pmin -> pmax or relaxed min -> relaxed max. Or maybe a mix, maybe they want to use the intermediate min results?

    I'd like to propose the following new fixed implementation of clamp:

      Float32x4 clamp(Float32x4 lowerLimit, Float32x4 upperLimit) =>
          min(upperLimit).max(lowerLimit);

    On arm64 for F32x4/F64x2 and arm32 F32x4 there's no value at all to having a clamp intrinsic as the assembly is identical to before.

    On x86, we used hardware min/max which is not IEEE, now it will be IEEE all around and correct and we will be able to enable the fuzzer on it* and fix this issue.

    * the fuzzer was disabled on reciprocal and reciprocalSqrt not here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-vmUse area-vm for VM related issues, including code coverage, and the AOT and JIT backends.dartfuzzFound with Dart fuzzing (DartFuzz, libFuzzer, etc.)library-typed-data

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions