ART: inline Math.Max/Min (float and double)
This implements the inlined version of Math.Max/Min intrinsics.
Change-Id: I2db8fa7603db3cdf01016ec26811a96f91b1e6ed
Signed-off-by: Alexei Zavjalov <alexei.zavjalov@intel.com>
Signed-off-by: Shou, Yixin <yixin.shou@intel.com>
diff --git a/compiler/dex/quick/x86/assemble_x86.cc b/compiler/dex/quick/x86/assemble_x86.cc
index ebe3f0a..efd9079 100644
--- a/compiler/dex/quick/x86/assemble_x86.cc
+++ b/compiler/dex/quick/x86/assemble_x86.cc
@@ -367,7 +367,11 @@
EXT_0F_ENCODING_MAP(Ucomiss, 0x00, 0x2E, SETS_CCODES|REG_USE0),
EXT_0F_ENCODING_MAP(Comisd, 0x66, 0x2F, SETS_CCODES|REG_USE0),
EXT_0F_ENCODING_MAP(Comiss, 0x00, 0x2F, SETS_CCODES|REG_USE0),
+ EXT_0F_ENCODING_MAP(Orpd, 0x66, 0x56, REG_DEF0_USE0),
EXT_0F_ENCODING_MAP(Orps, 0x00, 0x56, REG_DEF0_USE0),
+ EXT_0F_ENCODING_MAP(Andpd, 0x66, 0x54, REG_DEF0_USE0),
+ EXT_0F_ENCODING_MAP(Andps, 0x00, 0x54, REG_DEF0_USE0),
+ EXT_0F_ENCODING_MAP(Xorpd, 0x66, 0x57, REG_DEF0_USE0),
EXT_0F_ENCODING_MAP(Xorps, 0x00, 0x57, REG_DEF0_USE0),
EXT_0F_ENCODING_MAP(Addsd, 0xF2, 0x58, REG_DEF0_USE0),
EXT_0F_ENCODING_MAP(Addss, 0xF3, 0x58, REG_DEF0_USE0),
diff --git a/compiler/dex/quick/x86/codegen_x86.h b/compiler/dex/quick/x86/codegen_x86.h
index cf4521a..a67a5c8 100644
--- a/compiler/dex/quick/x86/codegen_x86.h
+++ b/compiler/dex/quick/x86/codegen_x86.h
@@ -173,6 +173,7 @@
void GenConversion(Instruction::Code opcode, RegLocation rl_dest, RegLocation rl_src);
bool GenInlinedCas(CallInfo* info, bool is_long, bool is_object);
bool GenInlinedMinMax(CallInfo* info, bool is_min, bool is_long);
+ bool GenInlinedMinMaxFP(CallInfo* info, bool is_min, bool is_double);
bool GenInlinedSqrt(CallInfo* info);
bool GenInlinedAbsFloat(CallInfo* info) OVERRIDE;
bool GenInlinedAbsDouble(CallInfo* info) OVERRIDE;
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index fc65deb..62053fd 100755
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -705,4 +705,77 @@
}
}
+bool X86Mir2Lir::GenInlinedMinMaxFP(CallInfo* info, bool is_min, bool is_double) {
+ if (is_double) {
+ RegLocation rl_src1 = LoadValueWide(info->args[0], kFPReg);
+ RegLocation rl_src2 = LoadValueWide(info->args[2], kFPReg);
+ RegLocation rl_dest = InlineTargetWide(info);
+ RegLocation rl_result = EvalLocWide(rl_dest, kFPReg, true);
+
+ // Avoid src2 corruption by OpRegCopyWide.
+ if (rl_result.reg == rl_src2.reg) {
+ std::swap(rl_src2.reg, rl_src1.reg);
+ }
+
+ OpRegCopyWide(rl_result.reg, rl_src1.reg);
+ NewLIR2(kX86UcomisdRR, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ // If either arg is NaN, return NaN.
+ LIR* branch_nan = NewLIR2(kX86Jcc8, 0, kX86CondP);
+ // Min/Max branches.
+ LIR* branch_cond1 = NewLIR2(kX86Jcc8, 0, (is_min) ? kX86CondA : kX86CondB);
+ LIR* branch_cond2 = NewLIR2(kX86Jcc8, 0, (is_min) ? kX86CondB : kX86CondA);
+ // If equal, we need to resolve situations like min/max(0.0, -0.0) == -0.0/0.0.
+ NewLIR2((is_min) ? kX86OrpdRR : kX86AndpdRR, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ LIR* branch_exit_equal = NewLIR1(kX86Jmp8, 0);
+ // Handle NaN.
+ branch_nan->target = NewLIR0(kPseudoTargetLabel);
+ LoadConstantWide(rl_result.reg, INT64_C(0x7ff8000000000000));
+ LIR* branch_exit_nan = NewLIR1(kX86Jmp8, 0);
+ // Handle Min/Max. Copy greater/lesser value from src2.
+ branch_cond1->target = NewLIR0(kPseudoTargetLabel);
+ OpRegCopyWide(rl_result.reg, rl_src2.reg);
+ // Right operand is already in result reg.
+ branch_cond2->target = NewLIR0(kPseudoTargetLabel);
+ // Exit.
+ branch_exit_nan->target = NewLIR0(kPseudoTargetLabel);
+ branch_exit_equal->target = NewLIR0(kPseudoTargetLabel);
+ StoreValueWide(rl_dest, rl_result);
+ } else {
+ RegLocation rl_src1 = LoadValue(info->args[0], kFPReg);
+ RegLocation rl_src2 = LoadValue(info->args[1], kFPReg);
+ RegLocation rl_dest = InlineTarget(info);
+ RegLocation rl_result = EvalLoc(rl_dest, kFPReg, true);
+
+ // Avoid src2 corruption by OpRegCopyWide.
+ if (rl_result.reg == rl_src2.reg) {
+ std::swap(rl_src2.reg, rl_src1.reg);
+ }
+
+ OpRegCopy(rl_result.reg, rl_src1.reg);
+ NewLIR2(kX86UcomissRR, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ // If either arg is NaN, return NaN.
+ LIR* branch_nan = NewLIR2(kX86Jcc8, 0, kX86CondP);
+ // Min/Max branches.
+ LIR* branch_cond1 = NewLIR2(kX86Jcc8, 0, (is_min) ? kX86CondA : kX86CondB);
+ LIR* branch_cond2 = NewLIR2(kX86Jcc8, 0, (is_min) ? kX86CondB : kX86CondA);
+ // If equal, we need to resolve situations like min/max(0.0, -0.0) == -0.0/0.0.
+ NewLIR2((is_min) ? kX86OrpsRR : kX86AndpsRR, rl_result.reg.GetReg(), rl_src2.reg.GetReg());
+ LIR* branch_exit_equal = NewLIR1(kX86Jmp8, 0);
+ // Handle NaN.
+ branch_nan->target = NewLIR0(kPseudoTargetLabel);
+ LoadConstantNoClobber(rl_result.reg, 0x7fc00000);
+ LIR* branch_exit_nan = NewLIR1(kX86Jmp8, 0);
+ // Handle Min/Max. Copy greater/lesser value from src2.
+ branch_cond1->target = NewLIR0(kPseudoTargetLabel);
+ OpRegCopy(rl_result.reg, rl_src2.reg);
+ // Right operand is already in result reg.
+ branch_cond2->target = NewLIR0(kPseudoTargetLabel);
+ // Exit.
+ branch_exit_nan->target = NewLIR0(kPseudoTargetLabel);
+ branch_exit_equal->target = NewLIR0(kPseudoTargetLabel);
+ StoreValue(rl_dest, rl_result);
+ }
+ return true;
+}
+
} // namespace art
diff --git a/compiler/dex/quick/x86/utility_x86.cc b/compiler/dex/quick/x86/utility_x86.cc
index 047a65d..bae01d9 100644
--- a/compiler/dex/quick/x86/utility_x86.cc
+++ b/compiler/dex/quick/x86/utility_x86.cc
@@ -1050,6 +1050,7 @@
->IsIntrinsic(index, &method)) {
switch (method.opcode) {
case kIntrinsicAbsDouble:
+ case kIntrinsicMinMaxDouble:
store_method_addr_ = true;
break;
default:
diff --git a/compiler/dex/quick/x86/x86_lir.h b/compiler/dex/quick/x86/x86_lir.h
index 17f9b91..500c6b8 100644
--- a/compiler/dex/quick/x86/x86_lir.h
+++ b/compiler/dex/quick/x86/x86_lir.h
@@ -534,10 +534,14 @@
Binary0fOpCode(kX86Ucomiss), // unordered float compare
Binary0fOpCode(kX86Comisd), // double compare
Binary0fOpCode(kX86Comiss), // float compare
- Binary0fOpCode(kX86Orps), // or of floating point registers
- Binary0fOpCode(kX86Xorps), // xor of floating point registers
- Binary0fOpCode(kX86Addsd), // double add
- Binary0fOpCode(kX86Addss), // float add
+ Binary0fOpCode(kX86Orpd), // double logical OR
+ Binary0fOpCode(kX86Orps), // float logical OR
+ Binary0fOpCode(kX86Andpd), // double logical AND
+ Binary0fOpCode(kX86Andps), // float logical AND
+ Binary0fOpCode(kX86Xorpd), // double logical XOR
+ Binary0fOpCode(kX86Xorps), // float logical XOR
+ Binary0fOpCode(kX86Addsd), // double ADD
+ Binary0fOpCode(kX86Addss), // float ADD
Binary0fOpCode(kX86Mulsd), // double multiply
Binary0fOpCode(kX86Mulss), // float multiply
Binary0fOpCode(kX86Cvtsd2ss), // double to float
diff --git a/test/082-inline-execute/src/Main.java b/test/082-inline-execute/src/Main.java
index 1c3c89e..9ecc0a0 100644
--- a/test/082-inline-execute/src/Main.java
+++ b/test/082-inline-execute/src/Main.java
@@ -66,25 +66,6 @@
test_Memory_pokeLong();
}
- /*
- * Determine if two floating point numbers are approximately equal.
- *
- * (Assumes that floating point is generally working, so we can't use
- * this for the first set of tests.)
- */
- static boolean approxEqual(float a, float b, float maxDelta) {
- if (a > b)
- return (a - b) < maxDelta;
- else
- return (b - a) < maxDelta;
- }
- static boolean approxEqual(double a, double b, double maxDelta) {
- if (a > b)
- return (a - b) < maxDelta;
- else
- return (b - a) < maxDelta;
- }
-
/**
* Will test inlining Thread.currentThread().
*/
@@ -340,39 +321,59 @@
}
public static void test_Math_min_F() {
- Assert.assertTrue(approxEqual(Math.min(0.0f, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.min(1.0f, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.min(0.0f, 1.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.min(0.0f, Float.MAX_VALUE), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.min(Float.MIN_VALUE, 0.0f), Float.MIN_VALUE, 0.001f));
- Assert.assertTrue(approxEqual(Math.min(Float.MIN_VALUE, Float.MAX_VALUE), Float.MIN_VALUE, 0.001f));
+ Assert.assertTrue(Float.isNaN(Math.min(1.0f, Float.NaN)));
+ Assert.assertTrue(Float.isNaN(Math.min(Float.NaN, 1.0f)));
+ Assert.assertEquals(Math.min(-0.0f, 0.0f), -0.0f);
+ Assert.assertEquals(Math.min(0.0f, -0.0f), -0.0f);
+ Assert.assertEquals(Math.min(-0.0f, -0.0f), -0.0f);
+ Assert.assertEquals(Math.min(0.0f, 0.0f), 0.0f);
+ Assert.assertEquals(Math.min(1.0f, 0.0f), 0.0f);
+ Assert.assertEquals(Math.min(0.0f, 1.0f), 0.0f);
+ Assert.assertEquals(Math.min(0.0f, Float.MAX_VALUE), 0.0f);
+ Assert.assertEquals(Math.min(Float.MIN_VALUE, 0.0f), 0.0f);
+ Assert.assertEquals(Math.min(Float.MIN_VALUE, Float.MAX_VALUE), Float.MIN_VALUE);
}
public static void test_Math_max_F() {
- Assert.assertTrue(approxEqual(Math.max(0.0f, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.max(1.0f, 0.0f), 1.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.max(0.0f, 1.0f), 1.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.max(0.0f, Float.MAX_VALUE), Float.MAX_VALUE, 0.001f));
- Assert.assertTrue(approxEqual(Math.max(Float.MIN_VALUE, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(Math.max(Float.MIN_VALUE, Float.MAX_VALUE), Float.MAX_VALUE, 0.001f));
+ Assert.assertTrue(Float.isNaN(Math.max(1.0f, Float.NaN)));
+ Assert.assertTrue(Float.isNaN(Math.max(Float.NaN, 1.0f)));
+ Assert.assertEquals(Math.max(-0.0f, 0.0f), 0.0f);
+ Assert.assertEquals(Math.max(0.0f, -0.0f), 0.0f);
+ Assert.assertEquals(Math.max(-0.0f, -0.0f), -0.0f);
+ Assert.assertEquals(Math.max(0.0f, 0.0f), 0.0f);
+ Assert.assertEquals(Math.max(1.0f, 0.0f), 1.0f);
+ Assert.assertEquals(Math.max(0.0f, 1.0f), 1.0f);
+ Assert.assertEquals(Math.max(0.0f, Float.MAX_VALUE), Float.MAX_VALUE);
+ Assert.assertEquals(Math.max(Float.MIN_VALUE, 0.0f), Float.MIN_VALUE);
+ Assert.assertEquals(Math.max(Float.MIN_VALUE, Float.MAX_VALUE), Float.MAX_VALUE);
}
public static void test_Math_min_D() {
- Assert.assertTrue(approxEqual(Math.min(0.0d, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.min(1.0d, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.min(0.0d, 1.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.min(0.0d, Double.MAX_VALUE), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.min(Double.MIN_VALUE, 0.0d), Double.MIN_VALUE, 0.001d));
- Assert.assertTrue(approxEqual(Math.min(Double.MIN_VALUE, Double.MAX_VALUE), Double.MIN_VALUE, 0.001d));
+ Assert.assertTrue(Double.isNaN(Math.min(1.0d, Double.NaN)));
+ Assert.assertTrue(Double.isNaN(Math.min(Double.NaN, 1.0d)));
+ Assert.assertEquals(Math.min(-0.0d, 0.0d), -0.0d);
+ Assert.assertEquals(Math.min(0.0d, -0.0d), -0.0d);
+ Assert.assertEquals(Math.min(-0.0d, -0.0d), -0.0d);
+ Assert.assertEquals(Math.min(0.0d, 0.0d), 0.0d);
+ Assert.assertEquals(Math.min(1.0d, 0.0d), 0.0d);
+ Assert.assertEquals(Math.min(0.0d, 1.0d), 0.0d);
+ Assert.assertEquals(Math.min(0.0d, Double.MAX_VALUE), 0.0d);
+ Assert.assertEquals(Math.min(Double.MIN_VALUE, 0.0d), 0.0d);
+ Assert.assertEquals(Math.min(Double.MIN_VALUE, Double.MAX_VALUE), Double.MIN_VALUE);
}
public static void test_Math_max_D() {
- Assert.assertTrue(approxEqual(Math.max(0.0d, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.max(1.0d, 0.0d), 1.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.max(0.0d, 1.0d), 1.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.max(0.0d, Double.MAX_VALUE), Double.MAX_VALUE, 0.001d));
- Assert.assertTrue(approxEqual(Math.max(Double.MIN_VALUE, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(Math.max(Double.MIN_VALUE, Double.MAX_VALUE), Double.MAX_VALUE, 0.001d));
+ Assert.assertTrue(Double.isNaN(Math.max(1.0d, Double.NaN)));
+ Assert.assertTrue(Double.isNaN(Math.max(Double.NaN, 1.0d)));
+ Assert.assertEquals(Math.max(-0.0d, 0.0d), 0.0d);
+ Assert.assertEquals(Math.max(0.0d, -0.0d), 0.0d);
+ Assert.assertEquals(Math.max(-0.0d, -0.0d), -0.0d);
+ Assert.assertEquals(Math.max(0.0d, 0.0d), 0.0d);
+ Assert.assertEquals(Math.max(1.0d, 0.0d), 1.0d);
+ Assert.assertEquals(Math.max(0.0d, 1.0d), 1.0d);
+ Assert.assertEquals(Math.max(0.0d, Double.MAX_VALUE), Double.MAX_VALUE);
+ Assert.assertEquals(Math.max(Double.MIN_VALUE, 0.0d), Double.MIN_VALUE);
+ Assert.assertEquals(Math.max(Double.MIN_VALUE, Double.MAX_VALUE), Double.MAX_VALUE);
}
public static void test_StrictMath_abs_I() {
@@ -431,39 +432,59 @@
}
public static void test_StrictMath_min_F() {
- Assert.assertTrue(approxEqual(StrictMath.min(0.0f, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.min(1.0f, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.min(0.0f, 1.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.min(0.0f, Float.MAX_VALUE), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.min(Float.MIN_VALUE, 0.0f), Float.MIN_VALUE, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.min(Float.MIN_VALUE, Float.MAX_VALUE), Float.MIN_VALUE, 0.001f));
+ Assert.assertTrue(Float.isNaN(StrictMath.min(1.0f, Float.NaN)));
+ Assert.assertTrue(Float.isNaN(StrictMath.min(Float.NaN, 1.0f)));
+ Assert.assertEquals(StrictMath.min(-0.0f, 0.0f), -0.0f);
+ Assert.assertEquals(StrictMath.min(0.0f, -0.0f), -0.0f);
+ Assert.assertEquals(StrictMath.min(-0.0f, -0.0f), -0.0f);
+ Assert.assertEquals(StrictMath.min(0.0f, 0.0f), 0.0f);
+ Assert.assertEquals(StrictMath.min(1.0f, 0.0f), 0.0f);
+ Assert.assertEquals(StrictMath.min(0.0f, 1.0f), 0.0f);
+ Assert.assertEquals(StrictMath.min(0.0f, Float.MAX_VALUE), 0.0f);
+ Assert.assertEquals(StrictMath.min(Float.MIN_VALUE, 0.0f), 0.0f);
+ Assert.assertEquals(StrictMath.min(Float.MIN_VALUE, Float.MAX_VALUE), Float.MIN_VALUE);
}
public static void test_StrictMath_max_F() {
- Assert.assertTrue(approxEqual(StrictMath.max(0.0f, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.max(1.0f, 0.0f), 1.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.max(0.0f, 1.0f), 1.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.max(0.0f, Float.MAX_VALUE), Float.MAX_VALUE, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.max(Float.MIN_VALUE, 0.0f), 0.0f, 0.001f));
- Assert.assertTrue(approxEqual(StrictMath.max(Float.MIN_VALUE, Float.MAX_VALUE), Float.MAX_VALUE, 0.001f));
+ Assert.assertTrue(Float.isNaN(StrictMath.max(1.0f, Float.NaN)));
+ Assert.assertTrue(Float.isNaN(StrictMath.max(Float.NaN, 1.0f)));
+ Assert.assertEquals(StrictMath.max(-0.0f, 0.0f), 0.0f);
+ Assert.assertEquals(StrictMath.max(0.0f, -0.0f), 0.0f);
+ Assert.assertEquals(StrictMath.max(-0.0f, -0.0f), -0.0f);
+ Assert.assertEquals(StrictMath.max(0.0f, 0.0f), 0.0f);
+ Assert.assertEquals(StrictMath.max(1.0f, 0.0f), 1.0f);
+ Assert.assertEquals(StrictMath.max(0.0f, 1.0f), 1.0f);
+ Assert.assertEquals(StrictMath.max(0.0f, Float.MAX_VALUE), Float.MAX_VALUE);
+ Assert.assertEquals(StrictMath.max(Float.MIN_VALUE, 0.0f), Float.MIN_VALUE);
+ Assert.assertEquals(StrictMath.max(Float.MIN_VALUE, Float.MAX_VALUE), Float.MAX_VALUE);
}
public static void test_StrictMath_min_D() {
- Assert.assertTrue(approxEqual(StrictMath.min(0.0d, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.min(1.0d, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.min(0.0d, 1.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.min(0.0d, Double.MAX_VALUE), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.min(Double.MIN_VALUE, 0.0d), Double.MIN_VALUE, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.min(Double.MIN_VALUE, Double.MAX_VALUE), Double.MIN_VALUE, 0.001d));
+ Assert.assertTrue(Double.isNaN(StrictMath.min(1.0d, Double.NaN)));
+ Assert.assertTrue(Double.isNaN(StrictMath.min(Double.NaN, 1.0d)));
+ Assert.assertEquals(StrictMath.min(-0.0d, 0.0d), -0.0d);
+ Assert.assertEquals(StrictMath.min(0.0d, -0.0d), -0.0d);
+ Assert.assertEquals(StrictMath.min(-0.0d, -0.0d), -0.0d);
+ Assert.assertEquals(StrictMath.min(0.0d, 0.0d), 0.0d);
+ Assert.assertEquals(StrictMath.min(1.0d, 0.0d), 0.0d);
+ Assert.assertEquals(StrictMath.min(0.0d, 1.0d), 0.0d);
+ Assert.assertEquals(StrictMath.min(0.0d, Double.MAX_VALUE), 0.0d);
+ Assert.assertEquals(StrictMath.min(Double.MIN_VALUE, 0.0d), 0.0d);
+ Assert.assertEquals(StrictMath.min(Double.MIN_VALUE, Double.MAX_VALUE), Double.MIN_VALUE);
}
public static void test_StrictMath_max_D() {
- Assert.assertTrue(approxEqual(StrictMath.max(0.0d, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.max(1.0d, 0.0d), 1.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.max(0.0d, 1.0d), 1.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.max(0.0d, Double.MAX_VALUE), Double.MAX_VALUE, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.max(Double.MIN_VALUE, 0.0d), 0.0d, 0.001d));
- Assert.assertTrue(approxEqual(StrictMath.max(Double.MIN_VALUE, Double.MAX_VALUE), Double.MAX_VALUE, 0.001d));
+ Assert.assertTrue(Double.isNaN(StrictMath.max(1.0d, Double.NaN)));
+ Assert.assertTrue(Double.isNaN(StrictMath.max(Double.NaN, 1.0d)));
+ Assert.assertEquals(StrictMath.max(-0.0d, 0.0d), 0.0d);
+ Assert.assertEquals(StrictMath.max(0.0d, -0.0d), 0.0d);
+ Assert.assertEquals(StrictMath.max(-0.0d, -0.0d), -0.0d);
+ Assert.assertEquals(StrictMath.max(0.0d, 0.0d), 0.0d);
+ Assert.assertEquals(StrictMath.max(1.0d, 0.0d), 1.0d);
+ Assert.assertEquals(StrictMath.max(0.0d, 1.0d), 1.0d);
+ Assert.assertEquals(StrictMath.max(0.0d, Double.MAX_VALUE), Double.MAX_VALUE);
+ Assert.assertEquals(StrictMath.max(Double.MIN_VALUE, 0.0d), Double.MIN_VALUE);
+ Assert.assertEquals(StrictMath.max(Double.MIN_VALUE, Double.MAX_VALUE), Double.MAX_VALUE);
}
public static void test_Float_floatToRawIntBits() {