#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 int uint8_t;
typedef int uint16_t;

/* Variables and functions */
uint8_t checksum(uint8_t *ptr) {
  uint16_t checksum = 0xff;
  for (int i = 0xfe; i >= 0; i--) {
    if (checksum > 0xff)
      checksum = (checksum + 1) & 0xff;
    checksum += ptr[i];
  }
  return checksum;
}


x86 assembly (clang, -O0):
<checksum>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
movl   $0xff,-0xc(%rbp)
movl   $0xfe,-0x10(%rbp)
cmpl   $0x0,-0x10(%rbp)
jl     115a <checksum+0x5a>
cmpl   $0xff,-0xc(%rbp)
jle    113b <checksum+0x3b>
mov    -0xc(%rbp),%eax
add    $0x1,%eax
and    $0xff,%eax
mov    %eax,-0xc(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x10(%rbp),%rcx
mov    (%rax,%rcx,4),%eax
add    -0xc(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0x10(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x10(%rbp)
jmp    1116 <checksum+0x16>
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<checksum>:
mov    $0xff,%eax
mov    $0xfc,%ecx
nopw   0x0(%rax,%rax,1)
lea    0x1(%rax),%edx
cmp    $0x100,%eax
movzbl %dl,%edx
cmovl  %eax,%edx
mov    0x4(%rdi,%rcx,4),%r8d
mov    0x8(%rdi,%rcx,4),%esi
lea    (%rsi,%rdx,1),%eax
cmp    $0x100,%eax
lea    0x1(%rsi,%rdx,1),%edx
movzbl %dl,%edx
cmovl  %eax,%edx
lea    (%r8,%rdx,1),%esi
cmp    $0x100,%esi
lea    0x1(%r8,%rdx,1),%eax
movzbl %al,%eax
cmovl  %esi,%eax
add    (%rdi,%rcx,4),%eax
add    $0xfffffffffffffffd,%rcx
cmp    $0xfffffffffffffffd,%rcx
jne    1110 <checksum+0x10>
ret

LLVM IR (-O0):
define i32 @checksum(i32* %0) {
%2 = alloca i32*
%3 = alloca i32
%4 = alloca i32
store i32* %0, i32** %2
store i32 255, i32* %3
store i32 254, i32* %4
br label %5
5: ; preds = %23, %1
%6 = load i32, i32* %4
%7 = icmp sge i32 %6, 0
br i1 %7, label %8, label %26
8: ; preds = %5
%9 = load i32, i32* %3
%10 = icmp sgt i32 %9, 255
br i1 %10, label %11, label %15
11: ; preds = %8
%12 = load i32, i32* %3
%13 = add nsw i32 %12, 1
%14 = and i32 %13, 255
store i32 %14, i32* %3
br label %15
15: ; preds = %11, %8
%16 = load i32*, i32** %2
%17 = load i32, i32* %4
%18 = sext i32 %17 to i64
%19 = getelementptr inbounds i32, i32* %16, i64 %18
%20 = load i32, i32* %19
%21 = load i32, i32* %3
%22 = add nsw i32 %21, %20
store i32 %22, i32* %3
br label %23
23: ; preds = %15
%24 = load i32, i32* %4
%25 = add nsw i32 %24, -1
store i32 %25, i32* %4
br label %5
26: ; preds = %5
%27 = load i32, i32* %3
ret i32 %27
}

LLVM IR (-O2):
define i32 @checksum(i32* nocapture %0) {
br label %3
2: ; preds = %3
ret i32 %28
3: ; preds = %3, %1
%4 = phi i64 [ 254, %1 ], [ %29, %3 ]
%5 = phi i32 [ 255, %1 ], [ %28, %3 ]
%6 = icmp sgt i32 %5, 255
%7 = add nsw i32 %5, 1
%8 = and i32 %7, 255
%9 = select i1 %6, i32 %8, i32 %5
%10 = getelementptr inbounds i32, i32* %0, i64 %4
%11 = load i32, i32* %10
%12 = add nsw i32 %11, %9
%13 = add nsw i64 %4, -1
%14 = icmp sgt i32 %12, 255
%15 = add nsw i32 %12, 1
%16 = and i32 %15, 255
%17 = select i1 %14, i32 %16, i32 %12
%18 = getelementptr inbounds i32, i32* %0, i64 %13
%19 = load i32, i32* %18
%20 = add nsw i32 %19, %17
%21 = add nsw i64 %4, -2
%22 = icmp sgt i32 %20, 255
%23 = add nsw i32 %20, 1
%24 = and i32 %23, 255
%25 = select i1 %22, i32 %24, i32 %20
%26 = getelementptr inbounds i32, i32* %0, i64 %21
%27 = load i32, i32* %26
%28 = add nsw i32 %27, %25
%29 = add nsw i64 %4, -3
%30 = icmp eq i64 %21, 0
br i1 %30, label %2, label %3
}