Program: 150199
Project: 150199
Buggy source:
/** 
 * Generate a branching dynamic type check. This routine assumes that the CFG and code order are already  correctly established. This routine must either remove s or mutuate it. 
 * @param s          The OPT_Instruction that is to be replaced by a branching type check
 * @param ir         The OPT_IR containing the instruction to be expanded.
 * @param RHSobj     The OPT_RegisterOperand containing the rhs object.
 * @param LHStype    The VM_TypeReference to be tested against.
 * @param RHStib     The OPT_RegisterOperand containing the TIB of the rhs.
 * @param trueBlock  The OPT_BasicBlock to continue at if the typecheck evaluates to true
 * @param falseBlock The OPT_BasicBlock to continue at if the typecheck evaluates to false.
 * @return the opt instruction immediately before the instruction to continue expansion.
 */
private static OPT_Instruction generateBranchingTypeCheck(OPT_Instruction s,OPT_IR ir,OPT_Operand RHSobj,VM_TypeReference LHStype,OPT_RegisterOperand RHStib,OPT_BasicBlock trueBlock,OPT_BasicBlock falseBlock,OPT_RegisterOperand oldGuard){
  OPT_Instruction continueAt=Goto.create(GOTO,trueBlock.makeJumpTarget());
  continueAt.copyPosition(s);
  s.insertBefore(continueAt);
  s.remove();
  if (LHStype.isClassType()) {
    VM_Class LHSclass=(VM_Class)LHStype.peekResolvedType();
    if (LHSclass != null && LHSclass.isResolved()) {
      if (LHSclass.isInterface()) {
        int interfaceIndex=LHSclass.getDoesImplementIndex();
        int interfaceMask=LHSclass.getDoesImplementBitMask();
        OPT_RegisterOperand doesImpl=InsertUnary(continueAt,ir,GET_DOES_IMPLEMENT_FROM_TIB,VM_TypeReference.IntArray,RHStib);
        if (VM_DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
          OPT_RegisterOperand doesImplLength=InsertGuardedUnary(continueAt,ir,ARRAYLENGTH,VM_TypeReference.Int,doesImpl.copyD2U(),TG());
          OPT_Instruction lengthCheck=IfCmp.create(INT_IFCMP,oldGuard,doesImplLength,I(interfaceIndex),OPT_ConditionOperand.LESS_EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand());
          continueAt.insertBefore(lengthCheck);
          OPT_BasicBlock oldBlock=continueAt.getBasicBlock();
          oldBlock.splitNodeWithLinksAt(lengthCheck,ir);
          oldBlock.insertOut(falseBlock);
        }
        OPT_RegisterOperand entry=InsertLoadOffset(continueAt,ir,INT_LOAD,VM_TypeReference.Int,doesImpl,interfaceIndex << 2,new OPT_LocationOperand(VM_TypeReference.Int),TG());
        OPT_RegisterOperand bit=InsertBinary(continueAt,ir,INT_AND,VM_TypeReference.Int,entry,I(interfaceMask));
        continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,bit,I(0),OPT_ConditionOperand.EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
        return continueAt;
      }
 else {
        if (LHSclass.isFinal()) {
          OPT_Operand classTIB=getTIB(continueAt,ir,LHSclass);
          continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,RHStib,classTIB,OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
          return continueAt;
        }
 else {
          int LHSDepth=LHSclass.getTypeDepth();
          int LHSId=LHSclass.getId();
          OPT_RegisterOperand superclassIds=InsertUnary(continueAt,ir,GET_SUPERCLASS_IDS_FROM_TIB,VM_TypeReference.ShortArray,RHStib);
          if (VM_DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
            OPT_RegisterOperand superclassIdsLength=InsertGuardedUnary(continueAt,ir,ARRAYLENGTH,VM_TypeReference.Int,superclassIds.copyD2U(),TG());
            OPT_Instruction lengthCheck=IfCmp.create(INT_IFCMP,oldGuard,superclassIdsLength,I(LHSDepth),OPT_ConditionOperand.LESS(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand());
            continueAt.insertBefore(lengthCheck);
            OPT_BasicBlock oldBlock=continueAt.getBasicBlock();
            oldBlock.splitNodeWithLinksAt(lengthCheck,ir);
            oldBlock.insertOut(falseBlock);
          }
          OPT_RegisterOperand refCandidate=InsertLoadOffset(continueAt,ir,USHORT_LOAD,VM_TypeReference.Short,superclassIds,LHSDepth << 1,new OPT_LocationOperand(VM_TypeReference.Short),TG());
          continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,refCandidate,I(LHSId),OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
          return continueAt;
        }
      }
    }
 else {
      OPT_RegisterOperand result=ir.regpool.makeTempInt();
      VM_Method target=VM_Entrypoints.instanceOfMethod;
      OPT_Instruction call=Call.create2(CALL,result,I(target.getOffset()),OPT_MethodOperand.STATIC(target),RHSobj,I(LHStype.getId()));
      call.copyPosition(continueAt);
      continueAt.insertBefore(call);
      call=callHelper(call,ir);
      continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,result.copyD2U(),I(0),OPT_ConditionOperand.EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
      return continueAt;
    }
  }
  if (LHStype.isArrayType()) {
    VM_Array LHSArray=(VM_Array)LHStype.peekResolvedType();
    if (LHSArray != null) {
      OPT_Operand classTIB=getTIB(continueAt,ir,LHSArray);
      VM_Type innermostElementType=LHSArray.getInnermostElementType();
      if (innermostElementType.isPrimitiveType() || (innermostElementType.asClass().isResolved() && innermostElementType.asClass().isFinal())) {
        continueAt.insertBefore(IfCmp.create(REF_IFCMP,oldGuard,RHStib,classTIB,OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
        return continueAt;
      }
      OPT_Instruction shortcircuit=IfCmp.create(REF_IFCMP,oldGuard,RHStib,classTIB,OPT_ConditionOperand.EQUAL(),trueBlock.makeJumpTarget(),new OPT_BranchProfileOperand());
      continueAt.insertBefore(shortcircuit);
      OPT_BasicBlock myBlock=shortcircuit.getBasicBlock();
      OPT_BasicBlock mainBlock=myBlock.splitNodeWithLinksAt(shortcircuit,ir);
      myBlock.insertOut(trueBlock);
      OPT_RegisterOperand rhsType=InsertUnary(continueAt,ir,GET_TYPE_FROM_TIB,VM_TypeReference.VM_Type,RHStib.copyD2U());
      if (innermostElementType.isJavaLangObjectType()) {
        OPT_IntConstantOperand lhsDimension=I(LHStype.getDimensionality());
        OPT_RegisterOperand rhsDimension=getField(continueAt,ir,rhsType,VM_Entrypoints.dimensionField);
        OPT_Instruction dimTest=IfCmp2.create(INT_IFCMP2,oldGuard,rhsDimension,lhsDimension,OPT_ConditionOperand.GREATER(),trueBlock.makeJumpTarget(),new OPT_BranchProfileOperand(),OPT_ConditionOperand.LESS(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand());
        continueAt.insertBefore(dimTest);
        OPT_BasicBlock testBlock=mainBlock.splitNodeWithLinksAt(dimTest,ir);
        mainBlock.insertOut(trueBlock);
        mainBlock.insertOut(falseBlock);
        OPT_RegisterOperand rhsInnermostElementType=getField(continueAt,ir,rhsType.copyU2U(),VM_Entrypoints.innermostElementTypeField);
        OPT_RegisterOperand rhsInnermostElementTypeDimension=getField(continueAt,ir,rhsInnermostElementType,VM_Entrypoints.dimensionField);
        continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,rhsInnermostElementTypeDimension,I(0),OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
        return continueAt;
      }
    }
    VM_Method target=VM_Entrypoints.instanceOfMethod;
    OPT_RegisterOperand callResult=ir.regpool.makeTempInt();
    OPT_Instruction call=Call.create2(CALL,callResult,I(target.getOffset()),OPT_MethodOperand.STATIC(target),RHSobj,I(LHStype.getId()));
    call.copyPosition(continueAt);
    continueAt.insertBefore(call);
    call=callHelper(call,ir);
    continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,callResult.copyD2U(),I(0),OPT_ConditionOperand.EQUAL(),falseBlock.makeJumpTarget(),new OPT_BranchProfileOperand()));
    return continueAt;
  }
  OPT_OptimizingCompilerException.UNREACHABLE();
  return null;
}

Fixed version (ground truth):
/** 
 * Generate a branching dynamic type check. This routine assumes that the CFG and code order are already  correctly established. This routine must either remove s or mutuate it. 
 * @param s          The OPT_Instruction that is to be replaced by a branching type check
 * @param ir         The OPT_IR containing the instruction to be expanded.
 * @param RHSobj     The OPT_RegisterOperand containing the rhs object.
 * @param LHStype    The VM_TypeReference to be tested against.
 * @param RHStib     The OPT_RegisterOperand containing the TIB of the rhs.
 * @param trueBlock  The OPT_BasicBlock to continue at if the typecheck evaluates to true
 * @param falseBlock The OPT_BasicBlock to continue at if the typecheck evaluates to false.
 * @param falseProb   The probability that typecheck will branch to the falseBlock
 * @return the opt instruction immediately before the instruction to continue expansion.
 */
private static OPT_Instruction generateBranchingTypeCheck(OPT_Instruction s,OPT_IR ir,OPT_Operand RHSobj,VM_TypeReference LHStype,OPT_RegisterOperand RHStib,OPT_BasicBlock trueBlock,OPT_BasicBlock falseBlock,OPT_RegisterOperand oldGuard,OPT_BranchProfileOperand falseProb){
  OPT_Instruction continueAt=Goto.create(GOTO,trueBlock.makeJumpTarget());
  continueAt.copyPosition(s);
  s.insertBefore(continueAt);
  s.remove();
  if (LHStype.isClassType()) {
    VM_Class LHSclass=(VM_Class)LHStype.peekResolvedType();
    if (LHSclass != null && LHSclass.isResolved()) {
      if (LHSclass.isInterface()) {
        int interfaceIndex=LHSclass.getDoesImplementIndex();
        int interfaceMask=LHSclass.getDoesImplementBitMask();
        OPT_RegisterOperand doesImpl=InsertUnary(continueAt,ir,GET_DOES_IMPLEMENT_FROM_TIB,VM_TypeReference.IntArray,RHStib);
        if (VM_DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
          OPT_RegisterOperand doesImplLength=InsertGuardedUnary(continueAt,ir,ARRAYLENGTH,VM_TypeReference.Int,doesImpl.copyD2U(),TG());
          OPT_Instruction lengthCheck=IfCmp.create(INT_IFCMP,oldGuard,doesImplLength,I(interfaceIndex),OPT_ConditionOperand.LESS_EQUAL(),falseBlock.makeJumpTarget(),OPT_BranchProfileOperand.unlikely());
          continueAt.insertBefore(lengthCheck);
          OPT_BasicBlock oldBlock=continueAt.getBasicBlock();
          oldBlock.splitNodeWithLinksAt(lengthCheck,ir);
          oldBlock.insertOut(falseBlock);
        }
        OPT_RegisterOperand entry=InsertLoadOffset(continueAt,ir,INT_LOAD,VM_TypeReference.Int,doesImpl,interfaceIndex << 2,new OPT_LocationOperand(VM_TypeReference.Int),TG());
        OPT_RegisterOperand bit=InsertBinary(continueAt,ir,INT_AND,VM_TypeReference.Int,entry,I(interfaceMask));
        continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,bit,I(0),OPT_ConditionOperand.EQUAL(),falseBlock.makeJumpTarget(),falseProb));
        return continueAt;
      }
 else {
        if (LHSclass.isFinal()) {
          OPT_Operand classTIB=getTIB(continueAt,ir,LHSclass);
          continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,RHStib,classTIB,OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),falseProb));
          return continueAt;
        }
 else {
          int LHSDepth=LHSclass.getTypeDepth();
          int LHSId=LHSclass.getId();
          OPT_RegisterOperand superclassIds=InsertUnary(continueAt,ir,GET_SUPERCLASS_IDS_FROM_TIB,VM_TypeReference.ShortArray,RHStib);
          if (VM_DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
            OPT_RegisterOperand superclassIdsLength=InsertGuardedUnary(continueAt,ir,ARRAYLENGTH,VM_TypeReference.Int,superclassIds.copyD2U(),TG());
            OPT_Instruction lengthCheck=IfCmp.create(INT_IFCMP,oldGuard,superclassIdsLength,I(LHSDepth),OPT_ConditionOperand.LESS(),falseBlock.makeJumpTarget(),OPT_BranchProfileOperand.unlikely());
            continueAt.insertBefore(lengthCheck);
            OPT_BasicBlock oldBlock=continueAt.getBasicBlock();
            oldBlock.splitNodeWithLinksAt(lengthCheck,ir);
            oldBlock.insertOut(falseBlock);
          }
          OPT_RegisterOperand refCandidate=InsertLoadOffset(continueAt,ir,USHORT_LOAD,VM_TypeReference.Short,superclassIds,LHSDepth << 1,new OPT_LocationOperand(VM_TypeReference.Short),TG());
          continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,refCandidate,I(LHSId),OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),falseProb));
          return continueAt;
        }
      }
    }
 else {
      OPT_RegisterOperand result=ir.regpool.makeTempInt();
      VM_Method target=VM_Entrypoints.instanceOfMethod;
      OPT_Instruction call=Call.create2(CALL,result,I(target.getOffset()),OPT_MethodOperand.STATIC(target),RHSobj,I(LHStype.getId()));
      call.copyPosition(continueAt);
      continueAt.insertBefore(call);
      call=callHelper(call,ir);
      continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,result.copyD2U(),I(0),OPT_ConditionOperand.EQUAL(),falseBlock.makeJumpTarget(),falseProb));
      return continueAt;
    }
  }
  if (LHStype.isArrayType()) {
    VM_Array LHSArray=(VM_Array)LHStype.peekResolvedType();
    if (LHSArray != null) {
      OPT_Operand classTIB=getTIB(continueAt,ir,LHSArray);
      VM_Type innermostElementType=LHSArray.getInnermostElementType();
      if (innermostElementType.isPrimitiveType() || (innermostElementType.asClass().isResolved() && innermostElementType.asClass().isFinal())) {
        continueAt.insertBefore(IfCmp.create(REF_IFCMP,oldGuard,RHStib,classTIB,OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),falseProb));
        return continueAt;
      }
      OPT_Instruction shortcircuit=IfCmp.create(REF_IFCMP,oldGuard,RHStib,classTIB,OPT_ConditionOperand.EQUAL(),trueBlock.makeJumpTarget(),new OPT_BranchProfileOperand());
      continueAt.insertBefore(shortcircuit);
      OPT_BasicBlock myBlock=shortcircuit.getBasicBlock();
      OPT_BasicBlock mainBlock=myBlock.splitNodeWithLinksAt(shortcircuit,ir);
      myBlock.insertOut(trueBlock);
      OPT_RegisterOperand rhsType=InsertUnary(continueAt,ir,GET_TYPE_FROM_TIB,VM_TypeReference.VM_Type,RHStib.copyD2U());
      if (innermostElementType.isJavaLangObjectType()) {
        OPT_IntConstantOperand lhsDimension=I(LHStype.getDimensionality());
        OPT_RegisterOperand rhsDimension=getField(continueAt,ir,rhsType,VM_Entrypoints.dimensionField);
        OPT_Instruction dimTest=IfCmp2.create(INT_IFCMP2,oldGuard,rhsDimension,lhsDimension,OPT_ConditionOperand.GREATER(),trueBlock.makeJumpTarget(),((OPT_BranchProfileOperand)falseProb.copy()).flip(),OPT_ConditionOperand.LESS(),falseBlock.makeJumpTarget(),falseProb);
        continueAt.insertBefore(dimTest);
        OPT_BasicBlock testBlock=mainBlock.splitNodeWithLinksAt(dimTest,ir);
        mainBlock.insertOut(trueBlock);
        mainBlock.insertOut(falseBlock);
        OPT_RegisterOperand rhsInnermostElementType=getField(continueAt,ir,rhsType.copyU2U(),VM_Entrypoints.innermostElementTypeField);
        OPT_RegisterOperand rhsInnermostElementTypeDimension=getField(continueAt,ir,rhsInnermostElementType,VM_Entrypoints.dimensionField);
        continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,rhsInnermostElementTypeDimension,I(0),OPT_ConditionOperand.NOT_EQUAL(),falseBlock.makeJumpTarget(),falseProb));
        return continueAt;
      }
    }
    VM_Method target=VM_Entrypoints.instanceOfMethod;
    OPT_RegisterOperand callResult=ir.regpool.makeTempInt();
    OPT_Instruction call=Call.create2(CALL,callResult,I(target.getOffset()),OPT_MethodOperand.STATIC(target),RHSobj,I(LHStype.getId()));
    call.copyPosition(continueAt);
    continueAt.insertBefore(call);
    call=callHelper(call,ir);
    continueAt.insertBefore(IfCmp.create(INT_IFCMP,oldGuard,callResult.copyD2U(),I(0),OPT_ConditionOperand.EQUAL(),falseBlock.makeJumpTarget(),falseProb));
    return continueAt;
  }
  OPT_OptimizingCompilerException.UNREACHABLE();
  return null;
}