LLVM IR 中的“select”和“phi”有什么区别?

Evi*_*ian 8 llvm ssa llvm-ir

例如,我有一段C代码:

void foo(int x) {
    int y;
    if (x > 0) {
        y = 1;
    } else {
        y = 2;
    }
    // do something with y
}
Run Code Online (Sandbox Code Playgroud)

为了在 LLVM IR 级别简化此代码(y可以放入寄存器而不是堆栈中),我可以使用select

define void @foo(i32 %x) {
    %result = icmp sgt i32 %x, 0
    %y = select i1 %result, i32 1, i32 2
    ; do something with %y
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我使用phi,代码会变得更长:

define void @foo(i32 %x) {
    %result = icmp sgt i32 %x, 0
    br i1 %result, label %btrue, label %bfalse
btrue:
    br label %end
bfalse:
    br label %end
end:
    %y = phi i32 [1, %btrue], [2, %bfalse]
    ; do something with %y
    ret void
}
Run Code Online (Sandbox Code Playgroud)

据我所知,phiover唯一的优点selectphi支持2个以上分支,而同时select只支持2个分支。除了这种情况之外,还有没有其他phi更好的情况呢select

arr*_*owd 8

的操作数select仅为Values,而phi操作数为Valueand的对BasicBlock

另一个区别是它phi可以改变函数的控制流,而select只允许根据布尔值在两个值之间进行选择。粗略地说,select对应于?:三元运算符,在很多情况下phi对应于Cswitch语句。