<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7652.24">
<TITLE>Code Generation Problem llvm 1.9</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>I sent a long message yesterday describing a problem I thought had to do with the JIT stubs.<BR>
After further investigating, the problem seems to be in the code generation.<BR>
<BR>
The following basic block seems to have an error in it's code generation:<BR>
<BR>
__exp.exit:             ; preds = %codeRepl258, %__exp_bb_bb.exit<BR>
        phi double [ 1.000000e+00, %codeRepl258 ], [ %.reload.reload.i, %__exp_bb_bb.exit ]             ; <double>:30 [#uses=2]<BR>
        %castPointerToLong10 = cast [10 x double]* %DataStore to long           ; <long> [#uses=1]<BR>
        %pointerArithmetic11 = add long %castPointerToLong10, 0         ; <long> [#uses=1]<BR>
        %castPointerToLong9 = cast [10 x double]* %DataStore to long            ; <long> [#uses=1]<BR>
        %pointerArithmetic10 = add long %castPointerToLong9, 40         ; <long> [#uses=1]<BR>
        %castLongToGV11 = cast long %pointerArithmetic10 to double*             ; <double*> [#uses=1]<BR>
        store double 7.000000e+00, double* %castLongToGV11<BR>
        %castPointerToLong12 = cast [10 x double]* %DataStore to long           ; <long> [#uses=1]<BR>
        %pointerArithmetic13 = add long %castPointerToLong12, 16                ; <long> [#uses=1]<BR>
        %tmp2.loc = alloca int          ; <int*> [#uses=2]<BR>
        %castLongToGV14 = cast long %pointerArithmetic13 to double*             ; <double*> [#uses=1]<BR>
        store double 2.000000e+00, double* %castLongToGV14<BR>
        cast int %x to double           ; <double>:31 [#uses=1]<BR>
        frem double %31, 1.000000e+02           ; <double>:32 [#uses=2]<BR>
        %castPointerToLong15 = cast [10 x double]* %DataStore to long           ; <long> [#uses=1]<BR>
        %pointerArithmetic16 = add long %castPointerToLong15, 24                ; <long> [#uses=1]<BR>
        %castLongToGV17 = cast long %pointerArithmetic16 to double*             ; <double*> [#uses=1]<BR>
        store double %32, double* %castLongToGV17<BR>
        %castPointerToLong18 = cast [10 x double]* %DataStore to long           ; <long> [#uses=1]<BR>
        %pointerArithmetic19 = add long %castPointerToLong18, 24                ; <long> [#uses=1]<BR>
        %castLongToGV20 = cast long %pointerArithmetic19 to double*             ; <double*> [#uses=1]<BR>
        load double* %castLongToGV20            ; <double>:33 [#uses=1]<BR>
        %castPointerToLong21 = cast [10 x double]* %DataStore to long           ; <long> [#uses=1]<BR>
        %pointerArithmetic22 = add long %castPointerToLong21, 16                ; <long> [#uses=1]<BR>
        %castLongToGV23 = cast long %pointerArithmetic22 to double*             ; <double*> [#uses=1]<BR>
        load double* %castLongToGV23            ; <double>:34 [#uses=1]<BR>
        cast double %34 to int          ; <int>:9 [#uses=2]<BR>
        seteq int %9, 0         ; <bool>:7 [#uses=1]<BR>
        br bool %7, label %entry.bb19_crit_edge.i270, label %bb.preheader.i271<BR>
<BR>
It gets converted to the following MachineBasicBlock<BR>
__exp.exit (0x8c58628, LLVM BB @0x8c1c558, ID#21):<BR>
    Predecessors according to CFG: 0x8c53a90 0x8c55b50<BR>
        MOV32mi %EBP, 1, %NOREG, -224, <ga:DataStore><BR>
        %EAX = MOV32rm %EBP, 1, %NOREG, -224<BR>
        %EAX = ADD32ri8 %EAX, 40<BR>
        MOV32mi %EAX, 1, %NOREG, 0, 0<BR>
        MOV32mi %EAX, 1, %NOREG, 4, 1075576832<BR>
        %ESP = SUB32ri %ESP, 16<BR>
        %XMM0 = CVTSI2SDrr %EDI<BR>
        MOVSDmr %ESP, 1, %NOREG, 0, %XMM0<BR>
        MOV32mr %EBP, 1, %NOREG, -268, %ESP<BR>
        ADD32mi8 %EBP, 1, %NOREG, -268, 4294967288<BR>
        %ESP = MOV32rm %EBP, 1, %NOREG, -268<BR>
        %ESI = MOV32rm %EBP, 1, %NOREG, -224<BR>
        %ESI = ADD32ri8 %ESI, 16<BR>
        MOV32mi %ESI, 1, %NOREG, 0, 0<BR>
        MOV32mi %ESI, 1, %NOREG, 4, 1073741824<BR>
        MOV32mi %ESP, 1, %NOREG, 12, 1079574528<BR>
        MOV32mi %ESP, 1, %NOREG, 8, 0<BR>
        CALLpcrel32 <es:fmod><BR>
        %ESP = ADD32ri8 %ESP, 16<BR>
        FSTP64m %EBP, 1, %NOREG, -160<BR>
        %EAX = MOV32rm %EBP, 1, %NOREG, -224<BR>
        %EAX = ADD32ri8 %EAX, 24<BR>
        %XMM0 = MOVSDrm %EBP, 1, %NOREG, -160<BR>
        MOVSDmr %EBP, 1, %NOREG, -232, %XMM0<BR>
        MOVSDmr %EAX, 1, %NOREG, 0, %XMM0<BR>
        %EAX = CVTTSD2SIrm %ESI, 1, %NOREG, 0<BR>
        %ECX = MOV32r0<BR>
        TEST32rr %EAX, %EAX<BR>
        JNE mbb<bb.preheader.i271,0x8c55330><BR>
    Successors according to CFG: 0x8c55330 0x8c573b0<BR>
<BR>
The gdb disassembler gives me the following lines for that basic block<BR>
<BR>
__exp.exit:<BR>
0xf5f6f317:     movl   $0xa542b70,0xffffff20(%ebp)<BR>
0xf5f6f321:     mov    0xffffff20(%ebp),%eax<BR>
0xf5f6f327:     add    $0x28,%eax<BR>
0xf5f6f32a:     movl   $0x0,(%eax)<BR>
0xf5f6f330:     movl   $0x401c0000,0x4(%eax)<BR>
0xf5f6f337:     sub    $0x10,%esp<BR>
0xf5f6f33d:     cvtsi2sd %edi,%xmm0<BR>
0xf5f6f341:     movsd  %xmm0,(%esp)<BR>
0xf5f6f346:     mov    %esp,0xfffffef4(%ebp)<BR>
0xf5f6f34c:     addl   $0xfffffff8,0xfffffef4(%ebp)<BR>
0xf5f6f353:     mov    0xfffffef4(%ebp),%esp<BR>
0xf5f6f359:     mov    0xffffff20(%ebp),%esi<BR>
0xf5f6f35f:     add    $0x10,%esi<BR>
0xf5f6f362:     movl   $0x0,(%esi)<BR>
0xf5f6f368:     movl   $0x40000000,0x4(%esi)<BR>
0xf5f6f36f:     movl   $0x40590000,0xc(%esp)<BR>
0xf5f6f377:     movl   $0x0,0x8(%esp)<BR>
0xf5f6f37f:     call   0xf5f6effb<BR>
0xf5f6f384:     add    $0x10,%esp<BR>
0xf5f6f387:     fstpl  0xffffff60(%ebp)<BR>
0xf5f6f38d:     mov    0xffffff20(%ebp),%eax<BR>
0xf5f6f393:     add    $0x18,%eax<BR>
0xf5f6f396:     movsd  0xffffff60(%ebp),%xmm0<BR>
0xf5f6f39e:     movsd  %xmm0,0xffffff18(%ebp)<BR>
0xf5f6f3a6:     movsd  %xmm0,(%eax)<BR>
0xf5f6f3aa:     cvttsd2si (%esi),%eax<BR>
0xf5f6f3ae:     xor    %ecx,%ecx<BR>
0xf5f6f3b0:     test   %eax,%eax<BR>
0xf5f6f3b2:     jne    0xf5f6f3c5<BR>
<BR>
<BR>
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<BR>
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<BR>
prepare for the insertion of arguments onto the stack.  However, before it insert the arguments on the stack, it allocates space for tmp2.loc.<BR>
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<BR>
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<BR>
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<BR>
I sent yesterday, it does get overwritten.<BR>
<BR>
Thanks,<BR>
<BR>
Ben Mayne<BR>
x245<BR>
<BR>
</FONT>
</P>

</BODY>
</HTML>