Strange error in generated assembly

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:

loopbody2: ; preds = %test1
%i14 = load i32* %i5 ; [#uses=1]
%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]
%src.data = getelementptr %tart.core.String* %get15, i32 0, i32 4 ; <[0 x i8]> [#uses=1]
%result.data = getelementptr %tart.core.String
%alloc, i32 0, i32 4 ; <[0 x i8]> [#uses=1]
%index16 = load i32
%index ; [#uses=1]
%src.length = getelementptr %tart.core.String* %get15, i32 0, i32 1 ; <i32*> [#uses=1]
%length17 = load i32* %src.length ; [#uses=1]
%4 = sext i32 %length17 to i64 ; [#uses=1]
%dst = getelementptr inbounds [0 x i8]* %result.data, i32 %index16, i64 0 ; <i8*> [#uses=1]
%src = getelementptr inbounds [0 x i8]* %src.data, i32 0, i64 0 ; <i8*> [#uses=1]
%5 = mul i64 %4, ptrtoint (i8* getelementptr (i8* null, i32 1) to i64) ; [#uses=1]
call void @llvm.memcpy.i64(i8* %dst, i8* %src, i64 %5, i32 0)
%index18 = load i32* %index ; [#uses=1]
%src.length19 = getelementptr %tart.core.String* %get15, i32 0, i32 1 ; <i32*> [#uses=1]
%length20 = load i32* %src.length19 ; [#uses=1]
%6 = add i32 %index18, %length20 ; [#uses=1]
store i32 %6, i32* %index
br label %incr3

And here is the generated assembly:

LBB59_5:
movl %edi, 4(%esp)
movl 48(%esp), %ecx
movl %ecx, (%esp)
call “_tart.core.Array[tart.core.String]…index.get(int)->tart.core.String”
movl %eax, %ebp
movl 4(%ebp), %eax
movl %eax, 8(%esp)
leal 16(%ebp), %eax
movl %eax, 4(%esp)
movl %esi, (%esp)
call _memcpy
addl 4(%ebp), %ebx
incl %edi
cmpl 24(%esp), %edi
jne LBB59_5

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’.

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().

Not that it is any way relevant, but in case you are wondering what the original source looks like, here it is:

static def concat(s:String…) → String {
let count = s.length;
var length = 0;
for i = 0; i < count; ++i {
length += s[i].length;
}

let result = alloc(length);
var index = 0;
for i = 0; i < count; ++i {
let src = s[i];
Memory.arrayCopy(result.data, index, src.data, 0, src.length);
index += src.length;
}

return result;
}