<div>I've spent the better part of a day trying to figure out why my generated assembly code isn't correct. Here is the IR code for my loop:</div><div><br></div><div><div>loopbody2:                                        ; preds = %test1</div>
<div>  %i14 = load i32* %i5                            ; <i32> [#uses=1]</div><div>  %get15 = call %tart.core.String* @"tart.core.Array[tart.core.String]..index.get(int)->tart.core.String"(%"tart.core.Array[tart.core.String]"* %s, i32 %i14) ; <%tart.core.String*> [#uses=3]</div>
<div>  %src.data = getelementptr %tart.core.String* %get15, i32 0, i32 4 ; <[0 x i8]*> [#uses=1]</div><div>  %result.data = getelementptr %tart.core.String* %alloc, i32 0, i32 4 ; <[0 x i8]*> [#uses=1]</div><div>
  %index16 = load i32* %index                     ; <i32> [#uses=1]</div><div>  %src.length = getelementptr %tart.core.String* %get15, i32 0, i32 1 ; <i32*> [#uses=1]</div><div>  %length17 = load i32* %src.length               ; <i32> [#uses=1]</div>
<div>  %4 = sext i32 %length17 to i64                  ; <i64> [#uses=1]</div><div>  %dst = getelementptr inbounds [0 x i8]* %result.data, i32 %index16, i64 0 ; <i8*> [#uses=1]</div><div>  %src = getelementptr inbounds [0 x i8]* %src.data, i32 0, i64 0 ; <i8*> [#uses=1]</div>
<div>  %5 = mul i64 %4, ptrtoint (i8* getelementptr (i8* null, i32 1) to i64) ; <i64> [#uses=1]</div><div>  call void @llvm.memcpy.i64(i8* %dst, i8* %src, i64 %5, i32 0)</div><div>  %index18 = load i32* %index                     ; <i32> [#uses=1]</div>
<div>  %src.length19 = getelementptr %tart.core.String* %get15, i32 0, i32 1 ; <i32*> [#uses=1]</div><div>  %length20 = load i32* %src.length19             ; <i32> [#uses=1]</div><div>  %6 = add i32 %index18, %length20                ; <i32> [#uses=1]</div>
<div>  store i32 %6, i32* %index</div><div>  br label %incr3</div><div><br></div><div>And here is the generated assembly:</div><div><br></div><div><div>LBB59_5:</div><div>        movl    %edi, 4(%esp)</div><div>        movl    48(%esp), %ecx</div>
<div>        movl    %ecx, (%esp)</div><div>        call    "_tart.core.Array[tart.core.String]..index.get(int)->tart.core.String"</div><div>        movl    %eax, %ebp</div><div>        movl    4(%ebp), %eax</div>
<div>        movl    %eax, 8(%esp)</div><div>        leal    16(%ebp), %eax</div><div>        movl    %eax, 4(%esp)</div><div>        movl    %esi, (%esp)</div><div>        call    _memcpy</div><div>        addl    4(%ebp), %ebx</div>
<div>        incl    %edi</div><div>        cmpl    24(%esp), %edi</div><div>        jne     LBB59_5</div><div><br></div></div></div><div>The issue has to do with the stack variable %index. In the IR code above, %index gets increased by 'length' each time through the loop. %index is also used as an offset to 'dst'.</div>
<div><br></div><div>However, in the assembly code, while 'ebx' does get incremented each time through the loop, the value of ebx is not being used in the address calculation for the first argument to memcpy().</div>
<div><br></div><div>Not that it is any way relevant, but in case you are wondering what the original source looks like, here it is:</div><br clear="all"><div>  static def concat(s:String...) -> String {</div><div>    let count = s.length;</div>
<div>    var length = 0;</div><div>    for i = 0; i < count; ++i {</div><div>      length += s[i].length;</div><div>    }</div><div>    </div><div>    let result = alloc(length);</div><div>    var index = 0;</div><div>
    for i = 0; i < count; ++i {</div><div>      let src = s[i];</div><div>      Memory.arrayCopy(result.data, index, src.data, 0, src.length);</div><div>      index += src.length;</div><div>    }</div><div><br></div><div>
    return result;</div><div>  }</div><div><br></div>-- <br>-- Talin<br>