Program: 150048
Project: 150048
Buggy source:
/** 
 * Explicitly copy parameters to a call into the appropriate physical registers as defined by the calling convention. Note: Assumes that ESP points to the word before the slot where the first parameter should be stored.
 */
private static int expandParametersToCall(OPT_Instruction call,OPT_IR ir){
  int nGPRParams=0;
  int nFPRParams=0;
  OPT_PhysicalRegisterSet phys=ir.regpool.getPhysicalRegisterSet();
  int FPRRegisterParams=countFPRParams(call);
  FPRRegisterParams=Math.min(FPRRegisterParams,OPT_PhysicalRegisterSet.getNumberOfFPRParams());
  int parameterBytes=0;
  OPT_Register ESP=phys.getESP();
  call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP,IC(0)));
  int numParams=MIR_Call.getNumberOfParams(call);
  int nParamsInRegisters=0;
  for (int i=0; i < numParams; i++) {
    OPT_Operand param=MIR_Call.getClearParam(call,i);
    MIR_Call.setParam(call,i,null);
    VM_TypeReference paramType=param.getType();
    if (paramType.isFloatType() || paramType.isDoubleType()) {
      nFPRParams++;
      int size=paramType.isFloatType() ? 4 : 8;
      parameterBytes-=size;
      if (nFPRParams > OPT_PhysicalRegisterSet.getNumberOfFPRParams()) {
        OPT_Operand M=new OPT_StackLocationOperand(false,parameterBytes,size);
        call.insertBefore(MIR_Move.create(IA32_FMOV,M,param));
      }
 else {
        OPT_Register phy=phys.getFPRParam(FPRRegisterParams - nFPRParams);
        OPT_RegisterOperand real=new OPT_RegisterOperand(phy,paramType);
        call.insertBefore(MIR_Move.create(IA32_FMOV,real,param));
        MIR_Call.setParam(call,nParamsInRegisters++,real.copy());
      }
    }
 else {
      nGPRParams++;
      parameterBytes-=4;
      if (nGPRParams > OPT_PhysicalRegisterSet.getNumberOfGPRParams()) {
        call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP,IC(parameterBytes + 4)));
        call.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH,param));
      }
 else {
        OPT_Register phy=phys.getGPRParam(nGPRParams - 1);
        OPT_RegisterOperand real=new OPT_RegisterOperand(phy,paramType);
        call.insertBefore(MIR_Move.create(IA32_MOV,real,param));
        MIR_Call.setParam(call,nParamsInRegisters++,real.copy());
      }
    }
  }
  return parameterBytes;
}

Fixed version (ground truth):
/** 
 * Explicitly copy parameters to a call into the appropriate physical registers as defined by the calling convention. Note: Assumes that ESP points to the word before the slot where the first parameter should be stored.
 */
private static int expandParametersToCall(OPT_Instruction call,OPT_IR ir){
  int nGPRParams=0;
  int nFPRParams=0;
  OPT_PhysicalRegisterSet phys=ir.regpool.getPhysicalRegisterSet();
  int FPRRegisterParams=countFPRParams(call);
  FPRRegisterParams=Math.min(FPRRegisterParams,OPT_PhysicalRegisterSet.getNumberOfFPRParams());
  int parameterBytes=0;
  call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP,IC(0)));
  int numParams=MIR_Call.getNumberOfParams(call);
  int nParamsInRegisters=0;
  for (int i=0; i < numParams; i++) {
    OPT_Operand param=MIR_Call.getClearParam(call,i);
    MIR_Call.setParam(call,i,null);
    VM_TypeReference paramType=param.getType();
    if (paramType.isFloatType() || paramType.isDoubleType()) {
      nFPRParams++;
      int size=paramType.isFloatType() ? 4 : 8;
      parameterBytes-=size;
      if (nFPRParams > OPT_PhysicalRegisterSet.getNumberOfFPRParams()) {
        OPT_Operand M=new OPT_StackLocationOperand(false,parameterBytes,size);
        call.insertBefore(MIR_Move.create(IA32_FMOV,M,param));
      }
 else {
        OPT_Register phy=phys.getFPRParam(FPRRegisterParams - nFPRParams);
        OPT_RegisterOperand real=new OPT_RegisterOperand(phy,paramType);
        call.insertBefore(MIR_Move.create(IA32_FMOV,real,param));
        MIR_Call.setParam(call,nParamsInRegisters++,real.copy());
      }
    }
 else {
      nGPRParams++;
      parameterBytes-=4;
      if (nGPRParams > OPT_PhysicalRegisterSet.getNumberOfGPRParams()) {
        call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP,IC(parameterBytes + 4)));
        call.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH,param));
      }
 else {
        OPT_Register phy=phys.getGPRParam(nGPRParams - 1);
        OPT_RegisterOperand real=new OPT_RegisterOperand(phy,paramType);
        call.insertBefore(MIR_Move.create(IA32_MOV,real,param));
        MIR_Call.setParam(call,nParamsInRegisters++,real.copy());
      }
    }
  }
  return parameterBytes;
}