diff options
| author | 2017-06-26 09:12:45 +0100 | |
|---|---|---|
| committer | 2017-06-26 13:42:42 +0100 | |
| commit | 860626e1a3e1314b7d2e828fd61fb25eebc5f081 (patch) | |
| tree | e5914601dc55818337fa95d2a23efb3458d3e396 /compiler/optimizing | |
| parent | 565cd4e9861d44c1b24b4b2054446edf3118cbba (diff) | |
Fix braino when handling branches fallthrough in arm backend.
bug: 62210114
Test: 657-branches
(cherry picked from commit 6fda42718a348cfb758d8714e223cab7e855765b)
Change-Id: I0e4f0577bcb1f3960459fe5d35473af191fc6534
Diffstat (limited to 'compiler/optimizing')
| -rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 9 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm64.cc | 7 | ||||
| -rw-r--r-- | compiler/optimizing/code_generator_arm_vixl.cc | 9 |
3 files changed, 16 insertions, 9 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index c9a6898e3b..419b2afe91 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -2522,21 +2522,28 @@ void InstructionCodeGeneratorARM::GenerateCompareTestAndBranch(HCondition* condi if (CanGenerateTest(condition, codegen_->GetAssembler())) { Label* non_fallthrough_target; bool invert; + bool emit_both_branches; if (true_target_in == nullptr) { + // The true target is fallthrough. DCHECK(false_target_in != nullptr); non_fallthrough_target = false_target_in; invert = true; + emit_both_branches = false; } else { + // Either the false target is fallthrough, or there is no fallthrough + // and both branches must be emitted. non_fallthrough_target = true_target_in; invert = false; + emit_both_branches = (false_target_in != nullptr); } const auto cond = GenerateTest(condition, invert, codegen_); __ b(non_fallthrough_target, cond.first); - if (false_target_in != nullptr && false_target_in != non_fallthrough_target) { + if (emit_both_branches) { + // No target falls through, we need to branch. __ b(false_target_in); } diff --git a/compiler/optimizing/code_generator_arm64.cc b/compiler/optimizing/code_generator_arm64.cc index fccb56786f..da146d72cd 100644 --- a/compiler/optimizing/code_generator_arm64.cc +++ b/compiler/optimizing/code_generator_arm64.cc @@ -3563,9 +3563,6 @@ void InstructionCodeGeneratorARM64::GenerateTestAndBranch(HInstruction* instruct size_t condition_input_index, vixl::aarch64::Label* true_target, vixl::aarch64::Label* false_target) { - // FP branching requires both targets to be explicit. If either of the targets - // is nullptr (fallthrough) use and bind `fallthrough_target` instead. - vixl::aarch64::Label fallthrough_target; HInstruction* cond = instruction->InputAt(condition_input_index); if (true_target == nullptr && false_target == nullptr) { @@ -3666,10 +3663,6 @@ void InstructionCodeGeneratorARM64::GenerateTestAndBranch(HInstruction* instruct if (true_target != nullptr && false_target != nullptr) { __ B(false_target); } - - if (fallthrough_target.IsLinked()) { - __ Bind(&fallthrough_target); - } } void LocationsBuilderARM64::VisitIf(HIf* if_instr) { diff --git a/compiler/optimizing/code_generator_arm_vixl.cc b/compiler/optimizing/code_generator_arm_vixl.cc index 59cd5f951d..c37cc52a2b 100644 --- a/compiler/optimizing/code_generator_arm_vixl.cc +++ b/compiler/optimizing/code_generator_arm_vixl.cc @@ -2557,21 +2557,28 @@ void InstructionCodeGeneratorARMVIXL::GenerateCompareTestAndBranch(HCondition* c if (CanGenerateTest(condition, codegen_->GetAssembler())) { vixl32::Label* non_fallthrough_target; bool invert; + bool emit_both_branches; if (true_target_in == nullptr) { + // The true target is fallthrough. DCHECK(false_target_in != nullptr); non_fallthrough_target = false_target_in; invert = true; + emit_both_branches = false; } else { non_fallthrough_target = true_target_in; invert = false; + // Either the false target is fallthrough, or there is no fallthrough + // and both branches must be emitted. + emit_both_branches = (false_target_in != nullptr); } const auto cond = GenerateTest(condition, invert, codegen_); __ B(cond.first, non_fallthrough_target); - if (false_target_in != nullptr && false_target_in != non_fallthrough_target) { + if (emit_both_branches) { + // No target falls through, we need to branch. __ B(false_target_in); } |