0

I am trying to delete a range of instructions ( specified as between [startIns , endIns) ) . the endIns may not be in the same basic block as the start.

I keep getting the following error when trying to delete the last instruction in - reference llvm::ilist_iterator, false, false>::operator*() const [OptionsT = llvm::ilist_detail::node_options, IsReverse = false, IsConst = false]: Assertion `!NodePtr->isKnownSentinel()' failed.

Following is my C++ code -

// delete all instructions between [start,end)

//startInst is "%res = alloca i8 " in IR below."

// endInst is "%resclone0 = alloca i10" in IR below.

void deleteAllInstructionsInRange(Instruction* startInst,Instruction* endInst)
    {
        BasicBlock::iterator it(startInst);
        BasicBlock::iterator it_end(endInst);

        Instruction* currentInst ;

        while(it != it_end)
        {
            currentInst = &*it;

            ++it;


            if (!currentInst->use_empty())
            {   
                currentInst->replaceAllUsesWith(UndefValue::get(currentInst->getType()));
            }

            currentInst->eraseFromParent();

        }



    }

Following is the relevant IR

define i32 @test2() {
entry:
  %calltmp = call i32 @UInt()
  %datasize = alloca i32
  switch i32 %calltmp, label %sw.bb.0 [
    i32 1, label %sw.bb.1
    i32 2, label %sw.bb.2
    i32 3, label %sw.bb.3
  ]
 ; %res = alloca i8                       ===> deleted
  ;store i8 0, i8* %res                  ===> deleted
  ;%datasize1 = load i32, i32* %datasize ===> deleted

  ret i32 %datasize1                     ===> UNABLE to delete

sw.bb.0:                                          ; preds = %entry
  %resclone0 = alloca i10
  store i10 0, i10* %resclone0
  %datasize1clone0 = load i32, i32* %datasize

Any help will be appreciated.

Thanks.

mal
  • 143
  • 2
  • 12

2 Answers2

0

First have a look at this answer to understand what isKnownSentinel() means.

My guess is that since you are modifying the basic block while iterating it which is not safe and you are getting the error.

deLta
  • 561
  • 2
  • 12
  • I already know what sentinel means for llvm , and you are correct about the fact that I am modifying the BB while iterating. Hence I simply stored the instructions in a vector and deleted them later. – mal Jun 15 '17 at 15:02
0

My guess is that ret is a terminator and deleting it would invalidate the IR. Quoting this question:

Every basic block must end with a terminator.

I suggest replacing terminator instructions with uncondicional jump to the next block (not tested):

if (currentInst->isTerminator()) {
    // works only if block has only one successor
    currentInst->replaceAllUsesWith(
        builder->CreateBr(
            builder->GetInsertBlock()->getSingleSuccessor())); 
}
vaartis
  • 334
  • 4
  • 10