Program: 132864
Project: 132864
Buggy source:
/** 
 * Unroll a loop by splitting into two loops, one short one with original stride, and another with a long stride We transform: range_loop [start:end:step] =======> range_loop [start : unroll_end : big_step] range_loop [remainder_start  : end : step]
 */
private List<Continuation> doUnroll(Logger logger,Block outerBlock,int unrollFactor){
  logger.debug("String_Node_Str" + this.loopName + "String_Node_Str"+ desiredUnroll+ "String_Node_Str");
  String vPrefix=Var.OPT_VALUE_VAR_PREFIX + loopName;
  String bigStepName=outerBlock.uniqueVarName(vPrefix + "String_Node_Str");
  VarProvenance prov=VarProvenance.optimizerTmp();
  Var bigIncr=new Var(Types.V_INT,bigStepName,Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var diff=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var diff2=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var extra=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var remainder=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var remainderStart=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var unrollEnd=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  outerBlock.addVariable(bigIncr);
  outerBlock.addVariable(diff);
  outerBlock.addVariable(diff2);
  outerBlock.addVariable(extra);
  outerBlock.addVariable(remainder);
  outerBlock.addVariable(remainderStart);
  outerBlock.addVariable(unrollEnd);
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MULT_INT,bigIncr,Arrays.asList(increment,Arg.createIntLit(unrollFactor))));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MINUS_INT,diff,Arrays.asList(end,start)));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.PLUS_INT,diff2,Arrays.asList(diff.asArg(),Arg.ONE)));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MOD_INT,remainder,Arrays.asList(diff2.asArg(),bigIncr.asArg())));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MINUS_INT,unrollEnd,Arrays.asList(end,remainder.asArg())));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.PLUS_INT,remainderStart,Arrays.asList(unrollEnd.asArg(),Arg.ONE)));
  RangeLoop unrolled=this.clone(false);
  this.start=remainderStart.asArg();
  this.unrolled=true;
  unrolled.end=unrollEnd.asArg();
  unrolled.increment=bigIncr.asArg();
  unrolled.unrolled=true;
  unrolled.leafDegree=Math.max(1,unrolled.leafDegree / unrollFactor);
  Block orig=this.loopBody;
  Arg oldIncr=this.increment;
  Var lastIterLoopVar=null;
  for (int i=0; i < unrollFactor; i++) {
    NestedBlock nb=new NestedBlock(orig.clone(BlockType.NESTED_BLOCK,null));
    Block unrolledBody=unrolled.getLoopBody();
    unrolledBody.addContinuation(nb);
    Var currIterLoopVar;
    if (i == 0) {
      currIterLoopVar=loopVar;
    }
 else {
      String newLoopVarName=outerBlock.uniqueVarName(unrolled.loopVar.name() + "String_Node_Str" + (i + 1));
      currIterLoopVar=new Var(Types.V_INT,newLoopVarName,Alloc.LOCAL,DefType.LOCAL_COMPILER,null);
      unrolledBody.addVariable(currIterLoopVar);
      unrolledBody.addInstruction(Builtin.createLocal(BuiltinOpcode.PLUS_INT,currIterLoopVar,Arrays.asList(Arg.createVar(lastIterLoopVar),oldIncr)));
      nb.renameVars(Collections.singletonMap(unrolled.loopVar,Arg.createVar(currIterLoopVar)),RenameMode.REPLACE_VAR,true);
    }
    lastIterLoopVar=currIterLoopVar;
  }
  return Collections.<Continuation>singletonList(unrolled);
}

Fixed version (ground truth):
/** 
 * Unroll a loop by splitting into two loops, one short one with original stride, and another with a long stride We transform: range_loop [start:end:step] =======> range_loop [start : unroll_end : big_step] range_loop [remainder_start  : end : step]
 */
private List<Continuation> doUnroll(Logger logger,Block outerBlock,int unrollFactor){
  logger.debug("String_Node_Str" + this.loopName + "String_Node_Str"+ desiredUnroll+ "String_Node_Str");
  String vPrefix=Var.OPT_VALUE_VAR_PREFIX + loopName;
  String bigStepName=outerBlock.uniqueVarName(vPrefix + "String_Node_Str");
  VarProvenance prov=VarProvenance.optimizerTmp();
  Var bigIncr=new Var(Types.V_INT,bigStepName,Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var diff=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var diff2=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var extra=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var remainder=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var remainderStart=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  Var unrollEnd=new Var(Types.V_INT,outerBlock.uniqueVarName(vPrefix + "String_Node_Str"),Alloc.LOCAL,DefType.LOCAL_COMPILER,prov);
  outerBlock.addVariable(bigIncr);
  outerBlock.addVariable(diff);
  outerBlock.addVariable(diff2);
  outerBlock.addVariable(extra);
  outerBlock.addVariable(remainder);
  outerBlock.addVariable(remainderStart);
  outerBlock.addVariable(unrollEnd);
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MULT_INT,bigIncr,Arrays.asList(increment,Arg.createIntLit(unrollFactor))));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MINUS_INT,diff,Arrays.asList(end,start)));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.PLUS_INT,diff2,Arrays.asList(diff.asArg(),Arg.ONE)));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MOD_INT,remainder,Arrays.asList(diff2.asArg(),bigIncr.asArg())));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.MINUS_INT,unrollEnd,Arrays.asList(end,remainder.asArg())));
  outerBlock.addInstruction(Builtin.createLocal(BuiltinOpcode.PLUS_INT,remainderStart,Arrays.asList(unrollEnd.asArg(),Arg.ONE)));
  RangeLoop unrolled=this.clone(false);
  this.start=remainderStart.asArg();
  this.unrolled=true;
  unrolled.end=unrollEnd.asArg();
  unrolled.increment=bigIncr.asArg();
  unrolled.unrolled=true;
  unrolled.leafDegree=Math.max(1,unrolled.leafDegree / unrollFactor);
  Block orig=this.loopBody;
  Arg oldIncr=this.increment;
  Var lastIterLoopVar=null;
  for (int i=0; i < unrollFactor; i++) {
    NestedBlock nb=new NestedBlock(orig.clone(BlockType.NESTED_BLOCK,null));
    Block unrolledBody=unrolled.getLoopBody();
    unrolledBody.addContinuation(nb);
    Var currIterLoopVar;
    if (i == 0) {
      currIterLoopVar=loopVar;
    }
 else {
      String newLoopVarName=outerBlock.uniqueVarName(unrolled.loopVar.name() + "String_Node_Str" + (i + 1));
      currIterLoopVar=new Var(Types.V_INT,newLoopVarName,Alloc.LOCAL,DefType.LOCAL_COMPILER,VarProvenance.renamed(unrolled.loopVar));
      unrolledBody.addVariable(currIterLoopVar);
      unrolledBody.addInstruction(Builtin.createLocal(BuiltinOpcode.PLUS_INT,currIterLoopVar,Arrays.asList(Arg.createVar(lastIterLoopVar),oldIncr)));
      nb.renameVars(Collections.singletonMap(unrolled.loopVar,Arg.createVar(currIterLoopVar)),RenameMode.REPLACE_VAR,true);
    }
    lastIterLoopVar=currIterLoopVar;
  }
  return Collections.<Continuation>singletonList(unrolled);
}