[Bug] Jump annotation to entry block fix

This commit is contained in:
kobalicek
2021-01-02 01:32:55 +01:00
parent 13876c4e5e
commit 70e80b18a5
2 changed files with 97 additions and 11 deletions

View File

@@ -95,12 +95,13 @@ public:
logNode(_funcNode, kRootIndentation); logNode(_funcNode, kRootIndentation);
logBlock(_curBlock, kRootIndentation); logBlock(_curBlock, kRootIndentation);
RABlock* entryBlock = _curBlock;
BaseNode* node = _funcNode->next(); BaseNode* node = _funcNode->next();
if (ASMJIT_UNLIKELY(!node)) if (ASMJIT_UNLIKELY(!node))
return DebugUtils::errored(kErrorInvalidState); return DebugUtils::errored(kErrorInvalidState);
_curBlock->setFirst(node); _curBlock->setFirst(_funcNode);
_curBlock->setLast(node); _curBlock->setLast(_funcNode);
RAInstBuilder ib; RAInstBuilder ib;
ZoneVector<RABlock*> blocksWithUnknownJumps; ZoneVector<RABlock*> blocksWithUnknownJumps;
@@ -379,9 +380,10 @@ public:
} }
else { else {
// First time we see this label. // First time we see this label.
if (_hasCode) { if (_hasCode || _curBlock == entryBlock) {
// Cannot continue the current block if it already contains some // Cannot continue the current block if it already contains some
// code. We need to create a new block and make it a successor. // code or it's a block entry. We need to create a new block and
// make it a successor.
ASMJIT_ASSERT(_curBlock->last() != node); ASMJIT_ASSERT(_curBlock->last() != node);
_curBlock->setLast(node->prev()); _curBlock->setLast(node->prev());
_curBlock->addFlags(RABlock::kFlagHasConsecutive); _curBlock->addFlags(RABlock::kFlagHasConsecutive);

View File

@@ -547,15 +547,15 @@ public:
}; };
// ============================================================================ // ============================================================================
// [X86Test_JumpTable] // [X86Test_JumpTable1]
// ============================================================================ // ============================================================================
class X86Test_JumpTable : public X86TestCase { class X86Test_JumpTable1 : public X86TestCase {
public: public:
bool _annotated; bool _annotated;
X86Test_JumpTable(bool annotated) X86Test_JumpTable1(bool annotated)
: X86TestCase("X86Test_JumpTable"), : X86TestCase("X86Test_JumpTable1"),
_annotated(annotated) { _annotated(annotated) {
_name.assignFormat("JumpTable {%s}", annotated ? "Annotated" : "Unknown Reg/Mem"); _name.assignFormat("JumpTable {%s}", annotated ? "Annotated" : "Unknown Reg/Mem");
} }
@@ -568,8 +568,8 @@ public:
}; };
static void add(TestApp& app) { static void add(TestApp& app) {
app.add(new X86Test_JumpTable(false)); app.add(new X86Test_JumpTable1(false));
app.add(new X86Test_JumpTable(true)); app.add(new X86Test_JumpTable1(true));
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
@@ -665,6 +665,89 @@ public:
} }
}; };
// ============================================================================
// [X86Test_JumpTable2]
// ============================================================================
class X86Test_JumpTable2 : public X86TestCase {
public:
X86Test_JumpTable2()
: X86TestCase("JumpTable {Jumping to Begin}") {}
static void add(TestApp& app) {
app.add(new X86Test_JumpTable2());
}
virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignatureT<int, int>(CallConv::kIdHost));
x86::Gp result = cc.newUInt32("result");
x86::Gp value = cc.newUInt32("value");
x86::Gp target = cc.newIntPtr("target");
x86::Gp offset = cc.newIntPtr("offset");
Label L_Table = cc.newLabel();
Label L_Begin = cc.newLabel();
Label L_Case0 = cc.newLabel();
Label L_Case1 = cc.newLabel();
Label L_End = cc.newLabel();
cc.setArg(0, value);
cc.bind(L_Begin);
cc.lea(offset, x86::ptr(L_Table));
if (cc.is64Bit())
cc.movsxd(target, x86::dword_ptr(offset, value.cloneAs(offset), 2));
else
cc.mov(target, x86::dword_ptr(offset, value.cloneAs(offset), 2));
cc.add(target, offset);
{
JumpAnnotation* annotation = cc.newJumpAnnotation();
annotation->addLabel(L_Case0);
annotation->addLabel(L_Case1);
annotation->addLabel(L_Begin); // Never used, just for the purpose of the test.
cc.jmp(target, annotation);
cc.bind(L_Case0);
cc.mov(result, 0);
cc.jmp(L_End);
cc.bind(L_Case1);
cc.mov(result, 1);
cc.jmp(L_End);
}
cc.bind(L_End);
cc.ret(result);
cc.endFunc();
cc.bind(L_Table);
cc.embedLabelDelta(L_Case0, L_Table, 4);
cc.embedLabelDelta(L_Case1, L_Table, 4);
}
virtual bool run(void* _func, String& result, String& expect) {
typedef int (*Func)(int);
Func func = ptr_as_func<Func>(_func);
int results[2];
int expected[2];
results[0] = func(0);
results[1] = func(1);
expected[0] = 0;
expected[1] = 1;
result.assignFormat("ret={%d, %d}", results[0], results[1]);
expect.assignFormat("ret={%d, %d}", expected[0], expected[1]);
return result == expect;
}
};
// ============================================================================ // ============================================================================
// [X86Test_AllocBase] // [X86Test_AllocBase]
// ============================================================================ // ============================================================================
@@ -4167,7 +4250,8 @@ void compiler_add_x86_tests(TestApp& app) {
app.addT<X86Test_JumpMany>(); app.addT<X86Test_JumpMany>();
app.addT<X86Test_JumpUnreachable1>(); app.addT<X86Test_JumpUnreachable1>();
app.addT<X86Test_JumpUnreachable2>(); app.addT<X86Test_JumpUnreachable2>();
app.addT<X86Test_JumpTable>(); app.addT<X86Test_JumpTable1>();
app.addT<X86Test_JumpTable2>();
// Alloc tests. // Alloc tests.
app.addT<X86Test_AllocBase>(); app.addT<X86Test_AllocBase>();