Modified: trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp (249746 => 249747)
--- trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp 2019-09-11 00:35:19 UTC (rev 249746)
+++ trunk/Source/_javascript_Core/b3/B3ReduceStrength.cpp 2019-09-11 00:46:32 UTC (rev 249747)
@@ -1033,8 +1033,8 @@
// Turn this: BitAnd(value, all-ones)
// Into this: value.
- if ((m_value->type() == Int64 && m_value->child(1)->isInt(std::numeric_limits<uint64_t>::max()))
- || (m_value->type() == Int32 && m_value->child(1)->isInt(std::numeric_limits<uint32_t>::max()))) {
+ if ((m_value->type() == Int64 && m_value->child(1)->isInt64(std::numeric_limits<uint64_t>::max()))
+ || (m_value->type() == Int32 && m_value->child(1)->isInt32(std::numeric_limits<uint32_t>::max()))) {
replaceWithIdentity(m_value->child(0));
break;
}
@@ -1083,6 +1083,7 @@
// and Op is BitOr or BitXor
// into this: BitAnd(value, constant2)
if (m_value->child(1)->hasInt()) {
+ bool replaced = false;
int64_t constant2 = m_value->child(1)->asInt();
switch (m_value->child(0)->opcode()) {
case BitOr:
@@ -1091,6 +1092,7 @@
&& !(m_value->child(0)->child(1)->asInt() & constant2)) {
m_value->child(0) = m_value->child(0)->child(0);
m_changed = true;
+ replaced = true;
break;
}
break;
@@ -1097,7 +1099,8 @@
default:
break;
}
- break;
+ if (replaced)
+ break;
}
// Turn this: BitAnd(BitXor(x1, allOnes), BitXor(x2, allOnes)
@@ -1106,11 +1109,11 @@
if (m_value->child(0)->opcode() == BitXor
&& m_value->child(1)->opcode() == BitXor
&& ((m_value->type() == Int64
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint64_t>::max())
- && m_value->child(1)->child(1)->isInt(std::numeric_limits<uint64_t>::max()))
+ && m_value->child(0)->child(1)->isInt64(std::numeric_limits<uint64_t>::max())
+ && m_value->child(1)->child(1)->isInt64(std::numeric_limits<uint64_t>::max()))
|| (m_value->type() == Int32
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint32_t>::max())
- && m_value->child(1)->child(1)->isInt(std::numeric_limits<uint32_t>::max())))) {
+ && m_value->child(0)->child(1)->isInt32(std::numeric_limits<uint32_t>::max())
+ && m_value->child(1)->child(1)->isInt32(std::numeric_limits<uint32_t>::max())))) {
Value* bitOr = m_insertionSet.insert<Value>(m_index, BitOr, m_value->origin(), m_value->child(0)->child(0), m_value->child(1)->child(0));
replaceWithNew<Value>(BitXor, m_value->origin(), bitOr, m_value->child(1)->child(1));
break;
@@ -1123,10 +1126,13 @@
if (m_value->child(0)->opcode() == BitXor
&& m_value->child(1)->hasInt()
&& ((m_value->type() == Int64
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint64_t>::max()))
+ && m_value->child(0)->child(1)->isInt64(std::numeric_limits<uint64_t>::max()))
|| (m_value->type() == Int32
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint32_t>::max())))) {
- Value* bitOr = m_insertionSet.insert<Value>(m_index, BitOr, m_value->origin(), m_value->child(0)->child(0), m_value->child(1)->bitXorConstant(m_proc, m_value->child(0)->child(1)));
+ && m_value->child(0)->child(1)->isInt32(std::numeric_limits<uint32_t>::max())))) {
+ Value* newConstant = m_value->child(1)->bitXorConstant(m_proc, m_value->child(0)->child(1));
+ ASSERT(newConstant);
+ m_insertionSet.insertValue(m_index, newConstant);
+ Value* bitOr = m_insertionSet.insert<Value>(m_index, BitOr, m_value->origin(), m_value->child(0)->child(0), newConstant);
replaceWithNew<Value>(BitXor, m_value->origin(), bitOr, m_value->child(0)->child(1));
break;
}
@@ -1171,8 +1177,8 @@
// Turn this: BitOr(value, all-ones)
// Into this: all-ones.
- if ((m_value->type() == Int64 && m_value->child(1)->isInt(std::numeric_limits<uint64_t>::max()))
- || (m_value->type() == Int32 && m_value->child(1)->isInt(std::numeric_limits<uint32_t>::max()))) {
+ if ((m_value->type() == Int64 && m_value->child(1)->isInt64(std::numeric_limits<uint64_t>::max()))
+ || (m_value->type() == Int32 && m_value->child(1)->isInt32(std::numeric_limits<uint32_t>::max()))) {
replaceWithIdentity(m_value->child(1));
break;
}
@@ -1183,11 +1189,11 @@
if (m_value->child(0)->opcode() == BitXor
&& m_value->child(1)->opcode() == BitXor
&& ((m_value->type() == Int64
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint64_t>::max())
- && m_value->child(1)->child(1)->isInt(std::numeric_limits<uint64_t>::max()))
+ && m_value->child(0)->child(1)->isInt64(std::numeric_limits<uint64_t>::max())
+ && m_value->child(1)->child(1)->isInt64(std::numeric_limits<uint64_t>::max()))
|| (m_value->type() == Int32
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint32_t>::max())
- && m_value->child(1)->child(1)->isInt(std::numeric_limits<uint32_t>::max())))) {
+ && m_value->child(0)->child(1)->isInt32(std::numeric_limits<uint32_t>::max())
+ && m_value->child(1)->child(1)->isInt32(std::numeric_limits<uint32_t>::max())))) {
Value* bitAnd = m_insertionSet.insert<Value>(m_index, BitAnd, m_value->origin(), m_value->child(0)->child(0), m_value->child(1)->child(0));
replaceWithNew<Value>(BitXor, m_value->origin(), bitAnd, m_value->child(1)->child(1));
break;
@@ -1200,10 +1206,13 @@
if (m_value->child(0)->opcode() == BitXor
&& m_value->child(1)->hasInt()
&& ((m_value->type() == Int64
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint64_t>::max()))
+ && m_value->child(0)->child(1)->isInt64(std::numeric_limits<uint64_t>::max()))
|| (m_value->type() == Int32
- && m_value->child(0)->child(1)->isInt(std::numeric_limits<uint32_t>::max())))) {
- Value* bitAnd = m_insertionSet.insert<Value>(m_index, BitAnd, m_value->origin(), m_value->child(0)->child(0), m_value->child(1)->bitXorConstant(m_proc, m_value->child(0)->child(1)));
+ && m_value->child(0)->child(1)->isInt32(std::numeric_limits<uint32_t>::max())))) {
+ Value* newConstant = m_value->child(1)->bitXorConstant(m_proc, m_value->child(0)->child(1));
+ ASSERT(newConstant);
+ m_insertionSet.insertValue(m_index, newConstant);
+ Value* bitAnd = m_insertionSet.insert<Value>(m_index, BitAnd, m_value->origin(), m_value->child(0)->child(0), newConstant);
replaceWithNew<Value>(BitXor, m_value->origin(), bitAnd, m_value->child(0)->child(1));
break;
}
Modified: trunk/Source/_javascript_Core/b3/testb3_2.cpp (249746 => 249747)
--- trunk/Source/_javascript_Core/b3/testb3_2.cpp 2019-09-11 00:35:19 UTC (rev 249746)
+++ trunk/Source/_javascript_Core/b3/testb3_2.cpp 2019-09-11 00:46:32 UTC (rev 249747)
@@ -2565,6 +2565,24 @@
CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a & ~b));
}
+static void testBitAndNotNot32(int32_t a, int32_t b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const32Value>(proc, Origin(), -1));
+ Value* notB = root->appendNew<Value>(proc, BitXor, Origin(), argB, root->appendNew<Const32Value>(proc, Origin(), -1));
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitAnd, Origin(),
+ notA,
+ notB));
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a, b), (~a & ~b));
+}
+
static void testBitAndNotImm(int64_t a, int64_t b)
{
Procedure proc;
@@ -2579,9 +2597,26 @@
notA,
cstB));
- CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a & b));
+ CHECK_EQ(compileAndRun<int64_t>(proc, a), (~a & b));
}
+static void testBitAndNotImm32(int32_t a, int32_t b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const32Value>(proc, Origin(), -1));
+ Value* cstB = root->appendNew<Const32Value>(proc, Origin(), b);
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitAnd, Origin(),
+ notA,
+ cstB));
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a), (~a & b));
+}
+
static void testBitAndImms(int64_t a, int64_t b)
{
Procedure proc;
@@ -2994,6 +3029,34 @@
}
}
+static void testBitOrAndAndArgs32(int32_t a, int32_t b, int32_t c)
+{
+ // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
+ // ((a & b) | (a & c))
+ // ((a & b) | (c & a))
+ // ((b & a) | (a & c))
+ // ((b & a) | (c & a))
+ for (int i = 0; i < 4; ++i) {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* argC = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
+ Value* andAB = i & 2 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
+ : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
+ Value* andAC = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argC)
+ : root->appendNew<Value>(proc, BitAnd, Origin(), argC, argA);
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitOr, Origin(),
+ andAB,
+ andAC));
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a, b, c), ((a & b) | (a & c)));
+ }
+}
+
static void testBitOrAndSameArgs(int64_t a, int64_t b)
{
// We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
@@ -3016,6 +3079,28 @@
}
}
+static void testBitOrAndSameArgs32(int32_t a, int32_t b)
+{
+ // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
+ // ((a & b) | a)
+ // ((b & a) | a)
+ // (a | (a & b))
+ // (a | (b & a))
+ for (int i = 0; i < 4; ++i) {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* andAB = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
+ : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
+ Value* result = i & 2 ? root->appendNew<Value>(proc, BitOr, Origin(), andAB, argA)
+ : root->appendNew<Value>(proc, BitOr, Origin(), argA, andAB);
+ root->appendNewControlValue(proc, Return, Origin(), result);
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a, b), ((a & b) | a));
+ }
+}
+
static void testBitOrNotNot(int64_t a, int64_t b)
{
Procedure proc;
@@ -3034,6 +3119,24 @@
CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a | ~b));
}
+static void testBitOrNotNot32(int32_t a, int32_t b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const32Value>(proc, Origin(), -1));
+ Value* notB = root->appendNew<Value>(proc, BitXor, Origin(), argB, root->appendNew<Const32Value>(proc, Origin(), -1));
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitOr, Origin(),
+ notA,
+ notB));
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a, b), (~a | ~b));
+}
+
static void testBitOrNotImm(int64_t a, int64_t b)
{
Procedure proc;
@@ -3051,6 +3154,23 @@
CHECK_EQ(compileAndRun<int64_t>(proc, a, b), (~a | b));
}
+static void testBitOrNotImm32(int32_t a, int32_t b)
+{
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* notA = root->appendNew<Value>(proc, BitXor, Origin(), argA, root->appendNew<Const32Value>(proc, Origin(), -1));
+ Value* cstB = root->appendNew<Const32Value>(proc, Origin(), b);
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitOr, Origin(),
+ notA,
+ cstB));
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a), (~a | b));
+}
+
static void testBitOrImms(int64_t a, int64_t b)
{
Procedure proc;
@@ -3287,7 +3407,9 @@
RUN_BINARY(testBitAndImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
RUN_BINARY(testBitAndArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
RUN_BINARY(testBitAndNotNot, int64Operands(), int64Operands());
+ RUN_BINARY(testBitAndNotNot32, int32Operands(), int32Operands());
RUN_BINARY(testBitAndNotImm, int64Operands(), int64Operands());
+ RUN_BINARY(testBitAndNotImm32, int32Operands(), int32Operands());
RUN(testBitOrArgs(43, 43));
RUN(testBitOrArgs(43, 0));
@@ -3351,9 +3473,13 @@
RUN_BINARY(testBitOrImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
RUN_BINARY(testBitOrArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
RUN_TERNARY(testBitOrAndAndArgs, int64Operands(), int64Operands(), int64Operands());
+ RUN_TERNARY(testBitOrAndAndArgs32, int32Operands(), int32Operands(), int32Operands());
RUN_BINARY(testBitOrAndSameArgs, int64Operands(), int64Operands());
+ RUN_BINARY(testBitOrAndSameArgs32, int32Operands(), int32Operands());
RUN_BINARY(testBitOrNotNot, int64Operands(), int64Operands());
+ RUN_BINARY(testBitOrNotNot32, int32Operands(), int32Operands());
RUN_BINARY(testBitOrNotImm, int64Operands(), int64Operands());
+ RUN_BINARY(testBitOrNotImm32, int32Operands(), int32Operands());
RUN_BINARY(testBitXorArgs, int64Operands(), int64Operands());
RUN_UNARY(testBitXorSameArg, int64Operands());
@@ -3393,7 +3519,9 @@
RUN(testBitXorImmBitXorArgImm32(6, 1, 6));
RUN(testBitXorImmBitXorArgImm32(24, 0xffff, 7));
RUN_TERNARY(testBitXorAndAndArgs, int64Operands(), int64Operands(), int64Operands());
+ RUN_TERNARY(testBitXorAndAndArgs32, int32Operands(), int32Operands(), int32Operands());
RUN_BINARY(testBitXorAndSameArgs, int64Operands(), int64Operands());
+ RUN_BINARY(testBitXorAndSameArgs32, int32Operands(), int32Operands());
RUN_UNARY(testBitNotArg, int64Operands());
RUN_UNARY(testBitNotImm, int64Operands());
Modified: trunk/Source/_javascript_Core/b3/testb3_3.cpp (249746 => 249747)
--- trunk/Source/_javascript_Core/b3/testb3_3.cpp 2019-09-11 00:35:19 UTC (rev 249746)
+++ trunk/Source/_javascript_Core/b3/testb3_3.cpp 2019-09-11 00:46:32 UTC (rev 249747)
@@ -259,6 +259,34 @@
}
}
+void testBitXorAndAndArgs32(int32_t a, int32_t b, int32_t c)
+{
+ // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
+ // ((a & b) ^ (a & c))
+ // ((a & b) ^ (c & a))
+ // ((b & a) ^ (a & c))
+ // ((b & a) ^ (c & a))
+ for (int i = 0; i < 4; ++i) {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* argC = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
+ Value* andAB = i & 2 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
+ : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
+ Value* andAC = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argC)
+ : root->appendNew<Value>(proc, BitAnd, Origin(), argC, argA);
+ root->appendNewControlValue(
+ proc, Return, Origin(),
+ root->appendNew<Value>(
+ proc, BitXor, Origin(),
+ andAB,
+ andAC));
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a, b, c), ((a & b) ^ (a & c)));
+ }
+}
+
void testBitXorAndSameArgs(int64_t a, int64_t b)
{
// We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
@@ -281,6 +309,28 @@
}
}
+void testBitXorAndSameArgs32(int32_t a, int32_t b)
+{
+ // We want to check every possible ordering of arguments (to properly check every path in B3ReduceStrength):
+ // ((a & b) ^ a)
+ // ((b & a) ^ a)
+ // (a ^ (a & b))
+ // (a ^ (b & a))
+ for (int i = 0; i < 4; ++i) {
+ Procedure proc;
+ BasicBlock* root = proc.addBlock();
+ Value* argA = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
+ Value* argB = root->appendNew<Value>(proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
+ Value* andAB = i & 1 ? root->appendNew<Value>(proc, BitAnd, Origin(), argA, argB)
+ : root->appendNew<Value>(proc, BitAnd, Origin(), argB, argA);
+ Value* result = i & 2 ? root->appendNew<Value>(proc, BitXor, Origin(), andAB, argA)
+ : root->appendNew<Value>(proc, BitXor, Origin(), argA, andAB);
+ root->appendNewControlValue(proc, Return, Origin(), result);
+
+ CHECK_EQ(compileAndRun<int32_t>(proc, a, b), ((a & b) ^ a));
+ }
+}
+
void testBitXorImms(int64_t a, int64_t b)
{
Procedure proc;