Skip to content

Commit

Permalink
[JSC] B3 should emit AddZeroExtend64 and AddSignExtend64 for Add(@x, …
Browse files Browse the repository at this point in the history
…ZExt(@y)) etc.

https://bugs.webkit.org/show_bug.cgi?id=281195
rdar://137648194

Reviewed by Keith Miller.

When there is Add(@x, ZExt(@y)), we should lower it to
AddZeroExtend64(@x, @y) form.

* Source/JavaScriptCore/b3/B3LowerToAir.cpp:
* Source/JavaScriptCore/b3/testb3.h:
* Source/JavaScriptCore/b3/testb3_2.cpp:
(testAddZeroExtend64):
(testAddSignExtend64):
(addBitTests):

Canonical link: https://commits.webkit.org/284958@main
  • Loading branch information
Constellation committed Oct 10, 2024
1 parent 1055e77 commit 4939b1d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
30 changes: 27 additions & 3 deletions Source/JavaScriptCore/b3/B3LowerToAir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3057,12 +3057,12 @@ class LowerToAir {
Value* left = m_value->child(0);
Value* right = m_value->child(1);

auto tryMultiplyAdd = [&] () -> bool {
auto tryMultiplyAdd = [&]() -> bool {
if (imm(right) && !m_valueToTmp[right])
return false;

// MADD: d = n * m + a
auto tryAppendMultiplyAdd = [&] (Value* left, Value* right) -> bool {
auto tryAppendMultiplyAdd = [&](Value* left, Value* right) -> bool {
if (left->opcode() != Mul || !canBeInternal(left) || m_locked.contains(right))
return false;
Value* multiplyLeft = left->child(0);
Expand Down Expand Up @@ -3103,7 +3103,7 @@ class LowerToAir {
return;

// add-with-shift Pattern: left + (right ShiftType amount)
auto tryAppendAddWithShift = [&] (Value* left, Value* right) -> bool {
auto tryAppendAddWithShift = [&](Value* left, Value* right) -> bool {
Air::Opcode opcode = opcodeBasedOnShiftKind(right->opcode(),
AddLeftShift32, AddLeftShift64,
AddRightShift32, AddRightShift64,
Expand All @@ -3114,6 +3114,30 @@ class LowerToAir {
if (tryAppendAddWithShift(left, right) || tryAppendAddWithShift(right, left))
return;

auto tryAppendAddWithExtend = [&](Value* left, Value* right) -> bool {
if constexpr (isARM64()) {
if (!canBeInternal(right))
return false;

if (isMergeableValue(right, ZExt32) && !imm(left)) {
append(AddZeroExtend64, tmp(left), tmp(right->child(0)), tmp(m_value));
commitInternal(right);
return true;
}

if (isMergeableValue(right, SExt32) && !imm(left)) {
append(AddSignExtend64, tmp(left), tmp(right->child(0)), tmp(m_value));
commitInternal(right);
return true;
}
}
return false;

};

if (tryAppendAddWithExtend(left, right) || tryAppendAddWithExtend(right, left))
return;

appendBinOp<Add32, Add64, AddDouble, AddFloat, Commutative>(left, right);
return;
}
Expand Down
2 changes: 2 additions & 0 deletions Source/JavaScriptCore/b3/testb3.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ void testSubWithUnsignedRightShift32();
void testSubWithLeftShift64();
void testSubWithRightShift64();
void testSubWithUnsignedRightShift64();
void testAddZeroExtend64();
void testAddSignExtend64();

void testAndLeftShift32();
void testAndRightShift32();
Expand Down
42 changes: 42 additions & 0 deletions Source/JavaScriptCore/b3/testb3_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5262,6 +5262,46 @@ void testAddWithUnsignedRightShift64()
}
}

void testAddZeroExtend64()
{
Procedure proc;
BasicBlock* root = proc.addBlock();
auto arguments = cCallArgumentValues<uint64_t, uint64_t>(proc, root);
Value* nValue = arguments[0];
Value* mValue = arguments[1];
root->appendNewControlValue(
proc, Return, Origin(),
root->appendNew<Value>(proc, Add, Origin(), nValue, root->appendNew<Value>(proc, ZExt32, Origin(), root->appendNew<Value>(proc, Trunc, Origin(), mValue))));
auto code = compileProc(proc);
for (auto nOperand : int64Operands()) {
for (auto mOperand : int64Operands()) {
int64_t n = nOperand.value;
int64_t m = mOperand.value;
CHECK_EQ(invoke<int64_t>(*code, n, m), n + static_cast<int64_t>(static_cast<uint64_t>(static_cast<uint32_t>(m))));
}
}
}

void testAddSignExtend64()
{
Procedure proc;
BasicBlock* root = proc.addBlock();
auto arguments = cCallArgumentValues<uint64_t, uint64_t>(proc, root);
Value* nValue = arguments[0];
Value* mValue = arguments[1];
root->appendNewControlValue(
proc, Return, Origin(),
root->appendNew<Value>(proc, Add, Origin(), nValue, root->appendNew<Value>(proc, SExt32, Origin(), root->appendNew<Value>(proc, Trunc, Origin(), mValue))));
auto code = compileProc(proc);
for (auto nOperand : int64Operands()) {
for (auto mOperand : int64Operands()) {
int64_t n = nOperand.value;
int64_t m = mOperand.value;
CHECK_EQ(invoke<int64_t>(*code, n, m), n + static_cast<int32_t>(m));
}
}
}

void testSubWithLeftShift32()
{
if (JSC::Options::defaultB3OptLevel() < 2)
Expand Down Expand Up @@ -7215,6 +7255,8 @@ void addBitTests(const TestConfig* config, Deque<RefPtr<SharedTask<void()>>>& ta
RUN(testAddWithLeftShift64());
RUN(testAddWithRightShift64());
RUN(testAddWithUnsignedRightShift64());
RUN(testAddZeroExtend64());
RUN(testAddSignExtend64());
RUN(testSubWithLeftShift32());
RUN(testSubWithRightShift32());
RUN(testSubWithUnsignedRightShift32());
Expand Down

0 comments on commit 4939b1d

Please sign in to comment.