Modified: trunk/Source/_javascript_Core/ChangeLog (265890 => 265891)
--- trunk/Source/_javascript_Core/ChangeLog 2020-08-19 19:44:42 UTC (rev 265890)
+++ trunk/Source/_javascript_Core/ChangeLog 2020-08-19 19:46:35 UTC (rev 265891)
@@ -1,3 +1,22 @@
+2020-08-19 Tadeu Zagallo <tzaga...@apple.com>
+
+ B3 IntRange is incorrect for negative masks
+ https://bugs.webkit.org/show_bug.cgi?id=215536
+ <rdar://problem/67130430>
+
+ Reviewed by Michael Saboff and Robin Morisset.
+
+ In the B3 ReduceStrength phase, we compute rangeForMask as (0, mask). This is correct for
+ positive values, but incorrect when negative. To fix it, we use `(INT_MIN & mask, INT_MAX & mask)`
+ as the range for negative masks.
+
+ * b3/B3ReduceStrength.cpp:
+ * b3/testb3.h:
+ * b3/testb3_1.cpp:
+ (run):
+ * b3/testb3_5.cpp:
+ (testCheckSubBitAnd):
+
2020-08-18 Saam Barati <sbar...@apple.com>
Update byte offsets in JSString.h comment
Modified: trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp (265890 => 265891)
--- trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp 2020-08-19 19:44:42 UTC (rev 265890)
+++ trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp 2020-08-19 19:46:35 UTC (rev 265891)
@@ -123,6 +123,8 @@
{
if (!(mask + 1))
return top<T>();
+ if (mask < 0)
+ return IntRange(INT_MIN & mask, mask & INT_MAX);
return IntRange(0, mask);
}
Modified: trunk/Source/_javascript_Core/b3/testb3.h (265890 => 265891)
--- trunk/Source/_javascript_Core/b3/testb3.h 2020-08-19 19:44:42 UTC (rev 265890)
+++ trunk/Source/_javascript_Core/b3/testb3.h 2020-08-19 19:46:35 UTC (rev 265891)
@@ -804,6 +804,7 @@
void testCheckSubImm();
void testCheckSubBadImm();
void testCheckSub();
+void testCheckSubBitAnd();
double doubleSub(double, double);
void testCheckSub64();
void testCheckSubFold(int, int);
Modified: trunk/Source/_javascript_Core/b3/testb3_1.cpp (265890 => 265891)
--- trunk/Source/_javascript_Core/b3/testb3_1.cpp 2020-08-19 19:44:42 UTC (rev 265890)
+++ trunk/Source/_javascript_Core/b3/testb3_1.cpp 2020-08-19 19:46:35 UTC (rev 265891)
@@ -496,6 +496,7 @@
RUN(testCheckSubImm());
RUN(testCheckSubBadImm());
RUN(testCheckSub());
+ RUN(testCheckSubBitAnd());
RUN(testCheckSub64());
RUN(testCheckSubFold(100, 200));
RUN(testCheckSubFoldFail(-2147483647, 100));
Modified: trunk/Source/_javascript_Core/b3/testb3_5.cpp (265890 => 265891)
--- trunk/Source/_javascript_Core/b3/testb3_5.cpp 2020-08-19 19:44:42 UTC (rev 265890)
+++ trunk/Source/_javascript_Core/b3/testb3_5.cpp 2020-08-19 19:46:35 UTC (rev 265891)
@@ -1125,6 +1125,38 @@
CHECK(invoke<double>(*code, -2147483647, 42) == -2147483689.0);
}
+void testCheckSubBitAnd()
+{
+ Procedure proc;
+ if (proc.optLevel() < 1)
+ return;
+ BasicBlock* root = proc.addBlock();
+ Value* zero = root->appendNew<Const32Value>(proc, Origin(), 0);
+ Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
+ Value* truncatedArg1 = root->appendNew<Value>(proc, Trunc, Origin(), arg1);
+ Value* minusTwo = root->appendNew<Const32Value>(proc, Origin(), -2);
+ Value* bitAnd = root->appendNew<Value>(proc, BitAnd, Origin(), truncatedArg1, minusTwo);
+ CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), zero, bitAnd);
+ checkSub->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) {
+ AllowMacroScratchRegisterUsage allowScratch(jit);
+ jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
+ jit.emitFunctionEpilogue();
+ jit.ret();
+ });
+ root->appendNewControlValue(proc, Return, Origin(), checkSub);
+
+ auto code = compileProc(proc);
+
+ CHECK_EQ(invoke<int>(*code, 1), 0);
+ CHECK_EQ(invoke<int>(*code, 2), -2);
+ CHECK_EQ(invoke<int>(*code, 3), -2);
+ CHECK_EQ(invoke<int>(*code, -1), 2);
+ CHECK_EQ(invoke<int>(*code, -2), 2);
+ CHECK_EQ(invoke<int>(*code, -3), 4);
+ CHECK_EQ(invoke<int>(*code, INT_MAX), -(INT_MAX - 1));
+ CHECK_EQ(invoke<int>(*code, INT_MIN), 42);
+}
+
NEVER_INLINE double doubleSub(double a, double b)
{
return a - b;