LibJS/Bytecode: Don't fuse unrelated compare and jump in peephole pass
Fixes an issue where https://x.com/awesomekling crashed on load. :^)
This commit is contained in:
parent
0f8c6dc9ad
commit
c1dbde72e9
Notes:
sideshowbarker
2024-07-17 08:13:43 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/c1dbde72e9 Pull-request: https://github.com/SerenityOS/serenity/pull/23474
2 changed files with 28 additions and 21 deletions
|
@ -40,32 +40,29 @@ void Peephole::perform(PassPipelineExecutable& executable)
|
||||||
|
|
||||||
if (instruction.type() == Instruction::Type::Not) {
|
if (instruction.type() == Instruction::Type::Not) {
|
||||||
auto const& not_ = static_cast<Op::Not const&>(instruction);
|
auto const& not_ = static_cast<Op::Not const&>(instruction);
|
||||||
VERIFY(jump.condition() == not_.dst());
|
if (jump.condition() != not_.dst()) {
|
||||||
new_block->append<Op::JumpIfNot>(
|
auto slot_offset = new_block->size();
|
||||||
not_.source_record().source_start_offset,
|
new_block->grow(not_.length());
|
||||||
not_.source_record().source_end_offset,
|
memcpy(new_block->data() + slot_offset, ¬_, not_.length());
|
||||||
not_.src(),
|
continue;
|
||||||
*jump.true_target(),
|
}
|
||||||
*jump.false_target());
|
|
||||||
++it;
|
|
||||||
VERIFY(it.at_end());
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DO_FUSE_JUMP(PreOp, ...) \
|
#define DO_FUSE_JUMP(PreOp, ...) \
|
||||||
if (instruction.type() == Instruction::Type::PreOp) { \
|
if (instruction.type() == Instruction::Type::PreOp) { \
|
||||||
auto const& compare = static_cast<Op::PreOp const&>(instruction); \
|
auto const& compare = static_cast<Op::PreOp const&>(instruction); \
|
||||||
VERIFY(jump.condition() == compare.dst()); \
|
if (jump.condition() == compare.dst()) { \
|
||||||
new_block->append<Op::Jump##PreOp>( \
|
new_block->append<Op::Jump##PreOp>( \
|
||||||
compare.source_record().source_start_offset, \
|
compare.source_record().source_start_offset, \
|
||||||
compare.source_record().source_end_offset, \
|
compare.source_record().source_end_offset, \
|
||||||
compare.lhs(), \
|
compare.lhs(), \
|
||||||
compare.rhs(), \
|
compare.rhs(), \
|
||||||
*jump.true_target(), \
|
*jump.true_target(), \
|
||||||
*jump.false_target()); \
|
*jump.false_target()); \
|
||||||
++it; \
|
++it; \
|
||||||
VERIFY(it.at_end()); \
|
VERIFY(it.at_end()); \
|
||||||
continue; \
|
continue; \
|
||||||
|
} \
|
||||||
}
|
}
|
||||||
JS_ENUMERATE_FUSABLE_BINARY_OPS(DO_FUSE_JUMP)
|
JS_ENUMERATE_FUSABLE_BINARY_OPS(DO_FUSE_JUMP)
|
||||||
}
|
}
|
||||||
|
|
10
Userland/Libraries/LibJS/Tests/optimizer-bugs.js
Normal file
10
Userland/Libraries/LibJS/Tests/optimizer-bugs.js
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
test("Don't fuse unrelated jump and compare", () => {
|
||||||
|
function go(a) {
|
||||||
|
a < 3;
|
||||||
|
a &&= 1;
|
||||||
|
|
||||||
|
a < 3;
|
||||||
|
a ||= 1;
|
||||||
|
}
|
||||||
|
go();
|
||||||
|
});
|
Loading…
Add table
Reference in a new issue