From e8f74e58b476520cfc53970304c67b800994e33d Mon Sep 17 00:00:00 2001 From: buzbee Date: Wed, 19 Nov 2014 05:26:05 -0800 Subject: [PATCH] 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 --- compiler/dex/quick/mir_to_lir.cc | 10 ++++++++++ test/083-compiler-regressions/expected.txt | 1 + test/083-compiler-regressions/src/Main.java | 26 ++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc index c945f7f89..70ef991de 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 51bf8471c..78c92fc51 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 9ad8ea7b1..285c3608c 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; -- 2.11.0