#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 */
typedef size_t uint8_t;
typedef size_t uint32_t;

/* Variables and functions */
uint32_t canopen_decode_uint(uint8_t *data, uint8_t len) {
  uint8_t n;
  uint32_t value = 0;
  if (data == NULL)
    return value;
  for (n = 0; n < len; n++)
    value += data[n] << (8 * n);
  return value;
}


x86 assembly (clang, -O0):
<canopen_decode_uint>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %rsi,-0x18(%rbp)
movq   $0x0,-0x28(%rbp)
cmpq   $0x0,-0x10(%rbp)
jne    112c <canopen_decode_uint+0x2c>
mov    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
jmp    117a <canopen_decode_uint+0x7a>
movq   $0x0,-0x20(%rbp)
mov    -0x20(%rbp),%rax
cmp    -0x18(%rbp),%rax
jae    1172 <canopen_decode_uint+0x72>
mov    -0x10(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rax,%rcx,8),%rax
mov    -0x20(%rbp),%rcx
shl    $0x3,%rcx
shl    %cl,%rax
add    -0x28(%rbp),%rax
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x20(%rbp)
jmp    1134 <canopen_decode_uint+0x34>
mov    -0x28(%rbp),%rax
mov    %rax,-0x8(%rbp)
mov    -0x8(%rbp),%rax
pop    %rbp
ret

x86 assembly (clang, -O2):
<canopen_decode_uint>:
xor    %eax,%eax
test   %rdi,%rdi
je     12c4 <canopen_decode_uint+0x1c4>
test   %rsi,%rsi
je     12c4 <canopen_decode_uint+0x1c4>
cmp    $0x4,%rsi
jae    1123 <canopen_decode_uint+0x23>
xor    %eax,%eax
xor    %ecx,%ecx
jmp    129e <canopen_decode_uint+0x19e>
mov    %rsi,%rcx
and    $0xfffffffffffffffc,%rcx
lea    -0x4(%rcx),%rax
mov    %rax,%r8
shr    $0x2,%r8
add    $0x1,%r8
test   %rax,%rax
je     12c5 <canopen_decode_uint+0x1c5>
mov    %r8,%rax
and    $0xfffffffffffffffe,%rax
movdqa 0xebe(%rip),%xmm12
pxor   %xmm0,%xmm0
xor    %edx,%edx
movdqa 0xebf(%rip),%xmm8
movdqa 0xec6(%rip),%xmm9
movdqa 0xecd(%rip),%xmm10
movdqa 0xed4(%rip),%xmm11
pxor   %xmm2,%xmm2
movdqa %xmm12,%xmm1
psllq  $0x3,%xmm1
movdqa %xmm1,%xmm5
paddq  %xmm8,%xmm5
movdqu (%rdi,%rdx,8),%xmm4
movdqu 0x10(%rdi,%rdx,8),%xmm7
movdqa %xmm4,%xmm6
psllq  %xmm1,%xmm6
pshufd $0xee,%xmm1,%xmm3
psllq  %xmm3,%xmm4
movsd  %xmm6,%xmm4
paddq  %xmm0,%xmm4
movdqu 0x20(%rdi,%rdx,8),%xmm0
movdqa %xmm7,%xmm3
psllq  %xmm5,%xmm3
pshufd $0xee,%xmm5,%xmm5
psllq  %xmm5,%xmm7
movsd  %xmm3,%xmm7
paddq  %xmm2,%xmm7
movdqu 0x30(%rdi,%rdx,8),%xmm2
movdqa %xmm1,%xmm3
paddq  %xmm9,%xmm3
movdqa %xmm0,%xmm5
psllq  %xmm3,%xmm5
paddq  %xmm10,%xmm1
pshufd $0xee,%xmm3,%xmm3
psllq  %xmm3,%xmm0
movsd  %xmm5,%xmm0
paddq  %xmm4,%xmm0
movdqa %xmm2,%xmm3
psllq  %xmm1,%xmm3
pshufd $0xee,%xmm1,%xmm1
psllq  %xmm1,%xmm2
movsd  %xmm3,%xmm2
paddq  %xmm7,%xmm2
add    $0x8,%rdx
paddq  %xmm11,%xmm12
add    $0xfffffffffffffffe,%rax
jne    1180 <canopen_decode_uint+0x80>
psllq  $0x3,%xmm12
test   $0x1,%r8b
je     1287 <canopen_decode_uint+0x187>
movdqu (%rdi,%rdx,8),%xmm1
movdqu 0x10(%rdi,%rdx,8),%xmm3
movdqa 0xdd2(%rip),%xmm4
paddq  %xmm12,%xmm4
movdqa %xmm1,%xmm5
psllq  %xmm12,%xmm5
pshufd $0xee,%xmm12,%xmm6
psllq  %xmm6,%xmm1
movsd  %xmm5,%xmm1
paddq  %xmm1,%xmm0
movdqa %xmm3,%xmm1
psllq  %xmm4,%xmm1
pshufd $0xee,%xmm4,%xmm4
psllq  %xmm4,%xmm3
movsd  %xmm1,%xmm3
paddq  %xmm3,%xmm2
paddq  %xmm2,%xmm0
pshufd $0xee,%xmm0,%xmm1
paddq  %xmm0,%xmm1
movq   %xmm1,%rax
cmp    %rsi,%rcx
je     12c4 <canopen_decode_uint+0x1c4>
sub    %rcx,%rsi
shl    $0x3,%rcx
cs nopw 0x0(%rax,%rax,1)
nop
mov    (%rdi,%rcx,1),%rdx
shl    %cl,%rdx
add    %rdx,%rax
add    $0x8,%rcx
add    $0xffffffffffffffff,%rsi
jne    12b0 <canopen_decode_uint+0x1b0>
ret
movdqa 0xd32(%rip),%xmm12
pxor   %xmm0,%xmm0
xor    %edx,%edx
pxor   %xmm2,%xmm2
test   $0x1,%r8b
jne    123b <canopen_decode_uint+0x13b>
jmp    1287 <canopen_decode_uint+0x187>

LLVM IR (-O0):
define i64 @canopen_decode_uint(i64* %0, i64 %1) {
%3 = alloca i64
%4 = alloca i64*
%5 = alloca i64
%6 = alloca i64
%7 = alloca i64
store i64* %0, i64** %4
store i64 %1, i64* %5
store i64 0, i64* %7
%8 = load i64*, i64** %4
%9 = icmp eq i64* %8, null
br i1 %9, label %10, label %12
10: ; preds = %2
%11 = load i64, i64* %7
store i64 %11, i64* %3
br label %32
12: ; preds = %2
store i64 0, i64* %6
br label %13
13: ; preds = %27, %12
%14 = load i64, i64* %6
%15 = load i64, i64* %5
%16 = icmp ult i64 %14, %15
br i1 %16, label %17, label %30
17: ; preds = %13
%18 = load i64*, i64** %4
%19 = load i64, i64* %6
%20 = getelementptr inbounds i64, i64* %18, i64 %19
%21 = load i64, i64* %20
%22 = load i64, i64* %6
%23 = mul i64 8, %22
%24 = shl i64 %21, %23
%25 = load i64, i64* %7
%26 = add i64 %25, %24
store i64 %26, i64* %7
br label %27
27: ; preds = %17
%28 = load i64, i64* %6
%29 = add i64 %28, 1
store i64 %29, i64* %6
br label %13
30: ; preds = %13
%31 = load i64, i64* %7
store i64 %31, i64* %3
br label %32
32: ; preds = %30, %10
%33 = load i64, i64* %3
ret i64 %33
}

LLVM IR (-O2):
define i64 @canopen_decode_uint(i64* %0, i64 %1) {
%3 = icmp ne i64* %0, null
%4 = icmp ne i64 %1, 0
%5 = and i1 %3, %4
br i1 %5, label %6, label %96
6: ; preds = %2
%7 = icmp ult i64 %1, 4
br i1 %7, label %83, label %8
8: ; preds = %6
%9 = and i64 %1, -4
%10 = add i64 %9, -4
%11 = lshr exact i64 %10, 2
%12 = add nuw nsw i64 %11, 1
%13 = and i64 %12, 1
%14 = icmp eq i64 %10, 0
br i1 %14, label %57, label %15
15: ; preds = %8
%16 = and i64 %12, 9223372036854775806
br label %17
17: ; preds = %17, %15
%18 = phi i64 [ 0, %15 ], [ %51, %17 ]
%19 = phi <2 x i64> [ zeroinitializer, %15 ], [ %49, %17 ]
%20 = phi <2 x i64> [ zeroinitializer, %15 ], [ %50, %17 ]
%21 = phi <2 x i64> [ <i64 0, i64 1>, %15 ], [ %52, %17 ]
%22 = phi i64 [ 0, %15 ], [ %53, %17 ]
%23 = getelementptr inbounds i64, i64* %0, i64 %18
%24 = bitcast i64* %23 to <2 x i64>*
%25 = load <2 x i64>, <2 x i64>* %24
%26 = getelementptr inbounds i64, i64* %23, i64 2
%27 = bitcast i64* %26 to <2 x i64>*
%28 = load <2 x i64>, <2 x i64>* %27
%29 = shl <2 x i64> %21, <i64 3, i64 3>
%30 = shl <2 x i64> %21, <i64 3, i64 3>
%31 = add <2 x i64> %30, <i64 16, i64 16>
%32 = shl <2 x i64> %25, %29
%33 = shl <2 x i64> %28, %31
%34 = add <2 x i64> %32, %19
%35 = add <2 x i64> %33, %20
%36 = or i64 %18, 4
%37 = add <2 x i64> %21, <i64 4, i64 4>
%38 = getelementptr inbounds i64, i64* %0, i64 %36
%39 = bitcast i64* %38 to <2 x i64>*
%40 = load <2 x i64>, <2 x i64>* %39
%41 = getelementptr inbounds i64, i64* %38, i64 2
%42 = bitcast i64* %41 to <2 x i64>*
%43 = load <2 x i64>, <2 x i64>* %42
%44 = shl <2 x i64> %37, <i64 3, i64 3>
%45 = shl <2 x i64> %37, <i64 3, i64 3>
%46 = add <2 x i64> %45, <i64 16, i64 16>
%47 = shl <2 x i64> %40, %44
%48 = shl <2 x i64> %43, %46
%49 = add <2 x i64> %47, %34
%50 = add <2 x i64> %48, %35
%51 = add nuw i64 %18, 8
%52 = add <2 x i64> %21, <i64 8, i64 8>
%53 = add i64 %22, 2
%54 = icmp eq i64 %53, %16
br i1 %54, label %55, label %17
55: ; preds = %17
%56 = shl <2 x i64> %52, <i64 3, i64 3>
br label %57
57: ; preds = %55, %8
%58 = phi <2 x i64> [ undef, %8 ], [ %49, %55 ]
%59 = phi <2 x i64> [ undef, %8 ], [ %50, %55 ]
%60 = phi i64 [ 0, %8 ], [ %51, %55 ]
%61 = phi <2 x i64> [ zeroinitializer, %8 ], [ %49, %55 ]
%62 = phi <2 x i64> [ zeroinitializer, %8 ], [ %50, %55 ]
%63 = phi <2 x i64> [ <i64 0, i64 8>, %8 ], [ %56, %55 ]
%64 = icmp eq i64 %13, 0
br i1 %64, label %77, label %65
65: ; preds = %57
%66 = getelementptr inbounds i64, i64* %0, i64 %60
%67 = bitcast i64* %66 to <2 x i64>*
%68 = load <2 x i64>, <2 x i64>* %67
%69 = getelementptr inbounds i64, i64* %66, i64 2
%70 = bitcast i64* %69 to <2 x i64>*
%71 = load <2 x i64>, <2 x i64>* %70
%72 = add <2 x i64> %63, <i64 16, i64 16>
%73 = shl <2 x i64> %68, %63
%74 = shl <2 x i64> %71, %72
%75 = add <2 x i64> %73, %61
%76 = add <2 x i64> %74, %62
br label %77
77: ; preds = %57, %65
%78 = phi <2 x i64> [ %58, %57 ], [ %75, %65 ]
%79 = phi <2 x i64> [ %59, %57 ], [ %76, %65 ]
%80 = add <2 x i64> %79, %78
%81 = call i64 @llvm.vector.reduce.add.v2i64(<2 x i64> %80)
%82 = icmp eq i64 %9, %1
br i1 %82, label %96, label %83
83: ; preds = %6, %77
%84 = phi i64 [ 0, %6 ], [ %81, %77 ]
%85 = phi i64 [ 0, %6 ], [ %9, %77 ]
br label %86
86: ; preds = %83, %86
%87 = phi i64 [ %93, %86 ], [ %84, %83 ]
%88 = phi i64 [ %94, %86 ], [ %85, %83 ]
%89 = getelementptr inbounds i64, i64* %0, i64 %88
%90 = load i64, i64* %89
%91 = shl i64 %88, 3
%92 = shl i64 %90, %91
%93 = add i64 %92, %87
%94 = add nuw i64 %88, 1
%95 = icmp eq i64 %94, %1
br i1 %95, label %96, label %86
96: ; preds = %86, %77, %2
%97 = phi i64 [ 0, %2 ], [ %81, %77 ], [ %93, %86 ]
ret i64 %97
}