mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
30f25ba735
The fuzzer found an issue where clamping negative zero would result in conflicting answers depending on whether or not the clamp operation had been optimized in JIT mode. The MINPS and MAXPS instructions will always return the second operand if the values being compared are -0 and 0, which is the opposite of what the C implementation of clamp was doing. Fixes https://github.com/dart-lang/sdk/issues/40426. Change-Id: I3afb725bd0c8643758dbe753d863ba93c86ad747 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/134093 Reviewed-by: Alexander Markov <alexmarkov@google.com>
72 lines
2.2 KiB
Dart
72 lines
2.2 KiB
Dart
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
|
|
|
|
// Library tag to be able to run in html test framework.
|
|
library float32x4_clamp_test;
|
|
|
|
import 'dart:typed_data';
|
|
import 'package:expect/expect.dart';
|
|
|
|
void testClampLowerGreaterThanUpper() {
|
|
Float32x4 l = new Float32x4(1.0, 1.0, 1.0, 1.0);
|
|
Float32x4 u = new Float32x4(-1.0, -1.0, -1.0, -1.0);
|
|
Float32x4 z = new Float32x4.zero();
|
|
Float32x4 a = z.clamp(l, u);
|
|
Expect.equals(a.x, 1.0);
|
|
Expect.equals(a.y, 1.0);
|
|
Expect.equals(a.z, 1.0);
|
|
Expect.equals(a.w, 1.0);
|
|
}
|
|
|
|
void testClamp() {
|
|
Float32x4 l = new Float32x4(-1.0, -1.0, -1.0, -1.0);
|
|
Float32x4 u = new Float32x4(1.0, 1.0, 1.0, 1.0);
|
|
Float32x4 z = new Float32x4.zero();
|
|
Float32x4 a = z.clamp(l, u);
|
|
Expect.equals(a.x, 0.0);
|
|
Expect.equals(a.y, 0.0);
|
|
Expect.equals(a.z, 0.0);
|
|
Expect.equals(a.w, 0.0);
|
|
}
|
|
|
|
Float32x4 negativeZeroClamp() {
|
|
final negZero = -Float32x4.zero();
|
|
return negZero.clamp(negZero, Float32x4.zero());
|
|
}
|
|
|
|
Float32x4 zeroClamp() {
|
|
final negOne = -Float32x4(1.0, 1.0, 1.0, 1.0);
|
|
return Float32x4.zero().clamp(negOne, -Float32x4.zero());
|
|
}
|
|
|
|
// Regression test for https://github.com/dart-lang/sdk/issues/40426.
|
|
void testNegativeZeroClamp(Float32x4 unopt) {
|
|
final res = negativeZeroClamp();
|
|
Expect.equals(res.x.compareTo(unopt.x), 0);
|
|
Expect.equals(res.y.compareTo(unopt.y), 0);
|
|
Expect.equals(res.z.compareTo(unopt.z), 0);
|
|
Expect.equals(res.w.compareTo(unopt.w), 0);
|
|
}
|
|
|
|
// Regression test for https://github.com/dart-lang/sdk/issues/40426.
|
|
void testZeroClamp(Float32x4 unopt) {
|
|
final res = zeroClamp();
|
|
Expect.equals(res.x.compareTo(unopt.x), 0);
|
|
Expect.equals(res.y.compareTo(unopt.y), 0);
|
|
Expect.equals(res.z.compareTo(unopt.z), 0);
|
|
Expect.equals(res.w.compareTo(unopt.w), 0);
|
|
}
|
|
|
|
main() {
|
|
final unoptNegZeroClamp = negativeZeroClamp();
|
|
final unoptZeroClamp = zeroClamp();
|
|
for (int i = 0; i < 2000; i++) {
|
|
testClampLowerGreaterThanUpper();
|
|
testClamp();
|
|
testNegativeZeroClamp(unoptNegZeroClamp);
|
|
testZeroClamp(unoptZeroClamp);
|
|
}
|
|
}
|