summaryrefslogtreecommitdiff
path: root/compiler/optimizing
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2017-06-26 09:12:45 +0100
committer Nicolas Geoffray <ngeoffray@google.com> 2017-06-26 13:42:42 +0100
commit860626e1a3e1314b7d2e828fd61fb25eebc5f081 (patch)
treee5914601dc55818337fa95d2a23efb3458d3e396 /compiler/optimizing
parent565cd4e9861d44c1b24b4b2054446edf3118cbba (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.cc9
-rw-r--r--compiler/optimizing/code_generator_arm64.cc7
-rw-r--r--compiler/optimizing/code_generator_arm_vixl.cc9
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);
}