Program: 79513
Project: 79513
Buggy source:
public void run(){
  for (  IRFunction irFunction : ir.getFuncs().values()) {
    FuncInfo funcInfo=new FuncInfo();
    for (    PhysicalRegister preg : irFunction.getUsedPhysicalGeneralRegs()) {
      if (preg.isCalleeSave())       funcInfo.usedCalleeSaveRegs.add(preg);
      if (preg.isCallerSave())       funcInfo.usedCallerSaveRegs.add(preg);
    }
    funcInfo.numStackSlot=irFunction.getStackSlots().size();
    for (int i=0; i < funcInfo.numStackSlot; ++i) {
      funcInfo.stackSlotOffsetMap.put(irFunction.getStackSlots().get(i),i * Configuration.getRegSize());
    }
    if ((funcInfo.usedCalleeSaveRegs.size() + funcInfo.numStackSlot) % 2 == 0) {
      ++funcInfo.numStackSlot;
    }
    funcInfo.numExtraArgs=irFunction.getArgVRegList().size() - 6;
    if (funcInfo.numExtraArgs < 0)     funcInfo.numExtraArgs=0;
    int extraArgOffset=-(funcInfo.usedCalleeSaveRegs.size() + funcInfo.numStackSlot + 1) * Configuration.getRegSize();
    for (int i=6; i < irFunction.getArgVRegList().size(); ++i) {
      funcInfo.stackSlotOffsetMap.put(irFunction.getArgsStackSlotMap().get(irFunction.getArgVRegList().get(i)),extraArgOffset);
      extraArgOffset-=Configuration.getRegSize();
    }
    funcInfoMap.put(irFunction,funcInfo);
  }
  for (  IRFunction builtinFunc : ir.getBuiltInFuncs().values()) {
    funcInfoMap.put(builtinFunc,new FuncInfo());
  }
  for (  IRFunction irFunction : funcInfoMap.keySet()) {
    FuncInfo funcInfo=funcInfoMap.get(irFunction);
    funcInfo.recursiveUsedRegs.addAll(irFunction.getUsedPhysicalGeneralRegs());
    for (    IRFunction calleeFunc : irFunction.recursiveCalleeSet) {
      funcInfo.recursiveUsedRegs.addAll(calleeFunc.getUsedPhysicalGeneralRegs());
    }
  }
  for (  IRFunction irFunction : ir.getFuncs().values()) {
    FuncInfo funcInfo=funcInfoMap.get(irFunction);
    BasicBlock entryBB=irFunction.getStartBB();
    IRInstruction firstInst=entryBB.getFirstInst();
    for (    PhysicalRegister preg : funcInfo.usedCalleeSaveRegs) {
      firstInst.prependInst(new IRPush(entryBB,preg));
    }
    if (funcInfo.numStackSlot > 0)     firstInst.prependInst(new IRBinaryOperation(entryBB,rsp,IRBinaryOperation.IRBinaryOp.SUB,rsp,new IntImmediate(funcInfo.numStackSlot * Configuration.getRegSize())));
    firstInst.prependInst(new IRMove(entryBB,rbp,rsp));
    for (    BasicBlock bb : irFunction.getReversePostOrder()) {
      for (IRInstruction inst=bb.getFirstInst(); inst != null; inst=inst.getNextInst()) {
        if (inst instanceof IRFunctionCall) {
          IRFunction calleeFunc=((IRFunctionCall)inst).getFunc();
          FuncInfo calleeInfo=funcInfoMap.get(calleeFunc);
          int numPushCallerSave=0;
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            if (calleeInfo.recursiveUsedRegs.contains(preg)) {
              ++numPushCallerSave;
              inst.prependInst(new IRPush(inst.getParentBB(),preg));
            }
          }
          int numPushArg6Regs=irFunction.getArgVRegList().size() <= 6 ? irFunction.getArgVRegList().size() : 6;
          for (int i=0; i < numPushArg6Regs; ++i) {
            inst.prependInst(new IRPush(inst.getParentBB(),arg6.get(i)));
          }
          numPushCallerSave+=numPushArg6Regs;
          boolean extraPush=false;
          List<RegValue> args=((IRFunctionCall)inst).getArgs();
          List<Integer> arg6BakOffset=new ArrayList<>();
          Map<PhysicalRegister,Integer> arg6BakOffsetMap=new HashMap<>();
          if ((numPushCallerSave + funcInfo.numExtraArgs) % 2 == 1) {
            extraPush=true;
            inst.prependInst(new IRPush(inst.getParentBB(),new IntImmediate(0)));
          }
          for (int i=args.size() - 1; i > 5; --i) {
            if (args.get(i) instanceof StackSlot) {
              inst.prependInst(new IRLoad(inst.getParentBB(),rax,Configuration.getRegSize(),rsp,funcInfo.stackSlotOffsetMap.get(args.get(i))));
              inst.prependInst(new IRPush(inst.getParentBB(),rax));
            }
 else {
              inst.prependInst(new IRPush(inst.getParentBB(),args.get(i)));
            }
          }
          int bakOffset=0;
          for (int i=0; i < 6; ++i) {
            if (args.size() <= i)             break;
            if (args.get(i) instanceof PhysicalRegister && ((PhysicalRegister)args.get(i)).isArg6() && ((PhysicalRegister)args.get(i)).getArg6Idx() < args.size()) {
              PhysicalRegister preg=(PhysicalRegister)args.get(i);
              if (arg6BakOffsetMap.containsKey(preg)) {
                arg6BakOffset.add(arg6BakOffsetMap.get(preg));
              }
 else {
                arg6BakOffset.add(bakOffset);
                arg6BakOffsetMap.put(preg,bakOffset);
                inst.prependInst(new IRPush(inst.getParentBB(),preg));
                ++bakOffset;
              }
            }
 else {
              arg6BakOffset.add(-1);
            }
          }
          for (int i=0; i < 6; ++i) {
            if (args.size() <= i)             break;
            if (arg6BakOffset.get(i) == -1) {
              if (args.get(i) instanceof StackSlot) {
                inst.prependInst(new IRLoad(inst.getParentBB(),rax,Configuration.getRegSize(),rsp,funcInfo.stackSlotOffsetMap.get(args.get(i))));
                inst.prependInst(new IRMove(inst.getParentBB(),arg6.get(i),rax));
              }
 else {
                inst.prependInst(new IRMove(inst.getParentBB(),arg6.get(i),args.get(i)));
              }
            }
 else {
              inst.prependInst(new IRLoad(inst.getParentBB(),arg6.get(i),Configuration.getRegSize(),rsp,Configuration.getRegSize() * (bakOffset - arg6BakOffset.get(i) - 1)));
            }
          }
          if (bakOffset > 0) {
            inst.prependInst(new IRBinaryOperation(inst.getParentBB(),rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(bakOffset * Configuration.getRegSize())));
          }
          if (((IRFunctionCall)inst).getDest() != null) {
            inst.appendInst(new IRMove(inst.getParentBB(),((IRFunctionCall)inst).getDest(),rax));
          }
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            if (calleeInfo.recursiveUsedRegs.contains(preg)) {
              inst.appendInst(new IRPop(inst.getParentBB(),preg));
            }
          }
          for (int i=0; i < numPushArg6Regs; ++i) {
            inst.appendInst(new IRPop(inst.getParentBB(),arg6.get(i)));
          }
          if (funcInfo.numExtraArgs > 0 || extraPush) {
            int numPushArg=extraPush ? funcInfo.numExtraArgs + 1 : funcInfo.numExtraArgs;
            inst.appendInst(new IRBinaryOperation(inst.getParentBB(),rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(numPushArg * Configuration.getRegSize())));
          }
        }
 else         if (inst instanceof IRHeapAlloc) {
          int numPushCallerSave=0;
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            ++numPushCallerSave;
            inst.prependInst(new IRPush(inst.getParentBB(),preg));
          }
          inst.prependInst(new IRMove(inst.getParentBB(),rdi,((IRHeapAlloc)inst).getAllocSize()));
          if (numPushCallerSave % 2 == 1) {
            inst.prependInst(new IRPush(inst.getParentBB(),new IntImmediate(0)));
          }
          inst.appendInst(new IRMove(inst.getParentBB(),((IRHeapAlloc)inst).getDest(),rax));
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            inst.appendInst(new IRPop(inst.getParentBB(),preg));
          }
          if (numPushCallerSave % 2 == 1) {
            inst.appendInst(new IRBinaryOperation(inst.getParentBB(),rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(Configuration.getRegSize())));
          }
        }
 else         if (inst instanceof IRLoad) {
          if (((IRLoad)inst).getAddr() instanceof StackSlot) {
            ((IRLoad)inst).setAddrOffset(funcInfo.stackSlotOffsetMap.get(((IRLoad)inst).getAddr()));
            ((IRLoad)inst).setAddr(rbp);
          }
        }
 else         if (inst instanceof IRStore) {
          if (((IRStore)inst).getAddr() instanceof StackSlot) {
            ((IRStore)inst).setAddrOffset(funcInfo.stackSlotOffsetMap.get(((IRStore)inst).getAddr()));
            ((IRStore)inst).setAddr(rbp);
          }
        }
 else         if (inst instanceof IRMove) {
          if (((IRMove)inst).getLhs() == ((IRMove)inst).getRhs()) {
            inst.remove();
          }
        }
      }
    }
    IRReturn retInst=irFunction.getRetInstList().get(0);
    if (retInst.getRetValue() != null) {
      retInst.prependInst(new IRMove(retInst.getParentBB(),rax,retInst.getRetValue()));
    }
    BasicBlock exitBB=irFunction.getEndBB();
    IRInstruction lastInst=exitBB.getLastInst();
    if (funcInfo.numStackSlot > 0)     lastInst.prependInst(new IRBinaryOperation(entryBB,rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(funcInfo.numStackSlot * Configuration.getRegSize())));
    for (int i=funcInfo.usedCalleeSaveRegs.size() - 1; i >= 0; --i) {
      lastInst.prependInst(new IRPop(entryBB,funcInfo.usedCalleeSaveRegs.get(i)));
    }
  }
}

Fixed version (ground truth):
public void run(){
  for (  IRFunction irFunction : ir.getFuncs().values()) {
    FuncInfo funcInfo=new FuncInfo();
    for (    PhysicalRegister preg : irFunction.getUsedPhysicalGeneralRegs()) {
      if (preg.isCalleeSave())       funcInfo.usedCalleeSaveRegs.add(preg);
      if (preg.isCallerSave())       funcInfo.usedCallerSaveRegs.add(preg);
    }
    funcInfo.usedCalleeSaveRegs.add(rbx);
    funcInfo.usedCalleeSaveRegs.add(rbp);
    funcInfo.numStackSlot=irFunction.getStackSlots().size();
    for (int i=0; i < funcInfo.numStackSlot; ++i) {
      funcInfo.stackSlotOffsetMap.put(irFunction.getStackSlots().get(i),i * Configuration.getRegSize());
    }
    if ((funcInfo.usedCalleeSaveRegs.size() + funcInfo.numStackSlot) % 2 == 0) {
      ++funcInfo.numStackSlot;
    }
    funcInfo.numExtraArgs=irFunction.getArgVRegList().size() - 6;
    if (funcInfo.numExtraArgs < 0)     funcInfo.numExtraArgs=0;
    int extraArgOffset=-(funcInfo.usedCalleeSaveRegs.size() + funcInfo.numStackSlot + 1) * Configuration.getRegSize();
    for (int i=6; i < irFunction.getArgVRegList().size(); ++i) {
      funcInfo.stackSlotOffsetMap.put(irFunction.getArgsStackSlotMap().get(irFunction.getArgVRegList().get(i)),extraArgOffset);
      extraArgOffset-=Configuration.getRegSize();
    }
    funcInfoMap.put(irFunction,funcInfo);
  }
  for (  IRFunction builtinFunc : ir.getBuiltInFuncs().values()) {
    funcInfoMap.put(builtinFunc,new FuncInfo());
  }
  for (  IRFunction irFunction : funcInfoMap.keySet()) {
    FuncInfo funcInfo=funcInfoMap.get(irFunction);
    funcInfo.recursiveUsedRegs.addAll(irFunction.getUsedPhysicalGeneralRegs());
    for (    IRFunction calleeFunc : irFunction.recursiveCalleeSet) {
      funcInfo.recursiveUsedRegs.addAll(calleeFunc.getUsedPhysicalGeneralRegs());
    }
  }
  for (  IRFunction irFunction : ir.getFuncs().values()) {
    FuncInfo funcInfo=funcInfoMap.get(irFunction);
    BasicBlock entryBB=irFunction.getStartBB();
    IRInstruction firstInst=entryBB.getFirstInst();
    for (    PhysicalRegister preg : funcInfo.usedCalleeSaveRegs) {
      firstInst.prependInst(new IRPush(entryBB,preg));
    }
    if (funcInfo.numStackSlot > 0)     firstInst.prependInst(new IRBinaryOperation(entryBB,rsp,IRBinaryOperation.IRBinaryOp.SUB,rsp,new IntImmediate(funcInfo.numStackSlot * Configuration.getRegSize())));
    firstInst.prependInst(new IRMove(entryBB,rbp,rsp));
    for (    BasicBlock bb : irFunction.getReversePostOrder()) {
      for (IRInstruction inst=bb.getFirstInst(); inst != null; inst=inst.getNextInst()) {
        if (inst instanceof IRFunctionCall) {
          IRFunction calleeFunc=((IRFunctionCall)inst).getFunc();
          FuncInfo calleeInfo=funcInfoMap.get(calleeFunc);
          int numPushCallerSave=0;
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            if (calleeInfo.recursiveUsedRegs.contains(preg)) {
              ++numPushCallerSave;
              inst.prependInst(new IRPush(inst.getParentBB(),preg));
            }
          }
          int numPushArg6Regs=irFunction.getArgVRegList().size() <= 6 ? irFunction.getArgVRegList().size() : 6;
          for (int i=0; i < numPushArg6Regs; ++i) {
            inst.prependInst(new IRPush(inst.getParentBB(),arg6.get(i)));
          }
          numPushCallerSave+=numPushArg6Regs;
          boolean extraPush=false;
          List<RegValue> args=((IRFunctionCall)inst).getArgs();
          List<Integer> arg6BakOffset=new ArrayList<>();
          Map<PhysicalRegister,Integer> arg6BakOffsetMap=new HashMap<>();
          if ((numPushCallerSave + funcInfo.numExtraArgs) % 2 == 1) {
            extraPush=true;
            inst.prependInst(new IRPush(inst.getParentBB(),new IntImmediate(0)));
          }
          for (int i=args.size() - 1; i > 5; --i) {
            if (args.get(i) instanceof StackSlot) {
              inst.prependInst(new IRLoad(inst.getParentBB(),rax,Configuration.getRegSize(),rsp,funcInfo.stackSlotOffsetMap.get(args.get(i))));
              inst.prependInst(new IRPush(inst.getParentBB(),rax));
            }
 else {
              inst.prependInst(new IRPush(inst.getParentBB(),args.get(i)));
            }
          }
          int bakOffset=0;
          for (int i=0; i < 6; ++i) {
            if (args.size() <= i)             break;
            if (args.get(i) instanceof PhysicalRegister && ((PhysicalRegister)args.get(i)).isArg6() && ((PhysicalRegister)args.get(i)).getArg6Idx() < args.size()) {
              PhysicalRegister preg=(PhysicalRegister)args.get(i);
              if (arg6BakOffsetMap.containsKey(preg)) {
                arg6BakOffset.add(arg6BakOffsetMap.get(preg));
              }
 else {
                arg6BakOffset.add(bakOffset);
                arg6BakOffsetMap.put(preg,bakOffset);
                inst.prependInst(new IRPush(inst.getParentBB(),preg));
                ++bakOffset;
              }
            }
 else {
              arg6BakOffset.add(-1);
            }
          }
          for (int i=0; i < 6; ++i) {
            if (args.size() <= i)             break;
            if (arg6BakOffset.get(i) == -1) {
              if (args.get(i) instanceof StackSlot) {
                inst.prependInst(new IRLoad(inst.getParentBB(),rax,Configuration.getRegSize(),rsp,funcInfo.stackSlotOffsetMap.get(args.get(i))));
                inst.prependInst(new IRMove(inst.getParentBB(),arg6.get(i),rax));
              }
 else {
                inst.prependInst(new IRMove(inst.getParentBB(),arg6.get(i),args.get(i)));
              }
            }
 else {
              inst.prependInst(new IRLoad(inst.getParentBB(),arg6.get(i),Configuration.getRegSize(),rsp,Configuration.getRegSize() * (bakOffset - arg6BakOffset.get(i) - 1)));
            }
          }
          if (bakOffset > 0) {
            inst.prependInst(new IRBinaryOperation(inst.getParentBB(),rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(bakOffset * Configuration.getRegSize())));
          }
          if (((IRFunctionCall)inst).getDest() != null) {
            inst.appendInst(new IRMove(inst.getParentBB(),((IRFunctionCall)inst).getDest(),rax));
          }
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            if (calleeInfo.recursiveUsedRegs.contains(preg)) {
              inst.appendInst(new IRPop(inst.getParentBB(),preg));
            }
          }
          for (int i=0; i < numPushArg6Regs; ++i) {
            inst.appendInst(new IRPop(inst.getParentBB(),arg6.get(i)));
          }
          if (funcInfo.numExtraArgs > 0 || extraPush) {
            int numPushArg=extraPush ? funcInfo.numExtraArgs + 1 : funcInfo.numExtraArgs;
            inst.appendInst(new IRBinaryOperation(inst.getParentBB(),rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(numPushArg * Configuration.getRegSize())));
          }
        }
 else         if (inst instanceof IRHeapAlloc) {
          int numPushCallerSave=0;
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            ++numPushCallerSave;
            inst.prependInst(new IRPush(inst.getParentBB(),preg));
          }
          inst.prependInst(new IRMove(inst.getParentBB(),rdi,((IRHeapAlloc)inst).getAllocSize()));
          if (numPushCallerSave % 2 == 1) {
            inst.prependInst(new IRPush(inst.getParentBB(),new IntImmediate(0)));
          }
          inst.appendInst(new IRMove(inst.getParentBB(),((IRHeapAlloc)inst).getDest(),rax));
          for (          PhysicalRegister preg : funcInfo.usedCallerSaveRegs) {
            inst.appendInst(new IRPop(inst.getParentBB(),preg));
          }
          if (numPushCallerSave % 2 == 1) {
            inst.appendInst(new IRBinaryOperation(inst.getParentBB(),rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(Configuration.getRegSize())));
          }
        }
 else         if (inst instanceof IRLoad) {
          if (((IRLoad)inst).getAddr() instanceof StackSlot) {
            ((IRLoad)inst).setAddrOffset(funcInfo.stackSlotOffsetMap.get(((IRLoad)inst).getAddr()));
            ((IRLoad)inst).setAddr(rbp);
          }
        }
 else         if (inst instanceof IRStore) {
          if (((IRStore)inst).getAddr() instanceof StackSlot) {
            ((IRStore)inst).setAddrOffset(funcInfo.stackSlotOffsetMap.get(((IRStore)inst).getAddr()));
            ((IRStore)inst).setAddr(rbp);
          }
        }
 else         if (inst instanceof IRMove) {
          if (((IRMove)inst).getLhs() == ((IRMove)inst).getRhs()) {
            inst.remove();
          }
        }
      }
    }
    IRReturn retInst=irFunction.getRetInstList().get(0);
    if (retInst.getRetValue() != null) {
      retInst.prependInst(new IRMove(retInst.getParentBB(),rax,retInst.getRetValue()));
    }
    BasicBlock exitBB=irFunction.getEndBB();
    IRInstruction lastInst=exitBB.getLastInst();
    if (funcInfo.numStackSlot > 0)     lastInst.prependInst(new IRBinaryOperation(entryBB,rsp,IRBinaryOperation.IRBinaryOp.ADD,rsp,new IntImmediate(funcInfo.numStackSlot * Configuration.getRegSize())));
    for (int i=funcInfo.usedCalleeSaveRegs.size() - 1; i >= 0; --i) {
      lastInst.prependInst(new IRPop(entryBB,funcInfo.usedCalleeSaveRegs.get(i)));
    }
  }
}