unsigned int memtest_sub(unsigned int start, unsigned int end) {
  unsigned int i, *p, old, pat0 = 0xaa55aa55, pat1 = 0x55aa55aa;
  for (i = start; i <= end; i += 0x1000) {
    p = (unsigned int *)(i + 0xffc);
    old = *p;
    *p = pat0;
    *p ^= 0xffffffff;
    if (*p != pat1) {
    not_memory:
      *p = old;
      break;
    }
    *p ^= 0xffffffff;
    if (*p != pat0) {
      goto not_memory;
    }
    *p = old;
  }
  return i;
}


x86 assembly (clang, -O0):
<memtest_sub>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %esi,-0x8(%rbp)
movl   $0xaa55aa55,-0x20(%rbp)
movl   $0x55aa55aa,-0x24(%rbp)
mov    -0x4(%rbp),%eax
mov    %eax,-0xc(%rbp)
mov    -0xc(%rbp),%eax
cmp    -0x8(%rbp),%eax
ja     11af <memtest_sub+0xaf>
mov    -0xc(%rbp),%eax
add    $0xffc,%eax
mov    %eax,%eax
mov    %rax,-0x18(%rbp)
mov    -0x18(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x1c(%rbp)
mov    -0x20(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x18(%rbp),%rax
mov    (%rax),%ecx
xor    $0xffffffff,%ecx
mov    %ecx,(%rax)
mov    -0x18(%rbp),%rax
mov    (%rax),%eax
cmp    -0x24(%rbp),%eax
je     1177 <memtest_sub+0x77>
jmp    1169 <memtest_sub+0x69>
mov    -0x1c(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
jmp    11af <memtest_sub+0xaf>
mov    -0x18(%rbp),%rax
mov    (%rax),%ecx
xor    $0xffffffff,%ecx
mov    %ecx,(%rax)
mov    -0x18(%rbp),%rax
mov    (%rax),%eax
cmp    -0x20(%rbp),%eax
je     1196 <memtest_sub+0x96>
jmp    1169 <memtest_sub+0x69>
mov    -0x1c(%rbp),%ecx
mov    -0x18(%rbp),%rax
mov    %ecx,(%rax)
mov    -0xc(%rbp),%eax
add    $0x1000,%eax
mov    %eax,-0xc(%rbp)
jmp    111e <memtest_sub+0x1e>
mov    -0xc(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<memtest_sub>:
lea    0x1(%rsi),%eax
xor    %ecx,%ecx
sub    %edi,%eax
cmovb  %ecx,%eax
add    $0xfff,%eax
and    $0xfffff000,%eax
add    %edi,%eax
ret

LLVM IR (-O0):
define i32 @memtest_sub(i32 %0, i32 %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32*
%7 = alloca i32
%8 = alloca i32
%9 = alloca i32
store i32 %0, i32* %3
store i32 %1, i32* %4
store i32 -1437226411, i32* %8
store i32 1437226410, i32* %9
%10 = load i32, i32* %3
store i32 %10, i32* %5
br label %11
11: ; preds = %47, %2
%12 = load i32, i32* %5
%13 = load i32, i32* %4
%14 = icmp ule i32 %12, %13
br i1 %14, label %15, label %50
15: ; preds = %11
%16 = load i32, i32* %5
%17 = add i32 %16, 4092
%18 = zext i32 %17 to i64
%19 = inttoptr i64 %18 to i32*
store i32* %19, i32** %6
%20 = load i32*, i32** %6
%21 = load i32, i32* %20
store i32 %21, i32* %7
%22 = load i32, i32* %8
%23 = load i32*, i32** %6
store i32 %22, i32* %23
%24 = load i32*, i32** %6
%25 = load i32, i32* %24
%26 = xor i32 %25, -1
store i32 %26, i32* %24
%27 = load i32*, i32** %6
%28 = load i32, i32* %27
%29 = load i32, i32* %9
%30 = icmp ne i32 %28, %29
br i1 %30, label %31, label %35
31: ; preds = %15
br label %32
32: ; preds = %43, %31
%33 = load i32, i32* %7
%34 = load i32*, i32** %6
store i32 %33, i32* %34
br label %50
35: ; preds = %15
%36 = load i32*, i32** %6
%37 = load i32, i32* %36
%38 = xor i32 %37, -1
store i32 %38, i32* %36
%39 = load i32*, i32** %6
%40 = load i32, i32* %39
%41 = load i32, i32* %8
%42 = icmp ne i32 %40, %41
br i1 %42, label %43, label %44
43: ; preds = %35
br label %32
44: ; preds = %35
%45 = load i32, i32* %7
%46 = load i32*, i32** %6
store i32 %45, i32* %46
br label %47
47: ; preds = %44
%48 = load i32, i32* %5
%49 = add i32 %48, 4096
store i32 %49, i32* %5
br label %11
50: ; preds = %32, %11
%51 = load i32, i32* %5
ret i32 %51
}

LLVM IR (-O2):
define i32 @memtest_sub(i32 %0, i32 %1) {
%3 = add nuw i32 %1, 1
%4 = call i32 @llvm.umax.i32(i32 %0, i32 %3)
%5 = add i32 %4, 4095
%6 = sub i32 %5, %0
%7 = and i32 %6, -4096
%8 = add i32 %7, %0
ret i32 %8
}