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 014525f693cf618187c25d3b3d6d0436153eed04..40cb2075397e131884f873afdd4e20039d227601 100644 |
--- a/src/compiler/arm64/instruction-selector-arm64.cc |
+++ b/src/compiler/arm64/instruction-selector-arm64.cc |
@@ -438,6 +438,13 @@ void InstructionSelector::VisitWord32And(Node* node) { |
// significant bits. |
Int32BinopMatcher mleft(m.left().node()); |
if (mleft.right().IsInRange(0, 31)) { |
+ // Ubfx cannot extract bits past the register size, however since |
+ // shifting the original value would have introduced some zeros we can |
+ // still use ubfx with a smaller mask and the remaining bits will be |
+ // zeros. |
+ uint32_t lsb = mleft.right().Value(); |
+ if (lsb + mask_width > 32) mask_width = 32 - lsb; |
+ |
Emit(kArm64Ubfx32, g.DefineAsRegister(node), |
g.UseRegister(mleft.left().node()), |
g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width)); |
@@ -468,6 +475,13 @@ void InstructionSelector::VisitWord64And(Node* node) { |
// significant bits. |
Int64BinopMatcher mleft(m.left().node()); |
if (mleft.right().IsInRange(0, 63)) { |
+ // Ubfx cannot extract bits past the register size, however since |
+ // shifting the original value would have introduced some zeros we can |
+ // still use ubfx with a smaller mask and the remaining bits will be |
+ // zeros. |
+ uint64_t lsb = mleft.right().Value(); |
+ if (lsb + mask_width > 64) mask_width = 64 - lsb; |
+ |
Emit(kArm64Ubfx, g.DefineAsRegister(node), |
g.UseRegister(mleft.left().node()), |
g.UseImmediate(mleft.right().node()), g.TempImmediate(mask_width)); |