#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 */
void *effective_memset(void *s, unsigned long cs, size_t n) {
  size_t K = sizeof(unsigned long);
  size_t cnt = 0;
  unsigned char *schar = s;
  while (cnt < n) {
    if ((size_t)schar % K == 0) {
      break;
    }
    *schar++ = (unsigned char)cs;
    cnt++;
  }
  unsigned long *slong = (unsigned long *)schar;
  size_t rest = n - cnt;
  size_t loop = rest / K;
  size_t tail = rest % K;
  for (size_t i = 0; i < loop; i++) {
    *slong++ = cs;
  }
  schar = (unsigned char *)slong;
  for (size_t i = 0; i < tail; i++) {
    *schar++ = (unsigned char)cs;
  }
  return s;
}


x86 assembly (clang, -O0):
<effective_memset>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movq   $0x8,-0x20(%rbp)
movq   $0x0,-0x28(%rbp)
mov    -0x8(%rbp),%rax
mov    %rax,-0x30(%rbp)
mov    -0x28(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1179 <effective_memset+0x79>
mov    -0x30(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x20(%rbp)
cmp    $0x0,%rdx
jne    1151 <effective_memset+0x51>
jmp    1179 <effective_memset+0x79>
mov    -0x10(%rbp),%rax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x28(%rbp)
jmp    1128 <effective_memset+0x28>
mov    -0x30(%rbp),%rax
mov    %rax,-0x38(%rbp)
mov    -0x18(%rbp),%rax
sub    -0x28(%rbp),%rax
mov    %rax,-0x40(%rbp)
mov    -0x40(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x20(%rbp)
mov    %rax,-0x48(%rbp)
mov    -0x40(%rbp),%rax
xor    %ecx,%ecx
mov    %ecx,%edx
divq   -0x20(%rbp)
mov    %rdx,-0x50(%rbp)
movq   $0x0,-0x58(%rbp)
mov    -0x58(%rbp),%rax
cmp    -0x48(%rbp),%rax
jae    11ea <effective_memset+0xea>
mov    -0x10(%rbp),%rcx
mov    -0x38(%rbp),%rax
mov    %rax,%rdx
add    $0x8,%rdx
mov    %rdx,-0x38(%rbp)
mov    %rcx,(%rax)
mov    -0x58(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x58(%rbp)
jmp    11b5 <effective_memset+0xb5>
mov    -0x38(%rbp),%rax
mov    %rax,-0x30(%rbp)
movq   $0x0,-0x60(%rbp)
mov    -0x60(%rbp),%rax
cmp    -0x50(%rbp),%rax
jae    1230 <effective_memset+0x130>
mov    -0x10(%rbp),%rax
mov    %al,%cl
mov    -0x30(%rbp),%rax
mov    %rax,%rdx
add    $0x1,%rdx
mov    %rdx,-0x30(%rbp)
mov    %cl,(%rax)
mov    -0x60(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x60(%rbp)
jmp    11fa <effective_memset+0xfa>
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<effective_memset>:
push   %r15
push   %r14
push   %r12
push   %rbx
push   %rax
mov    %rdx,%rbx
mov    %rsi,%r15
mov    %rdi,%r14
xor    %r12d,%r12d
test   %rdx,%rdx
je     116f <effective_memset+0x5f>
mov    %r14d,%eax
and    $0x7,%eax
mov    %r14,%rdi
test   %rax,%rax
je     1172 <effective_memset+0x62>
mov    %r14d,%eax
not    %eax
lea    -0x1(%rbx),%rcx
and    $0x7,%eax
cmp    %rcx,%rax
cmovae %rcx,%rax
add    $0x1,%rax
test   %rcx,%rcx
mov    $0x1,%r12d
cmovne %rax,%r12
mov    %r14,%rdi
mov    %r15d,%esi
mov    %r12,%rdx
call   1030 <memset@plt>
lea    (%r14,%r12,1),%rdi
jmp    1172 <effective_memset+0x62>
mov    %r14,%rdi
sub    %r12,%rbx
mov    %ebx,%edx
and    $0x7,%edx
cmp    $0x8,%rbx
jb     12ad <effective_memset+0x19d>
mov    %rbx,%rax
shr    $0x3,%rax
cmp    $0x20,%rbx
jae    1199 <effective_memset+0x89>
xor    %r8d,%r8d
jmp    129d <effective_memset+0x18d>
mov    %rax,%r8
and    $0xfffffffffffffffc,%r8
movq   %r15,%xmm0
pshufd $0x44,%xmm0,%xmm0
lea    -0x4(%r8),%rcx
mov    %rcx,%rsi
shr    $0x2,%rsi
add    $0x1,%rsi
mov    %esi,%ebx
and    $0x7,%ebx
cmp    $0x1c,%rcx
jae    11cb <effective_memset+0xbb>
xor    %ecx,%ecx
jmp    1265 <effective_memset+0x155>
and    $0xfffffffffffffff8,%rsi
xor    %ecx,%ecx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movdqu %xmm0,(%rdi,%rcx,8)
movdqu %xmm0,0x10(%rdi,%rcx,8)
movdqu %xmm0,0x20(%rdi,%rcx,8)
movdqu %xmm0,0x30(%rdi,%rcx,8)
movdqu %xmm0,0x40(%rdi,%rcx,8)
movdqu %xmm0,0x50(%rdi,%rcx,8)
movdqu %xmm0,0x60(%rdi,%rcx,8)
movdqu %xmm0,0x70(%rdi,%rcx,8)
movdqu %xmm0,0x80(%rdi,%rcx,8)
movdqu %xmm0,0x90(%rdi,%rcx,8)
movdqu %xmm0,0xa0(%rdi,%rcx,8)
movdqu %xmm0,0xb0(%rdi,%rcx,8)
movdqu %xmm0,0xc0(%rdi,%rcx,8)
movdqu %xmm0,0xd0(%rdi,%rcx,8)
movdqu %xmm0,0xe0(%rdi,%rcx,8)
movdqu %xmm0,0xf0(%rdi,%rcx,8)
add    $0x20,%rcx
add    $0xfffffffffffffff8,%rsi
jne    11e0 <effective_memset+0xd0>
test   %rbx,%rbx
je     1294 <effective_memset+0x184>
lea    (%rdi,%rcx,8),%rcx
add    $0x10,%rcx
shl    $0x5,%rbx
xor    %esi,%esi
nopl   0x0(%rax,%rax,1)
movdqu %xmm0,-0x10(%rcx,%rsi,1)
movdqu %xmm0,(%rcx,%rsi,1)
add    $0x20,%rsi
cmp    %rsi,%rbx
jne    1280 <effective_memset+0x170>
lea    (%rdi,%r8,8),%rdi
cmp    %r8,%rax
je     12ad <effective_memset+0x19d>
sub    %r8,%rax
mov    %r15,(%rdi)
add    $0x8,%rdi
add    $0xffffffffffffffff,%rax
jne    12a0 <effective_memset+0x190>
test   %rdx,%rdx
je     12ba <effective_memset+0x1aa>
mov    %r15d,%esi
call   1030 <memset@plt>
mov    %r14,%rax
add    $0x8,%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
ret

LLVM IR (-O0):
define i8* @effective_memset(i8* %0, i64 %1, i64 %2) {
%4 = alloca i8*
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
%8 = alloca i64
%9 = alloca i8*
%10 = alloca i64*
%11 = alloca i64
%12 = alloca i64
%13 = alloca i64
%14 = alloca i64
%15 = alloca i64
store i8* %0, i8** %4
store i64 %1, i64* %5
store i64 %2, i64* %6
store i64 8, i64* %7
store i64 0, i64* %8
%16 = load i8*, i8** %4
store i8* %16, i8** %9
br label %17
17: ; preds = %28, %3
%18 = load i64, i64* %8
%19 = load i64, i64* %6
%20 = icmp ult i64 %18, %19
br i1 %20, label %21, label %35
21: ; preds = %17
%22 = load i8*, i8** %9
%23 = ptrtoint i8* %22 to i64
%24 = load i64, i64* %7
%25 = urem i64 %23, %24
%26 = icmp eq i64 %25, 0
br i1 %26, label %27, label %28
27: ; preds = %21
br label %35
28: ; preds = %21
%29 = load i64, i64* %5
%30 = trunc i64 %29 to i8
%31 = load i8*, i8** %9
%32 = getelementptr inbounds i8, i8* %31, i32 1
store i8* %32, i8** %9
store i8 %30, i8* %31
%33 = load i64, i64* %8
%34 = add i64 %33, 1
store i64 %34, i64* %8
br label %17
35: ; preds = %27, %17
%36 = load i8*, i8** %9
%37 = bitcast i8* %36 to i64*
store i64* %37, i64** %10
%38 = load i64, i64* %6
%39 = load i64, i64* %8
%40 = sub i64 %38, %39
store i64 %40, i64* %11
%41 = load i64, i64* %11
%42 = load i64, i64* %7
%43 = udiv i64 %41, %42
store i64 %43, i64* %12
%44 = load i64, i64* %11
%45 = load i64, i64* %7
%46 = urem i64 %44, %45
store i64 %46, i64* %13
store i64 0, i64* %14
br label %47
47: ; preds = %55, %35
%48 = load i64, i64* %14
%49 = load i64, i64* %12
%50 = icmp ult i64 %48, %49
br i1 %50, label %51, label %58
51: ; preds = %47
%52 = load i64, i64* %5
%53 = load i64*, i64** %10
%54 = getelementptr inbounds i64, i64* %53, i32 1
store i64* %54, i64** %10
store i64 %52, i64* %53
br label %55
55: ; preds = %51
%56 = load i64, i64* %14
%57 = add i64 %56, 1
store i64 %57, i64* %14
br label %47
58: ; preds = %47
%59 = load i64*, i64** %10
%60 = bitcast i64* %59 to i8*
store i8* %60, i8** %9
store i64 0, i64* %15
br label %61
61: ; preds = %70, %58
%62 = load i64, i64* %15
%63 = load i64, i64* %13
%64 = icmp ult i64 %62, %63
br i1 %64, label %65, label %73
65: ; preds = %61
%66 = load i64, i64* %5
%67 = trunc i64 %66 to i8
%68 = load i8*, i8** %9
%69 = getelementptr inbounds i8, i8* %68, i32 1
store i8* %69, i8** %9
store i8 %67, i8* %68
br label %70
70: ; preds = %65
%71 = load i64, i64* %15
%72 = add i64 %71, 1
store i64 %72, i64* %15
br label %61
73: ; preds = %61
%74 = load i8*, i8** %4
ret i8* %74
}

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