Program: 149869
Project: 149869
Buggy source:
/** 
 * @param ir the IR to expand
 * @return return value is garbage for IA32
 */
public static int expand(OPT_IR ir){
  OPT_PhysicalRegisterSet phys=ir.regpool.getPhysicalRegisterSet();
  for (OPT_Instruction next, p=ir.firstInstructionInCodeOrder(); p != null; p=next) {
    next=p.nextInstructionInCodeOrder();
    p.setmcOffset(-1);
    p.scratchObject=null;
switch (p.getOpcode()) {
case MIR_LOWTABLESWITCH_opcode:
{
        OPT_BasicBlock thisBlock=p.getBasicBlock();
        OPT_BasicBlock nextBlock=thisBlock.splitNodeWithLinksAt(p,ir);
        nextBlock.firstInstruction().setmcOffset(-1);
        int NumTargets=MIR_LowTableSwitch.getNumberOfTargets(p);
        for (int i=0; i < NumTargets; i++) {
          thisBlock.appendInstruction(MIR_CaseLabel.create(IA32_OFFSET,IC(i),MIR_LowTableSwitch.getClearTarget(p,i)));
        }
        OPT_Register regS=MIR_LowTableSwitch.getIndex(p).getRegister();
        nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_SHL,new OPT_RegisterOperand(regS,VM_TypeReference.Int),IC(2)));
        nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_ADD,new OPT_RegisterOperand(regS,VM_TypeReference.Int),OPT_MemoryOperand.I(new OPT_RegisterOperand(phys.getESP(),VM_TypeReference.Int),(byte)4,null,null)));
        nextBlock.appendInstruction(MIR_Move.create(IA32_MOV,new OPT_RegisterOperand(regS,VM_TypeReference.Int),OPT_MemoryOperand.I(new OPT_RegisterOperand(regS,VM_TypeReference.Int),(byte)4,null,null)));
        nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_ADD,OPT_MemoryOperand.I(new OPT_RegisterOperand(phys.getESP(),VM_TypeReference.Int),(byte)4,null,null),new OPT_RegisterOperand(regS,VM_TypeReference.Int)));
        nextBlock.appendInstruction(MIR_Return.create(IA32_RET,IC(0),null,null));
        MIR_Call.mutate0(p,IA32_CALL,null,null,nextBlock.makeJumpTarget(),null);
      }
    break;
case IA32_TEST_opcode:
  if (MIR_Test.getVal2(p).isMemory()) {
    OPT_Operand tmp=MIR_Test.getClearVal1(p);
    MIR_Test.setVal1(p,MIR_Test.getClearVal2(p));
    MIR_Test.setVal2(p,tmp);
  }
break;
case NULL_CHECK_opcode:
{
OPT_Operand ref=NullCheck.getRef(p);
MIR_TrapIf.mutate(p,IA32_TRAPIF,null,ref.copy(),IC(0),OPT_IA32ConditionOperand.EQ(),OPT_TrapCodeOperand.NullPtr());
}
case IA32_TRAPIF_opcode:
{
OPT_BasicBlock thisBlock=p.getBasicBlock();
OPT_BasicBlock trap=thisBlock.createSubBlock(p.bcIndex,ir,0f);
thisBlock.insertOut(trap);
OPT_BasicBlock nextBlock=thisBlock.splitNodeWithLinksAt(p,ir);
thisBlock.insertOut(trap);
OPT_TrapCodeOperand tc=MIR_TrapIf.getClearTrapCode(p);
p.remove();
nextBlock.firstInstruction().setmcOffset(-1);
OPT_Instruction cmp=MIR_Compare.create(IA32_CMP,MIR_TrapIf.getVal1(p),MIR_TrapIf.getVal2(p));
if (p.isMarkedAsPEI()) {
cmp.markAsPEI();
cmp.copyPosition(p);
ir.MIRInfo.gcIRMap.insertTwin(p,cmp);
}
thisBlock.appendInstruction(cmp);
thisBlock.appendInstruction(MIR_CondBranch.create(IA32_JCC,MIR_TrapIf.getCond(p),trap.makeJumpTarget(),null));
ir.cfg.addLastInCodeOrder(trap);
if (tc.isArrayBounds()) {
OPT_Operand index=MIR_TrapIf.getVal2(p);
if (!(index instanceof OPT_RegisterOperand || index instanceof OPT_IntConstantOperand)) {
  index=IC(0xdeadbeef);
}
OPT_MemoryOperand mo=OPT_MemoryOperand.BD(ir.regpool.makePROp(),VM_ArchEntrypoints.arrayIndexTrapParamField.getOffset(),(byte)4,null,null);
trap.appendInstruction(MIR_Move.create(IA32_MOV,mo,index.copy()));
}
trap.appendInstruction(MIR_Trap.mutate(p,IA32_INT,null,tc));
ir.MIRInfo.gcIRMap.moveToEnd(p);
if (tc.isStackOverflow()) {
trap.appendInstruction(MIR_Branch.create(IA32_JMP,nextBlock.makeJumpTarget()));
}
}
break;
case IA32_FMOV_ENDING_LIVE_RANGE_opcode:
{
OPT_Operand result=MIR_Move.getResult(p);
OPT_Operand value=MIR_Move.getValue(p);
if (result.isRegister() && value.isRegister()) {
if (result.similar(value)) {
p.remove();
}
 else {
int i=OPT_PhysicalRegisterSet.getFPRIndex(result.asRegister().getRegister());
int j=OPT_PhysicalRegisterSet.getFPRIndex(value.asRegister().getRegister());
if (i == 0) {
MIR_XChng.mutate(p,IA32_FXCH,result,value);
}
 else if (j == 0) {
MIR_XChng.mutate(p,IA32_FXCH,value,result);
}
 else {
expandFmov(p,phys);
}
}
}
 else {
expandFmov(p,phys);
}
break;
}
case DUMMY_DEF_opcode:
case DUMMY_USE_opcode:
case REQUIRE_ESP_opcode:
case ADVISE_ESP_opcode:
p.remove();
break;
case IA32_FMOV_opcode:
expandFmov(p,phys);
break;
case IA32_MOV_opcode:
if (MIR_Move.getResult(p).isRegister() && MIR_Move.getValue(p).isIntConstant() && MIR_Move.getValue(p).asIntConstant().value == 0) {
OPT_Instruction x=next;
int futureDefs=0;
while (!BBend.conforms(x) && !OPT_PhysicalDefUse.usesEFLAGS(x.operator)) {
futureDefs|=x.operator.implicitDefs;
x=x.nextInstructionInCodeOrder();
}
if (BBend.conforms(x) || (futureDefs & OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) == OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) {
OPT_Operand result=MIR_Move.getClearResult(p);
MIR_BinaryAcc.mutate(p,IA32_XOR,result,result.copy());
}
}
break;
case IA32_SET__B_opcode:
if (MIR_Set.getResult(p).isRegister() && MIR_Unary.conforms(next) && (next.operator() == IA32_MOVZX__B)&& MIR_Unary.getResult(next).isRegister()&& MIR_Unary.getVal(next).similar(MIR_Unary.getResult(next))&& MIR_Unary.getVal(next).similar(MIR_Set.getResult(p))) {
OPT_Instruction x=p.getPrev();
OPT_Operand result=MIR_Unary.getResult(next);
boolean foundCmp=false;
outer: while (!Label.conforms(x)) {
OPT_OperandEnumeration e=x.getUses();
while (e.hasMoreElements()) {
if (e.next().similar(result)) {
break outer;
}
}
if (OPT_PhysicalDefUse.definesEFLAGS(x.operator)) {
foundCmp=true;
break outer;
}
x=x.getPrev();
}
if (foundCmp) {
next.remove();
MIR_BinaryAcc.mutate(next,IA32_XOR,result,MIR_Unary.getVal(next));
x.insertBefore(next);
next=p.nextInstructionInCodeOrder();
}
}
break;
case IA32_LEA_opcode:
{
OPT_MemoryOperand value=MIR_Lea.getValue(p);
OPT_RegisterOperand result=MIR_Lea.getResult(p);
if ((value.base != null && value.base.getRegister() == result.getRegister()) || (value.index != null && value.index.getRegister() == result.getRegister())) {
OPT_Instruction x=next;
int futureDefs=0;
while (!BBend.conforms(x) && !OPT_PhysicalDefUse.usesEFLAGS(x.operator)) {
futureDefs|=x.operator.implicitDefs;
x=x.nextInstructionInCodeOrder();
}
if (BBend.conforms(x) || (futureDefs & OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) == OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) {
if (value.base != null && value.index != null && value.index.getRegister() == result.getRegister() && value.disp.isZero() && value.scale == 0) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,value.base);
}
 else if (value.base != null && value.base.getRegister() == result.getRegister() && value.index != null && value.disp.isZero() && value.scale == 0) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,value.index);
}
 else if (value.base != null && value.base.getRegister() == result.getRegister() && value.index == null) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,IC(value.disp.toInt()));
}
 else if (value.base == null && value.index == null && value.index.getRegister() == result.getRegister() && value.scale == 0) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,IC(value.disp.toInt()));
}
 else if (value.base == null && value.index == null && value.index.getRegister() == result.getRegister() && value.disp.isZero()) {
MIR_BinaryAcc.mutate(p,IA32_SHL,result,IC(value.scale));
}
}
}
}
break;
case IA32_FCLEAR_opcode:
expandFClear(p,ir);
break;
case IA32_JCC2_opcode:
p.insertBefore(MIR_CondBranch.create(IA32_JCC,MIR_CondBranch2.getCond1(p),MIR_CondBranch2.getTarget1(p),MIR_CondBranch2.getBranchProfile1(p)));
MIR_CondBranch.mutate(p,IA32_JCC,MIR_CondBranch2.getCond2(p),MIR_CondBranch2.getTarget2(p),MIR_CondBranch2.getBranchProfile2(p));
break;
case CALL_SAVE_VOLATILE_opcode:
p.operator=IA32_CALL;
break;
case IA32_LOCK_CMPXCHG_opcode:
p.insertBefore(MIR_Empty.create(IA32_LOCK));
p.operator=IA32_CMPXCHG;
break;
case IA32_LOCK_CMPXCHG8B_opcode:
p.insertBefore(MIR_Empty.create(IA32_LOCK));
p.operator=IA32_CMPXCHG8B;
break;
case YIELDPOINT_PROLOGUE_opcode:
expandYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromPrologueMethod,OPT_IA32ConditionOperand.NE());
break;
case YIELDPOINT_EPILOGUE_opcode:
expandYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromEpilogueMethod,OPT_IA32ConditionOperand.NE());
break;
case YIELDPOINT_BACKEDGE_opcode:
expandYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromBackedgeMethod,OPT_IA32ConditionOperand.GT());
break;
case YIELDPOINT_OSR_opcode:
expandUnconditionalYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromOsrOptMethod);
break;
}
}
return 0;
}

Fixed version (ground truth):
/** 
 * @param ir the IR to expand
 * @return return value is garbage for IA32
 */
public static int expand(OPT_IR ir){
  OPT_PhysicalRegisterSet phys=ir.regpool.getPhysicalRegisterSet();
  for (OPT_Instruction next, p=ir.firstInstructionInCodeOrder(); p != null; p=next) {
    next=p.nextInstructionInCodeOrder();
    p.setmcOffset(-1);
    p.scratchObject=null;
switch (p.getOpcode()) {
case MIR_LOWTABLESWITCH_opcode:
{
        OPT_BasicBlock thisBlock=p.getBasicBlock();
        OPT_BasicBlock nextBlock=thisBlock.splitNodeWithLinksAt(p,ir);
        nextBlock.firstInstruction().setmcOffset(-1);
        int NumTargets=MIR_LowTableSwitch.getNumberOfTargets(p);
        for (int i=0; i < NumTargets; i++) {
          thisBlock.appendInstruction(MIR_CaseLabel.create(IA32_OFFSET,IC(i),MIR_LowTableSwitch.getClearTarget(p,i)));
        }
        OPT_Register regS=MIR_LowTableSwitch.getIndex(p).getRegister();
        nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_SHL,new OPT_RegisterOperand(regS,VM_TypeReference.Int),IC(2)));
        nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_ADD,new OPT_RegisterOperand(regS,VM_TypeReference.Int),OPT_MemoryOperand.I(new OPT_RegisterOperand(phys.getESP(),VM_TypeReference.Int),(byte)4,null,null)));
        nextBlock.appendInstruction(MIR_Move.create(IA32_MOV,new OPT_RegisterOperand(regS,VM_TypeReference.Int),OPT_MemoryOperand.I(new OPT_RegisterOperand(regS,VM_TypeReference.Int),(byte)4,null,null)));
        nextBlock.appendInstruction(MIR_BinaryAcc.create(IA32_ADD,OPT_MemoryOperand.I(new OPT_RegisterOperand(phys.getESP(),VM_TypeReference.Int),(byte)4,null,null),new OPT_RegisterOperand(regS,VM_TypeReference.Int)));
        nextBlock.appendInstruction(MIR_Return.create(IA32_RET,IC(0),null,null));
        MIR_Call.mutate0(p,IA32_CALL,null,null,nextBlock.makeJumpTarget(),null);
      }
    break;
case IA32_TEST_opcode:
  if (MIR_Test.getVal2(p).isMemory()) {
    OPT_Operand tmp=MIR_Test.getClearVal1(p);
    MIR_Test.setVal1(p,MIR_Test.getClearVal2(p));
    MIR_Test.setVal2(p,tmp);
  }
break;
case NULL_CHECK_opcode:
{
OPT_Operand ref=NullCheck.getRef(p);
MIR_TrapIf.mutate(p,IA32_TRAPIF,null,ref.copy(),IC(0),OPT_IA32ConditionOperand.EQ(),OPT_TrapCodeOperand.NullPtr());
}
case IA32_TRAPIF_opcode:
{
OPT_BasicBlock thisBlock=p.getBasicBlock();
OPT_BasicBlock trap=thisBlock.createSubBlock(p.bcIndex,ir,0f);
thisBlock.insertOut(trap);
OPT_BasicBlock nextBlock=thisBlock.splitNodeWithLinksAt(p,ir);
thisBlock.insertOut(trap);
OPT_TrapCodeOperand tc=MIR_TrapIf.getClearTrapCode(p);
p.remove();
nextBlock.firstInstruction().setmcOffset(-1);
OPT_Instruction cmp=MIR_Compare.create(IA32_CMP,MIR_TrapIf.getVal1(p),MIR_TrapIf.getVal2(p));
if (p.isMarkedAsPEI()) {
cmp.markAsPEI();
cmp.copyPosition(p);
ir.MIRInfo.gcIRMap.insertTwin(p,cmp);
}
thisBlock.appendInstruction(cmp);
thisBlock.appendInstruction(MIR_CondBranch.create(IA32_JCC,MIR_TrapIf.getCond(p),trap.makeJumpTarget(),null));
ir.cfg.addLastInCodeOrder(trap);
if (tc.isArrayBounds()) {
OPT_Operand index=MIR_TrapIf.getVal2(p);
if (!(index instanceof OPT_RegisterOperand || index instanceof OPT_IntConstantOperand)) {
  index=IC(0xdeadbeef);
}
OPT_MemoryOperand mo=OPT_MemoryOperand.BD(ir.regpool.makePROp(),VM_ArchEntrypoints.arrayIndexTrapParamField.getOffset(),(byte)4,null,null);
trap.appendInstruction(MIR_Move.create(IA32_MOV,mo,index.copy()));
}
trap.appendInstruction(MIR_Trap.mutate(p,IA32_INT,null,tc));
ir.MIRInfo.gcIRMap.moveToEnd(p);
if (tc.isStackOverflow()) {
trap.appendInstruction(MIR_Branch.create(IA32_JMP,nextBlock.makeJumpTarget()));
}
}
break;
case IA32_FMOV_ENDING_LIVE_RANGE_opcode:
{
OPT_Operand result=MIR_Move.getResult(p);
OPT_Operand value=MIR_Move.getValue(p);
if (result.isRegister() && value.isRegister()) {
if (result.similar(value)) {
p.remove();
}
 else {
int i=OPT_PhysicalRegisterSet.getFPRIndex(result.asRegister().getRegister());
int j=OPT_PhysicalRegisterSet.getFPRIndex(value.asRegister().getRegister());
if (i == 0) {
MIR_XChng.mutate(p,IA32_FXCH,result,value);
}
 else if (j == 0) {
MIR_XChng.mutate(p,IA32_FXCH,value,result);
}
 else {
expandFmov(p,phys);
}
}
}
 else {
expandFmov(p,phys);
}
break;
}
case DUMMY_DEF_opcode:
case DUMMY_USE_opcode:
case REQUIRE_ESP_opcode:
case ADVISE_ESP_opcode:
p.remove();
break;
case IA32_FMOV_opcode:
expandFmov(p,phys);
break;
case IA32_MOV_opcode:
if (MIR_Move.getResult(p).isRegister() && MIR_Move.getValue(p).isIntConstant() && MIR_Move.getValue(p).asIntConstant().value == 0) {
OPT_Instruction x=next;
int futureDefs=0;
while (!BBend.conforms(x) && !OPT_PhysicalDefUse.usesEFLAGS(x.operator)) {
futureDefs|=x.operator.implicitDefs;
x=x.nextInstructionInCodeOrder();
}
if (BBend.conforms(x) || (futureDefs & OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) == OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) {
OPT_Operand result=MIR_Move.getClearResult(p);
MIR_BinaryAcc.mutate(p,IA32_XOR,result,result.copy());
}
}
break;
case IA32_SET__B_opcode:
if (MIR_Set.getResult(p).isRegister() && MIR_Unary.conforms(next) && (next.operator() == IA32_MOVZX__B)&& MIR_Unary.getResult(next).isRegister()&& MIR_Unary.getVal(next).similar(MIR_Unary.getResult(next))&& MIR_Unary.getVal(next).similar(MIR_Set.getResult(p))) {
OPT_Instruction x=p.getPrev();
OPT_Operand result=MIR_Unary.getResult(next);
boolean foundCmp=false;
outer: while (!Label.conforms(x)) {
OPT_OperandEnumeration e=x.getUses();
while (e.hasMoreElements()) {
if (e.next().similar(result)) {
break outer;
}
}
if (OPT_PhysicalDefUse.definesEFLAGS(x.operator) && !OPT_PhysicalDefUse.usesEFLAGS(x.operator)) {
foundCmp=true;
break outer;
}
x=x.getPrev();
}
if (foundCmp) {
next.remove();
MIR_BinaryAcc.mutate(next,IA32_XOR,result,MIR_Unary.getVal(next));
x.insertBefore(next);
next=p.nextInstructionInCodeOrder();
}
}
break;
case IA32_LEA_opcode:
{
OPT_MemoryOperand value=MIR_Lea.getValue(p);
OPT_RegisterOperand result=MIR_Lea.getResult(p);
if ((value.base != null && value.base.getRegister() == result.getRegister()) || (value.index != null && value.index.getRegister() == result.getRegister())) {
OPT_Instruction x=next;
int futureDefs=0;
while (!BBend.conforms(x) && !OPT_PhysicalDefUse.usesEFLAGS(x.operator)) {
futureDefs|=x.operator.implicitDefs;
x=x.nextInstructionInCodeOrder();
}
if (BBend.conforms(x) || (futureDefs & OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) == OPT_PhysicalDefUse.maskAF_CF_OF_PF_SF_ZF) {
if (value.base != null && value.index != null && value.index.getRegister() == result.getRegister() && value.disp.isZero() && value.scale == 0) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,value.base);
}
 else if (value.base != null && value.base.getRegister() == result.getRegister() && value.index != null && value.disp.isZero() && value.scale == 0) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,value.index);
}
 else if (value.base != null && value.base.getRegister() == result.getRegister() && value.index == null) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,IC(value.disp.toInt()));
}
 else if (value.base == null && value.index == null && value.index.getRegister() == result.getRegister() && value.scale == 0) {
MIR_BinaryAcc.mutate(p,IA32_ADD,result,IC(value.disp.toInt()));
}
 else if (value.base == null && value.index == null && value.index.getRegister() == result.getRegister() && value.disp.isZero()) {
MIR_BinaryAcc.mutate(p,IA32_SHL,result,IC(value.scale));
}
}
}
}
break;
case IA32_FCLEAR_opcode:
expandFClear(p,ir);
break;
case IA32_JCC2_opcode:
p.insertBefore(MIR_CondBranch.create(IA32_JCC,MIR_CondBranch2.getCond1(p),MIR_CondBranch2.getTarget1(p),MIR_CondBranch2.getBranchProfile1(p)));
MIR_CondBranch.mutate(p,IA32_JCC,MIR_CondBranch2.getCond2(p),MIR_CondBranch2.getTarget2(p),MIR_CondBranch2.getBranchProfile2(p));
break;
case CALL_SAVE_VOLATILE_opcode:
p.operator=IA32_CALL;
break;
case IA32_LOCK_CMPXCHG_opcode:
p.insertBefore(MIR_Empty.create(IA32_LOCK));
p.operator=IA32_CMPXCHG;
break;
case IA32_LOCK_CMPXCHG8B_opcode:
p.insertBefore(MIR_Empty.create(IA32_LOCK));
p.operator=IA32_CMPXCHG8B;
break;
case YIELDPOINT_PROLOGUE_opcode:
expandYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromPrologueMethod,OPT_IA32ConditionOperand.NE());
break;
case YIELDPOINT_EPILOGUE_opcode:
expandYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromEpilogueMethod,OPT_IA32ConditionOperand.NE());
break;
case YIELDPOINT_BACKEDGE_opcode:
expandYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromBackedgeMethod,OPT_IA32ConditionOperand.GT());
break;
case YIELDPOINT_OSR_opcode:
expandUnconditionalYieldpoint(p,ir,VM_Entrypoints.optThreadSwitchFromOsrOptMethod);
break;
}
}
return 0;
}