int main(void) {
  volatile char ch;
  while (1) {
    while (!((*(volatile unsigned int *)0X3F215054) & (1U << 0)))
      ;
    ch = (char)(*(volatile unsigned int *)0x3F215040);
    while (!((*(volatile unsigned int *)0X3F215054) & (1U << 6)) &&
           !((*(volatile unsigned int *)0X3F215054) & (1U << 5)))
      ;
    (*(volatile unsigned int *)0x3F215040) = (unsigned int)ch;
  }
  return 0;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
movl   $0x0,-0x4(%rbp)
jmp    1110 <main+0x10>
mov    $0x3f215054,%eax
mov    (%rax),%eax
and    $0x1,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
test   $0x1,%al
jne    112f <main+0x2f>
jmp    1134 <main+0x34>
jmp    1110 <main+0x10>
mov    $0x3f215040,%eax
mov    (%rax),%eax
mov    %al,-0x5(%rbp)
mov    $0x3f215054,%eax
mov    (%rax),%ecx
and    $0x40,%ecx
xor    %eax,%eax
cmp    $0x0,%ecx
mov    %al,-0x6(%rbp)
jne    116b <main+0x6b>
mov    $0x3f215054,%eax
mov    (%rax),%eax
and    $0x20,%eax
cmp    $0x0,%eax
setne  %al
xor    $0xff,%al
mov    %al,-0x6(%rbp)
mov    -0x6(%rbp),%al
test   $0x1,%al
jne    117b <main+0x7b>
jmp    1180 <main+0x80>
jmp    113e <main+0x3e>
mov    -0x5(%rbp),%al
movsbl %al,%ecx
mov    $0x3f215040,%eax
mov    %ecx,(%rax)
jmp    110b <main+0xb>

x86 assembly (clang, -O2):
<main>:
jmp    111c <main+0x1c>
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax)
movsbl -0x1(%rsp),%eax
mov    %eax,0x3f215040
testl  $0x1,0x3f215054
je     111c <main+0x1c>
mov    0x3f215040,%eax
mov    %al,-0x1(%rsp)
cs nopw 0x0(%rax,%rax,1)
xchg   %ax,%ax
testl  $0x40,0x3f215054
jne    1110 <main+0x10>
testl  $0x20,0x3f215054
je     1140 <main+0x40>
jmp    1110 <main+0x10>

LLVM IR (-O0):
define i32 @main() {
%1 = alloca i32
%2 = alloca i8
store i32 0, i32* %1
br label %3
3: ; preds = %0, %25
br label %4
4: ; preds = %9, %3
%5 = load volatile i32, i32* inttoptr (i64 1059147860 to i32*)
%6 = and i32 %5, 1
%7 = icmp ne i32 %6, 0
%8 = xor i1 %7, true
br i1 %8, label %9, label %10
9: ; preds = %4
br label %4
10: ; preds = %4
%11 = load volatile i32, i32* inttoptr (i64 1059147840 to i32*)
%12 = trunc i32 %11 to i8
store volatile i8 %12, i8* %2
br label %13
13: ; preds = %24, %10
%14 = load volatile i32, i32* inttoptr (i64 1059147860 to i32*)
%15 = and i32 %14, 64
%16 = icmp ne i32 %15, 0
br i1 %16, label %22, label %17
17: ; preds = %13
%18 = load volatile i32, i32* inttoptr (i64 1059147860 to i32*)
%19 = and i32 %18, 32
%20 = icmp ne i32 %19, 0
%21 = xor i1 %20, true
br label %22
22: ; preds = %17, %13
%23 = phi i1 [ false, %13 ], [ %21, %17 ]
br i1 %23, label %24, label %25
24: ; preds = %22
br label %13
25: ; preds = %22
%26 = load volatile i8, i8* %2
%27 = sext i8 %26 to i32
store volatile i32 %27, i32* inttoptr (i64 1059147840 to i32*)
br label %3
}

LLVM IR (-O2):
define i32 @main() {
%1 = alloca i8
br label %2
2: ; preds = %6, %0
%3 = load volatile i32, i32* inttoptr (i64 1059147860 to i32*)
%4 = and i32 %3, 1
%5 = icmp eq i32 %4, 0
br i1 %5, label %6, label %7
6: ; preds = %2, %18
br label %2
7: ; preds = %2
%8 = load volatile i32, i32* inttoptr (i64 1059147840 to i32*)
%9 = trunc i32 %8 to i8
store volatile i8 %9, i8* %1
br label %10
10: ; preds = %14, %7
%11 = load volatile i32, i32* inttoptr (i64 1059147860 to i32*)
%12 = and i32 %11, 64
%13 = icmp eq i32 %12, 0
br i1 %13, label %14, label %18
14: ; preds = %10
%15 = load volatile i32, i32* inttoptr (i64 1059147860 to i32*)
%16 = and i32 %15, 32
%17 = icmp eq i32 %16, 0
br i1 %17, label %10, label %18
18: ; preds = %10, %14
%19 = load volatile i8, i8* %1
%20 = sext i8 %19 to i32
store volatile i32 %20, i32* inttoptr (i64 1059147840 to i32*)
br label %6
}