#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 */
int /*<<< orphan*/ memset(char *, char, size_t);
char *strncpy(char *dest, const char *src, size_t count) {
  char *ret = dest;
  unsigned long himagic = 0x80808080L;
  unsigned long lomagic = 0x01010101L;
  while (count && (unsigned long)src & (sizeof src - 1)) {
    count--;
    if (!(*dest++ = *src++)) {
      goto finalize;
    }
  }
  while (count >= sizeof(unsigned long)) {
    unsigned long value = *(unsigned long *)src;
    unsigned long magic;
    if ((magic = (value - lomagic) & himagic)) {
      if (magic & ~value) {
        break;
      }
    }
    *(unsigned long *)dest = value;
    dest += sizeof(unsigned long);
    src += sizeof(unsigned long);
    count -= sizeof(unsigned long);
  }
  while (count) {
    count--;
    if (!(*dest++ = *src++))
      break;
  }
finalize:
  if (count) {
    memset(dest, '\0', count);
  }
  return ret;
}


x86 assembly (clang, -O0):
<strncpy>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x20(%rbp)
mov    $0x80808080,%eax
mov    %rax,-0x28(%rbp)
movq   $0x1010101,-0x30(%rbp)
01
xor    %eax,%eax
cmpq   $0x0,-0x18(%rbp)
mov    %al,-0x41(%rbp)
je     115f <strncpy+0x4f>
mov    -0x10(%rbp),%rax
and    $0x7,%rax
cmp    $0x0,%rax
setne  %al
mov    %al,-0x41(%rbp)
mov    -0x41(%rbp),%al
test   $0x1,%al
jne    116f <strncpy+0x5f>
jmp    11af <strncpy+0x9f>
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%al
mov    -0x8(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %al,(%rcx)
cmp    $0x0,%al
jne    11aa <strncpy+0x9a>
jmp    1290 <strncpy+0x180>
jmp    113d <strncpy+0x2d>
jmp    11b4 <strncpy+0xa4>
cmpq   $0x8,-0x18(%rbp)
jb     123b <strncpy+0x12b>
mov    -0x10(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x38(%rbp)
mov    -0x38(%rbp),%rax
sub    -0x30(%rbp),%rax
and    -0x28(%rbp),%rax
mov    %rax,-0x40(%rbp)
cmp    $0x0,%rax
je     1207 <strncpy+0xf7>
mov    -0x40(%rbp),%rax
mov    -0x38(%rbp),%rcx
xor    $0xffffffffffffffff,%rcx
and    %rcx,%rax
cmp    $0x0,%rax
je     1202 <strncpy+0xf2>
jmp    123b <strncpy+0x12b>
jmp    1207 <strncpy+0xf7>
mov    -0x38(%rbp),%rcx
mov    -0x8(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x8(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x8(%rbp)
mov    -0x10(%rbp),%rax
add    $0x8,%rax
mov    %rax,-0x10(%rbp)
mov    -0x18(%rbp),%rax
sub    $0x8,%rax
mov    %rax,-0x18(%rbp)
jmp    11b4 <strncpy+0xa4>
jmp    1240 <strncpy+0x130>
cmpq   $0x0,-0x18(%rbp)
je     128b <strncpy+0x17b>
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x10(%rbp)
mov    (%rax),%al
mov    -0x8(%rbp),%rcx
mov    %rcx,%rdx
add    $0x1,%rdx
mov    %rdx,-0x8(%rbp)
mov    %al,(%rcx)
cmp    $0x0,%al
jne    1286 <strncpy+0x176>
jmp    128b <strncpy+0x17b>
jmp    1240 <strncpy+0x130>
jmp    1290 <strncpy+0x180>
cmpq   $0x0,-0x18(%rbp)
je     12aa <strncpy+0x19a>
mov    -0x8(%rbp),%rdi
mov    -0x18(%rbp),%rdx
xor    %esi,%esi
call   1030 <memset@plt>
mov    -0x20(%rbp),%rax
add    $0x50,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<strncpy>:
push   %r14
push   %rbx
push   %rax
mov    %rdx,%rax
mov    %rdi,%r14
test   %rdx,%rdx
je     1291 <strncpy+0x181>
mov    %esi,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     1291 <strncpy+0x181>
lea    -0x1(%rax),%rdx
mov    (%rsi),%cl
lea    0x1(%r14),%rdi
mov    %cl,(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
lea    0x1(%rsi),%r8
test   %rdx,%rdx
je     129a <strncpy+0x18a>
mov    %r8d,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     129a <strncpy+0x18a>
lea    -0x2(%rax),%rdx
mov    0x1(%rsi),%cl
lea    0x2(%r14),%rdi
mov    %cl,0x1(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
lea    0x2(%rsi),%r8
test   %rdx,%rdx
je     129a <strncpy+0x18a>
mov    %r8d,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     129a <strncpy+0x18a>
lea    -0x3(%rax),%rdx
mov    0x2(%rsi),%cl
lea    0x3(%r14),%rdi
mov    %cl,0x2(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
lea    0x3(%rsi),%r8
test   %rdx,%rdx
je     129a <strncpy+0x18a>
mov    %r8d,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     129a <strncpy+0x18a>
lea    -0x4(%rax),%rdx
mov    0x3(%rsi),%cl
lea    0x4(%r14),%rdi
mov    %cl,0x3(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
lea    0x4(%rsi),%r8
test   %rdx,%rdx
je     129a <strncpy+0x18a>
mov    %r8d,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     129a <strncpy+0x18a>
lea    -0x5(%rax),%rdx
mov    0x4(%rsi),%cl
lea    0x5(%r14),%rdi
mov    %cl,0x4(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
lea    0x5(%rsi),%r8
test   %rdx,%rdx
je     129a <strncpy+0x18a>
mov    %r8d,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     129a <strncpy+0x18a>
lea    -0x6(%rax),%rdx
mov    0x5(%rsi),%cl
lea    0x6(%r14),%rdi
mov    %cl,0x5(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
lea    0x6(%rsi),%r8
test   %rdx,%rdx
je     129a <strncpy+0x18a>
mov    %r8d,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     129a <strncpy+0x18a>
lea    -0x7(%rax),%rdx
mov    0x6(%rsi),%cl
lea    0x7(%r14),%rdi
mov    %cl,0x6(%r14)
test   %cl,%cl
je     131e <strncpy+0x20e>
add    $0x7,%rsi
test   %rdx,%rdx
je     12e0 <strncpy+0x1d0>
mov    %esi,%ecx
and    $0x7,%ecx
test   %rcx,%rcx
je     12e0 <strncpy+0x1d0>
add    $0xfffffffffffffff8,%rax
mov    (%rsi),%cl
lea    0x8(%r14),%rdi
mov    %cl,0x7(%r14)
mov    %rax,%rdx
jmp    131e <strncpy+0x20e>
mov    %rax,%rdx
mov    %rsi,%r8
mov    %r14,%rdi
cmp    $0x8,%rdx
jb     12e9 <strncpy+0x1d9>
mov    $0x80808080,%eax
jmp    12c5 <strncpy+0x1b5>
nopw   0x0(%rax,%rax,1)
mov    %rsi,(%rdi)
add    $0x8,%rdi
add    $0x8,%r8
add    $0xfffffffffffffff8,%rdx
cmp    $0x7,%rdx
jbe    12e9 <strncpy+0x1d9>
mov    (%r8),%rsi
lea    -0x1010101(%rsi),%ebx
and    %rax,%rbx
je     12b0 <strncpy+0x1a0>
mov    %rsi,%rcx
not    %rcx
test   %rcx,%rbx
je     12b0 <strncpy+0x1a0>
jmp    12ee <strncpy+0x1de>
mov    %rsi,%r8
cmp    $0x8,%rdx
jae    12a0 <strncpy+0x190>
test   %rdx,%rdx
je     132a <strncpy+0x21a>
lea    -0x1(%rdx),%rax
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
movzbl (%r8,%rsi,1),%ecx
mov    %cl,(%rdi,%rsi,1)
lea    0x1(%rsi),%rbx
test   %cl,%cl
je     1318 <strncpy+0x208>
cmp    %rsi,%rax
mov    %rbx,%rsi
jne    1300 <strncpy+0x1f0>
sub    %rbx,%rdx
add    %rbx,%rdi
test   %rdx,%rdx
je     132a <strncpy+0x21a>
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 i64
%9 = alloca i64
%10 = alloca i64
%11 = alloca i64
store i8* %0, i8** %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%12 = load i8*, i8** %4
store i8* %12, i8** %7
store i64 2155905152, i64* %8
store i64 16843009, i64* %9
br label %13
13: ; preds = %33, %3
%14 = load i64, i64* %6
%15 = icmp ne i64 %14, 0
br i1 %15, label %16, label %21
16: ; preds = %13
%17 = load i8*, i8** %5
%18 = ptrtoint i8* %17 to i64
%19 = and i64 %18, 7
%20 = icmp ne i64 %19, 0
br label %21
21: ; preds = %16, %13
%22 = phi i1 [ false, %13 ], [ %20, %16 ]
br i1 %22, label %23, label %34
23: ; preds = %21
%24 = load i64, i64* %6
%25 = add i64 %24, -1
store i64 %25, i64* %6
%26 = load i8*, i8** %5
%27 = getelementptr inbounds i8, i8* %26, i32 1
store i8* %27, i8** %5
%28 = load i8, i8* %26
%29 = load i8*, i8** %4
%30 = getelementptr inbounds i8, i8* %29, i32 1
store i8* %30, i8** %4
store i8 %28, i8* %29
%31 = icmp ne i8 %28, 0
br i1 %31, label %33, label %32
32: ; preds = %23
br label %82
33: ; preds = %23
br label %13
34: ; preds = %21
br label %35
35: ; preds = %56, %34
%36 = load i64, i64* %6
%37 = icmp uge i64 %36, 8
br i1 %37, label %38, label %66
38: ; preds = %35
%39 = load i8*, i8** %5
%40 = bitcast i8* %39 to i64*
%41 = load i64, i64* %40
store i64 %41, i64* %10
%42 = load i64, i64* %10
%43 = load i64, i64* %9
%44 = sub i64 %42, %43
%45 = load i64, i64* %8
%46 = and i64 %44, %45
store i64 %46, i64* %11
%47 = icmp ne i64 %46, 0
br i1 %47, label %48, label %56
48: ; preds = %38
%49 = load i64, i64* %11
%50 = load i64, i64* %10
%51 = xor i64 %50, -1
%52 = and i64 %49, %51
%53 = icmp ne i64 %52, 0
br i1 %53, label %54, label %55
54: ; preds = %48
br label %66
55: ; preds = %48
br label %56
56: ; preds = %55, %38
%57 = load i64, i64* %10
%58 = load i8*, i8** %4
%59 = bitcast i8* %58 to i64*
store i64 %57, i64* %59
%60 = load i8*, i8** %4
%61 = getelementptr inbounds i8, i8* %60, i64 8
store i8* %61, i8** %4
%62 = load i8*, i8** %5
%63 = getelementptr inbounds i8, i8* %62, i64 8
store i8* %63, i8** %5
%64 = load i64, i64* %6
%65 = sub i64 %64, 8
store i64 %65, i64* %6
br label %35
66: ; preds = %54, %35
br label %67
67: ; preds = %80, %66
%68 = load i64, i64* %6
%69 = icmp ne i64 %68, 0
br i1 %69, label %70, label %81
70: ; preds = %67
%71 = load i64, i64* %6
%72 = add i64 %71, -1
store i64 %72, i64* %6
%73 = load i8*, i8** %5
%74 = getelementptr inbounds i8, i8* %73, i32 1
store i8* %74, i8** %5
%75 = load i8, i8* %73
%76 = load i8*, i8** %4
%77 = getelementptr inbounds i8, i8* %76, i32 1
store i8* %77, i8** %4
store i8 %75, i8* %76
%78 = icmp ne i8 %75, 0
br i1 %78, label %80, label %79
79: ; preds = %70
br label %81
80: ; preds = %70
br label %67
81: ; preds = %79, %67
br label %82
82: ; preds = %81, %32
%83 = load i64, i64* %6
%84 = icmp ne i64 %83, 0
br i1 %84, label %85, label %89
85: ; preds = %82
%86 = load i8*, i8** %4
%87 = load i64, i64* %6
%88 = call i32 @memset(i8* %86, i8 signext 0, i64 %87)
br label %89
89: ; preds = %85, %82
%90 = load i8*, i8** %7
ret i8* %90
}

LLVM IR (-O2):
define i8* @strncpy(i8* returned %0, i8* %1, i64 %2) {
%4 = icmp ne i64 %2, 0
%5 = ptrtoint i8* %1 to i64
%6 = and i64 %5, 7
%7 = icmp ne i64 %6, 0
%8 = and i1 %4, %7
br i1 %8, label %14, label %9
9: ; preds = %92, %80, %68, %56, %44, %32, %20, %3
%10 = phi i64 [ %2, %3 ], [ %15, %20 ], [ %27, %32 ], [ %39, %44 ], [ %51, %56 ], [ %63, %68 ], [ %75, %80 ], [ %87, %92 ]
%11 = phi i8* [ %1, %3 ], [ %16, %20 ], [ %28, %32 ], [ %40, %44 ], [ %52, %56 ], [ %64, %68 ], [ %76, %80 ], [ %88, %92 ]
%12 = phi i8* [ %0, %3 ], [ %18, %20 ], [ %30, %32 ], [ %42, %44 ], [ %54, %56 ], [ %66, %68 ], [ %78, %80 ], [ %90, %92 ]
%13 = icmp ugt i64 %10, 7
br i1 %13, label %102, label %121
14: ; preds = %3
%15 = add i64 %2, -1
%16 = getelementptr inbounds i8, i8* %1, i64 1
%17 = load i8, i8* %1
%18 = getelementptr inbounds i8, i8* %0, i64 1
store i8 %17, i8* %0
%19 = icmp eq i8 %17, 0
br i1 %19, label %141, label %20
20: ; preds = %14
%21 = icmp ne i64 %15, 0
%22 = ptrtoint i8* %16 to i64
%23 = and i64 %22, 7
%24 = icmp ne i64 %23, 0
%25 = select i1 %21, i1 %24, i1 false
br i1 %25, label %26, label %9
26: ; preds = %20
%27 = add i64 %2, -2
%28 = getelementptr inbounds i8, i8* %1, i64 2
%29 = load i8, i8* %16
%30 = getelementptr inbounds i8, i8* %0, i64 2
store i8 %29, i8* %18
%31 = icmp eq i8 %29, 0
br i1 %31, label %141, label %32
32: ; preds = %26
%33 = icmp ne i64 %27, 0
%34 = ptrtoint i8* %28 to i64
%35 = and i64 %34, 7
%36 = icmp ne i64 %35, 0
%37 = select i1 %33, i1 %36, i1 false
br i1 %37, label %38, label %9
38: ; preds = %32
%39 = add i64 %2, -3
%40 = getelementptr inbounds i8, i8* %1, i64 3
%41 = load i8, i8* %28
%42 = getelementptr inbounds i8, i8* %0, i64 3
store i8 %41, i8* %30
%43 = icmp eq i8 %41, 0
br i1 %43, label %141, label %44
44: ; preds = %38
%45 = icmp ne i64 %39, 0
%46 = ptrtoint i8* %40 to i64
%47 = and i64 %46, 7
%48 = icmp ne i64 %47, 0
%49 = select i1 %45, i1 %48, i1 false
br i1 %49, label %50, label %9
50: ; preds = %44
%51 = add i64 %2, -4
%52 = getelementptr inbounds i8, i8* %1, i64 4
%53 = load i8, i8* %40
%54 = getelementptr inbounds i8, i8* %0, i64 4
store i8 %53, i8* %42
%55 = icmp eq i8 %53, 0
br i1 %55, label %141, label %56
56: ; preds = %50
%57 = icmp ne i64 %51, 0
%58 = ptrtoint i8* %52 to i64
%59 = and i64 %58, 7
%60 = icmp ne i64 %59, 0
%61 = select i1 %57, i1 %60, i1 false
br i1 %61, label %62, label %9
62: ; preds = %56
%63 = add i64 %2, -5
%64 = getelementptr inbounds i8, i8* %1, i64 5
%65 = load i8, i8* %52
%66 = getelementptr inbounds i8, i8* %0, i64 5
store i8 %65, i8* %54
%67 = icmp eq i8 %65, 0
br i1 %67, label %141, label %68
68: ; preds = %62
%69 = icmp ne i64 %63, 0
%70 = ptrtoint i8* %64 to i64
%71 = and i64 %70, 7
%72 = icmp ne i64 %71, 0
%73 = select i1 %69, i1 %72, i1 false
br i1 %73, label %74, label %9
74: ; preds = %68
%75 = add i64 %2, -6
%76 = getelementptr inbounds i8, i8* %1, i64 6
%77 = load i8, i8* %64
%78 = getelementptr inbounds i8, i8* %0, i64 6
store i8 %77, i8* %66
%79 = icmp eq i8 %77, 0
br i1 %79, label %141, label %80
80: ; preds = %74
%81 = icmp ne i64 %75, 0
%82 = ptrtoint i8* %76 to i64
%83 = and i64 %82, 7
%84 = icmp ne i64 %83, 0
%85 = select i1 %81, i1 %84, i1 false
br i1 %85, label %86, label %9
86: ; preds = %80
%87 = add i64 %2, -7
%88 = getelementptr inbounds i8, i8* %1, i64 7
%89 = load i8, i8* %76
%90 = getelementptr inbounds i8, i8* %0, i64 7
store i8 %89, i8* %78
%91 = icmp eq i8 %89, 0
br i1 %91, label %141, label %92
92: ; preds = %86
%93 = icmp ne i64 %87, 0
%94 = ptrtoint i8* %88 to i64
%95 = and i64 %94, 7
%96 = icmp ne i64 %95, 0
%97 = select i1 %93, i1 %96, i1 false
br i1 %97, label %98, label %9
98: ; preds = %92
%99 = add i64 %2, -8
%100 = load i8, i8* %88
%101 = getelementptr inbounds i8, i8* %0, i64 8
store i8 %100, i8* %90
br label %141
102: ; preds = %9, %115
%103 = phi i8* [ %117, %115 ], [ %12, %9 ]
%104 = phi i8* [ %118, %115 ], [ %11, %9 ]
%105 = phi i64 [ %119, %115 ], [ %10, %9 ]
%106 = bitcast i8* %104 to i64*
%107 = load i64, i64* %106
%108 = add i64 %107, 4278124287
%109 = and i64 %108, 2155905152
%110 = icmp eq i64 %109, 0
br i1 %110, label %115, label %111
111: ; preds = %102
%112 = xor i64 %107, -1
%113 = and i64 %109, %112
%114 = icmp eq i64 %113, 0
br i1 %114, label %115, label %126
115: ; preds = %102, %111
%116 = bitcast i8* %103 to i64*
store i64 %107, i64* %116
%117 = getelementptr inbounds i8, i8* %103, i64 8
%118 = getelementptr inbounds i8, i8* %104, i64 8
%119 = add i64 %105, -8
%120 = icmp ugt i64 %119, 7
br i1 %120, label %102, label %121
121: ; preds = %115, %9
%122 = phi i64 [ %10, %9 ], [ %119, %115 ]
%123 = phi i8* [ %11, %9 ], [ %118, %115 ]
%124 = phi i8* [ %12, %9 ], [ %117, %115 ]
%125 = icmp eq i64 %122, 0
br i1 %125, label %147, label %126
126: ; preds = %111, %121
%127 = phi i64 [ %122, %121 ], [ %105, %111 ]
%128 = phi i8* [ %123, %121 ], [ %104, %111 ]
%129 = phi i8* [ %124, %121 ], [ %103, %111 ]
br label %130
130: ; preds = %126, %130
%131 = phi i64 [ %134, %130 ], [ %127, %126 ]
%132 = phi i8* [ %135, %130 ], [ %128, %126 ]
%133 = phi i8* [ %137, %130 ], [ %129, %126 ]
%134 = add i64 %131, -1
%135 = getelementptr inbounds i8, i8* %132, i64 1
%136 = load i8, i8* %132
%137 = getelementptr inbounds i8, i8* %133, i64 1
store i8 %136, i8* %133
%138 = icmp ne i8 %136, 0
%139 = icmp ne i64 %134, 0
%140 = select i1 %138, i1 %139, i1 false
br i1 %140, label %130, label %141
141: ; preds = %14, %26, %38, %50, %62, %74, %86, %98, %130
%142 = phi i64 [ %134, %130 ], [ %15, %14 ], [ %27, %26 ], [ %39, %38 ], [ %51, %50 ], [ %63, %62 ], [ %75, %74 ], [ %87, %86 ], [ %99, %98 ]
%143 = phi i8* [ %137, %130 ], [ %18, %14 ], [ %30, %26 ], [ %42, %38 ], [ %54, %50 ], [ %66, %62 ], [ %78, %74 ], [ %90, %86 ], [ %101, %98 ]
%144 = icmp eq i64 %142, 0
br i1 %144, label %147, label %145
145: ; preds = %141
%146 = tail call i32 @memset(i8* %143, i8 signext 0, i64 %142)
br label %147
147: ; preds = %121, %145, %141
ret i8* %0
}