I am working with LLVM IR code. I want to delete instructions from LLVM IR representation through programs. LLVM Official documentation describing about how to delete, but it is not that clear. Because of some forward references, when I try to delete, it throws exceptions.
Eg:
`%add2 = add nsw i32 %4, %5`
`store i32 %add2, i32* %b, align 4 `
Here, I want to delete %add2 = add nsw i32 %4, %5
instruction, but it throws an exception because %add2
is referred by the second instruction.
There are ReplaceInstWithValue
and ReplaceInstWithInst
instructions, but the usage is not clear from the official documentation.
How to do this? Can anyone help me with some examples.
You can use the ReplaceInstWithInst functions when you have two instructions with the same llvm:Type.
For example if you have your BinaryOperator*
that results in %add2 = add nsw i32 %4, %5
you can do the following:
auto& ctx = getGlobalContext();
auto newAdd = BinaryOperator::CreateAdd(
ConstantInt::get(cast<Type>(Type::getInt32Ty(ctx)), APInt(32, 42)),
ConstantInt::get(cast<Type>(Type::getInt32Ty(ctx)), APInt(32, -42)));
ReplaceInstWithInst(oldAdd, newAdd);
If you just want to rip the instruction (and probably everything using it) out of the IR you replace do a RAUW with an UndefValue
like this:
oldAdd->replaceAllUsesWith(UndefValue::get(oldAdd->getType()));
oldAdd->eraseFromParent();
This will result in something like: store i32 undef, i32* %b, align 4
and may be removed by optimization passes.
If you want to remove the store as well you have to do it recursively through all users of the instructions:
void replaceAndErase(Instruction& I) {
for (auto& U : I.users()) {
replaceAndErase(*UI);
}
I.replaceAllUsesWith(UndefValue::get(I.getType()));
I.eraseFromParent();
}
However you can consider this function unsafe. It assumes that all users are Instructions. This can break if you have metadata referencing a instruction but you should get the idea.