Understanding llvm-ir to assembly for x86_64-unknown-linux-gnu

286 views Asked by At

I transform the following llvm-IR

; Function Attrs: noinline norecurse nounwind uwtable
define i32 @main() #0{
entry:
%sub = sub nsw i32 5, 3
%cmp = icmp slt i32 %sub, 3
br i1 %cmp, label %if.then, label %if.else

if.then:                                          ; preds = %entry
%mul = mul nsw i32 %sub, 2
br label %if.end

if.else:                                          ; preds = %entry
%sub1 = sub nsw i32 %sub, 3
br label %if.end

if.end:                                           ; preds = %if.else, 
%if.then
%y.0 = phi i32 [ %mul, %if.then ], [ %sub1, %if.else ]
%sub2 = sub nsw i32 %sub, %y.0
%add = add nsw i32 %sub, %y.0
ret i32 0
}

to assembly code for x86_64-unknown-linux-gnu using llc sample.ll generated assembly code:

    .text
    .file   "phi.cpp"
    .globl  main                    # -- Begin function main
    .p2align        4, 0x90
    .type   main,@function
main:                                   # @main
    .cfi_startproc
# BB#0:                                 # %entry
    pushq   %rbp
.Lcfi0:
    .cfi_def_cfa_offset 16
.Lcfi1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
.Lcfi2:
    .cfi_def_cfa_register %rbp
    xorl    %eax, %eax
    testb   %al, %al
    xorl    %eax, %eax
    popq    %rbp
    retq
.Lfunc_end0:
    .size   main, .Lfunc_end0-main
    .cfi_endproc
                                    # -- End function

The register in the above code: %rbp is the base pointer, which points to the base of the current stack frame, and %rsp is the stack pointer, which points to the top of the current stack frame and operand are store in %eax and %al for arithmatic operation but in can't find the instruction where the value is load in %eax and %al register I also want to know

  1. How llc is handling phi node on assembly level
1

There are 1 answers

0
arrowd On

lli defaults to -O2 and your code start with a constant expression sub nsw i32 5, 3. Thus, your function does, basically, nothing, and the only thing LLVM should keep is to nullify EAX.

If you run lli -O0 your.ll, you'll get much verbose code, that perform spills on stack and register loads.

BTW, there are a pair of passes called mem2reg and reg2mem that convert code back and forth code from SSA form. Specifically, these passes would convert phi nodes to branches and introduce explicit stores and loads in IR.