Index: src/compiler/arm64/instruction-selector-arm64.cc |
diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc |
index c07cfbacea72488b3cd6e25f4618892f82e309d7..06bd1e3b04bf62e8bccf9a59b1764bb7648778c0 100644 |
--- a/src/compiler/arm64/instruction-selector-arm64.cc |
+++ b/src/compiler/arm64/instruction-selector-arm64.cc |
@@ -593,6 +593,17 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { |
UNREACHABLE(); |
return; |
} |
+ // If the length is a constant power of two, allow the code generator to |
+ // pick a more efficient bounds check sequence by passing the length as an |
+ // immediate. |
+ if (length->opcode() == IrOpcode::kInt32Constant) { |
+ Int32Matcher m(length); |
+ if (m.IsPowerOf2()) { |
+ Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
+ g.UseRegister(offset), g.UseImmediate(length)); |
+ return; |
+ } |
+ } |
Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), |
g.UseRegister(offset), g.UseOperand(length, kArithmeticImm)); |
} |
@@ -632,6 +643,17 @@ void InstructionSelector::VisitCheckedStore(Node* node) { |
UNREACHABLE(); |
return; |
} |
+ // If the length is a constant power of two, allow the code generator to |
+ // pick a more efficient bounds check sequence by passing the length as an |
+ // immediate. |
+ if (length->opcode() == IrOpcode::kInt32Constant) { |
+ Int32Matcher m(length); |
+ if (m.IsPowerOf2()) { |
+ Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), |
+ g.UseImmediate(length), g.UseRegisterOrImmediateZero(value)); |
+ return; |
+ } |
+ } |
Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), |
g.UseOperand(length, kArithmeticImm), |
g.UseRegisterOrImmediateZero(value)); |