Fixed indirect jumps to a single label (Compiler) (fixes #380)

This commit is contained in:
kobalicek
2022-09-18 10:02:39 +02:00
committed by Petr Kobalicek
parent 5c469e3f7c
commit 052b4430e9
2 changed files with 131 additions and 4 deletions

View File

@@ -328,9 +328,14 @@ Error BaseRAPass::initSharedAssignments(const ZoneVector<uint32_t>& sharedAssign
RABlock* firstSuccessor = successors[0]; RABlock* firstSuccessor = successors[0];
// NOTE: Shared assignments connect all possible successors so we only need the first to propagate exit scratch // NOTE: Shared assignments connect all possible successors so we only need the first to propagate exit scratch
// GP registers. // GP registers.
ASMJIT_ASSERT(firstSuccessor->hasSharedAssignmentId()); if (firstSuccessor->hasSharedAssignmentId()) {
RASharedAssignment& sa = _sharedAssignments[firstSuccessor->sharedAssignmentId()]; RASharedAssignment& sa = _sharedAssignments[firstSuccessor->sharedAssignmentId()];
sa.addEntryScratchGpRegs(block->exitScratchGpRegs()); sa.addEntryScratchGpRegs(block->exitScratchGpRegs());
}
else {
// This is only allowed if there is a single successor - in that case shared assignment is not necessary.
ASMJIT_ASSERT(successors.size() == 1u);
}
} }
} }
if (block->hasSharedAssignmentId()) { if (block->hasSharedAssignmentId()) {

View File

@@ -277,7 +277,7 @@ public:
} }
virtual void compile(x86::Compiler& cc) { virtual void compile(x86::Compiler& cc) {
Label L0 = cc.newLabel(); Label L0 = cc.newLabel();
Label L1 = cc.newLabel(); Label L1 = cc.newLabel();
Label L2 = cc.newLabel(); Label L2 = cc.newLabel();
Label LEnd = cc.newLabel(); Label LEnd = cc.newLabel();
@@ -715,6 +715,126 @@ public:
} }
}; };
// x86::Compiler - X86Test_JumpTable3
// ==================================
class X86Test_JumpTable3 : public X86TestCase {
public:
X86Test_JumpTable3()
: X86TestCase("JumpTable {Jumping to a single label}") {}
static void add(TestApp& app) {
app.add(new X86Test_JumpTable3());
}
virtual void compile(x86::Compiler& cc) {
cc.addFunc(FuncSignatureT<int>(CallConvId::kHost));
Label L_Target = cc.newLabel();
x86::Gp target = cc.newUIntPtr("target");
x86::Gp result = cc.newUInt32("result");
JumpAnnotation* annotation = cc.newJumpAnnotation();
annotation->addLabel(L_Target);
cc.lea(target, x86::ptr(L_Target));
cc.jmp(target, annotation);
cc.bind(L_Target);
cc.mov(result, 1234);
cc.ret(result);
cc.endFunc();
}
virtual bool run(void* _func, String& result, String& expect) {
typedef int (*Func)(void);
Func func = ptr_as_func<Func>(_func);
int out = func();
int expected = 1234;
result.assignFormat("ret=%d", out);
expect.assignFormat("ret=%d", expected);
return result == expect;
}
};
// x86::Compiler - X86Test_JumpTable4
// ==================================
class X86Test_JumpTable4 : public X86TestCase {
public:
X86Test_JumpTable4()
: X86TestCase("JumpTable {Jumping to a single label and multiple labels}") {}
static void add(TestApp& app) {
app.add(new X86Test_JumpTable4());
}
virtual void compile(x86::Compiler& cc) {
x86::Gp result = cc.newUInt32("result");
x86::Gp condition = cc.newUInt32("condition");
FuncNode* func = cc.addFunc(FuncSignatureT<int, int>(CallConvId::kHost));
func->setArg(0, condition);
Label L_NonZero = cc.newLabel();
cc.test(condition, condition);
cc.jnz(L_NonZero);
{
JumpAnnotation* annotation = cc.newJumpAnnotation();
Label L_Target = cc.newLabel();
annotation->addLabel(L_Target);
x86::Gp target = cc.newUIntPtr("target");
cc.lea(target, x86::ptr(L_Target));
cc.jmp(target, annotation);
cc.bind(L_Target);
cc.mov(result, 1234);
cc.ret(result);
}
{
JumpAnnotation* annotation = cc.newJumpAnnotation();
Label L_Target1 = cc.newLabel();
Label L_Target2 = cc.newLabel();
annotation->addLabel(L_Target1);
annotation->addLabel(L_Target2);
cc.bind(L_NonZero);
x86::Gp target = cc.newUIntPtr("target");
cc.lea(target, x86::ptr(L_Target1));
cc.jmp(target, annotation);
cc.bind(L_Target1);
cc.mov(result, 4321);
cc.ret(result);
// Never executed.
cc.bind(L_Target2);
cc.mov(result, 0);
cc.ret(result);
}
cc.endFunc();
}
virtual bool run(void* _func, String& result, String& expect) {
typedef int (*Func)(int);
Func func = ptr_as_func<Func>(_func);
int results[2] = { func(0), func(1) };
int expected[2] = { 1234, 4321 };
result.assignFormat("ret={%d, %d}", results[0], results[1]);
expect.assignFormat("ret={%d, %d}", expected[0], expected[1]);
return result == expect;
}
};
// x86::Compiler - X86Test_AllocBase // x86::Compiler - X86Test_AllocBase
// ================================= // =================================
@@ -4246,6 +4366,8 @@ void compiler_add_x86_tests(TestApp& app) {
app.addT<X86Test_JumpUnreachable2>(); app.addT<X86Test_JumpUnreachable2>();
app.addT<X86Test_JumpTable1>(); app.addT<X86Test_JumpTable1>();
app.addT<X86Test_JumpTable2>(); app.addT<X86Test_JumpTable2>();
app.addT<X86Test_JumpTable3>();
app.addT<X86Test_JumpTable4>();
// Alloc tests. // Alloc tests.
app.addT<X86Test_AllocBase>(); app.addT<X86Test_AllocBase>();