[LLVMdev] Code Generation Problem llvm 1.9
Ben Mayne
bmayne at 21technologies.com
Thu Dec 20 12:54:32 PST 2007
I sent a long message yesterday describing a problem I thought had to do with the JIT stubs.
After further investigating, the problem seems to be in the code generation.
The following basic block seems to have an error in it's code generation:
__exp.exit: ; preds = %codeRepl258, %__exp_bb_bb.exit
phi double [ 1.000000e+00, %codeRepl258 ], [ %.reload.reload.i, %__exp_bb_bb.exit ] ; <double>:30 [#uses=2]
%castPointerToLong10 = cast [10 x double]* %DataStore to long ; <long> [#uses=1]
%pointerArithmetic11 = add long %castPointerToLong10, 0 ; <long> [#uses=1]
%castPointerToLong9 = cast [10 x double]* %DataStore to long ; <long> [#uses=1]
%pointerArithmetic10 = add long %castPointerToLong9, 40 ; <long> [#uses=1]
%castLongToGV11 = cast long %pointerArithmetic10 to double* ; <double*> [#uses=1]
store double 7.000000e+00, double* %castLongToGV11
%castPointerToLong12 = cast [10 x double]* %DataStore to long ; <long> [#uses=1]
%pointerArithmetic13 = add long %castPointerToLong12, 16 ; <long> [#uses=1]
%tmp2.loc = alloca int ; <int*> [#uses=2]
%castLongToGV14 = cast long %pointerArithmetic13 to double* ; <double*> [#uses=1]
store double 2.000000e+00, double* %castLongToGV14
cast int %x to double ; <double>:31 [#uses=1]
frem double %31, 1.000000e+02 ; <double>:32 [#uses=2]
%castPointerToLong15 = cast [10 x double]* %DataStore to long ; <long> [#uses=1]
%pointerArithmetic16 = add long %castPointerToLong15, 24 ; <long> [#uses=1]
%castLongToGV17 = cast long %pointerArithmetic16 to double* ; <double*> [#uses=1]
store double %32, double* %castLongToGV17
%castPointerToLong18 = cast [10 x double]* %DataStore to long ; <long> [#uses=1]
%pointerArithmetic19 = add long %castPointerToLong18, 24 ; <long> [#uses=1]
%castLongToGV20 = cast long %pointerArithmetic19 to double* ; <double*> [#uses=1]
load double* %castLongToGV20 ; <double>:33 [#uses=1]
%castPointerToLong21 = cast [10 x double]* %DataStore to long ; <long> [#uses=1]
%pointerArithmetic22 = add long %castPointerToLong21, 16 ; <long> [#uses=1]
%castLongToGV23 = cast long %pointerArithmetic22 to double* ; <double*> [#uses=1]
load double* %castLongToGV23 ; <double>:34 [#uses=1]
cast double %34 to int ; <int>:9 [#uses=2]
seteq int %9, 0 ; <bool>:7 [#uses=1]
br bool %7, label %entry.bb19_crit_edge.i270, label %bb.preheader.i271
It gets converted to the following MachineBasicBlock
__exp.exit (0x8c58628, LLVM BB @0x8c1c558, ID#21):
Predecessors according to CFG: 0x8c53a90 0x8c55b50
MOV32mi %EBP, 1, %NOREG, -224, <ga:DataStore>
%EAX = MOV32rm %EBP, 1, %NOREG, -224
%EAX = ADD32ri8 %EAX, 40
MOV32mi %EAX, 1, %NOREG, 0, 0
MOV32mi %EAX, 1, %NOREG, 4, 1075576832
%ESP = SUB32ri %ESP, 16
%XMM0 = CVTSI2SDrr %EDI
MOVSDmr %ESP, 1, %NOREG, 0, %XMM0
MOV32mr %EBP, 1, %NOREG, -268, %ESP
ADD32mi8 %EBP, 1, %NOREG, -268, 4294967288
%ESP = MOV32rm %EBP, 1, %NOREG, -268
%ESI = MOV32rm %EBP, 1, %NOREG, -224
%ESI = ADD32ri8 %ESI, 16
MOV32mi %ESI, 1, %NOREG, 0, 0
MOV32mi %ESI, 1, %NOREG, 4, 1073741824
MOV32mi %ESP, 1, %NOREG, 12, 1079574528
MOV32mi %ESP, 1, %NOREG, 8, 0
CALLpcrel32 <es:fmod>
%ESP = ADD32ri8 %ESP, 16
FSTP64m %EBP, 1, %NOREG, -160
%EAX = MOV32rm %EBP, 1, %NOREG, -224
%EAX = ADD32ri8 %EAX, 24
%XMM0 = MOVSDrm %EBP, 1, %NOREG, -160
MOVSDmr %EBP, 1, %NOREG, -232, %XMM0
MOVSDmr %EAX, 1, %NOREG, 0, %XMM0
%EAX = CVTTSD2SIrm %ESI, 1, %NOREG, 0
%ECX = MOV32r0
TEST32rr %EAX, %EAX
JNE mbb<bb.preheader.i271,0x8c55330>
Successors according to CFG: 0x8c55330 0x8c573b0
The gdb disassembler gives me the following lines for that basic block
__exp.exit:
0xf5f6f317: movl $0xa542b70,0xffffff20(%ebp)
0xf5f6f321: mov 0xffffff20(%ebp),%eax
0xf5f6f327: add $0x28,%eax
0xf5f6f32a: movl $0x0,(%eax)
0xf5f6f330: movl $0x401c0000,0x4(%eax)
0xf5f6f337: sub $0x10,%esp
0xf5f6f33d: cvtsi2sd %edi,%xmm0
0xf5f6f341: movsd %xmm0,(%esp)
0xf5f6f346: mov %esp,0xfffffef4(%ebp)
0xf5f6f34c: addl $0xfffffff8,0xfffffef4(%ebp)
0xf5f6f353: mov 0xfffffef4(%ebp),%esp
0xf5f6f359: mov 0xffffff20(%ebp),%esi
0xf5f6f35f: add $0x10,%esi
0xf5f6f362: movl $0x0,(%esi)
0xf5f6f368: movl $0x40000000,0x4(%esi)
0xf5f6f36f: movl $0x40590000,0xc(%esp)
0xf5f6f377: movl $0x0,0x8(%esp)
0xf5f6f37f: call 0xf5f6effb
0xf5f6f384: add $0x10,%esp
0xf5f6f387: fstpl 0xffffff60(%ebp)
0xf5f6f38d: mov 0xffffff20(%ebp),%eax
0xf5f6f393: add $0x18,%eax
0xf5f6f396: movsd 0xffffff60(%ebp),%xmm0
0xf5f6f39e: movsd %xmm0,0xffffff18(%ebp)
0xf5f6f3a6: movsd %xmm0,(%eax)
0xf5f6f3aa: cvttsd2si (%esi),%eax
0xf5f6f3ae: xor %ecx,%ecx
0xf5f6f3b0: test %eax,%eax
0xf5f6f3b2: jne 0xf5f6f3c5
The problem I'm seeing is that the generated code for the "%tmp2.loc = alloca int" instruction seems to get placed in the middle of
the generated code for the "frem double %31, 1.000000e+02" instruction. The generated code for the frem call subtracts 16 from the stack to
prepare for the insertion of arguments onto the stack. However, before it insert the arguments on the stack, it allocates space for tmp2.loc.
Therefore the stack essentially gets subtracted by 10 more. Then the arguments are placed on, the call is made, and upon return, 16 is added to
the stack. Basically, after the call, the stack doesn't go back to the state it was in before the call because the alloca snuck in between
the instructions. Now, tmp2.loc is sitting in memory past the stack pointer which can potentially be overwritten by a future call and in the example
I sent yesterday, it does get overwritten.
Thanks,
Ben Mayne
x245
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20071220/a2102e29/attachment.html>
More information about the llvm-dev
mailing list