x86_64: Fix fp-to-core conversion
Long max value cannot be represented with double precision
and check fp against max_long does not guard invocation of
conversion instruction. As a result conversion ends up with
min long instead of max long.
The patch changes the guard check to not allow conversion
instruction for max long.
Change-Id: Ied761051ec27cf6c833040c25a2c61ab9fcea414
Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com>
diff --git a/compiler/dex/quick/x86/fp_x86.cc b/compiler/dex/quick/x86/fp_x86.cc
index 1f05ab9..5082d60 100644
--- a/compiler/dex/quick/x86/fp_x86.cc
+++ b/compiler/dex/quick/x86/fp_x86.cc
@@ -221,7 +221,7 @@
LoadConstant(rl_result.reg, 0x7fffffff);
NewLIR2(kX86Cvtsi2ssRR, temp_reg.GetReg(), rl_result.reg.GetReg());
NewLIR2(kX86ComissRR, rl_src.reg.GetReg(), temp_reg.GetReg());
- LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA);
+ LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondAe);
LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP);
NewLIR2(kX86Cvttss2siRR, rl_result.reg.GetReg(), rl_src.reg.GetReg());
LIR* branch_normal = NewLIR1(kX86Jmp8, 0);
@@ -242,7 +242,7 @@
LoadConstant(rl_result.reg, 0x7fffffff);
NewLIR2(kX86Cvtsi2sdRR, temp_reg.GetReg(), rl_result.reg.GetReg());
NewLIR2(kX86ComisdRR, rl_src.reg.GetReg(), temp_reg.GetReg());
- LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA);
+ LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondAe);
LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP);
NewLIR2(kX86Cvttsd2siRR, rl_result.reg.GetReg(), rl_src.reg.GetReg());
LIR* branch_normal = NewLIR1(kX86Jmp8, 0);
@@ -281,7 +281,7 @@
LoadConstantWide(rl_result.reg, 0x7fffffffffffffff);
NewLIR2(kX86Cvtsqi2ssRR, temp_reg.GetReg(), rl_result.reg.GetReg());
NewLIR2(kX86ComissRR, rl_src.reg.GetReg(), temp_reg.GetReg());
- LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA);
+ LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondAe);
LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP);
NewLIR2(kX86Cvttss2sqiRR, rl_result.reg.GetReg(), rl_src.reg.GetReg());
LIR* branch_normal = NewLIR1(kX86Jmp8, 0);
@@ -306,7 +306,7 @@
LoadConstantWide(rl_result.reg, 0x7fffffffffffffff);
NewLIR2(kX86Cvtsqi2sdRR, temp_reg.GetReg(), rl_result.reg.GetReg());
NewLIR2(kX86ComisdRR, rl_src.reg.GetReg(), temp_reg.GetReg());
- LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondA);
+ LIR* branch_pos_overflow = NewLIR2(kX86Jcc8, 0, kX86CondAe);
LIR* branch_na_n = NewLIR2(kX86Jcc8, 0, kX86CondP);
NewLIR2(kX86Cvttsd2sqiRR, rl_result.reg.GetReg(), rl_src.reg.GetReg());
LIR* branch_normal = NewLIR1(kX86Jmp8, 0);
diff --git a/test/302-float-conversion/expected.txt b/test/302-float-conversion/expected.txt
index 7d5c1eb..0423076 100644
--- a/test/302-float-conversion/expected.txt
+++ b/test/302-float-conversion/expected.txt
@@ -1,2 +1,3 @@
Iteration Result is as expected
inter4:2.0
+max_long:9223372036854775807
diff --git a/test/302-float-conversion/src/Main.java b/test/302-float-conversion/src/Main.java
index afc5e97..2733135 100644
--- a/test/302-float-conversion/src/Main.java
+++ b/test/302-float-conversion/src/Main.java
@@ -21,6 +21,7 @@
public static void main(String args[]) {
test1();
test2();
+ test3();
}
public static void test1() {
@@ -55,4 +56,9 @@
System.out.println("inter4:" + inter4);
}
+ public static void test3() {
+ double d = Long.MAX_VALUE;
+ System.out.println("max_long:" + (long)d);
+ }
+
}