Index: runtime/vm/intermediate_language_arm64.cc |
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc |
index cb225a2ac6b79183f2aa8962af8c23bf21bc4ba3..325b694135eefa9361357f5a8b5ee2cb5ad4ecc1 100644 |
--- a/runtime/vm/intermediate_language_arm64.cc |
+++ b/runtime/vm/intermediate_language_arm64.cc |
@@ -2809,8 +2809,21 @@ void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
Register left = locs()->in(0).reg(); |
Register right = locs()->in(1).reg(); |
Register result = locs()->out(0).reg(); |
- __ orr(result, left, Operand(right)); |
- __ tsti(result, Immediate(kSmiTagMask)); |
+ intptr_t left_cid = this->left()->Type()->ToCid(); |
+ intptr_t right_cid = this->right()->Type()->ToCid(); |
+ bool combined_smi_check = false; |
+ if (this->left()->definition() == this->right()->definition()) { |
+ __ tsti(left, Immediate(kSmiTagMask)); |
+ } else if (left_cid == kSmiCid) { |
+ __ tsti(right, Immediate(kSmiTagMask)); |
+ } else if (right_cid == kSmiCid) { |
+ __ tsti(left, Immediate(kSmiTagMask)); |
+ } else { |
+ combined_smi_check = true; |
+ __ orr(result, left, Operand(right)); |
+ __ tsti(result, Immediate(kSmiTagMask)); |
+ } |
+ |
__ b(slow_path->entry_label(), NE); |
switch (op_kind()) { |
case Token::kADD: |
@@ -2822,7 +2835,10 @@ void CheckedSmiOpInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
__ b(slow_path->entry_label(), VS); |
break; |
case Token::kBIT_OR: |
- // Operation part of combined smi check. |
+ // Operation may be part of combined smi check. |
+ if (!combined_smi_check) { |
+ __ orr(result, left, Operand(right)); |
+ } |
break; |
case Token::kBIT_AND: |
__ and_(result, left, Operand(right)); |
@@ -3155,7 +3171,9 @@ void CheckEitherNonSmiInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
intptr_t right_cid = right()->Type()->ToCid(); |
const Register left = locs()->in(0).reg(); |
const Register right = locs()->in(1).reg(); |
- if (left_cid == kSmiCid) { |
+ if (this->left()->definition() == this->right()->definition()) { |
+ __ tsti(left, Immediate(kSmiTagMask)); |
+ } else if (left_cid == kSmiCid) { |
__ tsti(right, Immediate(kSmiTagMask)); |
} else if (right_cid == kSmiCid) { |
__ tsti(left, Immediate(kSmiTagMask)); |