diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 75ce373..7538bb1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -9,7 +9,8 @@
 import com.android.tools.r8.kotlin.KotlinInfo;
 import com.android.tools.r8.origin.Origin;
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.Iterators;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Set;
@@ -99,13 +100,23 @@
   }
 
   public Iterable<DexEncodedField> fields() {
-    return () ->
-        Iterators.concat(Iterators.forArray(instanceFields), Iterators.forArray(staticFields));
+    return fields(Predicates.alwaysTrue());
+  }
+
+  public Iterable<DexEncodedField> fields(final Predicate<? super DexEncodedField> predicate) {
+    return Iterables.concat(
+        Iterables.filter(Arrays.asList(instanceFields), predicate::test),
+        Iterables.filter(Arrays.asList(staticFields), predicate::test));
   }
 
   public Iterable<DexEncodedMethod> methods() {
-    return () ->
-        Iterators.concat(Iterators.forArray(directMethods), Iterators.forArray(virtualMethods));
+    return methods(Predicates.alwaysTrue());
+  }
+
+  public Iterable<DexEncodedMethod> methods(Predicate<? super DexEncodedMethod> predicate) {
+    return Iterables.concat(
+        Iterables.filter(Arrays.asList(directMethods), predicate::test),
+        Iterables.filter(Arrays.asList(virtualMethods), predicate::test));
   }
 
   @Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
index 39737ea..d1bfc9a 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
@@ -4,8 +4,12 @@
 package com.android.tools.r8.shaking;
 
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.AppInfo;
+import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.shaking.ProguardConfigurationParser.IdentifierPatternWithWildcards;
 import com.android.tools.r8.utils.StringUtils;
@@ -160,11 +164,14 @@
     return type;
   }
 
-  public boolean matches(DexEncodedField field, DexStringCache stringCache) {
+  public boolean matches(
+      DexEncodedField field, AppView<? extends AppInfo> appView, DexStringCache stringCache) {
+    DexField originalSignature = appView.graphLense().getOriginalFieldSignature(field.field);
     switch (getRuleType()) {
       case ALL:
       case ALL_FIELDS:
         // Access flags check.
+        // TODO(b/117330692): The access flags may have changed as a result of access relaxation.
         if (!getAccessFlags().containsAll(field.accessFlags)
             || !getNegatedAccessFlags().containsNone(field.accessFlags)) {
           break;
@@ -173,17 +180,18 @@
         return RootSetBuilder.containsAnnotation(annotation, field.annotations);
       case FIELD:
         // Name check.
-        String name = stringCache.lookupString(field.field.name);
+        String name = stringCache.lookupString(originalSignature.name);
         if (!getName().matches(name)) {
           break;
         }
         // Access flags check.
+        // TODO(b/117330692): The access flags may have changed as a result of access relaxation.
         if (!getAccessFlags().containsAll(field.accessFlags)
             || !getNegatedAccessFlags().containsNone(field.accessFlags)) {
           break;
         }
         // Type check.
-        if (!this.type.matches(field.field.type)) {
+        if (!getType().matches(originalSignature.type)) {
           break;
         }
         // Annotations check
@@ -200,7 +208,9 @@
     return false;
   }
 
-  public boolean matches(DexEncodedMethod method, DexStringCache stringCache) {
+  public boolean matches(
+      DexEncodedMethod method, AppView<? extends AppInfo> appView, DexStringCache stringCache) {
+    DexMethod originalSignature = appView.graphLense().getOriginalMethodSignature(method.method);
     switch (getRuleType()) {
       case ALL_METHODS:
         if (method.isClassInitializer()) {
@@ -209,6 +219,7 @@
         // Fall through for all other methods.
       case ALL:
         // Access flags check.
+        // TODO(b/117330692): The access flags may have changed as a result of access relaxation.
         if (!getAccessFlags().containsAll(method.accessFlags)
             || !getNegatedAccessFlags().containsNone(method.accessFlags)) {
           break;
@@ -217,18 +228,21 @@
         return RootSetBuilder.containsAnnotation(annotation, method.annotations);
       case METHOD:
         // Check return type.
-        if (!type.matches(method.method.proto.returnType)) {
+        // TODO(b/110141157): The name of the return type may have changed as a result of vertical
+        // class merging. We should use the original type name.
+        if (!type.matches(originalSignature.proto.returnType)) {
           break;
         }
         // Fall through for access flags, name and arguments.
       case CONSTRUCTOR:
       case INIT:
         // Name check.
-        String name = stringCache.lookupString(method.method.name);
+        String name = stringCache.lookupString(originalSignature.name);
         if (!getName().matches(name)) {
           break;
         }
         // Access flags check.
+        // TODO(b/117330692): The access flags may have changed as a result of access relaxation.
         if (!getAccessFlags().containsAll(method.accessFlags)
             || !getNegatedAccessFlags().containsNone(method.accessFlags)) {
           break;
@@ -241,23 +255,20 @@
         List<ProguardTypeMatcher> arguments = getArguments();
         if (arguments.size() == 1 && arguments.get(0).isTripleDotPattern()) {
           return true;
-        } else {
-          DexType[] parameters = method.method.proto.parameters.values;
-          if (parameters.length != arguments.size()) {
-            break;
-          }
-          int i = 0;
-          for (; i < parameters.length; i++) {
-            if (!arguments.get(i).matches(parameters[i])) {
-              break;
-            }
-          }
-          if (i == parameters.length) {
-            // All parameters matched.
-            return true;
+        }
+        DexType[] parameters = originalSignature.proto.parameters.values;
+        if (parameters.length != arguments.size()) {
+          break;
+        }
+        for (int i = 0; i < parameters.length; i++) {
+          // TODO(b/110141157): The names of the parameter types may have changed as a result of
+          // vertical class merging. We should use the original type names.
+          if (!arguments.get(i).matches(parameters[i])) {
+            return false;
           }
         }
-        break;
+        // All parameters matched.
+        return true;
       case ALL_FIELDS:
       case FIELD:
         break;
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index e6f6a17..d5d5422 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -29,6 +29,7 @@
 import com.android.tools.r8.utils.ThreadUtils;
 import com.google.common.base.Equivalence.Wrapper;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import java.io.PrintStream;
 import java.util.ArrayList;
@@ -164,39 +165,9 @@
     // seems not to care, so users have started to use this inconsistently. We are thus
     // inconsistent, as well, but tell them.
     // TODO(herhut): One day make this do what it says.
-    if (rule.hasInheritanceClassName()) {
-      boolean extendsExpected =
-          anySuperTypeMatches(
-              clazz.superType,
-              application::definitionFor,
-              rule.getInheritanceClassName(),
-              rule.getInheritanceAnnotation());
-      boolean implementsExpected = false;
-      if (!extendsExpected) {
-        implementsExpected =
-            anyImplementedInterfaceMatches(
-                clazz,
-                application::definitionFor,
-                rule.getInheritanceClassName(),
-                rule.getInheritanceAnnotation());
-      }
-      if (!extendsExpected && !implementsExpected) {
-        return;
-      }
-      // Warn if users got it wrong, but only warn once.
-      if (extendsExpected && !rule.getInheritanceIsExtends()) {
-        if (rulesThatUseExtendsOrImplementsWrong.add(rule)) {
-          options.reporter.warning(
-              new StringDiagnostic(
-                  "The rule `" + rule + "` uses implements but actually matches extends."));
-        }
-      } else if (implementsExpected && rule.getInheritanceIsExtends()) {
-        if (rulesThatUseExtendsOrImplementsWrong.add(rule)) {
-          options.reporter.warning(
-              new StringDiagnostic(
-                  "The rule `" + rule + "` uses extends but actually matches implements."));
-        }
-      }
+    if (rule.hasInheritanceClassName()
+        && !satisfyInheritanceRule(clazz, application::definitionFor, rule)) {
+      return;
     }
 
     if (rule.getClassNames().matches(clazz.type)) {
@@ -340,95 +311,39 @@
       Set<DexEncodedMethod> liveMethods,
       Set<DexEncodedField> liveFields) throws ExecutionException {
     application.timing.begin("Find consequent items for -if rules...");
-    Function<DexType, DexClass> definitionForWithLiveTypes =
-        type -> {
-          DexClass clazz = appView.appInfo().definitionFor(type);
-          if (clazz != null && liveTypes.contains(clazz.type)) {
-            return clazz;
-          }
-          return null;
-        };
     try {
-      List<Future<?>> futures = new ArrayList<>();
       if (rules != null) {
+        IfRuleEvaluator evaluator =
+            new IfRuleEvaluator(liveTypes, liveMethods, liveFields, executorService);
         for (ProguardConfigurationRule rule : rules) {
           assert rule instanceof ProguardIfRule;
           ProguardIfRule ifRule = (ProguardIfRule) rule;
-          // Depending on which types trigger the -if rule, the application of the subsequent
+          // Depending on which types that trigger the -if rule, the application of the subsequent
           // -keep rule may vary (due to back references). So, we need to try all pairs of -if rule
           // and live types.
-          for (DexType currentLiveType : liveTypes) {
-            DexClass currentLiveClass = appView.appInfo().definitionFor(currentLiveType);
-            if (currentLiveClass == null) {
+          for (DexType type : liveTypes) {
+            DexClass clazz = appView.appInfo().definitionFor(type);
+            if (clazz == null) {
               continue;
             }
-            if (!satisfyClassType(rule, currentLiveClass)) {
-              continue;
-            }
-            if (!satisfyAccessFlag(rule, currentLiveClass)) {
-              continue;
-            }
-            if (!satisfyAnnotation(rule, currentLiveClass)) {
-              continue;
-            }
-            if (ifRule.hasInheritanceClassName()) {
-              if (!satisfyInheritanceRule(currentLiveType, definitionForWithLiveTypes, ifRule)) {
-                // Try another live type since the current one doesn't satisfy the inheritance rule.
-                continue;
-              }
-            }
-            if (ifRule.getClassNames().matches(currentLiveType)) {
-              Collection<ProguardMemberRule> memberKeepRules = ifRule.getMemberRules();
-              if (memberKeepRules.isEmpty()) {
-                ProguardIfRule materializedRule = ifRule.materialize();
-                runPerRule(
-                    executorService, futures, materializedRule.subsequentRule, materializedRule);
-                // No member rule to satisfy. Move on to the next live type.
-                continue;
-              }
-              Set<DexDefinition> filteredFields = liveFields.stream()
-                  .filter(f -> f.field.getHolder() == currentLiveType)
-                  .collect(Collectors.toSet());
-              Set<DexDefinition> filteredMethods = liveMethods.stream()
-                  .filter(m -> m.method.getHolder() == currentLiveType)
-                  .collect(Collectors.toSet());
-              // If the number of member rules to hold is more than live members, we can't make it.
-              if (filteredFields.size() + filteredMethods.size() < memberKeepRules.size()) {
-                continue;
-              }
-              // Depending on which members trigger the -if rule, the application of the subsequent
-              // -keep rule may vary (due to back references). So, we need to try literally all
-              // combinations of live members.
-              // TODO(b/79486261): Some of those are equivalent from the point of view of -if rule.
-              Set<Set<DexDefinition>> combinationsOfMembers = Sets.combinations(
-                  Sets.union(filteredFields, filteredMethods), memberKeepRules.size());
-              for (Set<DexDefinition> combination : combinationsOfMembers) {
-                Set<DexEncodedField> fieldsInCombination =
-                    DexDefinition.filterDexEncodedField(combination.stream())
-                        .collect(Collectors.toSet());
-                Set<DexEncodedMethod> methodsInCombination =
-                    DexDefinition.filterDexEncodedMethod(combination.stream())
-                        .collect(Collectors.toSet());
-                // Member rules are combined as AND logic: if found unsatisfied member rule, this
-                // combination of live members is not a good fit.
-                boolean satisfied = true;
-                for (ProguardMemberRule memberRule : memberKeepRules) {
-                  if (!ruleSatisfiedByFields(memberRule, fieldsInCombination)
-                      && !ruleSatisfiedByMethods(memberRule, methodsInCombination)) {
-                    satisfied = false;
-                    break;
-                  }
-                }
-                if (satisfied) {
-                  ProguardIfRule materializedRule = ifRule.materialize();
-                  runPerRule(
-                      executorService, futures, materializedRule.subsequentRule, materializedRule);
-                }
+
+            // Check if the class matches the if-rule.
+            evaluator.evaluateIfRule(ifRule, clazz, clazz);
+
+            // Check if one of the types that have been merged into `clazz` satisfies the if-rule.
+            if (options.enableVerticalClassMerging && appView.verticallyMergedClasses() != null) {
+              for (DexType sourceType : appView.verticallyMergedClasses().getSourcesFor(type)) {
+                // Note that, although `sourceType` has been merged into `type`, the dex class for
+                // `sourceType` is still available until the second round of tree shaking. This way
+                // we can still retrieve the access flags of `sourceType`.
+                DexClass sourceClass = appView.appInfo().definitionFor(sourceType);
+                assert sourceClass != null;
+                evaluator.evaluateIfRule(ifRule, sourceClass, clazz);
               }
             }
           }
         }
-        ThreadUtils.awaitFutures(futures);
+        ThreadUtils.awaitFutures(evaluator.futures);
       }
     } finally {
       application.timing.end();
@@ -436,6 +351,115 @@
     return new ConsequentRootSet(noShrinking, noOptimization, noObfuscation, dependentNoShrinking);
   }
 
+  private class IfRuleEvaluator {
+
+    private final Set<DexType> liveTypes;
+    private final Set<DexEncodedMethod> liveMethods;
+    private final Set<DexEncodedField> liveFields;
+    private final ExecutorService executorService;
+
+    private final List<Future<?>> futures = new ArrayList<>();
+
+    public IfRuleEvaluator(
+        Set<DexType> liveTypes,
+        Set<DexEncodedMethod> liveMethods,
+        Set<DexEncodedField> liveFields,
+        ExecutorService executorService) {
+      this.liveTypes = liveTypes;
+      this.liveMethods = liveMethods;
+      this.liveFields = liveFields;
+      this.executorService = executorService;
+    }
+
+    /**
+     * Determines if `sourceClass` satisfies the given if-rule. If `sourceClass` has not been merged
+     * into another class, then `targetClass` is the same as `sourceClass`. Otherwise, `targetClass`
+     * denotes the class that `sourceClass` has been merged into.
+     */
+    private void evaluateIfRule(ProguardIfRule rule, DexClass sourceClass, DexClass targetClass) {
+      if (!satisfyClassType(rule, sourceClass)) {
+        return;
+      }
+      if (!satisfyAccessFlag(rule, sourceClass)) {
+        return;
+      }
+      if (!satisfyAnnotation(rule, sourceClass)) {
+        return;
+      }
+      // TODO(b/110141157): Handle the situation where the class in the extends/implements clause
+      // has been merged.
+      if (rule.hasInheritanceClassName()
+          && !satisfyInheritanceRule(sourceClass, this::definitionForWithLiveTypes, rule)) {
+        // Try another live type since the current one doesn't satisfy the inheritance rule.
+        return;
+      }
+      if (!rule.getClassNames().matches(sourceClass.type)) {
+        return;
+      }
+      Collection<ProguardMemberRule> memberKeepRules = rule.getMemberRules();
+      if (memberKeepRules.isEmpty()) {
+        materializeIfRule(rule);
+        return;
+      }
+
+      Set<DexDefinition> filteredMembers = Sets.newIdentityHashSet();
+      Iterables.addAll(
+          filteredMembers,
+          targetClass.fields(
+              f ->
+                  liveFields.contains(f)
+                      && appView.graphLense().getOriginalFieldSignature(f.field).getHolder()
+                          == sourceClass.type));
+      Iterables.addAll(
+          filteredMembers,
+          targetClass.methods(
+              m ->
+                  liveMethods.contains(m)
+                      && appView.graphLense().getOriginalMethodSignature(m.method).getHolder()
+                          == sourceClass.type));
+
+      // If the number of member rules to hold is more than live members, we can't make it.
+      if (filteredMembers.size() < memberKeepRules.size()) {
+        return;
+      }
+
+      // Depending on which members trigger the -if rule, the application of the subsequent
+      // -keep rule may vary (due to back references). So, we need to try literally all
+      // combinations of live members.
+      // TODO(b/79486261): Some of those are equivalent from the point of view of -if rule.
+      Sets.combinations(filteredMembers, memberKeepRules.size())
+          .forEach(
+              combination -> {
+                Collection<DexEncodedField> fieldsInCombination =
+                    DexDefinition.filterDexEncodedField(combination.stream())
+                        .collect(Collectors.toList());
+                Collection<DexEncodedMethod> methodsInCombination =
+                    DexDefinition.filterDexEncodedMethod(combination.stream())
+                        .collect(Collectors.toList());
+                // Member rules are combined as AND logic: if found unsatisfied member rule, this
+                // combination of live members is not a good fit.
+                boolean satisfied =
+                    memberKeepRules.stream()
+                        .allMatch(
+                            memberRule ->
+                                ruleSatisfiedByFields(memberRule, fieldsInCombination)
+                                    || ruleSatisfiedByMethods(memberRule, methodsInCombination));
+                if (satisfied) {
+                  materializeIfRule(rule);
+                }
+              });
+    }
+
+    private void materializeIfRule(ProguardIfRule rule) {
+      ProguardIfRule materializedRule = rule.materialize();
+      runPerRule(executorService, futures, materializedRule.subsequentRule, materializedRule);
+    }
+
+    private DexClass definitionForWithLiveTypes(DexType type) {
+      return liveTypes.contains(type) ? appView.appInfo().definitionFor(type) : null;
+    }
+  }
+
   private static DexDefinition testAndGetPrecondition(
       DexDefinition definition, Map<Predicate<DexDefinition>, DexDefinition> preconditionSupplier) {
     if (preconditionSupplier == null) {
@@ -497,7 +521,7 @@
     });
   }
 
-  // TODO(67934426): Test this code.
+  // TODO(b/67934426): Test this code.
   public static void writeSeeds(
       AppInfoWithLiveness appInfo, PrintStream out, Predicate<DexType> include) {
     for (DexReference seed : appInfo.getPinnedItems()) {
@@ -564,24 +588,34 @@
   }
 
   private boolean satisfyInheritanceRule(
-      DexType type,
-      Function<DexType, DexClass> definitionFor,
-      ProguardConfigurationRule rule) {
-    DexClass clazz = definitionFor.apply(type);
-    if (clazz == null) {
-      return false;
-    }
-    return
+      DexClass clazz, Function<DexType, DexClass> definitionFor, ProguardConfigurationRule rule) {
+    ProguardTypeMatcher inheritanceClassName = rule.getInheritanceClassName();
+    ProguardTypeMatcher inheritanceAnnotation = rule.getInheritanceAnnotation();
+    boolean extendsExpected =
         anySuperTypeMatches(
-            clazz.superType,
-            definitionFor,
-            rule.getInheritanceClassName(),
-            rule.getInheritanceAnnotation())
-        || anyImplementedInterfaceMatches(
-            clazz,
-            definitionFor,
-            rule.getInheritanceClassName(),
-            rule.getInheritanceAnnotation());
+            clazz.superType, definitionFor, inheritanceClassName, inheritanceAnnotation);
+    boolean implementsExpected = false;
+    if (!extendsExpected) {
+      implementsExpected =
+          anyImplementedInterfaceMatches(
+              clazz, definitionFor, inheritanceClassName, inheritanceAnnotation);
+    }
+    if (extendsExpected || implementsExpected) {
+      // Warn if users got it wrong, but only warn once.
+      if (rule.getInheritanceIsExtends()) {
+        if (implementsExpected && rulesThatUseExtendsOrImplementsWrong.add(rule)) {
+          options.reporter.warning(
+              new StringDiagnostic(
+                  "The rule `" + rule + "` uses extends but actually matches implements."));
+        }
+      } else if (extendsExpected && rulesThatUseExtendsOrImplementsWrong.add(rule)) {
+        options.reporter.warning(
+            new StringDiagnostic(
+                "The rule `" + rule + "` uses implements but actually matches extends."));
+      }
+      return true;
+    }
+    return false;
   }
 
   private boolean allRulesSatisfied(Collection<ProguardMemberRule> memberKeepRules,
@@ -606,11 +640,10 @@
   }
 
   private boolean ruleSatisfiedByMethods(
-      ProguardMemberRule rule,
-      Iterable<DexEncodedMethod> methods) {
+      ProguardMemberRule rule, Iterable<DexEncodedMethod> methods) {
     if (rule.getRuleType().includesMethods()) {
       for (DexEncodedMethod method : methods) {
-        if (rule.matches(method, dexStringCache)) {
+        if (rule.matches(method, appView, dexStringCache)) {
           return true;
         }
       }
@@ -619,22 +652,13 @@
   }
 
   private boolean ruleSatisfiedByMethods(ProguardMemberRule rule, DexEncodedMethod[] methods) {
-    if (rule.getRuleType().includesMethods()) {
-      for (DexEncodedMethod method : methods) {
-        if (rule.matches(method, dexStringCache)) {
-          return true;
-        }
-      }
-    }
-    return false;
+    return ruleSatisfiedByMethods(rule, Arrays.asList(methods));
   }
 
-  private boolean ruleSatisfiedByFields(
-      ProguardMemberRule rule,
-      Iterable<DexEncodedField> fields) {
+  private boolean ruleSatisfiedByFields(ProguardMemberRule rule, Iterable<DexEncodedField> fields) {
     if (rule.getRuleType().includesFields()) {
       for (DexEncodedField field : fields) {
-        if (rule.matches(field, dexStringCache)) {
+        if (rule.matches(field, appView, dexStringCache)) {
           return true;
         }
       }
@@ -643,14 +667,7 @@
   }
 
   private boolean ruleSatisfiedByFields(ProguardMemberRule rule, DexEncodedField[] fields) {
-    if (rule.getRuleType().includesFields()) {
-      for (DexEncodedField field : fields) {
-        if (rule.matches(field, dexStringCache)) {
-          return true;
-        }
-      }
-    }
-    return false;
+    return ruleSatisfiedByFields(rule, Arrays.asList(fields));
   }
 
   static boolean containsAnnotation(ProguardTypeMatcher classAnnotation,
@@ -680,7 +697,7 @@
       return;
     }
     for (ProguardMemberRule rule : rules) {
-      if (rule.matches(method, dexStringCache)) {
+      if (rule.matches(method, appView, dexStringCache)) {
         if (Log.ENABLED) {
           Log.verbose(getClass(), "Marking method `%s` due to `%s { %s }`.", method, context,
               rule);
@@ -699,7 +716,7 @@
       ProguardConfigurationRule context,
       DexDefinition precondition) {
     for (ProguardMemberRule rule : rules) {
-      if (rule.matches(field, dexStringCache)) {
+      if (rule.matches(field, appView, dexStringCache)) {
         if (Log.ENABLED) {
           Log.verbose(getClass(), "Marking field `%s` due to `%s { %s }`.", field, context,
               rule);
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index e592a9a..d41bd69 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -49,7 +49,9 @@
 import com.android.tools.r8.utils.Timing;
 import com.google.common.base.Equivalence;
 import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
 import it.unimi.dsi.fastutil.ints.Int2IntMap;
 import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
 import it.unimi.dsi.fastutil.objects.Reference2BooleanOpenHashMap;
@@ -91,9 +93,19 @@
   public static class VerticallyMergedClasses {
 
     private final Map<DexType, DexType> mergedClasses;
+    private final Map<DexType, List<DexType>> sources;
 
     private VerticallyMergedClasses(Map<DexType, DexType> mergedClasses) {
+      Map<DexType, List<DexType>> sources = Maps.newIdentityHashMap();
+      mergedClasses.forEach(
+          (source, target) ->
+              sources.computeIfAbsent(target, key -> new ArrayList<>()).add(source));
       this.mergedClasses = mergedClasses;
+      this.sources = sources;
+    }
+
+    public List<DexType> getSourcesFor(DexType type) {
+      return sources.getOrDefault(type, ImmutableList.of());
     }
 
     public DexType getTargetFor(DexType type) {
diff --git a/src/test/java/com/android/tools/r8/TestBase.java b/src/test/java/com/android/tools/r8/TestBase.java
index 6f93df4..94cc54b 100644
--- a/src/test/java/com/android/tools/r8/TestBase.java
+++ b/src/test/java/com/android/tools/r8/TestBase.java
@@ -12,10 +12,8 @@
 import com.android.tools.r8.ToolHelper.ArtCommandBuilder;
 import com.android.tools.r8.ToolHelper.DexVm;
 import com.android.tools.r8.ToolHelper.ProcessResult;
-import com.android.tools.r8.cf.code.CfInstruction;
 import com.android.tools.r8.code.Instruction;
 import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.SmaliWriter;
@@ -443,7 +441,7 @@
       String proguardConfig,
       Consumer<InternalOptions> optionsConsumer,
       Backend backend)
-      throws IOException, CompilationFailedException {
+      throws CompilationFailedException {
     R8Command command =
         ToolHelper.prepareR8CommandBuilder(app, emptyConsumer(backend))
             .addProguardConfiguration(ImmutableList.of(proguardConfig), Origin.unknown())
@@ -455,7 +453,7 @@
   /** Compile an application with R8 using the supplied proguard configuration. */
   protected AndroidApp compileWithR8(
       AndroidApp app, Path proguardConfig, Consumer<InternalOptions> optionsConsumer)
-      throws IOException, CompilationFailedException {
+      throws CompilationFailedException {
     R8Command command =
         ToolHelper.prepareR8CommandBuilder(app)
             .addProguardConfigurationFiles(proguardConfig)
diff --git a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
index 9cada6f..9d2e352 100644
--- a/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
+++ b/src/test/java/com/android/tools/r8/shaking/ifrule/verticalclassmerging/IfRuleWithVerticalClassMerging.java
@@ -8,17 +8,14 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThat;
 
-import com.android.tools.r8.OutputMode;
-import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.ToolHelper.ProcessResult;
-import com.android.tools.r8.shaking.forceproguardcompatibility.ProguardCompatibilityTestBase;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ir.optimize.Inliner.Reason;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.google.common.collect.ImmutableList;
-import java.io.File;
-import java.nio.file.Path;
+import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
 import java.util.List;
 import org.junit.Test;
@@ -31,7 +28,7 @@
   int a() throws ClassNotFoundException {
     // Class D is expected to be kept - vertical class merging or not. The -if rule say that if
     // the method A.a is in the output, then class D is needed.
-    String p =getClass().getPackage().getName();
+    String p = getClass().getPackage().getName();
     Class.forName(p + ".D");
     return 4;
   }
@@ -61,72 +58,67 @@
   }
 }
 
+// TODO(b/110141157):
+// - Add tests where the return type of a kept method changes.
+// - Add tests where the parameter type of a kept method changes.
+// - Add tests where the type of a kept field changes.
+// - Add tests where fields and methods get renamed due to naming conflicts.
+// - Add tests where the type in a implements/extends clause has changed.
 @RunWith(Parameterized.class)
-public class IfRuleWithVerticalClassMerging extends ProguardCompatibilityTestBase {
-  private final static List<Class> CLASSES = ImmutableList.of(
-      A.class, B.class, C.class, D.class, Main.class);
+public class IfRuleWithVerticalClassMerging extends TestBase {
 
-  private final Shrinker shrinker;
-  private final boolean enableClassMerging;
+  private static final List<Class> CLASSES =
+      ImmutableList.of(A.class, B.class, C.class, D.class, Main.class);
 
-  public IfRuleWithVerticalClassMerging(Shrinker shrinker, boolean enableClassMerging) {
-    this.shrinker = shrinker;
-    this.enableClassMerging = enableClassMerging;
+  private final Backend backend;
+  private final boolean enableVerticalClassMerging;
+
+  public IfRuleWithVerticalClassMerging(Backend backend, boolean enableVerticalClassMerging) {
+    this.backend = backend;
+    this.enableVerticalClassMerging = enableVerticalClassMerging;
   }
 
-  @Parameters(name = "shrinker: {0} classMerging: {1}")
+  @Parameters(name = "Backend: {0}, vertical class merging: {1}")
   public static Collection<Object[]> data() {
     // We don't run this on Proguard, as Proguard does not merge A into B.
     return ImmutableList.of(
-        new Object[] {Shrinker.R8, true},
-        new Object[] {Shrinker.R8, false},
-        new Object[] {Shrinker.R8_CF, true},
-        new Object[] {Shrinker.R8_CF, false});
+        new Object[] {Backend.DEX, true},
+        new Object[] {Backend.DEX, false},
+        new Object[] {Backend.CF, true},
+        new Object[] {Backend.CF, false});
   }
 
   private void configure(InternalOptions options) {
-    options.enableVerticalClassMerging = enableClassMerging;
+    options.enableVerticalClassMerging = enableVerticalClassMerging;
+
+    // TODO(b/110148109): Allow ordinary method inlining when -if rules work with inlining.
+    options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
   }
 
   private void check(AndroidApp app) throws Exception {
     CodeInspector inspector = new CodeInspector(app);
     ClassSubject clazzA = inspector.clazz(A.class);
-    assertEquals(!enableClassMerging, clazzA.isPresent());
+    assertEquals(!enableVerticalClassMerging, clazzA.isPresent());
     ClassSubject clazzB = inspector.clazz(B.class);
     assertThat(clazzB, isPresent());
     ClassSubject clazzD = inspector.clazz(D.class);
-    // TODO(110141157): Class D should be kept - vertical class merging or not.
-    assertEquals(!enableClassMerging, clazzD.isPresent());
-
-    ProcessResult result;
-    if (shrinker == Shrinker.R8) {
-      result = runOnArtRaw(app, Main.class.getName());
-    } else {
-      assert shrinker == Shrinker.R8_CF;
-      Path file = File.createTempFile("junit", ".zip", temp.getRoot()).toPath();
-      app.writeToZip(file, OutputMode.ClassFile);
-      result = ToolHelper.runJava(file, Main.class.getName());
-    }
-    // TODO(110141157): The code should run - vertical class merging or not.
-    assertEquals(enableClassMerging ? 1 : 0, result.exitCode);
-    if (!enableClassMerging) {
-      assertEquals("123456", result.stdout);
-    }
+    assertThat(clazzD, isPresent());
+    assertEquals("123456", runOnVM(app, Main.class, backend));
   }
 
   @Test
   public void testMergedClassInIfRule() throws Exception {
     // Class C is kept, meaning that it will not be touched.
     // Class A will be merged into class B.
-    List<String> config = ImmutableList.of(
-        "-keep class **.Main { public static void main(java.lang.String[]); }",
-        "-keep class **.C",
-        "-if class **.A",
-        "-keep class **.D",
-        "-dontobfuscate"
-    );
-
-    check(runShrinker(shrinker, CLASSES, config, this::configure));
+    String config =
+        String.join(
+            System.lineSeparator(),
+            "-keep class **.Main { public static void main(java.lang.String[]); }",
+            "-keep class **.C",
+            "-if class **.A",
+            "-keep class **.D",
+            "-dontobfuscate");
+    check(compileWithR8(readClasses(CLASSES), config, this::configure, backend));
   }
 
   @Test
@@ -134,15 +126,15 @@
     // Class C is kept, meaning that it will not be touched.
     // Class A will be merged into class B.
     // Main.main access A.x, so that field exists satisfying the if rule.
-    List<String> config = ImmutableList.of(
-        "-keep class **.Main { public static void main(java.lang.String[]); }",
-        "-keep class **.C",
-        "-if class **.A { int x; }",
-        "-keep class **.D",
-        "-dontobfuscate"
-    );
-
-    check(runShrinker(shrinker, CLASSES, config, this::configure));
+    String config =
+        String.join(
+            System.lineSeparator(),
+            "-keep class **.Main { public static void main(java.lang.String[]); }",
+            "-keep class **.C",
+            "-if class **.A { int x; }",
+            "-keep class **.D",
+            "-dontobfuscate");
+    check(compileWithR8(readClasses(CLASSES), config, this::configure, backend));
   }
 
   @Test
@@ -150,14 +142,14 @@
     // Class C is kept, meaning that it will not be touched.
     // Class A will be merged into class B.
     // Main.main access A.a(), that method exists satisfying the if rule.
-    List<String> config = ImmutableList.of(
-        "-keep class **.Main { public static void main(java.lang.String[]); }",
-        "-keep class **.C",
-        "-if class **.A { int a(); }",
-        "-keep class **.D",
-        "-dontobfuscate"
-    );
-
-    check(runShrinker(shrinker, CLASSES, config, this::configure));
+    String config =
+        String.join(
+            System.lineSeparator(),
+            "-keep class **.Main { public static void main(java.lang.String[]); }",
+            "-keep class **.C",
+            "-if class **.A { int a(); }",
+            "-keep class **.D",
+            "-dontobfuscate");
+    check(compileWithR8(readClasses(CLASSES), config, this::configure, backend));
   }
 }
