diff --git a/js/src/jit/arm/Assembler-arm.h b/js/src/jit/arm/Assembler-arm.h index 6b5137090c5..3e42a759122 100644 --- a/js/src/jit/arm/Assembler-arm.h +++ b/js/src/jit/arm/Assembler-arm.h @@ -647,9 +647,13 @@ class Imm8 : public Operand2 public: static datastore::Imm8mData EncodeImm(uint32_t imm) { + // RotateLeft below may not be called with a shift of zero. + if (imm <= 0xFF) + return datastore::Imm8mData(imm, 0); + // An encodable integer has a maximum of 8 contiguous set bits, // with an optional wrapped left rotation to even bit positions. - for (int rot = 0; rot < 16; rot++) { + for (int rot = 1; rot < 16; rot++) { uint32_t rotimm = mozilla::RotateLeft(imm, rot*2); if (rotimm <= 0xFF) return datastore::Imm8mData(rotimm, rot); diff --git a/mfbt/MathAlgorithms.h b/mfbt/MathAlgorithms.h index 81ec6dad4de..28e41826c45 100644 --- a/mfbt/MathAlgorithms.h +++ b/mfbt/MathAlgorithms.h @@ -484,6 +484,11 @@ inline T RotateLeft(const T aValue, uint_fast8_t aShift) { MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); + MOZ_ASSERT(aShift > 0, + "Rotation by value length is undefined behavior, but compilers " + "do not currently fold a test into the rotate instruction. " + "Please remove this restriction when compilers optimize the " + "zero case (http://blog.regehr.org/archives/1063)."); static_assert(IsUnsigned::value, "Rotates require unsigned values"); return (aValue << aShift) | (aValue >> (sizeof(T) * CHAR_BIT - aShift)); } @@ -496,6 +501,11 @@ inline T RotateRight(const T aValue, uint_fast8_t aShift) { MOZ_ASSERT(aShift < sizeof(T) * CHAR_BIT, "Shift value is too large!"); + MOZ_ASSERT(aShift > 0, + "Rotation by value length is undefined behavior, but compilers " + "do not currently fold a test into the rotate instruction. " + "Please remove this restriction when compilers optimize the " + "zero case (http://blog.regehr.org/archives/1063)."); static_assert(IsUnsigned::value, "Rotates require unsigned values"); return (aValue >> aShift) | (aValue << (sizeof(T) * CHAR_BIT - aShift)); }