llvm libLLVMCore源码分析 13 - Other Operators

源码路径

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:比较类型,包括:

  1. false: 总是返回false
  2. oeq: 有序且相等
  3. ogt: 有序且大于
  4. oge: 有序且大于等于
  5. olt: 有序且小于
  6. ole: 有序且小于等于
  7. one: 有序且不相等
  8. ord: 有序(no nans)
  9. ueq: 无序或相等
  10. ugt: 无序或大于
  11. uge: 无序或大于等于
  12. ult: 无序或小于
  13. ule: 无序或小于等于
  14. une: 无序或不等
  15. uno: 无序
  16. true: 总是返回true

语义

QNAN(Quiet No a Number):浮点数指数全部为1,尾数非0,表示这个值不是一个真正的值,通常表示未定义的算术运算结果(比如除0运算的结果)。

fcmp指令指定条件下,比较浮点数,浮点矢量的结果:

  1. false: 总是返回false
  2. oeq: op1和op2均不是QNAN且op1等于op2,返回true
  3. ogt: op1和op2均不是QNAN且op1大于op2,返回true
  4. oge: op1和op2均不是QNAN且op1大于等于op2,返回true
  5. olt: op1和op2均不是QNAN且op1小于op2,返回true
  6. ole: op1和op2均不是QNAN且op1小于等于op2,返回true
  7. one: op1和op2均不是QNAN且op1不等于op2,返回true
  8. ord: op1和op2均不是QNAN返回true
  9. ueq: op1或op2为QNAN,或者op1等于op2返回true
  10. ugt: op1或op2为QNAN,或者op1大于op2返回true
  11. uge: op1或op2为QNAN,或者op1大于等于op2返回true
  12. ult: op1或op2为QNAN,或者op1小于op2返回true
  13. ule: op1或op2为QNAN,或者op1小于等于op2返回true
  14. une: op1或op2为QNAN,或者op1等于op2返回true
  15. uno: op1或op2为QNAN,返回true
  16. true: 总是返回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 convention
  • coldcc:The cold calling convention
  • cc 10:GHC convention
  • cc 11:The HiPE calling convention
  • webkit_jscc:WebKit’s JavaScript calling convention.
  • anyregcc:Dynamic calling convention for code patching
  • preserve_mostcc:The PreserveMost calling convention
  • preserve_allcc:The PreserveAll calling convention
  • cxx_fast_tlscc:The CXX_FAST_TLS calling convention for access functions
  • tailcc:Tail callable calling convention
  • swiftcc: 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值