diff options
author | 2016-09-26 12:39:16 +0000 | |
---|---|---|
committer | 2016-09-26 12:39:16 +0000 | |
commit | 3cc69a894444ccd2450b100ae41fd2a932a38749 (patch) | |
tree | d8bdddc6eed689d3eff138d3720211a0b541e18a | |
parent | a1d66b9050aeecd7e698c51155f0dbc0198a6822 (diff) | |
parent | 50a9ed014e3b4dec67246ea07727d7bec89bfb17 (diff) |
Merge "Compensate in compiler for verifier shortcomings."
-rw-r--r-- | compiler/optimizing/instruction_builder.cc | 15 | ||||
-rw-r--r-- | compiler/optimizing/ssa_builder.cc | 14 | ||||
-rw-r--r-- | test/800-smali/expected.txt | 1 | ||||
-rw-r--r-- | test/800-smali/smali/b_31313170.smali | 22 | ||||
-rw-r--r-- | test/800-smali/src/Main.java | 3 |
5 files changed, 43 insertions, 12 deletions
diff --git a/compiler/optimizing/instruction_builder.cc b/compiler/optimizing/instruction_builder.cc index 5a6a212cc9..f7dc2377be 100644 --- a/compiler/optimizing/instruction_builder.cc +++ b/compiler/optimizing/instruction_builder.cc @@ -1815,7 +1815,20 @@ bool HInstructionBuilder::ProcessDexInstruction(const Instruction& instruction, case Instruction::MOVE_OBJECT: case Instruction::MOVE_OBJECT_16: case Instruction::MOVE_OBJECT_FROM16: { - HInstruction* value = LoadLocal(instruction.VRegB(), Primitive::kPrimNot); + // The verifier has no notion of a null type, so a move-object of constant 0 + // will lead to the same constant 0 in the destination register. To mimic + // this behavior, we just pretend we haven't seen a type change (int to reference) + // for the 0 constant and phis. We rely on our type propagation to eventually get the + // types correct. + uint32_t reg_number = instruction.VRegB(); + HInstruction* value = (*current_locals_)[reg_number]; + if (value->IsIntConstant()) { + DCHECK_EQ(value->AsIntConstant()->GetValue(), 0); + } else if (value->IsPhi()) { + DCHECK(value->GetType() == Primitive::kPrimInt || value->GetType() == Primitive::kPrimNot); + } else { + value = LoadLocal(reg_number, Primitive::kPrimNot); + } UpdateLocal(instruction.VRegA(), value); break; } diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc index f7dc112d00..03807ba1ee 100644 --- a/compiler/optimizing/ssa_builder.cc +++ b/compiler/optimizing/ssa_builder.cc @@ -163,18 +163,12 @@ static bool TypePhiFromInputs(HPhi* phi) { // Replace inputs of `phi` to match its type. Return false if conflict is identified. bool SsaBuilder::TypeInputsOfPhi(HPhi* phi, ArenaVector<HPhi*>* worklist) { Primitive::Type common_type = phi->GetType(); - if (common_type == Primitive::kPrimVoid || Primitive::IsIntegralType(common_type)) { - // Phi either contains only other untyped phis (common_type == kPrimVoid), - // or `common_type` is integral and we do not need to retype ambiguous inputs - // because they are always constructed with the integral type candidate. + if (Primitive::IsIntegralType(common_type)) { + // We do not need to retype ambiguous inputs because they are always constructed + // with the integral type candidate. if (kIsDebugBuild) { for (HInstruction* input : phi->GetInputs()) { - if (common_type == Primitive::kPrimVoid) { - DCHECK(input->IsPhi() && input->GetType() == Primitive::kPrimVoid); - } else { - DCHECK((input->IsPhi() && input->GetType() == Primitive::kPrimVoid) || - HPhi::ToPhiType(input->GetType()) == common_type); - } + DCHECK(HPhi::ToPhiType(input->GetType()) == common_type); } } // Inputs did not need to be replaced, hence no conflict. Report success. diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt index 3bb372529f..b8324e54e3 100644 --- a/test/800-smali/expected.txt +++ b/test/800-smali/expected.txt @@ -70,4 +70,5 @@ b/28187158 b/29778499 (1) b/29778499 (2) b/30458218 +b/31313170 Done! diff --git a/test/800-smali/smali/b_31313170.smali b/test/800-smali/smali/b_31313170.smali new file mode 100644 index 0000000000..327942a365 --- /dev/null +++ b/test/800-smali/smali/b_31313170.smali @@ -0,0 +1,22 @@ +.class public LB31313170; +.super Ljava/lang/Object; + + +.method public constructor <init>()V +.registers 1 + invoke-direct {p0}, Ljava/lang/Object;-><init>()V + return-void +.end method + +.method public static run()I +.registers 4 + const/4 v0, 0 + const/4 v1, 1 + sget v2, LB31313170;->a:I + if-nez v2, :exit + move-object v1, v0 + :exit + return v1 +.end method + +.field static public a:I diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java index 34f2580dde..8d39f0971f 100644 --- a/test/800-smali/src/Main.java +++ b/test/800-smali/src/Main.java @@ -181,6 +181,7 @@ public class Main { testCases.add(new TestCase("b/29778499 (2)", "B29778499_2", "run", null, new IncompatibleClassChangeError(), null)); testCases.add(new TestCase("b/30458218", "B30458218", "run", null, null, null)); + testCases.add(new TestCase("b/31313170", "B31313170", "run", null, null, 0)); } public void runTests() { @@ -228,7 +229,7 @@ public class Main { tc.testName); } else if (tc.expectedReturn == null && retValue != null) { errorReturn = new IllegalStateException("Expected a null result in test " + - tc.testName); + tc.testName + " got " + retValue); } else if (tc.expectedReturn != null && (retValue == null || !tc.expectedReturn.equals(retValue))) { errorReturn = new IllegalStateException("Expected return " + |