#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */

/* Variables and functions */
char *strncpy(char *dst0, const char *src0, size_t count) {
  char *dst = dst0;
  const char *src = src0;
  long *aligned_dst;
  const long *aligned_src;
  if (!(((long)src & (sizeof(long) - 1)) | ((long)dst & (sizeof(long) - 1))) &&
      !((count) < sizeof(long))) {
    aligned_dst = (long *)dst;
    aligned_src = (long *)src;
    while (count >= sizeof(long int) &&
           !(((*aligned_src) - 0x01010101) & ~(*aligned_src) & 0x80808080)) {
      count -= sizeof(long int);
      *aligned_dst++ = *aligned_src++;
    }
    dst = (char *)aligned_dst;
    src = (char *)aligned_src;
  }
  while (count > 0) {
    --count;
    if ((*dst++ = *src++) == '\0')
      break;
  }
  while (count-- > 0)
    *dst++ = '\0';
  return dst0;
}


x86 assembly (clang, -O0):
<strncpy>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x28(%rbp),%rax
and    $0x7,%rax
mov    -0x20(%rbp),%rcx
and    $0x7,%rcx
or     %rcx,%rax
cmp    $0x0,%rax
jne    11f1 <strncpy+0xf1>
cmpq   $0x8,-0x18(%rbp)
jb     11f1 <strncpy+0xf1>
mov    -0x20(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,-0x38(%rbp)
xor    %eax,%eax
cmpq   $0x8,-0x18(%rbp)
mov    %al,-0x39(%rbp)
jb     119c <strncpy+0x9c>
mov    -0x38(%rbp),%rax
mov    (%rax),%rax
sub    $0x1010101,%rax
mov    -0x38(%rbp),%rcx
mov    (%rcx),%rcx
xor    $0xffffffffffffffff,%rcx
and    %rcx,%rax
movabs $0x80808080,%rcx
and    %rcx,%rax
cmp    $0x0,%rax
setne  %al
xor    $0xff,%al
mov    %al,-0x39(%rbp)
mov    -0x39(%rbp),%al
test   $0x1,%al
jne    11ac <strncpy+0xac>
jmp    11e1 <strncpy+0xe1>
mov    -0x18(%rbp),%rax
sub    $0x8,%rax
mov    %rax,-0x18(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,%rcx
add    $0x8,%rcx
mov    %rcx,-0x38(%rbp)
mov    (%rax),%rcx
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x30(%rbp)
mov    %rcx,(%rax)
jmp    1158 <strncpy+0x58>
mov    -0x30(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    -0x38(%rbp),%rax
mov    %rax,-0x28(%rbp)
jmp    11f6 <strncpy+0xf6>
cmpq   $0x0,-0x18(%rbp)
jbe    1245 <strncpy+0x145>
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
mov    -0x28(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x28(%rbp)
mov    (%rax),%al
mov    -0x20(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x20(%rbp)
mov    %al,(%rcx)
movsbl %al,%eax
cmp    $0x0,%eax
jne    1240 <strncpy+0x140>
jmp    1245 <strncpy+0x145>
jmp    11f6 <strncpy+0xf6>
jmp    124a <strncpy+0x14a>
mov    -0x18(%rbp),%rax
mov    %rax,%rcx
add    $0xffffffffffffffff,%rcx
mov    %rcx,-0x18(%rbp)
cmp    $0x0,%rax
jbe    127a <strncpy+0x17a>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x20(%rbp)
movb   $0x0,(%rax)
jmp    124a <strncpy+0x14a>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<strncpy>:
push   %r14
push   %rbx
push   %rax
mov    %rdi,%r14
cmp    $0x8,%rdx
jb     1172 <strncpy+0x62>
mov    %esi,%eax
or     %r14d,%eax
and    $0x7,%eax
test   %rax,%rax
jne    117c <strncpy+0x6c>
mov    $0x80808080,%r8d
mov    %r14,%rdi
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mov    (%rsi),%rcx
lea    (%r8,%rcx,1),%ebx
add    $0x7e7e7e7f,%ebx
mov    %ecx,%eax
and    $0x80808080,%eax
xor    %r8d,%eax
test   %ebx,%eax
jne    1175 <strncpy+0x65>
add    $0xfffffffffffffff8,%rdx
add    $0x8,%rsi
mov    %rcx,(%rdi)
add    $0x8,%rdi
cmp    $0x7,%rdx
ja     1140 <strncpy+0x30>
jmp    1175 <strncpy+0x65>
mov    %r14,%rdi
test   %rdx,%rdx
jne    1184 <strncpy+0x74>
jmp    11b6 <strncpy+0xa6>
mov    %r14,%rdi
test   %rdx,%rdx
je     11b6 <strncpy+0xa6>
lea    -0x1(%rdx),%r8
xor    %ecx,%ecx
nopw   0x0(%rax,%rax,1)
movzbl (%rsi,%rcx,1),%eax
mov    %al,(%rdi,%rcx,1)
lea    0x1(%rcx),%rbx
test   %al,%al
je     11a7 <strncpy+0x97>
cmp    %rcx,%r8
mov    %rbx,%rcx
jne    1190 <strncpy+0x80>
sub    %rbx,%rdx
je     11b6 <strncpy+0xa6>
add    %rbx,%rdi
xor    %esi,%esi
call   1030 <memset@plt>
mov    %r14,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r14
ret

LLVM IR (-O0):
define i8* @strncpy(i8* %0, i8* %1, i64 %2) {
%4 = alloca i8*
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i8*
%8 = alloca i8*
%9 = alloca i64*
%10 = alloca i64*
store i8* %0, i8** %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%11 = load i8*, i8** %4
store i8* %11, i8** %7
%12 = load i8*, i8** %5
store i8* %12, i8** %8
%13 = load i8*, i8** %8
%14 = ptrtoint i8* %13 to i64
%15 = and i64 %14, 7
%16 = load i8*, i8** %7
%17 = ptrtoint i8* %16 to i64
%18 = and i64 %17, 7
%19 = or i64 %15, %18
%20 = icmp ne i64 %19, 0
br i1 %20, label %58, label %21
21: ; preds = %3
%22 = load i64, i64* %6
%23 = icmp ult i64 %22, 8
br i1 %23, label %58, label %24
24: ; preds = %21
%25 = load i8*, i8** %7
%26 = bitcast i8* %25 to i64*
store i64* %26, i64** %9
%27 = load i8*, i8** %8
%28 = bitcast i8* %27 to i64*
store i64* %28, i64** %10
br label %29
29: ; preds = %45, %24
%30 = load i64, i64* %6
%31 = icmp uge i64 %30, 8
br i1 %31, label %32, label %43
32: ; preds = %29
%33 = load i64*, i64** %10
%34 = load i64, i64* %33
%35 = sub nsw i64 %34, 16843009
%36 = load i64*, i64** %10
%37 = load i64, i64* %36
%38 = xor i64 %37, -1
%39 = and i64 %35, %38
%40 = and i64 %39, 2155905152
%41 = icmp ne i64 %40, 0
%42 = xor i1 %41, true
br label %43
43: ; preds = %32, %29
%44 = phi i1 [ false, %29 ], [ %42, %32 ]
br i1 %44, label %45, label %53
45: ; preds = %43
%46 = load i64, i64* %6
%47 = sub i64 %46, 8
store i64 %47, i64* %6
%48 = load i64*, i64** %10
%49 = getelementptr inbounds i64, i64* %48, i32 1
store i64* %49, i64** %10
%50 = load i64, i64* %48
%51 = load i64*, i64** %9
%52 = getelementptr inbounds i64, i64* %51, i32 1
store i64* %52, i64** %9
store i64 %50, i64* %51
br label %29
53: ; preds = %43
%54 = load i64*, i64** %9
%55 = bitcast i64* %54 to i8*
store i8* %55, i8** %7
%56 = load i64*, i64** %10
%57 = bitcast i64* %56 to i8*
store i8* %57, i8** %8
br label %58
58: ; preds = %53, %21, %3
br label %59
59: ; preds = %73, %58
%60 = load i64, i64* %6
%61 = icmp ugt i64 %60, 0
br i1 %61, label %62, label %74
62: ; preds = %59
%63 = load i64, i64* %6
%64 = add i64 %63, -1
store i64 %64, i64* %6
%65 = load i8*, i8** %8
%66 = getelementptr inbounds i8, i8* %65, i32 1
store i8* %66, i8** %8
%67 = load i8, i8* %65
%68 = load i8*, i8** %7
%69 = getelementptr inbounds i8, i8* %68, i32 1
store i8* %69, i8** %7
store i8 %67, i8* %68
%70 = sext i8 %67 to i32
%71 = icmp eq i32 %70, 0
br i1 %71, label %72, label %73
72: ; preds = %62
br label %74
73: ; preds = %62
br label %59
74: ; preds = %72, %59
br label %75
75: ; preds = %79, %74
%76 = load i64, i64* %6
%77 = add i64 %76, -1
store i64 %77, i64* %6
%78 = icmp ugt i64 %76, 0
br i1 %78, label %79, label %82
79: ; preds = %75
%80 = load i8*, i8** %7
%81 = getelementptr inbounds i8, i8* %80, i32 1
store i8* %81, i8** %7
store i8 0, i8* %80
br label %75
82: ; preds = %75
%83 = load i8*, i8** %4
ret i8* %83
}

LLVM IR (-O2):
define i8* @strncpy(i8* returned %0, i8* %1, i64 %2) {
%4 = ptrtoint i8* %1 to i64
%5 = ptrtoint i8* %0 to i64
%6 = or i64 %4, %5
%7 = and i64 %6, 7
%8 = icmp ne i64 %7, 0
%9 = icmp ult i64 %2, 8
%10 = or i1 %9, %8
br i1 %10, label %35, label %11
11: ; preds = %3
%12 = bitcast i8* %0 to i64*
%13 = bitcast i8* %1 to i64*
br label %14
14: ; preds = %11, %24
%15 = phi i64* [ %13, %11 ], [ %26, %24 ]
%16 = phi i64* [ %12, %11 ], [ %27, %24 ]
%17 = phi i64 [ %2, %11 ], [ %25, %24 ]
%18 = load i64, i64* %15
%19 = add i64 %18, 4278124287
%20 = and i64 %18, 2155905152
%21 = xor i64 %20, 2155905152
%22 = and i64 %21, %19
%23 = icmp eq i64 %22, 0
br i1 %23, label %24, label %29
24: ; preds = %14
%25 = add i64 %17, -8
%26 = getelementptr inbounds i64, i64* %15, i64 1
%27 = getelementptr inbounds i64, i64* %16, i64 1
store i64 %18, i64* %16
%28 = icmp ugt i64 %25, 7
br i1 %28, label %14, label %29
29: ; preds = %14, %24
%30 = phi i64 [ %25, %24 ], [ %17, %14 ]
%31 = phi i64* [ %27, %24 ], [ %16, %14 ]
%32 = phi i64* [ %26, %24 ], [ %15, %14 ]
%33 = bitcast i64* %31 to i8*
%34 = bitcast i64* %32 to i8*
br label %35
35: ; preds = %29, %3
%36 = phi i64 [ %2, %3 ], [ %30, %29 ]
%37 = phi i8* [ %0, %3 ], [ %33, %29 ]
%38 = phi i8* [ %1, %3 ], [ %34, %29 ]
%39 = icmp eq i64 %36, 0
br i1 %39, label %54, label %40
40: ; preds = %35, %40
%41 = phi i64 [ %44, %40 ], [ %36, %35 ]
%42 = phi i8* [ %47, %40 ], [ %37, %35 ]
%43 = phi i8* [ %45, %40 ], [ %38, %35 ]
%44 = add i64 %41, -1
%45 = getelementptr inbounds i8, i8* %43, i64 1
%46 = load i8, i8* %43
%47 = getelementptr inbounds i8, i8* %42, i64 1
store i8 %46, i8* %42
%48 = icmp ne i8 %46, 0
%49 = icmp ne i64 %44, 0
%50 = select i1 %48, i1 %49, i1 false
br i1 %50, label %40, label %51
51: ; preds = %40
%52 = icmp eq i64 %44, 0
br i1 %52, label %54, label %53
53: ; preds = %51
br label %54
54: ; preds = %35, %53, %51
ret i8* %0
}