源码路径
llvm\include\llvm\IR\Instruction.h
llvm\include\llvm\IR\Instruction.def
llvm\include\llvm\IR\Instructions.h
llvm\include\llvm\IR\InstrTypes.h
Other Operators
llvm中有部分指令不能简单地归类到某一类别下,这些指令被llvm归类到Other Operators。
ICmpInst(父类:CmpInst)
icmp返回比较两个操作数的结果。
语法
<result> = icmp <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
参数说明:
cond:比较的类型,包括:
eq
: 相等ne
: 不相等ugt
: 无符号大于uge
: 无符号大于等于ult
: 无符号小于ule
: 无符号小于等于sgt
: 有符号大于sge
: 有符号大于等于slt
: 有符号小于sle
: 有符号小于等于
ty:必须是整数,整数矢量,指针,指针矢量。
语义
icmp返回指定条件下,比较整数,整数矢量,指针,指针矢量的结果。
示例
<result> = icmp eq i32 4, 5 ; yields: result=false
<result> = icmp ne float* %X, %X ; yields: result=false
<result> = icmp ult i16 4, 5 ; yields: result=true
<result> = icmp sgt i16 4, 5 ; yields: result=false
<result> = icmp ule i16 -4, 5 ; yields: result=false
<result> = icmp sge i16 4, 5 ; yields: result=false
FCmpInst(父类:CmpInst)
fcmp指令返回比较两个操作数的结果。
语法
<result> = fcmp [fast-math flags]* <cond> <ty> <op1>, <op2> ; yields i1 or <N x i1>:result
参数说明:
fast-math flags(可选):使能不安全的浮点数优化。
ty:必须是浮点数或者浮点矢量。
cond:比较类型,包括:
false
: 总是返回falseoeq
: 有序且相等ogt
: 有序且大于oge
: 有序且大于等于olt
: 有序且小于ole
: 有序且小于等于one
: 有序且不相等ord
: 有序(no nans)ueq
: 无序或相等ugt
: 无序或大于uge
: 无序或大于等于ult
: 无序或小于ule
: 无序或小于等于une
: 无序或不等uno
: 无序true
: 总是返回true
语义
QNAN(Quiet No a Number):浮点数指数全部为1,尾数非0,表示这个值不是一个真正的值,通常表示未定义的算术运算结果(比如除0运算的结果)。
fcmp指令指定条件下,比较浮点数,浮点矢量的结果:
false
: 总是返回falseoeq
: op1和op2均不是QNAN且op1等于op2,
返回trueogt
: op1和op2均不是QNAN且op1大于op2,
返回trueoge
: op1和op2均不是QNAN且op1大于等于op2,
返回trueolt
: op1和op2均不是QNAN且op1小于op2,
返回trueole
: op1和op2均不是QNAN且op1小于等于op2,
返回trueone
: op1和op2均不是QNAN且op1不等于op2,
返回trueord
: op1和op2均不是QNAN,
返回trueueq
: op1或op2为QNAN,或者op1等于op2,
返回trueugt
: op1或op2为QNAN,或者op1大于op2,
返回trueuge
: op1或op2为QNAN,或者op1大于等于op2,
返回trueult
: op1或op2为QNAN,或者op1小于op2,
返回trueule
: op1或op2为QNAN,或者op1小于等于op2,
返回trueune
: op1或op2为QNAN,或者op1等于op2,
返回trueuno
: op1或op2为QNAN,返回truetrue
: 总是返回true
示例
<result> = fcmp oeq float 4.0, 5.0 ; yields: result=false
<result> = fcmp one float 4.0, 5.0 ; yields: result=true
<result> = fcmp olt float 4.0, 5.0 ; yields: result=true
<result> = fcmp ueq double 1.0, 2.0 ; yields: result=false
CallInst(父类:CallBase)
call指令表示简单的函数调用(和InvokeInst区分)。
语法
<result> = [tail | musttail | notail ] call [fast-math flags] [cconv] [ret attrs] [addrspace(<num>)] <ty>|<fnty> <fnptrval>(<function args>) [fn attrs] [ operand bundles ]
参数说明:
tail | musttail | nottail(可选):tail指示优化器可以进行尾调用优化,也可以忽略。musttail指示优化器必须进行尾调用优化,否则程序可能功能不正确。nottail指示优化器不进行尾调用优化。
注:尾调用优化是当父函数直接返回子函数的返回值时,可以进行的一种避免为子函数分配新栈帧的优化。最常见的是尾递归优化,可以使用常数大小的栈空间进行递归函数调用。
fast-math flags(可选):一组flag用于使能不安全的浮点优化。
cconv(可选):calling convention,call指令使用的调用约定,必须和被调用函数的调用约定相同,否则会产生未定义行为。常用的调用约定有:
- ccc:The C calling convention,是默认的调用约定。
fastcc:
The fast calling conventioncoldcc:
The cold calling conventioncc 10:
GHC conventioncc 11:
The HiPE calling conventionwebkit_jscc:
WebKit’s JavaScript calling convention.anyregcc:
Dynamic calling convention for code patchingpreserve_mostcc:
The PreserveMost calling conventionpreserve_allcc:
The PreserveAll calling conventioncxx_fast_tlscc:
The CXX_FAST_TLS calling convention for access functionstailcc:
Tail callable calling conventionswiftcc:
This calling convention is used for Swift language.swifttailcc:switfcc + tailcc
cfguard_checkcc:
Windows Control Flow Guard (Check mechanism)cc <n>:
target-specific calling conventions
ret attrs(可选):zeroext/signext/inreg。
addrspace(可选):调用函数的地址空间,如果不制定,使用datalayout中的程序地址空间。
ty:调用函数的返回值及call指令的返回值。
fnty:调用函数的签名。
fnptrval:调用函数的指针。
function args:和函数签名匹配的参数列表
fn attrs(可选):函数属性列表。
operand bundles(可选):参数的标签集。
语义
call指令将控制流转移到指定的函数,并传递对应的参数。当指定函数通过ret指令返回后,控制流返回到call指令的下一条指令,并且返回函数的返回值。
示例
%retval = call i32 @test(i32 %argc)
call i32 (i8*, ...)* @printf(i8* %msg, i32 12, i8 42) ; yields i32
%X = tail call i32 @foo() ; yields i32
%Y = tail call fastcc i32 @foo() ; yields i32
call void %foo(i8 signext 97)
%struct.A = type { i32, i8 }
%r = call %struct.A @foo() ; yields { i32, i8 }
%gr = extractvalue %struct.A %r, 0 ; yields i32
%gr1 = extractvalue %struct.A %r, 1 ; yields i8
%Z = call void @foo() noreturn ; indicates that %foo never returns normally
%ZZ = call zeroext i32 @bar() ; Return value is %zero extended
SelectInst(父类:Instruction)
select指令根据条件选择一个值,避免在IR中产生分支。
语法
<result> = select [fast-math flags] selty <cond>, <ty> <val1>, <ty> <val2> ; yields ty
selty is either i1 or {<N x i1>}
参数说明:
fast-math flags(可选):一系列标志,使能不安全的浮点优化。
selty:条件值的类型,只能是i1或者i1的矢量。
ty:如果是矢量,必须和selty的size相同。
语义
如果cond为true,则返回val1,否则返回val2。
示例
%X = select i1 true, i8 17, i8 42 ; yields i8:17
VAArgInst(父类:UnaryInstruction)
va_arg指令用于访问函数的变长参数。
语法
<resultval> = va_arg <va_list*> <arglist>, <argty>
va_list*:变长参数的类型,具体的类型是目标相关的。
arg_list:变长参数的值。
argty:要获取的下一个参数的类型。
语义
va_arg从va_list中获取一个指定类型的参数,并将va_list指向下一个参数。
示例
; This struct is different for every platform. For most platforms,
; it is merely an i8*.
%struct.va_list = type { i8* }
; For Unix x86_64 platforms, va_list is the following struct:
; %struct.va_list = type { i32, i32, i8*, i8* }
define i32 @test(i32 %X, ...) {
; Initialize variable argument processing
%ap = alloca %struct.va_list
%ap2 = bitcast %struct.va_list* %ap to i8*
call void @llvm.va_start(i8* %ap2)
; Read a single integer argument
%tmp = va_arg i8* %ap2, i32
; Demonstrate usage of llvm.va_copy and llvm.va_end
%aq = alloca i8*
%aq2 = bitcast i8** %aq to i8*
call void @llvm.va_copy(i8* %aq2, i8* %ap2)
call void @llvm.va_end(i8* %aq2)
; Stop processing of arguments.
call void @llvm.va_end(i8* %ap2)
ret i32 %tmp
}
declare void @llvm.va_start(i8*)
declare void @llvm.va_copy(i8*, i8*)
declare void @llvm.va_end(i8*)
FreezeInst(父类:UnaryInstruction)
freeze指令用于停止Undef和Poison Value的传播
语法
<result> = freeze ty <val> ; yields ty:result
语义
如果val是Undef或者Poison的,那么freeze指令会返回ty类型的任意固定值;否则什么都不做,直接返回val本身。
同一个freeze指令对所有Use返回相同的值,不同的freeze指令则可能返回不同的值。
指针freeze之后的值是一个不可解引用的指针。
聚合类型和矢量逐成员freeze,不包含Padding。
示例
%w = i32 undef
%x = freeze i32 %w
%y = add i32 %w, %w ; undef
%z = add i32 %x, %x ; even number because all uses of %x observe
; the same value
%x2 = freeze i32 %w
%cmp = icmp eq i32 %x, %x2 ; can be true or false
; example with vectors
%v = <2 x i32> <i32 undef, i32 poison>
%a = extractelement <2 x i32> %v, i32 0 ; undef
%b = extractelement <2 x i32> %v, i32 1 ; poison
%add = add i32 %a, %a ; undef
%v.fr = freeze <2 x i32> %v ; element-wise freeze
%d = extractelement <2 x i32> %v.fr, i32 0 ; not undef
%add.f = add i32 %d, %d ; even number
; branching on frozen value
%poison = add nsw i1 %k, undef ; poison
%c = freeze i1 %poison
br i1 %c, label %foo, label %bar ; non-deterministic branch to %foo or %bar