Here is my program in its entirety; I'm using a silly recursive algorithm to familiarize myself with LLVM assembly:
declare void @print_int(i32)
define i32 @rec_add(i32 %a, i32 %b) {
entry:
%tmp1 = icmp eq i32 %a, 0
br i1 %tmp1, label %done, label %recurse
recurse:
%tmp2 = sub i32 %a, 1
%tmp3 = add i32 %b, 1
ret i32 @rec_add(i32 %tmp2, i32 %tmp3)
done:
ret i32 %b
}
define i32 @main() {
%tmp4 = i32 4;
%tmp5 = i32 1;
%cast = call i32 @rec_add(i32 %tmp4, i32 %tmp5)
call void @print_int(i32 %cast)
}
When I compile this program with $ llvm-as rec_add.ll
, I receive this error message:
llvm-as: rec_add.ll:10:11: error: global variable reference must have pointer type
ret i32 @rec_add(i32 %tmp2, i32 %tmp3)
^
I do not understand what this error message means, because my program has no global variables. And I know for a fact that LLVM assembly does not require pointers as its arguments.
I didn't even know llvm-as existed, but assigning the recursive call result to a variable worked. Then return that. This optimizes away even at -O0
. See Oak's answer/comments for correct terminology.
define i32 @rec_add(i32 %a, i32 %b) {
entry:
%tmp1 = icmp eq i32 %a, 0
br i1 %tmp1, label %done, label %recurse
recurse:
%tmp2 = sub i32 %a, 1
%tmp3 = add i32 %b, 1
%tmp4 = call i32 @rec_add(i32 %tmp2, i32 %tmp3)
ret i32 %tmp4
done:
ret i32 %b
}
compiles to a recursive call with clang-3.8 -O0 -S -o-
.
With clang-3.8 -Wall -O3 rec-add.ll -S -masm=intel -o-
, llvm sees through the recursion:
rec_add: # @rec_add
# BB#0: # %entry
lea eax, [rdi + rsi]
ret
Your main
doesn't compile:
rec-add.ll:17:13: error: expected instruction opcode
%tmp4 = i32 4;
This does the trick:
define i32 @main() {
%cast = call i32 @rec_add(i32 4, i32 1)
call void @print_int(i32 %cast)
ret i32 0
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments