In general, you can define those instructions that cannot have a result assignment, but you cannot say whether the instruction will result in assignment, only so that it can.
This is because you do not need to assign the result of the operation. For example, the following line of code is valid in LLVM IR:
add nsw i32 %a, %b
but it is pointless because it has no effect. No sane tool would have emitted this line, and even if it had been emitted, it would have been destroyed by the optimizer while eliminating dead code. The only instruction for which ignoring the return value makes sense is call . In fact, you can only call a function for side effects, even if it is not declared void. Think of printf in C, whose return value is almost always ignored.
Due to this last consideration, you can assume that in practice all instructions that may have a result assignment will have one, with the exception of call . invoke very similar to call , so the same considerations apply as for the former.
As you can see, whether the execution of a command depends on assignment depends on its class. Using llvm/IR/Instruction.def , which contains a definition of all opcodes and classes and a link to the IR language , we can find the following subdivision:
Classes of instructions that cannot have a result assignment:
ReturnInst , BranchInst , SwitchInst , IndirectBrInst , ResumeInst , UnreachableInst , CleanupReturnInst , CatchReturnInstStoreInst , FenceInst , AtomicRMWInst , AtomicCmpXchgInst
Classes of teams that (may) have a result assignment:
CatchSwitchInstBinaryOperatorAllocaInst , LoadInst , GetElementPtrInstInvokeInst , CatchSwitchInstTruncInst , ZExtInst , SExtInst , FPToUIInst , FPToSIInst , UIToFPInst , SIToFPInst , FPTruncInst , FPExtInst , PtrToIntInst , IntToPtrInst , BitCastInstVAArgInstCleanupPad , CatchPadICmpInst , FCmpInst , PHINode , SelectInstExtractElementInst , ShuffleVectorInst , ExtractValueInst , InsertElementInst , InsertElementInst
Classes of instructions that may or may not have a result assignment:
Now you can build a switch based on the result of Instruction::getOpcode() or, better, InstVisitor to classify instructions:
#include <llvm/IR/InstVisitor.h> enum HaveRetVal { DEFINITELY_NOT, MAYBE, PROBABLY_YES }; class HaveRetAssignment : public InstVisitor<HaveRetAssignment, HaveRetVal> { public: HaveRetVal visitBinaryOperator(BinaryOperator &) { return PROBABLY_YES; } // ... HaveRetVal visitCallInst(CallInst&) { return MAYBE; } // ... HaveRetVal visitBranchInst(BranchInst&) { return DEFINITELY_NOT; } // ... };