char *mystrncat(char *s, char *ct, int n) {
  char *ts = s;
  while (*++ts)
    ;
  for (; n > 0 && ct != '\0'; n--)
    *ts++ = *ct++;
  *ts = '\0';
  return s;
}


x86 assembly (clang, -O0):
<mystrncat>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %edx,-0x14(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
cmpb   $0x0,0x1(%rax)
je     1135 <mystrncat+0x35>
jmp    1117 <mystrncat+0x17>
jmp    113a <mystrncat+0x3a>
xor    %eax,%eax
cmpl   $0x0,-0x14(%rbp)
mov    %al,-0x21(%rbp)
jle    1154 <mystrncat+0x54>
cmpq   $0x0,-0x10(%rbp)
setne  %al
mov    %al,-0x21(%rbp)
mov    -0x21(%rbp),%al
test   $0x1,%al
jne    1164 <mystrncat+0x64>
jmp    1194 <mystrncat+0x94>
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%cl
mov    -0x20(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x20(%rbp)
mov    %cl,(%rax)
mov    -0x14(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x14(%rbp)
jmp    113a <mystrncat+0x3a>
mov    -0x20(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<mystrncat>:
push   %r15
push   %r14
push   %rbx
mov    %rdi,%rax
mov    %rdi,%rcx
nopl   0x0(%rax,%rax,1)
cmpb   $0x0,0x1(%rcx)
lea    0x1(%rcx),%rcx
jne    1110 <mystrncat+0x10>
test   %edx,%edx
jle    1165 <mystrncat+0x65>
test   %rsi,%rsi
je     1165 <mystrncat+0x65>
lea    -0x1(%rdx),%edi
cmp    $0x1f,%edi
jb     1144 <mystrncat+0x44>
lea    0x1(%rdi),%r8
add    %rsi,%rdi
add    $0x1,%rdi
cmp    %rdi,%rcx
jae    116e <mystrncat+0x6e>
lea    (%rcx,%r8,1),%rdi
cmp    %rsi,%rdi
jbe    116e <mystrncat+0x6e>
mov    %rcx,%r11
add    $0x1,%edx
mov    %r11,%rcx
nopl   (%rax)
movzbl (%rsi),%ebx
add    $0x1,%rsi
mov    %bl,(%rcx)
add    $0x1,%rcx
add    $0xffffffff,%edx
cmp    $0x1,%edx
ja     1150 <mystrncat+0x50>
movb   $0x0,(%rcx)
pop    %rbx
pop    %r14
pop    %r15
ret
mov    %r8,%r9
and    $0xffffffffffffffe0,%r9
lea    -0x20(%r9),%rdi
mov    %rdi,%r11
shr    $0x5,%r11
add    $0x1,%r11
mov    %r11d,%r10d
and    $0x3,%r10d
cmp    $0x60,%rdi
jae    1195 <mystrncat+0x95>
xor    %edi,%edi
jmp    11f8 <mystrncat+0xf8>
and    $0xfffffffffffffffc,%r11
xor    %edi,%edi
nopl   0x0(%rax,%rax,1)
movups (%rsi,%rdi,1),%xmm0
movups 0x10(%rsi,%rdi,1),%xmm1
movups %xmm0,(%rcx,%rdi,1)
movups %xmm1,0x10(%rcx,%rdi,1)
movups 0x20(%rsi,%rdi,1),%xmm0
movups 0x30(%rsi,%rdi,1),%xmm1
movups %xmm0,0x20(%rcx,%rdi,1)
movups %xmm1,0x30(%rcx,%rdi,1)
movups 0x40(%rsi,%rdi,1),%xmm0
movups 0x50(%rsi,%rdi,1),%xmm1
movups %xmm0,0x40(%rcx,%rdi,1)
movups %xmm1,0x50(%rcx,%rdi,1)
movups 0x60(%rsi,%rdi,1),%xmm0
movups 0x70(%rsi,%rdi,1),%xmm1
movups %xmm0,0x60(%rcx,%rdi,1)
movups %xmm1,0x70(%rcx,%rdi,1)
sub    $0xffffffffffffff80,%rdi
add    $0xfffffffffffffffc,%r11
jne    11a0 <mystrncat+0xa0>
lea    (%rcx,%r9,1),%r11
test   %r10,%r10
je     1243 <mystrncat+0x143>
lea    (%rsi,%rdi,1),%r14
add    $0x10,%r14
add    $0x10,%rdi
shl    $0x5,%r10
xor    %ebx,%ebx
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
movups -0x10(%r14,%rbx,1),%xmm0
movups (%r14,%rbx,1),%xmm1
lea    (%rdi,%rbx,1),%r15
movups %xmm0,-0x10(%rcx,%r15,1)
movups %xmm1,(%rcx,%r15,1)
add    $0x20,%rbx
cmp    %rbx,%r10
jne    1220 <mystrncat+0x120>
mov    %r11,%rcx
cmp    %r9,%r8
je     1165 <mystrncat+0x65>
sub    %r9d,%edx
add    %r9,%rsi
jmp    1147 <mystrncat+0x47>

LLVM IR (-O0):
define i8* @mystrncat(i8* %0, i8* %1, i32 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i32
%7 = alloca i8*
store i8* %0, i8** %4
store i8* %1, i8** %5
store i32 %2, i32* %6
%8 = load i8*, i8** %4
store i8* %8, i8** %7
br label %9
9: ; preds = %14, %3
%10 = load i8*, i8** %7
%11 = getelementptr inbounds i8, i8* %10, i32 1
store i8* %11, i8** %7
%12 = load i8, i8* %11
%13 = icmp ne i8 %12, 0
br i1 %13, label %14, label %15
14: ; preds = %9
br label %9
15: ; preds = %9
br label %16
16: ; preds = %30, %15
%17 = load i32, i32* %6
%18 = icmp sgt i32 %17, 0
br i1 %18, label %19, label %22
19: ; preds = %16
%20 = load i8*, i8** %5
%21 = icmp ne i8* %20, null
br label %22
22: ; preds = %19, %16
%23 = phi i1 [ false, %16 ], [ %21, %19 ]
br i1 %23, label %24, label %33
24: ; preds = %22
%25 = load i8*, i8** %5
%26 = getelementptr inbounds i8, i8* %25, i32 1
store i8* %26, i8** %5
%27 = load i8, i8* %25
%28 = load i8*, i8** %7
%29 = getelementptr inbounds i8, i8* %28, i32 1
store i8* %29, i8** %7
store i8 %27, i8* %28
br label %30
30: ; preds = %24
%31 = load i32, i32* %6
%32 = add nsw i32 %31, -1
store i32 %32, i32* %6
br label %16
33: ; preds = %22
%34 = load i8*, i8** %7
store i8 0, i8* %34
%35 = load i8*, i8** %4
ret i8* %35
}

LLVM IR (-O2):
define i8* @mystrncat(i8* returned %0, i8* %1, i32 %2) {
br label %4
4: ; preds = %4, %3
%5 = phi i8* [ %0, %3 ], [ %6, %4 ]
%6 = getelementptr inbounds i8, i8* %5, i64 1
%7 = load i8, i8* %6
%8 = icmp eq i8 %7, 0
br i1 %8, label %9, label %4
9: ; preds = %4
%10 = icmp sgt i32 %2, 0
%11 = icmp ne i8* %1, null
%12 = and i1 %10, %11
br i1 %12, label %13, label %123
13: ; preds = %9
%14 = add i32 %2, -1
%15 = zext i32 %14 to i64
%16 = add nuw nsw i64 %15, 1
%17 = icmp ult i32 %14, 31
br i1 %17, label %110, label %18
18: ; preds = %13
%19 = add i32 %2, -1
%20 = zext i32 %19 to i64
%21 = add nuw nsw i64 %20, 1
%22 = getelementptr i8, i8* %6, i64 %21
%23 = getelementptr i8, i8* %1, i64 %21
%24 = icmp ult i8* %6, %23
%25 = icmp ugt i8* %22, %1
%26 = and i1 %24, %25
br i1 %26, label %110, label %27
27: ; preds = %18
%28 = and i64 %16, 8589934560
%29 = getelementptr i8, i8* %6, i64 %28
%30 = trunc i64 %28 to i32
%31 = sub i32 %2, %30
%32 = getelementptr i8, i8* %1, i64 %28
%33 = add nsw i64 %28, -32
%34 = lshr exact i64 %33, 5
%35 = add nuw nsw i64 %34, 1
%36 = and i64 %35, 3
%37 = icmp ult i64 %33, 96
br i1 %37, label %89, label %38
38: ; preds = %27
%39 = and i64 %35, 1152921504606846972
br label %40
40: ; preds = %40, %38
%41 = phi i64 [ 0, %38 ], [ %86, %40 ]
%42 = phi i64 [ 0, %38 ], [ %87, %40 ]
%43 = getelementptr i8, i8* %6, i64 %41
%44 = getelementptr i8, i8* %1, i64 %41
%45 = bitcast i8* %44 to <16 x i8>*
%46 = load <16 x i8>, <16 x i8>* %45
%47 = getelementptr i8, i8* %44, i64 16
%48 = bitcast i8* %47 to <16 x i8>*
%49 = load <16 x i8>, <16 x i8>* %48
%50 = bitcast i8* %43 to <16 x i8>*
store <16 x i8> %46, <16 x i8>* %50
%51 = getelementptr i8, i8* %43, i64 16
%52 = bitcast i8* %51 to <16 x i8>*
store <16 x i8> %49, <16 x i8>* %52
%53 = or i64 %41, 32
%54 = getelementptr i8, i8* %6, i64 %53
%55 = getelementptr i8, i8* %1, i64 %53
%56 = bitcast i8* %55 to <16 x i8>*
%57 = load <16 x i8>, <16 x i8>* %56
%58 = getelementptr i8, i8* %55, i64 16
%59 = bitcast i8* %58 to <16 x i8>*
%60 = load <16 x i8>, <16 x i8>* %59
%61 = bitcast i8* %54 to <16 x i8>*
store <16 x i8> %57, <16 x i8>* %61
%62 = getelementptr i8, i8* %54, i64 16
%63 = bitcast i8* %62 to <16 x i8>*
store <16 x i8> %60, <16 x i8>* %63
%64 = or i64 %41, 64
%65 = getelementptr i8, i8* %6, i64 %64
%66 = getelementptr i8, i8* %1, i64 %64
%67 = bitcast i8* %66 to <16 x i8>*
%68 = load <16 x i8>, <16 x i8>* %67
%69 = getelementptr i8, i8* %66, i64 16
%70 = bitcast i8* %69 to <16 x i8>*
%71 = load <16 x i8>, <16 x i8>* %70
%72 = bitcast i8* %65 to <16 x i8>*
store <16 x i8> %68, <16 x i8>* %72
%73 = getelementptr i8, i8* %65, i64 16
%74 = bitcast i8* %73 to <16 x i8>*
store <16 x i8> %71, <16 x i8>* %74
%75 = or i64 %41, 96
%76 = getelementptr i8, i8* %6, i64 %75
%77 = getelementptr i8, i8* %1, i64 %75
%78 = bitcast i8* %77 to <16 x i8>*
%79 = load <16 x i8>, <16 x i8>* %78
%80 = getelementptr i8, i8* %77, i64 16
%81 = bitcast i8* %80 to <16 x i8>*
%82 = load <16 x i8>, <16 x i8>* %81
%83 = bitcast i8* %76 to <16 x i8>*
store <16 x i8> %79, <16 x i8>* %83
%84 = getelementptr i8, i8* %76, i64 16
%85 = bitcast i8* %84 to <16 x i8>*
store <16 x i8> %82, <16 x i8>* %85
%86 = add nuw i64 %41, 128
%87 = add i64 %42, 4
%88 = icmp eq i64 %87, %39
br i1 %88, label %89, label %40
89: ; preds = %40, %27
%90 = phi i64 [ 0, %27 ], [ %86, %40 ]
%91 = icmp eq i64 %36, 0
br i1 %91, label %108, label %92
92: ; preds = %89, %92
%93 = phi i64 [ %105, %92 ], [ %90, %89 ]
%94 = phi i64 [ %106, %92 ], [ 0, %89 ]
%95 = getelementptr i8, i8* %6, i64 %93
%96 = getelementptr i8, i8* %1, i64 %93
%97 = bitcast i8* %96 to <16 x i8>*
%98 = load <16 x i8>, <16 x i8>* %97
%99 = getelementptr i8, i8* %96, i64 16
%100 = bitcast i8* %99 to <16 x i8>*
%101 = load <16 x i8>, <16 x i8>* %100
%102 = bitcast i8* %95 to <16 x i8>*
store <16 x i8> %98, <16 x i8>* %102
%103 = getelementptr i8, i8* %95, i64 16
%104 = bitcast i8* %103 to <16 x i8>*
store <16 x i8> %101, <16 x i8>* %104
%105 = add nuw i64 %93, 32
%106 = add i64 %94, 1
%107 = icmp eq i64 %106, %36
br i1 %107, label %108, label %92
108: ; preds = %92, %89
%109 = icmp eq i64 %16, %28
br i1 %109, label %123, label %110
110: ; preds = %18, %13, %108
%111 = phi i8* [ %6, %18 ], [ %6, %13 ], [ %29, %108 ]
%112 = phi i32 [ %2, %18 ], [ %2, %13 ], [ %31, %108 ]
%113 = phi i8* [ %1, %18 ], [ %1, %13 ], [ %32, %108 ]
br label %114
114: ; preds = %110, %114
%115 = phi i8* [ %120, %114 ], [ %111, %110 ]
%116 = phi i32 [ %121, %114 ], [ %112, %110 ]
%117 = phi i8* [ %118, %114 ], [ %113, %110 ]
%118 = getelementptr inbounds i8, i8* %117, i64 1
%119 = load i8, i8* %117
%120 = getelementptr inbounds i8, i8* %115, i64 1
store i8 %119, i8* %115
%121 = add nsw i32 %116, -1
%122 = icmp ugt i32 %116, 1
br i1 %122, label %114, label %123
123: ; preds = %114, %108, %9
%124 = phi i8* [ %6, %9 ], [ %29, %108 ], [ %120, %114 ]
store i8 0, i8* %124
ret i8* %0
}