summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorSerguei Katkov <serguei.i.katkov@intel.com>2015-08-05 17:03:30 +0600
committerCalin Juravle <calin@google.com>2015-08-06 18:58:06 +0100
commitf2ea71cdb3ee4f5198bc0298aa8be1f9e945ee1c (patch)
tree0c133429186d7d9f796efa2d883941a8130246e0 /compiler
parentce4b1329ca903d6b98734a27a46b54bb9cfd6d5b (diff)
downloadart-f2ea71cdb3ee4f5198bc0298aa8be1f9e945ee1c.zip
art-f2ea71cdb3ee4f5198bc0298aa8be1f9e945ee1c.tar.gz
art-f2ea71cdb3ee4f5198bc0298aa8be1f9e945ee1c.tar.bz2
ART: Fix the simplifier for add/sub
Instruction simplifier for add/sub should not proceed with floats because that might cause the incorrect behavior with signed zero. Bug: 23001681 Signed-off-by: Serguei Katkov <serguei.i.katkov@intel.com> (cherry picked from commit 115b53f609e74672fa93eea1845bb17340d5112a) Change-Id: I9928724c4158b3961e32e376b9203fe01ba2e442
Diffstat (limited to 'compiler')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc24
1 files changed, 16 insertions, 8 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 0ca676a..9ab9398 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -314,9 +314,14 @@ void InstructionSimplifierVisitor::VisitAdd(HAdd* instruction) {
// ADD dst, src, 0
// with
// src
- instruction->ReplaceWith(input_other);
- instruction->GetBlock()->RemoveInstruction(instruction);
- return;
+ // Note that we cannot optimize `x + 0.0` to `x` for floating-point. When
+ // `x` is `-0.0`, the former expression yields `0.0`, while the later
+ // yields `-0.0`.
+ if (Primitive::IsIntegralType(instruction->GetType())) {
+ instruction->ReplaceWith(input_other);
+ instruction->GetBlock()->RemoveInstruction(instruction);
+ return;
+ }
}
HInstruction* left = instruction->GetLeft();
@@ -606,21 +611,24 @@ void InstructionSimplifierVisitor::VisitSub(HSub* instruction) {
HConstant* input_cst = instruction->GetConstantRight();
HInstruction* input_other = instruction->GetLeastConstantLeft();
+ Primitive::Type type = instruction->GetType();
+ if (Primitive::IsFloatingPointType(type)) {
+ return;
+ }
+
if ((input_cst != nullptr) && input_cst->IsZero()) {
// Replace code looking like
// SUB dst, src, 0
// with
// src
+ // Note that we cannot optimize `x - 0.0` to `x` for floating-point. When
+ // `x` is `-0.0`, the former expression yields `0.0`, while the later
+ // yields `-0.0`.
instruction->ReplaceWith(input_other);
instruction->GetBlock()->RemoveInstruction(instruction);
return;
}
- Primitive::Type type = instruction->GetType();
- if (!Primitive::IsIntegralType(type)) {
- return;
- }
-
HBasicBlock* block = instruction->GetBlock();
ArenaAllocator* allocator = GetGraph()->GetArena();