Below is my code in LLVM LoopPass.

virtual bool runOnLoop(Loop* L, LPPassManager &LPM) {
    BasicBlock& loopCondBlock = *(L->getHeader());
    BasicBlock& loopIncBlock = *(L->getLoopLatch());
    BranchInst* brInsInLoopInc = dyn_cast<BranchInst>(loopIncBlock.getTerminator());
    for (auto &inst: loopCondBlock) {
        auto *new_inst = inst.clone();
        new_inst->insertBefore(brInsInLoopInc);
        llvm::ValueToValueMapTy vmap;
        llvm::RemapInstruction(new_inst, vmap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
    }
    return true;
}

I want to copy instructions in for.cond and paste them on for.inc before branch back to for.cond instruction.

Example original IR:

for.cond:                                         ; preds = %for.inc, %entry
  %0 = load i32, i32* %i, align 4
  %cmp = icmp ult i32 %0, 50000000
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond
  ...

for.inc:                                          ; preds = %for.body
  ...
  br label %for.cond

IR Expected:

for.cond:                                         ; preds = %for.inc, %entry
  %0 = load i32, i32* %i, align 4
  %cmp = icmp ult i32 %0, 50000000
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.cond
  ...

for.inc:                                          ; preds = %for.body
  ...
  // ******PASS ADDED******
  %4 = load i32, i32* %i, align 4
  %cmp2 = icmp ult i32 %4, 50000000
  br i1 %cmp2, label %for.body, label %for.end
  // ******PASS ADDED******

My Loop Pass Result:

for.cond:                                         ; preds = %for.inc, %entry
  %0 = load i32, i32* %i, align 4
  %cmp = icmp ult i32 %0, 50000000
  br i1 %cmp, label %for.body, label %for.end

for.body:                                         ; preds = %for.inc, %for.cond
  ...

for.inc:                                          ; preds = %for.body
  ...
  // ******PASS ADDED******
  %4 = load i32, i32* %i, align 4
  %5 = icmp ult i32 %0, 50000000
  br i1 %cmp, label %for.body, label %for.end
  // ******PASS ADDED******
  br label %for.cond

How to fix the icmp and related branch instruction to be correct and remove the "br label %for.cond"?

Thanks you for your help.

2

There are 2 answers

4
PaulR On

I think you forgot to actually fill the value to value map used in the remap call with mappings from original to copy.

According to the manual, deleting instructions should work by calling eraseFromParent.

This code is untested, so it will likely contain errors, but it should convey the idea:

virtual bool runOnLoop(Loop* L, LPPassManager &LPM) {
    BasicBlock& loopCondBlock = *(L->getHeader());
    BasicBlock& loopIncBlock = *(L->getLoopLatch());
   BranchInst* brInsInLoopInc = dyn_cast<BranchInst>(loopIncBlock.getTerminator());
    llvm::ValueToValueMapTy vmap;
    for (auto &inst: loopCondBlock) {
        auto *new_inst = inst.clone();
        new_inst->insertBefore(brInsInLoopInc);
        // map each instruction to its copy
        vmap[&inst] = new_inst;
        // now this should remap each instruction to its copy
        llvm::RemapInstruction(new_inst, vmap, RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
    }
    // now erase the original branch
    brInsInLoopInc->eraseFromParent();
}
0
Y. Tseng On

I solve my question just add below code after "inst.clone();".

if(inst.hasName()) {
    new_inst->setName(inst.getName()+NameSuffix);
}