Version 1.5.49

Cherry pick: Add regression test for b/134304597
CL: https://r8-review.googlesource.com/c/r8/+/39304

Cherry pick: Don't inline methods that returns an integer as a boolean on dalvik.
CL: https://r8-review.googlesource.com/c/r8/+/39642

Bug: 134304597
Change-Id: I6bacef2006c86c3f2467981e0ed247776bc35a2d
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index b714708..20ca7f5 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.5.48";
+  public static final String LABEL = "1.5.49";
 
   private Version() {
   }
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java
index 90c112c..f72aef7 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/ArrayTypeLatticeElement.java
@@ -57,7 +57,7 @@
     return nesting;
   }
 
-  TypeLatticeElement getArrayMemberTypeAsMemberType() {
+  public TypeLatticeElement getArrayMemberTypeAsMemberType() {
     return memberTypeLattice;
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java
index e12d780..ab3268b 100644
--- a/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java
+++ b/src/main/java/com/android/tools/r8/ir/analysis/type/TypeLatticeElement.java
@@ -17,7 +17,7 @@
 public abstract class TypeLatticeElement {
   public static final BottomTypeLatticeElement BOTTOM = BottomTypeLatticeElement.getInstance();
   public static final TopTypeLatticeElement TOP = TopTypeLatticeElement.getInstance();
-  static final BooleanTypeLatticeElement BOOLEAN = BooleanTypeLatticeElement.getInstance();
+  public static final BooleanTypeLatticeElement BOOLEAN = BooleanTypeLatticeElement.getInstance();
   static final ByteTypeLatticeElement BYTE = ByteTypeLatticeElement.getInstance();
   static final ShortTypeLatticeElement SHORT = ShortTypeLatticeElement.getInstance();
   static final CharTypeLatticeElement CHAR = CharTypeLatticeElement.getInstance();
diff --git a/src/main/java/com/android/tools/r8/ir/code/And.java b/src/main/java/com/android/tools/r8/ir/code/And.java
index cc782ff..357edf8 100644
--- a/src/main/java/com/android/tools/r8/ir/code/And.java
+++ b/src/main/java/com/android/tools/r8/ir/code/And.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.code.AndIntLit8;
 import com.android.tools.r8.code.AndLong;
 import com.android.tools.r8.code.AndLong2Addr;
+import java.util.Set;
 
 public class And extends LogicalBinop {
 
@@ -87,4 +88,9 @@
   CfLogicalBinop.Opcode getCfOpcode() {
     return CfLogicalBinop.Opcode.And;
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return leftValue().knownToBeBoolean(seen) && rightValue().knownToBeBoolean(seen);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Argument.java b/src/main/java/com/android/tools/r8/ir/code/Argument.java
index b8f4e9f..54004cb 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Argument.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Argument.java
@@ -14,14 +14,18 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import java.util.Set;
 
 /**
  * Argument pseudo instruction used to introduce values for all arguments for SSA conversion.
  */
 public class Argument extends Instruction {
 
-  public Argument(Value outValue) {
+  private final boolean knownToBeBoolean;
+
+  public Argument(Value outValue, boolean knownToBeBoolean) {
     super(outValue);
+    this.knownToBeBoolean = knownToBeBoolean;
     outValue.markAsArgument();
   }
 
@@ -99,4 +103,9 @@
   public boolean hasInvariantOutType() {
     return true;
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return knownToBeBoolean;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
index e082dcd..5690a16 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ArrayGet.java
@@ -28,6 +28,7 @@
 import com.android.tools.r8.ir.optimize.InliningConstraints;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
 import java.util.Arrays;
+import java.util.Set;
 
 public class ArrayGet extends Instruction implements ImpreciseMemberTypeInstruction {
 
@@ -248,6 +249,13 @@
   }
 
   @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return array().getTypeLattice().isArrayType()
+        && array().getTypeLattice().asArrayTypeLatticeElement().getArrayMemberTypeAsMemberType()
+        == TypeLatticeElement.BOOLEAN;
+  }
+
+  @Override
   public void constrainType(TypeConstraintResolver constraintResolver) {
     constraintResolver.constrainArrayMemberType(type, dest(), array(), t -> type = t);
   }
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 dc8a32b..bac4a5a 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
@@ -15,6 +15,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import java.util.Set;
 
 public class Assume<An extends Assumption> extends Instruction {
 
@@ -67,6 +68,11 @@
   }
 
   @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return src().knownToBeBoolean(seen);
+  }
+
+  @Override
   public String getInstructionName() {
     if (isAssumeDynamicType()) {
       return "AssumeDynamicType";
diff --git a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
index b9bc91b..e831599 100644
--- a/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
+++ b/src/main/java/com/android/tools/r8/ir/code/ConstNumber.java
@@ -26,6 +26,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.utils.InternalOutputMode;
 import com.android.tools.r8.utils.NumberUtils;
+import java.util.Set;
 import java.util.function.Function;
 
 public class ConstNumber extends ConstInstruction {
@@ -314,4 +315,8 @@
     return true;
   }
 
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return this.value == 0 || this.value == 1;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
index 3fc9562..6a59713 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceGet.java
@@ -29,6 +29,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import java.util.Set;
 import org.objectweb.asm.Opcodes;
 
 public class InstanceGet extends FieldInstruction {
@@ -38,6 +39,11 @@
   }
 
   @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return getField().type.isBooleanType();
+  }
+
+  @Override
   public <T> T accept(InstructionVisitor<T> visitor) {
     return visitor.visit(this);
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
index 600c299..c74ab1b 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstanceOf.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import java.util.Set;
 
 public class InstanceOf extends Instruction {
 
@@ -104,4 +105,9 @@
   public void buildCf(CfBuilder builder) {
     builder.add(new CfInstanceOf(type));
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return true;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Instruction.java b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
index 3a8bb2c..6d2464f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Instruction.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Instruction.java
@@ -1314,4 +1314,8 @@
     assert !instructionTypeCanThrow() || getPosition().isSome() || getPosition().isSyntheticNone();
     return true;
   }
+
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return false;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Invoke.java b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
index 83e2bc3..dc02268 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Invoke.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Invoke.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import java.util.List;
+import java.util.Set;
 
 public abstract class Invoke extends Instruction {
 
@@ -269,4 +270,9 @@
     }
     return TypeLatticeElement.fromDexType(returnType, Nullability.maybeNull(), appView);
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return getReturnType().isBooleanType();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java b/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
index bf94a76..77394b1 100644
--- a/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
+++ b/src/main/java/com/android/tools/r8/ir/code/NumberConversion.java
@@ -25,6 +25,7 @@
 import com.android.tools.r8.ir.analysis.type.TypeLatticeElement;
 import com.android.tools.r8.ir.conversion.CfBuilder;
 import com.android.tools.r8.ir.conversion.DexBuilder;
+import java.util.Set;
 
 public class NumberConversion extends Unop {
 
@@ -155,4 +156,9 @@
   public void buildCf(CfBuilder builder) {
     builder.add(new CfNumberConversion(from, to));
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return to == NumericType.BYTE && source().knownToBeBoolean(seen);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/Or.java b/src/main/java/com/android/tools/r8/ir/code/Or.java
index 67b730f..78330a4 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Or.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Or.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.code.OrIntLit8;
 import com.android.tools.r8.code.OrLong;
 import com.android.tools.r8.code.OrLong2Addr;
+import java.util.Set;
 
 public class Or extends LogicalBinop {
 
@@ -86,4 +87,9 @@
   CfLogicalBinop.Opcode getCfOpcode() {
     return CfLogicalBinop.Opcode.Or;
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return leftValue().knownToBeBoolean(seen) && rightValue().knownToBeBoolean(seen);
+  }
 }
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 c0dac12..7dff8be 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
@@ -325,41 +325,6 @@
     definitionUsers = null;
   }
 
-  /**
-   * Determine if the only possible values for the phi are the integers 0 or 1.
-   */
-  @Override
-  public boolean knownToBeBoolean() {
-    return knownToBeBoolean(new HashSet<>());
-  }
-
-  private boolean knownToBeBoolean(HashSet<Phi> active) {
-    active.add(this);
-
-    for (Value operand : operands) {
-      if (!operand.isPhi()) {
-        if (operand.isConstNumber()) {
-          ConstNumber number = operand.getConstInstruction().asConstNumber();
-          if (!number.isIntegerOne() && !number.isIntegerZero()) {
-            return false;
-          }
-        } else {
-          return false;
-        }
-      }
-    }
-
-    for (Value operand : operands) {
-      if (operand.isPhi() && !active.contains(operand.asPhi())) {
-        if (!operand.asPhi().knownToBeBoolean(active)) {
-          return false;
-        }
-      }
-    }
-
-    return true;
-  }
-
   @Override
   public boolean isConstant() {
     return false;
diff --git a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
index c109441..83e593e 100644
--- a/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
+++ b/src/main/java/com/android/tools/r8/ir/code/StaticGet.java
@@ -27,6 +27,7 @@
 import com.android.tools.r8.ir.conversion.DexBuilder;
 import com.android.tools.r8.ir.optimize.Inliner.ConstraintWithTarget;
 import com.android.tools.r8.ir.optimize.InliningConstraints;
+import java.util.Set;
 import org.objectweb.asm.Opcodes;
 
 public class StaticGet extends FieldInstruction {
@@ -182,4 +183,9 @@
     return ClassInitializationAnalysis.InstructionUtils.forStaticGet(
         this, clazz, appView, mode, assumption);
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return getField().type.isBooleanType();
+  }
 }
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 ced7264..2243641 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
@@ -209,7 +209,6 @@
   private int needsRegister = -1;
   private boolean isThis = false;
   private boolean isArgument = false;
-  private boolean knownToBeBoolean = false;
   private LongInterval valueRange;
   private DebugData debugData;
   protected TypeLatticeElement typeLattice;
@@ -815,22 +814,35 @@
     return isArgument;
   }
 
-  public void setKnownToBeBoolean(boolean knownToBeBoolean) {
-    this.knownToBeBoolean = knownToBeBoolean;
-  }
 
   public boolean knownToBeBoolean() {
-    if (knownToBeBoolean) {
+    return knownToBeBoolean(null);
+  }
+
+  public boolean knownToBeBoolean(Set<Phi> seen) {
+    if (!getTypeLattice().isInt()) {
+      return false;
+    }
+
+    if (isPhi()) {
+      Phi self = this.asPhi();
+      if (seen == null) {
+        seen = new HashSet<>();
+      }
+      if (seen.contains(self)) {
+        return true;
+      }
+      seen.add(self);
+      for (Value operand : self.getOperands()) {
+        if (!operand.knownToBeBoolean(seen)) {
+          operand.knownToBeBoolean(seen);
+          return false;
+        }
+      }
       return true;
     }
-    if (getTypeLattice().isInt()) {
-      Value aliasedValue = getAliasedValue();
-      if (!aliasedValue.isPhi() && aliasedValue.definition.isConstNumber()) {
-        ConstNumber definition = aliasedValue.definition.asConstNumber();
-        return definition.isZero() || definition.getRawValue() == 1;
-      }
-    }
-    return false;
+    assert definition != null;
+    return definition.outTypeKnownToBeBoolean(seen);
   }
 
   public void markAsThis() {
diff --git a/src/main/java/com/android/tools/r8/ir/code/Xor.java b/src/main/java/com/android/tools/r8/ir/code/Xor.java
index ec2d8db..3cf845a 100644
--- a/src/main/java/com/android/tools/r8/ir/code/Xor.java
+++ b/src/main/java/com/android/tools/r8/ir/code/Xor.java
@@ -10,6 +10,7 @@
 import com.android.tools.r8.code.XorIntLit8;
 import com.android.tools.r8.code.XorLong;
 import com.android.tools.r8.code.XorLong2Addr;
+import java.util.Set;
 
 public class Xor extends LogicalBinop {
 
@@ -86,4 +87,9 @@
   CfLogicalBinop.Opcode getCfOpcode() {
     return CfLogicalBinop.Opcode.Xor;
   }
+
+  @Override
+  public boolean outTypeKnownToBeBoolean(Set<Phi> seen) {
+    return leftValue().knownToBeBoolean(seen) && rightValue().knownToBeBoolean(seen);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
index 53750d6..8adb821 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/DexSourceCode.java
@@ -174,12 +174,17 @@
         nextRemovedArgument =
             removedArgumentIterator.hasNext() ? removedArgumentIterator.next() : null;
       } else {
+        DexType dexType = method.method.proto.parameters.values[usedArgumentIndex++];
         type =
             TypeLatticeElement.fromDexType(
-                method.method.proto.parameters.values[usedArgumentIndex++],
+                dexType,
                 Nullability.maybeNull(),
                 builder.appView);
-        builder.addNonThisArgument(register, type);
+        if (dexType.isBooleanType()) {
+          builder.addBooleanNonThisArgument(register);
+        } else {
+          builder.addNonThisArgument(register, type);
+        }
       }
       register += type.requiredRegisters();
     }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
index bd7d27e..cbddf03 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRBuilder.java
@@ -855,7 +855,7 @@
     TypeLatticeElement receiver =
         TypeLatticeElement.fromDexType(method.method.holder, nullability, appView);
     Value value = writeRegister(register, receiver, ThrowingInfo.NO_THROW, local);
-    addInstruction(new Argument(value));
+    addInstruction(new Argument(value, false));
     value.markAsThis();
   }
 
@@ -864,7 +864,7 @@
     if (removedArgumentInfo == null) {
       DebugLocalInfo local = getOutgoingLocal(register);
       Value value = writeRegister(register, typeLattice, ThrowingInfo.NO_THROW, local);
-      addInstruction(new Argument(value));
+      addInstruction(new Argument(value, false));
     } else {
       handleConstantOrUnusedArgument(register, removedArgumentInfo);
     }
@@ -875,8 +875,8 @@
     if (removedArgumentInfo == null) {
       DebugLocalInfo local = getOutgoingLocal(register);
       Value value = writeRegister(register, INT, ThrowingInfo.NO_THROW, local);
-      value.setKnownToBeBoolean(true);
-      addInstruction(new Argument(value));
+
+      addInstruction(new Argument(value, true));
     } else {
       assert removedArgumentInfo.isNeverUsed();
     }
@@ -1005,7 +1005,6 @@
     Value in2 = readRegister(index, ValueTypeConstraint.INT);
     TypeLatticeElement typeLattice = fromMemberType(type);
     Value out = writeRegister(dest, typeLattice, ThrowingInfo.CAN_THROW);
-    out.setKnownToBeBoolean(type == MemberType.BOOLEAN);
     ArrayGet instruction = new ArrayGet(type, out, in1, in2);
     assert instruction.instructionTypeCanThrow();
     if (!type.isPrecise()) {
@@ -1325,7 +1324,6 @@
             dest,
             TypeLatticeElement.fromDexType(field.type, maybeNull(), appView),
             ThrowingInfo.CAN_THROW);
-    out.setKnownToBeBoolean(field.type == appView.dexItemFactory().booleanType);
     InstanceGet instruction = new InstanceGet(out, in, field);
     assert instruction.instructionTypeCanThrow();
     addInstruction(instruction);
@@ -1606,7 +1604,6 @@
             dest,
             TypeLatticeElement.fromDexType(outType, maybeNull(), appView),
             ThrowingInfo.CAN_THROW);
-    outValue.setKnownToBeBoolean(outType.isBooleanType());
     invoke.setOutValue(outValue);
   }
 
@@ -1689,7 +1686,6 @@
             dest,
             TypeLatticeElement.fromDexType(field.type, maybeNull(), appView),
             ThrowingInfo.CAN_THROW);
-    out.setKnownToBeBoolean(field.type == appView.dexItemFactory().booleanType);
     StaticGet instruction = new StaticGet(out, field);
     assert instruction.instructionTypeCanThrow();
     addInstruction(instruction);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
index 9d3954f..07e72b4 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Inliner.java
@@ -102,6 +102,11 @@
       return ConstraintWithTarget.NEVER;
     }
 
+    if (appView.options().canHaveDalvikIntUsedAsBooleanBug()
+        && returnsIntAsBoolean(code, method, appView)) {
+      return ConstraintWithTarget.NEVER;
+    }
+
     ConstraintWithTarget result = ConstraintWithTarget.ALWAYS;
     InliningConstraints inliningConstraints =
         new InliningConstraints(appView, GraphLense.getIdentityLense());
@@ -120,6 +125,22 @@
     return result;
   }
 
+  private boolean returnsIntAsBoolean(IRCode code, DexEncodedMethod method, AppView appView) {
+    DexType returnType = method.method.proto.returnType;
+    for (BasicBlock basicBlock : code.blocks) {
+      InstructionListIterator instructionListIterator = basicBlock.listIterator();
+      while (instructionListIterator.hasNext()) {
+        Instruction instruction = instructionListIterator.nextUntil(Instruction::isReturn);
+        if (instruction != null) {
+          if (returnType.isBooleanType() && !instruction.inValues().get(0).knownToBeBoolean()) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
   boolean hasInliningAccess(DexEncodedMethod method, DexEncodedMethod target) {
     if (!isVisibleWithFlags(target.method.holder, method.method.holder, target.accessFlags)) {
       return false;
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 33c8c96..2fe484e 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
@@ -1458,9 +1458,13 @@
     public void buildPrelude(IRBuilder builder) {
       // Fill in the Argument instructions in the argument block.
       for (int i = 0; i < outline.argumentTypes.size(); i++) {
-        TypeLatticeElement typeLattice =
-            TypeLatticeElement.fromDexType(outline.argumentTypes.get(i), maybeNull(), appView);
-        builder.addNonThisArgument(i, typeLattice);
+        if (outline.argumentTypes.get(i).isBooleanType()) {
+          builder.addBooleanNonThisArgument(i);
+        } else {
+          TypeLatticeElement typeLattice =
+              TypeLatticeElement.fromDexType(outline.argumentTypes.get(i), maybeNull(), appView);
+          builder.addNonThisArgument(i, typeLattice);
+        }
       }
       builder.flushArgumentInstructions();
     }
diff --git a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
index a75b3bc..a833241 100644
--- a/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
+++ b/src/main/java/com/android/tools/r8/ir/synthetic/SyntheticSourceCode.java
@@ -191,7 +191,7 @@
               TypeLatticeElement.fromDexType(
                   receiver, Nullability.definitelyNotNull(), builder.appView),
               NO_THROW);
-      builder.add(new Argument(receiverValue));
+      builder.add(new Argument(receiverValue, false));
       receiverValue.markAsThis();
     }
 
@@ -203,7 +203,7 @@
           TypeLatticeElement.fromDexType(parameters[i], Nullability.maybeNull(), builder.appView);
       Value paramValue = builder.writeRegister(paramRegisters[i], typeLattice, NO_THROW);
       paramValues[i] = paramValue;
-      builder.add(new Argument(paramValue));
+      builder.add(new Argument(paramValue, parameters[i].isBooleanType()));
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 951feef..2d3100c 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1104,7 +1104,7 @@
   //
   // See b/131349148
   public boolean canHaveDalvikCatchHandlerVerificationBug() {
-    return minApiLevel < AndroidApiLevel.L.getLevel();
+    return isGeneratingClassFiles() || minApiLevel < AndroidApiLevel.L.getLevel();
   }
 
   // Having an invoke instruction that targets an abstract method on a non-abstract class will fail
@@ -1114,4 +1114,14 @@
   public boolean canHaveDalvikAbstractMethodOnNonAbstractClassVerificationBug() {
     return minApiLevel < AndroidApiLevel.L.getLevel();
   }
+
+  // On dalvik we see issues if we inline the following method into the call site:
+  // public int value;
+  // public boolean getValue() {
+  //   return value;
+  // }
+  // See b/134304597
+  public boolean canHaveDalvikIntUsedAsBooleanBug() {
+    return isGeneratingClassFiles() || minApiLevel < AndroidApiLevel.L.getLevel();
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
index 059501b..48a8246 100644
--- a/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
+++ b/src/test/java/com/android/tools/r8/ir/optimize/TrivialGotoEliminationTest.java
@@ -136,7 +136,7 @@
             TypeLatticeElement.fromDexType(
                 app.dexItemFactory.throwableType, Nullability.definitelyNotNull(), appView),
             null);
-    instruction = new Argument(value);
+    instruction = new Argument(value, false);
     instruction.setPosition(position);
     block0.add(instruction);
     instruction = new If(Type.EQ, value);
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/Main.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/Main.java
new file mode 100644
index 0000000..384d500
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/Main.java
@@ -0,0 +1,15 @@
+// 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.inliner.Regress134304597;
+
+public class Main {
+  public static void main(String[] args) {
+    Test a = new Test();
+    if (args.length > 10) {
+      a.printValue();
+    }
+
+    System.out.println(a.getValue());
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test.java
new file mode 100644
index 0000000..979cb6d
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test.java
@@ -0,0 +1,22 @@
+// 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.inliner.Regress134304597;
+
+class Test {
+  public int i = 33;
+  private int j = 42;
+
+  Test() {
+    i = System.currentTimeMillis() == 42 ? 0 : 1;
+    j = i + 3;
+  }
+
+  public boolean getValue() {
+    return i > 0;
+  }
+
+  public void printValue() {
+    System.out.println(j);
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/TestDump.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/TestDump.java
new file mode 100644
index 0000000..1683e4b
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/TestDump.java
@@ -0,0 +1,152 @@
+// 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.inliner.Regress134304597;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+
+public class TestDump implements Opcodes {
+
+
+  // Generated from Test.java with tools/asmifier.py. Change commented out below
+  public static byte[] dump() throws Exception {
+
+    ClassWriter classWriter = new ClassWriter(0);
+    FieldVisitor fieldVisitor;
+    MethodVisitor methodVisitor;
+    AnnotationVisitor annotationVisitor0;
+
+    classWriter
+        .visit(V1_8, ACC_SUPER, "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test",
+            null, "java/lang/Object", null);
+
+    classWriter.visitSource("Test.java", null);
+
+    {
+      fieldVisitor = classWriter.visitField(ACC_PUBLIC, "i", "I", null, null);
+      fieldVisitor.visitEnd();
+    }
+    {
+      fieldVisitor = classWriter.visitField(ACC_PRIVATE, "j", "I", null, null);
+      fieldVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(0, "<init>", "()V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(7, label0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitLineNumber(4, label1);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitIntInsn(BIPUSH, 33);
+      methodVisitor.visitFieldInsn(PUTFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "i", "I");
+      Label label2 = new Label();
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitLineNumber(5, label2);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitIntInsn(BIPUSH, 42);
+      methodVisitor.visitFieldInsn(PUTFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "j", "I");
+      Label label3 = new Label();
+      methodVisitor.visitLabel(label3);
+      methodVisitor.visitLineNumber(8, label3);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor
+          .visitMethodInsn(INVOKESTATIC, "java/lang/System", "currentTimeMillis", "()J", false);
+      methodVisitor.visitLdcInsn(new Long(42L));
+      methodVisitor.visitInsn(LCMP);
+      Label label4 = new Label();
+      methodVisitor.visitJumpInsn(IFNE, label4);
+      methodVisitor.visitInsn(ICONST_0);
+      Label label5 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label5);
+      methodVisitor.visitLabel(label4);
+      methodVisitor.visitFrame(Opcodes.F_FULL, 1,
+          new Object[]{"com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test"}, 1,
+          new Object[]{"com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test"});
+      methodVisitor.visitIntInsn(BIPUSH, 1);
+      methodVisitor.visitLabel(label5);
+      methodVisitor.visitFrame(Opcodes.F_FULL, 1,
+          new Object[]{"com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test"}, 2,
+          new Object[]{"com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test",
+              Opcodes.INTEGER});
+      methodVisitor.visitFieldInsn(PUTFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "i", "I");
+      Label label6 = new Label();
+      methodVisitor.visitLabel(label6);
+      methodVisitor.visitLineNumber(9, label6);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitFieldInsn(GETFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "i", "I");
+      methodVisitor.visitInsn(ICONST_3);
+      methodVisitor.visitInsn(IADD);
+      methodVisitor.visitFieldInsn(PUTFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "j", "I");
+      Label label7 = new Label();
+      methodVisitor.visitLabel(label7);
+      methodVisitor.visitLineNumber(10, label7);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(5, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "getValue", "()Z", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(13, label0);
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitFieldInsn(GETFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "i", "I");
+      // Removed code to change:
+      // if (i > 0) return true;
+      // into
+      // return i;
+      /*  Label label1 = new Label();
+      methodVisitor.visitJumpInsn(IFLE, label1);
+      methodVisitor.visitInsn(ICONST_1);
+      Label label2 = new Label();
+      methodVisitor.visitJumpInsn(GOTO, label2);
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
+      methodVisitor.visitInsn(ICONST_0);
+      methodVisitor.visitLabel(label2);
+      methodVisitor.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[]{Opcodes.INTEGER});*/
+      methodVisitor.visitInsn(IRETURN);
+      methodVisitor.visitMaxs(1, 1);
+      methodVisitor.visitEnd();
+    }
+    {
+      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "printValue", "()V", null, null);
+      methodVisitor.visitCode();
+      Label label0 = new Label();
+      methodVisitor.visitLabel(label0);
+      methodVisitor.visitLineNumber(17, label0);
+      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+      methodVisitor.visitVarInsn(ALOAD, 0);
+      methodVisitor.visitFieldInsn(GETFIELD,
+          "com/android/tools/r8/ir/optimize/inliner/Regress134304597/Test", "j", "I");
+      methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V", false);
+      Label label1 = new Label();
+      methodVisitor.visitLabel(label1);
+      methodVisitor.visitLineNumber(18, label1);
+      methodVisitor.visitInsn(RETURN);
+      methodVisitor.visitMaxs(2, 1);
+      methodVisitor.visitEnd();
+    }
+    classWriter.visitEnd();
+
+    return classWriter.toByteArray();
+  }
+}
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/TestRunner.java b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/TestRunner.java
new file mode 100644
index 0000000..d59a8ba
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/optimize/inliner/Regress134304597/TestRunner.java
@@ -0,0 +1,41 @@
+// 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.inliner.Regress134304597;
+
+import com.android.tools.r8.R8TestRunResult;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestCompileResult;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class TestRunner extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection params() {
+    return getTestParameters().withAllRuntimes().withAllApiLevels().build();
+  }
+
+  public TestRunner(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void TestInlineIntForBoolean() throws Exception {
+    testForR8(parameters.getBackend())
+        .addProgramClasses(Main.class)
+        .addProgramClassFileData(TestDump.dump())
+        .setMinApi(parameters.getApiLevel())
+        .addKeepMainRule(Main.class)
+        .run(parameters.getRuntime(), Main.class)
+        .assertSuccessWithOutputLines("true");
+  }
+}