<div dir="ltr">It's not a solution to the actual bug (which is, as the thread you linked discusses, a problem with the assumption on LLVM's part that the __chkstk function lies within 2GB of the emitted code's address space) but there is a simple workaround: hoist all allocas to the first basic block of your function. This allows the JIT to perform all stack allocations in a single adjustment of the SP instead of needing to use dynamic stack allocation, and thereby avoids the call to __chkstk entirely.</div>
<div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 19, 2013 at 12:21 PM, Kévin Szkudlapski <span dir="ltr"><<a href="mailto:szkudl.k@gmail.com" target="_blank">szkudl.k@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
I'm using LLVM to convert expressions to native assembly, the problem<br>
is when LLVM compiles this code:<br>
<br>
define void @fn_0000000000000000(i8*, i8*, i8*) {<br>
bb:<br>
%res = alloca i32<br>
%3 = load i32* %res<br>
%4 = bitcast i8* %0 to i32*<br>
%5 = load i32* %4<br>
%6 = bitcast i8* %0 to i32*<br>
%7 = load i32* %6<br>
%8 = xor i32 %5, %7<br>
store volatile i32 %8, i32* %res<br>
%9 = load i32* %res<br>
%10 = icmp eq i32 %9, 0<br>
br i1 %10, label %then, label %else<br>
<br>
merged: ; preds = %else, %then<br>
%11 = load i32* %res<br>
%12 = and i32 %11, -2147483648<br>
%13 = icmp eq i32 %12, 0<br>
br i1 %13, label %then3, label %else4<br>
<br>
then: ; preds = %bb<br>
%zf = alloca i1<br>
%14 = load i1* %zf<br>
%15 = getelementptr i8* %0, i32 148<br>
%16 = bitcast i8* %15 to i1*<br>
%17 = load i1* %16<br>
store volatile i1 true, i1* %16<br>
br label %merged<br>
<br>
else: ; preds = %bb<br>
%zf1 = alloca i1<br>
%18 = load i1* %zf1<br>
%19 = getelementptr i8* %0, i32 148<br>
%20 = bitcast i8* %19 to i1*<br>
%21 = load i1* %20<br>
store volatile i1 false, i1* %20<br>
br label %merged<br>
<br>
merged2: ; preds = %else4, %then3<br>
%22 = bitcast i8* %0 to i32*<br>
%23 = load i32* %22<br>
%24 = load i32* %res<br>
store volatile i32 %24, i32* %22<br>
%af = alloca i1<br>
%25 = load i1* %af<br>
%26 = getelementptr i8* %0, i32 148<br>
%27 = bitcast i8* %26 to i1*<br>
%28 = load i1* %27<br>
store volatile i1 false, i1* %27<br>
%of = alloca i1<br>
%29 = load i1* %of<br>
%30 = getelementptr i8* %0, i32 148<br>
%31 = bitcast i8* %30 to i1*<br>
%32 = load i1* %31<br>
store volatile i1 false, i1* %31<br>
%cf = alloca i1<br>
%33 = load i1* %cf<br>
%34 = getelementptr i8* %0, i32 148<br>
%35 = bitcast i8* %34 to i1*<br>
%36 = load i1* %35<br>
store volatile i1 false, i1* %35<br>
%37 = getelementptr i8* %0, i32 64<br>
%38 = bitcast i8* %37 to i32*<br>
%39 = load i32* %38<br>
%40 = getelementptr i8* %0, i32 64<br>
%41 = bitcast i8* %40 to i32*<br>
%42 = load i32* %41<br>
%43 = add i32 %42, 2<br>
store volatile i32 %43, i32* %38<br>
ret void<br>
<br>
then3: ; preds = %merged<br>
%sf = alloca i1<br>
%44 = load i1* %sf<br>
%45 = getelementptr i8* %0, i32 148<br>
%46 = bitcast i8* %45 to i1*<br>
%47 = load i1* %46<br>
store volatile i1 false, i1* %46<br>
br label %merged2<br>
<br>
else4: ; preds = %merged<br>
%sf5 = alloca i1<br>
%48 = load i1* %sf5<br>
%49 = getelementptr i8* %0, i32 148<br>
%50 = bitcast i8* %49 to i1*<br>
%51 = load i1* %50<br>
store volatile i1 true, i1* %50<br>
br label %merged2<br>
}<br>
<br>
<br>
It generates the following assembly:<br>
0000000581D30010 push rbp<br>
0000000581D30011 mov rbp,rsp<br>
0000000581D30014 sub rsp,10h<br>
0000000581D30018 mov dword ptr [rbp-4],0<br>
0000000581D3001F mov al,1<br>
0000000581D30021 test al,al<br>
0000000581D30023 jne 0000000581D30042<br>
0000000581D30029 mov eax,10h<br>
0000000581D3002E call 00000005F08425D0<br>
0000000581D30033 sub rsp,rax<br>
0000000581D30036 mov byte ptr [rcx+94h],0<br>
0000000581D3003D jmp 0000000581D30056<br>
0000000581D30042 mov eax,10h<br>
0000000581D30047 call 00000005F08425D0<br>
0000000581D3004C sub rsp,rax<br>
0000000581D3004F mov byte ptr [rcx+94h],1<br>
0000000581D30056 test byte ptr [rbp-1],80h<br>
0000000581D3005A je 0000000581D30079<br>
0000000581D30060 mov eax,10h<br>
0000000581D30065 call 00000005F08425D0<br>
0000000581D3006A sub rsp,rax<br>
0000000581D3006D mov byte ptr [rcx+94h],1<br>
0000000581D30074 jmp 0000000581D3008D<br>
0000000581D30079 mov eax,10h<br>
0000000581D3007E call 00000005F08425D0<br>
0000000581D30083 sub rsp,rax<br>
0000000581D30086 mov byte ptr [rcx+94h],0<br>
0000000581D3008D mov eax,dword ptr [rbp-4]<br>
0000000581D30090 mov dword ptr [rcx],eax<br>
0000000581D30092 mov eax,10h<br>
0000000581D30097 call 00000005F08425D0<br>
0000000581D3009C sub rsp,rax<br>
0000000581D3009F mov byte ptr [rcx+94h],0<br>
0000000581D300A6 mov eax,10h<br>
0000000581D300AB call 00000005F08425D0<br>
0000000581D300B0 sub rsp,rax<br>
0000000581D300B3 mov byte ptr [rcx+94h],0<br>
0000000581D300BA mov eax,10h<br>
0000000581D300BF call 00000005F08425D0<br>
0000000581D300C4 sub rsp,rax<br>
0000000581D300C7 mov byte ptr [rcx+94h],0<br>
0000000581D300CE add dword ptr [rcx+40h],2<br>
0000000581D300D2 mov rsp,rbp<br>
0000000581D300D5 pop rbp<br>
0000000581D300D6 ret<br>
<br>
The function located at 0x00000005F08425D0 is not valid (according to<br>
visual studio: 00000005F08425D0 ?? ??).<br>
<br>
If I compile LLVM bytecode using llc, this function is __chkstk:<br>
.def fn_0000000000000000;<br>
.scl 2;<br>
.type 32;<br>
.endef<br>
.text<br>
.globl fn_0000000000000000<br>
.align 16, 0x90<br>
fn_0000000000000000: # @fn_0000000000000000<br>
# BB#0: # %bb<br>
push rbp<br>
mov rbp, rsp<br>
sub rsp, 16<br>
mov dword ptr [rbp - 4], 0<br>
mov al, 1<br>
test al, al<br>
jne .LBB0_1<br>
# BB#2: # %else<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 0<br>
jmp .LBB0_3<br>
.LBB0_1: # %then<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 1<br>
.LBB0_3: # %merged<br>
test byte ptr [rbp - 1], -128<br>
je .LBB0_4<br>
# BB#5: # %else4<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 1<br>
jmp .LBB0_6<br>
.LBB0_4: # %then3<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 0<br>
.LBB0_6: # %merged2<br>
mov eax, dword ptr [rbp - 4]<br>
mov dword ptr [rcx], eax<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 0<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 0<br>
mov eax, 16<br>
call __chkstk<br>
sub rsp, rax<br>
mov byte ptr [rcx + 148], 0<br>
add dword ptr [rcx + 64], 2<br>
mov rsp, rbp<br>
pop rbp<br>
ret<br>
<br>
It seems this issue has already been described here<br>
<a href="https://groups.google.com/forum/#!topic/llvm-commit/htNjwbWsNe8" target="_blank">https://groups.google.com/forum/#!topic/llvm-commit/htNjwbWsNe8</a><br>
<br>
I'm using this code<br>
<a href="https://github.com/wisk/medusa/blob/master/src/emul/llvm/llvm_emulator.cpp" target="_blank">https://github.com/wisk/medusa/blob/master/src/emul/llvm/llvm_emulator.cpp</a><br>
which is pretty basic.<br>
<br>
Please, tell me if you need further information about this issue.<br>
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Kevin Szkudlapski<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
</font></span></blockquote></div><br></div>