Fix isRematerializable to always use the unadjusted real register number.
This ensures that isRematerializable returns the same value for the same
interval both when generating moves and when performing peephole
optimizations.
Change-Id: I2953fac1db981e045c61b7c9717098c2479862a6
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
index e79abc1..f2d039d 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LinearScanRegisterAllocator.java
@@ -470,7 +470,7 @@
return realRegisterNumberFromAllocated(intervalsRegister);
}
- int realRegisterNumberFromAllocated(int allocated) {
+ int unadjustedRealRegisterFromAllocated(int allocated) {
assert allocated != NO_REGISTER;
assert allocated >= 0;
int register;
@@ -484,6 +484,11 @@
// For everything else use the lower numbers.
register = allocated - numberOfArgumentRegisters - NUMBER_OF_SENTINEL_REGISTERS;
}
+ return register;
+ }
+
+ int realRegisterNumberFromAllocated(int allocated) {
+ int register = unadjustedRealRegisterFromAllocated(allocated);
// Adjust for spill registers that turn out to be unused because the value can be
// rematerialized instead of spilled.
if (unusedRegisters != null) {
diff --git a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java
index f1d3b9e..c966813 100644
--- a/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java
+++ b/src/main/java/com/android/tools/r8/ir/regalloc/LiveIntervals.java
@@ -89,8 +89,12 @@
}
// If one of the non-spilled splits uses a register that is higher than U8BIT_MAX we cannot
// rematerialize it using a ConstNumber instruction and we use spill moves instead of
- // rematerialization.
- int max = registerAllocator.realRegisterNumberFromAllocated(getMaxNonSpilledRegister());
+ // rematerialization. We use this check both before and after we have computed the set
+ // of unused registers. We therefore have to be careful to use the same max number for
+ // these computations. We use the unadjusted real register number to make sure that
+ // isRematerializable for the same intervals does not change from one phase of
+ // compilation to the next.
+ int max = registerAllocator.unadjustedRealRegisterFromAllocated(getMaxNonSpilledRegister());
return max < Constants.U8BIT_MAX;
}