#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 volatile uint32_t;

/* Variables and functions */
int /*<<< orphan*/ puts(char *);
void main(void) {
  *(((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x18))) |=
      (uint32_t)(0x00000001 | 0x00000004);
  *(((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x1C))) |=
      (uint32_t)(0x00020000);
  *(((volatile uint32_t *)(((volatile uint32_t)0x40010800) + 0x00))) =
      0x00004B00;
  *(((volatile uint32_t *)(((volatile uint32_t)0x40010800) + 0x04))) =
      0x44444444;
  *(((volatile uint32_t *)(((volatile uint32_t)0x40004400) + 0x0C))) =
      0x0000000C;
  *(((volatile uint32_t *)(((volatile uint32_t)0x40004400) + 0x0C))) |= 0x2000;
  puts("Hello World!\n");
  while (1)
    ;
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
mov    $0x40021018,%eax
mov    (%rax),%ecx
or     $0x5,%ecx
mov    $0x40021018,%eax
mov    %ecx,(%rax)
mov    $0x4002101c,%eax
mov    (%rax),%ecx
or     $0x20000,%ecx
mov    $0x4002101c,%eax
mov    %ecx,(%rax)
mov    $0x40010800,%eax
movl   $0x4b00,(%rax)
mov    $0x40010804,%eax
movl   $0x44444444,(%rax)
mov    $0x4000440c,%eax
movl   $0xc,(%rax)
mov    $0x4000440c,%eax
mov    (%rax),%ecx
or     $0x2000,%ecx
mov    $0x4000440c,%eax
mov    %ecx,(%rax)
lea    0xe8b(%rip),%rdi
call   1030 <puts@plt>
jmp    117a <main+0x6a>

x86 assembly (clang, -O2):
<main>:
push   %rax
orl    $0x5,0x40021018
05
orl    $0x20000,0x4002101c
movl   $0x4b00,0x40010800
movl   $0x44444444,0x40010804
44 44 44 44
movl   $0xc,0x4000440c
orl    $0x2000,0x4000440c
lea    0xea9(%rip),%rdi
call   1030 <puts@plt>
nopl   0x0(%rax)
jmp    1160 <main+0x50>

LLVM IR (-O0):
@.str = [14 x i8] c"Hello World!\0A\00"
define void @main() {
%1 = load volatile i32, i32* inttoptr (i64 1073877016 to i32*)
%2 = or i32 %1, 5
store volatile i32 %2, i32* inttoptr (i64 1073877016 to i32*)
%3 = load volatile i32, i32* inttoptr (i64 1073877020 to i32*)
%4 = or i32 %3, 131072
store volatile i32 %4, i32* inttoptr (i64 1073877020 to i32*)
store volatile i32 19200, i32* inttoptr (i64 1073809408 to i32*)
store volatile i32 1145324612, i32* inttoptr (i64 1073809412 to i32*)
store volatile i32 12, i32* inttoptr (i64 1073759244 to i32*)
%5 = load volatile i32, i32* inttoptr (i64 1073759244 to i32*)
%6 = or i32 %5, 8192
store volatile i32 %6, i32* inttoptr (i64 1073759244 to i32*)
%7 = call i32 @puts(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
br label %8
8: ; preds = %0, %8
br label %8
}

LLVM IR (-O2):
@.str = [14 x i8] c"Hello World!\0A\00"
define void @main() {
%1 = load volatile i32, i32* inttoptr (i64 1073877016 to i32*)
%2 = or i32 %1, 5
store volatile i32 %2, i32* inttoptr (i64 1073877016 to i32*)
%3 = load volatile i32, i32* inttoptr (i64 1073877020 to i32*)
%4 = or i32 %3, 131072
store volatile i32 %4, i32* inttoptr (i64 1073877020 to i32*)
store volatile i32 19200, i32* inttoptr (i64 1073809408 to i32*)
store volatile i32 1145324612, i32* inttoptr (i64 1073809412 to i32*)
store volatile i32 12, i32* inttoptr (i64 1073759244 to i32*)
%5 = load volatile i32, i32* inttoptr (i64 1073759244 to i32*)
%6 = or i32 %5, 8192
store volatile i32 %6, i32* inttoptr (i64 1073759244 to i32*)
%7 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i64 0, i64 0))
br label %8
8: ; preds = %0, %8
br label %8
}