char *my_strncat(char *str1, char *str2, int n) {
  int i;
  int j;
  i = 0;
  j = 0;
  while (*(str1 + i) != '\0')
    i++;
  while (*(str2 + j) != '\0')
    j++;
  for (j = 0; j < n; j++) {
    *(str1 + i) = *(str2 + j);
    i++;
  }
  if (j > n)
    *(str1 + i) = '\0';
  return (str1);
}


x86 assembly (clang, -O0):
<my_strncat>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
movl   $0x0,-0x18(%rbp)
movl   $0x0,-0x1c(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     1140 <my_strncat+0x40>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    111d <my_strncat+0x1d>
jmp    1145 <my_strncat+0x45>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     1168 <my_strncat+0x68>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    1145 <my_strncat+0x45>
movl   $0x0,-0x1c(%rbp)
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jge    11a8 <my_strncat+0xa8>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%dl
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    116f <my_strncat+0x6f>
mov    -0x1c(%rbp),%eax
cmp    -0x14(%rbp),%eax
jle    11c0 <my_strncat+0xc0>
mov    -0x8(%rbp),%rax
movslq -0x18(%rbp),%rcx
movb   $0x0,(%rax,%rcx,1)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<my_strncat>:
push   %rbx
mov    %rdi,%rax
mov    $0xffffffffffffffff,%rcx
nopl   0x0(%rax,%rax,1)
cmpb   $0x0,0x1(%rax,%rcx,1)
lea    0x1(%rcx),%rcx
jne    1110 <my_strncat+0x10>
test   %edx,%edx
jle    11bd <my_strncat+0xbd>
mov    %ecx,%r11d
mov    %edx,%r8d
cmp    $0x8,%edx
jb     114b <my_strncat+0x4b>
lea    (%rax,%r11,1),%rdi
lea    (%rsi,%r8,1),%rbx
cmp    %rbx,%rdi
jae    11c1 <my_strncat+0xc1>
lea    (%r11,%r8,1),%rdi
add    %rax,%rdi
cmp    %rsi,%rdi
jbe    11c1 <my_strncat+0xc1>
xor    %edx,%edx
mov    %rdx,%rcx
not    %rcx
add    %r8,%rcx
mov    %r8,%rdi
and    $0x3,%rdi
je     1176 <my_strncat+0x76>
nop
movzbl (%rsi,%rdx,1),%ebx
mov    %bl,(%rax,%r11,1)
add    $0x1,%r11
add    $0x1,%rdx
add    $0xffffffffffffffff,%rdi
jne    1160 <my_strncat+0x60>
cmp    $0x3,%rcx
jb     11bf <my_strncat+0xbf>
lea    (%r11,%rax,1),%rcx
add    $0x3,%rcx
sub    %rdx,%r8
add    %rsi,%rdx
add    $0x3,%rdx
xor    %esi,%esi
movzbl -0x3(%rdx,%rsi,1),%ebx
mov    %bl,-0x3(%rcx,%rsi,1)
movzbl -0x2(%rdx,%rsi,1),%ebx
mov    %bl,-0x2(%rcx,%rsi,1)
movzbl -0x1(%rdx,%rsi,1),%ebx
mov    %bl,-0x1(%rcx,%rsi,1)
movzbl (%rdx,%rsi,1),%ebx
mov    %bl,(%rcx,%rsi,1)
add    $0x4,%rsi
cmp    %rsi,%r8
jne    1190 <my_strncat+0x90>
jmp    11bf <my_strncat+0xbf>
js     11cd <my_strncat+0xcd>
pop    %rbx
ret
cmp    $0x20,%edx
jae    11d5 <my_strncat+0xd5>
xor    %edx,%edx
jmp    12bc <my_strncat+0x1bc>
mov    %ecx,%ecx
movb   $0x0,(%rax,%rcx,1)
pop    %rbx
ret
mov    %r8d,%edx
and    $0xffffffe0,%edx
lea    -0x20(%rdx),%rdi
mov    %rdi,%r10
shr    $0x5,%r10
add    $0x1,%r10
mov    %r10d,%r9d
and    $0x3,%r9d
cmp    $0x60,%rdi
jae    11fb <my_strncat+0xfb>
xor    %edi,%edi
jmp    1268 <my_strncat+0x168>
and    $0xfffffffffffffffc,%r10
mov    %ecx,%edi
lea    (%rax,%rdi,1),%rbx
add    $0x70,%rbx
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
movups (%rsi,%rdi,1),%xmm0
movups 0x10(%rsi,%rdi,1),%xmm1
movups %xmm0,-0x70(%rbx,%rdi,1)
movups %xmm1,-0x60(%rbx,%rdi,1)
movups 0x20(%rsi,%rdi,1),%xmm0
movups 0x30(%rsi,%rdi,1),%xmm1
movups %xmm0,-0x50(%rbx,%rdi,1)
movups %xmm1,-0x40(%rbx,%rdi,1)
movups 0x40(%rsi,%rdi,1),%xmm0
movups 0x50(%rsi,%rdi,1),%xmm1
movups %xmm0,-0x30(%rbx,%rdi,1)
movups %xmm1,-0x20(%rbx,%rdi,1)
movups 0x60(%rsi,%rdi,1),%xmm0
movups 0x70(%rsi,%rdi,1),%xmm1
movups %xmm0,-0x10(%rbx,%rdi,1)
movups %xmm1,(%rbx,%rdi,1)
sub    $0xffffffffffffff80,%rdi
add    $0xfffffffffffffffc,%r10
jne    1210 <my_strncat+0x110>
test   %r9,%r9
je     12ad <my_strncat+0x1ad>
lea    (%rsi,%rdi,1),%r10
add    $0x10,%r10
lea    (%rax,%rdi,1),%rbx
add    $0x10,%rbx
mov    %ecx,%edi
add    %rbx,%rdi
shl    $0x5,%r9
xor    %ebx,%ebx
nopl   0x0(%rax,%rax,1)
movups -0x10(%r10,%rbx,1),%xmm0
movups (%r10,%rbx,1),%xmm1
movups %xmm0,-0x10(%rdi,%rbx,1)
movups %xmm1,(%rdi,%rbx,1)
add    $0x20,%rbx
cmp    %rbx,%r9
jne    1290 <my_strncat+0x190>
cmp    %r8,%rdx
je     11bf <my_strncat+0xbf>
test   $0x18,%r8b
je     12ef <my_strncat+0x1ef>
mov    %rdx,%rdi
mov    %r8d,%edx
and    $0xfffffff8,%edx
add    %rdx,%r11
mov    %ecx,%ecx
add    %rax,%rcx
nopl   (%rax)
mov    (%rsi,%rdi,1),%rbx
mov    %rbx,(%rcx,%rdi,1)
add    $0x8,%rdi
cmp    %rdi,%rdx
jne    12d0 <my_strncat+0x1d0>
cmp    %r8,%rdx
je     11bf <my_strncat+0xbf>
jmp    114d <my_strncat+0x4d>
add    %rdx,%r11
jmp    114d <my_strncat+0x4d>

LLVM IR (-O0):
define i8* @my_strncat(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i32
%8 = alloca i32
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
store i32 0, i32* %7
store i32 0, i32* %8
br label %9
9: ; preds = %17, %3
%10 = load i8*, i8** %4
%11 = load i32, i32* %7
%12 = sext i32 %11 to i64
%13 = getelementptr inbounds i8, i8* %10, i64 %12
%14 = load i8, i8* %13
%15 = sext i8 %14 to i32
%16 = icmp ne i32 %15, 0
br i1 %16, label %17, label %20
17: ; preds = %9
%18 = load i32, i32* %7
%19 = add nsw i32 %18, 1
store i32 %19, i32* %7
br label %9
20: ; preds = %9
br label %21
21: ; preds = %29, %20
%22 = load i8*, i8** %5
%23 = load i32, i32* %8
%24 = sext i32 %23 to i64
%25 = getelementptr inbounds i8, i8* %22, i64 %24
%26 = load i8, i8* %25
%27 = sext i8 %26 to i32
%28 = icmp ne i32 %27, 0
br i1 %28, label %29, label %32
29: ; preds = %21
%30 = load i32, i32* %8
%31 = add nsw i32 %30, 1
store i32 %31, i32* %8
br label %21
32: ; preds = %21
store i32 0, i32* %8
br label %33
33: ; preds = %49, %32
%34 = load i32, i32* %8
%35 = load i32, i32* %6
%36 = icmp slt i32 %34, %35
br i1 %36, label %37, label %52
37: ; preds = %33
%38 = load i8*, i8** %5
%39 = load i32, i32* %8
%40 = sext i32 %39 to i64
%41 = getelementptr inbounds i8, i8* %38, i64 %40
%42 = load i8, i8* %41
%43 = load i8*, i8** %4
%44 = load i32, i32* %7
%45 = sext i32 %44 to i64
%46 = getelementptr inbounds i8, i8* %43, i64 %45
store i8 %42, i8* %46
%47 = load i32, i32* %7
%48 = add nsw i32 %47, 1
store i32 %48, i32* %7
br label %49
49: ; preds = %37
%50 = load i32, i32* %8
%51 = add nsw i32 %50, 1
store i32 %51, i32* %8
br label %33
52: ; preds = %33
%53 = load i32, i32* %8
%54 = load i32, i32* %6
%55 = icmp sgt i32 %53, %54
br i1 %55, label %56, label %61
56: ; preds = %52
%57 = load i8*, i8** %4
%58 = load i32, i32* %7
%59 = sext i32 %58 to i64
%60 = getelementptr inbounds i8, i8* %57, i64 %59
store i8 0, i8* %60
br label %61
61: ; preds = %56, %52
%62 = load i8*, i8** %4
ret i8* %62
}

LLVM IR (-O2):
define i8* @my_strncat(i8* returned %0, i8* nocapture %1, i32 %2) {
br label %4
4: ; preds = %4, %3
%5 = phi i64 [ %9, %4 ], [ 0, %3 ]
%6 = getelementptr inbounds i8, i8* %0, i64 %5
%7 = load i8, i8* %6
%8 = icmp eq i8 %7, 0
%9 = add nuw i64 %5, 1
br i1 %8, label %10, label %4
10: ; preds = %4
%11 = icmp sgt i32 %2, 0
br i1 %11, label %12, label %176
12: ; preds = %10
%13 = and i64 %5, 4294967295
%14 = zext i32 %2 to i64
%15 = icmp ult i32 %2, 8
br i1 %15, label %130, label %16
16: ; preds = %12
%17 = getelementptr i8, i8* %0, i64 %13
%18 = add nuw nsw i64 %13, %14
%19 = getelementptr i8, i8* %0, i64 %18
%20 = getelementptr i8, i8* %1, i64 %14
%21 = icmp ult i8* %17, %20
%22 = icmp ugt i8* %19, %1
%23 = and i1 %21, %22
br i1 %23, label %130, label %24
24: ; preds = %16
%25 = icmp ult i32 %2, 32
br i1 %25, label %114, label %26
26: ; preds = %24
%27 = and i64 %14, 4294967264
%28 = add nsw i64 %27, -32
%29 = lshr exact i64 %28, 5
%30 = add nuw nsw i64 %29, 1
%31 = and i64 %30, 3
%32 = icmp ult i64 %28, 96
br i1 %32, label %88, label %33
33: ; preds = %26
%34 = and i64 %30, 1152921504606846972
br label %35
35: ; preds = %35, %33
%36 = phi i64 [ 0, %33 ], [ %85, %35 ]
%37 = phi i64 [ 0, %33 ], [ %86, %35 ]
%38 = add i64 %13, %36
%39 = getelementptr inbounds i8, i8* %1, i64 %36
%40 = bitcast i8* %39 to <16 x i8>*
%41 = load <16 x i8>, <16 x i8>* %40
%42 = getelementptr inbounds i8, i8* %39, i64 16
%43 = bitcast i8* %42 to <16 x i8>*
%44 = load <16 x i8>, <16 x i8>* %43
%45 = getelementptr inbounds i8, i8* %0, i64 %38
%46 = bitcast i8* %45 to <16 x i8>*
store <16 x i8> %41, <16 x i8>* %46
%47 = getelementptr inbounds i8, i8* %45, i64 16
%48 = bitcast i8* %47 to <16 x i8>*
store <16 x i8> %44, <16 x i8>* %48
%49 = or i64 %36, 32
%50 = add i64 %13, %49
%51 = getelementptr inbounds i8, i8* %1, i64 %49
%52 = bitcast i8* %51 to <16 x i8>*
%53 = load <16 x i8>, <16 x i8>* %52
%54 = getelementptr inbounds i8, i8* %51, i64 16
%55 = bitcast i8* %54 to <16 x i8>*
%56 = load <16 x i8>, <16 x i8>* %55
%57 = getelementptr inbounds i8, i8* %0, i64 %50
%58 = bitcast i8* %57 to <16 x i8>*
store <16 x i8> %53, <16 x i8>* %58
%59 = getelementptr inbounds i8, i8* %57, i64 16
%60 = bitcast i8* %59 to <16 x i8>*
store <16 x i8> %56, <16 x i8>* %60
%61 = or i64 %36, 64
%62 = add i64 %13, %61
%63 = getelementptr inbounds i8, i8* %1, i64 %61
%64 = bitcast i8* %63 to <16 x i8>*
%65 = load <16 x i8>, <16 x i8>* %64
%66 = getelementptr inbounds i8, i8* %63, i64 16
%67 = bitcast i8* %66 to <16 x i8>*
%68 = load <16 x i8>, <16 x i8>* %67
%69 = getelementptr inbounds i8, i8* %0, i64 %62
%70 = bitcast i8* %69 to <16 x i8>*
store <16 x i8> %65, <16 x i8>* %70
%71 = getelementptr inbounds i8, i8* %69, i64 16
%72 = bitcast i8* %71 to <16 x i8>*
store <16 x i8> %68, <16 x i8>* %72
%73 = or i64 %36, 96
%74 = add i64 %13, %73
%75 = getelementptr inbounds i8, i8* %1, i64 %73
%76 = bitcast i8* %75 to <16 x i8>*
%77 = load <16 x i8>, <16 x i8>* %76
%78 = getelementptr inbounds i8, i8* %75, i64 16
%79 = bitcast i8* %78 to <16 x i8>*
%80 = load <16 x i8>, <16 x i8>* %79
%81 = getelementptr inbounds i8, i8* %0, i64 %74
%82 = bitcast i8* %81 to <16 x i8>*
store <16 x i8> %77, <16 x i8>* %82
%83 = getelementptr inbounds i8, i8* %81, i64 16
%84 = bitcast i8* %83 to <16 x i8>*
store <16 x i8> %80, <16 x i8>* %84
%85 = add nuw i64 %36, 128
%86 = add i64 %37, 4
%87 = icmp eq i64 %86, %34
br i1 %87, label %88, label %35
88: ; preds = %35, %26
%89 = phi i64 [ 0, %26 ], [ %85, %35 ]
%90 = icmp eq i64 %31, 0
br i1 %90, label %108, label %91
91: ; preds = %88, %91
%92 = phi i64 [ %105, %91 ], [ %89, %88 ]
%93 = phi i64 [ %106, %91 ], [ 0, %88 ]
%94 = add i64 %13, %92
%95 = getelementptr inbounds i8, i8* %1, i64 %92
%96 = bitcast i8* %95 to <16 x i8>*
%97 = load <16 x i8>, <16 x i8>* %96
%98 = getelementptr inbounds i8, i8* %95, i64 16
%99 = bitcast i8* %98 to <16 x i8>*
%100 = load <16 x i8>, <16 x i8>* %99
%101 = getelementptr inbounds i8, i8* %0, i64 %94
%102 = bitcast i8* %101 to <16 x i8>*
store <16 x i8> %97, <16 x i8>* %102
%103 = getelementptr inbounds i8, i8* %101, i64 16
%104 = bitcast i8* %103 to <16 x i8>*
store <16 x i8> %100, <16 x i8>* %104
%105 = add nuw i64 %92, 32
%106 = add i64 %93, 1
%107 = icmp eq i64 %106, %31
br i1 %107, label %108, label %91
108: ; preds = %91, %88
%109 = icmp eq i64 %27, %14
br i1 %109, label %181, label %110
110: ; preds = %108
%111 = add nuw nsw i64 %13, %27
%112 = and i64 %14, 24
%113 = icmp eq i64 %112, 0
br i1 %113, label %130, label %114
114: ; preds = %24, %110
%115 = phi i64 [ %27, %110 ], [ 0, %24 ]
%116 = and i64 %14, 4294967288
%117 = add nuw nsw i64 %13, %116
br label %118
118: ; preds = %118, %114
%119 = phi i64 [ %115, %114 ], [ %126, %118 ]
%120 = add i64 %13, %119
%121 = getelementptr inbounds i8, i8* %1, i64 %119
%122 = bitcast i8* %121 to <8 x i8>*
%123 = load <8 x i8>, <8 x i8>* %122
%124 = getelementptr inbounds i8, i8* %0, i64 %120
%125 = bitcast i8* %124 to <8 x i8>*
store <8 x i8> %123, <8 x i8>* %125
%126 = add nuw i64 %119, 8
%127 = icmp eq i64 %126, %116
br i1 %127, label %128, label %118
128: ; preds = %118
%129 = icmp eq i64 %116, %14
br i1 %129, label %181, label %130
130: ; preds = %16, %12, %110, %128
%131 = phi i64 [ %13, %12 ], [ %13, %16 ], [ %111, %110 ], [ %117, %128 ]
%132 = phi i64 [ 0, %12 ], [ 0, %16 ], [ %27, %110 ], [ %116, %128 ]
%133 = xor i64 %132, -1
%134 = add nsw i64 %133, %14
%135 = and i64 %14, 3
%136 = icmp eq i64 %135, 0
br i1 %136, label %148, label %137
137: ; preds = %130, %137
%138 = phi i64 [ %144, %137 ], [ %131, %130 ]
%139 = phi i64 [ %145, %137 ], [ %132, %130 ]
%140 = phi i64 [ %146, %137 ], [ 0, %130 ]
%141 = getelementptr inbounds i8, i8* %1, i64 %139
%142 = load i8, i8* %141
%143 = getelementptr inbounds i8, i8* %0, i64 %138
store i8 %142, i8* %143
%144 = add nuw nsw i64 %138, 1
%145 = add nuw nsw i64 %139, 1
%146 = add i64 %140, 1
%147 = icmp eq i64 %146, %135
br i1 %147, label %148, label %137
148: ; preds = %137, %130
%149 = phi i64 [ %131, %130 ], [ %144, %137 ]
%150 = phi i64 [ %132, %130 ], [ %145, %137 ]
%151 = icmp ult i64 %134, 3
br i1 %151, label %181, label %152
152: ; preds = %148, %152
%153 = phi i64 [ %173, %152 ], [ %149, %148 ]
%154 = phi i64 [ %174, %152 ], [ %150, %148 ]
%155 = getelementptr inbounds i8, i8* %1, i64 %154
%156 = load i8, i8* %155
%157 = getelementptr inbounds i8, i8* %0, i64 %153
store i8 %156, i8* %157
%158 = add nuw nsw i64 %153, 1
%159 = add nuw nsw i64 %154, 1
%160 = getelementptr inbounds i8, i8* %1, i64 %159
%161 = load i8, i8* %160
%162 = getelementptr inbounds i8, i8* %0, i64 %158
store i8 %161, i8* %162
%163 = add nuw nsw i64 %153, 2
%164 = add nuw nsw i64 %154, 2
%165 = getelementptr inbounds i8, i8* %1, i64 %164
%166 = load i8, i8* %165
%167 = getelementptr inbounds i8, i8* %0, i64 %163
store i8 %166, i8* %167
%168 = add nuw nsw i64 %153, 3
%169 = add nuw nsw i64 %154, 3
%170 = getelementptr inbounds i8, i8* %1, i64 %169
%171 = load i8, i8* %170
%172 = getelementptr inbounds i8, i8* %0, i64 %168
store i8 %171, i8* %172
%173 = add nuw nsw i64 %153, 4
%174 = add nuw nsw i64 %154, 4
%175 = icmp eq i64 %174, %14
br i1 %175, label %181, label %152
176: ; preds = %10
%177 = icmp slt i32 %2, 0
br i1 %177, label %178, label %181
178: ; preds = %176
%179 = and i64 %5, 4294967295
%180 = getelementptr inbounds i8, i8* %0, i64 %179
store i8 0, i8* %180
br label %181
181: ; preds = %148, %152, %108, %128, %178, %176
ret i8* %0
}