void main() {
  int *p = 100;
  int *q = 200;
  __VERIFIER_assert(p + 5 == 100 + 5 * sizeof(int));
  __VERIFIER_assert(p - 10 == 100 - 10 * sizeof(int));
  __VERIFIER_assert(p - q == -100 / sizeof(int));
  __VERIFIER_assert(q - p == 100 / sizeof(int));
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x10,%rsp
mov    $0x64,%eax
mov    %rax,-0x8(%rbp)
mov    $0xc8,%eax
mov    %rax,-0x10(%rbp)
mov    -0x8(%rbp),%rax
add    $0x14,%rax
mov    $0x78,%ecx
cmp    %rcx,%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <__VERIFIER_assert@plt>
mov    -0x8(%rbp),%rax
add    $0xffffffffffffffd8,%rax
mov    $0x3c,%ecx
cmp    %rcx,%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <__VERIFIER_assert@plt>
mov    -0x8(%rbp),%rax
mov    -0x10(%rbp),%rcx
sub    %rcx,%rax
sar    $0x2,%rax
movabs $0x3fffffffffffffe7,%rcx
ff ff 3f
cmp    %rcx,%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <__VERIFIER_assert@plt>
mov    -0x10(%rbp),%rax
mov    -0x8(%rbp),%rcx
sub    %rcx,%rax
sar    $0x2,%rax
cmp    $0x19,%rax
sete   %al
and    $0x1,%al
movzbl %al,%edi
mov    $0x0,%al
call   1030 <__VERIFIER_assert@plt>
add    $0x10,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<main>:
push   %rax
mov    $0x1,%edi
xor    %eax,%eax
call   1030 <__VERIFIER_assert@plt>
mov    $0x1,%edi
xor    %eax,%eax
call   1030 <__VERIFIER_assert@plt>
xor    %edi,%edi
xor    %eax,%eax
call   1030 <__VERIFIER_assert@plt>
mov    $0x1,%edi
xor    %eax,%eax
pop    %rcx
jmp    1030 <__VERIFIER_assert@plt>

LLVM IR (-O0):
define void @main() {
%1 = alloca i32*
%2 = alloca i32*
store i32* inttoptr (i64 100 to i32*), i32** %1
store i32* inttoptr (i64 200 to i32*), i32** %2
%3 = load i32*, i32** %1
%4 = getelementptr inbounds i32, i32* %3, i64 5
%5 = icmp eq i32* %4, inttoptr (i64 120 to i32*)
%6 = zext i1 %5 to i32
%7 = call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 %6)
%8 = load i32*, i32** %1
%9 = getelementptr inbounds i32, i32* %8, i64 -10
%10 = icmp eq i32* %9, inttoptr (i64 60 to i32*)
%11 = zext i1 %10 to i32
%12 = call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 %11)
%13 = load i32*, i32** %1
%14 = load i32*, i32** %2
%15 = ptrtoint i32* %13 to i64
%16 = ptrtoint i32* %14 to i64
%17 = sub i64 %15, %16
%18 = sdiv exact i64 %17, 4
%19 = icmp eq i64 %18, 4611686018427387879
%20 = zext i1 %19 to i32
%21 = call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 %20)
%22 = load i32*, i32** %2
%23 = load i32*, i32** %1
%24 = ptrtoint i32* %22 to i64
%25 = ptrtoint i32* %23 to i64
%26 = sub i64 %24, %25
%27 = sdiv exact i64 %26, 4
%28 = icmp eq i64 %27, 25
%29 = zext i1 %28 to i32
%30 = call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 %29)
ret void
}

LLVM IR (-O2):
define void @main() {
%1 = tail call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 1)
%2 = tail call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 1)
%3 = tail call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 0)
%4 = tail call i32 (i32, ...) bitcast (i32 (...)* @__VERIFIER_assert to i32 (i32, ...)*)(i32 1)
ret void
}