diff --git a/Core/MIPS/IR/IRPassSimplify.cpp b/Core/MIPS/IR/IRPassSimplify.cpp index 0ba252a018..6c6de0c16c 100644 --- a/Core/MIPS/IR/IRPassSimplify.cpp +++ b/Core/MIPS/IR/IRPassSimplify.cpp @@ -416,8 +416,8 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts } else if (gpr.IsImm(inst.src2)) { const u32 imm2 = gpr.GetImm(inst.src2); gpr.MapDirtyIn(inst.dest, inst.src1); - if (imm2 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) { - // Add / Or with zero is just a Mov. + if (imm2 == 0 && (inst.op == IROp::Add || inst.op == IROp::Sub || inst.op == IROp::Or || inst.op == IROp::Xor)) { + // Add / Sub / Or / Xor with zero is just a Mov. Add / Or are most common. if (inst.dest != inst.src1) out.Write(IROp::Mov, inst.dest, inst.src1); } else { @@ -426,8 +426,8 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts } else if (symmetric && gpr.IsImm(inst.src1)) { const u32 imm1 = gpr.GetImm(inst.src1); gpr.MapDirtyIn(inst.dest, inst.src2); - if (imm1 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or)) { - // Add / Or with zero is just a Mov. + if (imm1 == 0 && (inst.op == IROp::Add || inst.op == IROp::Or || inst.op == IROp::Xor)) { + // Add / Or / Xor with zero is just a Mov. if (inst.dest != inst.src2) out.Write(IROp::Mov, inst.dest, inst.src2); } else { @@ -467,6 +467,11 @@ bool PropagateConstants(const IRWriter &in, IRWriter &out, const IROptions &opts gpr.SetImm(inst.dest, 0); } else if (gpr.IsImm(inst.src1)) { gpr.SetImm(inst.dest, Evaluate(gpr.GetImm(inst.src1), inst.constant, inst.op)); + } else if (inst.constant == 0 && (inst.op == IROp::AddConst || inst.op == IROp::SubConst || inst.op == IROp::OrConst || inst.op == IROp::XorConst)) { + // Convert an Add/Sub/Or/Xor with a constant zero to a Mov (just like with reg zero.) + gpr.MapDirtyIn(inst.dest, inst.src1); + if (inst.dest != inst.src1) + out.Write(IROp::Mov, inst.dest, inst.src1); } else { gpr.MapDirtyIn(inst.dest, inst.src1); goto doDefault; diff --git a/unittest/TestIRPassSimplify.cpp b/unittest/TestIRPassSimplify.cpp index 93b57d4115..e04dfecbe6 100644 --- a/unittest/TestIRPassSimplify.cpp +++ b/unittest/TestIRPassSimplify.cpp @@ -127,11 +127,15 @@ static const IRVerification tests[] = { { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, { IROp::Or, MIPS_REG_S0, MIPS_REG_A0, MIPS_REG_ZERO }, { IROp::Add, MIPS_REG_S1, MIPS_REG_A0, MIPS_REG_ZERO }, + { IROp::OrConst, MIPS_REG_S2, MIPS_REG_A0, 0, 0 }, + { IROp::AddConst, MIPS_REG_S3, MIPS_REG_A0, 0, 0 }, }, { { IROp::Sub, MIPS_REG_A0, MIPS_REG_A1, MIPS_REG_A2 }, { IROp::Mov, MIPS_REG_S0, MIPS_REG_A0 }, { IROp::Mov, MIPS_REG_S1, MIPS_REG_A0 }, + { IROp::Mov, MIPS_REG_S2, MIPS_REG_A0 }, + { IROp::Mov, MIPS_REG_S3, MIPS_REG_A0 }, }, { &PropagateConstants }, },