[LLVMdev] Issue with X86FrameLowering __chkstk on Windows 8 64-bit / Visual Studio 2012
Kévin Szkudlapski
szkudl.k at gmail.com
Mon Aug 19 12:21:54 PDT 2013
Hi,
I'm using LLVM to convert expressions to native assembly, the problem
is when LLVM compiles this code:
define void @fn_0000000000000000(i8*, i8*, i8*) {
bb:
%res = alloca i32
%3 = load i32* %res
%4 = bitcast i8* %0 to i32*
%5 = load i32* %4
%6 = bitcast i8* %0 to i32*
%7 = load i32* %6
%8 = xor i32 %5, %7
store volatile i32 %8, i32* %res
%9 = load i32* %res
%10 = icmp eq i32 %9, 0
br i1 %10, label %then, label %else
merged: ; preds = %else, %then
%11 = load i32* %res
%12 = and i32 %11, -2147483648
%13 = icmp eq i32 %12, 0
br i1 %13, label %then3, label %else4
then: ; preds = %bb
%zf = alloca i1
%14 = load i1* %zf
%15 = getelementptr i8* %0, i32 148
%16 = bitcast i8* %15 to i1*
%17 = load i1* %16
store volatile i1 true, i1* %16
br label %merged
else: ; preds = %bb
%zf1 = alloca i1
%18 = load i1* %zf1
%19 = getelementptr i8* %0, i32 148
%20 = bitcast i8* %19 to i1*
%21 = load i1* %20
store volatile i1 false, i1* %20
br label %merged
merged2: ; preds = %else4, %then3
%22 = bitcast i8* %0 to i32*
%23 = load i32* %22
%24 = load i32* %res
store volatile i32 %24, i32* %22
%af = alloca i1
%25 = load i1* %af
%26 = getelementptr i8* %0, i32 148
%27 = bitcast i8* %26 to i1*
%28 = load i1* %27
store volatile i1 false, i1* %27
%of = alloca i1
%29 = load i1* %of
%30 = getelementptr i8* %0, i32 148
%31 = bitcast i8* %30 to i1*
%32 = load i1* %31
store volatile i1 false, i1* %31
%cf = alloca i1
%33 = load i1* %cf
%34 = getelementptr i8* %0, i32 148
%35 = bitcast i8* %34 to i1*
%36 = load i1* %35
store volatile i1 false, i1* %35
%37 = getelementptr i8* %0, i32 64
%38 = bitcast i8* %37 to i32*
%39 = load i32* %38
%40 = getelementptr i8* %0, i32 64
%41 = bitcast i8* %40 to i32*
%42 = load i32* %41
%43 = add i32 %42, 2
store volatile i32 %43, i32* %38
ret void
then3: ; preds = %merged
%sf = alloca i1
%44 = load i1* %sf
%45 = getelementptr i8* %0, i32 148
%46 = bitcast i8* %45 to i1*
%47 = load i1* %46
store volatile i1 false, i1* %46
br label %merged2
else4: ; preds = %merged
%sf5 = alloca i1
%48 = load i1* %sf5
%49 = getelementptr i8* %0, i32 148
%50 = bitcast i8* %49 to i1*
%51 = load i1* %50
store volatile i1 true, i1* %50
br label %merged2
}
It generates the following assembly:
0000000581D30010 push rbp
0000000581D30011 mov rbp,rsp
0000000581D30014 sub rsp,10h
0000000581D30018 mov dword ptr [rbp-4],0
0000000581D3001F mov al,1
0000000581D30021 test al,al
0000000581D30023 jne 0000000581D30042
0000000581D30029 mov eax,10h
0000000581D3002E call 00000005F08425D0
0000000581D30033 sub rsp,rax
0000000581D30036 mov byte ptr [rcx+94h],0
0000000581D3003D jmp 0000000581D30056
0000000581D30042 mov eax,10h
0000000581D30047 call 00000005F08425D0
0000000581D3004C sub rsp,rax
0000000581D3004F mov byte ptr [rcx+94h],1
0000000581D30056 test byte ptr [rbp-1],80h
0000000581D3005A je 0000000581D30079
0000000581D30060 mov eax,10h
0000000581D30065 call 00000005F08425D0
0000000581D3006A sub rsp,rax
0000000581D3006D mov byte ptr [rcx+94h],1
0000000581D30074 jmp 0000000581D3008D
0000000581D30079 mov eax,10h
0000000581D3007E call 00000005F08425D0
0000000581D30083 sub rsp,rax
0000000581D30086 mov byte ptr [rcx+94h],0
0000000581D3008D mov eax,dword ptr [rbp-4]
0000000581D30090 mov dword ptr [rcx],eax
0000000581D30092 mov eax,10h
0000000581D30097 call 00000005F08425D0
0000000581D3009C sub rsp,rax
0000000581D3009F mov byte ptr [rcx+94h],0
0000000581D300A6 mov eax,10h
0000000581D300AB call 00000005F08425D0
0000000581D300B0 sub rsp,rax
0000000581D300B3 mov byte ptr [rcx+94h],0
0000000581D300BA mov eax,10h
0000000581D300BF call 00000005F08425D0
0000000581D300C4 sub rsp,rax
0000000581D300C7 mov byte ptr [rcx+94h],0
0000000581D300CE add dword ptr [rcx+40h],2
0000000581D300D2 mov rsp,rbp
0000000581D300D5 pop rbp
0000000581D300D6 ret
The function located at 0x00000005F08425D0 is not valid (according to
visual studio: 00000005F08425D0 ?? ??).
If I compile LLVM bytecode using llc, this function is __chkstk:
.def fn_0000000000000000;
.scl 2;
.type 32;
.endef
.text
.globl fn_0000000000000000
.align 16, 0x90
fn_0000000000000000: # @fn_0000000000000000
# BB#0: # %bb
push rbp
mov rbp, rsp
sub rsp, 16
mov dword ptr [rbp - 4], 0
mov al, 1
test al, al
jne .LBB0_1
# BB#2: # %else
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 0
jmp .LBB0_3
.LBB0_1: # %then
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 1
.LBB0_3: # %merged
test byte ptr [rbp - 1], -128
je .LBB0_4
# BB#5: # %else4
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 1
jmp .LBB0_6
.LBB0_4: # %then3
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 0
.LBB0_6: # %merged2
mov eax, dword ptr [rbp - 4]
mov dword ptr [rcx], eax
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 0
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 0
mov eax, 16
call __chkstk
sub rsp, rax
mov byte ptr [rcx + 148], 0
add dword ptr [rcx + 64], 2
mov rsp, rbp
pop rbp
ret
It seems this issue has already been described here
https://groups.google.com/forum/#!topic/llvm-commit/htNjwbWsNe8
I'm using this code
https://github.com/wisk/medusa/blob/master/src/emul/llvm/llvm_emulator.cpp
which is pretty basic.
Please, tell me if you need further information about this issue.
--
Kevin Szkudlapski
More information about the llvm-dev
mailing list