eraseFromParent and stack dump

Hello,

I am creating a new instruction and I want to replace the use of a specified instruction.
This is the code I have written

Instruction *new_instr = BinaryOperator::Create(Instruction::Sub, op1, op2, "");
b->getInstList().insertAfter(old_instr, new_instr); //b is the BasicBlock
old_instr->replaceAllUsesWith(new_instr);
old_instr->eraseFromParent();

When I print the basic block, I see that my instruction was inserted and replaces the old instruction, however I get a stack dump, when I run the instrumented IR file.

0 opt 0x00000000014680df llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1 opt 0x000000000146835c
2 opt 0x0000000001467dd8
3 libpthread.so.0 0x00007f8934eecbb0
4 llfi-passes.so 0x00007f89340a39b2 llvm::Value::getValueID() const + 12
5 llfi-passes.so 0x00007f89340a3aa4 llvm::Instruction::getOpcode() const + 24
6 llfi-passes.so 0x00007f89340a331c llfi::FaultInjectionPass::locate_instruction(llvm::Module&, llvm::Function*, llvm::LoopInfo&, int) + 282
7 llfi-passes.so 0x00007f89340a2e50 llfi::FaultInjectionPass::finalize(llvm::Module&, int) + 506
8 llfi-passes.so 0x00007f89340a3509 llfi::FaultInjectionPass::runOnModule(llvm::Module&) + 113
9 opt 0x0000000001362a1e llvm::MPPassManager::runOnModule(llvm::Module&) + 502
10 opt 0x0000000001362fee llvm::PassManagerImpl::run(llvm::Module&) + 244
11 opt 0x00000000013631f9 llvm::PassManager::run(llvm::Module&) + 39
12 opt 0x00000000008719e8 main + 5698
13 libc.so.6 0x00007f8934318de5 __libc_start_main + 245
14 opt 0x0000000000863779
Stack dump:

I replace the uses of the old instruction, before deleting it. I am not sure why this is happening.
any suggestions?

Vasileios

Hello,

I am creating a new instruction and I want to replace the use of a specified instruction.
This is the code I have written

Instruction *new_instr = BinaryOperator::Create(Instruction::Sub, op1, op2, "");

As a matter of style, I'd use the version of BinaryOperator::Create() that takes an Instruction * as an insert point and use it to insert the new instruction *before* the old instruction. It shouldn't matter whether it goes before or after, and it avoids having to do a separate operation to insert the BinaryOperator into the basic block.

b->getInstList().insertAfter(old_instr, new_instr); //b is the BasicBlock
old_instr->replaceAllUsesWith(new_instr);
old_instr->eraseFromParent();

When I print the basic block, I see that my instruction was inserted and replaces the old instruction, however I get a stack dump, when I run the instrumented IR file.

0 opt 0x00000000014680df llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1 opt 0x000000000146835c
2 opt 0x0000000001467dd8
3 libpthread.so.0 0x00007f8934eecbb0
4 llfi-passes.so 0x00007f89340a39b2 llvm::Value::getValueID() const + 12
5 llfi-passes.so 0x00007f89340a3aa4 llvm::Instruction::getOpcode() const + 24
6 llfi-passes.so 0x00007f89340a331c llfi::FaultInjectionPass::locate_instruction(llvm::Module&, llvm::Function*, llvm::LoopInfo&, int) + 282
7 llfi-passes.so 0x00007f89340a2e50 llfi::FaultInjectionPass::finalize(llvm::Module&, int) + 506
8 llfi-passes.so 0x00007f89340a3509 llfi::FaultInjectionPass::runOnModule(llvm::Module&) + 113
9 opt 0x0000000001362a1e llvm::MPPassManager::runOnModule(llvm::Module&) + 502
10 opt 0x0000000001362fee llvm::PassManagerImpl::run(llvm::Module&) + 244
11 opt 0x00000000013631f9 llvm::PassManager::run(llvm::Module&) + 39
12 opt 0x00000000008719e8 main + 5698
13 libc.so.6 0x00007f8934318de5 __libc_start_main + 245
14 opt 0x0000000000863779
Stack dump:

I replace the uses of the old instruction, before deleting it. I am not sure why this is happening.
any suggestions?

I'm assuming that FaultInjectionPass is your code, correct?

If so, if you look at your stack dump, you'll see that it crashes calling Instruction::getOpcode() in the method locate_instruction() in your passes finalize() method.

I recommend finding the line in locate_instruction that is causing the problem. If it's one of the 4 lines you list at the top of this email, check that the old instruction pointer is non-NULL and points to an actual instruction.

You may also want to check and see if the old instruction is a phi-node. That might cause issues.

Finally, if you're building a FaultInjector pass, we built a very simple one for SAFECode that tries to create memory safety errors. You may or may not find it helpful for what you're doing.

Regards,

John Criswell

Indeed, it'd be helpful to know the contents of the function
locate_instruction().

Also, a quick suggestion: ensure the FaultInjectionPass doesn't have
any datastructures that are invalidated by your IR modifications,
in particular look for collections of llvm::Instruction* (or
llvm::Value*) that might be used in later code to reference
instructions you've erased. These datastructures are commonly used
for worklists and for mapping from LLVM constructs to analysis
information.

Otherwise a bit more detail on your code and workflow (you say you get
a crash when you run the IR--but the stack dump is from an LLVM
pass--is this part of some interpreter?) would likely help us sort out
your issue :).

Hope this helps,

~Will