Fixed dead code elimination.

Fixed wrong xchg instruction encoding under x64 if one of the operand is r8-15 register.
This commit is contained in:
kobalicekp
2014-03-25 00:08:58 +01:00
parent 2bf1af0dde
commit c279c9ed7d
3 changed files with 68 additions and 10 deletions

View File

@@ -231,14 +231,14 @@ struct X86Test_JumpCross : public X86Test {
};
// ============================================================================
// [X86Test_JumpUnreachable]
// [X86Test_JumpUnreachable1]
// ============================================================================
struct X86Test_JumpUnreachable : public X86Test {
X86Test_JumpUnreachable() : X86Test("[Jump] Unreachable code") {}
struct X86Test_JumpUnreachable1 : public X86Test {
X86Test_JumpUnreachable1() : X86Test("[Jump] Unreachable #1") {}
static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_JumpUnreachable());
tests.append(new X86Test_JumpUnreachable1());
}
virtual void compile(Compiler& c) {
@@ -291,6 +291,52 @@ struct X86Test_JumpUnreachable : public X86Test {
}
};
// ============================================================================
// [X86Test_JumpUnreachable2]
// ============================================================================
struct X86Test_JumpUnreachable2 : public X86Test {
X86Test_JumpUnreachable2() : X86Test("[Jump] Unreachable #2") {}
static void add(PodVector<X86Test*>& tests) {
tests.append(new X86Test_JumpUnreachable2());
}
virtual void compile(Compiler& c) {
c.addFunc(kFuncConvHost, FuncBuilder0<FnVoid>());
Label L_1(c);
Label L_2(c);
GpVar v0(c, kVarTypeUInt32, "v0");
GpVar v1(c, kVarTypeUInt32, "v1");
c.jmp(L_1);
c.bind(L_2);
c.mov(v0, 1);
c.mov(v1, 2);
c.cmp(v0, v1);
c.jz(L_2);
c.jmp(L_1);
c.bind(L_1);
c.ret();
c.endFunc();
}
virtual bool run(void* _func, StringBuilder& result, StringBuilder& expect) {
typedef void (*Func)(void);
Func func = asmjit_cast<Func>(_func);
func();
result.appendString("ret={}");
expect.appendString("ret={}");
return true;
}
};
// ============================================================================
// [X86Test_AllocBase]
// ============================================================================
@@ -2331,7 +2377,8 @@ X86TestSuite::X86TestSuite() :
// Jump.
ADD_TEST(X86Test_JumpCross);
ADD_TEST(X86Test_JumpUnreachable);
ADD_TEST(X86Test_JumpUnreachable1);
ADD_TEST(X86Test_JumpUnreachable2);
// Alloc.
ADD_TEST(X86Test_AllocBase);

View File

@@ -270,11 +270,11 @@ Error BaseContext::removeUnreachableCode() {
while (link != NULL) {
BaseNode* node = link->getValue();
if (node != NULL) {
if (node != NULL && node->getPrev() != NULL) {
// Locate all unreachable nodes.
BaseNode* first = node;
do {
if (node->isFetched() || (node->getType() == kNodeTypeTarget && static_cast<TargetNode*>(node)->getNumRefs() > 0))
if (node->isFetched())
break;
node = node->getNext();
} while (node != stop);

View File

@@ -2021,9 +2021,20 @@ _GroupPop_Gp:
opReg = static_cast<const GpReg*>(o1)->getRegIndex();
rmReg = static_cast<const GpReg*>(o0)->getRegIndex();
// Special opcode for AX/EAX/RAX.
if (o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
opCode = 0x90 + opReg + rmReg; // One of them is zero.
// Special opcode for 'xchg ?ax, reg'.
if (code == kInstXchg && o0->getSize() > 1 && (opReg == 0 || rmReg == 0)) {
// One of them is zero, it doesn't matter if the instruction's form is
// 'xchg ?ax, reg' or 'xchg reg, ?ax'.
opReg += rmReg;
// Rex.B (0x01).
if (Arch == kArchX64) {
opX += opReg >> 3;
opReg &= 0x7;
}
opCode = 0x90 + opReg;
ADD_66H_P(o0->getSize() == 2);
ADD_REX_W(o0->getSize() == 8);
goto _EmitX86Op;