Fix incorrect LSE across throwing ArraySet.
Test: Additional test in 530-checker-lse.
Test: m test-art-host-gtest
Test: testrunner.py --host --optimizing
Bug: 161233339
Change-Id: I0aaa6a4a1060e1a5abdbb49b6241e7e0bf58a7d5
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index 86e84bd..207a11a 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -648,6 +648,9 @@
instruction->GetBlock()->RemoveInstruction(instruction);
return;
} else {
+ if (instruction->CanThrow()) {
+ HandleExit(instruction->GetBlock());
+ }
HLoopInformation* loop_info = instruction->GetBlock()->GetLoopInformation();
if (loop_info == nullptr) {
// Store is not in a loop. We try to precisely track the heap value by
diff --git a/test/530-checker-lse/src/Main.java b/test/530-checker-lse/src/Main.java
index d0ad6ae..e228912 100644
--- a/test/530-checker-lse/src/Main.java
+++ b/test/530-checker-lse/src/Main.java
@@ -1279,6 +1279,27 @@
return a[0] + (a[0] & 0xff);
}
+ /// CHECK-START: void Main.$noinline$testThrowingArraySet(java.lang.Object[], java.lang.Object) load_store_elimination (before)
+ /// CHECK-DAG: ArrayGet
+ /// CHECK-DAG: ArraySet
+ /// CHECK-DAG: ArraySet
+ /// CHECK-DAG: ArraySet
+ /// CHECK-DAG: ArraySet
+
+ /// CHECK-START: void Main.$noinline$testThrowingArraySet(java.lang.Object[], java.lang.Object) load_store_elimination (after)
+ /// CHECK-DAG: ArrayGet
+ /// CHECK-DAG: ArraySet
+ /// CHECK-DAG: ArraySet
+ /// CHECK-DAG: ArraySet
+ /// CHECK-DAG: ArraySet
+ private static void $noinline$testThrowingArraySet(Object[] a, Object o) {
+ Object olda0 = a[0];
+ a[0] = null;
+ a[1] = olda0;
+ a[0] = o;
+ a[1] = null;
+ }
+
static void assertIntEquals(int result, int expected) {
if (expected != result) {
throw new Error("Expected: " + expected + ", found: " + result);
@@ -1422,6 +1443,18 @@
assertIntEquals(testLocalArrayMerge3(false), 1);
assertIntEquals(testLocalArrayMerge4(true), 2);
assertIntEquals(testLocalArrayMerge4(false), 2);
+
+ TestClass[] tca = new TestClass[] { new TestClass(), null };
+ try {
+ $noinline$testThrowingArraySet(tca, new TestClass2());
+ } catch (ArrayStoreException expected) {
+ if (tca[0] != null) {
+ throw new Error("tca[0] is not null");
+ }
+ if (tca[1] == null) {
+ throw new Error("tca[1] is null");
+ }
+ }
}
static boolean sFlag;