#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*/ moduloTwoDivision(char *, int, char *, char *, int);
int /*<<< orphan*/ printf(char *, ...);
int crcDecoder(char codeword[], char divisor[], int n, int k) {
  int i;
  char dataword[k];
  char remain[n - k + 1];
  moduloTwoDivision(codeword, n, divisor, remain, n - k + 1);
  int recovered = 1;
  for (i = 0; i < n - k; i++)
    if (remain[i] != '0')
      recovered = 0;
  if (!recovered)
    printf("\nNot able to recover message\n");
  else {
    printf("\nMessage recovered\n");
    for (i = 0; i < k; i++) {
      dataword[i] = codeword[i];
      printf("%c", dataword[i]);
    }
    printf("\n");
  }
}


x86 assembly (clang, -O0):
<crcDecoder>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
mov    %edx,-0x1c(%rbp)
mov    %ecx,-0x20(%rbp)
mov    -0x20(%rbp),%eax
mov    %rsp,%rcx
mov    %rcx,-0x30(%rbp)
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x58(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x38(%rbp)
mov    -0x1c(%rbp),%eax
mov    -0x20(%rbp),%ecx
sub    %ecx,%eax
add    $0x1,%eax
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x50(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x40(%rbp)
mov    -0x10(%rbp),%rdi
mov    -0x1c(%rbp),%esi
mov    -0x18(%rbp),%rdx
mov    -0x1c(%rbp),%r8d
sub    -0x20(%rbp),%r8d
add    $0x1,%r8d
call   1040 <moduloTwoDivision@plt>
movl   $0x1,-0x44(%rbp)
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
mov    -0x1c(%rbp),%ecx
sub    -0x20(%rbp),%ecx
cmp    %ecx,%eax
jge    11ed <crcDecoder+0xcd>
mov    -0x50(%rbp),%rax
movslq -0x24(%rbp),%rcx
movsbl (%rax,%rcx,1),%eax
cmp    $0x30,%eax
je     11da <crcDecoder+0xba>
movl   $0x0,-0x44(%rbp)
jmp    11df <crcDecoder+0xbf>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    11ad <crcDecoder+0x8d>
cmpl   $0x0,-0x44(%rbp)
jne    120a <crcDecoder+0xea>
lea    0xe02(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
jmp    1273 <crcDecoder+0x153>
lea    0xe0d(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
movl   $0x0,-0x24(%rbp)
mov    -0x24(%rbp),%eax
cmp    -0x20(%rbp),%eax
jge    1265 <crcDecoder+0x145>
mov    -0x58(%rbp),%rax
mov    -0x10(%rbp),%rcx
movslq -0x24(%rbp),%rdx
mov    (%rcx,%rdx,1),%dl
movslq -0x24(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
movslq -0x24(%rbp),%rcx
movsbl (%rax,%rcx,1),%esi
lea    0xde2(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
jmp    121f <crcDecoder+0xff>
lea    0xdc4(%rip),%rdi
mov    $0x0,%al
call   1030 <printf@plt>
mov    -0x30(%rbp),%rax
mov    %rax,%rsp
mov    -0x4(%rbp),%eax
mov    %rbp,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<crcDecoder>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r12
push   %rbx
mov    %ecx,%r14d
mov    %rsi,%rax
mov    %rdi,%r15
mov    %edx,%r12d
sub    %ecx,%r12d
lea    0x1(%r12),%r8d
lea    0xf(%r8),%rcx
and    $0xfffffffffffffff0,%rcx
mov    %rsp,%rbx
sub    %rcx,%rbx
mov    %rbx,%rsp
mov    %edx,%esi
mov    %rax,%rdx
mov    %rbx,%rcx
call   1050 <moduloTwoDivision@plt>
test   %r12d,%r12d
jle    12b4 <crcDecoder+0x184>
mov    %r12d,%eax
xor    %ecx,%ecx
cmp    $0x8,%r12d
jae    118d <crcDecoder+0x5d>
mov    $0x1,%esi
xor    %edx,%edx
jmp    12a0 <crcDecoder+0x170>
mov    %eax,%edx
and    $0xfffffff8,%edx
lea    -0x8(%rdx),%rsi
mov    %rsi,%r8
shr    $0x3,%r8
add    $0x1,%r8
test   %rsi,%rsi
je     1308 <crcDecoder+0x1d8>
mov    %r8,%rsi
and    $0xfffffffffffffffe,%rsi
movdqa 0xe47(%rip),%xmm0
xor    %edi,%edi
movdqa 0xe4d(%rip),%xmm2
movdqa %xmm0,%xmm1
nopw   0x0(%rax,%rax,1)
movd   0x4(%rbx,%rdi,1),%xmm3
movdqa (%rbx,%rdi,1),%xmm4
pcmpeqb %xmm2,%xmm4
pcmpeqb %xmm2,%xmm3
movq   0x8(%rbx,%rdi,1),%xmm5
movd   0xc(%rbx,%rdi,1),%xmm6
pcmpeqb %xmm2,%xmm5
pand   %xmm4,%xmm5
punpcklbw %xmm5,%xmm4
punpcklwd %xmm4,%xmm4
pcmpeqb %xmm2,%xmm6
pand   %xmm3,%xmm6
punpcklbw %xmm6,%xmm3
punpcklwd %xmm3,%xmm3
psrad  $0x18,%xmm4
pand   %xmm4,%xmm0
psrad  $0x18,%xmm3
pand   %xmm3,%xmm1
add    $0x10,%rdi
add    $0xfffffffffffffffe,%rsi
jne    11d0 <crcDecoder+0xa0>
test   $0x1,%r8b
je     126e <crcDecoder+0x13e>
movq   (%rbx,%rdi,1),%xmm2
movd   0x4(%rbx,%rdi,1),%xmm3
movdqa 0xdcc(%rip),%xmm4
pcmpeqb %xmm4,%xmm2
punpcklbw %xmm2,%xmm2
punpcklwd %xmm2,%xmm2
psrad  $0x18,%xmm2
pand   %xmm2,%xmm0
pcmpeqb %xmm4,%xmm3
punpcklbw %xmm3,%xmm2
punpcklwd %xmm2,%xmm2
psrad  $0x18,%xmm2
pand   %xmm2,%xmm1
movdqa 0xd8a(%rip),%xmm2
movdqa %xmm0,%xmm3
pcmpeqd %xmm2,%xmm3
pand   %xmm3,%xmm1
pandn  %xmm0,%xmm3
por    %xmm1,%xmm3
pcmpeqd %xmm2,%xmm3
movmskps %xmm3,%edi
xor    %esi,%esi
cmp    $0xf,%edi
sete   %sil
cmp    %rax,%rdx
je     12b0 <crcDecoder+0x180>
nop
cmpb   $0x30,(%rbx,%rdx,1)
cmovne %ecx,%esi
add    $0x1,%rdx
cmp    %rdx,%rax
jne    12a0 <crcDecoder+0x170>
test   %esi,%esi
je     12ef <crcDecoder+0x1bf>
lea    0xd82(%rip),%rdi
call   1040 <puts@plt>
test   %r14d,%r14d
jle    12e3 <crcDecoder+0x1b3>
mov    %r14d,%r14d
xor    %ebx,%ebx
nopw   0x0(%rax,%rax,1)
movsbl (%r15,%rbx,1),%edi
call   1030 <putchar@plt>
add    $0x1,%rbx
cmp    %rbx,%r14
jne    12d0 <crcDecoder+0x1a0>
mov    $0xa,%edi
call   1030 <putchar@plt>
jmp    12fb <crcDecoder+0x1cb>
lea    0xd2a(%rip),%rdi
call   1040 <puts@plt>
lea    -0x20(%rbp),%rsp
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret
movdqa 0xcf0(%rip),%xmm0
xor    %edi,%edi
movdqa %xmm0,%xmm1
test   $0x1,%r8b
jne    1231 <crcDecoder+0x101>
jmp    126e <crcDecoder+0x13e>

LLVM IR (-O0):
@.str = [30 x i8] c"\0ANot able to recover message\0A\00"
@.str.1 = [20 x i8] c"\0AMessage recovered\0A\00"
@.str.2 = [3 x i8] c"%c\00"
@.str.3 = [2 x i8] c"\0A\00"
define i32 @crcDecoder(i8* %0, i8* %1, i32 %2, i32 %3) {
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i8*
%8 = alloca i32
%9 = alloca i32
%10 = alloca i32
%11 = alloca i8*
%12 = alloca i64
%13 = alloca i64
%14 = alloca i32
store i8* %0, i8** %6
store i8* %1, i8** %7
store i32 %2, i32* %8
store i32 %3, i32* %9
%15 = load i32, i32* %9
%16 = zext i32 %15 to i64
%17 = call i8* @llvm.stacksave()
store i8* %17, i8** %11
%18 = alloca i8, i64 %16
store i64 %16, i64* %12
%19 = load i32, i32* %8
%20 = load i32, i32* %9
%21 = sub nsw i32 %19, %20
%22 = add nsw i32 %21, 1
%23 = zext i32 %22 to i64
%24 = alloca i8, i64 %23
store i64 %23, i64* %13
%25 = load i8*, i8** %6
%26 = load i32, i32* %8
%27 = load i8*, i8** %7
%28 = load i32, i32* %8
%29 = load i32, i32* %9
%30 = sub nsw i32 %28, %29
%31 = add nsw i32 %30, 1
%32 = call i32 @moduloTwoDivision(i8* %25, i32 %26, i8* %27, i8* %24, i32 %31)
store i32 1, i32* %14
store i32 0, i32* %10
br label %33
33: ; preds = %48, %4
%34 = load i32, i32* %10
%35 = load i32, i32* %8
%36 = load i32, i32* %9
%37 = sub nsw i32 %35, %36
%38 = icmp slt i32 %34, %37
br i1 %38, label %39, label %51
39: ; preds = %33
%40 = load i32, i32* %10
%41 = sext i32 %40 to i64
%42 = getelementptr inbounds i8, i8* %24, i64 %41
%43 = load i8, i8* %42
%44 = sext i8 %43 to i32
%45 = icmp ne i32 %44, 48
br i1 %45, label %46, label %47
46: ; preds = %39
store i32 0, i32* %14
br label %47
47: ; preds = %46, %39
br label %48
48: ; preds = %47
%49 = load i32, i32* %10
%50 = add nsw i32 %49, 1
store i32 %50, i32* %10
br label %33
51: ; preds = %33
%52 = load i32, i32* %14
%53 = icmp ne i32 %52, 0
br i1 %53, label %56, label %54
54: ; preds = %51
%55 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str, i64 0, i64 0))
br label %82
56: ; preds = %51
%57 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.1, i64 0, i64 0))
store i32 0, i32* %10
br label %58
58: ; preds = %77, %56
%59 = load i32, i32* %10
%60 = load i32, i32* %9
%61 = icmp slt i32 %59, %60
br i1 %61, label %62, label %80
62: ; preds = %58
%63 = load i8*, i8** %6
%64 = load i32, i32* %10
%65 = sext i32 %64 to i64
%66 = getelementptr inbounds i8, i8* %63, i64 %65
%67 = load i8, i8* %66
%68 = load i32, i32* %10
%69 = sext i32 %68 to i64
%70 = getelementptr inbounds i8, i8* %18, i64 %69
store i8 %67, i8* %70
%71 = load i32, i32* %10
%72 = sext i32 %71 to i64
%73 = getelementptr inbounds i8, i8* %18, i64 %72
%74 = load i8, i8* %73
%75 = sext i8 %74 to i32
%76 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.2, i64 0, i64 0), i32 %75)
br label %77
77: ; preds = %62
%78 = load i32, i32* %10
%79 = add nsw i32 %78, 1
store i32 %79, i32* %10
br label %58
80: ; preds = %58
%81 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
br label %82
82: ; preds = %80, %54
%83 = load i8*, i8** %11
%84 = load i32, i32* %5
ret i32 %84
}

LLVM IR (-O2):
@str = [29 x i8] c"\0ANot able to recover message\00"
@str.4 = [19 x i8] c"\0AMessage recovered\00"
define i32 @crcDecoder(i8* %0, i8* %1, i32 %2, i32 %3) {
%5 = sub nsw i32 %2, %3
%6 = add nsw i32 %5, 1
%7 = zext i32 %6 to i64
%8 = alloca i8, i64 %7
%9 = call i32 @moduloTwoDivision(i8* %0, i32 %2, i8* %1, i8* %8, i32 %6)
%10 = icmp sgt i32 %5, 0
br i1 %10, label %11, label %97
11: ; preds = %4
%12 = zext i32 %5 to i64
%13 = icmp ult i32 %5, 8
br i1 %13, label %80, label %14
14: ; preds = %11
%15 = and i64 %12, 4294967288
%16 = add nsw i64 %15, -8
%17 = lshr exact i64 %16, 3
%18 = add nuw nsw i64 %17, 1
%19 = and i64 %18, 1
%20 = icmp eq i64 %16, 0
br i1 %20, label %52, label %21
21: ; preds = %14
%22 = and i64 %18, 4611686018427387902
br label %23
23: ; preds = %23, %21
%24 = phi i64 [ 0, %21 ], [ %49, %23 ]
%25 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %21 ], [ %46, %23 ]
%26 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %21 ], [ %48, %23 ]
%27 = phi i64 [ 0, %21 ], [ %50, %23 ]
%28 = getelementptr inbounds i8, i8* %8, i64 %24
%29 = bitcast i8* %28 to <4 x i8>*
%30 = load <4 x i8>, <4 x i8>* %29
%31 = getelementptr inbounds i8, i8* %28, i64 4
%32 = bitcast i8* %31 to <4 x i8>*
%33 = load <4 x i8>, <4 x i8>* %32
%34 = icmp eq <4 x i8> %30, <i8 48, i8 48, i8 48, i8 48>
%35 = icmp eq <4 x i8> %33, <i8 48, i8 48, i8 48, i8 48>
%36 = or i64 %24, 8
%37 = getelementptr inbounds i8, i8* %8, i64 %36
%38 = bitcast i8* %37 to <4 x i8>*
%39 = load <4 x i8>, <4 x i8>* %38
%40 = getelementptr inbounds i8, i8* %37, i64 4
%41 = bitcast i8* %40 to <4 x i8>*
%42 = load <4 x i8>, <4 x i8>* %41
%43 = icmp eq <4 x i8> %39, <i8 48, i8 48, i8 48, i8 48>
%44 = icmp eq <4 x i8> %42, <i8 48, i8 48, i8 48, i8 48>
%45 = select <4 x i1> %43, <4 x i1> %34, <4 x i1> zeroinitializer
%46 = select <4 x i1> %45, <4 x i32> %25, <4 x i32> zeroinitializer
%47 = select <4 x i1> %44, <4 x i1> %35, <4 x i1> zeroinitializer
%48 = select <4 x i1> %47, <4 x i32> %26, <4 x i32> zeroinitializer
%49 = add nuw i64 %24, 16
%50 = add i64 %27, 2
%51 = icmp eq i64 %50, %22
br i1 %51, label %52, label %23
52: ; preds = %23, %14
%53 = phi <4 x i32> [ undef, %14 ], [ %46, %23 ]
%54 = phi <4 x i32> [ undef, %14 ], [ %48, %23 ]
%55 = phi i64 [ 0, %14 ], [ %49, %23 ]
%56 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %14 ], [ %46, %23 ]
%57 = phi <4 x i32> [ <i32 1, i32 1, i32 1, i32 1>, %14 ], [ %48, %23 ]
%58 = icmp eq i64 %19, 0
br i1 %58, label %70, label %59
59: ; preds = %52
%60 = getelementptr inbounds i8, i8* %8, i64 %55
%61 = bitcast i8* %60 to <4 x i8>*
%62 = load <4 x i8>, <4 x i8>* %61
%63 = getelementptr inbounds i8, i8* %60, i64 4
%64 = bitcast i8* %63 to <4 x i8>*
%65 = load <4 x i8>, <4 x i8>* %64
%66 = icmp eq <4 x i8> %62, <i8 48, i8 48, i8 48, i8 48>
%67 = icmp eq <4 x i8> %65, <i8 48, i8 48, i8 48, i8 48>
%68 = select <4 x i1> %66, <4 x i32> %56, <4 x i32> zeroinitializer
%69 = select <4 x i1> %67, <4 x i32> %57, <4 x i32> zeroinitializer
br label %70
70: ; preds = %52, %59
%71 = phi <4 x i32> [ %53, %52 ], [ %68, %59 ]
%72 = phi <4 x i32> [ %54, %52 ], [ %69, %59 ]
%73 = icmp eq <4 x i32> %71, <i32 1, i32 1, i32 1, i32 1>
%74 = select <4 x i1> %73, <4 x i32> %72, <4 x i32> %71
%75 = icmp ne <4 x i32> %74, <i32 1, i32 1, i32 1, i32 1>
%76 = bitcast <4 x i1> %75 to i4
%77 = icmp eq i4 %76, 0
%78 = zext i1 %77 to i32
%79 = icmp eq i64 %15, %12
br i1 %79, label %92, label %80
80: ; preds = %11, %70
%81 = phi i64 [ 0, %11 ], [ %15, %70 ]
%82 = phi i32 [ 1, %11 ], [ %78, %70 ]
br label %83
83: ; preds = %80, %83
%84 = phi i64 [ %90, %83 ], [ %81, %80 ]
%85 = phi i32 [ %89, %83 ], [ %82, %80 ]
%86 = getelementptr inbounds i8, i8* %8, i64 %84
%87 = load i8, i8* %86
%88 = icmp eq i8 %87, 48
%89 = select i1 %88, i32 %85, i32 0
%90 = add nuw nsw i64 %84, 1
%91 = icmp eq i64 %90, %12
br i1 %91, label %92, label %83
92: ; preds = %83, %70
%93 = phi i32 [ %78, %70 ], [ %89, %83 ]
%94 = icmp eq i32 %93, 0
br i1 %94, label %95, label %97
95: ; preds = %92
%96 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([29 x i8], [29 x i8]* @str, i64 0, i64 0))
br label %112
97: ; preds = %4, %92
%98 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([19 x i8], [19 x i8]* @str.4, i64 0, i64 0))
%99 = icmp sgt i32 %3, 0
br i1 %99, label %100, label %110
100: ; preds = %97
%101 = zext i32 %3 to i64
br label %102
102: ; preds = %100, %102
%103 = phi i64 [ 0, %100 ], [ %108, %102 ]
%104 = getelementptr inbounds i8, i8* %0, i64 %103
%105 = load i8, i8* %104
%106 = sext i8 %105 to i32
%107 = call i32 @putchar(i32 %106)
%108 = add nuw nsw i64 %103, 1
%109 = icmp eq i64 %108, %101
br i1 %109, label %110, label %102
110: ; preds = %102, %97
%111 = call i32 @putchar(i32 10)
br label %112
112: ; preds = %110, %95
ret i32 undef
}