Implement workaround for Art x86 mul instruction bug on Android L and below.
R=sgjesse@google.com
Bug: 38492350
Change-Id: I9052c31897f29cb15a090ec7eb0540ef993c7261
diff --git a/src/main/java/com/android/tools/r8/code/MulDouble.java b/src/main/java/com/android/tools/r8/code/MulDouble.java
index 2d63172..039f602 100644
--- a/src/main/java/com/android/tools/r8/code/MulDouble.java
+++ b/src/main/java/com/android/tools/r8/code/MulDouble.java
@@ -18,6 +18,11 @@
public MulDouble(int dest, int left, int right) {
super(dest, left, right);
+ // The art x86 backend had a bug that made it fail on "mul r0, r1, r0" instructions where
+ // the second src register and the dst register is the same (but the first src register is
+ // different). Therefore, we have to avoid generating that pattern. The bug was fixed for
+ // Android M: https://android-review.googlesource.com/#/c/114932/
+ assert dest != right || dest == left;
}
public String getName() {
diff --git a/src/main/java/com/android/tools/r8/code/MulFloat.java b/src/main/java/com/android/tools/r8/code/MulFloat.java
index bb10eaf..aa3eaa0 100644
--- a/src/main/java/com/android/tools/r8/code/MulFloat.java
+++ b/src/main/java/com/android/tools/r8/code/MulFloat.java
@@ -18,6 +18,11 @@
public MulFloat(int dest, int left, int right) {
super(dest, left, right);
+ // The art x86 backend had a bug that made it fail on "mul r0, r1, r0" instructions where
+ // the second src register and the dst register is the same (but the first src register is
+ // different). Therefore, we have to avoid generating that pattern. The bug was fixed for
+ // Android M: https://android-review.googlesource.com/#/c/114932/
+ assert dest != right || dest == left;
}
public String getName() {
diff --git a/src/main/java/com/android/tools/r8/code/MulInt.java b/src/main/java/com/android/tools/r8/code/MulInt.java
index cb24a89..28b2fb3 100644
--- a/src/main/java/com/android/tools/r8/code/MulInt.java
+++ b/src/main/java/com/android/tools/r8/code/MulInt.java
@@ -17,6 +17,11 @@
public MulInt(int dest, int left, int right) {
super(dest, left, right);
+ // The art x86 backend had a bug that made it fail on "mul r0, r1, r0" instructions where
+ // the second src register and the dst register is the same (but the first src register is
+ // different). Therefore, we have to avoid generating that pattern. The bug was fixed for
+ // Android M: https://android-review.googlesource.com/#/c/114932/
+ assert dest != right || dest == left;
}
public String getName() {
diff --git a/src/main/java/com/android/tools/r8/code/MulLong.java b/src/main/java/com/android/tools/r8/code/MulLong.java
index 487f786..d341c3c 100644
--- a/src/main/java/com/android/tools/r8/code/MulLong.java
+++ b/src/main/java/com/android/tools/r8/code/MulLong.java
@@ -18,6 +18,11 @@
public MulLong(int dest, int left, int right) {
super(dest, left, right);
+ // The art x86 backend had a bug that made it fail on "mul r0, r1, r0" instructions where
+ // the second src register and the dst register is the same (but the first src register is
+ // different). Therefore, we have to avoid generating that pattern. The bug was fixed for
+ // Android M: https://android-review.googlesource.com/#/c/114932/
+ assert dest != right || dest == left;
}
public String getName() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Mul.java b/src/main/java/com/android/tools/r8/ir/code/Mul.java
index 19024f5..67aca89 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Mul.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Mul.java
@@ -27,19 +27,31 @@
}
public com.android.tools.r8.code.Instruction CreateInt(int dest, int left, int right) {
- return new MulInt(dest, left, right);
+ // Flip arguments if dest and right are the same to work around x86 code generation bug on
+ // Android L. See https://android-review.googlesource.com/#/c/114932/ for the fix for Android
+ // M.
+ return dest == right ? new MulInt(dest, right, left) : new MulInt(dest, left, right);
}
public com.android.tools.r8.code.Instruction CreateLong(int dest, int left, int right) {
- return new MulLong(dest, left, right);
+ // Flip arguments if dest and right are the same to work around x86 code generation bug on
+ // Android L. See https://android-review.googlesource.com/#/c/114932/ for the fix for Android
+ // M.
+ return dest == right ? new MulLong(dest, right, left) : new MulLong(dest, left, right);
}
public com.android.tools.r8.code.Instruction CreateFloat(int dest, int left, int right) {
- return new MulFloat(dest, left, right);
+ // Flip arguments if dest and right are the same to work around x86 code generation bug on
+ // Android L. See https://android-review.googlesource.com/#/c/114932/ for the fix for Android
+ // M.
+ return dest == right ? new MulFloat(dest, right, left) : new MulFloat(dest, left, right);
}
public com.android.tools.r8.code.Instruction CreateDouble(int dest, int left, int right) {
- return new MulDouble(dest, left, right);
+ // Flip arguments if dest and right are the same to work around x86 code generation bug on
+ // Android L. See https://android-review.googlesource.com/#/c/114932/ for the fix for Android
+ // M.
+ return dest == right ? new MulDouble(dest, right, left) : new MulDouble(dest, left, right);
}
public com.android.tools.r8.code.Instruction CreateInt2Addr(int left, int right) {