diff options
author | 2014-11-19 05:26:05 -0800 | |
---|---|---|
committer | 2014-11-19 05:26:05 -0800 | |
commit | e8f74e58b476520cfc53970304c67b800994e33d (patch) | |
tree | df40c442d18e3b0eab1de365f445ba13d9771063 | |
parent | e0491682d101c69bf88c3c24a965312129cbfa38 (diff) |
Quick compiler: fix x86 special identity
The Quick compiler recognizes and specially handles a set of
small methods - including those that simply return one of their
arguments. For x86, special identity was broken if the returned
argument was a double that was passed half in register and half
in memory.
internal b/17325447
Change-Id: I3a766977cdc0b4216d8ad65a9870c3250b32471e
-rw-r--r-- | compiler/dex/quick/mir_to_lir.cc | 10 | ||||
-rw-r--r-- | test/083-compiler-regressions/expected.txt | 1 | ||||
-rw-r--r-- | test/083-compiler-regressions/src/Main.java | 26 |
3 files changed, 37 insertions, 0 deletions
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index c945f7f891..70ef991dee 100644 --- a/compiler/dex/quick/mir_to_lir.cc +++ b/compiler/dex/quick/mir_to_lir.cc @@ -201,6 +201,16 @@ void Mir2Lir::LoadArgDirect(int in_position, RegLocation rl_dest) { RegStorage reg_arg_low = GetArgMappingToPhysicalReg(in_position); RegStorage reg_arg_high = GetArgMappingToPhysicalReg(in_position + 1); + if (cu_->instruction_set == kX86) { + // Can't handle double split between reg & memory. Flush reg half to memory. + if (rl_dest.reg.IsDouble() && (reg_arg_low.Valid() != reg_arg_high.Valid())) { + DCHECK(reg_arg_low.Valid()); + DCHECK(!reg_arg_high.Valid()); + Store32Disp(TargetPtrReg(kSp), offset, reg_arg_low); + reg_arg_low = RegStorage::InvalidReg(); + } + } + if (reg_arg_low.Valid() && reg_arg_high.Valid()) { OpRegCopyWide(rl_dest.reg, RegStorage::MakeRegPair(reg_arg_low, reg_arg_high)); } else if (reg_arg_low.Valid() && !reg_arg_high.Valid()) { diff --git a/test/083-compiler-regressions/expected.txt b/test/083-compiler-regressions/expected.txt index 51bf8471c5..78c92fc51a 100644 --- a/test/083-compiler-regressions/expected.txt +++ b/test/083-compiler-regressions/expected.txt @@ -1,3 +1,4 @@ +b17325447 passes b17630605 passes b17411468 passes b2296099 passes diff --git a/test/083-compiler-regressions/src/Main.java b/test/083-compiler-regressions/src/Main.java index 9ad8ea7b1b..285c3608ca 100644 --- a/test/083-compiler-regressions/src/Main.java +++ b/test/083-compiler-regressions/src/Main.java @@ -30,6 +30,7 @@ public class Main { } public static void main(String args[]) throws Exception { + b17325447(); b17630605(); b17411468(); b2296099Test(); @@ -64,6 +65,31 @@ public class Main { minDoubleWith3ConstsTest(); } + public static double b17325447_i1(int i1, double f) { + return f; + } + + public static double b17325447_i2(int i1, int i2, double f) { + return f; + } + + public static double b17325447_i3(int i1, int i2, int i3, double f) { + return f; + } + + public static void b17325447() { + // b/17325447 - x86 handling of special identity method w/ double spanning reg/mem. + double d = 0.0; + d += b17325447_i1(123, 1.0); + d += b17325447_i2(123, 456, 2.0); + d += b17325447_i3(123, 456, 789, 3.0); + if (d == 6.0) { + System.out.println("b17325447 passes"); + } else { + System.out.println("b17325447 fails: " + d); + } + } + public static void b17630605() { // b/17630605 - failure to properly handle min long immediates. long a1 = 40455547223404749L; |