summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2015-12-18 23:07:03 +0000
committer android-build-merger <android-build-merger@google.com> 2015-12-18 23:07:03 +0000
commitbd968bd36f9948d27f63cc1a7abb602ab9264f06 (patch)
tree581d6d5071b7a0450d676eee167aeb34812240fa
parente3e6822adde3b53c84723a78412c4bd9eb812da6 (diff)
parentd9493c2d611601b1f076e5f92a2fe8a9e4ccf78d (diff)
Merge "ART: Fix bug in LSE"
am: d9493c2d61 * commit 'd9493c2d611601b1f076e5f92a2fe8a9e4ccf78d': ART: Fix bug in LSE
-rw-r--r--compiler/optimizing/load_store_elimination.cc13
-rw-r--r--test/530-checker-lse/src/Main.java37
2 files changed, 49 insertions, 1 deletions
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index adde00464b..2a2221a82c 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -655,6 +655,16 @@ class LSEVisitor : public HGraphVisitor {
}
}
+ static bool IsIntFloatAlias(Primitive::Type type1, Primitive::Type type2) {
+ return (type1 == Primitive::kPrimFloat && type2 == Primitive::kPrimInt) ||
+ (type2 == Primitive::kPrimFloat && type1 == Primitive::kPrimInt);
+ }
+
+ static bool IsLongDoubleAlias(Primitive::Type type1, Primitive::Type type2) {
+ return (type1 == Primitive::kPrimDouble && type2 == Primitive::kPrimLong) ||
+ (type2 == Primitive::kPrimDouble && type1 == Primitive::kPrimLong);
+ }
+
void VisitGetLocation(HInstruction* instruction,
HInstruction* ref,
size_t offset,
@@ -686,7 +696,8 @@ class LSEVisitor : public HGraphVisitor {
if ((heap_value != kUnknownHeapValue) &&
// Keep the load due to possible I/F, J/D array aliasing.
// See b/22538329 for details.
- (heap_value->GetType() == instruction->GetType())) {
+ !IsIntFloatAlias(heap_value->GetType(), instruction->GetType()) &&
+ !IsLongDoubleAlias(heap_value->GetType(), instruction->GetType())) {
removed_loads_.push_back(instruction);
substitute_instructions_for_loads_.push_back(heap_value);
TryRemovingNullCheck(instruction);
diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java
index 98251e4af3..7d89372a96 100644
--- a/test/530-checker-lse/src/Main.java
+++ b/test/530-checker-lse/src/Main.java
@@ -52,6 +52,11 @@ class TestClass2 {
int j;
}
+class TestClass3 {
+ float floatField = 8.0f;
+ boolean test1 = true;
+}
+
class Finalizable {
static boolean sVisited = false;
static final int VALUE = 0xbeef;
@@ -577,6 +582,37 @@ public class Main {
return obj.i;
}
+ /// CHECK-START: float Main.test24() load_store_elimination (before)
+ /// CHECK-DAG: <<True:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Float8:f\d+>> FloatConstant 8
+ /// CHECK-DAG: <<Float42:f\d+>> FloatConstant 42
+ /// CHECK-DAG: <<Obj:l\d+>> NewInstance
+ /// CHECK-DAG: InstanceFieldSet [<<Obj>>,<<True>>]
+ /// CHECK-DAG: InstanceFieldSet [<<Obj>>,<<Float8>>]
+ /// CHECK-DAG: <<GetTest:z\d+>> InstanceFieldGet [<<Obj>>]
+ /// CHECK-DAG: If [<<GetTest>>]
+ /// CHECK-DAG: <<GetField:f\d+>> InstanceFieldGet [<<Obj>>]
+ /// CHECK-DAG: <<Phi:f\d+>> Phi [<<Float42>>,<<GetField>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ /// CHECK-START: float Main.test24() load_store_elimination (after)
+ /// CHECK-DAG: <<True:i\d+>> IntConstant 1
+ /// CHECK-DAG: <<Float8:f\d+>> FloatConstant 8
+ /// CHECK-DAG: <<Float42:f\d+>> FloatConstant 42
+ /// CHECK-DAG: <<Obj:l\d+>> NewInstance
+ /// CHECK-DAG: If [<<True>>]
+ /// CHECK-DAG: <<Phi:f\d+>> Phi [<<Float42>>,<<Float8>>]
+ /// CHECK-DAG: Return [<<Phi>>]
+
+ static float test24() {
+ float a = 42.0f;
+ TestClass3 obj = new TestClass3();
+ if (obj.test1) {
+ a = obj.floatField;
+ }
+ return a;
+ }
+
/// CHECK-START: void Main.testFinalizable() load_store_elimination (before)
/// CHECK: NewInstance
/// CHECK: InstanceFieldSet
@@ -683,6 +719,7 @@ public class Main {
assertIntEquals(test22(), 13);
assertIntEquals(test23(true), 4);
assertIntEquals(test23(false), 5);
+ assertFloatEquals(test24(), 8.0f);
testFinalizableByForcingGc();
}
}