llvmllvm-irssa

What is the difference between `select` and `phi` in LLVM IR?


For example, I have a C code:

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

To simplify this code in LLVM IR level (where y can be put in the register rather than stack), I can use select:

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

However, if I use phi, the code becomes much longer:

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
}

As far as I know, the only advantage of phi over select is that phi supports more than 2 branches, while select only supports 2 branches. Beyond this situation, is there any other situation where phi is better than select?


Solution

  • Operands of select are Values only, while phi operands are pairs of Value and BasicBlock.

    Another difference is that phi can turn the control flow of a function, while select only allows choosing between two values based on the boolean value. Roughly speaking, select corresponds to the ?: ternary operator, and phi corresponds to C switch statement with many cases.