| 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));
|
|
|