How to tell if LLVM Instruction has a Left-Hand Side
In general you can identify those instructions which cannot have a result assignment, but you cannot say if an instruction will result in an assignment, only that it might.
This is because you don't have to assign the result of an operation. For instance, the following line of code is valid in LLVM IR:
add nsw i32 %a, %b
but it's pointless because it has no effect whatsoever. No sane tool would emit that line, and even if emitted, it would be wiped away by the optimizer during dead code elimination. The only instruction for which ignoring the return value actually makes sense is call
. In fact, you might want to call a function only for side-effects, even when it's not declared void
. Think about printf
in C, whose return value is almost invariably ignored.
Because of this last consideration, you can assume that in practice all the instructions that can have a result assignment will have one, with the only exception of call
. invoke
is very similar to call
, so the same considerations made for the former apply.
As you might have noticed, whether an instruction results in an assignment depends on its class. With the help of llvm/IR/Instruction.def
, which contains the definition of all opcodes and classes, and the IR language reference, we can come up with the following subdivision:
Instruction classes that cannot have a result assignment:
ReturnInst
,BranchInst
,SwitchInst
,IndirectBrInst
,ResumeInst
,UnreachableInst
,CleanupReturnInst
,CatchReturnInst
StoreInst
,FenceInst
,AtomicRMWInst
,AtomicCmpXchgInst
Instruction classes that (might) have a result assignment:
CatchSwitchInst
BinaryOperator
AllocaInst
,LoadInst
,GetElementPtrInst
InvokeInst
,CatchSwitchInst
TruncInst
,ZExtInst
,SExtInst
,FPToUIInst
,FPToSIInst
,UIToFPInst
,SIToFPInst
,FPTruncInst
,FPExtInst
,PtrToIntInst
,IntToPtrInst
,BitCastInst
VAArgInst
CleanupPad
,CatchPad
ICmpInst
,FCmpInst
,PHINode
,SelectInst
ExtractElementInst
,ShuffleVectorInst
,ExtractValueInst
,InsertElementInst
,InsertValueInst
Instruction classes that might or might not have a result assignment:
CallInst
,InvokeInst
You can now build a switch
on the result of Instruction::getOpcode()
or, better, an 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; }
// ...
};
You can check whether the return type of the instruction is void
:
getType()->isVoidTy()