Version 1.7.4-dev

Merge commit 'e7cf47187d4fa35e0bf968a977c81932fa331e96' into 1.7.4-dev
diff --git a/infra/config/global/luci-scheduler.cfg b/infra/config/global/luci-scheduler.cfg
index 0c95e98..c55893a 100644
--- a/infra/config/global/luci-scheduler.cfg
+++ b/infra/config/global/luci-scheduler.cfg
@@ -58,6 +58,7 @@
     repo: "https://r8.googlesource.com/r8"
     # Version branches are named d8-x.y (up until d8-1.5) or just x.y (from 1.6)
     refs: "regexp:refs/heads/(?:d8-)?[0-9]+\\.[0-9]+"
+    path_regexps: "src/main/java/com/android/tools/r8/Version.java"
   }
   triggers: "archive_release"
   triggers: "linux-android-4.0.4_release"
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 0b02763..695aef4 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "1.7.3-dev";
+  public static final String LABEL = "1.7.4-dev";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Assume.java b/src/main/java/com/android/tools/r8/ir/code/Assume.java
index 18ba962..c4dfbc4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Assume.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Assume.java
@@ -153,10 +153,6 @@
     return self;
   }
 
-  public boolean mayAffectStaticType() {
-    return isAssumeNonNull();
-  }
-
   @Override
   public boolean couldIntroduceAnAlias(AppView<?> appView, Value root) {
     assert root != null && root.getTypeLattice().isReference();
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index cb32015..fa3074e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -1008,22 +1008,14 @@
   }
 
   public void removeAllTrivialPhis() {
-    removeAllTrivialPhis(null, null);
+    removeAllTrivialPhis(null);
   }
 
   public void removeAllTrivialPhis(IRBuilder builder) {
-    removeAllTrivialPhis(builder, null);
-  }
-
-  public void removeAllTrivialPhis(Set<Value> affectedValues) {
-    removeAllTrivialPhis(null, affectedValues);
-  }
-
-  public void removeAllTrivialPhis(IRBuilder builder, Set<Value> affectedValues) {
     for (BasicBlock block : blocks) {
       List<Phi> phis = new ArrayList<>(block.getPhis());
       for (Phi phi : phis) {
-        phi.removeTrivialPhi(builder, affectedValues);
+        phi.removeTrivialPhi(builder);
       }
     }
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Phi.java b/src/main/java/com/android/tools/r8/ir/code/Phi.java
index 7cd8ca2..e2f9cf3 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Phi.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Phi.java
@@ -123,7 +123,7 @@
       builder.constrainType(operand, readConstraint);
       appendOperand(operand);
     }
-    removeTrivialPhi(builder, null);
+    removeTrivialPhi(builder);
   }
 
   public void addOperands(List<Value> operands) {
@@ -224,10 +224,10 @@
   }
 
   public void removeTrivialPhi() {
-    removeTrivialPhi(null, null);
+    removeTrivialPhi(null);
   }
 
-  void removeTrivialPhi(IRBuilder builder, Set<Value> affectedValues) {
+  public void removeTrivialPhi(IRBuilder builder) {
     Value same = null;
     for (Value op : operands) {
       if (op == same || op == this) {
@@ -252,9 +252,6 @@
     if (builder != null && typeLattice.isPreciseType() && !typeLattice.isBottom()) {
       builder.constrainType(same, ValueTypeConstraint.fromTypeLattice(typeLattice));
     }
-    if (affectedValues != null) {
-      affectedValues.addAll(this.affectedValues());
-    }
     // Removing this phi, so get rid of it as a phi user from all of the operands to avoid
     // recursively getting back here with the same phi. If the phi has itself as an operand
     // that also removes the self-reference.
@@ -280,7 +277,7 @@
       replaceUsers(same);
       // Try to simplify phi users that might now have become trivial.
       for (Phi user : phiUsersToSimplify) {
-        user.removeTrivialPhi(builder, affectedValues);
+        user.removeTrivialPhi(builder);
       }
     }
     // Get rid of the phi itself.
diff --git a/src/main/java/com/android/tools/r8/ir/code/Value.java b/src/main/java/com/android/tools/r8/ir/code/Value.java
index 6648777..2881de7 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Value.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Value.java
@@ -19,7 +19,6 @@
 import com.android.tools.r8.position.MethodPosition;
 import com.android.tools.r8.utils.LongInterval;
 import com.android.tools.r8.utils.Reporter;
-import com.android.tools.r8.utils.SetUtils;
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableSet;
@@ -425,22 +424,6 @@
     return users.getFirst();
   }
 
-  public Set<Instruction> aliasedUsers() {
-    Set<Instruction> users = SetUtils.newIdentityHashSet(uniqueUsers());
-    collectAliasedUsersViaAssume(uniqueUsers(), users);
-    return users;
-  }
-
-  private static void collectAliasedUsersViaAssume(
-      Set<Instruction> usersToTest, Set<Instruction> collectedUsers) {
-    for (Instruction user : usersToTest) {
-      if (user.isAssume()) {
-        collectedUsers.addAll(user.outValue().uniqueUsers());
-        collectAliasedUsersViaAssume(user.outValue().uniqueUsers(), collectedUsers);
-      }
-    }
-  }
-
   public Phi firstPhiUser() {
     assert !phiUsers.isEmpty();
     return phiUsers.getFirst();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 46f8bf4..dc2516c 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -1249,6 +1249,26 @@
 
     assert code.verifyTypes(appView);
 
+    if (nonNullTracker != null) {
+      // TODO(b/139246447): Once we extend this optimization to, e.g., constants of primitive args,
+      //   this may not be the right place to collect call site optimization info.
+      // Collecting call-site optimization info depends on the existence of non-null IRs.
+      // Arguments can be changed during the debug mode.
+      if (!isDebugMode && appView.callSiteOptimizationInfoPropagator() != null) {
+        appView.callSiteOptimizationInfoPropagator().collectCallSiteOptimizationInfo(code);
+      }
+      // Computation of non-null parameters on normal exits rely on the existence of non-null IRs.
+      nonNullTracker.computeNonNullParamOnNormalExits(feedback, code);
+    }
+    if (aliasIntroducer != null || nonNullTracker != null || dynamicTypeOptimization != null) {
+      codeRewriter.removeAssumeInstructions(code);
+      assert code.isConsistentSSA();
+    }
+    // Assert that we do not have unremoved non-sense code in the output, e.g., v <- non-null NULL.
+    assert code.verifyNoNullabilityBottomTypes();
+
+    assert code.verifyTypes(appView);
+
     previous = printMethod(code, "IR before class inlining (SSA)", previous);
 
     if (classInliner != null) {
@@ -1310,6 +1330,26 @@
       assert code.isConsistentSSA();
     }
 
+    if (nonNullTracker != null) {
+      // TODO(b/139246447): Once we extend this optimization to, e.g., constants of primitive args,
+      //   this may not be the right place to collect call site optimization info.
+      // Collecting call-site optimization info depends on the existence of non-null IRs.
+      // Arguments can be changed during the debug mode.
+      if (!isDebugMode && appView.callSiteOptimizationInfoPropagator() != null) {
+        appView.callSiteOptimizationInfoPropagator().collectCallSiteOptimizationInfo(code);
+      }
+      // Computation of non-null parameters on normal exits rely on the existence of non-null IRs.
+      nonNullTracker.computeNonNullParamOnNormalExits(feedback, code);
+    }
+    if (aliasIntroducer != null || nonNullTracker != null || dynamicTypeOptimization != null) {
+      codeRewriter.removeAssumeInstructions(code);
+      assert code.isConsistentSSA();
+    }
+    // Assert that we do not have unremoved non-sense code in the output, e.g., v <- non-null NULL.
+    assert code.verifyNoNullabilityBottomTypes();
+
+    assert code.verifyTypes(appView);
+
     previous = printMethod(code, "IR after lambda merger (SSA)", previous);
 
     if (options.outline.enabled) {
@@ -1342,26 +1382,6 @@
       classStaticizer.examineMethodCode(method, code);
     }
 
-    if (nonNullTracker != null) {
-      // TODO(b/139246447): Once we extend this optimization to, e.g., constants of primitive args,
-      //   this may not be the right place to collect call site optimization info.
-      // Collecting call-site optimization info depends on the existence of non-null IRs.
-      // Arguments can be changed during the debug mode.
-      if (!isDebugMode && appView.callSiteOptimizationInfoPropagator() != null) {
-        appView.callSiteOptimizationInfoPropagator().collectCallSiteOptimizationInfo(code);
-      }
-      // Computation of non-null parameters on normal exits rely on the existence of non-null IRs.
-      nonNullTracker.computeNonNullParamOnNormalExits(feedback, code);
-    }
-    if (aliasIntroducer != null || nonNullTracker != null || dynamicTypeOptimization != null) {
-      codeRewriter.removeAssumeInstructions(code);
-      assert code.isConsistentSSA();
-    }
-    // Assert that we do not have unremoved non-sense code in the output, e.g., v <- non-null NULL.
-    assert code.verifyNoNullabilityBottomTypes();
-
-    assert code.verifyTypes(appView);
-
     if (appView.enableWholeProgramOptimizations()) {
       if (libraryMethodOverrideAnalysis != null) {
         libraryMethodOverrideAnalysis.analyze(code);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 1f36d25..fba5ae7 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -218,7 +218,7 @@
     // Therefore, Assume elimination may result in a trivial phi:
     //   z <- phi(x, x)
     if (needToCheckTrivialPhis) {
-      code.removeAllTrivialPhis(valuesThatRequireWidening);
+      code.removeAllTrivialPhis();
     }
 
     if (!valuesThatRequireWidening.isEmpty()) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 1845186..4837545 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -556,10 +556,8 @@
           templateInstructions.add(OutlineInstruction.fromInstruction(current));
         } else if (current.isConstInstruction()) {
           // Don't include const instructions in the template.
-        } else if (current.isAssume()) {
-          // Don't include assume instructions in the template.
         } else {
-          assert false : "Unexpected type of instruction in outlining template:" + current;
+          assert false : "Unexpected type of instruction in outlining template.";
         }
       }
     }
@@ -790,12 +788,6 @@
           include = true;
           instructionIncrement = 0;
         }
-      } else if (instruction.isAssume()) {
-        // Technically, assume instructions will be removed, and thus it should not be included.
-        // However, we should keep searching, so here we pretend to include it with 0 increment.
-        // When adding instruction into the outline candidate, we filter out assume instructions.
-        include = true;
-        instructionIncrement = 0;
       } else {
         include = canIncludeInstruction(instruction);
       }
@@ -994,16 +986,12 @@
 
     // Add the current instruction to the outline.
     private void includeInstruction(Instruction instruction) {
-      if (instruction.isAssume()) {
-        return;
-      }
-
       List<Value> inValues = orderedInValues(instruction, returnValue);
 
       Value prevReturnValue = returnValue;
       if (returnValue != null) {
         for (Value value : inValues) {
-          if (value.getAliasedValue() == returnValue) {
+          if (value == returnValue) {
             assert returnValueUsersLeft > 0;
             returnValueUsersLeft--;
           }
@@ -1025,7 +1013,7 @@
           || instruction.isArithmeticBinop();
       if (inValues.size() > 0) {
         for (int i = 0; i < inValues.size(); i++) {
-          Value value = inValues.get(i).getAliasedValue();
+          Value value = inValues.get(i);
           if (value == prevReturnValue) {
             argumentsMap.add(OutlineInstruction.OUTLINE_TEMP);
             continue;
@@ -1079,6 +1067,7 @@
       }
     }
 
+
     protected abstract void handle(int start, int end, Outline outline);
 
     private void candidate(int start, int index) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
index 7df3542..b656678 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/ClassInliner.java
@@ -8,11 +8,9 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Instruction;
 import com.android.tools.r8.ir.code.InstructionOrPhi;
-import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.desugar.LambdaRewriter;
 import com.android.tools.r8.ir.optimize.CodeRewriter;
 import com.android.tools.r8.ir.optimize.Inliner;
@@ -20,11 +18,9 @@
 import com.android.tools.r8.ir.optimize.string.StringOptimizer;
 import com.android.tools.r8.logging.Log;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.google.common.collect.Sets;
 import com.google.common.collect.Streams;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
@@ -38,14 +34,8 @@
     NON_CLASS_TYPE,
     UNKNOWN_TYPE,
 
-    // Used by isClassEligible
-    NON_PROGRAM_CLASS,
-    ABSTRACT_OR_INTERFACE,
-    NEVER_CLASS_INLINE,
-    HAS_FINALIZER,
-    TRIGGER_CLINIT,
-
     // Used by InlineCandidateProcessor#isClassAndUsageEligible
+    INELIGIBLE_CLASS,
     HAS_CLINIT,
     HAS_INSTANCE_FIELDS,
     NON_FINAL_TYPE,
@@ -56,8 +46,7 @@
   }
 
   private final LambdaRewriter lambdaRewriter;
-  private final ConcurrentHashMap<DexClass, EligibilityStatus> knownClasses =
-      new ConcurrentHashMap<>();
+  private final ConcurrentHashMap<DexClass, Boolean> knownClasses = new ConcurrentHashMap<>();
 
   public ClassInliner(LambdaRewriter lambdaRewriter) {
     this.lambdaRewriter = lambdaRewriter;
@@ -67,15 +56,7 @@
       DexEncodedMethod context, Instruction root, EligibilityStatus status) {
     if (Log.ENABLED && Log.isLoggingEnabledFor(ClassInliner.class)) {
       Log.info(getClass(), "At %s,", context.toSourceString());
-      Log.info(getClass(), "ClassInlining eligibility of `%s`: %s.", root, status);
-    }
-  }
-
-  private void logIneligibleUser(
-      DexEncodedMethod context, Instruction root, InstructionOrPhi ineligibleUser) {
-    if (Log.ENABLED && Log.isLoggingEnabledFor(ClassInliner.class)) {
-      Log.info(getClass(), "At %s,", context.toSourceString());
-      Log.info(getClass(), "Ineligible user of `%s`: `%s`.", root, ineligibleUser);
+      Log.info(getClass(), "ClassInlining eligibility of %s: %s,", root, status);
     }
   }
 
@@ -152,7 +133,7 @@
   //       return 1;
   //     }
   //     static int method3() {
-  //       return 123;
+  //       return "F::getX";
   //     }
   //   }
   //
@@ -214,7 +195,6 @@
         InstructionOrPhi ineligibleUser = processor.areInstanceUsersEligible(defaultOracle);
         if (ineligibleUser != null) {
           // This root may succeed if users change in future.
-          logIneligibleUser(code.method, root, ineligibleUser);
           continue;
         }
 
@@ -228,11 +208,7 @@
         anyInlinedMethods |= processor.processInlining(code, defaultOracle);
 
         // Restore normality.
-        Set<Value> affectedValues = Sets.newIdentityHashSet();
-        code.removeAllTrivialPhis(affectedValues);
-        if (!affectedValues.isEmpty()) {
-          new TypeAnalysis(appView).narrowing(affectedValues);
-        }
+        code.removeAllTrivialPhis();
         assert code.isConsistentSSA();
         rootsIterator.remove();
         repeat = true;
@@ -257,11 +233,11 @@
     }
   }
 
-  private EligibilityStatus isClassEligible(AppView<AppInfoWithLiveness> appView, DexClass clazz) {
-    EligibilityStatus eligible = knownClasses.get(clazz);
+  private boolean isClassEligible(AppView<AppInfoWithLiveness> appView, DexClass clazz) {
+    Boolean eligible = knownClasses.get(clazz);
     if (eligible == null) {
-      EligibilityStatus computed = computeClassEligible(appView, clazz);
-      EligibilityStatus existing = knownClasses.putIfAbsent(clazz, computed);
+      boolean computed = computeClassEligible(appView, clazz);
+      Boolean existing = knownClasses.putIfAbsent(clazz, computed);
       assert existing == null || existing == computed;
       eligible = existing == null ? computed : existing;
     }
@@ -272,19 +248,13 @@
   //   - is not an abstract class or interface
   //   - does not declare finalizer
   //   - does not trigger any static initializers except for its own
-  private EligibilityStatus computeClassEligible(
-      AppView<AppInfoWithLiveness> appView, DexClass clazz) {
-    if (clazz == null) {
-      return EligibilityStatus.UNKNOWN_TYPE;
-    }
-    if (clazz.isNotProgramClass()) {
-      return EligibilityStatus.NON_PROGRAM_CLASS;
-    }
-    if (clazz.isAbstract() || clazz.isInterface()) {
-      return EligibilityStatus.ABSTRACT_OR_INTERFACE;
-    }
-    if (appView.appInfo().neverClassInline.contains(clazz.type)) {
-      return EligibilityStatus.NEVER_CLASS_INLINE;
+  private boolean computeClassEligible(AppView<AppInfoWithLiveness> appView, DexClass clazz) {
+    if (clazz == null
+        || clazz.isNotProgramClass()
+        || clazz.accessFlags.isAbstract()
+        || clazz.accessFlags.isInterface()
+        || appView.appInfo().neverClassInline.contains(clazz.type)) {
+      return false;
     }
 
     // Class must not define finalizer.
@@ -292,14 +262,11 @@
     for (DexEncodedMethod method : clazz.virtualMethods()) {
       if (method.method.name == dexItemFactory.finalizeMethodName
           && method.method.proto == dexItemFactory.objectMethods.finalize.proto) {
-        return EligibilityStatus.HAS_FINALIZER;
+        return false;
       }
     }
 
     // Check for static initializers in this class or any of interfaces it implements.
-    if (clazz.initializationOfParentTypesMayHaveSideEffects(appView)) {
-      return EligibilityStatus.TRIGGER_CLINIT;
-    }
-    return EligibilityStatus.ELIGIBLE;
+    return !clazz.initializationOfParentTypesMayHaveSideEffects(appView);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java
index d06b3f9..e207e50 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/FieldValueHelper.java
@@ -41,9 +41,6 @@
     this.code = code;
     this.root = root;
     this.appView = appView;
-    // Verify that `root` is not aliased.
-    assert root.hasOutValue();
-    assert root.outValue() == root.outValue().getAliasedValue();
   }
 
   void replaceValue(Value oldValue, Value newValue) {
@@ -127,10 +124,10 @@
       Instruction instruction = iterator.previous();
       assert instruction != null;
 
-      if (instruction == root
-          || (instruction.isInstancePut()
-              && instruction.asInstancePut().getField() == field
-              && instruction.asInstancePut().object().getAliasedValue() == root.outValue())) {
+      if (instruction == root ||
+          (instruction.isInstancePut() &&
+              instruction.asInstancePut().getField() == field &&
+              instruction.asInstancePut().object() == root.outValue())) {
         valueProducingInsn = instruction;
         break;
       }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
index 1318135..a2e9358 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/classinliner/InlineCandidateProcessor.java
@@ -17,7 +17,6 @@
 import com.android.tools.r8.graph.ResolutionResult;
 import com.android.tools.r8.ir.analysis.ClassInitializationAnalysis;
 import com.android.tools.r8.ir.analysis.type.TypeAnalysis;
-import com.android.tools.r8.ir.code.Assume;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.ConstNumber;
 import com.android.tools.r8.ir.code.IRCode;
@@ -41,18 +40,16 @@
 import com.android.tools.r8.ir.optimize.info.ParameterUsagesInfo.ParameterUsage;
 import com.android.tools.r8.kotlin.KotlinInfo;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.Pair;
-import com.android.tools.r8.utils.StringUtils;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.function.Supplier;
 
@@ -63,7 +60,7 @@
   private final AppView<AppInfoWithLiveness> appView;
   private final LambdaRewriter lambdaRewriter;
   private final Inliner inliner;
-  private final Function<DexClass, EligibilityStatus> isClassEligible;
+  private final Predicate<DexClass> isClassEligible;
   private final Predicate<DexEncodedMethod> isProcessedConcurrently;
   private final DexEncodedMethod method;
   private final Instruction root;
@@ -86,7 +83,7 @@
       AppView<AppInfoWithLiveness> appView,
       LambdaRewriter lambdaRewriter,
       Inliner inliner,
-      Function<DexClass, EligibilityStatus> isClassEligible,
+      Predicate<DexClass> isClassEligible,
       Predicate<DexEncodedMethod> isProcessedConcurrently,
       DexEncodedMethod method,
       Instruction root) {
@@ -143,9 +140,8 @@
   //      * class has class initializer marked as TrivialClassInitializer, and
   //        class initializer initializes the field we are reading here.
   EligibilityStatus isClassAndUsageEligible() {
-    EligibilityStatus status = isClassEligible.apply(eligibleClassDefinition);
-    if (status != EligibilityStatus.ELIGIBLE) {
-      return status;
+    if (!isClassEligible.test(eligibleClassDefinition)) {
+      return EligibilityStatus.INELIGIBLE_CLASS;
     }
 
     if (root.isNewInstance()) {
@@ -255,7 +251,7 @@
    *
    * @return null if all users are eligible, or the first ineligible user.
    */
-  InstructionOrPhi areInstanceUsersEligible(Supplier<InliningOracle> defaultOracle) {
+  protected InstructionOrPhi areInstanceUsersEligible(Supplier<InliningOracle> defaultOracle) {
     // No Phi users.
     if (eligibleInstance.numberOfPhiUsers() > 0) {
       return eligibleInstance.firstPhiUser(); // Not eligible.
@@ -263,19 +259,11 @@
 
     Set<Instruction> currentUsers = eligibleInstance.uniqueUsers();
     while (!currentUsers.isEmpty()) {
-      Set<Instruction> indirectUsers = Sets.newIdentityHashSet();
+      Set<Instruction> indirectUsers = new HashSet<>();
       for (Instruction user : currentUsers) {
-        if (user.isAssume()) {
-          if (user.outValue().numberOfPhiUsers() > 0) {
-            return user.outValue().firstPhiUser(); // Not eligible.
-          }
-          indirectUsers.addAll(user.outValue().uniqueUsers());
-          continue;
-        }
         // Field read/write.
         if (user.isInstanceGet()
-            || (user.isInstancePut()
-                && user.asInstancePut().value().getAliasedValue() != eligibleInstance)) {
+            || (user.isInstancePut() && user.asInstancePut().value() != eligibleInstance)) {
           DexField field = user.asFieldInstruction().getField();
           if (field.holder == eligibleClass
               && eligibleClassDefinition.lookupInstanceField(field) != null) {
@@ -300,7 +288,7 @@
               boolean isCorrespondingConstructorCall =
                   root.isNewInstance()
                       && !invoke.inValues().isEmpty()
-                      && root.outValue() == invoke.getReceiver();
+                      && root.outValue() == invoke.inValues().get(0);
               if (isCorrespondingConstructorCall) {
                 InliningInfo inliningInfo =
                     isEligibleConstructorCall(user.asInvokeDirect(), singleTarget, defaultOracle);
@@ -355,7 +343,6 @@
 
   // Process inlining, includes the following steps:
   //
-  //  * remove linked assume instructions if any so that users of the eligible field are up-to-date.
   //  * replace unused instance usages as arguments which are never used
   //  * inline extra methods if any, collect new direct method calls
   //  * inline direct methods if any
@@ -365,9 +352,6 @@
   //
   // Returns `true` if at least one method was inlined.
   boolean processInlining(IRCode code, Supplier<InliningOracle> defaultOracle) {
-    // Verify that `eligibleInstance` is not aliased.
-    assert eligibleInstance == eligibleInstance.getAliasedValue();
-
     replaceUsagesAsUnusedArgument(code);
 
     boolean anyInlinedMethods = forceInlineExtraMethodInvocations(code);
@@ -390,14 +374,11 @@
         // methods that need to be inlined anyway.
         return true;
       }
-      assert extraMethodCalls.isEmpty()
-          : "Remaining extra method calls: " + StringUtils.join(extraMethodCalls.entrySet(), ", ");
-      assert unusedArguments.isEmpty()
-          : "Remaining unused arg: " + StringUtils.join(unusedArguments, ", ");
+      assert extraMethodCalls.isEmpty();
+      assert unusedArguments.isEmpty();
     }
 
     anyInlinedMethods |= forceInlineDirectMethodInvocations(code);
-    removeAssumeInstructionsLinkedToEligibleInstance();
     removeMiscUsages(code);
     removeFieldReads(code);
     removeFieldWrites();
@@ -438,22 +419,6 @@
     return true;
   }
 
-  private void removeAssumeInstructionsLinkedToEligibleInstance() {
-    for (Instruction user : eligibleInstance.aliasedUsers()) {
-      if (!user.isAssume()) {
-        continue;
-      }
-      Assume<?> assumeInstruction = user.asAssume();
-      Value src = assumeInstruction.src();
-      Value dest = assumeInstruction.outValue();
-      assert dest.numberOfPhiUsers() == 0;
-      dest.replaceUsers(src);
-      removeInstruction(user);
-    }
-    // Verify that no more assume instructions are left as users.
-    assert eligibleInstance.aliasedUsers().stream().noneMatch(Instruction::isAssume);
-  }
-
   // Remove miscellaneous users before handling field reads.
   private void removeMiscUsages(IRCode code) {
     boolean needToRemoveUnreachableBlocks = false;
@@ -530,8 +495,8 @@
     }
   }
 
-  private void replaceFieldRead(
-      IRCode code, InstanceGet fieldRead, Map<DexField, FieldValueHelper> fieldHelpers) {
+  private void replaceFieldRead(IRCode code,
+      InstanceGet fieldRead, Map<DexField, FieldValueHelper> fieldHelpers) {
     Value value = fieldRead.outValue();
     if (value != null) {
       FieldValueHelper helper =
@@ -543,10 +508,7 @@
         fieldValueHelper.replaceValue(value, newValue);
       }
       assert value.numberOfAllUsers() == 0;
-      // `newValue` could be a phi introduced by FieldValueHelper. Its initial type is set as the
-      // type of read field, but it could be more precise than that due to (multiple) inlining.
-      // Instead of values affected by `newValue`, it's necessary to begin with `newValue` itself.
-      new TypeAnalysis(appView).narrowing(ImmutableSet.of(newValue));
+      new TypeAnalysis(appView).narrowing(newValue.affectedValues());
     }
     removeInstruction(fieldRead);
   }
@@ -577,8 +539,7 @@
     assert isEligibleSingleTarget(singleTarget);
 
     // Must be a constructor called on the receiver.
-    if (ListUtils.lastIndexMatching(
-        invoke.inValues(), v -> v.getAliasedValue() == eligibleInstance) != 0) {
+    if (invoke.inValues().lastIndexOf(eligibleInstance) != 0) {
       return null;
     }
 
@@ -633,7 +594,7 @@
         : null;
   }
 
-  // An invoke is eligible for inlining in the following cases:
+  // An invoke is eligible for inlinining in the following cases:
   //
   // - if it does not return the receiver
   // - if there are no uses of the out value
@@ -684,8 +645,7 @@
       DexEncodedMethod singleTarget,
       Set<Instruction> indirectUsers) {
     assert isEligibleSingleTarget(singleTarget);
-    if (ListUtils.lastIndexMatching(
-        invoke.inValues(), v -> v.getAliasedValue() == eligibleInstance) > 0) {
+    if (invoke.inValues().lastIndexOf(eligibleInstance) > 0) {
       return null; // Instance passed as an argument.
     }
     return isEligibleVirtualMethodCall(
@@ -754,8 +714,7 @@
       return false;
     }
     if (invoke.isInvokeMethodWithReceiver()
-        && invoke.asInvokeMethodWithReceiver().getReceiver().getAliasedValue()
-            == eligibleInstance) {
+        && invoke.asInvokeMethodWithReceiver().getReceiver() == eligibleInstance) {
       return false;
     }
     if (invoke.isInvokeSuper()) {
@@ -796,7 +755,7 @@
 
     // If we got here with invocation on receiver the user is ineligible.
     if (invoke.isInvokeMethodWithReceiver()) {
-      if (arguments.get(0).getAliasedValue() == eligibleInstance) {
+      if (arguments.get(0) == eligibleInstance) {
         return false;
       }
 
@@ -816,7 +775,7 @@
     }
 
     for (int argIndex = 0; argIndex < arguments.size(); argIndex++) {
-      Value argument = arguments.get(argIndex).getAliasedValue();
+      Value argument = arguments.get(argIndex);
       if (argument == eligibleInstance && optimizationInfo.getParameterUsages(argIndex).notUsed()) {
         // Reference can be removed since it's not used.
         unusedArguments.add(new Pair<>(invoke, argIndex));
@@ -837,7 +796,7 @@
       Supplier<InliningOracle> defaultOracle) {
     // Go through all arguments, see if all usages of eligibleInstance are good.
     for (int argIndex = 0; argIndex < arguments.size(); argIndex++) {
-      Value argument = arguments.get(argIndex).getAliasedValue();
+      Value argument = arguments.get(argIndex);
       if (argument != eligibleInstance) {
         continue; // Nothing to worry about.
       }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
index 1e7d21a..88a20da 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/ClassStaticizer.java
@@ -28,7 +28,6 @@
 import com.android.tools.r8.ir.conversion.IRConverter;
 import com.android.tools.r8.ir.optimize.info.OptimizationFeedback;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
-import com.android.tools.r8.utils.ListUtils;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
 import java.util.Arrays;
@@ -44,7 +43,6 @@
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.BiConsumer;
-import java.util.function.Predicate;
 
 public final class ClassStaticizer {
 
@@ -232,8 +230,8 @@
       // We are inside an instance method of candidate class (not an instance initializer
       // which we will check later), check if all the references to 'this' are valid
       // (the call will invalidate the candidate if some of them are not valid).
-      analyzeAllValueUsers(
-          receiverClassCandidateInfo, receiverValue, factory.isConstructor(method.method));
+      analyzeAllValueUsers(receiverClassCandidateInfo,
+          receiverValue, factory.isConstructor(method.method));
 
       // If the candidate is still valid, ignore all instructions
       // we treat as valid usages on receiver.
@@ -291,7 +289,7 @@
           // If the candidate still valid, ignore all usages in further analysis.
           Value value = instruction.outValue();
           if (value != null) {
-            alreadyProcessed.addAll(value.aliasedUsers());
+            alreadyProcessed.addAll(value.uniqueUsers());
           }
         }
         continue;
@@ -435,16 +433,14 @@
         appView.appInfo().lookupDirectTarget(invoke.getInvokedMethod());
     List<Value> values = invoke.inValues();
 
-    if (ListUtils.lastIndexMatching(values, v -> v.getAliasedValue() == candidateValue) != 0
-        || methodInvoked == null
-        || methodInvoked.method.holder != candidateType) {
+    if (values.lastIndexOf(candidateValue) != 0 ||
+        methodInvoked == null || methodInvoked.method.holder != candidateType) {
       return false;
     }
 
     // Check arguments.
     for (int i = 1; i < values.size(); i++) {
-      Value arg = values.get(i).getAliasedValue();
-      if (arg.isPhi() || !arg.definition.isConstInstruction()) {
+      if (!values.get(i).definition.isConstInstruction()) {
         return false;
       }
     }
@@ -488,54 +484,40 @@
 
   private CandidateInfo analyzeAllValueUsers(
       CandidateInfo candidateInfo, Value value, boolean ignoreSuperClassInitInvoke) {
-    assert value != null && value == value.getAliasedValue();
+    assert value != null;
 
     if (value.numberOfPhiUsers() > 0) {
       return candidateInfo.invalidate();
     }
 
-    Set<Instruction> currentUsers = value.uniqueUsers();
-    while (!currentUsers.isEmpty()) {
-      Set<Instruction> indirectUsers = Sets.newIdentityHashSet();
-      for (Instruction user : currentUsers) {
-        if (user.isAssume()) {
-          if (user.outValue().numberOfPhiUsers() > 0) {
-            return candidateInfo.invalidate();
-          }
-          indirectUsers.addAll(user.outValue().uniqueUsers());
-          continue;
-        }
-        if (user.isInvokeVirtual() || user.isInvokeDirect() /* private methods */) {
-          InvokeMethodWithReceiver invoke = user.asInvokeMethodWithReceiver();
-          Predicate<Value> isAliasedValue = v -> v.getAliasedValue() == value;
-          DexMethod methodReferenced = invoke.getInvokedMethod();
-          if (factory.isConstructor(methodReferenced)) {
-            assert user.isInvokeDirect();
-            if (ignoreSuperClassInitInvoke
-                && ListUtils.lastIndexMatching(invoke.inValues(), isAliasedValue) == 0
-                && methodReferenced == factory.objectMethods.constructor) {
-              // If we are inside candidate constructor and analyzing usages
-              // of the receiver, we want to ignore invocations of superclass
-              // constructor which will be removed after staticizing.
-              continue;
-            }
-            return candidateInfo.invalidate();
-          }
-          AppInfo appInfo = appView.appInfo();
-          DexEncodedMethod methodInvoked = user.isInvokeDirect()
-              ? appInfo.lookupDirectTarget(methodReferenced)
-              : appInfo.lookupVirtualTarget(methodReferenced.holder, methodReferenced);
-          if (ListUtils.lastIndexMatching(invoke.inValues(), isAliasedValue) == 0
-              && methodInvoked != null
-              && methodInvoked.method.holder == candidateInfo.candidate.type) {
+    for (Instruction user : value.uniqueUsers()) {
+      if (user.isInvokeVirtual() || user.isInvokeDirect() /* private methods */) {
+        InvokeMethodWithReceiver invoke = user.asInvokeMethodWithReceiver();
+        DexMethod methodReferenced = invoke.getInvokedMethod();
+        if (factory.isConstructor(methodReferenced)) {
+          assert user.isInvokeDirect();
+          if (ignoreSuperClassInitInvoke &&
+              invoke.inValues().lastIndexOf(value) == 0 &&
+              methodReferenced == factory.objectMethods.constructor) {
+            // If we are inside candidate constructor and analyzing usages
+            // of the receiver, we want to ignore invocations of superclass
+            // constructor which will be removed after staticizing.
             continue;
           }
+          return candidateInfo.invalidate();
         }
-
-        // All other users are not allowed.
-        return candidateInfo.invalidate();
+        AppInfo appInfo = appView.appInfo();
+        DexEncodedMethod methodInvoked = user.isInvokeDirect()
+            ? appInfo.lookupDirectTarget(methodReferenced)
+            : appInfo.lookupVirtualTarget(methodReferenced.holder, methodReferenced);
+        if (invoke.inValues().lastIndexOf(value) == 0 &&
+            methodInvoked != null && methodInvoked.method.holder == candidateInfo.candidate.type) {
+          continue;
+        }
       }
-      currentUsers = indirectUsers;
+
+      // All other users are not allowed.
+      return candidateInfo.invalidate();
     }
 
     return candidateInfo;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
index 3956609..1ab806d 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/staticizer/StaticizingProcessor.java
@@ -340,11 +340,10 @@
       }
       Set<Phi> chainedPhis = Sets.newIdentityHashSet();
       for (Value operand : phi.getOperands()) {
-        Value v = operand.getAliasedValue();
-        if (v.isPhi()) {
+        if (operand.isPhi()) {
           chainedPhis.add(operand.asPhi());
         } else {
-          if (v != thisValue) {
+          if (operand != thisValue) {
             return false;
           }
         }
@@ -361,7 +360,7 @@
 
   // Fixup `this` usages: rewrites all method calls so that they point to static methods.
   private void fixupStaticizedThisUsers(IRCode code, Value thisValue) {
-    assert thisValue != null && thisValue == thisValue.getAliasedValue();
+    assert thisValue != null;
     // Depending on other optimizations, e.g., inlining, `this` can be flown to phis.
     Set<Phi> trivialPhis = Sets.newIdentityHashSet();
     boolean onlyHasTrivialPhis = testAndCollectPhisComposedOfThis(
@@ -369,10 +368,10 @@
     assert thisValue.numberOfPhiUsers() == 0 || onlyHasTrivialPhis;
     assert trivialPhis.isEmpty() || onlyHasTrivialPhis;
 
-    Set<Instruction> users = SetUtils.newIdentityHashSet(thisValue.aliasedUsers());
+    Set<Instruction> users = SetUtils.newIdentityHashSet(thisValue.uniqueUsers());
     // If that is the case, method calls we want to fix up include users of those phis.
     for (Phi phi : trivialPhis) {
-      users.addAll(phi.aliasedUsers());
+      users.addAll(phi.uniqueUsers());
     }
 
     fixupStaticizedValueUsers(code, users);
@@ -426,14 +425,13 @@
       }
       Set<Phi> chainedPhis = Sets.newIdentityHashSet();
       for (Value operand : phi.getOperands()) {
-        Value v = operand.getAliasedValue();
-        if (v.isPhi()) {
+        if (operand.isPhi()) {
           chainedPhis.add(operand.asPhi());
         } else {
-          if (!v.definition.isStaticGet()) {
+          if (!operand.definition.isStaticGet()) {
             return false;
           }
-          if (v.definition.asStaticGet().getField() != field) {
+          if (operand.definition.asStaticGet().getField() != field) {
             return false;
           }
         }
@@ -460,10 +458,10 @@
     assert dest.numberOfPhiUsers() == 0 || onlyHasTrivialPhis;
     assert trivialPhis.isEmpty() || onlyHasTrivialPhis;
 
-    Set<Instruction> users = SetUtils.newIdentityHashSet(dest.aliasedUsers());
+    Set<Instruction> users = SetUtils.newIdentityHashSet(dest.uniqueUsers());
     // If that is the case, method calls we want to fix up include users of those phis.
     for (Phi phi : trivialPhis) {
-      users.addAll(phi.aliasedUsers());
+      users.addAll(phi.uniqueUsers());
     }
 
     fixupStaticizedValueUsers(code, users);
@@ -477,9 +475,6 @@
 
   private void fixupStaticizedValueUsers(IRCode code, Set<Instruction> users) {
     for (Instruction user : users) {
-      if (user.isAssume()) {
-        continue;
-      }
       assert user.isInvokeVirtual() || user.isInvokeDirect();
       InvokeMethodWithReceiver invoke = user.asInvokeMethodWithReceiver();
       Value newValue = null;
diff --git a/src/main/java/com/android/tools/r8/utils/ListUtils.java b/src/main/java/com/android/tools/r8/utils/ListUtils.java
index 370d5e2..a9c3f98 100644
--- a/src/main/java/com/android/tools/r8/utils/ListUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ListUtils.java
@@ -8,19 +8,9 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.function.Function;
-import java.util.function.Predicate;
 
 public class ListUtils {
 
-  public static <T> int lastIndexMatching(List<T> list, Predicate<T> tester) {
-    for (int i = list.size() - 1; i >= 0; i--) {
-      if (tester.test(list.get(i))) {
-        return i;
-      }
-    }
-    return -1;
-  }
-
   public static <S, T> List<T> map(Collection<S> list, Function<S, T> fn) {
     List<T> result = new ArrayList<>(list.size());
     for (S element : list) {
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/callsites/nullability/WithStaticizerTest.java b/src/test/java/com/android/tools/r8/ir/optimize/callsites/nullability/WithStaticizerTest.java
index d55484d..79ea92e 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/callsites/nullability/WithStaticizerTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/callsites/nullability/WithStaticizerTest.java
@@ -44,6 +44,7 @@
         .addKeepMainRule(MAIN)
         .enableInliningAnnotations()
         .enableClassInliningAnnotations()
+        .noMinification()
         .setMinApi(parameters.getRuntime())
         .run(parameters.getRuntime(), MAIN)
         .assertSuccessWithOutputLines("Input")
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java b/src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java
deleted file mode 100644
index eabd3cc..0000000
--- a/src/test/java/com/android/tools/r8/ir/optimize/outliner/OutlinesWithNonNullTest.java
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.ir.optimize.outliner;
-
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.InternalOptions.OutlineOptions;
-import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.CodeMatchers;
-import com.android.tools.r8.utils.codeinspector.MethodSubject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class OutlinesWithNonNullTest extends TestBase {
-  private static final String JVM_OUTPUT = StringUtils.lines(
-      "42",
-      "arg",
-      "42",
-      "arg"
-  );
-
-  private final TestParameters parameters;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    return getTestParameters().withAllRuntimes().build();
-  }
-
-  public OutlinesWithNonNullTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testNonNullOnOneSide() throws Exception {
-    testForR8(parameters.getBackend())
-        .enableClassInliningAnnotations()
-        .enableInliningAnnotations()
-        .addProgramClasses(TestArg.class, TestClassWithNonNullOnOneSide.class)
-        .addKeepMainRule(TestClassWithNonNullOnOneSide.class)
-        .setMinApi(parameters.getRuntime())
-        .allowAccessModification()
-        .noMinification()
-        .addOptionsModification(
-            options -> {
-              options.outline.threshold = 2;
-              options.outline.minSize = 2;
-            })
-        .compile()
-        .inspect(inspector -> validateOutlining(inspector, TestClassWithNonNullOnOneSide.class))
-        .run(parameters.getRuntime(), TestClassWithNonNullOnOneSide.class)
-        .assertSuccessWithOutput(JVM_OUTPUT);
-  }
-
-  @Test
-  public void testNonNullOnBothSides() throws Exception {
-    testForR8(parameters.getBackend())
-        .enableClassInliningAnnotations()
-        .enableInliningAnnotations()
-        .addProgramClasses(TestArg.class, TestClassWithNonNullOnBothSides.class)
-        .addKeepMainRule(TestClassWithNonNullOnBothSides.class)
-        .setMinApi(parameters.getRuntime())
-        .allowAccessModification()
-        .noMinification()
-        .addOptionsModification(
-            options -> {
-              options.outline.threshold = 2;
-              options.outline.minSize = 2;
-            })
-        .compile()
-        .inspect(inspector -> validateOutlining(inspector, TestClassWithNonNullOnBothSides.class))
-        .run(parameters.getRuntime(), TestClassWithNonNullOnBothSides.class)
-        .assertSuccessWithOutput(JVM_OUTPUT);
-  }
-
-  private void validateOutlining(CodeInspector inspector, Class<?> main) {
-    ClassSubject outlineClass = inspector.clazz(OutlineOptions.CLASS_NAME);
-    assertThat(outlineClass, isPresent());
-    MethodSubject outlineMethod = outlineClass.uniqueMethodWithName("outline0");
-    assertThat(outlineMethod, isPresent());
-
-    ClassSubject argClass = inspector.clazz(TestArg.class);
-    assertThat(argClass, isPresent());
-    MethodSubject printHash = argClass.uniqueMethodWithName("printHash");
-    assertThat(printHash, isPresent());
-    MethodSubject printArg= argClass.uniqueMethodWithName("printArg");
-    assertThat(printArg, isPresent());
-
-    ClassSubject classSubject = inspector.clazz(main);
-    assertThat(classSubject, isPresent());
-    MethodSubject method1 = classSubject.uniqueMethodWithName("method1");
-    assertThat(method1, isPresent());
-    assertThat(method1, CodeMatchers.invokesMethod(outlineMethod));
-    assertThat(method1, not(CodeMatchers.invokesMethod(printHash)));
-    assertThat(method1, not(CodeMatchers.invokesMethod(printArg)));
-    MethodSubject method2 = classSubject.uniqueMethodWithName("method2");
-    assertThat(method2, isPresent());
-    assertThat(method2, CodeMatchers.invokesMethod(outlineMethod));
-    assertThat(method2, not(CodeMatchers.invokesMethod(printHash)));
-    assertThat(method2, not(CodeMatchers.invokesMethod(printArg)));
-  }
-
-  @NeverClassInline
-  public static class TestArg {
-    @Override
-    public int hashCode() {
-      return 42;
-    }
-
-    @Override
-    public String toString() {
-      return "arg";
-    }
-
-    @NeverInline
-    static void printHash(Object arg) {
-      if (arg == null) {
-        throw new NullPointerException();
-      }
-      System.out.println(arg.hashCode());
-      // This method guarantees that, at the normal exit, argument is not null.
-    }
-
-    @NeverInline
-    static void printArg(Object arg) {
-      System.out.println(arg);
-    }
-  }
-
-  static class TestClassWithNonNullOnOneSide {
-    @NeverInline
-    static void method1(Object arg) {
-      TestArg.printHash(arg);
-      // We will have non-null aliasing here.
-      TestArg.printArg(arg);
-    }
-
-    @NeverInline
-    static void method2(Object arg) {
-      if (arg != null) {
-        // We will have non-null aliasing here.
-        TestArg.printHash(arg);
-        TestArg.printArg(arg);
-      }
-    }
-
-    public static void main(String... args) {
-      TestArg arg = new TestArg();
-      method1(arg);
-      method2(arg);
-    }
-  }
-
-  static class TestClassWithNonNullOnBothSides {
-    @NeverInline
-    static void method1(Object arg) {
-      TestArg.printHash(arg);
-      // We will have non-null aliasing here.
-      TestArg.printArg(arg);
-    }
-
-    @NeverInline
-    static void method2(Object arg) {
-      TestArg.printHash(arg);
-      // We will have non-null aliasing here.
-      TestArg.printArg(arg);
-    }
-
-    public static void main(String... args) {
-      TestArg arg = new TestArg();
-      method1(arg);
-      method2(arg);
-    }
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/CompanionAsArgumentTest.java b/src/test/java/com/android/tools/r8/ir/optimize/staticizer/CompanionAsArgumentTest.java
deleted file mode 100644
index a93e72b..0000000
--- a/src/test/java/com/android/tools/r8/ir/optimize/staticizer/CompanionAsArgumentTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.ir.optimize.staticizer;
-
-import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
-import static org.hamcrest.CoreMatchers.not;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import com.android.tools.r8.NeverClassInline;
-import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.TestBase;
-import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.TestParametersCollection;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.android.tools.r8.utils.codeinspector.MethodSubject;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-
-@RunWith(Parameterized.class)
-public class CompanionAsArgumentTest extends TestBase {
-  private static final Class<?> MAIN = Main.class;
-
-  @Parameterized.Parameters(name = "{0}")
-  public static TestParametersCollection data() {
-    // TODO(b/112831361): support for class staticizer in CF backend.
-    return getTestParameters().withDexRuntimes().build();
-  }
-
-  private final TestParameters parameters;
-
-  public CompanionAsArgumentTest(TestParameters parameters) {
-    this.parameters = parameters;
-  }
-
-  @Test
-  public void testR8() throws Exception {
-    testForR8(parameters.getBackend())
-        .addInnerClasses(CompanionAsArgumentTest.class)
-        .addKeepMainRule(MAIN)
-        .enableInliningAnnotations()
-        .enableClassInliningAnnotations()
-        .setMinApi(parameters.getRuntime())
-        .run(parameters.getRuntime(), MAIN)
-        .assertSuccessWithOutputLines("Companion#foo(true)")
-        .inspect(this::inspect);
-  }
-
-  private void inspect(CodeInspector inspector) {
-    // Check if the candidate is not staticized.
-    ClassSubject companion = inspector.clazz(Host.Companion.class);
-    assertThat(companion, isPresent());
-    MethodSubject foo = companion.uniqueMethodWithName("foo");
-    assertThat(foo, isPresent());
-    assertTrue(foo.streamInstructions().anyMatch(
-        i -> i.isInvokeVirtual()
-            && i.getMethod().toSourceString().contains("PrintStream.println")));
-
-    // Nothing migrated from Companion to Host.
-    ClassSubject host = inspector.clazz(Host.class);
-    assertThat(host, isPresent());
-    MethodSubject migrated_foo = host.uniqueMethodWithName("foo");
-    assertThat(migrated_foo, not(isPresent()));
-  }
-
-  @NeverClassInline
-  static class Host {
-    private static final Companion companion = new Companion();
-
-    static class Companion {
-      @NeverInline
-      public void foo(Object arg) {
-        System.out.println("Companion#foo(" + (arg != null) + ")");
-      }
-    }
-
-    @NeverInline
-    static void bar() {
-      // The target singleton is used as not only a receiver but also an argument.
-      companion.foo(companion);
-    }
-  }
-
-  static class Main {
-    public static void main(String[] args) {
-      Host.bar();
-    }
-  }
-}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking18Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking18Test.java
index f28f242..fa76296 100644
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking18Test.java
+++ b/src/test/java/com/android/tools/r8/shaking/examples/TreeShaking18Test.java
@@ -3,14 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.shaking.examples;
 
-import static org.junit.Assert.assertFalse;
-
 import com.android.tools.r8.shaking.TreeShakingTest;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.collect.ImmutableList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import org.junit.Assert;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -44,7 +43,8 @@
   }
 
   private static void unusedRemoved(CodeInspector inspector) {
-    assertFalse(
+    // TODO(b/80455722): Change to assertFalse when tree-shaking detects this case.
+    Assert.assertTrue(
         "DerivedUnused should be removed", inspector.clazz("shaking18.DerivedUnused").isPresent());
   }
 }
diff --git a/src/test/java/com/android/tools/r8/utils/ListUtilsTest.java b/src/test/java/com/android/tools/r8/utils/ListUtilsTest.java
deleted file mode 100644
index 3a63555..0000000
--- a/src/test/java/com/android/tools/r8/utils/ListUtilsTest.java
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-package com.android.tools.r8.utils;
-
-import static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Predicate;
-import org.junit.Test;
-
-public class ListUtilsTest {
-
-  private List<Integer> createInputData(int size) {
-    List<Integer> input = new ArrayList<>(size);
-    for (int i = 0; i < size; i++) {
-      input.add(i);
-    }
-    return input;
-  }
-
-  @Test
-  public void lastIndexOf_outOfRange() {
-    List<Integer> input = createInputData(3);
-    Predicate<Integer> tester = x -> x * x == -1;
-    assertEquals(-1, ListUtils.lastIndexMatching(input, tester));
-  }
-
-  @Test
-  public void lastIndexOf_first() {
-    List<Integer> input = createInputData(3);
-    Predicate<Integer> tester = x -> x * x == 0;
-    assertEquals(0, ListUtils.lastIndexMatching(input, tester));
-  }
-
-  @Test
-  public void lastIndexOf_middle() {
-    List<Integer> input = createInputData(4);
-    Predicate<Integer> tester = x -> x * x == 4;
-    assertEquals(2, ListUtils.lastIndexMatching(input, tester));
-  }
-
-  @Test
-  public void lastIndexOf_last() {
-    List<Integer> input = createInputData(2);
-    Predicate<Integer> tester = x -> x * x == 1;
-    assertEquals(1, ListUtils.lastIndexMatching(input, tester));
-  }
-}