Code Generation Problem llvm 1.9

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 ] ; :30 [#uses=2]
%castPointerToLong10 = cast [10 x double]* %DataStore to long ; [#uses=1]
%pointerArithmetic11 = add long %castPointerToLong10, 0 ; [#uses=1]
%castPointerToLong9 = cast [10 x double]* %DataStore to long ; [#uses=1]
%pointerArithmetic10 = add long %castPointerToLong9, 40 ; [#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 ; [#uses=1]
%pointerArithmetic13 = add long %castPointerToLong12, 16 ; [#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 ; :31 [#uses=1]
frem double %31, 1.000000e+02 ; :32 [#uses=2]
%castPointerToLong15 = cast [10 x double]* %DataStore to long ; [#uses=1]
%pointerArithmetic16 = add long %castPointerToLong15, 24 ; [#uses=1]
%castLongToGV17 = cast long %pointerArithmetic16 to double* ; <double*> [#uses=1]
store double %32, double* %castLongToGV17
%castPointerToLong18 = cast [10 x double]* %DataStore to long ; [#uses=1]
%pointerArithmetic19 = add long %castPointerToLong18, 24 ; [#uses=1]
%castLongToGV20 = cast long %pointerArithmetic19 to double* ; <double*> [#uses=1]
load double* %castLongToGV20 ; :33 [#uses=1]
%castPointerToLong21 = cast [10 x double]* %DataStore to long ; [#uses=1]
%pointerArithmetic22 = add long %castPointerToLong21, 16 ; [#uses=1]
%castLongToGV23 = cast long %pointerArithmetic22 to double* ; <double*> [#uses=1]
load double* %castLongToGV23 ; :34 [#uses=1]
cast double %34 to int ; :9 [#uses=2]
seteq int %9, 0 ; :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
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
%ECX = MOV32r0
JNE mbb<bb.preheader.i271,0x8c55330>
Successors according to CFG: 0x8c55330 0x8c573b0

The gdb disassembler gives me the following lines for that basic block

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.


Ben Mayne

llvm 1.9 is fairly old. Please move to top of tree and try to reproduce the problem if possible.

Then please file a bugzilla report with reproducible test case and information about system configuration.