Index: runtime/vm/intermediate_language.cc |
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc |
index 32f1323f43ae2f8fe131449f61bfc2ffa1e73d5c..fdccf5968b58f2cca9379e28f2f4a662f0423421 100644 |
--- a/runtime/vm/intermediate_language.cc |
+++ b/runtime/vm/intermediate_language.cc |
@@ -1168,6 +1168,7 @@ void Instruction::Goto(JoinEntryInstr* entry) { |
bool UnboxedIntConverterInstr::CanDeoptimize() const { |
return (to() == kUnboxedInt32) && |
+ !is_truncating() && |
!RangeUtils::Fits(value()->definition()->range(), |
RangeBoundary::kRangeBoundaryInt32); |
} |
@@ -1176,10 +1177,14 @@ bool UnboxedIntConverterInstr::CanDeoptimize() const { |
bool UnboxInt32Instr::CanDeoptimize() const { |
const intptr_t value_cid = value()->Type()->ToCid(); |
if (value_cid == kSmiCid) { |
- return false; |
+ return (kSmiBits > 32) && |
+ !is_truncating() && |
+ !RangeUtils::Fits(value()->definition()->range(), |
+ RangeBoundary::kRangeBoundaryInt32); |
} else if (value_cid == kMintCid) { |
- return !RangeUtils::Fits(value()->definition()->range(), |
- RangeBoundary::kRangeBoundaryInt32); |
+ return !is_truncating() && |
+ !RangeUtils::Fits(value()->definition()->range(), |
+ RangeBoundary::kRangeBoundaryInt32); |
} else { |
return true; |
} |
@@ -1743,6 +1748,9 @@ Definition* UnboxIntNInstr::Canonicalize(FlowGraph* flow_graph) { |
representation(), |
box_defn->value()->CopyWithType(), |
representation() == kUnboxedInt32 ? deopt_id_ : Isolate::kNoDeoptId); |
+ if ((representation() == kUnboxedInt32) && is_truncating()) { |
+ converter->mark_truncating(); |
+ } |
flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); |
return converter; |
} |
@@ -1767,6 +1775,9 @@ Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { |
representation(), |
box_defn->value()->CopyWithType(), |
to() == kUnboxedInt32 ? deopt_id_ : NULL); |
+ if ((representation() == kUnboxedInt32) && is_truncating()) { |
+ converter->mark_truncating(); |
+ } |
flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue); |
return converter; |
} |
@@ -1781,6 +1792,9 @@ Definition* UnboxedIntConverterInstr::Canonicalize(FlowGraph* flow_graph) { |
// these instructions close to each other instead of fusing them. |
Definition* replacement = |
new UnboxInt32Instr(unbox_defn->value()->CopyWithType(), deopt_id_); |
+ if (is_truncating()) { |
+ replacement->AsUnboxInt32()->mark_truncating(); |
+ } |
flow_graph->InsertBefore(this, |
replacement, |
env(), |
@@ -1800,6 +1814,15 @@ Definition* UnboxInt32Instr::Canonicalize(FlowGraph* flow_graph) { |
ConstantInstr* c = value()->definition()->AsConstant(); |
if ((c != NULL) && c->value().IsSmi()) { |
+ if (!is_truncating() && (kSmiBits > 32)) { |
+ // Check that constant fits into 32-bit integer. |
+ const int64_t value = |
+ static_cast<int64_t>(Smi::Cast(c->value()).Value()); |
+ if (!Utils::IsInt(32, value)) { |
+ return this; |
+ } |
+ } |
+ |
UnboxedConstantInstr* uc = |
new UnboxedConstantInstr(c->value(), kUnboxedInt32); |
flow_graph->InsertBefore(this, uc, NULL, FlowGraph::kValue); |