LLVM Pass : DELETE all branch in the IR occurs errors

218 views Asked by At

I want to delete branch instructions in the IR code through LLVM pass.

The code below is my Function pass (Github):

virtual bool runOnFunction(Function &F) {
    for (auto &B : F) {
        for (auto &I : B) {
            auto op_name = I.getOpcodeName();
            if(strcmp(op_name, "br")==0) {
                I.eraseFromParent();
            }
        }
    }
    return true;
}

The Function Pass is compiled successfully, but when i use it on test.c, it occurs the error like Pastebin

1

There are 1 answers

0
PaulR On

Modifying a container while iterating over it with a range based for loop will not work, because the end expression will not be reevaluated. Moreover depending on the container you may invalidate the iterator to the element you are deleting.

cppreference explains range based for loops until C++17 like this:

{
    auto && __range = range_expression ;
    for (auto __begin = begin_expr, __end = end_expr;
         // __end not reevaluated!
         __begin != __end; ++__begin) {

        range_declaration = *__begin;
        loop_statement

    }
}

eraseFromParent will delete the instruction from the basic block, so you cannot use the range based for loop in this case. The LLVM developers have however made it return an iterator to the next element, that you can use to continue your loop.

virtual bool runOnFunction(Function &F) {
    for (auto &B : F) {
        auto It = B.begin()
        // we modify B, so we must reevaluate end()
        while(It != B.end()) {
            auto &I = *It;
            auto op_name = I.getOpcodeName();
            if(strcmp(op_name, "br")==0) {
                // we continue with the next element
                It = I.eraseFromParent();
            } else {
                ++It;
            }
        }
    }
    return true;
}